diff --git a/tutorial/Wmml.pmod b/tutorial/Wmml.pmod index 2bedb5771664714b60edc76e2c2586dc28857ca0..1f611165a2b12c261248d7e19a407c99f090d902 100644 --- a/tutorial/Wmml.pmod +++ b/tutorial/Wmml.pmod @@ -54,100 +54,104 @@ static private int verify_any(SGML data, } switch(x->tag) { - default: - werror("Unknown tag "+x->tag+" near "+x->location()+".\n"); - werror(in->dump()); - i=0; - break; - - case "font": - case "firstpage": - case "preface": - case "introduction": - - case "chapter": - case "appendix": - case "i": - case "b": - case "a": - case "anchor": - case "tt": - case "pre": - case "tr": - case "td": - case "table": - case "box": - case "h1": - case "h2": - case "h3": - case "dl": - case "ul": - case "section": - case "center": - case "ol": - case "encaps": - case "th": - case "illustration": - case "strong": - case "link": - - case "man_nb": - case "module": - case "class": - case "method": - case "variable": - case "function": - case "constant": - case "man_description": - case "man_see": - case "man_syntax": - case "man_bugs": - case "man_example": - case "man_title": - case "man_arguments": - case "man_returns": - case "man_note": - - case "ex_identifier": - case "ex_keyword": - case "ex_string": - case "ex_comment": - case "ex_meta": - case "example": + default: + werror("Unknown tag "+x->tag+" near "+x->location()+".\n"); + werror(in->dump()); + i=0; + break; + + case "font": + case "firstpage": + case "preface": + case "introduction": + + case "chapter": + case "appendix": + case "i": + case "b": + case "a": + case "anchor": + case "tt": + case "pre": + case "tr": + case "td": + case "table": + case "h1": + case "h2": + case "h3": + case "dl": + case "ul": + case "section": + case "center": + case "ol": + case "encaps": + case "th": + case "illustration": + case "link": + + case "exercises": + case "exercise": + + case "man_nb": + case "module": + case "class": + case "method": + case "variable": + case "function": + case "constant": + case "man_description": + case "man_see": + case "man_syntax": + case "man_bugs": + case "man_example": + case "man_title": + case "man_arguments": + case "man_returns": + case "man_note": + + case "ex_identifier": + case "ex_keyword": + case "ex_string": + case "ex_comment": + case "ex_meta": + case "example": + + case "data_description": + case "elem": // in data_description - case "aargdesc": - case "aarg": - case "adesc": - if(!x->data) - { - werror("Tag "+x->tag+" not closed near "+x->location()+".\n"); - werror(in->dump()); - i=0; - } - - break; + case "aargdesc": // in man_arguments + case "aarg": // in man_arguments + case "adesc": // in man_arguments + if(!x->data) + { + werror("Tag "+x->tag+" not closed near "+x->location()+".\n"); + werror(in->dump()); + i=0; + } - case "ex_indent": - case "ex_br": - case "include": - case "dt": - case "dd": - case "li": - case "ref": - case "hr": - case "br": - case "img": - case "image": - case "table-of-contents": - case "index": - if(x->data) - { - werror("Tag "+x->tag+" should not be closed near "+x->location()+"\n"); - werror(in->dump()); - i=0; - } - case "p": - case "wbr": + break; + + case "ex_indent": + case "ex_br": + case "include": + case "dt": + case "dd": + case "li": + case "ref": + case "hr": + case "br": + case "img": + case "image": + case "table-of-contents": + case "index": + if(x->data) + { + werror("Tag "+x->tag+" should not be closed near "+x->location()+"\n"); + werror(in->dump()); + i=0; + } + case "p": + case "wbr": } if(x->data) diff --git a/tutorial/html.pike b/tutorial/html.pike index ebc34c55732ff4eda449c88f34d1decd03e38b17..46b69e2d404c2ee7e232ba26206dd62d782ebcd6 100644 --- a/tutorial/html.pike +++ b/tutorial/html.pike @@ -335,6 +335,82 @@ int cpos; SGML wmml_to_html(SGML data); +SGML preify(SGML in,int id) +{ + array r=({}); + foreach (in,TAG z) + if (!stringp(z)) + if (z->tag=="br") + r+=({"\n"+" "*id}); + else + { + z->data=preify(z->data,id); + r+=({z}); + } + else + r+=({replace(z,"\n","")}); + return r; +} + +SGML data_description(mapping arg,int pos,array(object) data, + object orig) +{ + array d=({}); + // ({ type, name, value, pos, desc }) + // or ({ ?, 0, 0, pos, group description }) + + string type=arg->type||"",subtype=""; + sscanf(type,"%s(%s)",type,subtype); + + foreach (data,TAG data) + if (!stringp(data)) + switch (data->tag) + { + case "elem": + d+=({({data->params->type||subtype, /* 0 */ + data->params->name, /* 1 */ + data->params->value, /* 2 */ + data->pos, /* 3 */ + data->data})}); /* 4 */ + break; + default: + werror("Warning: Found tag "+data->tag+" in data_description" + +" (near "+data->location()+")\n"); + } + switch (type) + { + case "array": + { + SGML ret=({}); + int ns,id,nl,ins,n=0; + ins=strlen(""+sizeof(column(d,2)-({0})))+2; + ns=max(@Array.map(d, + lambda(array z) + { + return strlen(z[0]||"")+strlen(z[2]||""); + }))+1; + if (ns>30) id=8,nl=1; else id=ns+5+ins,nl=0; + foreach (d,array t) + if (t[2]) + { + ret+=({sprintf(" %-*s %*s ", + ns,t[0]+" "+t[2],ins,"["+n+"]")}); + ret+=({Sgml.Tag("i",([]),t[3], + (nl?({"\n"+" "*id}):({}))+ + preify(t[4],id)),"\n"}); + n++; + } + else /* group title */ + ret+=({" ",Sgml.Tag("b",([]),t[3],preify(t[4],id)),"\n"}); + return ({Sgml.Tag("pre",([]),pos,({"({\n"})+ret+({"})\n"}))}); + } + default: + werror("Warning: Illegal/unimplemented data type %O" + " (near "+orig->location()+")\n",type); + } + return ({}); +} + /* Partially destructive! */ SGML convert(SGML data) { @@ -418,6 +494,17 @@ SGML convert(SGML data) Sgml.Tag("br")})); continue; + case "exercises": + ret+=convert(({Sgml.Tag("box",([]),data->pos,data->data)})); + continue; + case "exercise": + ret+=convert(({Sgml.Tag("li",([]),data->pos,data->data)})); + continue; + + case "data_description": + ret+=data_description(data->params,data->pos,data->data,data); + continue; + case "ref": { string to=data->params->to; diff --git a/tutorial/tutorial.wmml b/tutorial/tutorial.wmml index 38d8d27e455faebb775615d3dd5ef36cc84d8e5c..e40399ab3235eabcb35c157c8f06e7eeb8806df3 100644 --- a/tutorial/tutorial.wmml +++ b/tutorial/tutorial.wmml @@ -863,24 +863,36 @@ to do as you continue to read this book. The complete listing of this example ca </section> <section title="Simple exercises"> -<box> -<ul> -<li> Make a program which writes hello world 10 times. -<li> Modify hello_world.pike to write the first argument to the program. -<li> Make a program that writes a hello_world program to stdout - when executed. -<li> Modify the register program to store data about programs and diskettes - instead of songs and records. -<li> Add code to the register program that checks that the user typed - an argument when required. The program should notify the user and - wait to receive more commands instead of exiting with an error message. -<li> Add code to the register program to check that the arguments to - <tt>show_record</tt> and <tt>delete_records</tt> are numbers. Also - make sure that the number isn't less than one or bigger than the - available number of records. -<li> Rewrite the register program and put all the code in main(). -</ul> -</box> +<exercises> +<exercise> + Make a program which writes hello world 10 times. +</exercise> +<exercise> + Modify hello_world.pike to write the first argument to the program. +</exercise> +<exercise> + Make a program that writes a hello_world program to stdout + when executed. +</exercise> +<exercise> + Modify the register program to store data about programs and diskettes + instead of songs and records. +</exercise> +<exercise> + Add code to the register program that checks that the user typed + an argument when required. The program should notify the user and + wait to receive more commands instead of exiting with an error message. +</exercise> +<exercise> + Add code to the register program to check that the arguments to + <tt>show_record</tt> and <tt>delete_records</tt> are numbers. Also + make sure that the number isn't less than one or bigger than the + available number of records. +</exercise> +<exercise> + Rewrite the register program and put all the code in main(). +</exercise> +</exercises> </section> </chapter> @@ -1184,22 +1196,28 @@ is run. </section> <section title=Exercises> - -<box> -<ul> -<li> End all functions in the examples in chapter two with a return statement. -<li> Change all <tt>foreach</tt> loops to <tt>for</tt> or <tt>while</tt> loops. -<li> Make the <tt>find_song</tt> function in chapter 2 return when the first +<exercises> +<exercise> + End all functions in the examples in chapter two with a return statement. +</exercise><exercise> + Change all <tt>foreach</tt> loops to <tt>for</tt> or <tt>while</tt> loops. +</exercise><exercise> + Make the <tt>find_song</tt> function in chapter 2 return when the first matching song is found. -<li> Make the <tt>find_song</tt> function write the number of the record +</exercise><exercise> + Make the <tt>find_song</tt> function write the number of the record the song is on. -<li> If you failed to get the program to work properly in the last exercise +</exercise><exercise> + If you failed to get the program to work properly in the last exercise of chapter 2, try it again now. -<li> Make a program that writes all the numbers from 1 to 1000. -<li> Modify the program in the previous exercise to NOT write numbers divisible by 3, 7 or 17. -<li> Make a program that writes all the prime numbers between 1 and 1000. -</ul> -</box> +</exercise><exercise> + Make a program that writes all the numbers from 1 to 1000. +</exercise><exercise> + Modify the program in the previous exercise to NOT write numbers divisible by 3, 7 or 17. +</exercise><exercise> + Make a program that writes all the prime numbers between 1 and 1000. +</exercise> +</exercises> </section> </chapter> @@ -3178,12 +3196,16 @@ expect, in which case you are better off not using operator overloading. </section> <section title="Simple exercises"> -<box> -<ul> -<li> Make a program that clones 10 hello world and then runs main() in +<exercises> +<exercise> + Make a program that clones 10 hello world and then runs main() in each one of them. -<li> Modify the register program to use an object for each record. -<li> Modify the register program to use the following search function: + +</exercise><exercise> + Modify the register program to use an object for each record. + +</exercise><exercise> + Modify the register program to use the following search function: <example language=pike> void find_song(string title) { @@ -3204,9 +3226,8 @@ expect, in which case you are better off not using operator overloading. if(!hits) write("Not found.\n"); } </example> - -</ul> -</box> +</exercise> +</exercises> <!-- FIXME add more examples above --> </section> </chapter> @@ -3501,21 +3522,28 @@ or like this: </section> <section title="Simple exercises"> -<box> -<ul> -<li> Save the hello_world.pike program as hello_world.pike.pmod, then make +<exercises> +<exercise> + Save the hello_world.pike program as hello_world.pike.pmod, then make a program that loads this module and calls its main(). -<li> Make a directory called <tt>Programs.pmod</tt> and put all the examples you + +</exercise><exercise> + Make a directory called <tt>Programs.pmod</tt> + and put all the examples you have written so far in it. Make a program that runs one of those programs. Make sure the program can be modified to run another of your examples by changing what module it loads. -<li> Copy the file hello_world.pike.pmod to programs/module.pike.pmod and + +</exercise><exercise> + Copy the file hello_world.pike.pmod to programs/module.pike.pmod and then write a program that runs hello_world without actually using the identifier <tt>hello_world</tt>. -<li> Try putting <tt>Programs.pmod</tt> in another directory and then try to + +</exercise><exercise> + Try putting <tt>Programs.pmod</tt> in another directory and then try to run the programs from the last two examples. -</ul> -</box> +</exercise> +</exercises> </section> </chapter> @@ -11198,21 +11226,20 @@ array(int) file->stat(); <man_description> file_stat returns an array of integers describing some properties<br> about the file. Currently file_stat returns 7 entries:<br> -<pre> + <data_description type=array(int)> <elem value=mode>file mode, protection bits etc. etc. </elem> <elem value=size>file size for regular files, <br> - -2 for dirs,<br> - -3 for links,<br> - -4 for otherwise </elem> +-2 for dirs,<br> +-3 for links,<br> +-4 for otherwise </elem> <elem value=atime>last access time </elem> <elem value=mtime>last modify time </elem> <elem value=ctime>last status time change </elem> <elem value=uid>The user who owns this file</elem> <elem value=gid>The group this file belongs to</elem> </data_description> -</pre> -</tt> + If you give 1 as a second argument, file_stat does not follow links.<br> You can never get -3 as size if you don't give a second argument.<br> @@ -11845,13 +11872,12 @@ first object in this list, and next_object(o) the next object in the list after o. </man_description> <man_example> -<pre> +<example language=pike> /* This example calls shutting_down() in all cloned objects */ object o; for(o=next_object();o;o=next_object(o)) o->shutting_down();<br> -</pre> -</dl> +</example> </man_example> <man_see> clone, destruct diff --git a/tutorial/wmml.wmml b/tutorial/wmml.wmml index 4415c50c24748d40b3cf625bd6d295e76402f8e7..31a42526372530bc8d50c2690cbe9d01710fb184 100644 --- a/tutorial/wmml.wmml +++ b/tutorial/wmml.wmml @@ -100,8 +100,8 @@ wbr <section title="reference markup tags"> -method name= title= module name= title= mansuffix= +method name= title= class name= title= constant name= title= function name= fullpath= title=