/* * A nroff like object for formating text files. * * This creates a saveable file format thingy. */ #include "nroff.h" mixed *nroffed_file; string nroffed_file_name; int modified_time; void create() { nroffed_file = ({ }); seteuid("Root"); /* Security risk? nahhhhh */ } /* create() */ #define do_bounds(bing) (bing<0?bing+cols:bing) /* * Creates a string from a nroffed file * * If update is non zero it will try and find the file_name and return * 0 from here if it is either not found, or non existant... */ string cat_file(string fname, int update) { int i, cols; string ret; if (!"/secure/master"->valid_read(fname, geteuid(previous_object()), "restore_object")) return 0; nroffed_file_name = 0; modified_time = 0; if (!restore_object(fname,1)) return 0; if (!nroffed_file_name && update) return 0; if (update) { mixed *something; if (!"/secure/master"->valid_read(nroffed_file_name, geteuid(previous_object()), "restore_object")) return 0; if (file_size(nroffed_file_name) <= 0) return 0; something = stat(nroffed_file_name); if (something[1] > modified_time) return 0; } ret = ""; cols = (int)this_player()->query_cols(); for (i=0;i<sizeof(nroffed_file);i++) if (stringp(nroffed_file[i])) ret += nroffed_file[i]; else switch (nroffed_file[i]) { case V_CENTER : ret += sprintf("%|=*s", cols, nroffed_file[i+1]); i++; break; case V_ALL : ret += sprintf("%-*s%|*s%*s\n", nroffed_file[i+1], nroffed_file[i+2], cols - nroffed_file[i+1]*2, nroffed_file[i+3], nroffed_file[i+1], nroffed_file[i+4]); i += 4; break; case V_INDENT : ret += sprintf("%*=s%-=*s\n", nroffed_file[i+1], "", cols-nroffed_file[i+1], nroffed_file[i+2]); i += 2; break; case V_PARA : ret += sprintf("%*=s%-=*s%=*s\n", nroffed_file[i+1], "", cols-nroffed_file[i+1]- nroffed_file[i+2], nroffed_file[i+3], nroffed_file[i+2], ""); i += 3; break; case V_LEFT : ret += sprintf("%-=*s", cols, nroffed_file[i+1]); i++; break; case V_TABLE : ret += sprintf("%-#*s", cols, nroffed_file[i+1]); i++; break; case V_COLUMN : { int j; switch (sizeof(nroffed_file[i+1])) { case 2 : for (j=0;j<sizeof(nroffed_file[i+2]);j++) ret += sprintf("%*-=s%*-=s\n", do_bounds(nroffed_file[i+1][0]), nroffed_file[i+2][j], do_bounds(nroffed_file[i+1][1]), nroffed_file[i+3][j]); i += 3; break; case 3 : for (j=0;j<sizeof(nroffed_file[i+2]);j++) ret += sprintf("%*-=s%*-=s%*-=s\n", do_bounds(nroffed_file[i+1][0]), nroffed_file[i+2][j], do_bounds(nroffed_file[i+1][1]), nroffed_file[i+3][j], do_bounds(nroffed_file[i+1][2]), nroffed_file[i+4][j]); i += 4; break; } break; } } return " \n"+ret; } static int new_string, force_string; void add_array(mixed *i) { if (!sizeof(nroffed_file)) nroffed_file += ({ i }); else if (force_string) nroffed_file += ({ "", i }); else nroffed_file += ({ i }); force_string = 0; new_string = 0; } void add_int(int i) { if (!sizeof(nroffed_file)) nroffed_file += ({ i }); else if (force_string) nroffed_file += ({ "", i }); else nroffed_file += ({ i }); force_string = 0; new_string = 0; } void add_string(string s) { if (!sizeof(nroffed_file) || new_string) nroffed_file += ({ s }); else if (stringp(nroffed_file[sizeof(nroffed_file)-1])) nroffed_file[sizeof(nroffed_file)-1] += s; else nroffed_file += ({ s }); new_string = 0; force_string = 0; } int create_nroff(string in_file, string out_file) { string text, tmp, *bits; string *bing; mixed *cols; int strip_crs, col_mode, conv_tabs, i, j, k, num_cols; if (!"/secure/master"->valid_read(in_file, geteuid(previous_object()), "read_file")) return 0; if (!"/secure/master"->valid_write(out_file, geteuid(previous_object()), "save_object")) return 0; nroffed_file_name = in_file; modified_time = time(); text = read_file(in_file); if (!text) return 0; bits = explode("#\n"+text, "\n."); bits[0] = bits[0][1..strlen(bits[0])-1]; nroffed_file = ({ 0 }); if (strlen(bits[0])) add_string(bits[0]); for (i=1;i<sizeof(bits);i++) { /* if (!strlen(bits[i])) { if (col_mode) { for (j=0;j<num_cols;j++) cols[j] += "\n"; } else if (strip_crs) add_string("\n\n"); else add_string("\n"); } else if (bits[i][0] == '.') { */ if (sscanf(bits[i], "%s\n%s", tmp, bits[i]) != 2) { tmp = bits[i]; bits[i] = ""; } switch (tmp[0..1]) { case "SI" : /* Start indent */ add_int(V_INDENT); j = 0; sscanf(tmp[2..1000], "%d%s", j, tmp); add_int(j); force_string = 1; break; case "EI" : /* End paragraph */ new_string = 1; break; case "SP" : /* Start paragraph */ add_int(V_PARA); j = 0; sscanf(tmp[2..1000], "%d%s", j, tmp); add_int(j); j = 0; sscanf(tmp, " %d%s", j, tmp); add_int(j); force_string = 1; strip_crs = 1; break; case "EP" : /* End paragraph */ new_string = 1; strip_crs = 0; break; case "SC" : /* start centering */ add_int(V_CENTER); force_string = 1; break; case "EC" : /* End centering */ new_string = 1; break; case "SL" : /* Start left justify */ add_int(V_LEFT); force_string = 1; break; case "EL " : /* End left justify */ new_string = 1; break; case "ST" : /* Start table mode (Turn tabs into new lines) */ add_int(V_TABLE); force_string = 1; conv_tabs = 1; break; case "ET" : /* End table mode */ new_string = 1; conv_tabs = 0; break; case "DT" : /* Do title. Take the next three lines... */ bing = explode(bits[i], "\n"); if (sizeof(bing) < i+3) return 0; /* failed! */ add_int(V_ALL); if (strlen(bing[0]) > strlen(bing[2])) add_int(strlen(bing[0])); else add_int(strlen(bing[2])); new_string = 1; add_string(bing[0]); new_string = 1; add_string(bing[1]); new_string = 1; add_string(bing[2]); new_string = 1; bits[i] = implode(bing[3..1000], "\n"); break; case "SO" : /* starts column mode. The numbers after it * are column size */ num_cols = 0; tmp = tmp[2..1000]; cols = ({ }); while (sscanf(tmp, "%d%s", j, tmp) == 2) { cols += ({ j }); num_cols++; while (strlen(tmp) && tmp[0] == ' ') tmp = tmp[1..1000]; } add_int(V_COLUMN); if (sscanf(tmp, "%d", j) == 1) { cols += ({ j }); num_cols++; } add_array(cols); cols = allocate(num_cols); for (j=0;j<num_cols;j++) cols[j] = ({ }); col_mode = 1; break; case "EO" : /* End column mode */ for (j=0;j<num_cols;j++) { add_array(cols[j]); } col_mode = 0; break; } /* Now dis bit... */ if (!strlen(bits[i])) continue; if (conv_tabs) bits[i] = replace(bits[i], "\t", "\n"); if (col_mode) { string *frog; frog = explode(bits[i], "\n"); for (k=0;k<sizeof(frog);k++) { bing = explode("#"+frog[k], "\t"); bing[0] = bing[0][1..1000]; for (j=0;j<num_cols && j < sizeof(bing);j++) cols[j] += ({ bing[j] }); for (j=sizeof(bing);j<num_cols;j++) cols[j] += ({ "\n" }); } } else if (strip_crs) { bits[i] = replace_string(bits[i], "\n\n", "$%^NeW_LiNe^%$"); bits[i] = replace_string(bits[i], "\n", " "); bits[i] = replace_string(bits[i], "$%^NeW_LiNe^%$", "\n\n"); add_string(bits[i]+" "); } else add_string(bits[i]+"\n"); /* } */ } new_string = 0; force_string = 0; save_object(out_file,1); return 1; } void create_help(string path, string file) { if (path[0..4] == "/doc/") this_object()->create_nroff(path+file, NROFF_DIR+file); else write("Invalid path. "+path+"\n"); } void create_chelp(string path, string file) { if (path[0..4] == "/doc/") this_object()->create_nroff(path+file, CNROFF_DIR+file); else write("Invalid path.\n"); }