1d5f692001-07-25Martin Nilsson /* $Id: mkxml.pike,v 1.31 2001/07/25 21:20:08 nilsson Exp $ */
0a94502001-07-18Martin Nilsson  string LENA_PATH = "../autodoc/image_ill.pnm"; string makepic1; string makepic2;
61fee92001-05-05Mirar (Pontus Hagland) 
e507c42001-07-17Martin Nilsson mapping parse=([ " appendix":([]) ]);
61fee92001-05-05Mirar (Pontus Hagland) int illustration_counter; #define error(X) throw( ({ (X), backtrace()[0..sizeof(backtrace())-2] }) ) /* module : mapping <- moduleM "desc" : text "see also" : array of references "note" : mapping of "desc": text "modules" : same as classes (below) "classes" : mapping class : mapping <- classM "see also" : array of references "desc" : text "note" : mapping of "desc": text "methods" : array of mappings <- methodM "decl" : array of textlines of declarations "desc" : text "returns" : textline "see also" : array of references "note" : mapping of "desc": text "known bugs" : mapping of "desc": text "args" : array of mappings <- argM "args" : array of args names and types "desc" : description "names" : multiset of method name(s) Quoting: Only '<' must be quoted as '&lt;'. */
e507c42001-07-17Martin Nilsson mapping moduleM, classM, methodM, argM, nowM, descM, appendixM;
61fee92001-05-05Mirar (Pontus Hagland)  mapping focM(mapping dest,string name,string line) { if (!dest->_order) dest->_order=({});
648eb42001-07-17Martin Nilsson  if (!has_value(dest->_order,name)) dest->_order+=({name});
61fee92001-05-05Mirar (Pontus Hagland)  return dest[name] || (dest[name]=(["_line":line])); } string stripws(string s) {
e507c42001-07-17Martin Nilsson  if (s=="") return s;
61fee92001-05-05Mirar (Pontus Hagland) 
e507c42001-07-17Martin Nilsson  array lines = s / "\n"; lines = map(lines, lambda(string s) { s = reverse(s); sscanf(s, "%*[ \t\r]%s", s); s = reverse(s); return s; }); int m=10000; foreach (lines,string s) if (s!="") { sscanf(s,"%[ ]%s",string a,string b); if (b!="") m=min(strlen(a),m); } return map(lines,lambda(string s) { return s[m..]; })*"\n";
61fee92001-05-05Mirar (Pontus Hagland) } mapping lower_nowM() { if (nowM && (nowM==parse || nowM==classM || nowM==methodM || nowM==moduleM)) return nowM; else return nowM=methodM; } void report(string s) {
648eb42001-07-17Martin Nilsson  werror("mkxml: "+s+"\n");
61fee92001-05-05Mirar (Pontus Hagland) } #define complain(X) (X)
7cf59c2001-05-09Henrik Grubbström (Grubba) string file_version = "";
61fee92001-05-05Mirar (Pontus Hagland) mapping keywords=
7cf59c2001-05-09Henrik Grubbström (Grubba) (["$Id":lambda(string arg, string line) { file_version = " version='Id: "+arg[..search(arg, "$")-1]+"'"; },
e507c42001-07-17Martin Nilsson  "appendix":lambda(string arg,string line) { descM=nowM=appendixM=focM(parse[" appendix"],stripws(arg),line); report("appendix "+arg);},
7cf59c2001-05-09Henrik Grubbström (Grubba)  "module":lambda(string arg,string line)
61fee92001-05-05Mirar (Pontus Hagland)  { classM=descM=nowM=moduleM=focM(parse,stripws(arg),line); methodM=0; if (!nowM->classes) nowM->classes=(["_order":({})]); if (!nowM->modules) nowM->modules=(["_order":({})]); report("module "+arg); }, "class":lambda(string arg,string line) { if (!moduleM) return complain("class w/o module"); descM=nowM=classM=focM(moduleM->classes,stripws(arg),line); methodM=0; report("class "+arg); }, "submodule":lambda(string arg,string line) { if (!moduleM) return complain("submodule w/o module"); classM=descM=nowM=moduleM=focM(moduleM->modules,stripws(arg),line); methodM=0; if (!nowM->classes) nowM->classes=(["_order":({})]); if (!nowM->modules) nowM->modules=(["_order":({})]); report("submodule "+arg); }, "method":lambda(string arg,string line) { if (!classM) return complain("method w/o class"); if (!nowM || methodM!=nowM || methodM->desc || methodM->args || descM==methodM) { if (!classM->methods) classM->methods=({}); classM->methods+=({methodM=nowM=(["decl":({}),"_line":line])}); } methodM->decl+=({stripws(arg)}); descM=0; }, "inherits":lambda(string arg,string line) { if (!nowM) return complain("inherits w/o class or module"); if (nowM != classM) return complain("inherits outside class or module"); if (!classM->inherits) classM->inherits=({}); classM->inherits+=({stripws(arg)}); }, "variable":lambda(string arg,string line) { if (!classM) return complain("variable w/o class"); if (!classM->variables) classM->variables=({}); classM->variables+=({descM=nowM=(["_line":line])}); nowM->decl=stripws(arg); }, "constant":lambda(string arg,string line) { if (!classM) return complain("constant w/o class"); if (!classM->constants) classM->constants=({}); classM->constants+=({descM=nowM=(["_line":line])}); nowM->decl=stripws(arg); }, "arg":lambda(string arg,string line) { if (!methodM) return complain("arg w/o method"); if (!methodM->args) methodM->args=({}); methodM->args+=({argM=nowM=(["args":({}),"_line":line])}); argM->args+=({arg}); descM=argM; }, "note":lambda(string arg,string line) { if (!lower_nowM()) return complain("note w/o method, class or module"); descM=nowM->note||(nowM->note=(["_line":line])); }, "added":lambda(string arg,string line) { if (!lower_nowM()) return complain("added in: w/o method, class or module"); descM=nowM->added||(nowM->added=(["_line":line])); }, "bugs":lambda(string arg,string line) { if (!lower_nowM()) return complain("bugs w/o method, class or module"); descM=nowM->bugs||(nowM->bugs=(["_line":line])); }, "see":lambda(string arg,string line) { if (arg[0..3]!="also") return complain("see w/o 'also:'\n"); if (!lower_nowM()) return complain("see also w/o method, class or module"); sscanf(arg,"also%*[:]%s",arg); nowM["see also"]=map(arg/",",stripws)-({""}); if (!nowM["see also"]) return complain("empty see also\n"); }, "returns":lambda(string arg) { if (!methodM) return complain("returns w/o method"); methodM->returns=stripws(arg); descM=0; nowM=0; } ]); string getridoftabs(string s) { string res=""; while (sscanf(s,"%s\t%s",string a,s)==2) { res+=a; res+=" "[(strlen(res)%8)..7]; } return res+s; }
e507c42001-07-17Martin Nilsson string htmlify(string s)
61fee92001-05-05Mirar (Pontus Hagland) { #define HTMLIFY(S) \ (replace((S),({"&lt;","&gt;",">","&","\240"}),({"&lt;","&gt;","&gt;","&amp;","&nbsp;"}))) string t="",u,v; while (sscanf(s,"%s<%s>%s",u,v,s)==3) t+=HTMLIFY(u)+"<"+v+">"; return t+HTMLIFY(s); } #define linkify(S) \ ("\""+replace((S),({"->","()","&lt;","&gt;"}),({".","","<",">"}))+"\"") string make_nice_reference(string what,string prefix,string stuff) { string q; if (what==prefix[strlen(prefix)-strlen(what)-2..strlen(prefix)-3]) { q=prefix[0..strlen(prefix)-3]; } else if (what==prefix[strlen(prefix)-strlen(what)-1..strlen(prefix)-2]) { q=prefix[0..strlen(prefix)-2]; } else if (search(what,".")==-1 && search(what,"->")==-1 && !parse[what]) { q=prefix+what; } else q=what;
c944b12001-05-05Mirar (Pontus Hagland)  return "<ref to="+linkify(q)+">"+htmlify(stuff)+"</ref>";
61fee92001-05-05Mirar (Pontus Hagland) }
1d5f692001-07-25Martin Nilsson Parser.HTML parser;
648eb42001-07-17Martin Nilsson 
0a94502001-07-18Martin Nilsson string fixdesc(string s,string prefix,void|string where)
61fee92001-05-05Mirar (Pontus Hagland) {
0a94502001-07-18Martin Nilsson  s = stripws(replace(s, "<p>", "\n"));
e507c42001-07-17Martin Nilsson 
1d5f692001-07-25Martin Nilsson  parser->set_extra(where);
0a94502001-07-18Martin Nilsson 
1d5f692001-07-25Martin Nilsson  s = parser->finish(s)->read();
e507c42001-07-17Martin Nilsson  s = "<p>" + (s/"\n\n")*"</p>\n\n<p>" + "</p>";
0a94502001-07-18Martin Nilsson  s = htmlify(s);
e507c42001-07-17Martin Nilsson  if (where)
7cf59c2001-05-09Henrik Grubbström (Grubba)  return "<source-position " + where + file_version + "/>\n"+s;
e507c42001-07-17Martin Nilsson 
5af3db2001-05-07Mirar (Pontus Hagland)  return s;
61fee92001-05-05Mirar (Pontus Hagland) } multiset(string) get_method_names(string *decls) { string decl,name; multiset(string) names=(<>); foreach (decls,decl) { sscanf(decl,"%*s%*[\t ]%s%*[\t (]%*s",name); names[name]=1; } return names; }
e507c42001-07-17Martin Nilsson array(string) nice_order(string *arr)
61fee92001-05-05Mirar (Pontus Hagland) { sort(map(arr,replace,({"_","`"}),({"ÿ","þ"})), arr); return arr; } string addprefix(string suffix,string prefix) { return prefix+suffix; } #define S(X) ("'"+(X)+"'") /* XML arg quote */ string doctype(string type,void|string indent) { array(string) endparan(string in) { int i; int q=1; for (i=0; i<strlen(in); i++) switch (in[i]) { case '(': q++; break; case ')': q--; if (!q) return ({in[..i-1],in[i+1..]}); break; } return ({in,""}); }; string combine_or(string a,string b) { if (b[..3]=="<or>") b=b[4..strlen(b)-6]; return "<or>"+a+b+"</or>"; }; array(string) paramlist(string in,string indent) { int i; int q=0; array res=({}); for (i=0; i<strlen(in); i++) switch (in[i]) { case '(': q++; break; case ')': q--; break; case ':': case ',': if (!q) return ({doctype(in[..i-1],indent+" ")})+ paramlist(in[i+1..],indent); }
62fd782001-07-20Martin Nilsson  return ({doctype(in,indent+" ")});
61fee92001-05-05Mirar (Pontus Hagland)  }; if (!indent) indent="\n "; string nindent=indent+" ";
e507c42001-07-17Martin Nilsson  if (type[..2]=="...")
61fee92001-05-05Mirar (Pontus Hagland)  return nindent+"<varargs>"+doctype(type[3..])+"</varargs>"; string a=type,b=0,c,o=0; sscanf(type,"%s(%s",a,b); if (b) [b,c]=endparan(b); if (sscanf(a,"%s|%s",string d,string e)==2) { if (b) e+="("+b+")"+c; return nindent+combine_or(doctype(d,nindent), doctype(e,nindent)); } if (b && c!="" && sscanf(c,"%s|%s",string d,string e)==2) return nindent+combine_or(doctype(a+"("+b+")"+d,nindent), doctype(e,nindent)); switch (a) { case "int": case "float": case "string": case "void": case "program": case "array": case "mapping": case "multiset": case "function": case "object": case "mixed": if (!b) return "<"+a+"/>"; break; } switch (a) { case "array": return nindent+"<array><valuetype>"+ doctype(b,nindent)+"</valuetype></array>"; case "multiset": return nindent+"<multiset><indextype>"+ doctype(b,nindent)+"</indextype></multiset>"; case "mapping": array z=paramlist(b,nindent); if (sizeof(z)!=2) werror("warning: confused mapping type: %O\n",type),
62fd782001-07-20Martin Nilsson  z+=({"<mixed/>","<mixed/>"});
61fee92001-05-05Mirar (Pontus Hagland)  return nindent+"<mapping><indextype>"+z[0]+"</indextype>"+ nindent+" <valuetype>"+z[1]+"</valuetype></mapping>"; case "object": return nindent+"<object>"+b+"</object>"; case "function": z=paramlist(b,nindent); if (sizeof(z)<1) werror("warning: confused function type: %O\n",type),
62fd782001-07-20Martin Nilsson  z+=({"<mixed/>"});
61fee92001-05-05Mirar (Pontus Hagland)  return nindent+ "<function>"+ map(z[..sizeof(z)-2], lambda(string s) {
15aafd2001-07-19Martin Nilsson  return nindent+" <argtype>"+s+"</argtype>";
61fee92001-05-05Mirar (Pontus Hagland)  })*""+ nindent+" <returntype>"+z[-1]+"</returntype>"+ nindent+"</function>"; }
69ffe82001-05-05Mirar (Pontus Hagland)  if (b && a=="int") { if (sscanf(b,"%d..%d",int min,int max)==2) return nindent+"<int><min>"+min+"</min><max>"+max+"</max></int>"; if (sscanf(b,"..%d",int max)==1) return nindent+"<int><max>"+max+"</max></int>"; if (sscanf(b,"%d..%",int min)==1) return nindent+"<int><min>"+min+"</min></int>"; }
61fee92001-05-05Mirar (Pontus Hagland)  if (b) werror("warning: confused type: %O\n",type); return nindent+"<object>"+type+"</object>"; }
46275a2001-05-05Mirar (Pontus Hagland) 
5af3db2001-05-07Mirar (Pontus Hagland) constant convname= ([ "`>":"`&gt;", "`<":"`&lt;", "`>=":"`&gt;=", "`<=":"`&lt;=", "`&":"`&amp;", ]);
61fee92001-05-05Mirar (Pontus Hagland) void docdecl(string enttype, string decl, object f) { string rv,name,params=0; sscanf(decl,"%s %s(%s",rv,name,params);
5af3db2001-05-07Mirar (Pontus Hagland)  if (convname[name]) name=convname[name];
61fee92001-05-05Mirar (Pontus Hagland)  f->write("<"+enttype+" name="+S(name)+">"); if (params) {
15aafd2001-07-19Martin Nilsson  string paramlist(string in) { int i; string res = ""; while(i<sizeof(in)) { // Find type string t = ""; int br; for (; i<sizeof(in); i++) { t += in[i..i]; if(in[i]=='(') br++; if(in[i]==')') br--; if(in[i]==' ' && !br) { t = doctype(t[..sizeof(t)-2]); break; } if(br==-1 || in[i]==',') { if(String.trim_all_whites(t)==")") return res; if(String.trim_all_whites(t[..sizeof(t)-2])=="void" && res=="") return "<argument/>\n"; if(t[-1]==')') return res += "<argument><value>" + t[..sizeof(t)-2] + "</value></argument>"; if(t[-1]==',') break; } } if(t[-1]==',') { res += "<argument><value>" + t[..sizeof(t)-2] + "</value></argument>"; i++; continue; } // Find name string n = "";
f292212001-07-20Martin Nilsson  i++;
15aafd2001-07-19Martin Nilsson  for (; i<sizeof(in); i++) {
f292212001-07-20Martin Nilsson  if(in[i]==')') { if(!sizeof(String.trim_all_whites(n)))
1d5f692001-07-25Martin Nilsson  throw( ({ "Empty argument name. ("+in+")\n", backtrace() }) );
15aafd2001-07-19Martin Nilsson  return res + "<argument name=" + S(n) + "><type>" + t + "</type></argument>\n";
f292212001-07-20Martin Nilsson  }
15aafd2001-07-19Martin Nilsson  if(in[i]==',') {
f292212001-07-20Martin Nilsson  if(!sizeof(String.trim_all_whites(n)))
1d5f692001-07-25Martin Nilsson  throw( ({ "Empty argument name. ("+in+")\n", backtrace() }) );
15aafd2001-07-19Martin Nilsson  res += "<argument name=" + S(n) + "><type>" + t + "</type></argument>\n"; break; }
f292212001-07-20Martin Nilsson  if(in[i]==' ') {
15aafd2001-07-19Martin Nilsson  if(n=="...") { n = ""; t = "<varargs>" + t + "</varargs>"; }
f292212001-07-20Martin Nilsson  }
15aafd2001-07-19Martin Nilsson  else n += in[i..i]; } i++; } throw( ({ "Malformed argument list \"(" + in + "\".\n", backtrace() }) ); }; f->write("\n <returntype>"+doctype(rv,"\n ")+"</returntype>\n" " <arguments>"+paramlist(params)+"\n </arguments>\n");
61fee92001-05-05Mirar (Pontus Hagland)  } else { f->write("<typevalue>"+doctype(rv)+"</typevalue>\n"); } f->write("</"+enttype+">"); } void document(string enttype, mapping huh,string name,string prefix, object f) {
e507c42001-07-17Martin Nilsson  array(string) names;
61fee92001-05-05Mirar (Pontus Hagland)  if (huh->names) names=map(indices(huh->names),addprefix,name); else names=({name});
648eb42001-07-17Martin Nilsson  report(name+" : "+names*",");
61fee92001-05-05Mirar (Pontus Hagland)  array v=name/"."; string canname=v[-1]; sscanf(canname,"%s->",canname); sscanf(canname,"%s()",canname);
0a94502001-07-18Martin Nilsson  string presname = replace(sort(names)[0], ([ ".":"_", ">":"_" ]) );
5af3db2001-05-07Mirar (Pontus Hagland)  if (convname[canname]) canname=convname[canname];
61fee92001-05-05Mirar (Pontus Hagland)  switch (enttype) {
e507c42001-07-17Martin Nilsson  case "appendix": f->write("<"+enttype+" name="+S(name)+">\n"); break;
61fee92001-05-05Mirar (Pontus Hagland)  case "class": case "module": f->write("<"+enttype+" name="+S(canname)+">\n"); break; default:
5efbf32001-07-20Martin Nilsson  f->write("<docgroup homogen-type="+S(enttype)); if(huh->decl) { lambda() { string m,n; array decl; if(!arrayp(huh->decl)) decl = ({ huh->decl }); else decl = huh->decl; foreach(decl, string prot) { sscanf(prot, "%*s %s(", n); if(!m) { m=n; continue; } if(n!=m) return; } if(convname[m]) m=convname[m]; f->write(" homogen-name="+S(m)); }(); } f->write(">\n");
61fee92001-05-05Mirar (Pontus Hagland)  if (huh->decl) { foreach (arrayp(huh->decl)?huh->decl:({huh->decl}),string decl) { docdecl(enttype,decl,f); } } else foreach (names,string name) {
5af3db2001-05-07Mirar (Pontus Hagland)  if (convname[name]) name=convname[name];
61fee92001-05-05Mirar (Pontus Hagland)  f->write("<"+enttype+" name="+S(name)+">\n"); f->write("</"+enttype+">"); } break; }
7cf59c2001-05-09Henrik Grubbström (Grubba)  f->write("<source-position " + huh->_line + file_version + "/>\n");
61fee92001-05-05Mirar (Pontus Hagland)  // [DESCRIPTION]
5af3db2001-05-07Mirar (Pontus Hagland)  string res="";
69ffe82001-05-05Mirar (Pontus Hagland) 
61fee92001-05-05Mirar (Pontus Hagland)  if (huh->desc) {
5af3db2001-05-07Mirar (Pontus Hagland)  res+="<text>\n";
61fee92001-05-05Mirar (Pontus Hagland)  if (huh->inherits) { string s=""; foreach (huh->inherits,string what)
5af3db2001-05-07Mirar (Pontus Hagland)  res+="inherits "+make_nice_reference(what,prefix,what)+
71a0602001-05-07Henrik Grubbström (Grubba)  "<br/>\n"; res+="<br/>\n";
61fee92001-05-05Mirar (Pontus Hagland)  }
5af3db2001-05-07Mirar (Pontus Hagland)  res+=fixdesc(huh->desc,prefix,huh->_line)+"\n"; res+="</text>\n";
61fee92001-05-05Mirar (Pontus Hagland)  } // [ARGUMENTS]
5af3db2001-05-07Mirar (Pontus Hagland) #if 1
61fee92001-05-05Mirar (Pontus Hagland)  if (huh->args) { string rarg=""; mapping arg;
5af3db2001-05-07Mirar (Pontus Hagland)  array v=({});
61fee92001-05-05Mirar (Pontus Hagland)  foreach (huh->args, arg) {
5af3db2001-05-07Mirar (Pontus Hagland)  v+=arg->args;
61fee92001-05-05Mirar (Pontus Hagland)  if (arg->desc) {
5af3db2001-05-07Mirar (Pontus Hagland)  res+="<group>\n"; foreach (v,string arg) {
b620f12001-05-08Mirar (Pontus Hagland)  sscanf(arg,"%*s %s",arg); sscanf(arg,"%s(%*s",arg); // type name(whatever) res+=" <param name="+S(arg)+"/>\n";
5af3db2001-05-07Mirar (Pontus Hagland)  } res+= "<text>"+ fixdesc(arg->desc,prefix,arg->_line)+ "</text></group>\n";
61fee92001-05-05Mirar (Pontus Hagland)  } } if (rarg!="") error("trailing args w/o desc on "+arg->_line+"\n"); }
69ffe82001-05-05Mirar (Pontus Hagland) #endif
61fee92001-05-05Mirar (Pontus Hagland)  // [RETURN VALUE] if (huh->returns) {
88464d2001-05-09Henrik Grubbström (Grubba)  res+="<group><returns/><text>\n";
5af3db2001-05-07Mirar (Pontus Hagland)  res+=fixdesc(huh->returns,prefix,huh->_line)+"\n";
88464d2001-05-09Henrik Grubbström (Grubba)  res+="</text></group>\n";
61fee92001-05-05Mirar (Pontus Hagland)  } // [NOTE] if (huh->note && huh->note->desc) {
88464d2001-05-09Henrik Grubbström (Grubba)  res+="<group><note/><text>\n";
5af3db2001-05-07Mirar (Pontus Hagland)  res+=fixdesc(huh->note->desc,prefix,huh->_line)+"\n";
88464d2001-05-09Henrik Grubbström (Grubba)  res+="</text></group>\n";
61fee92001-05-05Mirar (Pontus Hagland)  } // [BUGS] if (huh->bugs && huh->bugs->desc) {
88464d2001-05-09Henrik Grubbström (Grubba)  res+="<group><bugs/><text>\n";
5af3db2001-05-07Mirar (Pontus Hagland)  res+=fixdesc(huh->bugs->desc,prefix,huh->_line)+"\n";
88464d2001-05-09Henrik Grubbström (Grubba)  res+="</text></group>\n";
61fee92001-05-05Mirar (Pontus Hagland)  } // [ADDED] if (huh->added && huh->added->desc) { /* noop */ } // [SEE ALSO] if (huh["see also"]) {
88464d2001-05-09Henrik Grubbström (Grubba)  res+="<group><seealso/><text>\n";
5af3db2001-05-07Mirar (Pontus Hagland)  res+=fixdesc( map(huh["see also"], lambda(string s) { return "<ref>"+htmlify(s)+"</ref>"; })*", ", prefix,0);
88464d2001-05-09Henrik Grubbström (Grubba)  res+="</text></group>\n";
61fee92001-05-05Mirar (Pontus Hagland)  }
5af3db2001-05-07Mirar (Pontus Hagland)  if (res!="") { f->write("<doc>\n"+res+"\n</doc>\n"); }
61fee92001-05-05Mirar (Pontus Hagland)  // ---childs---- if (huh->constants) { foreach(huh->constants,mapping m) { sscanf(m->decl,"%s %s",string type,string name); sscanf(name,"%s=%s",name,string value); document("constant",m,prefix+name,prefix+name+".",f); } } if (huh->variables) { foreach(huh->variables,mapping m) { sscanf(m->decl,"%s %s",string type,string name); if (!name) name=m->decl,type="mixed"; sscanf(name,"%s=%s",name,string value); document("variable",m,prefix+name,prefix+name+".",f); } } if (huh->methods) { // postprocess methods to get names multiset(string) method_names=(<>); string *method_names_arr,method_name; mapping method; if (huh->methods) foreach (huh->methods,method) method_names|=(method->names=get_method_names(method->decl)); method_names_arr=nice_order(indices(method_names)); // alphabetically foreach (method_names_arr,method_name) if (method_names[method_name]) { // find it foreach (huh->methods,method) if ( method->names[method_name] ) { document("method",method,prefix,prefix,f); method_names-=method->names; } if (method_names[method_name])
648eb42001-07-17Martin Nilsson  Stdio.stderr->write("failed to find "+method_name+" again, wierd...\n");
61fee92001-05-05Mirar (Pontus Hagland)  } } if (huh->classes) { foreach(huh->classes->_order,string n) { // f->write("\n\n\n<section title=\""+prefix+n+"\">\n"); document("class",huh->classes[n], prefix+n,prefix+n+"->",f); // f->write("</section title=\""+prefix+n+"\">\n"); } } if (huh->modules) { foreach(huh->modules->_order,string n) { document("module",huh->modules[n], prefix+n,prefix+n+".",f); } } // end ANCHOR switch (enttype) {
e507c42001-07-17Martin Nilsson  case "appendix":
61fee92001-05-05Mirar (Pontus Hagland)  case "class": case "module": f->write("</"+enttype+">\n\n"); break; default: f->write("</docgroup>\n\n"); break; } } void make_doc_files() {
648eb42001-07-17Martin Nilsson  Stdio.stderr->write("modules: "+sort(indices(parse)-({" appendix"}))*", "+"\n");
cb0c7b2001-05-06Henrik Grubbström (Grubba) 
648eb42001-07-17Martin Nilsson  Stdio.stdout->write("<module name=''>\n");
5af3db2001-05-07Mirar (Pontus Hagland) 
e507c42001-07-17Martin Nilsson  foreach (sort(indices(parse)-({"_order", " appendix"})),string module)
648eb42001-07-17Martin Nilsson  document("module",parse[module],module,module+".", Stdio.stdout);
5af3db2001-05-07Mirar (Pontus Hagland) 
e507c42001-07-17Martin Nilsson  if(appendixM) foreach(parse[" appendix"]->_order, string title)
648eb42001-07-17Martin Nilsson  document("appendix",parse[" appendix"][title],title,"", Stdio.stdout);
e507c42001-07-17Martin Nilsson 
648eb42001-07-17Martin Nilsson  Stdio.stdout->write("</module>\n");
61fee92001-05-05Mirar (Pontus Hagland) }
5af3db2001-05-07Mirar (Pontus Hagland) void process_line(string s,string currentfile,int line)
084e452001-05-06Henrik Grubbström (Grubba) {
5af3db2001-05-07Mirar (Pontus Hagland)  s=getridoftabs(s); int i; if ((i=search(s,"**!"))!=-1 || (i=search(s,"//!"))!=-1) { string kw,arg; sscanf(s[i+3..],"%*[ \t]%[^: \t\n\r]%*[: \t]%s",kw,arg); if (keywords[kw]) { string err; if ( (err=keywords[kw](arg,"file='"+currentfile+"' line='"+line+"'")) ) {
648eb42001-07-17Martin Nilsson  report(currentfile+"file='"+currentfile+"' line="+line); exit(1);
5af3db2001-05-07Mirar (Pontus Hagland)  } } else if (s[i+3..]!="")
084e452001-05-06Henrik Grubbström (Grubba)  {
5af3db2001-05-07Mirar (Pontus Hagland)  string d=s[i+3..]; // sscanf(d,"%*[ \t]!%s",d); // if (search(s,"$Id")!=-1) report("Id: "+d); if (!descM) descM=methodM; if (!descM) {
648eb42001-07-17Martin Nilsson  report(currentfile+" line "+line+": illegal description position");
5af3db2001-05-07Mirar (Pontus Hagland)  exit(1); } if (!descM->desc) descM->desc=""; else descM->desc+="\n"; d=getridoftabs(d); descM->desc+=d;
084e452001-05-06Henrik Grubbström (Grubba)  }
5af3db2001-05-07Mirar (Pontus Hagland)  else if (descM)
084e452001-05-06Henrik Grubbström (Grubba)  {
5af3db2001-05-07Mirar (Pontus Hagland)  if (!descM->desc) descM->desc=""; else descM->desc+="\n";
084e452001-05-06Henrik Grubbström (Grubba)  }
5af3db2001-05-07Mirar (Pontus Hagland)  }
084e452001-05-06Henrik Grubbström (Grubba) }
e507c42001-07-17Martin Nilsson string safe_newlines(string in) { string old; do { old = in; in = replace(in, "\n\n", "\n \n"); } while(old!=in); return in; }
1d5f692001-07-25Martin Nilsson array(string) tag_quote_args(Parser.HTML p, mapping args) { return ({ sprintf("<%s%{ %s='%s'%}>", p->tag_name(), (array)args) }); } array(string) tag_preserve_ws(Parser.HTML p, mapping args, string c) { return ({ sprintf("<%s%{ %s='%s'%}>%s</%s>", p->tag_name(), (array)args, safe_newlines(p->clone()->finish(c)->read()), p->tag_name()) }); }
0a94502001-07-18Martin Nilsson void create() {
1d5f692001-07-25Martin Nilsson  parser = Parser.HTML(); Parser.HTML p = Parser.HTML(); parser->add_containers( ([ "pre":tag_preserve_ws, "table":tag_preserve_ws, "execute":tag_preserve_ws, "ul":tag_preserve_ws ]) ); parser->add_container("illustration", lambda(Parser.HTML p, mapping args, string c, string where) { c = replace(c, ([ "&gt;":">" ])); string name; sscanf(where, "file='%s'", name); name = (name/"/")[-1]; array err; object g; err = catch { g = compile_string(makepic1 + c + makepic2)(name+(illustration_counter++), args->type); }; if(err) { werror("%O\n", where); array rows = (makepic1+c+makepic2)/"\n"; werror("******\n"); for(int i; i<sizeof(rows); i++) werror("%04d: %s\n", i, rows[i]); werror("******\n"); throw(err); } return ({ g->make() }); }); parser->add_container("data_description", lambda(Parser.HTML p, mapping args, string c) { if(args->type=="mapping") { Parser.HTML i = Parser.HTML()-> add_container("elem", lambda(Parser.HTML p, mapping args, string c) { if(!args->type) throw("mkxml: Type attribute missing on elem tag."); if(args->type!="int" && args->type!="float" && args->type!="string") throw("mkxml: Unknown type "+args->type+" in elem type attribute.\n"); if(!args->name) throw("mkxml: Name attribute missing on elem tag."); return "<group>\n<member><type><" + args->type + "/></type><index>\"" + args->name + "\"</index></member>\n" "<text><p>" + c + "</p></text>\n</group>\n"; }); return ({ "<mapping>\n " + safe_newlines(i->finish(c)->read()) + "</mapping>\n " }); } throw("mkxml: Unknown data_description type "+args->type+".\n"); }); parser->add_tag("br",lambda(mixed...) { return ({"<br/>"}); }); parser->add_tag("wbr",lambda(mixed...) { return ({"<br/>"}); }); parser->add_tags( ([ "dl":tag_quote_args, "dt":tag_quote_args, "dd":tag_quote_args, "tr":tag_quote_args, "th":tag_quote_args, "td":tag_quote_args, "ref":tag_quote_args ]) ); parser->add_container( "text", lambda(Parser.HTML p,mapping args, string c) { c=p->clone()->finish(c)->read(); string res="<text><p>"+c+"</p></text>"; string t; do { t=res; res=replace(res,"<p></p>",""); res=replace(res,"<br/></p>","</p>"); } while (t!=res); return ({res}); }); parser->add_container("link", lambda(Parser.HTML p, mapping args, string c) { return ({ sprintf("<ref%{ %s=\"%s\"%}>%s</ref>", (array)args, c) }); }); parser->add_container("a", lambda(Parser.HTML p, mapping args, string c) { return ({ sprintf("<url%{ %s=\"%s\"%}>%s</url>", (array)args, c) }); }); parser->add_container("execute", lambda(Parser.HTML p, mapping args, string c) { return ({ c }); });
0a94502001-07-18Martin Nilsson  array tmp = __FILE__/"/"; string file = tmp[..sizeof(tmp)-2]*"/"; LENA_PATH = combine_path(file, LENA_PATH); makepic1 = #" string fn; void create(string _fn, void|string type) { fn = _fn; string ext; if(type==\"image/gif\") ext=\"gif\"; fn += \".\" + (ext||\"png\"); } object lena() { object i = Image.load(\"" + LENA_PATH + #"\"); return i; } object|string render() { "; makepic2 = #"; }
1d5f692001-07-25Martin Nilsson 
0a94502001-07-18Martin Nilsson  string make() { object|string o=render();
1d5f692001-07-25Martin Nilsson  if(objectp(o)) o=Image.PNG.encode(o);
61fee92001-05-05Mirar (Pontus Hagland) 
1d5f692001-07-25Martin Nilsson  Stdio.write_file(fn, o);
0a94502001-07-18Martin Nilsson  werror(\"Wrote %s.\\n\", fn);
1d5f692001-07-25Martin Nilsson  return \"<image>\"+fn+\"</image>\";
0a94502001-07-18Martin Nilsson  } ";
61fee92001-05-05Mirar (Pontus Hagland) 
0a94502001-07-18Martin Nilsson  nowM = parse;
61fee92001-05-05Mirar (Pontus Hagland) }