From 8d8049be4641b66526db23a053119aee8096875e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Tue, 6 Jul 1999 03:05:27 -0700 Subject: [PATCH] latex.pike now generates a (unfinished) table of contents and a half-working index Rev: tutorial/.cvsignore:1.14 Rev: tutorial/Makefile:1.33 Rev: tutorial/Wmml.pmod:1.34 Rev: tutorial/html.pike:1.28 Rev: tutorial/latex.pike:1.4 --- tutorial/.cvsignore | 1 + tutorial/.gitignore | 1 + tutorial/Makefile | 1 + tutorial/Wmml.pmod | 134 ++++++++++++++++++++++++++++++++++++- tutorial/html.pike | 14 +++- tutorial/latex.pike | 158 +++++++++++++++++++++++++++++++++++++++++--- 6 files changed, 296 insertions(+), 13 deletions(-) diff --git a/tutorial/.cvsignore b/tutorial/.cvsignore index 585375328d..cb9c820fd1 100644 --- a/tutorial/.cvsignore +++ b/tutorial/.cvsignore @@ -19,5 +19,6 @@ tutorial.dvi tutorial.html tutorial.log tutorial.mif +tutorial.pdf tutorial.tex tutorial_*.html diff --git a/tutorial/.gitignore b/tutorial/.gitignore index 1e8f91b7dd..cc2a927602 100644 --- a/tutorial/.gitignore +++ b/tutorial/.gitignore @@ -19,5 +19,6 @@ /tutorial.html /tutorial.log /tutorial.mif +/tutorial.pdf /tutorial.tex /tutorial_*.html diff --git a/tutorial/Makefile b/tutorial/Makefile index 4ab3ab413b..864e7d871d 100644 --- a/tutorial/Makefile +++ b/tutorial/Makefile @@ -57,6 +57,7 @@ tutorial.tex: .DUMMY $(SRCFILES) tutorial.dvi: tutorial.tex -@rm tutorial.aux latex tutorial.tex + latex tutorial.tex tutorial.ps: tutorial.dvi dvips -Z tutorial.dvi diff --git a/tutorial/Wmml.pmod b/tutorial/Wmml.pmod index 5817495d68..26ff506e2f 100644 --- a/tutorial/Wmml.pmod +++ b/tutorial/Wmml.pmod @@ -209,6 +209,13 @@ INDEX_DATA collect_index(SGML data, void|INDEX_DATA index,void|mapping taken) if(string real_name=data->params->name) { string new_name=real_name; + + if(!strlen(new_name)) + { + werror("Empty link name in <anchor> at %s\n",data->location()); + continue; + } + if(taken[new_name]) { @@ -226,6 +233,8 @@ INDEX_DATA collect_index(SGML data, void|INDEX_DATA index,void|mapping taken) }else{ index[real_name]=({new_name}); } + }else{ + werror("<anchor> without name near %s\n",data->location()); } } if(data->data) @@ -278,8 +287,14 @@ INDEX group_index_by_character(INDEX i) foreach(indices(i),string key) { int c; - sscanf(lower_case(Html.unquote_param(key)),"%*[_ ]%c",c); - string char=upper_case(sprintf("%c",c)); + string char; + if(sscanf(lower_case(Html.unquote_param(key)),"%*[_ ]%c",c)==2) + { + char=upper_case(sprintf("%c",c)); + }else{ + char=""; + } + // werror(char +" : "+key+"\n"); if(!m[char]) m[char]=([]); m[char][key]=i[key]; @@ -440,10 +455,20 @@ object(Tag) parse_pike_code(string x, // output generator. class Wmml { + // Header data SGML metadata; + + // Table of contents TOC toc; + + // Index INDEX_DATA index_data; + + // Concrete WMML data SGML data; + + // Link name to tag mapping + mapping(string:TAG) links; }; // Enumerators are used to give numbers to chapters, @@ -921,9 +946,114 @@ object(Wmml) make_concrete_wmml(SGML data) ret->index_data=collect_index(ret->data); ret->toc=toker->query(); ret->metadata=metadata; + collect_links(ret->data,ret->links=([])); + ret->data=unlink_unknown_links(ret->data,ret->links); + + return ret; +} + +// These routines are meant to create a mapping from a link name +// to the corresponding TAG. + +int useful_tag(TAG t) +{ + return !stringp(t) || sscanf(t,"%*[ \n\r\t�]%*c")==2; +} + +TAG get_tag(TAG t) +{ + while(1) + { + switch(t->tag) + { + default: return t; + + case "a": + case "anchor": + } + if(!t->data) return t; + + SGML x=Array.filter(t->data,useful_tag); + if(sizeof(x)==1 && objectp(t->data[0])) + t=t->data[0]; + else + break; + } + + return t; +} + +// must be called after Wmml has been made concrete +void collect_links(SGML data, mapping known_links) +{ + foreach(data,TAG t) + { + if(objectp(t)) + { + if(t->tag == "anchor") + { + if(t->params->name) + { + known_links[t->params->name]=get_tag(t); + } + } + + if(t->data) + collect_links(t->data,known_links); + } + } +} + +// This finds nonworking links and makes them non-links, +// this way the output controller doesn't have to worry +// about broken links. +SGML unlink_unknown_links(SGML data, mapping known_links) +{ + SGML ret=({}); + + foreach(data,TAG t) + { + if(objectp(t)) + { + switch(t->tag) + { + case "ref": + if(!t->params->to) + { + werror("<ref> without to= at %s\n",t->location()); + continue; + } + if(!known_links[t->params->to]) + { + werror("<ref to=> broken link at %s\n",t->location()); + continue; + } + break; + + case "link": + if(!t->params->to) + { + werror("<ref> without to= at %s\n",t->location()); + ret+=unlink_unknown_links(t->data || ({}),known_links); + continue; + } + if(!known_links[t->params->to]) + { + werror("<ref to=> broken link at %s\n",t->location()); + ret+=unlink_unknown_links(t->data || ({}),known_links); + continue; + } + } + + if(t->data) + t->data=unlink_unknown_links(t->data,known_links); + } + ret+=({t}); + } return ret; } + void save_image_cache(); int gifnum; diff --git a/tutorial/html.pike b/tutorial/html.pike index 772c7c637e..d1ed084569 100644 --- a/tutorial/html.pike +++ b/tutorial/html.pike @@ -279,7 +279,7 @@ int count_index_lines(SGML z) return ret; } -SGML index_to_wmml(INDEX data) +SGML index_to_wmml_low(INDEX data) { SGML ret=({}); foreach(srt(indices(data)-({0})),string key) @@ -296,7 +296,19 @@ SGML index_to_wmml(INDEX data) }); } } + return ret; +} +SGML index_to_wmml_onecol(INDEX data) +{ + SGML ret=index_to_wmml_low(data); + return ({ Sgml.Tag("dl",([]),0,ret) }); +} + +SGML index_to_wmml(INDEX data) +{ + SGML ret=index_to_wmml_low(data); + #if 1 int total_lines=count_index_lines(ret); // werror("\nTOTAL LINES: %d\n",total_lines); diff --git a/tutorial/latex.pike b/tutorial/latex.pike index b61069cf53..60fb8c6ae3 100644 --- a/tutorial/latex.pike +++ b/tutorial/latex.pike @@ -6,6 +6,8 @@ inherit Stdio.File : out; object html=.html(); +WMML global_data; + string low_latex_quote(string text) { return replace( text, @@ -35,6 +37,15 @@ string latex_quote(string text) return low_latex_quote( pre ? text : ((text/"\n") - ({""})) *"\n" ); } +string quote_label(string s) +{ + string ret=""; + while(sscanf(s,"%[_a-zA-Z0-9.:]%c%s",string safe, int char, s)==3) + ret+=sprintf("%s-%02x",safe,char); + ret+=s; + return ret; +} + float weighted_strlen(string tag) { @@ -65,6 +76,24 @@ float aproximate_length(SGML data) return len; } +string mkref(string label) +{ + if(!global_data->links[label]) + { + return "\\pageref{"+quote_label(label)+"}"; + } + switch(global_data->links[label]->tag) + { + case "chapter": + case "section": + case "appendix": + return global_data->links[label]->tag+" \\ref{"+quote_label(label)+"}"; + + default: + return "\\pageref{"+quote_label(label)+"}"; + } +} + string convert_table(TAG table) { SGML data=table->data; @@ -134,6 +163,7 @@ string convert_table(TAG table) if(border) ret+="\\hline \\\\\n"; + in_table++; foreach(data, TAG tag) { int c=0; @@ -154,6 +184,7 @@ string convert_table(TAG table) ret+=row*" & "+"\\\\\n"; if(border) ret+="\\hline\n"; } + in_table--; ret+="\\end{longtable}\n"; @@ -180,9 +211,95 @@ string convert_image_to_latex(TAG tag) } } +string *srt(string *x) +{ + string *y=allocate(sizeof(x)); + for(int e=0;e<sizeof(y);e++) + { + y[e]=lower_case(x[e]); + sscanf(y[e],"%*[ ,./_]%s",y[e]); + } + sort(y,x); + return x; +} + +string low_index_to_latex(INDEX data, string prefix, string indent) +{ +// werror("%O\n",data); + string ret=""; + foreach(srt(indices(data)-({0})),string key) + { + ret+="\\item \\verb+"+indent+"+"; + + if(data[key][0]) + { + ret+=latex_quote(Html.unquote_param(key)); + if(data[key][0][prefix+key]) + { + // FIXME: show all links + ret+=", \\pageref{"+quote_label(data[key][0][prefix+key][0])+"}\n"; + } + ret+="\n"; + + foreach(srt(indices(data[key][0])), string key2) + { + if(key2==prefix+key) continue; + ret+="\\item \\verb+"+indent+" +"; + ret+=latex_quote(Html.unquote_param(key2)); + ret+=", \\pageref{"+quote_label(data[key][0][key2][0])+"}\n"; + } + + }else{ + ret+=latex_quote(Html.unquote_param(key))+"\n"; + } + + if(sizeof(data[key]) > !!data[key][0]) + { + ret+=low_index_to_latex(data[key],prefix+key+".",indent+" "); + } + } + + return ret; +} + + +// FIXME: +// End chapter / appendix!! +// Too long symbols, fix linebreaking or do not use +// two-column mode... +string index_to_latex(INDEX foo) +{ + string ret=""; + ret+="\n\\twocolumn[\\begin{Huge}Index\\end{Huge}]\n\\begin{small}\n"; + +// ret+="\\begin{Huge}Index\\end{Huge}\n\n"; + + INDEX data=Wmml.group_index(foo); + data=Wmml.group_index_by_character(data); + + ret+="\\begin{list}{}{}\n"; + + foreach(srt(indices(data)-({0})),string key) + { + if(sizeof(data[key]) > !!data[key][0]) + { + ret+="\n\\item \\begin{large}"+ + latex_quote(key)+ + "\\end{large}\n"; + + ret+=low_index_to_latex(data[key],""," "); + } + } + ret+="\\end{list}\n"; + ret+="\n\\end{small}\n\\onecolumn\n"; + return ret; +} + + int depth; int appendixes; int pre; +int in_table; constant FLAG_TABLE=1; constant FLAG_LIST=2; @@ -248,7 +365,7 @@ string convert_to_latex(SGML data, void|int flags) case "chapter": depth++; - ret+="\\cleardoublepage \\section{"+ + ret+="\\chapter{"+ latex_quote(tag->params->title)+"}\n"+ convert_to_latex(tag->data); depth--; @@ -261,7 +378,7 @@ string convert_to_latex(SGML data, void|int flags) appendixes=1; } depth++; - ret+="\\cleardoublepage \\section{"+ + ret+="\\chapter{"+ latex_quote(tag->params->title)+"}\n"+ convert_to_latex(tag->data); depth--; @@ -299,6 +416,17 @@ string convert_to_latex(SGML data, void|int flags) ret+=convert_to_latex(tag->data); break; + case "table-of-contents": + ret+="\\tableofcontents \\newpage\n"; + break; + + case "index": + { + ret+=index_to_latex(global_data->index_data); + + break; + } + case "pre": if(pre) { @@ -315,7 +443,8 @@ string convert_to_latex(SGML data, void|int flags) case "encaps": // FIXME: Manual should not really use <encaps> - ret+=convert_to_latex(tag->data); + ret+="\\begin{scshape}"+convert_to_latex(tag->data)+ + "\\end{scshape}"; break; case "bloackquote": @@ -405,11 +534,16 @@ string convert_to_latex(SGML data, void|int flags) case "link": // FIXME -// if(tag->params->to) + // (la)tex doesn't like having too many links on one + // page. We need to not do this for see-also links. + // To do this we need to put hints in the concrete wmml +// if(tag->params->to && !in_table) // { // ret+= // convert_to_latex(tag->data)+ -// "\\marginpar{See "+latex_quote(tag->params->to)+"}"; +// "\\marginpar{See \\ref{"+ +// quote_label(tag->params->to)+"} \\pageref{"+ +// quote_label(tag->params->to)+"}.}"; // }else{ ret+=convert_to_latex(tag->data); // } @@ -426,10 +560,9 @@ string convert_to_latex(SGML data, void|int flags) if(flags & FLAG_LIST) ret+="\\item "; else - ; // FIXME, insert filled circle + ret="$\\bullet$ "; break; - case "ol": ret+="\\begin{enumerate} "+ convert_to_latex(tag->data,FLAG_LIST)+ @@ -438,14 +571,15 @@ string convert_to_latex(SGML data, void|int flags) case "anchor": // FIXME labels causes tex stack overflow!! -// ret+="\\label{"+latex_quote(tag->params->name)+"}"; + ret+="\\label{"+quote_label(tag->params->name)+"}"; ret+=convert_to_latex(tag->data); break; case "ref": // FIXME: must find out what type of object we are // referencing!! - ret+="\\ref{"+tag->params->to+"}"; + + ret+=mkref(tag->params->to); break; @@ -502,6 +636,7 @@ string convert_to_latex(SGML data, void|int flags) void output(string base, WMML data) { + global_data=data; string x=convert_to_latex(data->data); x=replace(x, @@ -529,6 +664,9 @@ void output(string base, WMML data) "\\end{document}\n"; rm(base+".tex"); Stdio.write_file(base+".tex",x); + array(string) lines=x/"\n"; + array(int) linenum=indices("x"*sizeof(lines)); + array(int) lenghts=sort(Array.map(lines,strlen),linenum,lines); - werror("Longest line is %d characters.\n",sort(Array.map(x/"\n",strlen))[-1]); + werror("Longest line is line %d (%d characters).\n",linenum[-1],lenghts[-1]); } -- GitLab