From 8ffe5aaafe7975a705f38f69eaadfeb0361c485e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Tue, 13 Jul 1999 01:46:21 -0700 Subject: [PATCH] moved graphics generation to separate file, WARNING: may not work 100% yet, be patient Rev: tutorial/Gfx.pmod:1.1 Rev: tutorial/Makefile:1.36 Rev: tutorial/Wmml.pmod:1.35 Rev: tutorial/extending.wmml:1.7 Rev: tutorial/html.pike:1.30 Rev: tutorial/latex.pike:1.5 Rev: tutorial/tutorial.wmml:1.124 Rev: tutorial/wmmltohtml2:1.12 --- tutorial/Gfx.pmod | 303 ++++++++++++++++++++++++++++++++++++ tutorial/Makefile | 4 +- tutorial/Wmml.pmod | 336 ---------------------------------------- tutorial/extending.wmml | 2 +- tutorial/html.pike | 20 ++- tutorial/latex.pike | 76 +++++---- tutorial/tutorial.wmml | 16 +- tutorial/wmmltohtml2 | 12 +- 8 files changed, 386 insertions(+), 383 deletions(-) create mode 100644 tutorial/Gfx.pmod diff --git a/tutorial/Gfx.pmod b/tutorial/Gfx.pmod new file mode 100644 index 0000000000..24c630b8cb --- /dev/null +++ b/tutorial/Gfx.pmod @@ -0,0 +1,303 @@ +/* This module contains low-level graphics functions + */ + + +int image_num; +mapping(string:array(string)) image_cache=([]); +mapping(string:string) illustration_cache=([]); + + +void save_image_cache() +{ + rm("illustration_cache"); + Stdio.write_file("illustration_cache", + encode_value( ({ + image_num, + image_cache, + illustration_cache, + }))); +} + +void create() +{ + if(file_stat("illustration_cache")) + { + [image_num,image_cache,illustration_cache]= + decode_value(Stdio.read_file("illustration_cache")); + } + werror("Illustration caches: %d %d\n",sizeof(image_cache), sizeof(illustration_cache)); +} + + +string cached_write(string data, string ext) +{ +// trace(1); + string key=ext+"-"+Crypto.md5()->update(data)->digest(); + +// werror("key=%O len=%d\n",key,strlen(data)); + + foreach(image_cache[key] || ({}),string file) + { + if(Stdio.read_file(file)==data) + { + werror("Cache hit in cached_write: "+file+"\n"); + return file; + } + } + + image_num++; + string filename="illustration"+image_num+"."+ext; + rm(filename); + werror("Writing "+filename+".\n"); + Stdio.write_file(filename,data); + + if(image_cache[key]) + image_cache[key]+=({filename}); + else + image_cache[key]=({filename}); + + save_image_cache(); + + return filename; +} + + +string mkgif(mixed o,void|mapping options) +{ +// werror(master()->describe_backtrace(({"FOO\n",backtrace()}))); + if(!options) options=([]); + string g= + stringp(o)?o: + options->alpha?Image.GIF.encode(o,options->alpha): + Image.GIF.encode(o); + + return cached_write(g,"gif"); +} + +string mkjpg(mixed o,void|mapping options) +{ + if(!options) options=([]); + string g=Image.JPEG.encode(o,options); + return cached_write(g,"jpg"); +} + + +string mkeps(mixed o,void|mapping options) +{ + if(!options) options=([]); + string g=Image.PS.encode(o, options); + return cached_write(g,"eps"); +} + +string mkpng(mixed o,void|mapping options) +{ + if(!options) options=([]); + string g=Image.PNG.encode(o); + return cached_write(g,"png"); +} + +mapping(string:Image.Image) srccache=([]); +Image.Image errimg=Image.image(10,10)->test(); + +Image.Image read_image(string file) +{ + if(!file) return 0; + +// werror("Reading %s ",file); + if(file[0]!='_' && srccache[file]) + { +// werror("(cached) "); + return srccache[file]; + } + + if( (file/".")[-1]=="fig" ) + { + Process.create_process(({"fig2dev","-L","ps",file,"___tmp.ps"}))->wait(); + Stdio.File("___tmp.ps","aw")->write("showpage\n"); +// Process.system("/bin/sh -c 'gs -q -sDEVICE=pbmraw -r225 -g2500x2500 -sOutputFile=___tmp.ppm ___tmp.ps </dev/null >/dev/null'"); + + Process.create_process(({"gs","-q","-sDEVICE=pbmraw","-r225","-g2500x2500","-sOutputFile=___tmp.ppm","___tmp.ps"}),(["stdin":Stdio.File("/dev/null","r"),"stdout":Stdio.File("/dev/null","w")]))->wait(); + object o=read_image("___tmp.ppm")->autocrop()->scale(1.0/3); //->rotate(-90); + o=Image.image(o->xsize()+40, o->ysize()+40, 255,255,255)->paste(o,20,20); + rm("___tmp.ps"); + rm("___tmp.ppm"); + if(o!=errimg) srccache[file]=o; + return o; + } + + string data=Stdio.read_file(file); + if(!data || !strlen(data)) + { + werror("\nFailed to read image %s\n\n",file); + return srccache[file]=errimg; + } + + catch { return srccache[file]=Image.GIF.decode(data); }; + catch { return srccache[file]=Image.JPEG.decode(data); }; + catch { return srccache[file]=Image.PNM.decode(data); }; + catch { return srccache[file]=Image.PNG.decode(data); }; + werror("\nFailed to decode image %s\n\n",file); + return srccache[file]=errimg; +} + +string write_image(string fmt, Image.Image o, void|float pic_dpi) +{ + switch(fmt) + { + case "gif": return mkgif(o); + case "jpg": return mkjpg(o); + case "eps": return mkeps(o, (["dpi":pic_dpi ])); + case "png": return mkpng(o); + default: + error("Unknown output format.\n"); + } +} + +string gettext(string s) +{ + string tmp=(s/".")[-1]; + if(tmp=="jpeg") tmp="jpg"; + return tmp; +} + + +string convert(mapping params, + string wanted_formats, + void|float wanted_dpi, + void|string filter) +{ + if(params->__from__) werror("[%s]",params->__from__); + if(!wanted_dpi) wanted_dpi=75.0; + string input=params->src; + array(string) tmp=input/"|"; + +// FIXME +// if(params->scale) wanted_dpi*=(float)params->scale; + + array(float) dpi = (array(float)) ( (params->dpi || "75.0" )/"|" ); + if(sizeof(dpi) < sizeof(tmp)) + tmp+=({ tmp[-1] }) * ( sizeof(tmp) - sizeof(dpi) ); + + mapping(string:string) ext_to_input=mkmapping(Array.map(tmp,gettext),tmp); + mapping(string:float) ext_to_dpi=mkmapping(Array.map(tmp,gettext),dpi); + + if(!filter) + { + string best; + float badness=100000.0; + + foreach(wanted_formats/"|", string fmt) + { + if(ext_to_input[fmt]) + { + float tmp=ext_to_dpi[fmt]-wanted_dpi; + if(tmp<0) tmp*=-5.0; + if(tmp < badness) + { + best=ext_to_input[fmt]; + badness=tmp; + } + } + } + if(best) return best; + } + + array(int) mtimes=column(Array.map(tmp, file_stat)-({0}), 3); + + string key=encode_value( aggregate ( + input, + dpi, + mtimes, + wanted_formats, + wanted_dpi, + filter)); + + if(illustration_cache[key]) + return illustration_cache[key]; + + + string primary_format=(wanted_formats/"|")[0]; + + + // FIXME: check dpi! + switch(primary_format) + { + case "eps": + if(ext_to_input->fig) + { + Process.create_process( ({"fig2dev","-L","ps","-m","0.6666666666",ext_to_input->xfig,"___tmp.eps" }))->wait(); + return illustration_cache[key]= + cached_write(Stdio.read_file("___tmp.eps"),"eps"); + } + break; + + case "tex": + if(ext_to_input->fig) + { + Process.create_process( ({"fig2dev","-L","latex",ext_to_input->xfig,"___tmp.tex" }))->wait(); + return illustration_cache[key]= + cached_write(Stdio.read_file("___tmp.tex"),"tex"); + } + } + + float pic_dpi=0.0; + Image.Image o; + for(int e=0;e<sizeof(tmp);e++) + { + if(dpi[e]<wanted_dpi) continue; + if(o=read_image(tmp[e])) + { + pic_dpi=dpi[e]; + break; + } + } + + if(!o) + { + sort(dpi,tmp); + tmp=reverse(tmp); + dpi=reverse(dpi); + + for(int e=0;e<sizeof(tmp);e++) + { + if(o=read_image(tmp[e])) + { + pic_dpi=dpi[e]; + break; + } + } + } + + if(!o) + { + error("Failed to read image!\n"); + } + + + + if(filter) + { + mixed err=catch { + o=compile_string("import Image;\n" + "mixed `()(object src) { "+filter+" ;}")()(o); + }; + if(err) + { + werror("This code caused an error: \n%s\n",filter); + throw(err); + } + } + + string ret; + foreach(wanted_formats/"|", string tmp) + { + if(!catch { + string ret=write_image(tmp, o, pic_dpi); + }) break; + } + illustration_cache[key]=ret; + save_image_cache(); + return ret; +} + + diff --git a/tutorial/Makefile b/tutorial/Makefile index 12d72eb410..b7abd328a7 100644 --- a/tutorial/Makefile +++ b/tutorial/Makefile @@ -87,8 +87,8 @@ the_image_module.html: Image.wmml the_image_module.wmml $(pike) ./wmmltohtml2 the_image_module.wmml mirar_html the_image_module clean: - -rm -f *.html *.md illustration_cache illustration*.gif $(MADEFILES) - -rm -f tutorial.dvi tutorial.tex tutorial.aux illustration*.eps + -rm -f *.html *.md illustration_cache illustration*.* $(MADEFILES) + -rm -f tutorial.dvi tutorial.tex tutorial.aux -rm -f tutorial.log tutorial.toc rebuild: diff --git a/tutorial/Wmml.pmod b/tutorial/Wmml.pmod index 26ff506e2f..e4b3ff400b 100644 --- a/tutorial/Wmml.pmod +++ b/tutorial/Wmml.pmod @@ -1054,210 +1054,7 @@ SGML unlink_unknown_links(SGML data, mapping known_links) } -void save_image_cache(); -int gifnum; -mapping gifcache=([]); -mapping jpgcache=([]); -mapping epscache=([]); -mapping srccache=([]); - -string mkgif(mixed o,void|object alpha) -{ - string g= - stringp(o)?o: - alpha?Image.GIF.encode(o,alpha): - Image.GIF.encode(o); - - int key=hash(g); - - foreach(gifcache[key]||({}),string file) - { - if(Stdio.read_file(file)==g) - { - werror("Cache hit in mkgif: "+file+"\n"); - return file; - } - } - - gifnum++; - string gifname="illustration"+gifnum+".gif"; - rm(gifname); - werror("Writing "+gifname+".\n"); - Stdio.write_file(gifname,g); - - if(gifcache[key]) - gifcache[key]+=({gifname}); - else - gifcache[key]=({gifname}); - - return gifname; -} - -string mkeps(mixed o,float dpi) -{ - string g=Image.PS.encode(o, (["dpi":dpi]) ); - - int key=hash(g); - - foreach(epscache[key]||({}),string file) - { - if(Stdio.read_file(file)==g) - { - werror("Cache hit in mkeps: "+file+"\n"); - return file; - } - } - - gifnum++; - string epsname="illustration"+gifnum+".eps"; - rm(epsname); - werror("Writing "+epsname+".\n"); - Stdio.write_file(epsname,g); - - if(epscache[key]) - epscache[key]+=({epsname}); - else - epscache[key]=({epsname}); - - return epsname; -} - -string mkjpeg(mixed o,void|int quality) -{ - string g=Image.JPEG.encode(o,(["quality":quality||100])); - - int key=hash(g); - - foreach(jpgcache[key]||({}),string file) - { - if(Stdio.read_file(file)==g) - { - werror("Cache hit in mkjpeg: "+file+"\n"); - return file; - } - } - - gifnum++; - string gifname="illustration"+gifnum+".jpeg"; - rm(gifname); - werror("Writing "+gifname+".\n"); - Stdio.write_file(gifname,g); - - if(jpgcache[key]) - jpgcache[key]+=({gifname}); - else - jpgcache[key]=({gifname}); - - return gifname; -} - -Image.Image read_image(string file) -{ - string data=Stdio.read_file(file); - catch { return Image.GIF.decode(data); }; - catch { return Image.JPEG.decode(data); }; - catch { return Image.PNM.decode(data); }; - werror("\nFailed to read image %s\n\n",file); - return Image.image(10,10)->test(); -} - -// -// Execute a small pice of pike code to generate an illustration. -// -object render_illustration(string pike_code, mapping params, float wanted_dpi) -{ - werror("Rendering "); - if (params->__from__) werror("["+params->__from__+"] "); - string src=params->src; - object img=Image.image(); - - float actual_dpi=75.0; - if(params->dpi) actual_dpi=(float)params->dpi; - if(params->scale) wanted_dpi*=(float)params->scale; - float scale=wanted_dpi/actual_dpi; - - if(params->src) - img=srccache[params->src]|| - (srccache[params->src]= - read_image(params->src)); - if(scale!=1.0) img=img->scale(scale); - return compile_string("import Image;\n" - "mixed `()(object src){ "+pike_code+" ; }")()(img); -} - -private static string mkkey(mapping params, mixed ... other) -{ - params+=([]); - m_delete(params,"align"); - m_delete(params,"alt"); - m_delete(params,"__from__"); - if(params->src) - if(mixed x=file_stat(params->src)) - params->mtime=(string)(x[3]); - string *keys=indices(params); - string *values=values(params); - sort(keys,values); - - return encode_value( ({keys,values,other}) ); -} - -mapping illustration_cache=([]); -string illustration_to_gif(TAG data, float dpi) -{ - mapping params=data->params; - string pike_code=data->data[0]; - string key=mkkey(params,pike_code,dpi,"gif"); - - string ret=illustration_cache[key]; - if(!ret) - { - mixed err=catch - { - ret=mkgif(render_illustration(pike_code,params, dpi)); - illustration_cache[key]=ret; - save_image_cache(); - }; - if (err) - { - werror("error while compiling and running\n"+pike_code+"\n"); - if (params->__from__) - werror("from "+params->__from__+":\n"); - werror(master()->describe_backtrace(err)+"\n"); - return "failed to illustrate..."; - } - } - return ret; -} - - -string illustration_to_eps(TAG data, float dpi) -{ - mapping params=data->params; - string pike_code=data->data[0]; - string key=mkkey(params,pike_code,dpi,"eps"); - - string ret=illustration_cache[key]; - if(!ret) - { - mixed err=catch - { - ret=mkeps(render_illustration(pike_code,params, dpi), dpi); - illustration_cache[key]=ret; - save_image_cache(); - }; - if (err) - { - werror("error while compiling and running\n"+pike_code+"\n"); - if (params->__from__) - werror("from "+params->__from__+":\n"); - werror(master()->describe_backtrace(err)+"\n"); - return "error.eps"; - } - } - return ret; - -} array execute_contents(Tag tag) { @@ -1265,16 +1062,6 @@ array execute_contents(Tag tag) data=replace(data,"\n<p>","\n"); - add_constant("illustration", - lambda(object o,void|object alpha) - { - return Sgml.Tag("image",(["gif":mkgif(o,alpha)]),0); - }); - add_constant("illustration_jpeg", - lambda(object o,void|object alpha) - { - return Sgml.Tag("image",(["jpeg":mkjpeg(o,alpha)]),0); - }); add_constant("mktag", lambda(string name,void|mapping arg,void|mixed cont) { @@ -1366,127 +1153,4 @@ array execute_contents(Tag tag) } -// FIXME: handle EPS input -string image_to_gif(TAG data, float dpi) -{ - mapping params=data->params; - - if(params->gif) - return params->gif; - - if(params->jpeg) - return params->jpeg; - - if(params->xfig) - params->src=params->xfig+".fig"; - - string key=mkkey(params,dpi,"gif"); - - string ret=illustration_cache[key]; - if(!ret) - { - if(!params->src) - { - werror("Image without source near "+data->location()+".\n"); - return ""; - } - string ext=reverse(params->src); - sscanf(ext,"%s.",ext); - switch(reverse(ext)) - { - case "fig": - werror("Converting "); - Process.system("/bin/sh -c 'fig2dev -L ps "+params->src+" ___tmp.ps;echo showpage >>___tmp.ps'"); - Process.system("/bin/sh -c 'gs -q -sDEVICE=pbmraw -r225 -g2500x2500 -sOutputFile=___tmp.ppm ___tmp.ps </dev/null >/dev/null'"); - object o=Image.PNM.decode(Stdio.read_file("___tmp.ppm"))->autocrop()->scale(1.0/3); //->rotate(-90); - o=Image.image(o->xsize()+40, o->ysize()+40, 255,255,255)->paste(o,20,20); - rm("___tmp.ps"); - rm("___tmp.ppm"); - ret=mkgif(o); - break; - - default: - ret=mkgif(render_illustration("return src",params,dpi)); - break; - } - - illustration_cache[key]=ret; - save_image_cache(); - } - return ret; -} - -// FIXME: move all graphics stuff into a separate module -string image_to_eps(TAG data, float dpi) -{ - mapping params=data->params; - - if(params->eps) - return params->eps; - - if(params->jpeg) - params->src=params->jpeg; - - if(params->gif) - params->src=params->gif; - - if(params->xfig) - params->src=params->xfig+".fig"; - - string key=mkkey(params,dpi,"eps"); - - string ret=illustration_cache[key]; - if(!ret) - { - if(!params->src) - { - throw( ({"Image without source near "+data->location()+".\n", - backtrace() }) ); - } - string ext=reverse(params->src); - sscanf(ext,"%s.",ext); - switch(reverse(ext)) - { - case "fig": - werror("Converting "); - ret="illustration"+ (++gifnum) +".eps"; - Process.create_process( ({"fig2dev","-L","ps","-m","0.6666666666",params->src,ret }))->wait(); - break; - - default: - ret=mkeps(render_illustration("return src",params,dpi),dpi); - break; - } - - illustration_cache[key]=ret; - save_image_cache(); - } - return ret; -} - -void save_image_cache() -{ - rm("illustration_cache"); - Stdio.write_file("illustration_cache", - encode_value(([ - "gifnum":gifnum, - "gifcache":gifcache, - "jpgcache":gifcache, - "epscache":gifcache, - "illustration_cache":illustration_cache, - ]))); -} - -void create() -{ - if(file_stat("illustration_cache")) - { - mixed x=decode_value(Stdio.read_file("illustration_cache")); - gifnum=x->gifnum; - gifcache=x->gifcache; - jpgcache=x->jpgcache; - epscache=x->epscache; - illustration_cache=x->illustration_cache; - } -} diff --git a/tutorial/extending.wmml b/tutorial/extending.wmml index 8367658627..0d94c709bf 100644 --- a/tutorial/extending.wmml +++ b/tutorial/extending.wmml @@ -740,7 +740,7 @@ Below is an illustration which shows an example of a small mapping with hash table, free list and key-index pairs. <center> -<image xfig=mapping-internals> +<image src=mapping-internals.fig> </center> As you can see, mappings uses a linked list for each bucket in the diff --git a/tutorial/html.pike b/tutorial/html.pike index de4f0b1876..741315a867 100644 --- a/tutorial/html.pike +++ b/tutorial/html.pike @@ -41,6 +41,7 @@ string mklinkname(string section) TAG mkimgtag(string file, mapping params) { + if(!file) return "<!-- error, no file -->"; mapping p=([]); p->src=file; if(params->align) p->align=params->align; @@ -820,11 +821,12 @@ SGML convert(SGML data) break; case "illustration": - ret+=({ mkimgtag(Wmml.illustration_to_gif(data,75.0),data->params) }); - continue; - case "image": - ret+=({ mkimgtag(Wmml.image_to_gif(data,75.0),data->params) }); + ret+=({ mkimgtag(Gfx.convert(data->params, + "jpg|gif", + 75.0, + data->data && Sgml.get_text(data->data)),data->params) + }); continue; case "box": @@ -1196,3 +1198,13 @@ void output(string base, WMML data) werror(" done\n"); } } + +Sgml.Tag illustration(object o,void|mapping options) +{ + return Sgml.Tag("image",(["src":Gfx.mkgif(o,options)]),0); +} + +Sgml.Tag illustration_jpeg(object o,void|mapping options) +{ + return Sgml.Tag("image",(["src":Gfx.mkjpg(o,options)]),0); +} diff --git a/tutorial/latex.pike b/tutorial/latex.pike index 60fb8c6ae3..362f9132fd 100644 --- a/tutorial/latex.pike +++ b/tutorial/latex.pike @@ -47,6 +47,8 @@ string quote_label(string s) } + + float weighted_strlen(string tag) { return strlen(tag)+ @@ -191,23 +193,18 @@ string convert_table(TAG table) return ret; } -string convert_image_to_latex(TAG tag) +string convert_gfx(Sgml.Tag tag) { - mapping params=tag->params; - if(params->xfig) - params->src=params->xfig+".fig"; + string file=Gfx.convert( tag->params, + "tex|eps", + 300.0, + tag->data && Sgml.get_text(tag->data)); - if(params->src && (params->src/".")[-1]=="fig") + switch( (file/".")[-1]=="." ) { - rm("___tmp.latex"); - werror("Converting fig->latex"); - Process.create_process( ({ "fig2dev", "-L","latex",params->src,"___tmp.latex" }) )->wait(); - string ret=Stdio.read_file("___tmp.latex"); - rm("___tmp.latex"); - return ret; - }else{ - string file=Wmml.image_to_eps(tag,600.0); - return "\\epsfbox{"+file+"}"; + case "tex": return "\\input{"+file+"}"; + case "eps": return "\\epsfbox{"+file+"}"; + default: return "\\epsfbox{error.eps}"; } } @@ -608,12 +605,10 @@ string convert_to_latex(SGML data, void|int flags) ret+=convert_to_latex(tag->data); break; - case "image": - ret+="\\epsfbox{"+Wmml.image_to_eps(tag,75.0)+"}"; - break; - + case "img": // FIXME ?? case "illustration": - ret+="\\epsfbox{"+Wmml.illustration_to_eps(tag,75.0)+"}"; + case "image": + ret+=convert_gfx(tag); break; default: @@ -634,17 +629,9 @@ string convert_to_latex(SGML data, void|int flags) } -void output(string base, WMML data) +string package(string x) { - global_data=data; - string x=convert_to_latex(data->data); - - x=replace(x, - "\\verb+ +\\verb+ +", - "\\verb+ +" - ); - - x=#" + return #" \\documentclass[twoside,a4paper]{book} \\usepackage{isolatin1} \\usepackage{latexsym} % For $\Box$ @@ -662,11 +649,38 @@ void output(string base, WMML data) "+ x+ "\\end{document}\n"; - rm(base+".tex"); - Stdio.write_file(base+".tex",x); +} + +string extention=".tex"; + +void output(string base, WMML data) +{ + global_data=data; + string x=convert_to_latex(data->data); + + x=replace(x, + "\\verb+ +\\verb+ +", + "\\verb+ +" + ); + + x=package(x); + + rm(base+extention); + Stdio.write_file(base+extention,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 line %d (%d characters).\n",linenum[-1],lenghts[-1]); } + + +Sgml.Tag illustration(object o,void|mapping options) +{ + return Sgml.Tag("image",(["src":Gfx.mkeps(o,options)]),0); +} + +Sgml.Tag illustration_jpeg(object o,void|mapping options) +{ + return Sgml.Tag("image",(["src":Gfx.mkeps(o,options)]),0); +} diff --git a/tutorial/tutorial.wmml b/tutorial/tutorial.wmml index dcb257f8a2..da15b2b6d2 100644 --- a/tutorial/tutorial.wmml +++ b/tutorial/tutorial.wmml @@ -149,7 +149,7 @@ this comment can be erased. <h1> Programming, using and understanding <p> -<img src=pike.gif> +<img src=pike.gif> <!-- FIXME: hi-res version for Latex --> <p> <font size=+7>Pike</font> <p> @@ -1636,7 +1636,7 @@ which creates a new array. Figure 4.1 shows how the schematics of an array. As you can see, it is a very simple memory structure. <p> <center> -<image xfig=array><br> +<image src=array.fig><br> fig 4.1 </center> <p> @@ -1770,7 +1770,7 @@ What makes mappings special is that they can be indexed on other things than integers. We can imagine that a mapping looks like this: <p> <center> -<image xfig=mapping><br> +<image src=mapping.fig><br> fig 4.2 </center> <p> @@ -1862,7 +1862,7 @@ A multiset is almost the same thing as a mapping. The difference is that there are no values: <p> <center> -<image xfig=multiset><br> +<image src=multiset.fig><br> fig 4.3 </center> <p> @@ -1897,7 +1897,7 @@ space needed to execute the code in the program is stored in an <tt>object</tt> which is the next data type we will discuss. <p> <center> - <image xfig=program><br> + <image src=program.fig><br> fig 4.4 </center> Writing a <tt>program</tt> is easy, in fact, every example we have tried so @@ -2038,7 +2038,7 @@ with a reference to the program from which it was cloned. Many objects can be made from one program. The <tt>program</tt> outlines where in the object different variables are stored. <center> - <image xfig=object><br> + <image src=object.fig><br> fig 4.5 </center> Each object has its own set of variables, and when calling a function in that @@ -2132,7 +2132,7 @@ When indexing an object on a string, and that string is the name of a function in the object a <tt>function</tt> is returned. Despite its name, a <tt>function</tt> is really a <b>function pointer</b>. <center> - <image xfig=function><br> + <image src=function.fig><br> fig 4.6 </center> @@ -3142,7 +3142,7 @@ in front of the function name. The argument to inherit can be one of the followi Let's look at an example. We'll split up an earlier example into three parts and let each inherit the previous part. It would look something like this: <center> -<image xfig=inherit><br> +<image src=inherit.fig><br> </center> Note that the actual code is not copied, only the list of references. Also note that the list of inherits is copied when you inherit a program. diff --git a/tutorial/wmmltohtml2 b/tutorial/wmmltohtml2 index fd9ceb390a..927bfaabea 100755 --- a/tutorial/wmmltohtml2 +++ b/tutorial/wmmltohtml2 @@ -8,7 +8,13 @@ import "."; #include "types.h" int main(int argc, string *argv) -{ +{ +#if constant(signal) + signal(signum("SIGQUIT"),lambda() + { + master()->handle_error( ({"\nSIGQUIT recived, printing backtrace and continuing.\n",backtrace() }) ); + }); +#endif random_seed(0); // increase cache hit potential mixed *ER=catch { @@ -16,6 +22,10 @@ int main(int argc, string *argv) if (!output) error("can't cast %O to program\n",argv[2]); object out=output(); if (!out->output) error("%O doesn't have an output method",argv[2]); + + add_constant("illustration",out->illustration); + add_constant("illustration_jpeg",out->illustration_jpeg); + werror("Reading "); string input=Stdio.read_file(argv[1]); werror("Lexing "); -- GitLab