Commit 8cc7d01a34c9b6a90095babe6c899b67ed513b69

Authored by Alain Prouté
1 parent 732f1785

Preliminary version of MAML4. Not yet absolutely complete, but already very usable.

Please, view the file doc_tools/maml4_tutorial.maml.html
anubis_dev/library/doc_tools/basis.maml 0 → 100644
  1 +
  2 +
  3 + basis.maml
  4 +
  5 + A set of common usage macros for MAML.
  6 +
  7 +$begin
  8 +$//////////////////////////////////////////////////////
  9 +$// Some colors
  10 +$define(_ivory) (0)(230,230,210) $define(ivory) (1)($rgb($_ivory)($1))
  11 +$define(_azure) (0)(190,210,210) $define(azure) (1)($rgb($_azure)($1))
  12 +$define(_lavender) (0)(200,200,220) $define(lavender) (1)($rgb($_lavender)($1))
  13 +$define(_white) (0)(255,255,255) $define(white) (1)($rgb($_white)($1))
  14 +$define(_black) (0)(000,000,000) $define(black) (1)($rgb($_black)($1))
  15 +$define(_grey) (0)(190,190,190) $define(grey) (1)($rgb($_grey)($1))
  16 +$define(_navy) (0)(000,000,128) $define(navy) (1)($rgb($_navy)($1))
  17 +$define(_blue) (0)(000,000,255) $define(blue) (1)($rgb($_blue)($1))
  18 +$define(_turquoise) (0)(064,224,208) $define(turquoise) (1)($rgb($_turquoise)($1))
  19 +$define(_cyan) (0)(000,255,255) $define(cyan) (1)($rgb($_cyan)($1))
  20 +$define(_darkgreen) (0)(000,100,000) $define(darkgreen) (1)($rgb($_darkgreen)($1))
  21 +$define(_green) (0)(000,255,000) $define(green) (1)($rgb($_green)($1))
  22 +$define(_yellow) (0)(255,255,000) $define(yellow) (1)($rgb($_yellow)($1))
  23 +$define(_gold) (0)(255,195,000) $define(gold) (1)($rgb($_gold)($1))
  24 +$define(_sienna) (0)(160,082,045) $define(sienna) (1)($rgb($_sienna)($1))
  25 +$define(_caramel) (0)(210,105,030) $define(caramel) (1)($rgb($_caramel)($1))
  26 +$define(_chocolate) (0)(105,055,020) $define(chocolate) (1)($rgb($_chocolate)($1))
  27 +$define(_salmon) (0)(233,150,122) $define(salmon) (1)($rgb($_salmon)($1))
  28 +$define(_orange) (0)(255,165,000) $define(orange) (1)($rgb($_orange)($1))
  29 +$define(_red) (0)(255,000,000) $define(red) (1)($rgb($_red)($1))
  30 +$define(_darkred) (0)(110,000,000) $define(darkred) (1)($rgb($_darkred)($1))
  31 +$define(_pink) (0)(255,182,193) $define(pink) (1)($rgb($_pink)($1))
  32 +$define(_magenta) (0)(255,000,255) $define(magenta) (1)($rgb($_magenta)($1))
  33 +$define(_purple) (0)(160,032,240) $define(purple) (1)($rgb($_purple)($1))
  34 +
  35 +
  36 +
  37 +
  38 +$//////////////////////////////////////////////////////
  39 +$// The style 'article'.
  40 +$// This style requires that $article is defined.
  41 +$if($defined(article))
  42 +(
  43 +$pushcounter(sec)(0)$pushcounter(subsec)(0)$pushcounter(subsubsec)(0)$// counters for sections etc...
  44 +$accumulator(tableofcontents)$// accumulator for the table of contents
  45 +$// Layout for section titles.
  46 +$if($defined(seclayout))()($define(seclayout)(1)($par$big($big($bold($1)))$par$par))
  47 +$if($defined(subseclayout))()($define(subseclayout)(1)($par$big($bold($1))$par))
  48 +$if($defined(subsubseclayout))()($define(subsubseclayout)(1)($par$bold($1)$par))
  49 +$// Layout for table of contents lines.
  50 +$if($defined(tocsec))()($define(tocsec)(1)($bold($1)$par))
  51 +$if($defined(tocsubsec))()($define(tocsubsec)(1)($box(20)()$1$par))
  52 +$if($defined(tocsubsubsec))()($define(tocsubsubsec)(1)($box(40)()$1$par))
  53 +$define(tableofcontents)(0)($postpone($content(tableofcontents)))
  54 +$define(section)(2)
  55 + ($setcounter(subsec)(0)$addtocounter(sec)(1)$label($1)$seclayout($countervalue(sec). $2)$//
  56 +$append(tableofcontents)($ref($1)($tocsec($countervalue(sec). $2))))
  57 +$define(subsection)(2)
  58 + ($setcounter(subsubsec)(0)$addtocounter(subsec)(1)$label($1)$subseclayout($countervalue(sec).$countervalue(subsec). $2)$//
  59 +$append(tableofcontents)($ref($1)($tocsubsec($countervalue(sec).$countervalue(subsec). $2))))
  60 +$define(subsubsection)(2)
  61 + ($addtocounter(subsubsec)(1)$label($1)$subsubseclayout($countervalue(sec).$countervalue(subsec).$countervalue(subsubsec). $2)$//
  62 +$append(tableofcontents)($ref($1)($tocsubsubsec($countervalue(sec).$countervalue(subsec).$countervalue(subsubsec). $2))))
  63 +)()
  64 +
  65 +
  66 +$//////////////////////////////////////////////////////
  67 +$// The style 'book'.
  68 +$// This style requires that $book is defined.
  69 +$if($defined(book))
  70 +(
  71 +$pushcounter(chap)(0)$pushcounter(sec)(0)$pushcounter(subsec)(0)$pushcounter(subsubsec)(0)$// counters for sections etc...
  72 +$accumulator(tableofcontents)$// accumulator for the table of contents
  73 +$define(tableofcontents)(0)($postpone($content(tableofcontents)))
  74 +$define(chapter)(2)
  75 + ($setcounter(sec)(0)$addtocounter(chap)(1)$label($1)$chaplayout($countervalue(chap). $2)$//
  76 +$append(tableofcontents)($ref($1)($tocchap($countervalue(chap). $2))))
  77 +$define(section)(2)
  78 + ($setcounter(subsec)(0)$addtocounter(sec)(1)$label($1)$seclayout($countervalue(sec). $2)$//
  79 +$append(tableofcontents)($ref($1)($tocsec($countervalue(sec). $2))))
  80 +$define(subsection)(2)
  81 + ($setcounter(subsubsec)(0)$addtocounter(subsec)(1)$label($1)$subseclayout($countervalue(sec).$countervalue(subsec). $2)$//
  82 +$append(tableofcontents)($ref($1)($tocsubsec($countervalue(sec).$countervalue(subsec). $2))))
  83 +$define(subsubsection)(2)
  84 + ($addtocounter(subsubsec)(1)$label($1)$subsubseclayout($countervalue(sec).$countervalue(subsec).$countervalue(subsubsec). $2)$//
  85 +$append(tableofcontents)($ref($1)($tocsubsubsec($countervalue(sec).$countervalue(subsec).$countervalue(subsubsec). $2))))
  86 +)()
  87 +
  88 +
  89 +$//////////////////////////////////////////////////////
  90 +
  91 +
  92 +
  93 +$end
  94 +
0 95 \ No newline at end of file
... ...
anubis_dev/library/doc_tools/maml4.anubis 0 → 100644
  1 +
  2 +
  3 + MAML4
  4 +
  5 + The Minimalist Anubis Markup Language (version 4).
  6 +
  7 + Author: Alain Prouté Jan. 2017
  8 +
  9 + The file 'maml4_interface.anubis' contains the user's documentation in MAML format.
  10 + This file 'maml4.anubis' contains the technical documentation in MAML format.
  11 +
  12 + $begin
  13 + $input(../anubis_doc.maml)
  14 + $define(title)(1)($big($bold($rgb(120,40,0)($1)))$p)
  15 +
  16 + $center($big($big($big($bold(MAML (version 4) technical documentation)))))
  17 + $p
  18 +
  19 + This document explains the structure of the (somehow complex) source of the program MAML version 4.
  20 + Another document (in MAML format in $fname(maml4_interface.anubis)) explains how to use MAML in your programs.
  21 + There is also a tutorial and reference (in MAML format in $fname(maml4_tutorial.maml)) for writing MAML texts.
  22 + $p
  23 +
  24 + $title(Files)
  25 + This program MAML version 4 is made of the following files:
  26 + $define(file)(2)($item$box(160)($fname($1))$par$2)
  27 + $list(
  28 + $file(maml4_interface.anubis) (contains the public declarations and the programer documentation
  29 + (this is an Anubis and MAML file))
  30 + $file(maml4_types.anubis) (types and declarations which are not part of the interface)
  31 + $file(maml4_private.anubis) (various private tools)
  32 + $file(maml4_lexers.anubis) (contains the lexers (constructed by fast_lexer_5))
  33 + $file(maml4_png.anubis) (making PNG images to be inserted into the HTML output when the mark
  34 + $tt($$latex) is used)
  35 + $file(maml4_colorize.anubis) (execution of colorizations)
  36 + $file(maml4_eval.anubis) (evaluator (expansions of macros and execution of category 1 marks))
  37 + $file(maml4_parser.anubis) (contains the 'hand written' parser (APG not suitable for MAML syntax which is
  38 + not LALR1, but nevertheless quite simple))
  39 + $file(maml4_html.anubis) (produce HTML output)
  40 + $file(maml4_pdf.anubis) (produce LaTeX/PDF output)
  41 + $file(maml4.anubis) (the 'main' file' (this file) to be compiled for creating 'maml.adm')
  42 + )
  43 + $undefine(file)
  44 + Each file 'transmits' its public content to the next one (in the order above).
  45 + $p
  46 +
  47 + Furthermore, when the program is compiled, it generates the following files:
  48 + $define(file)(2)($item$box(160)($fname(generated/$1))$par$2)
  49 + $list(
  50 + $file(prim1.anubis)(types and functions related to primitive marks (part 1))
  51 + $file(prim2.anubis)(types and functions related to primitive marks (part 2))
  52 + $file(skip_lexer.anubis)(lexer for skipping until $tt($$begin))
  53 + $file(out_lexer.anubis)(lexer for parsing between $tt($$begin) and $tt($$end))
  54 + $file(blank_lexer.anubis)(lexer for skipping blanks before operands of marks)
  55 + $file(in_lexer.anubis)(lexer for parsing within operands of marks)
  56 + $file(verb_lexer.anubis)(lexer for parsing $em(verbatim) operands)
  57 + $file(color_value_lexer.anubis)(lexer for checking colors)
  58 + $file(symbol_lexer.anubis)(lexer for checking symbols)
  59 + $file(html_lexer.anubis)(lexer for handling special HTML characters)
  60 + )
  61 + $undefine(file)
  62 +
  63 + $title(Marks by category)
  64 + Marks are dispatched into three $em(categories):
  65 + $list(
  66 + $item $bold(Category 1): marks not producing an output by themselves.
  67 + $item $bold(Category 2): the mark $tt($$colorize), and the $em(internal) marks $tt($$call) and $tt($$return),
  68 + $item $bold(Category 3): marks actually translated into HTML and LaTeX.
  69 + )
  70 + For example, $tt($$addtocounter) is in category 1, whereas $tt($$rgb) is in category 3. The official lists of marks
  71 + of categories 1 and 3 are given by $att(primitives1) and $att(primitives3) in $fname(maml4_types.anubis). These lists
  72 + record some informations about the marks, which allow to produce automatically some types and functions. Two files
  73 + are generated that way:
  74 + $list(
  75 + $item $fname(generated/prim1.anubis)
  76 + $item $fname(generated/prim2.anubis)
  77 + )
  78 +
  79 +
  80 + $title(Compiler operation)
  81 + The MAML compiler proceeds as follows:
  82 + $list(
  83 + $item (1) The MAML source text is parsed. This produces syntax trees of type $att(MAML1).
  84 + $item (2) $att(MAML1) entities are $em(evaluated). This consists in expanding macros and executing all category 1 marks.
  85 + This produces data of type $att(MAML2).
  86 + $item (3) $att(MAML2) data are processed for colorization. This produces data of type $att(MAML3).
  87 + $item (4) $att(MAML3) data are translated into HTML and/or LaTeX.
  88 + )
  89 + Of course, $att(MAML1) has one alternative for each sort of syntactic MAML concept. This also includes errors, which
  90 + are stored into the $att(MAML1) datum, so that several errors can be transmitted to the user. $att(MAML2) is similar
  91 + but the alternatives for category 1 marks and for macros have desappeared. Finally, $att(MAML3) data are even simpler
  92 + because the alternative for the category 2 mark and MAML variables also desappear.$p
  93 +
  94 + We also make use of two variants of $att(MAML2) named $att(MAML2a) and $att(MAML2b).$p
  95 +
  96 +
  97 + $title(Lexers)
  98 + The MAML parser uses several lexers (constructed by $fname(fast_lexer_5)):
  99 + $list(
  100 + $item the $em(skip) lexer is used outside pairs ($tt($$begin),$tt($$end)),
  101 + $item the $em(out) lexer is used $em(at top level) between $tt($$begin) and $tt($$end).
  102 + $item the $em(blank) lexer is used for skipping blanks until the next expected operand of a mark.
  103 + $item the $em(in) lexer is used for parsing MAML texts within operands of marks.
  104 + $item the $em(verb) lexer is used for parsing the operands which must be read in $em(verbatim) mode.
  105 + )
  106 + By ``$em(at top level)'', we mean: $em(not within an argument of a mark).$p
  107 +
  108 + Actually, evaluation takes place during parsing after each top level mark is parsed together with its operands.$p
  109 +
  110 + Other lexers are constructed for parsing colors (of the form $tt(r,g,b)) or checking that the result of parsing and
  111 + evaluating an operand yields a string of a particular form (for example a $em(symbol) for naming colorizers, etc...).
  112 + Finally, two lexers are also constructed during the execution of the MAML compiler for each colorizer.$p
  113 +
  114 + All lexers, including colorizer lexers, are saved in $fname(generated) so that they are not reconstructed at each
  115 + recompilation, except of course if they are modified (this is an automatic mecanism of $fname(fast_lexer_5)).$p
  116 +
  117 + $title(The toolbox)
  118 + The system uses a $em(toolbox) (of type $att(Toolbox)), which contains a subtoolbox named $att(keep). The subtoolbox
  119 + contains all the stuff which is not reinitialized when we change the input source via $tt($$input). On the contrary,
  120 + the stuff specifically depending on the input source is stored directly into the toolbox. The toolbox contains:
  121 + $list(
  122 + $item $em(input source dependent):
  123 + $list(
  124 + $item current (absolute) file path,
  125 + $item current file name,
  126 + $item lexing stream through which the source is read,
  127 + $item the five lexers already plugged onto the lexing stream.
  128 + )
  129 + $item $em(input source independent ($att(keep))):
  130 + $list(
  131 + $item options of the MAML compiler,
  132 + $item B-tree containing the stacks of definitions of macros (within a dynamic variable),
  133 + $item list of all color rules (within a dynamic variable),
  134 + $item list of all colorizers (within a dynamic variable),
  135 + $item list of all colorizer call rules (within a dynamic variable),
  136 + $item B-tree of all stacks of counters (within a dynamic variable),
  137 + $item counter of errors (within a dynamic variable),
  138 + $item HTML options,
  139 + $item PDF options.
  140 + )
  141 + )
  142 +
  143 + $title(The colorization process)
  144 + For each colorizer, we construct two lexers:
  145 + $list(
  146 + $item a first lexer for handling calls and returns (constructed from informations provided by $tt($$colorizercall)),
  147 + $item a second lexer for handling the colorization itself (constructed from informations provided by $tt($$colorize)).
  148 + )
  149 + Colorizing a text is performed in two passes:
  150 + $list(
  151 + $item a first pass for handling colorizer calls using the first lexer,
  152 + $item a second pass for handling colorisation itself using the second lexer.
  153 + )
  154 + The first lexer is constructed as follows. For each $tt($$colorizercall(<name>)(<regexpr>)(?)(?)), there is a lexer item
  155 + with $tt(<regexpr>) as its regular expression and returning a token of the form $att(call(<name>,<token>)). For each
  156 + $tt($$colorizercall(?)(?)(<name>)(<regexpr>)), there is a lexer item with $tt(<regexpr>) as its regular expression
  157 + and returning a token of the form $att(return(<token>)). There are other standard lexer items for the rest of the
  158 + text returning tokens of the form $att(text(<text>)).$p
  159 +
  160 + Using this lexer, we can insert (actually virtual)
  161 + $tt($$call(<name>)) and $tt($$return) special marks into the text, even if this text is not a
  162 + character string. Indeed, this process acts on $att(MAML2) data. It produces $att(MAML2b) data, where $att(MAML2b)
  163 + is the same as $att(MAML2) except that it has two more alternatives for representing $tt($$call(<name>)) and
  164 + $tt($$return).$p
  165 +
  166 + The second lexer, for a given colorizer name, is constructed with one lexer item for each
  167 + $tt($$colorrule(<name>)(<regexpr>)(<value>)) such that $tt(<name>) is the colorizer name. This lexer item has
  168 + $tt(<regexpr>) as its regular expression and returns a token of the form $att(color(<value>,<text>)), where
  169 + $att(<value>) is the expression for colorizing $att(<text>) as given as the third operand of $tt($$colorrule). Other
  170 + standard lexer items are added for handling the rest of the text, returning tokens of the form $att(text(<text>)).$p
  171 +
  172 + Now, this second lexer is used for the actual colorization of a $att(MAML2b) data. A token of the form
  173 + $att(text(<text>)) is left unchanged, whereas a token of the form $att(color(<value>,<text>)) produces what we
  174 + obtain by replacing $tt($$1) by $att(<text>) in $att(<value>). This is for characters strings, i.e. for the
  175 + alternative $att(text(<text>)) of $att(MAML2b). Otherwise, we have to
  176 + handle the other alternatives of $att(MAML2b), and in particular $att(call(<name>)) and $att(return).$p
  177 +
  178 + When the colorizer program sees a $att(call(<name>)), it pushes the current colorizer on the colorizer stack and
  179 + considers $att(<name>) as the name of the now current colorizer. When it encounters a $att(return) is pops a
  180 + coloriser from the stack which becomes the current colorizer.$p
  181 +
  182 + A colorizer already constructed by $tt($$colorizer) cannot be reconstructed. Hence, a tentative to reconstruct it
  183 + or to add a new rule to it is ignored and generates a warning.
  184 +
  185 + $p
  186 + $center($title(---------------------------------------))
  187 + $par
  188 + This is all for the general overview of the MAML version 4 source. Other more specific informations can
  189 + be found in the source files.
  190 +
  191 + $p
  192 + $end
  193 +
  194 +read maml4_pdf.anubis
  195 +
  196 +
  197 + *** Separating options from other command line arguments.
  198 +
  199 +define (List(MAML_Option),List(String))
  200 + separate_options
  201 + (
  202 + List(String) args
  203 + ) =
  204 + if args is
  205 + {
  206 + [ ] then ([ ],[ ]),
  207 + [h . t] then
  208 + since separate_options(t) is (opts1,others1),
  209 + if h = "-pdf" then ([pdf . opts1],others1) else
  210 + if h = "-verbose" | h = "-v" then ([verbose . opts1],others1) else
  211 + (opts1,[h . others1])
  212 + }.
  213 +
  214 +
  215 + *** 'Usage' message.
  216 +
  217 +define One
  218 + usage
  219 + =
  220 + iprint("Usage: anbexec maml4 <file name> [options]\n" +
  221 + " Options:\n"+
  222 + " -pdf produce LaTeX and PDF outputs\n"+
  223 + " -verbose \n").
  224 +
  225 +
  226 + *** 'maml' as a command line tool.
  227 +
  228 +global define One
  229 + maml
  230 + (
  231 + List(String) args
  232 + ) =
  233 + since separate_options(args) is (opts,other_args),
  234 + if other_args is
  235 + {
  236 + [ ] then usage,
  237 + [fname . _] then
  238 + if file(fname,read) is
  239 + {
  240 + failure then iprint("File '"+fname+"' not found.\n"),
  241 + success(fp) then if make_lexing_stream("",fp,1000,10) is
  242 + {
  243 + failure then iprint("Cannot read file '"+fname+"'.\n"),
  244 + success(ls) then
  245 + with gcount_v = var((Int)0),
  246 + with kbox = toolboxkeep(opts,
  247 + var((MacroTree)new_tree(bt24cmp)),
  248 + var((ArityTree)new_tree(bt24cmp)),
  249 + var((List(ColorRule))[]),
  250 + var((List(ColorCall))[]),
  251 + var((CallLexerTree)new_tree(bt24cmp)),
  252 + var((ColorLexerTree)new_tree(bt24cmp)),
  253 + var((CounterTree)new_tree(bt24cmp)),
  254 + var((AccumulatorTree)new_tree(bt24cmp)),
  255 + var((Int)30),
  256 + default
  257 + ),
  258 + since ((String,String))split_path(fname) is (rel_path,fname1),
  259 + with start_path = get_current_directory/rel_path,
  260 + with tbox = make_toolbox(start_path,fname1,ls,kbox),
  261 + with result = if_verbose(tbox,"--> '"+fname+"' ...\n",parse_eval(tbox),"<--\n"),
  262 + with presult = execute_postponed(tbox,result),
  263 + with cresult = colorize(tbox, // needed because values of colorrules must be evaluated during colorization
  264 + *tbox.keep.call_lexer_tree_v,
  265 + *tbox.keep.color_lexer_tree_v,
  266 + presult),
  267 + with errors = extract_errors(cresult),
  268 + map_forget((MAML_Error me) |->
  269 + print(cyan("Error: ")+to_English(me)+"\n"),
  270 + errors);
  271 + with html_text = if_verbose(tbox,"Producing HTML ... ",to_HTML(start_path,default,cresult),"done\n"),
  272 + if file(fname+".html",new) is
  273 + {
  274 + failure then print("Canot create file '"+fname+"4.html"+"'\n"),
  275 + success(htmlfp) then if_verbose(tbox,"Outputing HTML ... ",print(weaken(htmlfp),
  276 + html_encapsulate(tbox.keep.html_options,html_text)),"done\n")
  277 + }
  278 +
  279 + /*
  280 + if errors is
  281 + {
  282 + [ ] then
  283 + with html_text = if_verbose(tbox,"Producing HTML ... ",to_HTML(start_path,default,result),"done\n"),
  284 + if file(fname+".html",new) is
  285 + {
  286 + failure then print("Canot create file '"+fname+"4.html"+"'\n"),
  287 + success(htmlfp) then if_verbose(tbox,"Outputing HTML ... ",print(weaken(htmlfp),
  288 + html_encapsulate(tbox.keep.html_options,html_text)),"done\n")
  289 + },
  290 + [_ . _] then map_forget((MAML_Error me) |->
  291 + print(cyan("Error: ")+to_English(me)+"\n"),
  292 + errors)
  293 + }
  294 + */
  295 +
  296 + }
  297 + }
  298 + }.
  299 +
  300 +
... ...
anubis_dev/library/doc_tools/maml4_colorize.anubis 0 → 100644
  1 +
  2 +
  3 + MAML4
  4 +
  5 + Colorizer stuff.
  6 +
  7 +
  8 +transmit maml4_png.anubis
  9 +
  10 +
  11 + *** This file defines the following function:
  12 +
  13 +
  14 +public define MAML3 colorize (CallLexerTree call_lexers,
  15 + ColorLexerTree color_lexers,
  16 + MAML2 m).
  17 +
  18 +
  19 + Each colorizer has two lexers attached to it.
  20 +
  21 + - (1) a 'call lexer' of type LexingStream -> CallLexer,
  22 + where CallLexer is an alias for One -> Result(LexicalError(One),ColorCallToken),
  23 +
  24 + - (2) a 'color lexer' of type LexingStream -> ColorLexer,
  25 + where ColorLexer is an alias for One -> Result(LexicalError(One),ColorToken).
  26 +
  27 + These lexers are stored into the keep subtoolbox into two B-trees of respective types CallLexerTree, and
  28 + ColorLexerTree.
  29 +
  30 + Colorizing is performed in two phases. The first phase uses 'call lexers' in order to introduce 'call' and 'return'
  31 + marks into the MAML2 text. This produces a MAML2b text. The second phase is the colorisation proper which uses
  32 + 'color lexers'.
  33 +
  34 + The first phase is preformed by the function 'handle_calls' acting on a MAML2 datum, and it uses the function
  35 + 'color_call_parser' for handling the case of the 'text' alternative, the only one which needs to use call lexers.
  36 + This first phase produces a MAML2b from a MAML2, and consists in replacing all 'text(s)' by MAML2b compound data
  37 + containing 'call(name,tok)' and 'return(tok)' items.
  38 +
  39 + 'color_call_parser' works as follows. When a string (alternative 'text' of MAML2) need colorization,
  40 + a lexing stream is constructed from this string. The colorization
  41 + uses a stack of plugged call lexers (whereas the B-tree contains unplugged call lexers). We start with a stack
  42 + containing only one plugged call lexer, and the string is always analysed using the call lexer on top of stack.
  43 + When a call lexer returns a token of the form 'call(name,tok)', the lexer corresponding to name is plugged onto
  44 + the lexing stream and pushed onto the stack. When the lexer returns a token of the form 'return(tok)' a lexer is poped
  45 + from the stack. The tokens 'tok' are in both cases inserted in tothe result in the form 'text(tok)'. When a lexer returns a token
  46 + of the form 'text(s)', this produces a element of the form 'text(s)'.
  47 +
  48 + The second phase is performed by 'colorize_2b' taking a MAML2b datum and producing a MAML3 datum. 'colorize_2b'
  49 + uses a stack of color lexers, and when a string is to be colorized this is performed using the lexer on top of stack.
  50 + Of course, 'colorize_2b' handles instructions 'call' and 'return' by pushing/poping lexers on the stack. Strings
  51 + (alternative 'text' of MAML2b) are colorized by the function 'color_parser' using the lexer on top of stack.
  52 + This lexer returns tokens of the form 'color(value,text)' where 'value' is a MAML2a datum which is actually an
  53 + evaluation of the body of a color rule, and where 'text' is a string. In this case, 'color_parser' just produces
  54 + a MAML3 item which is the result of the replacement of the MAML variable $1 by 'text' in 'value'. Otherwise, the
  55 + lexer returns tokens of the form 'text(...)' producing 'text(...)' (non colorized piece of text).
  56 +
  57 +
  58 +
  59 +
  60 +
  61 + --- That's all for the public part ! -------------------------------------------------
  62 +
  63 +
  64 + 'canonical' map from MAML2 to MAML2b.
  65 +
  66 +define MAML2b
  67 + can
  68 + (
  69 + MAML2 m
  70 + ) =
  71 + if m is
  72 + {
  73 + error(me) then error(me),
  74 + erroneous(me,text) then erroneous(me,text),
  75 + empty then empty,
  76 + false then empty,
  77 + true then empty,
  78 + text(value) then text(value),
  79 + variable(id) then variable(id),
  80 + list(l,_) then list(map(can,l)),
  81 + alpha(m1) then can(m1),
  82 + colorize(pos,cname,operand) then colorize(pos,cname,can(operand)),
  83 + postpone(pos,text) then should_not_happen(empty),
  84 + prim3(p3) then prim3(map(can,p3)),
  85 + m1 + m2 then can(m1) + can(m2)
  86 + }.
  87 +
  88 + 'canonical' map from MAML2 to MAML2a.
  89 +
  90 +define MAML2a
  91 + can
  92 + (
  93 + MAML2 m
  94 + ) =
  95 + if m is
  96 + {
  97 + error(me) then error(me),
  98 + erroneous(me,text) then erroneous(me,text),
  99 + empty then empty,
  100 + false then empty,
  101 + true then empty,
  102 + text(value) then text(value),
  103 + variable(id) then variable(id),
  104 + list(l,_) then list(map(can,l)),
  105 + alpha(m1) then can(m1),
  106 + colorize(pos,cname,operand) then empty,
  107 + postpone(pos,text) then should_not_happen(empty),
  108 + prim3(p3) then prim3(map(can,p3)),
  109 + m1 + m2 then can(m1) + can(m2)
  110 + }.
  111 +
  112 + 'canonical' map from MAML2b to MAML3.
  113 +
  114 +define MAML3
  115 + can
  116 + (
  117 + MAML2b m
  118 + ) =
  119 + if m is
  120 + {
  121 + error(me) then error(me),
  122 + erroneous(me,text) then erroneous(me,text),
  123 + empty then empty,
  124 + call(cname) then empty,
  125 + return then empty,
  126 + text(value) then text(value),
  127 + variable(id) then empty,
  128 + list(l) then sum(map(can,l)),
  129 + colorize(pos,cname,operand) then can(operand),
  130 + prim3(p3) then prim3(map(can,p3)),
  131 + m1 + m2 then can(m1) + can(m2)
  132 + }.
  133 +
  134 +
  135 +
  136 +public define MAML2
  137 + can
  138 + (
  139 + MAML3 m
  140 + ) =
  141 + if m is
  142 + {
  143 + error(me) then error(me),
  144 + erroneous(me,text) then erroneous(me,text),
  145 + empty then empty,
  146 + text(value) then text(value),
  147 + list(l) then list(map(can,l),[]),
  148 + postpone(pos,text) then postpone(pos,text),
  149 + prim3(p3) then prim3(map(can,p3)),
  150 + m1+m2 then can(m1)+can(m2)
  151 + }.
  152 +
  153 +
  154 +public define MAML3
  155 + can
  156 + (
  157 + MAML2 m
  158 + ) =
  159 + if m is
  160 + {
  161 + error(me) then error(me),
  162 + erroneous(me,text) then erroneous(me,text),
  163 + empty then empty,
  164 + false then empty,
  165 + true then empty,
  166 + text(value) then text(value),
  167 + variable(id) then empty,
  168 + list(l,deco) then list(map(can,l)),
  169 + alpha(m1) then can(m1),
  170 + colorize(pos,cname,operand) then can(operand),
  171 + postpone(pos,text) then postpone(pos,text),
  172 + prim3(p3) then prim3(map(can,p3)),
  173 + m1+m2 then can(m1)+can(m2)
  174 + }.
  175 +
  176 +
  177 +
  178 + *** Gluing texts in MAML2.
  179 +
  180 + The function below looks for consecutive text("bla") and text("blu") and replaces them by text ("blablu"),
  181 + so that the colorizer can recognize a token spanning over several pieces of texts. It also elimnates 'empty'
  182 + when it is added (on the left or on the right) to something.
  183 +
  184 +public define MAML2
  185 + glue_texts
  186 + (
  187 + MAML2 m
  188 + ) =
  189 + //print("gluing MAML2 ");
  190 + if m is
  191 + {
  192 + error(me) then m,
  193 + erroneous(me,m1) then m,
  194 + empty then m,
  195 + false then m,
  196 + true then m,
  197 + text(value) then m,
  198 + variable(id) then m,
  199 + list(l,d) then list(map(glue_texts,l),d),
  200 + alpha(m1) then alpha(glue_texts(m1)),
  201 + colorize(pos,cname,op) then colorize(pos,cname,glue_texts(op)),
  202 + postpone(pos,text) then m, // text is MAML1
  203 + prim3(p3) then glue_texts(p3),
  204 + _m1 + _m2 then
  205 + if _m1 is empty then glue_texts(_m2) else
  206 + if _m2 is empty then glue_texts(_m1) else
  207 + with m1 = glue_texts(_m1),
  208 + m2 = glue_texts(_m2),
  209 + if m1 is text(t1)
  210 + then if m2 is text(t2)
  211 + then text(t1+t2)
  212 + else if m2 is m2a+m2b
  213 + then if m2a is text(t2a)
  214 + then glue_texts(text(t1+t2a)+m2b)
  215 + else m1+m2
  216 + else m1+m2
  217 + else if m1 is m1a+m1b
  218 + then if m1b is text(t1b)
  219 + then if m2 is text(t2)
  220 + then glue_texts(m1a+text(t1b+t2))
  221 + else m1+m2
  222 + else m1+m2
  223 + else m1+m2
  224 + }.
  225 +
  226 + The same one for MAML2b.
  227 +
  228 +public define MAML2b
  229 + glue_texts
  230 + (
  231 + MAML2b m
  232 + ) =
  233 + //print("gluing MAML2b ");
  234 + if m is
  235 + {
  236 + error(me) then m,
  237 + erroneous(me,m1) then m,
  238 + empty then m,
  239 + call(name) then m,
  240 + return then m,
  241 + text(value) then m,
  242 + variable(id) then m,
  243 + list(l) then list(map(glue_texts,l)),
  244 + colorize(pos,cname,op) then colorize(pos,cname,glue_texts(op)),
  245 + prim3(p3) then glue_texts(p3),
  246 + _m1 + _m2 then
  247 + if _m1 is empty then glue_texts(_m2) else
  248 + if _m2 is empty then glue_texts(_m1) else
  249 + with m1 = glue_texts(_m1),
  250 + m2 = glue_texts(_m2),
  251 + if m1 is text(t1)
  252 + then if m2 is text(t2)
  253 + then text(t1+t2)
  254 + else if m2 is m2a+m2b
  255 + then if m2a is text(t2a)
  256 + then glue_texts(text(t1+t2a)+m2b)
  257 + else m1+m2
  258 + else m1+m2
  259 + else if m1 is m1a+m1b
  260 + then if m1b is text(t1b)
  261 + then if m2 is text(t2)
  262 + then glue_texts(m1a+text(t1b+t2))
  263 + else m1+m2
  264 + else m1+m2
  265 + else m1+m2
  266 + }.
  267 +
  268 +
  269 +
  270 + *** Creating colorizers.
  271 +
  272 + A colorizer is created when we encounter a $colorizer(name). This amounts to create two lexers (a call lexer and
  273 + a color lexer) and to store them in the B-trees of the keep subtoolbox.
  274 +
  275 + *** Creating the call lexer.
  276 +
  277 +define Result(RegExprError,One)
  278 + create_call_lexer
  279 + (
  280 + Toolbox tbox,
  281 + String name, // of colorizer
  282 + List(ColorCall) callrules
  283 + ) =
  284 + with my_call_rules = map_select((ColorCall cc) |->
  285 + if cc is colorcall(mode,cname1,open,cname2,close) then
  286 + if name = cname1
  287 + then success(cc)
  288 + else failure,
  289 + callrules),
  290 + with my_return_rules = map_select((ColorCall cc) |->
  291 + if cc is colorcall(mode,cname1,open,cname2,close) then
  292 + if name = cname2
  293 + then success(cc)
  294 + else failure,
  295 + callrules),
  296 + with ldesc = (List(LexerItem(ColorCallToken,One)))
  297 + map((ColorCall cc) |->
  298 + if cc is colorcall(mode,_,open,cname2,_) then
  299 + //print("call lexer "+name+": "+open+" (call)\n");
  300 + lexer_item(open, return((ByteArray b, LexingTools t, One u) |-> ok(call(mode_for_call(mode),cname2,to_string(b)))))
  301 + ,my_call_rules)
  302 + + map((ColorCall cc) |->
  303 + if cc is colorcall(mode,_,_,_,close) then
  304 + //print("call lexer "+name+": "+close+" (return)\n");
  305 + lexer_item(close, return((ByteArray b, LexingTools t, One u) |-> ok(return(mode_for_return(mode),to_string(b)))))
  306 + ,my_return_rules)
  307 + + [
  308 + lexer_item("#n", return((ByteArray b, LexingTools t, One u) |-> ok(text(to_string(b))))),
  309 + lexer_item(".", return((ByteArray b, LexingTools t, One u) |-> ok(text(to_string(b)))))
  310 + ],
  311 + if if_verbose(tbox,"(1) Making colorizer '"+name+"' ... ",make_saved_lexer(ldesc,end_of_input,'#'),"done\n") is
  312 + {
  313 + error(e) then error(e),
  314 + ok(lex) then
  315 + with lexer = (LexingStream ls) |-> lex(ls,unique),
  316 + v = tbox.keep.call_lexer_tree_v,
  317 + ok(v <- insert(name,lexer,*v))
  318 + }.
  319 +
  320 +
  321 + *** Creating the color lexer.
  322 +
  323 +define Result(RegExprError,One)
  324 + create_color_lexer
  325 + (
  326 + Toolbox tbox,
  327 + String name, // of colorizer
  328 + List(ColorRule) rules
  329 + ) =
  330 + with myrules = map_select((ColorRule r) |->
  331 + if r is rule(n,_,_) then if n = name
  332 + then success(r)
  333 + else failure,
  334 + rules),
  335 + // 'reverse' is needed because the order conventions must be the same as in fast_lexer_5.anubis.
  336 + ldesc = (List(LexerItem(ColorToken,One)))reverse(
  337 + [
  338 + lexer_item(".", return((ByteArray b, LexingTools t, One u) |-> ok(text(to_string(b))))),
  339 + lexer_item("([# #r#t]+)|(#n)", return((ByteArray b, LexingTools t, One u) |-> ok(text(to_string(b)))))
  340 + . map((ColorRule r) |-> if r is rule(_,re,c) then
  341 + lexer_item(re,return((ByteArray b, LexingTools t, One u) |-> ok(color(c,to_string(b))))),myrules)
  342 + ]
  343 + ),
  344 + if if_verbose(tbox,"(2) Making colorizer '"+name+"' ... ",make_saved_lexer(ldesc,end_of_input,'#'),"done\n") is
  345 + {
  346 + error(e) then error(e),
  347 + ok(lex) then
  348 + with lexer = (LexingStream ls) |-> lex(ls,unique),
  349 + v = tbox.keep.color_lexer_tree_v,
  350 + ok(v <- insert(name,lexer,*v))
  351 + }.
  352 +
  353 +
  354 + *** Creating the whole colorizer.
  355 +
  356 +public define MAML2
  357 + create_colorizer
  358 + (
  359 + Toolbox tbox,
  360 + MAML_Pos pos,
  361 + String name
  362 + ) =
  363 + if get(name,*tbox.keep.call_lexer_tree_v) is
  364 + {
  365 + failure then
  366 + if create_call_lexer(tbox,name,*tbox.keep.colorcall_v) is
  367 + {
  368 + error(e) then error(regexpr(pos,e)),
  369 + ok(_) then if create_color_lexer(tbox,name,*tbox.keep.colorrules_v) is
  370 + {
  371 + error(e) then error(regexpr(pos,e)),
  372 + ok(_) then empty
  373 + }
  374 + },
  375 + success(_) then error(colorizer_already_exists(pos,name))
  376 + }.
  377 +
  378 +
  379 +
  380 + *** Handling colorizer calls.
  381 +
  382 +define MAML2b
  383 + color_call_parser
  384 + (
  385 + CallLexerTree call_lexers, // all known (unplugged) call lexers
  386 + List(CallLexer) stk, // a stack of plugged call lexers
  387 + LexingStream ls // the source of bytes to be lexered
  388 + ) =
  389 + if stk is
  390 + {
  391 + [ ] then empty,
  392 + [lex1 . _] then if lex1(unique) is
  393 + {
  394 + error(e) then empty,
  395 + ok(s) then if s is
  396 + {
  397 + end_of_input then empty,
  398 + call(mode,cn,tok) then //print("got a call("+cn+","+tok+")\n");
  399 + if get(cn,call_lexers) is
  400 + {
  401 + failure then error(unknown_colorizer(cn)),
  402 + success(lex2) then
  403 + (if mode is e then (text(tok) + call(cn)) else (call(cn) + text(tok)))
  404 + + color_call_parser(call_lexers,[lex2(ls) . stk],ls)
  405 + },
  406 + return(mode,tok) then //print("got a return("+tok+")\n");
  407 + if stk is
  408 + {
  409 + [ ] then text(tok) + color_call_parser(call_lexers,[],ls),
  410 + [_ . t] then (if mode is e then (return + text(tok)) else (text(tok) + return))
  411 + + color_call_parser(call_lexers,t,ls),
  412 + },
  413 + text(tx) then //print("got a text: "+tx+"\n");
  414 + text(tx) + color_call_parser(call_lexers,stk,ls)
  415 + }
  416 + }
  417 + }.
  418 +
  419 +
  420 + The function 'handle_calls' inserts the instructions 'call(cname)' and 'return' into a MAML2
  421 + (this produces a MAML2b). It needs a stack of colorizers because when it is within the text
  422 + of a $colorize(cname)(operand), it must remember 'cname' in order to call the right color_call_parser
  423 + on pieces of text in 'operand'
  424 +
  425 +public define MAML2b
  426 + handle_calls
  427 + (
  428 + CallLexerTree call_lexers, // all call lexers as they are stored in the keep subtoolbox
  429 + List(String) stack, // stack of names of call lexers
  430 + MAML2 m
  431 + ) =
  432 + if m is
  433 + {
  434 + error(me) then error(me),
  435 + erroneous(me,text) then erroneous(me,text),
  436 + empty then empty,
  437 + false then empty,
  438 + true then empty,
  439 + text(value) then
  440 + if stack is
  441 + {
  442 + [ ] then text(value), // we are not within a $colorize()()
  443 + [h . t] then if get(h,call_lexers) is
  444 + {
  445 + failure then error(unknown_colorizer(h)),
  446 + success(col) then with ls = make_lexing_stream("",value),
  447 + color_call_parser(call_lexers,[col(ls)],ls)
  448 + }
  449 + },
  450 + variable(id) then variable(id),
  451 + list(l,_) then list(map((MAML2 m2) |-> handle_calls(call_lexers,stack,m2),l)),
  452 + alpha(m1) then handle_calls(call_lexers,stack,m1),
  453 + colorize(pos,cname,operand) then colorize(pos,cname,handle_calls(call_lexers,[cname . stack],operand)),
  454 + postpone(pos,text) then should_not_happen(empty),
  455 + prim3(p3) then prim3(map((MAML2 m2) |-> handle_calls(call_lexers,[],m2),p3)),
  456 + m1 + m2 then handle_calls(call_lexers,stack,m1) + handle_calls(call_lexers,stack,m2)
  457 + }.
  458 +
  459 +
  460 +
  461 + *** Actual colorization (phase 2).
  462 +
  463 +
  464 + *** Colorizing a string.
  465 +
  466 +define MAML3
  467 + color_parser
  468 + (
  469 + Toolbox tbox,
  470 + ColorLexer lex // already plugged color lexer
  471 + ) =
  472 + if lex(unique) is
  473 + {
  474 + error(e) then empty,
  475 + ok(s) then if s is
  476 + {
  477 + end_of_input then empty,
  478 + color(c,tx) then with m1 = //replace_vars_in_MAML(can(eval(tbox,c)),[text(tx)]),
  479 + (MAML3)can(eval(tbox,replace_vars_in_MAML(c,[text(tx)]))),
  480 + m2 = color_parser(tbox,lex),
  481 + m1+m2,
  482 + text(tx) then text(tx) + color_parser(tbox,lex)
  483 + }
  484 + }.
  485 +
  486 +
  487 +
  488 + *** Colorizing a MAML2b.
  489 +
  490 + The function 'colorize_2b' performs the actual colorization.
  491 +
  492 +define MAML2b
  493 + sum
  494 + (
  495 + List(MAML2b) l
  496 + ) =
  497 + if l is
  498 + {
  499 + [ ] then empty,
  500 + [h . t] then h + sum(t)
  501 + }.
  502 +
  503 +define (List(LexingStream -> ColorLexer),MAML3)
  504 + colorize_2b_aux
  505 + (
  506 + Toolbox tbox,
  507 + ColorLexerTree color_lexers,
  508 + List(LexingStream -> ColorLexer) stk,
  509 + MAML2b m
  510 + ) =
  511 + if m is
  512 + {
  513 + error(me) then (stk,error(me)),
  514 + erroneous(me,text) then (stk,erroneous(me,text)),
  515 + empty then (stk,empty),
  516 + call(cname) then if get(cname,color_lexers) is
  517 + {
  518 + failure then (stk,error(unknown_colorizer(cname))),
  519 + success(col) then ([col . stk], empty)
  520 + },
  521 + return then if stk is
  522 + {
  523 + [ ] then ([ ],empty),
  524 + [_ . t] then (t,empty)
  525 + },
  526 + text(value) then if stk is
  527 + {
  528 + [ ] then ([ ],text(value)),
  529 + [h . _] then (stk,color_parser(tbox,h(make_lexing_stream("",value))))
  530 + },
  531 + variable(id) then (stk,empty),
  532 + list(l) then colorize_2b_aux(tbox,color_lexers,stk,sum(l)),
  533 + colorize(pos,cname,operand) then if get(cname,color_lexers) is
  534 + {
  535 + failure then (stk,error(unknown_colorizer(cname))),
  536 + success(col) then since colorize_2b_aux(tbox,
  537 + color_lexers,
  538 + [col . stk],
  539 + operand) is (_,r), (stk,r)
  540 + },
  541 + prim3(p3) then (stk,prim3(map((MAML2b m2b) |-> since colorize_2b_aux(tbox,color_lexers,[],m2b) is (_,r), r, p3)))
  542 + m1 + m2 then since colorize_2b_aux(tbox,color_lexers,stk,m1) is (stk1,r1),
  543 + since colorize_2b_aux(tbox,color_lexers,stk1,m2) is (stk2,r2),
  544 + (stk2,r1+r2)
  545 + }.
  546 +
  547 +
  548 +public define MAML3
  549 + colorize_2b
  550 + (
  551 + Toolbox tbox,
  552 + ColorLexerTree color_lexers,
  553 + List(LexingStream -> ColorLexer) stk,
  554 + MAML2b m
  555 + ) =
  556 + since colorize_2b_aux(tbox,color_lexers,stk,m) is (_,r), r.
  557 +
  558 +
  559 +
  560 +
  561 +public define MAML3
  562 + colorize
  563 + (
  564 + Toolbox tbox,
  565 + CallLexerTree call_lexers,
  566 + ColorLexerTree color_lexers,
  567 + MAML2 m
  568 + ) =
  569 + if m is
  570 + {
  571 + error(me) then error(me),
  572 + erroneous(me,text) then erroneous(me,text),
  573 + empty then empty,
  574 + false then empty,
  575 + true then empty,
  576 + text(value) then text(value),
  577 + variable(id) then empty,
  578 + list(l,_) then colorize(tbox,call_lexers,color_lexers,sum(l)),
  579 + alpha(m1) then colorize(tbox,call_lexers,color_lexers,m1),
  580 + colorize(pos,cname,operand) then with a = glue_texts(handle_calls(call_lexers,[cname],glue_texts(operand))),
  581 + //print(to_string(a)+"\n");
  582 + if get(cname,color_lexers) is
  583 + {
  584 + failure then error(unknown_colorizer(cname)),
  585 + success(col) then colorize_2b(tbox,color_lexers,[col],a)
  586 + },
  587 + postpone(pos,text) then should_not_happen(empty),
  588 + prim3(p3) then prim3(map((MAML2 m2) |-> colorize(tbox,call_lexers,color_lexers,m2),p3)),
  589 + m1+m2 then colorize(tbox,call_lexers,color_lexers,m1) + colorize(tbox,call_lexers,color_lexers,m2)
  590 + }.
  591 +
  592 +
  593 +
  594 +
  595 +
0 596 \ No newline at end of file
... ...
anubis_dev/library/doc_tools/maml4_eval.anubis 0 → 100644
  1 +
  2 + MAML4
  3 +
  4 + The evaluator.
  5 +
  6 +transmit maml4_colorize.anubis
  7 +
  8 +
  9 +public define MAML2 glue_eval (Toolbox tbox, MAML1 m).
  10 +public define MAML2 eval (Toolbox tbox, MAML1 m).
  11 +public define MAML2 parse_eval (Toolbox tbox).
  12 +
  13 +
  14 + --- That's all for the public part ! ---------------------------------------------------
  15 +
  16 +
  17 +
  18 +define MAML2 eval_prim1 (Toolbox tbox, Stack stk, MAML_Prim1 p1).
  19 +define MAML2 eval_macro (Toolbox tbox, MAML_Pos pos, String name, List(MAML1) operands).
  20 +define List(MAML2) eval_several (Toolbox tbox, List(MAML1) operands).
  21 +
  22 +public define MAML2 glue_eval (Toolbox tbox, MAML1 m) = glue_texts(eval(tbox,m)).
  23 +
  24 + public define MAML2
  25 + glue_eval
  26 + (
  27 + Toolbox tbox,
  28 + MAML1 m
  29 + ) =
  30 + with m2 = glue_texts(eval(tbox,m)),
  31 + can(colorize(tbox,
  32 + *tbox.keep.call_lexer_tree_v,
  33 + *tbox.keep.color_lexer_tree_v,
  34 + m2)).
  35 +
  36 + --- Executing the actions.
  37 +
  38 +public define MAML2 create_colorizer (Toolbox tbox,
  39 + MAML_Pos pos,
  40 + String name).
  41 +
  42 +define MAML2 record_colorizercall (Toolbox tbox,
  43 + CCMode mode,
  44 + String cn1,
  45 + String _call,
  46 + String cn2,
  47 + String _return).
  48 +
  49 +define MAML2 record_colorrule (Toolbox tbox,
  50 + String cn,
  51 + String regexpr,
  52 + MAML1 value).
  53 +
  54 +define MAML2 get_counter_value (Toolbox tbox,
  55 + MAML_Pos pos,
  56 + String name).
  57 +
  58 +
  59 +
  60 +
  61 + *** A tool for checking if we are currently within a given stackable mark.
  62 +
  63 +define Bool
  64 + within
  65 + (
  66 + Stack stk,
  67 + PrimName name
  68 + ) =
  69 + if stk is
  70 + {
  71 + [ ] then false,
  72 + [h . t] then
  73 + if name = h
  74 + then true
  75 + else within(t,name)
  76 + }.
  77 +
  78 +
  79 +
  80 +
  81 + *** Simulating HTML or PDF result by evaluating $ifhtml or $ifpdf.
  82 +
  83 +define MAML2
  84 + html_reduce
  85 + (
  86 + MAML2 m
  87 + ) =
  88 + if m is
  89 + {
  90 + error(me) then m,
  91 + erroneous(me,text) then m,
  92 + empty then m,
  93 + false then m,
  94 + true then m,
  95 + text(value) then m,
  96 + variable(id) then m,
  97 + list(l,d) then list(map(html_reduce,l),d),
  98 + alpha(m1) then alpha(html_reduce(m1)),
  99 + colorize(pos,cname,operand) then colorize(pos,cname,html_reduce(operand)),
  100 + postpone(pos,text) then m,
  101 + prim3(p3) then if p3 is ifhtml(_,n) then html_reduce(n) else
  102 + if p3 is ifpdf(_,n) then empty else
  103 + prim3(map(html_reduce,p3)),
  104 + m1 + m2 then html_reduce(m1) + html_reduce(m2)
  105 + }.
  106 +
  107 +define MAML2
  108 + pdf_reduce
  109 + (
  110 + MAML2 m
  111 + ) =
  112 + if m is
  113 + {
  114 + error(me) then m,
  115 + erroneous(me,text) then m,
  116 + empty then m,
  117 + false then m,
  118 + true then m,
  119 + text(value) then m,
  120 + variable(id) then m,
  121 + list(l,d) then list(map(pdf_reduce,l),d),
  122 + alpha(m1) then alpha(pdf_reduce(m1)),
  123 + colorize(pos,cname,operand) then colorize(pos,cname,pdf_reduce(operand)),
  124 + postpone(pos,text) then m,
  125 + prim3(p3) then if p3 is ifhtml(_,n) then empty else
  126 + if p3 is ifpdf(_,n) then pdf_reduce(n) else
  127 + prim3(map(pdf_reduce,p3)),
  128 + m1 + m2 then pdf_reduce(m1) + pdf_reduce(m2)
  129 + }.
  130 +
  131 +define Maybe(Value($T))
  132 + simulate_html_pdf
  133 + (
  134 + MAML2 -> Maybe($T) test,
  135 + MAML2 m
  136 + ) =
  137 + with m_html = html_reduce(m),
  138 + m_pdf = pdf_reduce(m),
  139 + if test(m_html) is
  140 + {
  141 + failure then failure,
  142 + success(mh) then if test(m_pdf) is
  143 + {
  144 + failure then failure,
  145 + success(mp) then success(value(mh,mp))
  146 + }
  147 + }.
  148 +
  149 +
  150 + *** Checking that a MAML operand has the required 'form'.
  151 +
  152 +define Maybe(One)
  153 + parse_color_value
  154 + (
  155 + One -> LexOut(ColorValueToken,One) lex,
  156 + Int done // number of correct tokens read
  157 + ) =
  158 + if lex(unique) is
  159 + {
  160 + error(_) then failure,
  161 + ok(tok) then if tok is
  162 + {
  163 + end_of_input then if done = 5
  164 + then success(unique)
  165 + else failure,
  166 + int(n) then if (0 =< n & n =< 255 & (done:[0,2,4]))
  167 + then parse_color_value(lex,done+1)
  168 + else failure,
  169 + comma then if done:[1,3]
  170 + then parse_color_value(lex,done+1)
  171 + else failure
  172 + }
  173 + }.
  174 +
  175 +
  176 +define Maybe(String) // produces "r,g,b"
  177 + must_be_color
  178 + (
  179 + MAML2 m
  180 + ) =
  181 + with s = to_string(glue_texts(m)),
  182 + if parse_color_value(retrieve_lexer(color_value_lexer_desc,color_value_lexer,end_of_input)
  183 + (make_lexing_stream("",s),unique),0) is
  184 + {
  185 + failure then failure,
  186 + success(_) then success(s)
  187 + }.
  188 +
  189 +
  190 +public define Result(MAML_Error,Value(String))
  191 + eval_as_color
  192 + (
  193 + Toolbox tbox,
  194 + MAML_Pos pos,
  195 + MAML1 m
  196 + ) =
  197 + if simulate_html_pdf(must_be_color,glue_eval(tbox,m)) is
  198 + {
  199 + failure then error(must_be_a_color(pos,to_string(m))),
  200 + success(n) then ok(n)
  201 + }.
  202 +
  203 +
  204 +
  205 +define Maybe(Int)
  206 + must_be_int
  207 + (
  208 + MAML2 m
  209 + ) =
  210 + decimal_scan(to_string(glue_texts(m))).
  211 +
  212 +public define Result(MAML_Error,Value(Int))
  213 + eval_as_int
  214 + (
  215 + Toolbox tbox,
  216 + MAML_Pos pos,
  217 + MAML1 m
  218 + ) =
  219 + if simulate_html_pdf(must_be_int,glue_eval(tbox,m)) is
  220 + {
  221 + failure then error(must_be_an_int(pos,to_string(m))),
  222 + success(n) then ok(n)
  223 + }.
  224 +
  225 +define Maybe(Int)
  226 + must_be_nzint
  227 + (
  228 + MAML2 m
  229 + ) =
  230 + if decimal_scan(to_string(glue_texts(m))) is
  231 + {
  232 + failure then failure,
  233 + success(n) then if n = 0
  234 + then failure
  235 + else success(n)
  236 + }.
  237 +
  238 +public define Result(MAML_Error,Value(Int))
  239 + eval_as_nzint
  240 + (
  241 + Toolbox tbox,
  242 + MAML_Pos pos,
  243 + MAML1 m
  244 + ) =
  245 + if simulate_html_pdf(must_be_nzint,glue_eval(tbox,m)) is
  246 + {
  247 + failure then error(must_be_a_nzint(pos,to_string(m))),
  248 + success(n) then ok(n)
  249 + }.
  250 +
  251 +
  252 +public define Maybe(Int)
  253 + must_be_pint
  254 + (
  255 + MAML2 m
  256 + ) =
  257 + if decimal_scan(to_string(glue_texts(m))) is
  258 + {
  259 + failure then failure,
  260 + success(n) then if n < 0
  261 + then failure
  262 + else success(n)
  263 + }.
  264 +
  265 +public define Result(MAML_Error,Value(Int))
  266 + eval_as_pint
  267 + (
  268 + Toolbox tbox,
  269 + MAML_Pos pos,
  270 + MAML1 m
  271 + ) =
  272 + if simulate_html_pdf(must_be_pint,glue_eval(tbox,m)) is
  273 + {
  274 + failure then error(must_be_a_positive_int(pos,to_string(m))),
  275 + success(n) then ok(n)
  276 + }.
  277 +
  278 +
  279 +
  280 + Test if an evaluated expression represents a boolean.
  281 +
  282 +define Maybe(Bool)
  283 + must_be_bool
  284 + (
  285 + MAML2 m
  286 + ) =
  287 + if glue_texts(m) is // glue_texts is necessary because we can have $false+empty for example
  288 + {
  289 + error(me) then failure,
  290 + erroneous(me,text) then failure,
  291 + empty then failure,
  292 + false then success(false),
  293 + true then success(true),
  294 + text(value) then failure,
  295 + variable(id) then failure,
  296 + list(l,d) then failure,
  297 + alpha(m1) then failure,
  298 + colorize(pos,cname,operand) then failure,
  299 + postpone(pos,text) then failure,
  300 + prim3(p3) then failure,
  301 + m1+m2 then failure
  302 + }.
  303 +
  304 +
  305 + The same one with debugging stuff:
  306 + define Maybe(Bool)
  307 + must_be_bool
  308 + (
  309 + MAML2 m
  310 + ) =
  311 + if glue_texts(m) is // glue_texts is necessary because we can have $false+empty for example
  312 + {
  313 + error(me) then iprint("[error]\n"); failure,
  314 + erroneous(me,text) then iprint("[erroneous]\n"); failure,
  315 + empty then iprint("[empty]\n"); failure,
  316 + false then iprint("[false]\n"); success(false),
  317 + true then iprint("[true]\n"); success(true),
  318 + text(value) then iprint("[text: "+value+"]\n"); failure,
  319 + variable(id) then iprint("[variable]\n"); failure,
  320 + colorize(pos,cname,operand) then iprint("[colorize]\n"); failure,
  321 + postpone(pos,text) then iprint("[postpone]\n"); failure,
  322 + prim3(p3) then iprint("[prim3]\n"); failure,
  323 + m1+m2 then iprint(to_string(m1)+"+"+to_string(m2)+"\n"); failure
  324 + }.
  325 +
  326 +
  327 +public define Result(MAML_Error,Value(Bool))
  328 + eval_as_bool
  329 + (
  330 + Toolbox tbox,
  331 + MAML_Pos pos,
  332 + MAML1 m
  333 + ) =
  334 + if simulate_html_pdf(must_be_bool,glue_eval(tbox,m)) is
  335 + {
  336 + failure then error(boolean_expected(pos,to_string(m))),
  337 + success(n) then ok(n)
  338 + }.
  339 +
  340 +
  341 +
  342 +define Maybe(String)
  343 + must_be_string
  344 + (
  345 + MAML2 m
  346 + ) =
  347 + success(to_string(glue_texts(m))).
  348 +
  349 +public define Result(MAML_Error,Value(String))
  350 + eval_as_string
  351 + (
  352 + Toolbox tbox,
  353 + MAML_Pos pos,
  354 + MAML1 m
  355 + ) =
  356 + if simulate_html_pdf(must_be_string,glue_eval(tbox,m)) is
  357 + {
  358 + failure then should_not_happen(error(string_expected(pos,to_string(m)))),
  359 + success(n) then ok(n)
  360 + }.
  361 +
  362 +
  363 +
  364 +define Maybe(One)
  365 + parse_symbol
  366 + (
  367 + One -> LexOut(SymbolToken,One) lex,
  368 + Bool done
  369 + ) =
  370 + if lex(unique) is
  371 + {
  372 + error(_) then failure,
  373 + ok(tok) then if tok is
  374 + {
  375 + end_of_input then if done then success(unique) else failure,
  376 + symbol then if done then failure else parse_symbol(lex,true)
  377 + }
  378 + }.
  379 +
  380 +
  381 +define Maybe(CCMode)
  382 + must_be_colorizercall_mode
  383 + (
  384 + MAML2 m
  385 + ) =
  386 + with s = to_string(glue_texts(m)),
  387 + if s = "ee" then success(ee) else
  388 + if s = "ei" then success(ei) else
  389 + if s = "ie" then success(ie) else
  390 + if s = "ii" then success(ii) else
  391 + failure.
  392 +
  393 +
  394 +public define Result(MAML_Error,Value(CCMode))
  395 + eval_as_colorizercall_mode
  396 + (
  397 + Toolbox tbox,
  398 + MAML_Pos pos,
  399 + MAML1 m
  400 + ) =
  401 + if simulate_html_pdf(must_be_colorizercall_mode,glue_eval(tbox,m)) is
  402 + {
  403 + failure then error(not_a_colorizercall_mode(pos,to_string(m))),
  404 + success(mode) then ok(mode)
  405 + }.
  406 +
  407 +
  408 +public define Maybe(String)
  409 + must_be_symbol
  410 + (
  411 + MAML2 m
  412 + ) =
  413 + with s = to_string(glue_texts(m)),
  414 + if parse_symbol(retrieve_lexer(symbol_lexer_desc,symbol_lexer,end_of_input)
  415 + (make_lexing_stream("",s),unique),false) is
  416 + {
  417 + failure then failure,
  418 + success(_) then success(s)
  419 + }.
  420 +
  421 +public define Result(MAML_Error,Value(String))
  422 + eval_as_symbol
  423 + (
  424 + Toolbox tbox,
  425 + MAML_Pos pos,
  426 + MAML1 m
  427 + ) =
  428 + if simulate_html_pdf(must_be_symbol,glue_eval(tbox,m)) is
  429 + {
  430 + failure then error(must_be_a_symbol(pos,to_string(m))),
  431 + success(n) then ok(n)
  432 + }.
  433 +
  434 +
  435 +define Value($T)
  436 + same
  437 + (
  438 + $T t
  439 + ) =
  440 + value(t,t).
  441 +
  442 +
  443 +
  444 + *** Expanding macros, without evaluating.
  445 +
  446 +define MAML1 -> MAML1
  447 + expand_macros
  448 + (
  449 + MacroTree mt
  450 + ) =
  451 + (MAML1 m) |-f->
  452 + if m is
  453 + {
  454 + error(me) then m,
  455 + erroneous(me,text) then m,
  456 + empty then m,
  457 + text(value) then m,
  458 + variable(id) then m,
  459 + prim1(p1) then prim1(map(f,p1)),
  460 + list(l,d) then list(map(f,l),d),
  461 + alpha(m1) then alpha(f(m1)),
  462 + colorize(pos,cname,operand) then colorize(pos,cname,f(operand)),
  463 + define(pos,name,ar,val) then define(pos,name,ar,f(val)),
  464 + undefine(pos,name) then m,
  465 + _if(pos,test,ift,iff) then _if(pos,f(test),f(ift),f(iff)),
  466 + prim3(p3) then prim3(map(f,p3)),
  467 + computed(m2) then m,
  468 + macro(pos,name,operands) then with eops = map(f,operands),
  469 + if get(name,mt) is
  470 + {
  471 + failure then error(unknown_macro_name(pos,name)),
  472 + success(l) then if l is
  473 + {
  474 + [ ] then error(unknown_macro_name(pos,name)),
  475 + [h . t] then since h is macro(_,ar,body),
  476 + f(replace_vars_in_MAML(body,eops))
  477 + }
  478 + },
  479 + m1 + m2 then f(m1) + f(m2)
  480 + }.
  481 +
  482 +
  483 +
  484 + Comparison for sorting MAML lists.
  485 +
  486 +define Maybe(MAML2) alpha_part (List(MAML2) l).
  487 +
  488 +public define Maybe(MAML2)
  489 + alpha_part // find $alphabetic(m1) in m and return m1
  490 + (
  491 + MAML2 m
  492 + ) =
  493 + if m is
  494 + {
  495 + error(me) then failure,
  496 + erroneous(me,text) then failure,
  497 + empty then failure,
  498 + false then failure,
  499 + true then failure,
  500 + text(value) then failure,
  501 + variable(id) then failure,
  502 + list(l,_) then alpha_part(l),
  503 + alpha(m1) then success(m1),
  504 + colorize(pos,cname,operand) then alpha_part(operand),
  505 + postpone(pos,text) then failure,
  506 + prim3(p3) then alpha_part(p3),
  507 + m1+m2 then if alpha_part(m1) is
  508 + {
  509 + failure then alpha_part(m2),
  510 + success(m1a) then success(m1a)
  511 + }
  512 + }.
  513 +
  514 +
  515 +define Maybe(MAML2)
  516 + alpha_part // find $alphabetic(m1) in m and return m1
  517 + (
  518 + List(MAML2) l
  519 + ) =
  520 + if l is
  521 + {
  522 + [ ] then failure,
  523 + [h . t] then if alpha_part(h) is
  524 + {
  525 + failure then alpha_part(t),
  526 + success(p) then success(p)
  527 + }
  528 + }.
  529 +
  530 +
  531 +
  532 +define Bool
  533 + maml_alpha_compare
  534 + (
  535 + MAML2 m1,
  536 + MAML2 m2
  537 + ) =
  538 + if alpha_part(m1) is
  539 + {
  540 + failure then true,
  541 + success(p1) then if alpha_part(m2) is
  542 + {
  543 + failure then false,
  544 + success(p2) then string_less(to_string(p1),to_string(p2))
  545 + }
  546 + }.
  547 +
  548 +
  549 +define Maybe(List(MAML2))
  550 + is_list
  551 + (
  552 + MAML2 m
  553 + ) =
  554 + if m is
  555 + {
  556 + error(me) then failure,
  557 + erroneous(me,text) then failure,
  558 + empty then failure,
  559 + false then failure,
  560 + true then failure,
  561 + text(value) then failure,
  562 + variable(id) then failure,
  563 + list(l,d) then success(l),
  564 + alpha(m1) then failure,
  565 + colorize(pos,cname,operand) then failure, // maybe something to do here
  566 + postpone(pos,text) then failure,
  567 + prim3(p3) then failure,
  568 + m1+m2 then failure
  569 + }.
  570 +
  571 +
  572 +define Maybe(List(List(MAML2)))
  573 + are_lists
  574 + (
  575 + List(MAML2) l
  576 + ) =
  577 + if l is
  578 + {
  579 + [ ] then success([ ]),
  580 + [h . t] then if are_lists(t) is
  581 + {
  582 + failure then failure,
  583 + success(rest) then if is_list(h) is
  584 + {
  585 + failure then failure,
  586 + success(h1) then success([h1 . rest])
  587 + }
  588 + }
  589 + }.
  590 +
  591 +define Maybe(List(List(MAML2)))
  592 + is_list_of_lists
  593 + (
  594 + MAML2 m
  595 + ) =
  596 + if is_list(m) is
  597 + {
  598 + failure then failure,
  599 + success(l) then are_lists(l)
  600 + }.
  601 +
  602 +define Bool is_empty(MAML2 m) = to_string(m) = "".
  603 +
  604 +
  605 +define List(List(MAML2))
  606 + add_in_front
  607 + (
  608 + List(MAML2) line,
  609 + List(List(MAML2)) rest,
  610 + ) =
  611 + if line is
  612 + {
  613 + [ ] then [ ],
  614 + [a1 . as] then if rest is
  615 + {
  616 + [ ] then map((MAML2 a) |-> [a],line),
  617 + [r1 . rs] then [[a1 . r1] . add_in_front(as,rs)]
  618 + }
  619 + }.
  620 +
  621 +define List(List(MAML2))
  622 + add_in_front_fill
  623 + (
  624 + List(MAML2) line,
  625 + List(List(MAML2)) rest,
  626 + ) =
  627 + if line is
  628 + {
  629 + [ ] then map((List(MAML2) l) |-> [text("") . l],rest),
  630 + [a1 . as] then if rest is
  631 + {
  632 + [ ] then map((MAML2 a) |-> [a],line),
  633 + [r1 . rs] then [[a1 . r1] . add_in_front_fill(as,rs)]
  634 + }
  635 + }.
  636 +
  637 +
  638 +define List(List(MAML2))
  639 + transpose
  640 + (
  641 + List(List(MAML2)) ll
  642 + ) =
  643 + if ll is
  644 + {
  645 + [ ] then [ ],
  646 + [line1 . lines] then with rest = transpose(lines),
  647 + if length(line1) = length(rest)
  648 + then add_in_front(line1,rest)
  649 + else add_in_front_fill(line1,rest)
  650 + }.
  651 +
  652 +
  653 +define List($T)
  654 + sublist
  655 + (
  656 + Int start, // already known as positive or zero and start =< end
  657 + Int end, // return all elements between number start (included) to number end (not included)
  658 + List($T) l
  659 + ) =
  660 + if end =< 0 then [ ] else
  661 + if l is
  662 + {
  663 + [ ] then [ ],
  664 + [h . t] then
  665 + if start > 0
  666 + then sublist(start-1,end-1,t)
  667 + else [h . sublist(0,end-1,t)]
  668 + }.
  669 +
  670 +
  671 +define MAML2
  672 + shuffle
  673 + (
  674 + List(String) d,
  675 + List(MAML2) l
  676 + ) =
  677 + if l is
  678 + {
  679 + [ ] then text(concat(d)),
  680 + [l1 . ls] then if d is
  681 + {
  682 + [ ] then sum(l),
  683 + [d1 . ds] then
  684 + text(d1)+l1+shuffle(ds,ls)
  685 + }
  686 + }.
  687 +
  688 +define MAML2
  689 + do_nolist
  690 + (
  691 + MAML2 m
  692 + ) =
  693 + if m is
  694 + {
  695 + error(me) then m,
  696 + erroneous(me,text) then m,
  697 + empty then m,
  698 + false then m,
  699 + true then m,
  700 + text(value) then m,
  701 + variable(id) then m,
  702 + list(l,deco) then with l1 = map(do_nolist,l),
  703 + shuffle(deco,l1),
  704 + alpha(m1) then alpha(do_nolist(m1)),
  705 + colorize(pos,cname,operand) then colorize(pos,cname,do_nolist(operand)),
  706 + postpone(pos,text) then m,
  707 + prim3(p3) then prim3(map(do_nolist,p3)),
  708 + m1+m2 then do_nolist(m1) + do_nolist(m2)
  709 + }.
  710 +
  711 +
  712 +
  713 + *** Evaluating category 1 marks.
  714 +
  715 + For each category 1 mark, we must:
  716 + - (1) evaluate the operands,
  717 + - (2) check they have the required form,
  718 + - (3) execute the action.
  719 +
  720 + In the function 'eval_prim1', we don't use 'eval_as_symbol', etc... because since category 1 marks
  721 + desapppear, they should not contain any $ifhtml nor any $ifpdf.
  722 +
  723 +define MAML2
  724 + eval_prim1
  725 + (
  726 + Toolbox tbox,
  727 + List(PrimName) stk,
  728 + MAML_Prim1 pr1 // the mark together with its operands
  729 + ) =
  730 + ////////////////////// Category 1a ////////////////////////////////////////////
  731 + //iprint("eval_prim1\n");
  732 + if pr1 is
  733 + {
  734 + /// $accumulator(name)
  735 + _accumulator(pos,_name) then
  736 + if must_be_symbol(glue_eval(tbox,_name)) is
  737 + {
  738 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  739 + success(name) then
  740 + with v = tbox.keep.accumulator_tree_v,
  741 + v <- insert(name,[],*v); empty
  742 + },
  743 +
  744 + /// $addtocounter(symbol)(int)
  745 + _addtocounter(pos,_name,_val) then
  746 + if must_be_symbol(glue_eval(tbox,_name)) is
  747 + {
  748 + failure then error(unknown_counter(pos,to_string(_name))),
  749 + success(name) then if must_be_int(glue_eval(tbox,_val)) is
  750 + {
  751 + failure then error(invalid_number_to_add(pos,to_string(_val))),
  752 + success(val) then
  753 + with v = tbox.keep.counter_tree_v,
  754 + since ((CounterTree,(Maybe(List(Int)),MAML2)))get_update(name,*v,(Maybe(List(Int)) mb_l) |->
  755 + if mb_l is
  756 + {
  757 + failure then (failure, error(unknown_counter(pos,name))),
  758 + success(l) then if l is
  759 + {
  760 + [ ] then (failure, error(unknown_counter(pos,name))),
  761 + [h . t] then (success([h+val . t]),empty)
  762 + }
  763 + }) is (new_tree,p),
  764 + v <- new_tree;
  765 + since p is (_,result), result
  766 + }
  767 + },
  768 +
  769 + /// $append(name)(text)
  770 + _append(pos,_name,_text) then
  771 + if must_be_symbol(glue_eval(tbox,_name)) is
  772 + {
  773 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  774 + success(name) then with text = glue_eval(tbox,_text),
  775 + v = tbox.keep.accumulator_tree_v,
  776 + since get_update(name,*v,(Maybe(List(MAML2)) mbm) |-> if mbm is
  777 + {
  778 + failure then failure,
  779 + success(text1) then success([text . text1])
  780 + }) is (new_tree,mbv),
  781 + v <- new_tree;
  782 + if mbv is
  783 + {
  784 + failure then error(unknown_accumulator(pos,name)),
  785 + success(_) then empty
  786 + }
  787 + },
  788 +
  789 + /// $colorizer(symbol)
  790 + _colorizer(pos,_name) then
  791 + if must_be_symbol(glue_eval(tbox,_name)) is
  792 + {
  793 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  794 + success(name) then create_colorizer(tbox,pos,name)
  795 + },
  796 +
  797 + /// $colorizercall(mode)(symbol)(string)(symbol)(string)
  798 + _colorizercall(pos,_mode,_cn1,_call,_cn2,_return) then
  799 + if must_be_colorizercall_mode(glue_eval(tbox,_mode)) is
  800 + {
  801 + failure then error(not_a_colorizercall_mode(pos,to_string(_mode))),
  802 + success(mode) then if must_be_symbol(glue_eval(tbox,_cn1)) is
  803 + {
  804 + failure then error(must_be_a_symbol(pos,to_string(_cn1))),
  805 + success(cn1) then if must_be_symbol(glue_eval(tbox,_cn2)) is
  806 + {
  807 + failure then error(must_be_a_symbol(pos,to_string(_cn2))),
  808 + success(cn2) then record_colorizercall(tbox,
  809 + mode,
  810 + cn1,
  811 + to_string(glue_eval(tbox,_call)),
  812 + cn2,
  813 + to_string(glue_eval(tbox,_return)))
  814 + }
  815 + }
  816 + },
  817 +
  818 + /// $colorrule(symbol)(string)(maml)
  819 + _colorrule(pos,_cn,_reg,_val) then
  820 + if must_be_symbol(glue_eval(tbox,_cn)) is
  821 + {
  822 + failure then error(must_be_a_symbol(pos,to_string(_cn))),
  823 + success(cn) then record_colorrule(tbox,
  824 + cn,
  825 + to_string(glue_eval(tbox,_reg)),
  826 + _val)
  827 + },
  828 +
  829 + /// $output(maml)(maml)
  830 + _output(pos,_path,text) then
  831 + with path = to_string(glue_eval(tbox,_path)),
  832 + if file(path,new) is
  833 + {
  834 + failure then error(cannot_write_file(path)),
  835 + success(fp) then print(weaken(fp),to_string(text)); empty
  836 + },
  837 +
  838 + /// $popcounter(symbol)
  839 + _popcounter(pos,_name) then
  840 + if must_be_symbol(glue_eval(tbox,_name)) is
  841 + {
  842 + failure then error(unknown_counter(pos,to_string(_name))),
  843 + success(name) then
  844 + with v = tbox.keep.counter_tree_v,
  845 + v <- update(name,*v,(Maybe(List(Int)) mbl) |-> if mbl is
  846 + {
  847 + failure then failure,
  848 + success(l) then if l is
  849 + {
  850 + [ ] then failure,
  851 + [h . t] then success(t)
  852 + }
  853 + });
  854 + empty
  855 + },
  856 +
  857 + /// $pushcounter(symbol)(int)
  858 + _pushcounter(pos,_name,_init) then
  859 + if must_be_symbol(glue_eval(tbox,_name)) is
  860 + {
  861 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  862 + success(name) then if must_be_int(glue_eval(tbox,_init)) is
  863 + {
  864 + failure then error(must_be_an_int(pos,to_string(_init))),
  865 + success(init) then with v = tbox.keep.counter_tree_v,
  866 + v <- update(name,*v,(Maybe(List(Int)) mbl) |-> if mbl is
  867 + {
  868 + failure then success([init]),
  869 + success(l) then success([init . l])
  870 + }); empty
  871 + }
  872 + },
  873 +
  874 + /// $setcounter(symbol)(int)
  875 + _setcounter(pos,_name,_val) then
  876 + if must_be_symbol(glue_eval(tbox,_name)) is
  877 + {
  878 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  879 + success(name) then if must_be_int(glue_eval(tbox,_val)) is
  880 + {
  881 + failure then error(must_be_an_int(pos,to_string(_val))),
  882 + success(val) then with v = tbox.keep.counter_tree_v,
  883 + since ((CounterTree,(Maybe(List(Int)),MAML2)))get_update(name,*v,(Maybe(List(Int)) mbl) |-> if mbl is
  884 + {
  885 + failure then (failure,error(unknown_counter(pos,name))),
  886 + success(l) then if l is
  887 + {
  888 + [ ] then (failure,error(unknown_counter(pos,name))),
  889 + [h . t] then (success([val . t]),empty)
  890 + }
  891 + }
  892 + ) is (new_tree,p),
  893 + v <- new_tree;
  894 + since p is (_,result), result
  895 + }
  896 + },
  897 +
  898 +
  899 + /////////////////////////////// Category 1b ////////////////////////////////////////:
  900 + /// $add(n)(m)
  901 + _add(pos,_n,_m) then
  902 + if must_be_int(glue_eval(tbox,_n)) is
  903 + {
  904 + failure then error(must_be_an_int(pos,to_string(_n))),
  905 + success(n) then if must_be_int(glue_eval(tbox,_m)) is
  906 + {
  907 + failure then error(must_be_an_int(pos,to_string(_m))),
  908 + success(m) then text(to_decimal(n+m))
  909 + }
  910 + },
  911 +
  912 + /// $apply(name)(list)
  913 + _apply(pos,_name,_list) then
  914 + with op = (MAML2)glue_eval(tbox,_list), // the computed operand
  915 + //iprint("_apply: op = "+to_string_all(op)+" at "+format(pos)+"\n");
  916 + if must_be_symbol(glue_eval(tbox,_name)) is
  917 + {
  918 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  919 + success(name) then
  920 + // since we must know if '_list' actually represents a list, we must compute it.
  921 + // Then, we have to apply the macro to an already computed operand. The body of definition
  922 + // of the macro is a MAML1 containing a $1. We can evaluate this body since $1 will remain
  923 + // $1. Then we can replace $1 by the (MAML2)operand, but we still need to compute, because
  924 + // this replacement can create non completely computed stuff. It is well known in logic that
  925 + // replacement creates new redexes.
  926 + if get_apply_function(tbox,pos,name) is
  927 + // getting a function representing the macro especially designed for $apply (see maml4_lexers.anubis)
  928 + {
  929 + error(e) then error(e), // incorrect name or macro not found or macro of bad arity
  930 + ok(f) then // the macro in the form of a function MAML2 -> MAML2
  931 + if is_list(op) is
  932 + {
  933 + failure then error(not_a_list(pos,to_string(op))),
  934 + success(l) then list(map(f,l),[])
  935 + }
  936 + }
  937 + },
  938 +
  939 + /// $content(name)
  940 + _content(pos,_name) then
  941 + if must_be_symbol(glue_eval(tbox,_name)) is
  942 + {
  943 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  944 + success(name) then
  945 + with v = tbox.keep.accumulator_tree_v,
  946 + if get(name,*v) is
  947 + {
  948 + failure then error(unknown_accumulator(pos,name)),
  949 + success(t) then //v <- remove(name,*v); // $content destroys the accumulator
  950 + //iprint("_content: got "+to_string(sum(t))+"\n");
  951 + list(reverse(t),[])
  952 + }
  953 + },
  954 +
  955 + /// $countervalue(symbol)
  956 + _countervalue(pos,_name) then
  957 + if must_be_symbol(glue_eval(tbox,_name)) is
  958 + {
  959 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  960 + success(name) then get_counter_value(tbox,pos,name)
  961 + },
  962 +
  963 + /// $defined(symbol)
  964 + _defined(pos,_name) then
  965 + //iprint("---> at "+format(pos)+" $defined("+to_string(_name)+") = ");
  966 + if must_be_symbol(text(to_string(_name))) is
  967 + {
  968 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  969 + success(name) then with v = tbox.keep.macro_tree_v,
  970 + if get(name,*v) is
  971 + {
  972 + failure then //iprint("false\n");
  973 + false,
  974 + success(l) then if l is
  975 + {
  976 + [ ] then //iprint("false\n");
  977 + false,
  978 + [_ . _] then //iprint("true\n");
  979 + true
  980 + }
  981 + }
  982 + },
  983 +
  984 + /// $$
  985 + _dollar(pos) then text("$"),
  986 +
  987 + /// $equals(maml)(maml)
  988 + _equals(pos,_e1,_e2) then
  989 + with e1 = glue_eval(tbox,_e1),
  990 + e2 = glue_eval(tbox,_e2),
  991 + ers = extract_errors(e1+e2),
  992 + if ers is
  993 + {
  994 + [ ] then //iprint("===== "+to_string(e1)+" == "+to_string(e2)+" ====\n");
  995 + if to_string(e1) = to_string(e2) // will identify more
  996 + then (MAML2)true // the explicit typing is not necessary here
  997 + else (MAML2)false,
  998 + [_ . _] then add_errors(ers)
  999 + },
  1000 +
  1001 + /// $false
  1002 + _false(pos) then false,
  1003 +
  1004 + /// $input(path)
  1005 + _input(pos,_path) then
  1006 + with path = to_string(_path),
  1007 + since ((String,String))split_path(path) is (rel_path,fname),
  1008 + with abs_path = (tbox.file_path)/path,
  1009 + if file(abs_path,read) is
  1010 + {
  1011 + failure then error(file_not_found(pos,abs_path)),
  1012 + success(fp) then
  1013 + if make_lexing_stream("",fp,1000,10) is
  1014 + {
  1015 + failure then error(cannot_read_file(pos,abs_path)),
  1016 + success(ls) then
  1017 + with tbox1 = make_toolbox((tbox.file_path)/rel_path,
  1018 + fname,
  1019 + ls,
  1020 + tbox.keep),
  1021 + parse_eval(tbox1),
  1022 + }
  1023 + },
  1024 +
  1025 + /// $latex(string)
  1026 + _latex(pos,_text) then
  1027 + with text = to_string(_text),
  1028 + with html_opts = tbox.keep.html_options,
  1029 + with fsize = font_size(html_opts),
  1030 + with note_fsize = note_font_size(html_opts),
  1031 + with rf = if within(stk,note) then (30.0/note_fsize) else (26.4/fsize),
  1032 + with r = latex_to_png(text,html_opts),
  1033 + //iprint("back from latex_to_png\n");
  1034 + if r is
  1035 + {
  1036 + error(msg) then error(msg),
  1037 + log_file(path) then error(latex_error(pos,path)),
  1038 + png_file_down(fname,w,h,down) then
  1039 + if has_a_display(text)
  1040 + then prim3(displaylatex(pos,same(text),same(fname),same(w/rf),same(h/rf),same(down/rf)))
  1041 + else prim3(inlinelatex (pos,same(text),same(fname),same(w/rf),same(h/rf),same(down/rf)))
  1042 + },
  1043 +
  1044 + /// $length(list)
  1045 + _length(pos,_list) then
  1046 + //iprint("_length: _list = "+to_string_all(_list)+"\n");
  1047 + with op = glue_eval(tbox,_list),
  1048 + //iprint("_length: op = "+to_string_all(op)+"\n");
  1049 + if is_list(op) is
  1050 + {
  1051 + failure then error(not_a_list(pos,to_string(_list))),
  1052 + success(l) then text(to_decimal(length(l)))
  1053 + },
  1054 +
  1055 + /// $lpar
  1056 + _lpar(pos) then text("("),
  1057 +
  1058 + /// $minus(n)(m)
  1059 + _minus(pos,_n,_m) then
  1060 + if must_be_int(glue_eval(tbox,_n)) is
  1061 + {
  1062 + failure then error(must_be_an_int(pos,to_string(_n))),
  1063 + success(n) then if must_be_int(glue_eval(tbox,_m)) is
  1064 + {
  1065 + failure then error(must_be_an_int(pos,to_string(_m))),
  1066 + success(m) then text(to_decimal(n-m))
  1067 + }
  1068 + },
  1069 +
  1070 + /// $mul(n)(m)
  1071 + _mul(pos,_n,_m) then
  1072 + if must_be_int(glue_eval(tbox,_n)) is
  1073 + {
  1074 + failure then error(must_be_an_int(pos,to_string(_n))),
  1075 + success(n) then if must_be_int(glue_eval(tbox,_m)) is
  1076 + {
  1077 + failure then error(must_be_an_int(pos,to_string(_m))),
  1078 + success(m) then text(to_decimal(n*m))
  1079 + }
  1080 + },
  1081 +
  1082 + /// $nolist(text)
  1083 + _nolist(pos,_text) then
  1084 + with text = eval(tbox,_text),
  1085 + do_nolist(text),
  1086 +
  1087 + /// $opp(n)
  1088 + _opp(pos,_n) then
  1089 + if must_be_int(glue_eval(tbox,_n)) is
  1090 + {
  1091 + failure then error(must_be_an_int(pos,to_string(_n))),
  1092 + success(n) then text(to_decimal(-n))
  1093 + },
  1094 +
  1095 + /// $postpone(text)
  1096 + _postpone(pos,_text) then
  1097 + postpone(pos,_text),
  1098 +
  1099 + /// $quotient(n)(m)
  1100 + _quotient(pos,_n,_m) then
  1101 + if must_be_int(glue_eval(tbox,_n)) is
  1102 + {
  1103 + failure then error(must_be_an_int(pos,to_string(_n))),
  1104 + success(n) then if must_be_nzint(glue_eval(tbox,_m)) is
  1105 + {
  1106 + failure then error(must_be_a_nzint(pos,to_string(_m))),
  1107 + success(m) then if n/m is
  1108 + {
  1109 + failure then error(must_be_a_nzint(pos,to_string(_m))),
  1110 + success(p) then since p is (q,r), text(to_decimal(q))
  1111 + }
  1112 + }
  1113 + },
  1114 +
  1115 + /// $remainder(n)(m)
  1116 + _remainder(pos,_n,_m) then
  1117 + if must_be_int(glue_eval(tbox,_n)) is
  1118 + {
  1119 + failure then error(must_be_an_int(pos,to_string(_n))),
  1120 + success(n) then if must_be_nzint(glue_eval(tbox,_m)) is
  1121 + {
  1122 + failure then error(must_be_a_nzint(pos,to_string(_m))),
  1123 + success(m) then if n/m is
  1124 + {
  1125 + failure then error(must_be_a_nzint(pos,to_string(_m))),
  1126 + success(p) then since p is (q,r), text(to_decimal(r))
  1127 + }
  1128 + }
  1129 + },
  1130 +
  1131 + /// $reverse(list)
  1132 + _reverse(pos,_op) then
  1133 + with op = glue_eval(tbox,_op),
  1134 + if is_list(op) is
  1135 + {
  1136 + failure then error(not_a_list(pos,to_string(_op))),
  1137 + success(l) then list(reverse(l),[])
  1138 + },
  1139 +
  1140 + /// $rpar
  1141 + _rpar(pos) then text(")"),
  1142 +
  1143 + /// $sort(list)
  1144 + _sort(pos,_op) then
  1145 + //iprint("sorting item: "+to_string_all(_op)+"\n");
  1146 + with op = glue_eval(tbox,_op),
  1147 + if is_list(op) is
  1148 + {
  1149 + failure then //iprint(" which is not a list\n");
  1150 + op,
  1151 + success(l) then ///iprint(" which is a list of "+length(l)+" element.\n");
  1152 + list(merge_sort(l,maml_alpha_compare),[])
  1153 + },
  1154 +
  1155 + /// $sublist(start)(end)(list)
  1156 + _sublist(pos,_start,_end,_list) then
  1157 + if must_be_int(glue_eval(tbox,_start)) is
  1158 + {
  1159 + failure then error(must_be_an_int(pos,to_string(_start))),
  1160 + success(start) then if must_be_int(glue_eval(tbox,_end)) is
  1161 + {
  1162 + failure then error(must_be_an_int(pos,to_string(_end))),
  1163 + success(end) then if is_list(glue_eval(tbox,_list)) is
  1164 + {
  1165 + failure then error(not_a_list(pos,to_string(_list))),
  1166 + success(l) then
  1167 + with s = (if start < 0 then 0 else start),
  1168 + e = (if end > length(l) then length(l) else end),
  1169 + if e =< s
  1170 + then list([],[])
  1171 + else list(sublist(s,e,l),[])
  1172 + }
  1173 + }
  1174 + },
  1175 +
  1176 + /// $thisfilepath
  1177 + _thisfilepath(pos) then text(tbox.file_path),
  1178 +
  1179 + /// $transpose(list)
  1180 + _transpose(pos,_list) then
  1181 + with mblol = glue_eval(tbox,_list),
  1182 + if is_list_of_lists(mblol) is
  1183 + {
  1184 + failure then mblol,
  1185 + success(lol) then list(map((List(MAML2) r) |-> list(r,[]),transpose(lol)),[]),
  1186 + },
  1187 +
  1188 + /// $true
  1189 + _true(pos) then true,
  1190 +
  1191 + /// $verbatim(text)
  1192 + _verbatim(pos,txt) then text(to_string(txt))
  1193 + }.
  1194 +
  1195 +
  1196 +
  1197 +
  1198 +public define MAML2
  1199 + eval
  1200 + (
  1201 + Toolbox tbox,
  1202 + MAML1 m
  1203 + ) =
  1204 + //iprint("eval\n");
  1205 + if m is
  1206 + {
  1207 + error(me) then error(me),
  1208 + erroneous(me,text) then erroneous(me,text),
  1209 + empty then empty,
  1210 + text(value) then text(value),
  1211 + variable(id) then variable(id),
  1212 + prim1(p1) then eval_prim1(tbox,[],p1),
  1213 + list(l,d) then list(map((MAML1 m1) |-> eval(tbox,m1),l),d),
  1214 + alpha(m1) then alpha(glue_eval(tbox,m1)),
  1215 +
  1216 +
  1217 +
  1218 + colorize(pos,cname,text) then //colorize(pos,to_string(glue_eval(tbox,cname)),glue_eval(tbox,text)),
  1219 + with name = to_string(glue_eval(tbox,cname)),
  1220 + txt = glue_eval(tbox,text),
  1221 + with a = glue_texts(handle_calls(*tbox.keep.call_lexer_tree_v,[name],glue_texts(txt))),
  1222 + color_lexers = *tbox.keep.color_lexer_tree_v,
  1223 + //print(to_string(a)+"\n");
  1224 + if get(name,color_lexers) is
  1225 + {
  1226 + failure then error(unknown_colorizer(name)),
  1227 + success(col) then can(colorize_2b(tbox,color_lexers,[col],a))
  1228 + },
  1229 +
  1230 +
  1231 +
  1232 +
  1233 +
  1234 + define(pos,name,ar,val) then //iprint("eval $define("+name+")... at "+format(pos)+"\n");
  1235 + with v = tbox.keep.macro_tree_v,
  1236 + value = expand_macros(*v)(val),
  1237 + v <- update(name,*v,(Maybe(List(MacroDef)) mbl) |-> if mbl is
  1238 + {
  1239 + failure then success([macro(name,cst_maml_arity(ar),value)]),
  1240 + success(l) then success([macro(name,cst_maml_arity(ar),value) . l])
  1241 + }); empty,
  1242 + undefine(pos,name) then with v = tbox.keep.macro_tree_v,
  1243 + v <- update(name,*v,(Maybe(List(MacroDef)) mbl) |-> if mbl is
  1244 + {
  1245 + failure then failure,
  1246 + success(l) then if l is
  1247 + {
  1248 + [ ] then failure,
  1249 + [h . t] then success(t)
  1250 + }
  1251 + }); empty,
  1252 + _if(pos,test,ift,iff) then if must_be_bool(glue_eval(tbox,test)) is
  1253 + {
  1254 + failure then error(boolean_expected(pos,to_string(test))),
  1255 + success(b) then if b
  1256 + then eval(tbox,ift)
  1257 + else eval(tbox,iff)
  1258 + },
  1259 + prim3(p3) then eval_prim3(tbox,p3),
  1260 + computed(m2) then m2,
  1261 + macro(pos,name,operands) then eval_macro(tbox,pos,name,operands),
  1262 + m1 + m2 then with m1a = eval(tbox,m1), // the two 'with' are necessary for preserving
  1263 + m2a = eval(tbox,m2), // execution order ('eval' is non deterministic)
  1264 + m1a + m2a
  1265 + }.
  1266 +
  1267 +
  1268 +
  1269 +define MAML2
  1270 + eval_macro
  1271 + (
  1272 + Toolbox tbox,
  1273 + MAML_Pos pos,
  1274 + String name,
  1275 + List(MAML1) operands
  1276 + ) =
  1277 + //iprint("eval_macro: "+name+"\n");
  1278 + if get(name,*tbox.keep.macro_tree_v) is
  1279 + {
  1280 + failure then should_not_happen(error(unknown_macro_name(make_pos(tbox),name))),
  1281 + success(l) then if l is
  1282 + {
  1283 + [ ] then should_not_happen(error(unknown_macro_name(make_pos(tbox),name))),
  1284 + [h . t] then since h is macro(_,arity,body),
  1285 + with r = replace_vars_in_MAML(body,operands),
  1286 + glue_eval(tbox,r)
  1287 + }
  1288 + }.
  1289 +
  1290 +
  1291 +
  1292 +
  1293 +define MAML2
  1294 + record_colorizercall
  1295 + (
  1296 + Toolbox tbox,
  1297 + CCMode mode,
  1298 + String cn1,
  1299 + String _call,
  1300 + String cn2,
  1301 + String _return
  1302 + ) =
  1303 + with v = tbox.keep.colorcall_v,
  1304 + v <- [colorcall(mode,cn1,_call,cn2,_return) . *v];
  1305 + empty.
  1306 +
  1307 +
  1308 +define MAML2
  1309 + record_colorrule
  1310 + (
  1311 + Toolbox tbox,
  1312 + String cn,
  1313 + String regexpr,
  1314 + MAML1 value
  1315 + ) =
  1316 + with v = tbox.keep.colorrules_v,
  1317 + v <- [rule(cn,regexpr,value) . *v];
  1318 + empty.
  1319 +
  1320 +define MAML2
  1321 + get_counter_value
  1322 + (
  1323 + Toolbox tbox,
  1324 + MAML_Pos pos,
  1325 + String name
  1326 + ) =
  1327 + with v = tbox.keep.counter_tree_v,
  1328 + if get(name,*v) is
  1329 + {
  1330 + failure then error(unknown_counter(pos,name)),
  1331 + success(l) then if l is
  1332 + {
  1333 + [ ] then error(unknown_counter(pos,name)),
  1334 + [h . _] then text(to_decimal(h))
  1335 + }
  1336 + }.
  1337 +
  1338 +
  1339 +
  1340 +
  1341 + -----------------------------------------------------------------------------------------
  1342 +
  1343 +
0 1344 \ No newline at end of file
... ...
anubis_dev/library/doc_tools/maml4_html.anubis 0 → 100644
  1 +
  2 + MAML 4
  3 +
  4 + Generating the HTML output.
  5 +
  6 +transmit maml4_parser.anubis
  7 +
  8 +
  9 +public define Text to_HTML (MAML_HTML_Options options,
  10 + MAML3 text).
  11 +
  12 +public define MAML_HTML_Options default.
  13 +
  14 +
  15 + --- That's all for the public part ! -------------------------------------------------------------
  16 +
  17 +
  18 + *** Default options for HTML.
  19 +
  20 +public define MAML_HTML_Options
  21 + default
  22 + =
  23 + options(
  24 + "png", // png_path_server
  25 + "png", // png_path_client
  26 + "tmp", // tmp_path
  27 + 12, // font size
  28 + 10, // footnote font size
  29 + 600 // width of text (pixels)
  30 + ).
  31 +
  32 +
  33 + *** MAML3 -> HTML
  34 +
  35 +type HTML_SpecialChar:
  36 + lt,
  37 + gt,
  38 + amp.
  39 +
  40 +type HTML_Token:
  41 + end_of_input,
  42 + text (String),
  43 + special (HTML_SpecialChar).
  44 +
  45 +define List(LexerItem(HTML_Token,One))
  46 + html_lex_desc
  47 + =
  48 + [
  49 + lexer_item("#<", return((ByteArray b, LexingTools t, One u) |-> ok(special(lt)))),
  50 + lexer_item("#>", return((ByteArray b, LexingTools t, One u) |-> ok(special(gt)))),
  51 + lexer_item("#&", return((ByteArray b, LexingTools t, One u) |-> ok(special(amp)))),
  52 + lexer_item("[^#<#>#&]+", return((ByteArray b, LexingTools t, One u) |-> ok(text(to_string(b)))))
  53 + ].
  54 +
  55 +global define One
  56 + make_html_lexer
  57 + (
  58 + List(String) _
  59 + ) =
  60 + make_precompiled_lexer("html_lexer", html_lex_desc, '#').
  61 +
  62 +execute anbexec make_html_lexer
  63 +read generated/html_lexer.anubis
  64 +
  65 +define List(HTML_Token)
  66 + parse_html_specials
  67 + (
  68 + One -> LexOut(HTML_Token,One) lex
  69 + ) =
  70 + if lex(unique) is
  71 + {
  72 + error(_) then should_not_happen([]),
  73 + ok(tok) then if tok is
  74 + {
  75 + end_of_input then [],
  76 + text(s) then [text(s) . parse_html_specials(lex)],
  77 + special(c) then [special(c) . parse_html_specials(lex)]
  78 + }
  79 + }.
  80 +
  81 +define List(String)
  82 + html_assemble
  83 + (
  84 + List(HTML_Token) l
  85 + ) =
  86 + if l is
  87 + {
  88 + [ ] then [ ],
  89 + [h . t] then if h is
  90 + {
  91 + end_of_input then should_not_happen(html_assemble(t)),
  92 + text(s) then [s . html_assemble(t)],
  93 + special(c) then [if c is
  94 + {
  95 + lt then "&lt;",
  96 + gt then "&gt;",
  97 + amp then "&amp;"
  98 + } . html_assemble(t)]
  99 + }
  100 + }.
  101 +
  102 +define String
  103 + handle_html_special_chars // replace < by &lt; etc...
  104 + (
  105 + String s
  106 + ) =
  107 + with ls = make_lexing_stream("",s),
  108 + lex = retrieve_lexer(html_lex_desc, html_lexer, end_of_input)(ls,unique),
  109 + text = parse_html_specials(lex),
  110 + concat(html_assemble(text)).
  111 +
  112 +
  113 +
  114 +
  115 +
  116 +public define Text
  117 + to_HTML_text
  118 + (
  119 + String path,
  120 + MAML_HTML_Options opts,
  121 + MAML3 text
  122 + ) =
  123 + if text is
  124 + {
  125 + error(me) then t(to_English(me)),
  126 + erroneous(me,m1) then t(to_English(me)),
  127 + empty then t(""),
  128 + text(value) then t(handle_html_special_chars(value)),
  129 + list(l) then sum(map((MAML3 m3) |-> to_HTML_text(path,opts,m3),l)),
  130 + postpone(pos,txt) then should_not_happen(t("")),
  131 + prim3(p3) then to_HTML_text(path,opts,p3),
  132 + m1 + m2 then to_HTML_text(path,opts,m1)+to_HTML_text(path,opts,m2)
  133 + }.
  134 +
  135 +public define Text
  136 + to_HTML
  137 + (
  138 + String path,
  139 + MAML_HTML_Options opts,
  140 + MAML3 text
  141 + ) =
  142 + to_HTML_text(path,opts,text).
  143 +
  144 +
  145 +define String
  146 + html_head
  147 + (
  148 + MAML_HTML_Options opts
  149 + ) =
  150 + since opts is options(spath,cpath,tpath,fsize,fnsize,twidth),
  151 +"<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">
  152 +<style>
  153 +body { counter-reset: section;
  154 + font-size: "+fsize+"px; }
  155 +p { align: justify; width: "+twidth+"px; }
  156 +h2 { counter-reset: subsection; }
  157 +h2::before { counter-increment: section;
  158 + content: counter(section) \". \"; }
  159 +h3 { counter-reset: subsubsection; }
  160 +h3::before { counter-increment: subsection;
  161 + content: counter(section) \".\" counter(subsection) \" \"; }
  162 +h4::before { counter-increment: subsubsection;
  163 + content: counter(section) \".\" counter(subsection) \".\" counter(subsubsection) \" \"; }
  164 +.dropdown { position: relative;
  165 + display: inline-block; }
  166 +.drp-content { display: none;
  167 + position: fixed;
  168 + bottom: 10px;
  169 + right: 10px;
  170 + background-color: #ffcc00;
  171 + max-width: "+(twidth-100)+"px;
  172 + box-shadow: 0px 16px 16px 0px rgba(0,0,0,0.6);
  173 + padding: 0px 6px;
  174 + z-index: 0; }
  175 +.dropdown:hover .drp-content { display: block;
  176 + z-index: 2; }
  177 +</style>
  178 +</head>".
  179 +
  180 +
  181 +
  182 +public define Text
  183 + html_encapsulate
  184 + (
  185 + MAML_HTML_Options opts,
  186 + Text html_text
  187 + ) =
  188 + "<html>"+html_head(default)+
  189 + "<body><center><table style=\"width: 600px; font-size:12px;\"><tr><td>"+
  190 + "<div style=\"text-align: justify; text-justify: inter-word; width: "+
  191 + to_decimal(text_width(default))+"px;\">"+
  192 + html_text+"</div></td></tr></table></center></body></html>".
  193 +
  194 +
  195 +
0 196 \ No newline at end of file
... ...
anubis_dev/library/doc_tools/maml4_interface.anubis 0 → 100644
  1 +
  2 + MAML4
  3 +
  4 + The public interface (and documentation).
  5 +
  6 +
  7 +transmit tools/basis.anubis
  8 +transmit tools/ANSI-colors.anubis
  9 +transmit_tools/file_and_dir.anubis
  10 +transmit tools/2-4tree.anubis
  11 +transmit lexical_analysis/fast_lexer_5.anubis
  12 +
  13 +
  14 +
  15 +
  16 + $begin
  17 + $input(../anubis_doc.maml)
  18 + $define(mark)(1)($rgb(100,0,0)($$$1))
  19 +
  20 + $section(MAML (The Minimalist Anubis Markup Language))
  21 +
  22 +
  23 + MAML was first implemented in 2005 and was mainly to be used for writing texts within a
  24 + web page. It was called 'minimalist' since it was to be used by web site users, hence had
  25 + to remain very simple.$p
  26 +
  27 + After some time, a need for a more generic and flexible tool appeared.
  28 + This led to some modifications in the original MAML (this was version 2). However, we wanted
  29 + to make everything cleaner, more efficient concerning LaTeX code generation, and also easier
  30 + to use for the programer. This was version 3, and finally, this version 4 is mainly equivalent
  31 + to version 3 except that it is about 8 times faster, due to the use of the tools available in
  32 + $fname(lexical_analysis/fast_lexer_5.anubis) and $fname(tools/2-4tree.anubis).$p
  33 +
  34 + MAML texts can be translated into HTML and PDF (via LaTeX). Notice that producing HTML output
  35 + also uses LaTeX if the $mark(latex) mark is used in the MAML source text.$p
  36 +
  37 + This program requires that the following are installed if LaTeX is to be used:
  38 + $list(
  39 + $item LaTeX2e (together with some LaTeX packages; see below)
  40 + $item dvipng (used only for producing images for the HTML output in presence of the $mark(latex) mark)
  41 + )
  42 + LaTeX2e and dvipng are available under Linux and Windows (you can use MiKTeX under Windows).
  43 + The LaTeX packages used by MAML are:
  44 + $list(
  45 + $item babel
  46 + $item inputenc
  47 + $item amsfonts
  48 + $item amsmath
  49 + $item amssymb
  50 + $item latexsym
  51 + $item xy
  52 + $item color
  53 + $item graphicx
  54 + )
  55 + Normally, they should be all present in a standard distribution.
  56 +
  57 + $subsection(How to write texts in MAML)
  58 +
  59 + A $em(user's guide) for writing texts in MAML can be found in $fname(maml4_tutorial.maml) in $fname(library/doc_tools).
  60 + This is a MAML file that you can process as follows (provided that $fname(library/doc_tools/maml4.anubis) is first
  61 + compiled):
  62 +
  63 + $ecode(anbexec maml maml4_tutorial.maml -pdf)
  64 +
  65 + This requires that LaTeX2e and dvipng are installed because, of course, the tutorial examplifies the
  66 + $mark(latex) mark. This produces $fname(maml4_tutorial.maml.html) and $fname(maml4_tutorial.maml.pdf). Actually,
  67 + these two files are already
  68 + part of the distribution. The HTML file refers to images which are also stored in $fname(library/doc_tools).$p
  69 +
  70 + Actually, $fname(maml4_tutorial) is mainly intended for insertion into the online documentation of a web site, if this web
  71 + site wants to offer some text formating facilities to its users (for example, if it is a forum).
  72 +
  73 +
  74 + $subsection(Errors)
  75 +
  76 + Of course, syntax errors can be found during the parsing of the MAML text, and also later during
  77 + the output. Positions within source texts are formalized as:
  78 + $acode(
  79 +public type MAML_Pos: // position in a MAML text
  80 + position
  81 + (String file_path, // absolute path of the file where the error was found
  82 + String file_name, // name of this file
  83 + Int line, // line number at which the error was found
  84 + Int column, // column number
  85 + Int offset). // offset in file
  86 +
  87 +public type LexerAux:
  88 + laux (String path,
  89 + String fname).
  90 + )
  91 +
  92 + $acode(
  93 +public type MAML_Error:
  94 + lexical (MAML_Pos pos,
  95 + LexicalError(One) lexical_error),
  96 + lexical (MAML_Pos pos,
  97 + LexicalError(LexerAux) lexical_error),
  98 + missing_end (String path,
  99 + String fname),
  100 + end_in_operand (MAML_Pos pos),
  101 + end_in_list (MAML_Pos pos),
  102 + unknown_mark (MAML_Pos pos,
  103 + String mark_name),
  104 + premature_end_of_file (String path,
  105 + String file),
  106 + missing_operand (MAML_Pos pos,
  107 + String mark_name),
  108 + file_not_found (MAML_Pos pos,
  109 + String path),
  110 + cannot_read_file (MAML_Pos pos,
  111 + String path),
  112 + cannot_open_file (String path),
  113 + cannot_create_file (String path),
  114 + cannot_write_file (String path),
  115 + cannot_execute_latex,
  116 + cannot_execute_dvipng,
  117 + png_file_corrupted (String path),
  118 + dvipng_error (Int code),
  119 + regexpr (MAML_Pos pos,
  120 + RegExprError e),
  121 + latex_error (MAML_Pos pos,
  122 + String logfname),
  123 + latex_error (Int code,
  124 + String logfname),
  125 + integer_expected (MAML_Pos pos),
  126 + must_be_a_color (MAML_Pos pos,
  127 + String s),
  128 + boolean_expected (MAML_Pos pos,
  129 + String s),
  130 + must_be_an_int (MAML_Pos pos,
  131 + String s),
  132 + must_be_a_nzint (MAML_Pos pos,
  133 + String s),
  134 + must_be_a_positive_int (MAML_Pos pos,
  135 + String s),
  136 + must_be_a_symbol (MAML_Pos pos,
  137 + String s),
  138 + string_expected (MAML_Pos pos,
  139 + String s),
  140 + invalid_initial_counter_value (MAML_Pos pos,
  141 + String value),
  142 + unknown_counter (MAML_Pos pos,
  143 + String counter_name),
  144 + unknown_macro_name (MAML_Pos pos,
  145 + String s),
  146 + invalid_number_to_add (MAML_Pos pos,
  147 + String value),
  148 + unknown_colorizer (String name),
  149 + colorizer_already_exists (MAML_Pos pos,
  150 + String name),
  151 + not_a_colorizercall_mode (MAML_Pos pos,
  152 + String s),
  153 + unknown_accumulator (MAML_Pos pos,
  154 + String name),
  155 + invalid_apply_name (MAML_Pos pos,
  156 + String name),
  157 + bad_apply_arity (MAML_Pos pos,
  158 + String name),
  159 + not_a_list (MAML_Pos pos,
  160 + String s),
  161 + misplaced_right_bracket (MAML_Pos pos),
  162 + misplaced_right_par (MAML_Pos pos).
  163 + )
  164 +
  165 + The function below formats a MAML error into an English text.
  166 +
  167 + $acode(
  168 +public define String to_English (MAML_Error e).
  169 + )
  170 +
  171 +
  172 + $subsection(Parsing options)
  173 +
  174 + Options can be transmitted to the MAML parser.
  175 +
  176 + $acode(
  177 +public type MAML_Option:
  178 + verbose,
  179 + pdf. // produce a PDF output (HTML only by default)
  180 + )
  181 +
  182 +
  183 + $subsection(Generating an HTML output)
  184 +
  185 + A MAML source text is read through the use of a $em(lexing stream) as defined in:
  186 + $acode(
  187 +read lexical_analysis/fast_lexer_5.anubis
  188 + )
  189 + This allows to read MAML texts from files, network connections and character strings (and more; see
  190 + $fname(fast_lexer_5.anubis)). You can of course also use the $ref(cmdlinetool)(command line tool
  191 + $att(maml)).$p
  192 +
  193 + In order to produce an HTML or a PDF output, you need to provide some parameters. These parameters
  194 + are gathered into a datum of type $att(MAML_HTML_Options) for HTML output and $att(MAML_PDF_Options) for
  195 + PDF output.
  196 + $acode(
  197 +public type MAML_HTML_Options:... (explained below)
  198 + )
  199 + There is a default value:
  200 + $acode(
  201 +public define MAML_HTML_Options default.
  202 + )
  203 +
  204 + We use the type $att(Text) for storing texts. This is a variant of $att(Printable_tree). Such data can
  205 + be printed.
  206 + $acode(
  207 +public type Text:...
  208 +public define One print(WStream s, Text text).
  209 + )
  210 + In order to produce an HTML output, use the following:
  211 + $acode(
  212 +public define Result(MAML_Error,Text)
  213 + to_HTML
  214 + (
  215 + List(MAML_Option) maml_options,
  216 + LexingStream maml_source,
  217 + MAML_HTML_Options options // you can put 'default' here
  218 + ).
  219 + )
  220 +
  221 + $subsection(Generating LaTeX and PDF output)
  222 +
  223 + Again there are options and a default value:
  224 + $acode(
  225 +public type MAML_PDF_Options:...
  226 +public define MAML_PDF_Options default.
  227 + )
  228 +
  229 + $acode(
  230 +public define Result(MAML_Error,Text)
  231 + to_PDF
  232 + (
  233 + List(MAML_Option) maml_options,
  234 + LexingStream maml_source,
  235 + Maybe((String,String)) pdf_output_path_and_name,
  236 + // no output file if 'failure'
  237 + MAML_PDF_Options options
  238 + // you can put 'default' here
  239 + ).
  240 + )
  241 +
  242 + Putting $att(failure) for $att(pdf_output_path_and_name) is used if one wants only the LaTeX text.
  243 +
  244 +
  245 + $subsection(Managing options)
  246 +
  247 + If you are not satisfied by the default options, you can create your own by defining data of
  248 + these types:
  249 + $acode(
  250 +public type MAML_HTML_Options:
  251 + options
  252 + (
  253 + // directories:
  254 + String png_path_server,
  255 + // the directory where dvipng generated images will be stored
  256 + // for example: site_directory/"public/png"
  257 + String png_path_client,
  258 + // the same one but seen from the client viewpoint (i.e. included
  259 + // in the HTML text) in this case: "png" since site_directory/"public"
  260 + // is the root from the client viewpoint
  261 + String tmp_path,
  262 + // the directory for temporary files on the server (.tex, .dvi, .aux, ...)
  263 +
  264 + // Sizes:
  265 + Int font_size,
  266 + // font size for main text (in pixels)
  267 + Int note_font_size,
  268 + // font size for text in footnotes
  269 + Int text_width
  270 + // width of text in pixels
  271 + ).
  272 + )
  273 +
  274 + $acode(
  275 +public type MAML_PDF_Options:
  276 + options
  277 + (
  278 + // directories:
  279 + String tmp_path,
  280 + // the directory for temporary files (.tex, .dvi, .aux, .log, ...)
  281 +
  282 + // LaTeX specific:
  283 + String babel_language,
  284 + // the language for the Babel package ("english", "french", ...)
  285 + String add_to_preambule,
  286 + // what you want to add just before \begin{document}
  287 + Int page_width,
  288 + // in millimeters
  289 + Int page_height
  290 + // in millimeters
  291 + ).
  292 + )
  293 +
  294 + You can of course use the value $att("") for $att(add_to_preambule). If you want to include a table of contents,
  295 + use $att($mark(ifpdf)(\tableofcontents)) in your MAML source, etc...
  296 +
  297 +
  298 + $subsection(Parsing MAML first)
  299 +
  300 + Here is how to avoid parsing twice the MAML source text if you want to produce both outputs.
  301 + You can first parse the MAML source, which yields a datum of type:
  302 + $acode(
  303 +public type MAML3:...
  304 + public type alias MAML = MAML3.
  305 +
  306 +public define Result(MAML_Error,MAML3)
  307 + parse_MAML
  308 + (
  309 + List(MAML_Option) maml_options,
  310 + LexingStream s
  311 + ).
  312 + )
  313 + and from this datum produce the HTML, LaTeX and PDF outputs:
  314 + $acode(
  315 +public define Result(MAML_Error,Text)
  316 + to_HTML
  317 + (
  318 + MAML3 maml_text,
  319 + MAML_HTML_Options options // you can put 'default' here
  320 + ).
  321 +
  322 +public define Result(MAML_Error,Text)
  323 + to_PDF
  324 + (
  325 + MAML3 maml_text,
  326 + Maybe(String) pdf_output_path_and_name, // no output file if 'failure'
  327 + MAML_PDF_Options options // you can put 'default' here
  328 + ).
  329 + )
  330 +
  331 + $define(nl)(0)(
  332 +)
  333 +
  334 + $label(cmdlinetool)
  335 + $subsection(Command line tool)
  336 + $acode($id($nl)anbexec maml $nt(file) $nt(options)
  337 + )
  338 + The command line tool $att(maml) reads the file given as its argument, but only between
  339 + the marks $mark(begin) and $mark(end). These pairs of marks can be present several times
  340 + in the file and the texts they delimit are all parsed.$p
  341 +
  342 + The option $att(-pdf) tells maml to produce a PDF output (by default, it produces a HTML
  343 + output only).$p
  344 +
  345 + An option $att(-verbose) is also available.
  346 +
  347 +
  348 + $end
  349 +
  350 +
  351 +
  352 +
  353 +
... ...
anubis_dev/library/doc_tools/maml4_lexers.anubis 0 → 100644
  1 +
  2 +
  3 + MAML4
  4 + The lexers.
  5 +
  6 +transmit maml4_private.anubis
  7 +
  8 + We need 5 lexers (to be constructed by fast_lexer_5), which are:
  9 +
  10 + - (1) the 'skip' lexer for reading outside the pairs $begin $end
  11 + - (2) the 'out' lexer for reading between $begin and $end but outside any mark operand
  12 + - (3) the 'blank' lexer for skipping blanks before operands
  13 + - (4) the 'in' lexer for reading mark operands as MAML texts
  14 + - (5) the 'verb' lexer for reading mark operands as verbatim text
  15 +
  16 + The reason why there is an 'out' and an 'in' lexer is that the 'out' lexer doesn't care about
  17 + parentheses (which can be unbalanced), whereas the 'in' lexer must care about parenthese
  18 + (which must be balanced). Of course, the 'verb' lexer also has to care about parentheses, but not
  19 + about mark names.
  20 +
  21 + We precompile these lexers separately (i.e. as 'single state lexers'). Each lexer has
  22 + his own type of tokens.
  23 +
  24 +
  25 +
  26 +
  27 + *** A tool for stripping the dollar.
  28 +
  29 +define ByteArray
  30 + strip_dollar
  31 + (
  32 + ByteArray b
  33 + ) =
  34 + extract(b,1,length(b)).
  35 +
  36 +
  37 + *** The 'skip' lexer.
  38 +
  39 +define List(LexerItem(SkipToken,One))
  40 + skip_lexer_desc
  41 + =
  42 + [
  43 + lexer_item("#$begin", return((ByteArray b, LexingTools t, One u) |-> ok(begin))),
  44 +
  45 + lexer_item("#$b[^e]", ignore),
  46 + lexer_item("#$be[^g]", ignore),
  47 + lexer_item("#$beg[^i]", ignore),
  48 + lexer_item("#$begi[^n]", ignore),
  49 + lexer_item("(.)|(#n)", ignore)
  50 + ].
  51 +
  52 +
  53 + *** The 'out' lexer.
  54 +
  55 +define List(LexerItem(OutToken,LexerAux))
  56 + out_lexer_desc
  57 + =
  58 + [
  59 + // $end, $colorize, ...
  60 + lexer_item("#$end", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(end))),
  61 + lexer_item("#$colorize", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(colorize(make_pos(t,a))))),
  62 + lexer_item("#$define", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(define(make_pos(t,a))))),
  63 + lexer_item("#$undefine", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(undefine(make_pos(t,a))))),
  64 + lexer_item("#$if", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(_if(make_pos(t,a)))))
  65 + ]
  66 + // primitive marks
  67 + +prims_lexer_items(prim1,prim3)+
  68 + [
  69 + // special syntaxes for $
  70 + lexer_item("(#$# )|(#$#$)",
  71 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(prim1(_dollar(make_pos(t,a)))))),
  72 +
  73 + // other mark names
  74 + lexer_item("#$[a-zA-Z_][a-zA-Z_0-9]*",
  75 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(macro(make_pos(t,a),to_string(strip_dollar(b)))))),
  76 +
  77 + // line comments $// bla bla
  78 + lexer_item("#$//.*" , ignore),
  79 +
  80 + // lines of text
  81 + lexer_item("[^#$#n]+",
  82 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text(to_string(b))))),
  83 +
  84 + // newline
  85 + lexer_item("#n",
  86 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text("\n"))))
  87 + ].
  88 +
  89 +
  90 + *** The 'blank' lexer.
  91 +
  92 +define List(LexerItem(BlankToken,One))
  93 + blank_lexer_desc
  94 + =
  95 + [
  96 + // line comments $// bla bla
  97 + lexer_item("[# #r#n#t]*#$//.*" , ignore),
  98 +
  99 + // skipping blanks until lpar.
  100 + lexer_item("[# #r#n#t]*#(",
  101 + return((ByteArray b, LexingTools t, One u) |-> ok(lpar)))
  102 + ].
  103 +
  104 +
  105 + *** The 'in' lexer.
  106 +
  107 +public define Int // also used in 'maml4_eval.anubis'
  108 + decscan // a decimal_scan which cannot fail
  109 + (
  110 + String s
  111 + ) =
  112 + if decimal_scan(s) is
  113 + {
  114 + failure then should_not_happen(0),
  115 + success(n) then n
  116 + }.
  117 +
  118 +
  119 +
  120 + The 'in' lexer description.
  121 +
  122 +define List(LexerItem(InToken,LexerAux))
  123 + in_lexer_desc
  124 + =
  125 + [
  126 + // $end, $colorize, ...
  127 + lexer_item("#$end", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(end))),
  128 + lexer_item("#$colorize", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(colorize(make_pos(t,a))))),
  129 + lexer_item("#$define", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(define(make_pos(t,a))))),
  130 + lexer_item("#$undefine", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(undefine(make_pos(t,a))))),
  131 + lexer_item("#$if", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(_if(make_pos(t,a))))),
  132 + lexer_item("#$alphabetic", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(alpha(make_pos(t,a))))),
  133 +
  134 + // square brackets and the comma
  135 + lexer_item("[# #r#n]*#[[# #r#n]*",
  136 + return((ByteArray b, LexingTools t, LexerAux a) |-> //iprint("in_lexer: saw a [ at "+format(make_pos(t,a))+"\n");
  137 + ok(lbrk(to_string(b))))),
  138 + lexer_item("[# #r#n]*#][# #r#n]*",
  139 + return((ByteArray b, LexingTools t, LexerAux a) |-> //iprint("in_lexer: saw a ] at "+format(make_pos(t,a))+"\n");
  140 + ok(rbrk(to_string(b))))),
  141 + lexer_item("[# #r#n]*#,[# #r#n]*",
  142 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(comma(to_string(b))))),
  143 +
  144 + // special characters
  145 + lexer_item("#(",
  146 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(lpar))),
  147 + lexer_item("#)",
  148 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(rpar)))
  149 + ]
  150 + // primitive marks
  151 + +prims_lexer_items(prim1,prim3)+
  152 + [
  153 + // inhibited special characters
  154 + lexer_item("#$#,",
  155 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text(",")))),
  156 + lexer_item("#$#(",
  157 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text("(")))),
  158 + lexer_item("#$#)",
  159 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text(")")))),
  160 + lexer_item("#$#[",
  161 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text("[")))),
  162 + lexer_item("#$#]",
  163 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text("]")))),
  164 + lexer_item("#$#$",
  165 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text("$")))),
  166 + lexer_item("#$",
  167 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text("$")))),
  168 +
  169 + // mark names
  170 + lexer_item("#$[a-zA-Z_][a-zA-Z_0-9]*",
  171 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(macro(make_pos(t,a),to_string(strip_dollar(b)))))),
  172 +
  173 + // MAML variables
  174 + lexer_item("#$[0-9]+",
  175 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(variable(decscan(to_string(strip_dollar(b))))))),
  176 +
  177 + // lines of text
  178 + lexer_item("[^#$#n#(#)#[#]#,]+",
  179 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text(to_string(b))))),
  180 +
  181 + // line comments $// bla bla
  182 + lexer_item("#$//.*" , ignore),
  183 +
  184 + // newline
  185 + lexer_item("#n",
  186 + return((ByteArray b, LexingTools t, LexerAux a) |-> ok(text("\n"))))
  187 + ].
  188 +
  189 +
  190 + *** The 'verb' lexer.
  191 +
  192 +
  193 +define List(LexerItem(VerbToken,One))
  194 + verb_lexer_desc
  195 + =
  196 + [
  197 + lexer_item("#$lpar", return((ByteArray b, LexingTools t, One u) |-> ok(text("(")))),
  198 + lexer_item("#$rpar", return((ByteArray b, LexingTools t, One u) |-> ok(text(")")))),
  199 + lexer_item("#$", return((ByteArray b, LexingTools t, One u) |-> ok(dollar))),
  200 + lexer_item("[^#(#)#n#$]+", return((ByteArray b, LexingTools t, One u) |-> //iprint("verb_lex: text: "+to_string(b)+"\n");
  201 + ok(text(to_string(b))))),
  202 + lexer_item("#n", return((ByteArray b, LexingTools t, One u) |-> ok(text("\n")))),
  203 + lexer_item("#(", return((ByteArray b, LexingTools t, One u) |-> ok(lpar))),
  204 + lexer_item("#)", return((ByteArray b, LexingTools t, One u) |-> ok(rpar)))
  205 + ].
  206 +
  207 +
  208 + *** The 'color_value' lexer.
  209 +
  210 +public define List(LexerItem(ColorValueToken,One))
  211 + color_value_lexer_desc
  212 + =
  213 + [
  214 + lexer_item("[0-9]+", return((ByteArray b, LexingTools t, One u) |-> ok(int(decscan(to_string(b)))))),
  215 + lexer_item("#,", return((ByteArray b, LexingTools t, One u) |-> ok(comma)))
  216 + ].
  217 +
  218 + *** The 'symbol' lexer.
  219 +
  220 +public define List(LexerItem(SymbolToken,One))
  221 + symbol_lexer_desc
  222 + =
  223 + [
  224 + lexer_item("[A-Za-z#_][A-Za-z0-9#_]*", return((ByteArray b, LexingTools t, One u) |-> ok(symbol))),
  225 + ].
  226 +
  227 +
  228 +global define One
  229 + make_maml4_lexers
  230 + (
  231 + List(String) _
  232 + ) =
  233 + make_precompiled_lexer("skip_lexer", skip_lexer_desc, '#');
  234 + make_precompiled_lexer("out_lexer", out_lexer_desc, '#');
  235 + make_precompiled_lexer("blank_lexer", blank_lexer_desc, '#');
  236 + make_precompiled_lexer("in_lexer", in_lexer_desc, '#');
  237 + make_precompiled_lexer("verb_lexer", verb_lexer_desc, '#');
  238 + make_precompiled_lexer("color_value_lexer", color_value_lexer_desc, '#');
  239 + make_precompiled_lexer("symbol_lexer", symbol_lexer_desc, '#').
  240 +
  241 +
  242 +execute anbexec make_maml4_lexers
  243 +
  244 +read generated/skip_lexer.anubis
  245 +read generated/out_lexer.anubis
  246 +read generated/blank_lexer.anubis
  247 +read generated/in_lexer.anubis
  248 +read generated/verb_lexer.anubis
  249 +
  250 + Below we must use 'transmit' because the lexers are used in another file.
  251 +
  252 +transmit generated/color_value_lexer.anubis
  253 +transmit generated/symbol_lexer.anubis
  254 +
  255 +
  256 + *** Making a toolbox for parsing a file.
  257 +
  258 +
  259 +public define Toolbox
  260 + make_toolbox
  261 + (
  262 + String fpath,
  263 + String fname,
  264 + LexingStream ls,
  265 + ToolboxKeep keep
  266 + ) =
  267 + with skip_lex = retrieve_lexer( skip_lexer_desc, skip_lexer, end_of_input)(ls,unique),
  268 + out_lex = retrieve_lexer( out_lexer_desc, out_lexer, end_of_input)(ls,laux(fpath,fname)),
  269 + blank_lex = retrieve_lexer( blank_lexer_desc, blank_lexer, end_of_input)(ls,unique),
  270 + in_lex = retrieve_lexer( in_lexer_desc, in_lexer, end_of_input)(ls,laux(fpath,fname)),
  271 + verb_lex = retrieve_lexer( verb_lexer_desc, verb_lexer, end_of_input)(ls,unique),
  272 + toolbox(
  273 + fpath,
  274 + fname,
  275 + ls,
  276 + skip_lex,
  277 + out_lex,
  278 + blank_lex,
  279 + in_lex,
  280 + verb_lex,
  281 + keep).
  282 +
  283 +public define SpecLex(ColorValueToken)
  284 + make_color_value_lexer
  285 + (
  286 + One u
  287 + ) =
  288 + retrieve_lexer(color_value_lexer_desc, color_value_lexer, end_of_input).
  289 +
  290 +public define SpecLex(SymbolToken)
  291 + make_symbol_lexer
  292 + (
  293 + One u
  294 + ) =
  295 + retrieve_lexer(symbol_lexer_desc, symbol_lexer, end_of_input).
  296 +
  297 +public define MAML2 glue_eval (Toolbox tbox, MAML1 m).
  298 +
  299 +
  300 +
  301 +define MAML2
  302 + apply_macro
  303 + (
  304 + Toolbox tbox,
  305 + String name,
  306 + MAML1 body, // of macro definition
  307 + List(MAML1) ops // already computed operands
  308 + ) =
  309 + //iprint("\nmacro name: "+name+"\n");
  310 + //iprint("body = "+to_string_all(body)+"\n");
  311 + //iprint("ops: "+concat(map(to_string_all,ops),"-----")+"\n");
  312 + with result = replace_vars_in_MAML(body,ops),
  313 + //iprint("result: "+to_string(result)+"\n");
  314 + eval(tbox,result).
  315 +
  316 +
  317 +
  318 +
  319 +public define Result(MAML_Error,MAML2 -> MAML2)
  320 + get_apply_function
  321 + (
  322 + Toolbox tbox,
  323 + MAML_Pos pos,
  324 + String name // must be the name of a macro
  325 + ) =
  326 + with ls = make_lexing_stream("$",name),
  327 + lex = retrieve_lexer(in_lexer_desc,in_lexer,end_of_input)(ls,laux("","")),
  328 + if lex(unique) is
  329 + {
  330 + error(e) then error(lexical(pos,e)),
  331 + ok(tok) then
  332 + if tok is macro(_,mname)
  333 + then if get(mname,*tbox.keep.macro_tree_v) is
  334 + {
  335 + failure then error(unknown_macro_name(pos,name)),
  336 + success(defs) then if defs is
  337 + {
  338 + [ ] then error(unknown_macro_name(pos,name)),
  339 + [h . t] then since h is macro(_,arity,body),
  340 + if length(arity) = 1
  341 + then ok((MAML2 m) |-> apply_macro(tbox,name,body,[computed(m)]))
  342 + else error(bad_apply_arity(pos,name))
  343 + }
  344 + }
  345 + else error(invalid_apply_name(pos,name))
  346 + }.
  347 +
  348 +
  349 +
  350 +
  351 +
  352 +
0 353 \ No newline at end of file
... ...
anubis_dev/library/doc_tools/maml4_parser.anubis 0 → 100644
  1 +
  2 + MAML4
  3 +
  4 + The parser.
  5 +
  6 +transmit maml4_eval.anubis
  7 +
  8 + The MAML4 parser is 'hand made' because APG appears to be inappropriate in this case.
  9 + Indeed, the MAML grammar is not LALR1 because detecting the end of a sequence of
  10 + operands depends on the arity of the mark, which is not of a syntactic nature in the
  11 + case of macros (for primitives, the arity is known to the lexer; recall that a macro
  12 + cannot be defined with the name of a primitive). Furthermore,
  13 + the MAML syntax is also quite simple. Hence, we have a 'hand made' parser, using the
  14 + lexers defined in maml4_lexers.anubis.
  15 +
  16 + Nevertheless, the MAML grammar is not as simple as it may seem at first glance. Indeed,
  17 + we must keep in mind that:
  18 +
  19 + - (1) Parentheses must be balanced within operands of marks, but can very well not be
  20 + balanced outside any operand.
  21 + - (2) Some operands must be parsed in verbatim mode, others in maml mode.
  22 +
  23 + For designing our parser we must choose one of these methods:
  24 +
  25 + - (1) the parser stops after the first error encountered,
  26 + - (2) the parser stores errors into the maml result and doesn't stop (possibly before
  27 + a given number of errors is found).
  28 +
  29 + The second method is better for at least two reasons:
  30 + - the programming is simpler,
  31 + - the user can discover several errors in a single compilation.
  32 +
  33 + So, we choose the second method. This is why the type MAML1 has an alternative 'error'
  34 + (and an alternative 'erroneous'), allowing to insert errors into the output of the parser.
  35 +
  36 +
  37 +
  38 + In this file, we define:
  39 +
  40 +public define MAML2 parse_eval (Toolbox tbox).
  41 +
  42 + which parses and evaluates a MAML text, beginning in 'skip' mode.
  43 +
  44 +
  45 + --- That's all for the public part ! ---------------------------------------------------
  46 +
  47 +
  48 + *** Return type for parsing elements of list.
  49 +
  50 +
  51 +type ListElem: // returning a list element together with how it was delimited
  52 + error (MAML1), // in case of an error the delimiter is not known
  53 + rbrk (MAML1, String), // list element delimited by a right bracket (with its decoration)
  54 + comma (MAML1, String). // list element delimited by a comma (with its decoration)
  55 +
  56 +
  57 +
  58 + *** Auxiliary (cross-recursive) functions.
  59 +
  60 +define MAML2 parse_skip (Toolbox tbox).
  61 +define MAML2 parse_out (Toolbox tbox).
  62 +define MAML1 parse_in (Toolbox tbox).
  63 +define MAML1 parse_colorize (Toolbox tbox, MAML_Pos pos).
  64 +define MAML1 parse_define (Toolbox tbox, MAML_Pos pos).
  65 +define MAML1 parse_undefine (Toolbox tbox, MAML_Pos pos).
  66 +define MAML1 parse_alpha (Toolbox tbox, MAML_Pos pos).
  67 +define (List(MAML1),
  68 + List(String)) parse_list (Toolbox tbox, List(MAML1) m_so_far, List(String) d_so_far).
  69 +define MAML1 parse_if (Toolbox tbox, MAML_Pos pos).
  70 +define MAML1 parse_in_operand (Toolbox tbox).
  71 +define ListElem parse_list_elem (Toolbox tbox).
  72 +define MAML1 parse_in_verbatim (Toolbox tbox).
  73 +define MAML1 parse_maml_operand (Toolbox tbox, String mark_name).
  74 +public define MAML1 parse_operand (Toolbox tbox, ParseMode mode, String mark_name).
  75 +define MAML1 parse_verbatim_operand (Toolbox tbox, String mark_name).
  76 +define MAML1 parse_macro (Toolbox tbox, MAML_Pos pos, String name).
  77 +define List(MAML1) parse_several_operands (Toolbox tbox, Int arity, String mark_name).
  78 +define (MAML1,MAML1) parse_2_operands (Toolbox tbox, ParseMode mode1, ParseMode mode2, String mark_name).
  79 +define (MAML1,MAML1,MAML1) parse_3_operands (Toolbox tbox, ParseMode mode1, ParseMode mode2, ParseMode mode3, String mark_name).
  80 +
  81 +
  82 + 'parse_prim1' and 'parse_prim3' are defined in generated/prim2.anubis, and need
  83 + 'parse_operand(Toolbox,ParseMode)'. This is why this function is declared 'public' above.
  84 +
  85 +
  86 + *** From Here, parse functions produce MAML1 data because they don't evaluate.
  87 +
  88 +
  89 +
  90 + Now parsing an operand of list element.
  91 +
  92 +define MAML1
  93 + parse_in // parsing within an operand. The opening parenthese is already parsed.
  94 + (
  95 + Toolbox tbox,
  96 + ) =
  97 + if tbox.in_lex(unique) is
  98 + {
  99 + error(e) then error(lexical(make_pos(tbox),e)),
  100 + ok(tok) then if tok is
  101 + {
  102 + end_of_input then error(premature_end_of_file(tbox.file_path,tbox.file_name)),
  103 + end then error(end_in_operand(make_pos(tbox))),
  104 + lpar then with m = parse_in(tbox),
  105 + with n = parse_in(tbox),
  106 + text("(")+m+text(")")+n,
  107 + rpar then empty, // end of operand
  108 + lbrk(d) then //iprint("parse_in: At "+format(make_pos(tbox))+" seen a [\n");
  109 + with m = parse_list(tbox,[],[d]),
  110 + with n = parse_in(tbox),
  111 + since m is (l,dec),
  112 + list(l,dec)+n,
  113 + rbrk(d) then error(misplaced_right_bracket(make_pos(tbox))),
  114 + comma(d) then with n = parse_in(tbox),
  115 + text(d)+n,
  116 + prim1(name) then //iprint("parse_in: prim1\n");
  117 + with m = parse_prim1(tbox,name),
  118 + //iprint("got a: "+to_string(m)+"\n");
  119 + with n = parse_in(tbox),
  120 + m+n,
  121 + alpha(pos) then with m = parse_alpha(tbox,pos),
  122 + with n = parse_in(tbox),
  123 + m+n,
  124 + colorize(pos) then with m = parse_colorize(tbox,pos),
  125 + with n = parse_in(tbox),
  126 + m+n,
  127 + define(pos) then with m = parse_define(tbox,pos),
  128 + with n = parse_in(tbox),
  129 + m+n,
  130 + undefine(pos) then with m = parse_undefine(tbox,pos),
  131 + with n = parse_in(tbox),
  132 + m+n,
  133 + _if(pos) then with m = parse_if(tbox,pos),
  134 + with n = parse_in(tbox),
  135 + m+n,
  136 + prim3(name) then with m = parse_prim3(tbox,name),
  137 + with n = parse_in(tbox),
  138 + m+n,
  139 + text(value) then with m = (MAML1)text(value),
  140 + with n = parse_in(tbox),
  141 + m+n,
  142 + macro(pos,name) then with m = parse_macro(tbox,pos,name),
  143 + with n = parse_in(tbox),
  144 + m+n,
  145 + variable(id) then with n = parse_in(tbox),
  146 + variable(id)+n
  147 + }
  148 + }.
  149 +
  150 +
  151 +define ListElem
  152 + MAML1 m + ListElem n
  153 + =
  154 + if n is
  155 + {
  156 + error(e) then error(m+e),
  157 + rbrk(e,d) then rbrk(m+e,d),
  158 + comma(e,d) then comma(m+e,d)
  159 + }.
  160 +
  161 +define ListElem
  162 + parse_list_elem // parsing within square brackets. The opening bracket or leading comma is already parsed.
  163 + (
  164 + Toolbox tbox,
  165 + ) =
  166 + if tbox.in_lex(unique) is
  167 + {
  168 + error(e) then error(error(lexical(make_pos(tbox),e))),
  169 + ok(tok) then if tok is
  170 + {
  171 + end_of_input then error(error(premature_end_of_file(tbox.file_path,tbox.file_name))),
  172 + end then error(error(end_in_list(make_pos(tbox)))),
  173 + lpar then with m = parse_in(tbox),
  174 + with n = parse_list_elem(tbox),
  175 + (text("(")+m+text(")"))+n,
  176 + rpar then error(error(misplaced_right_par(make_pos(tbox)))),
  177 + lbrk(d) then //iprint("parse_list_elem: At "+format(make_pos(tbox))+" seen a [\n");
  178 + with m = parse_list(tbox,[],[d]),
  179 + //iprint("Got this: "+to_string(list(m))+"\n");
  180 + with n = parse_list_elem(tbox),
  181 + since m is (l,dec),
  182 + list(l,dec)+n,
  183 + rbrk(d) then //iprint("parse_list_elem: At "+format(make_pos(tbox))+" seen a ]\n");
  184 + rbrk(empty,d),
  185 + comma(d) then //iprint("parse_list_elem: At "+format(make_pos(tbox))+" seen a ,\n");
  186 + comma(empty,d),
  187 + prim1(name) then with m = parse_prim1(tbox,name),
  188 + with n = parse_list_elem(tbox),
  189 + m+n,
  190 + alpha(pos) then with m = parse_alpha(tbox,pos),
  191 + with n = parse_list_elem(tbox),
  192 + m+n,
  193 + colorize(pos) then with m = parse_colorize(tbox,pos),
  194 + with n = parse_list_elem(tbox),
  195 + m+n,
  196 + define(pos) then with m = parse_define(tbox,pos),
  197 + with n = parse_list_elem(tbox),
  198 + m+n,
  199 + undefine(pos) then with m = parse_undefine(tbox,pos),
  200 + with n = parse_list_elem(tbox),
  201 + m+n,
  202 + _if(pos) then with m = parse_if(tbox,pos),
  203 + with n = parse_list_elem(tbox),
  204 + m+n,
  205 + prim3(name) then with m = parse_prim3(tbox,name),
  206 + with n = parse_list_elem(tbox),
  207 + m+n,
  208 + text(value) then with m = (MAML1)text(value),
  209 + with n = parse_list_elem(tbox),
  210 + m+n,
  211 + macro(pos,name) then with m = parse_macro(tbox,pos,name),
  212 + with n = parse_list_elem(tbox),
  213 + m+n,
  214 + variable(id) then with n = parse_list_elem(tbox),
  215 + variable(id)+n
  216 + }
  217 + }.
  218 +
  219 +
  220 +
  221 +define (List(MAML1),List(String))
  222 + parse_list
  223 + (
  224 + Toolbox tbox,
  225 + List(MAML1) m_so_far,
  226 + List(String) d_so_far
  227 + ) =
  228 + if parse_list_elem(tbox) is
  229 + {
  230 + error(e) then (reverse([e . m_so_far]),reverse(d_so_far)),
  231 + rbrk(elem,d) then (reverse([elem . m_so_far]),reverse([d . d_so_far])),
  232 + comma(elem,d) then parse_list(tbox,[elem . m_so_far],[d . d_so_far])
  233 + }.
  234 +
  235 +
  236 +
  237 +
  238 +
  239 +
  240 + *** Parsing the next expected operand (assumed not verbatim).
  241 +
  242 +define MAML1
  243 + parse_maml_operand
  244 + (
  245 + Toolbox tbox,
  246 + String mark_name
  247 + ) =
  248 + if tbox.blank_lex(unique) is
  249 + {
  250 + error(e) then error(missing_operand(make_pos(tbox),mark_name)),
  251 + ok(tok) then if tok is
  252 + {
  253 + end_of_input then error(premature_end_of_file(tbox.file_path,tbox.file_name)),
  254 + lpar then parse_in(tbox)
  255 + }
  256 + }.
  257 +
  258 +
  259 + *** Parsing the next expected operand (assumed verbatim).
  260 +
  261 +define MAML1
  262 + parse_verbatim_operand // parsing an expected verbatim operand
  263 + (
  264 + Toolbox tbox,
  265 + String mark_name
  266 + ) =
  267 + if tbox.blank_lex(unique) is
  268 + {
  269 + error(e) then error(missing_operand(make_pos(tbox),mark_name)),
  270 + ok(tok) then if tok is
  271 + {
  272 + end_of_input then error(premature_end_of_file(tbox.file_path,tbox.file_name)),
  273 + lpar then parse_in_verbatim(tbox)
  274 + }
  275 + }.
  276 +
  277 +define MAML1
  278 + parse_in_verbatim // parsing within a verbatim operand
  279 + (
  280 + Toolbox tbox
  281 + ) =
  282 + if tbox.verb_lex(unique) is
  283 + {
  284 + error(e) then error(lexical(make_pos(tbox),e)),
  285 + ok(tok) then if tok is
  286 + {
  287 + end_of_input then error(premature_end_of_file(tbox.file_path,tbox.file_name)),
  288 + lpar then with m = parse_in_verbatim(tbox),
  289 + with n = parse_in_verbatim(tbox),
  290 + text("(")+m+text(")")+n,
  291 + rpar then empty,
  292 + dollar then with n = parse_in_verbatim(tbox),
  293 + text("$")+n,
  294 + text(content) then with n = parse_in_verbatim(tbox),
  295 + text(content)+n
  296 + }
  297 + }.
  298 +
  299 +
  300 +
  301 + *** Parsing all sorts of expected operands.
  302 +
  303 +public define MAML1
  304 + parse_operand
  305 + (
  306 + Toolbox tbox,
  307 + ParseMode mode,
  308 + String mark_name
  309 + ) =
  310 + if mode is
  311 + {
  312 + maml then parse_maml_operand(tbox,mark_name),
  313 + maml(mb) then parse_maml_operand(tbox,mark_name), // checking the form is done after eval.
  314 + verb then parse_verbatim_operand(tbox,mark_name)
  315 + }.
  316 +
  317 +
  318 + *** Parsing 2 and 3 operands.
  319 +
  320 +define (MAML1,MAML1)
  321 + parse_2_operands
  322 + (
  323 + Toolbox tbox,
  324 + ParseMode mode1,
  325 + ParseMode mode2,
  326 + String mark_name
  327 + ) =
  328 + // with is necessary because of the order of execution of non deterministic parsing
  329 + with m1 = parse_operand(tbox,mode1,mark_name),
  330 + m2 = parse_operand(tbox,mode2,mark_name),
  331 + (m1,m2).
  332 +
  333 +define (MAML1,MAML1,MAML1)
  334 + parse_3_operands
  335 + (
  336 + Toolbox tbox,
  337 + ParseMode mode1,
  338 + ParseMode mode2,
  339 + ParseMode mode3,
  340 + String mark_name
  341 + ) =
  342 + with m1 = parse_operand(tbox,mode1,mark_name),
  343 + m2 = parse_operand(tbox,mode2,mark_name),
  344 + m3 = parse_operand(tbox,mode3,mark_name),
  345 + (m1,m2,m3).
  346 +
  347 +
  348 + *** Parsing several operands (used for parsing operands of macros).
  349 +
  350 +define List(MAML1)
  351 + parse_several_operands // parse several operands as indicated by 'arity'
  352 + (
  353 + Toolbox tbox,
  354 + Int arity,
  355 + String mark_name
  356 + ) =
  357 + if arity =< 0 then [ ] else
  358 + with a1 = parse_operand(tbox,maml,mark_name),
  359 + t1 = parse_several_operands(tbox,arity-1,mark_name),
  360 + [a1 . t1].
  361 +
  362 +
  363 + *** Parsing macros.
  364 +
  365 +define MAML1
  366 + parse_macro
  367 + (
  368 + Toolbox tbox,
  369 + MAML_Pos pos,
  370 + String name
  371 + ) =
  372 + //iprint("Parsing macro "+name+": ");
  373 + if get_macro_arity(tbox,name) is
  374 + {
  375 + failure then //iprint("error name not found\n");
  376 + error(unknown_macro_name(pos,name)),
  377 + success(ar) then //iprint("ok "+ar+" operands\n");
  378 + with ops = parse_several_operands(tbox,ar,name),
  379 + macro(pos,name,ops)
  380 + }.
  381 +
  382 +
  383 +
  384 +
  385 +
  386 +
  387 +
  388 + *** Special cases.
  389 +
  390 + *** Parsing a '$colorize...'.
  391 +
  392 +define MAML1
  393 + parse_colorize
  394 + (
  395 + Toolbox tbox,
  396 + MAML_Pos pos
  397 + ) =
  398 + if parse_2_operands(tbox,maml(symbol),maml,"$colorize") is (m1,m2) then
  399 + colorize(pos,m1,m2).
  400 +
  401 +
  402 +
  403 +
  404 + *** Parsing a '$define...'.
  405 +
  406 +define One
  407 + record_macro_arity
  408 + (
  409 + Toolbox tbox,
  410 + String name,
  411 + Int ar,
  412 + ) =
  413 + //iprint("Recording macro '"+name+"' arity = "+ar+"\n");
  414 + with v = tbox.keep.arity_tree_v,
  415 + v <- update(name,*v,(Maybe(List(Int)) mbl) |-> if mbl is
  416 + {
  417 + failure then success([ar]),
  418 + success(l) then success([ar . l])
  419 + }).
  420 +
  421 +define MAML1
  422 + parse_define
  423 + (
  424 + Toolbox tbox,
  425 + MAML_Pos pos
  426 + ) =
  427 + //iprint("Parsing a $define\n");
  428 + since parse_3_operands(tbox,maml(symbol),maml(pint),maml,"$define") is (_name,_arity,_value),
  429 + if must_be_symbol(text(to_string(_name))) is
  430 + {
  431 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  432 + success(name) then if must_be_pint(text(to_string(_arity))) is
  433 + {
  434 + failure then error(must_be_a_positive_int(pos,to_string(_arity))),
  435 + success(arity) then record_macro_arity(tbox,name,arity);
  436 + define(pos,name,arity,_value)
  437 + }
  438 + }.
  439 +
  440 +
  441 + *** Parsing an '$undefine...'.
  442 +
  443 +define MAML1
  444 + parse_undefine
  445 + (
  446 + Toolbox tbox,
  447 + MAML_Pos pos
  448 + ) =
  449 + with _name = parse_operand(tbox,maml(symbol),"$undefine"),
  450 + if must_be_symbol(text(to_string(_name))) is
  451 + {
  452 + failure then error(must_be_a_symbol(pos,to_string(_name))),
  453 + success(name) then with v = tbox.keep.arity_tree_v,
  454 + since ((ArityTree,(Maybe(List(Int)),MAML2)))get_update(name,*v,(Maybe(List(Int)) mbl) |-> if mbl is
  455 + {
  456 + failure then (failure,empty),
  457 + success(l) then if l is
  458 + {
  459 + [ ] then (failure,empty),
  460 + [h . t] then (success(t),empty)
  461 + }
  462 + }) is (new_tree,_),
  463 + v <- new_tree;
  464 + undefine(pos,name)
  465 + }.
  466 +
  467 +
  468 +define MAML1
  469 + parse_alpha
  470 + (
  471 + Toolbox tbox,
  472 + MAML_Pos pos
  473 + ) =
  474 + with a = parse_maml_operand(tbox,"$alphabetic"),
  475 + alpha(a).
  476 +
  477 + define MAML1
  478 + parse_alpha_in_list
  479 + (
  480 + Toolbox tbox,
  481 + MAML_Pos pos
  482 + ) =
  483 + with a = parse_maml_operand_in_list(tbox,"$alphabetic"),
  484 + alpha(a).
  485 +
  486 +
  487 +define MAML1
  488 + parse_if
  489 + (
  490 + Toolbox tbox,
  491 + MAML_Pos pos
  492 + ) =
  493 + since parse_3_operands(tbox,maml(bool),maml,maml,"$if") is (_test,_iftrue,_iffalse),
  494 + _if(pos,_test,_iftrue,_iffalse).
  495 +
  496 +
  497 +
  498 + *** Parsing before $begin.
  499 +
  500 +define MAML2
  501 + parse_skip
  502 + (
  503 + Toolbox tbox
  504 + ) =
  505 + if tbox.skip_lex(unique) is // skip until the first $begin
  506 + {
  507 + error(e) then error(lexical(make_pos(tbox),e)),
  508 + ok(tok) then if tok is
  509 + {
  510 + end_of_input then empty, // no $begin found
  511 + begin then parse_out(tbox)
  512 + }
  513 + }.
  514 +
  515 +
  516 +
  517 + *** Parsing between $begin and $end (and evaluating).
  518 +
  519 +define MAML2
  520 + parse_out // this is for parsing outside any operand
  521 + (
  522 + Toolbox tbox
  523 + ) =
  524 + if tbox.out_lex(unique) is
  525 + {
  526 + error(e) then error(lexical(make_pos(tbox),e)),
  527 + ok(tok) then if tok is
  528 + {
  529 + end_of_input then error(premature_end_of_file(tbox.file_path,tbox.file_name)),
  530 + end then parse_skip(tbox), // returning to 'skip' mode.
  531 + prim1(name) then with m = glue_eval(tbox,parse_prim1(tbox,name)),
  532 + with n = parse_out(tbox),
  533 + m+n,
  534 + colorize(pos) then with m = glue_eval(tbox,parse_colorize(tbox,pos)),
  535 + with n = parse_out(tbox),
  536 + m+n,
  537 + define(pos) then with m = glue_eval(tbox,parse_define(tbox,pos)),
  538 + with n = parse_out(tbox),
  539 + m+n,
  540 + undefine(pos) then with m = glue_eval(tbox,parse_undefine(tbox,pos)),
  541 + with n = parse_out(tbox),
  542 + m+n,
  543 + _if(pos) then with m = glue_eval(tbox,parse_if(tbox,pos)),
  544 + with n = parse_out(tbox),
  545 + m+n,
  546 + prim3(name) then with m = glue_eval(tbox,parse_prim3(tbox,name)),
  547 + with n = parse_out(tbox),
  548 + m+n,
  549 + text(value) then with n = parse_out(tbox),
  550 + text(value)+n,
  551 + macro(pos,name) then with m = glue_eval(tbox,parse_macro(tbox,pos,name)),
  552 + with n = parse_out(tbox),
  553 + m+n
  554 + }
  555 + }.
  556 +
  557 +
  558 + *** The public tool (parse and eval).
  559 +
  560 +public define MAML2
  561 + parse_eval
  562 + (
  563 + Toolbox tbox
  564 + ) =
  565 + parse_skip(tbox).
  566 +
  567 +
  568 + *** Executing postponed expressions.
  569 +
  570 +public define MAML2
  571 + execute_postponed
  572 + (
  573 + Toolbox tbox,
  574 + MAML2 m
  575 + ) =
  576 + if m is
  577 + {
  578 + error(me) then m,
  579 + erroneous(me,text) then m,
  580 + empty then m,
  581 + false then m,
  582 + true then m,
  583 + text(value) then m,
  584 + variable(id) then m,
  585 + list(l,d) then list(map((MAML2 m2) |-> execute_postponed(tbox,m2),l),d),
  586 + alpha(m1) then alpha(execute_postponed(tbox,m1)),
  587 + colorize(pos,cname,operand) then colorize(pos,cname,execute_postponed(tbox,operand)),
  588 + postpone(pos,text) then eval(tbox,text),
  589 + prim3(p3) then prim3(map((MAML2 p) |-> execute_postponed(tbox,p),p3)),
  590 + m1 + m2 then with m1e = execute_postponed(tbox,m1),
  591 + m2e = execute_postponed(tbox,m2),
  592 + m1e + m2e
  593 + }.
  594 +
  595 +
  596 +
  597 +
0 598 \ No newline at end of file
... ...
anubis_dev/library/doc_tools/maml4_pdf.anubis 0 → 100644
  1 +
  2 +
  3 +transmit maml4_html.anubis
  4 +
... ...
anubis_dev/library/doc_tools/maml4_png.anubis 0 → 100644
  1 +
  2 +
  3 + MAML 4
  4 +
  5 + The PNG stuff.
  6 +
  7 +transmit maml4_lexers.anubis
  8 +
  9 + Because there is a $latex mark in MAML, we need to transform peices of LaTeX text into images
  10 + to be inserted into the HTML output. Hopefully, there is a tool, 'dvipng' able to transform
  11 + a .dvi file (produced by LaTeX) into a PNG image with transparent background.
  12 +
  13 + We also have to ensure that the base line of LaTeX formulas is at the same height as the base
  14 + line of the surrounding HTML text. In order to achieve this, we create a first image with a
  15 + TeX \rule of height 50 points so that we know that the TeX base line in 50 point below the top
  16 + of the image. Next, we create a second without the \rule, and comparing the heights of the two
  17 + images allows to compute the number of pixels that the image must be shifted up or down in the
  18 + HTML text.
  19 +
  20 +
  21 +read web/web_arg_encode.anubis (used for creating file names)
  22 +read graphism/png_size.anubis ('png_image_size' needed)
  23 +read system/files.anubis ('copy_file' needed)
  24 +
  25 +
  26 + We need to know the number of pixels a PNG image must be moved down in the HTML output (so that the
  27 + LaTeX baseline is at the same height as the surrounding HTML baseline).
  28 +
  29 +public type ResultPNG_down:
  30 + error (MAML_Error), // MAML error
  31 + log_file (String fname), // LaTeX error
  32 + png_file_down (String fname, // name of PNG image file
  33 + Int width, // of image
  34 + Int height,
  35 + Int down). // number of pixels the image must be shifted down in the HTML page
  36 +
  37 +
  38 +public define ResultPNG_down latex_to_png (String text, // a LaTex body
  39 + MAML_HTML_Options opts).
  40 +
  41 +
  42 + --- That's all for the public part ! -----------------------------------------------------
  43 +
  44 +
  45 + We define a LaTeX preambule and a LaTeX postambule for constructing the LaTeX source file.
  46 +
  47 +define String
  48 + latex_png_preambule
  49 + =
  50 +"\\documentclass[12pt]{article}
  51 +\\usepackage[english]{babel}
  52 +\\usepackage[utf8]{inputenc}
  53 +\\usepackage[T1]{fontenc}
  54 +\\usepackage{amsfonts,amsmath,amssymb}
  55 +\\usepackage{latexsym}
  56 +\\usepackage[all]{xy}
  57 +\\usepackage{color}
  58 +\\pagestyle{empty}
  59 +\\textwidth20cm
  60 +\\textheight30cm
  61 +\\begin{document}
  62 +{\\Huge
  63 +".
  64 +
  65 +
  66 +define String
  67 + latex_png_postambule
  68 + =
  69 +"
  70 +}
  71 +\\end{document}
  72 +
  73 +".
  74 +
  75 +
  76 + *** Checking if a LaTeX body contains a display $$....$$.
  77 +
  78 +public define Bool
  79 + has_a_display
  80 + (
  81 + String latex_text
  82 + ) =
  83 + if find_string(latex_text,"$$",0) is
  84 + {
  85 + failure then false,
  86 + success(_) then true
  87 + }.
  88 +
  89 +
  90 +
  91 + *** Making a PNG image file.
  92 +
  93 + The type below is for returning a pair (<file name>,<height>) where <height> is the height in
  94 + pixels of the image contained in the PNG file. It can return a MAML error or a LaTeX error.
  95 +
  96 +type ResultPNG_height:
  97 + error (MAML_Error), // MAML error
  98 + log_file (String fname), // LaTeX error
  99 + png_file_height (String fname, Int height). // height of image in pixels
  100 +
  101 +
  102 +define ResultPNG_height
  103 + make_png_file
  104 + (
  105 + String text, // LaTeX body
  106 + String fname, // a common name for the files
  107 + Bool true_png_file, // false for the temporary png file
  108 + MAML_HTML_Options opts
  109 + ) =
  110 + //iprint("(1) LaTeX text: ["+text+"]\n");
  111 + since opts is options(spath,cpath,tpath,fsize,fnsize,twidth),
  112 + forget(make_directory(spath,default_directory_mode));
  113 + forget(make_directory(cpath,default_directory_mode));
  114 + forget(make_directory(tpath,default_directory_mode));
  115 + with fnametex = fname+".tex", // actual name of the .tex file
  116 + fnamedvi = fname+".dvi", // idem .dvi file
  117 + fnamepng = fname+".png", // idem .png file
  118 + if write_to_file(tpath/fnametex,
  119 + to_byte_array(latex_png_preambule+text+latex_png_postambule)) is
  120 + {
  121 + cannot_open_file then error(cannot_create_file(tpath/fnametex)),
  122 + write_error(_) then error(cannot_write_file(tpath/fnametex)),
  123 + ok then if (Maybe(Word8))execute(success(tpath),"latex",
  124 + ["-no-shell-escape", // avoid security problems
  125 + "-interaction=batchmode", // quiet mode
  126 + //"nonstopmode", // avoid stopping
  127 + fnametex]) is
  128 + {
  129 + failure then error(cannot_execute_latex),
  130 + success(rcode1) then if rcode1 /= 0
  131 + then
  132 + (
  133 + /* return the error code and path of log file */
  134 + log_file((tpath/fname)+".log")
  135 + )
  136 + else
  137 + // The DVI file is okay. Convert it to PNG.
  138 + if (Maybe(Word8))execute(success(tpath),"dvipng",
  139 + ["-T","tight","-Q","8","-bg","Transparent","-o",fnamepng,fnamedvi]) is
  140 + {
  141 + failure then error(cannot_execute_dvipng),
  142 + success(rcode2) then
  143 + if rcode2 /= 0
  144 + then error(dvipng_error(to_Int([rcode2])))
  145 + else if png_image_size(tpath/fnamepng) is
  146 + {
  147 + failure then error(png_file_corrupted(tpath/fnamepng)),
  148 + success(p) then
  149 + (if tpath = spath
  150 + then unique
  151 + else if true_png_file
  152 + then forget(copy_file(tpath/fnamepng,spath/fnamepng))
  153 + else unique);
  154 + since p is (w,h), png_file_height(cpath/fnamepng,to_Int(h))
  155 + }
  156 + }
  157 + }
  158 + }.
  159 +
  160 +
  161 +
  162 + *** Vertical positionning of PNG images.
  163 +
  164 +public define ResultPNG_down
  165 + latex_to_png
  166 + (
  167 + String text, // a LaTex body
  168 + MAML_HTML_Options opts
  169 + ) =
  170 + //iprint("(2) LaTeX text: ["+text+"]\n");
  171 + with hash = sha1(text), // create a unique name for all our files
  172 + corefname = web_arg_encode(hash),
  173 + spath = png_path_server(opts),
  174 + if file_exists(spath/("/f"+corefname+".png"))
  175 + then with dims = if png_image_size(spath+"/f"+corefname+".png") is
  176 + {
  177 + failure then (0,0),
  178 + success(p) then p
  179 + },
  180 + since dims is (w,h),
  181 + png_file_down(spath/("f"+corefname+".png"),to_Int(w),to_Int(h),
  182 + to_Int(if png_image_size(spath+"/t"+corefname+".png") is
  183 + {
  184 + failure then 0,
  185 + success(p) then if p is (w1,h1) then
  186 + if h1 +=< 100 then 0 else h1-100
  187 + }))
  188 + else if make_png_file(text,"f"+corefname,true,opts) is
  189 + {
  190 + error(msg) then error(msg),
  191 + log_file(fname) then log_file(fname),
  192 + png_file_height(true_fnamepng,true_height) then
  193 + with dims = if png_image_size(spath+"/f"+corefname+".png") is
  194 + {
  195 + failure then (0,0),
  196 + success(p) then p
  197 + },
  198 + since dims is (w,h),
  199 + if has_a_display(text)
  200 + then png_file_down(true_fnamepng,to_Int(w),to_Int(h),0)
  201 + else if make_png_file("\\rule{1mm}{1in}"+text,"t"+corefname,true,opts) is
  202 + {
  203 + error(msg) then error(msg),
  204 + log_file(fname) then log_file(fname),
  205 + png_file_height(_,fake_height) then
  206 + png_file_down(true_fnamepng,
  207 + to_Int(w),to_Int(h),
  208 + if fake_height =< 100 then 0 else fake_height-100)
  209 + }
  210 + }.
  211 +
  212 +
... ...
anubis_dev/library/doc_tools/maml4_private.anubis 0 → 100644
  1 +
  2 + MAML 4
  3 +
  4 + Definition of most tools used in this program.
  5 +
  6 +transmit maml4_types.anubis
  7 +
  8 +
  9 +
  10 + *** Making a position from the toolbox.
  11 +
  12 +public define MAML_Pos
  13 + make_pos
  14 + (
  15 + Toolbox tbox
  16 + ) =
  17 + since tbox is toolbox(path,fname,ls,_,_,_,_,_,kp),
  18 + with t = tools(ls),
  19 + position(path,fname,line(t)(unique),column(t)(unique),offset(t)(unique)).
  20 +
  21 +
  22 + *** Formating a list of parsing modes.
  23 +
  24 +define String
  25 + format
  26 + (
  27 + MustBe mb
  28 + ) =
  29 + if mb is
  30 + {
  31 + any then "any",
  32 + bool then "bool",
  33 + color then "color",
  34 + ccmode then "ccmode",
  35 + int then "int",
  36 + pint then "pint",
  37 + nzint then "nzint",
  38 + string then "string",
  39 + symbol then "symbol"
  40 + }.
  41 +
  42 +public define String
  43 + format
  44 + (
  45 + ParseMode m
  46 + ) =
  47 + if m is
  48 + {
  49 + maml then "maml",
  50 + maml(mb) then "maml("+format(mb)+")",
  51 + verb then "verb"
  52 + }.
  53 +
  54 +public define String
  55 + format
  56 + (
  57 + CCMode m
  58 + ) =
  59 + if m is
  60 + {
  61 + ee then "ee",
  62 + ei then "ei",
  63 + ie then "ie",
  64 + ii then "ii"
  65 + }.
  66 +
  67 +public define CCMode1
  68 + mode_for_call
  69 + (
  70 + CCMode m
  71 + ) =
  72 + if m is
  73 + {
  74 + ee then e,
  75 + ei then e,
  76 + ie then i,
  77 + ii then i
  78 + }.
  79 +
  80 +public define CCMode1
  81 + mode_for_return
  82 + (
  83 + CCMode m
  84 + ) =
  85 + if m is
  86 + {
  87 + ee then e,
  88 + ei then i,
  89 + ie then e,
  90 + ii then i
  91 + }.
  92 +
  93 +public define String
  94 + format
  95 + (
  96 + List(ParseMode) l
  97 + ) =
  98 + "["+concat(map(format,l),",")+"]".
  99 +
  100 +
  101 + Create a constant 'maml' arity.
  102 +public define List(ParseMode)
  103 + cst_maml_arity // for example: 3 |-> [maml,maml,maml]
  104 + (
  105 + Int n
  106 + ) =
  107 + if n =< 0 then [ ] else [maml . cst_maml_arity(n-1)].
  108 +
  109 +
  110 +
  111 + *** Printing a 'Text' into a file.
  112 +
  113 +public define One
  114 + print
  115 + (
  116 + WStream fp,
  117 + Text text
  118 + ) =
  119 + if text is
  120 + {
  121 + t(s) then print(fp,s),
  122 + t1 + t2 then print(fp,t1); print(fp,t2)
  123 + }.
  124 +
  125 +
  126 +
  127 +
  128 + *** Transforming a Text or VText into a string.
  129 +
  130 + The functions below are used for generating 'generated/prim2.anubis'.
  131 +
  132 + A variant of 'sub_string' forcing the result to be a 'String'. Used just below for backslashing
  133 + the double quotes within a string.
  134 +
  135 +define String
  136 + sub_str
  137 + (
  138 + String s,
  139 + Int start,
  140 + Int end
  141 + ) =
  142 + if sub_string(s,start,end) is
  143 + {
  144 + failure then should_not_happen(""),
  145 + success(t) then t
  146 + }.
  147 +
  148 +define String
  149 + backslash_the_doublequotes
  150 + (
  151 + String s
  152 + ) =
  153 + if find_string(s,"\"",0) is
  154 + {
  155 + failure then s,
  156 + success(n) then sub_str(s,0,n)+"\\\""+backslash_the_doublequotes(sub_str(s,n+1,length(s)-n-1))
  157 + }.
  158 +
  159 +
  160 +
  161 +
  162 +public define String
  163 + to_string
  164 + (
  165 + VText t
  166 + ) =
  167 + if t is
  168 + {
  169 + t(text) then "t(\""+backslash_the_doublequotes(text)+"\")",
  170 + v(i) then "v("+i+")",
  171 + fnsize then "fnsize",
  172 + textwidth then "textwidth",
  173 + vt1 + vt2 then to_string(vt1)+"+\n "+to_string(vt2)
  174 + }.
  175 +
  176 +public define String
  177 + to_string
  178 + (
  179 + Text t
  180 + ) =
  181 + if t is
  182 + {
  183 + t(s) then s,
  184 + t1+t2 then to_string(t1)+to_string(t2)
  185 + }.
  186 +
  187 +
  188 + *** Generating the file 'generated/prim2.anubis'.
  189 +
  190 +define One
  191 + dump_prims_names_format
  192 + (
  193 + WStream fp
  194 + ) =
  195 + print(fp,"\n\npublic define String\n");
  196 + print(fp," format\n");
  197 + print(fp," (\n");
  198 + print(fp," Prim1 rp\n");
  199 + print(fp," ) =\n");
  200 + print(fp," if rp is \n");
  201 + print(fp," {\n");
  202 + print(fp,concat(map((PrimMark1 m) |-> " _"+padn(name(m)+"(_)")+" then \""+name(m)+"\"",
  203 + primitives1),",\n"));
  204 + print(fp,"\n }.\n");
  205 + print(fp,"\n\npublic define String\n");
  206 + print(fp," format\n");
  207 + print(fp," (\n");
  208 + print(fp," Prim3 rp\n");
  209 + print(fp," ) =\n");
  210 + print(fp," if rp is \n");
  211 + print(fp," {\n");
  212 + print(fp,concat(map((PrimMark3 m) |-> " "+padn(name(m)+"(_)")+" then \""+name(m)+"\"",
  213 + primitives3),",\n"));
  214 + print(fp,"\n }.\n").
  215 +
  216 +define One
  217 + dump_prims_lexer_items
  218 + (
  219 + WStream fp
  220 + ) =
  221 + print(fp,"\npublic define List(LexerItem($T,LexerAux))\n");
  222 + print(fp," prims_lexer_items(Prim1 -> $T prim1, Prim3 -> $T prim3)\n");
  223 + print(fp," =\n");
  224 + print(fp," [\n");
  225 + print(fp,concat(map((PrimMark1 m) |->
  226 + " lexer_item(\"#$"+name(m)+"\""+constant_string(20-length(name(m)),' ')+
  227 + ", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(prim1(_"+name(m)+"(make_pos(t,a))))))",
  228 + primitives1),",\n")+",\n");
  229 + print(fp,concat(map((PrimMark3 m) |->
  230 + " lexer_item(\"#$"+name(m)+"\""+constant_string(20-length(name(m)),' ')+
  231 + ", return((ByteArray b, LexingTools t, LexerAux a) |-> ok(prim3("+name(m)+"(make_pos(t,a))))))",
  232 + primitives3),",\n"));
  233 + print(fp,"\n ].\n").
  234 +
  235 +
  236 +
  237 +
  238 +
  239 + A special 'map' function to be used just below.
  240 + Example: map_number(f,[a,b,c],0) yields [f(a,0),f(b,1),f(c,2)]
  241 +
  242 +define List($U)
  243 + map_number
  244 + (
  245 + ($T,Int) -> $U f,
  246 + List($T) l,
  247 + Int i
  248 + ) =
  249 + if l is
  250 + {
  251 + [ ] then [ ],
  252 + [h . t] then [f(h,i) . map_number(f,t,i+1)]
  253 + }.
  254 +
  255 +
  256 +define One
  257 + dump_make_parse_prim1
  258 + (
  259 + WStream fp
  260 + ) =
  261 + print(fp,"\n\npublic define MAML1 parse_operand(Toolbox tbox, ParseMode m, String mark_name).\n");
  262 + print(fp,"\npublic define MAML1\n");
  263 + print(fp," parse_prim1(Toolbox tbox, Prim1 p) =\n");
  264 + print(fp," if p is\n");
  265 + print(fp," {\n");
  266 + print(fp,concat(map((PrimMark1 m) |-> if m is
  267 + {
  268 + primitive1(name,stackable,arity,_) then
  269 + " _"+padn(name+"(pos)")+" then\n"+
  270 + concat(map_number((ParseMode mod, Int i) |->
  271 + " with m"+i+" = parse_operand(tbox"
  272 + +","+format(mod)+",\"$"+name+"\"),\n",
  273 + arity,0),"")+
  274 + " prim1(_"+name+(if arity is [] then "(pos)" else "(pos,"+
  275 + concat(map_number((ParseMode mod, Int i) |-> "m"+i,arity,0),",")+")")+")"
  276 + }, primitives1),",\n"));
  277 + print(fp,"\n }.\n").
  278 +
  279 +define One
  280 + dump_make_parse_prim1_in_list
  281 + (
  282 + WStream fp
  283 + ) =
  284 + print(fp,"\n\npublic define MAML1 parse_operand_in_list(Toolbox tbox, ParseMode m, String mark_name).\n");
  285 + print(fp,"\npublic define MAML1\n");
  286 + print(fp," parse_prim1_in_list(Toolbox tbox, Prim1 p) =\n");
  287 + print(fp," if p is\n");
  288 + print(fp," {\n");
  289 + print(fp,concat(map((PrimMark1 m) |-> if m is
  290 + {
  291 + primitive1(name,stackable,arity,_) then
  292 + " _"+padn(name+"(pos)")+" then\n"+
  293 + concat(map_number((ParseMode mod, Int i) |->
  294 + " with m"+i+" = parse_operand_in_list(tbox"
  295 + +","+format(mod)+",\"$"+name+"\"),\n",
  296 + arity,0),"")+
  297 + " prim1(_"+name+(if arity is [] then "(pos)" else "(pos,"+
  298 + concat(map_number((ParseMode mod, Int i) |-> "m"+i,arity,0),",")+")")+")"
  299 + }, primitives1),",\n"));
  300 + print(fp,"\n }.\n").
  301 +
  302 +define One
  303 + dump_make_parse_prim3
  304 + (
  305 + WStream fp
  306 + ) =
  307 + //print(fp,"\n\npublic define MAML1 parse_operand(Toolbox tbox, ParseMode m, String mark_name).\n");
  308 + print(fp,"\npublic define MAML1\n");
  309 + print(fp," parse_prim3(Toolbox tbox, Prim3 p) =\n");
  310 + print(fp," if p is\n");
  311 + print(fp," {\n");
  312 + print(fp,concat(map((PrimMark3 m) |-> if m is
  313 + {
  314 + primitive3(name,stackable,arity,_,_) then
  315 + " "+padn(name+"(pos)")+" then\n"+
  316 + concat(map_number((ParseMode mod, Int i) |->
  317 + " with m"+i+" = parse_operand(tbox"
  318 + +","+format(mod)+",\"$"+name+"\"),\n",
  319 + arity,0),"")+
  320 + " prim3("+name+(if arity is [ ] then "(pos)" else "(pos,"+
  321 + concat(map_number((ParseMode mod, Int i) |-> "m"+i,arity,0),",")+")")+")"
  322 + }, primitives3),",\n"));
  323 + print(fp,"\n }.\n").
  324 +
  325 +
  326 +define One
  327 + dump_make_parse_prim3_in_list
  328 + (
  329 + WStream fp
  330 + ) =
  331 + //print(fp,"\n\npublic define MAML1 parse_operand(Toolbox tbox, ParseMode m, String mark_name).\n");
  332 + print(fp,"\npublic define MAML1\n");
  333 + print(fp," parse_prim3_in_list(Toolbox tbox, Prim3 p) =\n");
  334 + print(fp," if p is\n");
  335 + print(fp," {\n");
  336 + print(fp,concat(map((PrimMark3 m) |-> if m is
  337 + {
  338 + primitive3(name,stackable,arity,_,_) then
  339 + " "+padn(name+"(pos)")+" then\n"+
  340 + concat(map_number((ParseMode mod, Int i) |->
  341 + " with m"+i+" = parse_operand_in_list(tbox"
  342 + +","+format(mod)+",\"$"+name+"\"),\n",
  343 + arity,0),"")+
  344 + " prim3("+name+(if arity is [ ] then "(pos)" else "(pos,"+
  345 + concat(map_number((ParseMode mod, Int i) |-> "m"+i,arity,0),",")+")")+")"
  346 + }, primitives3),",\n"));
  347 + print(fp,"\n }.\n").
  348 +
  349 +
  350 +define One
  351 + dump_make_extract_errors_prim3
  352 + (
  353 + WStream fp,
  354 + String parm,
  355 + ) =
  356 + print(fp,"\npublic define List(MAML_Error) extract_errors(MAML_Prim3("+parm+") p3) = \n");
  357 + print(fp," if p3 is\n");
  358 + print(fp," {\n");
  359 + print(fp,concat(map((PrimMark3 m) |-> since m is primitive3(name,_,arity,_,_),
  360 + " "+padn(name+(if arity is [] then "(pos" else "(pos,")+
  361 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n"+
  362 + if arity is
  363 + {
  364 + [ ] then " [ ]",
  365 + [_ . _] then " "+stdvars(arity,(String v) |-> "extract_errors("+v+")"," + ")
  366 + }, primitives3),
  367 + ",\n"));
  368 + print(fp," }.\n").
  369 +
  370 +
  371 + From an arity such as [maml,maml(Int),verb] produce the following string:
  372 +
  373 + with __0 = to_HTML_text(path,opts,_0),
  374 + with __1 = t(to_decimal(_1)),
  375 + with __2 = t(_2),
  376 +
  377 +define String
  378 + arity_to_HTML
  379 + (
  380 + Arity arity
  381 + ) =
  382 + concat(map_iterate((Int i, ParseMode mod) |-> if mod is
  383 + {
  384 + maml then " with __"+i+" = to_HTML_text(path,opts,_"+i+")",
  385 + maml(mb) then if mb is
  386 + {
  387 + any then " with __"+i+" = to_HTML_text(path,opts,_"+i+")",
  388 + bool then should_not_happen(""),
  389 + color then " with __"+i+" = (Text)t(for_html(_"+i+"))",
  390 + ccmode then " with __"+i+" = (Text)t(format(for_html(_"+i+")))",
  391 + int then " with __"+i+" = (Text)t(to_decimal(for_html(_"+i+")))",
  392 + pint then " with __"+i+" = (Text)t(to_decimal(for_html(_"+i+")))",
  393 + nzint then " with __"+i+" = (Text)t(to_decimal(for_html(_"+i+")))",
  394 + string then " with __"+i+" = (Text)t(for_html(_"+i+"))",
  395 + symbol then " with __"+i+" = (Text)t(for_html(_"+i+"))",
  396 + },
  397 + verb then " with __"+i+" = (Text)t(for_html(_"+i+"))"
  398 + }, arity,0,(Int i) |-> i+1),",\n").
  399 +
  400 +
  401 +define One
  402 + dump_html_formater
  403 + (
  404 + WStream fp
  405 + ) =
  406 + print(fp,"\n Forward declarations:");
  407 + print(fp,"\npublic define Text replace_vars_etc(String path, MAML_HTML_Options opts, VText text, List(Text) values).");
  408 +// print(fp,"\npublic define Text replace_vars_etc(Text _0,String path, MAML_HTML_Options opts, VText text).");
  409 +// print(fp,"\npublic define Text replace_vars_etc(Text _0,Text _1,String path, MAML_HTML_Options opts, VText text).");
  410 +// print(fp,"\npublic define Text replace_vars_etc(Text _0,Text _1,Text _2,String path, MAML_HTML_Options opts, VText text).");
  411 +// print(fp,"\npublic define Text replace_vars_etc(Text _0,Text _1,Text _2,Text _3,String path, MAML_HTML_Options opts, VText text).");
  412 +// print(fp,"\npublic define Text replace_vars_etc(Text _0,Text _1,Text _2,Text _3,Text _4,String path, MAML_HTML_Options opts, VText text).");
  413 + print(fp,"\npublic define Text to_HTML_text(String path, MAML_HTML_Options opts, MAML3 m).\n");
  414 +
  415 + print(fp,"\npublic define Text to_HTML_text (String path, MAML_HTML_Options opts, MAML_Prim3(MAML3) p) = \n");
  416 + print(fp," if p is\n");
  417 + print(fp," {\n");
  418 + print(fp,concat(map((PrimMark3 m) |-> if m is
  419 + {
  420 + primitive3(name,stackable,arity,html_code,_) then
  421 + " "+padn(name+(if arity is [] then "(pos" else "(pos,")+
  422 + stdvars_no_par(arity,(String s) |-> s,",")+")")+" then\n"+
  423 + arity_to_HTML(arity)+(if arity is [] then " " else ",\n ")+
  424 + if arity is [] then to_string(html_code) else
  425 + "replace_vars_etc(path,opts,"+to_string(html_code)+","+
  426 + "["+stdvars_no_par(arity,(String v) |-> "_"+v,",")+"])"
  427 + }, primitives3),
  428 + ",\n"));
  429 + print(fp,"\n }.\n").
  430 +
  431 +
  432 +define One
  433 + dump_arity_functions
  434 + (
  435 + WStream fp
  436 + ) =
  437 + print(fp,"\npublic define List(ParseMode) get_arity(Prim3 p) = \n");
  438 + print(fp," if p is\n");
  439 + print(fp," {\n");
  440 + print(fp,concat(map((PrimMark3 m) |-> if m is
  441 + {
  442 + primitive3(name,stackable,arity,html_code,_) then
  443 + " "+padn(name+"(pos)")+" then "+format(arity)
  444 + }, primitives3),",\n"));
  445 + print(fp,"\n }.\n").
  446 +
  447 +
  448 +define One
  449 + dump_replace_vars_in_prim1
  450 + (
  451 + WStream fp
  452 + ) =
  453 + print(fp,"\npublic define MAML1 replace_vars_in_prim1(MAML_Prim1 p, List(MAML1) values) =\n");
  454 + print(fp," if p is\n");
  455 + print(fp," {\n");
  456 + print(fp,concat(map((PrimMark1 m) |-> if m is primitive1(name,_,arity,_) then
  457 + " _"+padn(name+(if arity is [] then "(pos" else "(pos,")+
  458 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n "+
  459 + "prim1(_"+name+(if arity is [] then "(pos" else "(pos,")+
  460 + stdvars_no_par(arity,(String v) |-> "replace_vars_in_MAML("+v+",values)",",")+"))",
  461 + primitives1),",\n"));
  462 + print(fp,"\n }.\n").
  463 +
  464 +define One
  465 + dump_make_lists_prim1
  466 + (
  467 + WStream fp
  468 + ) =
  469 + print(fp,"\npublic define MAML1 make_lists(MAML_Prim1 p) =\n");
  470 + print(fp," if p is\n");
  471 + print(fp," {\n");
  472 + print(fp,concat(map((PrimMark1 m) |-> if m is primitive1(name,_,arity,_) then
  473 + " _"+padn(name+(if arity is [] then "(pos" else "(pos,")+
  474 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n "+
  475 + "prim1(_"+name+(if arity is [] then "(pos" else "(pos,")+
  476 + stdvars_no_par(arity,(String v) |-> "make_lists("+v+")",",")+"))",
  477 + primitives1),",\n"));
  478 + print(fp,"\n }.\n").
  479 +
  480 +define One
  481 + dump_replace_vars_in_prim3
  482 + (
  483 + WStream fp,
  484 + String src_parm,
  485 + String trg_parm
  486 + ) =
  487 + print(fp,"\npublic define "+trg_parm+" replace_vars_in_prim3(MAML_Prim3("+src_parm+") p, List("+trg_parm+") values) =\n");
  488 + print(fp," if p is\n");
  489 + print(fp," {\n");
  490 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  491 + " "+padn(name+(if arity is [] then "(pos" else "(pos,")+
  492 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n "+
  493 + "prim3("+name+(if arity is [] then "(pos" else "(pos,")+
  494 + stdvars_no_par(arity,(String v) |-> "replace_vars_in_MAML("+v+",values)",",")+"))",
  495 + primitives3),",\n"));
  496 + print(fp,"\n }.\n").
  497 +
  498 +define One
  499 + dump_replace_vars_in_prim3_MAML1
  500 + (
  501 + WStream fp
  502 + ) =
  503 + print(fp,"\npublic define MAML1 replace_vars_in_prim3(MAML_Prim3_MAML1 p, List(MAML1) values) =\n");
  504 + print(fp," if p is\n");
  505 + print(fp," {\n");
  506 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  507 + " "+padn(name+(if arity is [] then "(pos" else "(pos,")+
  508 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n "+
  509 + //" iprint(\"replace_vars_in_prim3: "+name+"\\n \");\n"+
  510 + "prim3("+name+(if arity is [] then "(pos" else "(pos,")+
  511 + stdvars_no_par(arity,(String v) |-> "replace_vars_in_MAML("+v+",values)",",")+"))",
  512 + primitives3),",\n"));
  513 + print(fp,"\n }.\n").
  514 +
  515 +
  516 +define One
  517 + dump_glue_texts_MAML2
  518 + (
  519 + WStream fp
  520 + ) =
  521 + print(fp,"\npublic define MAML2 glue_texts(MAML_Prim3(MAML2) p) = \n");
  522 + print(fp," if p is\n");
  523 + print(fp," {\n");
  524 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  525 + " "+padn(name+(if arity is [] then "(pos" else "(pos,")+
  526 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n "+
  527 + "prim3("+name+(if arity is [] then "(pos" else "(pos,")+
  528 + stdvars_no_par(arity,(String v) |-> "glue_texts("+v+")",",")+"))",
  529 + primitives3),",\n"));
  530 + print(fp,"\n }.\n").
  531 +
  532 +define One
  533 + dump_glue_texts_MAML2b
  534 + (
  535 + WStream fp
  536 + ) =
  537 + print(fp,"\npublic define MAML2b glue_texts(MAML_Prim3(MAML2b) p) = \n");
  538 + print(fp," if p is\n");
  539 + print(fp," {\n");
  540 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  541 + " "+padn(name+(if arity is [] then "(pos" else "(pos,")+
  542 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n "+
  543 + "prim3("+name+(if arity is [] then "(pos" else "(pos,")+
  544 + stdvars_no_par(arity,(String v) |-> "glue_texts("+v+")",",")+"))",
  545 + primitives3),",\n"));
  546 + print(fp,"\n }.\n").
  547 +
  548 +define One
  549 + dump_map_MAML_Prim3
  550 + (
  551 + WStream fp
  552 + ) =
  553 + print(fp,"\npublic define MAML_Prim3($U) map($T -> $U f, MAML_Prim3($T) p) = \n");
  554 + print(fp," if p is\n");
  555 + print(fp," {\n");
  556 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  557 + " "+padn(name+(if arity is [] then "(pos" else "(pos,")+
  558 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n "+
  559 + name+(if arity is [] then "(pos" else "(pos,")+
  560 + stdvars_no_par(arity,(String v, ParseMode mod) |->
  561 + if mod is
  562 + {
  563 + maml then "f("+v+")",
  564 + maml(mb) then if mb is
  565 + {
  566 + any then "f("+v+")",
  567 + bool then v,
  568 + color then v,
  569 + ccmode then v,
  570 + int then v,
  571 + pint then v,
  572 + nzint then v,
  573 + string then v,
  574 + symbol then v
  575 + },
  576 + verb then v
  577 + },",")+")",
  578 + primitives3),",\n"));
  579 + print(fp,"\n }.\n").
  580 +
  581 +define One
  582 + dump_map_MAML_Prim1
  583 + (
  584 + WStream fp
  585 + ) =
  586 + print(fp,"\npublic define MAML_Prim1 map(MAML1 -> MAML1 f, MAML_Prim1 p) = \n");
  587 + print(fp," if p is\n");
  588 + print(fp," {\n");
  589 + print(fp,concat(map((PrimMark1 m) |-> if m is primitive1(name,_,arity,_) then
  590 + " _"+padn(name+(if arity is [] then "(pos" else "(pos,")+
  591 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n "+
  592 + "_"+name+(if arity is [] then "(pos" else "(pos,")+
  593 + stdvars_no_par(arity,(String v, ParseMode mod) |-> "f("+v+")",",")+")",
  594 + primitives1),",\n"));
  595 + print(fp,"\n }.\n").
  596 +
  597 +define One
  598 + dump_map_MAML_Prim3_MAML1
  599 + (
  600 + WStream fp
  601 + ) =
  602 + print(fp,"\npublic define MAML_Prim3_MAML1 map(MAML1 -> MAML1 f, MAML_Prim3_MAML1 p) = \n");
  603 + print(fp," if p is\n");
  604 + print(fp," {\n");
  605 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  606 + " "+padn(name+(if arity is [] then "(pos" else "(pos,")+
  607 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n "+
  608 + name+(if arity is [] then "(pos" else "(pos,")+
  609 + stdvars_no_par(arity,(String v, ParseMode mod) |-> "f("+v+")",",")+")",
  610 + primitives3),",\n"));
  611 + print(fp,"\n }.\n").
  612 +
  613 +
  614 +define String
  615 + make_with_evals
  616 + (
  617 + Arity ar,
  618 + Int i
  619 + ) =
  620 + if ar is
  621 + {
  622 + [ ] then "",
  623 + [h . t] then
  624 + (if h is
  625 + {
  626 + maml then " with __"+i+" = eval(tbox,_"+i+"),\n",
  627 + maml(mb) then if mb is
  628 + {
  629 + any then " with __"+i+" = eval(tbox,_"+i+"),\n",
  630 + bool then " if eval_as_bool(tbox,pos,_"+i+") is { error(e) then error(e), ok(__"+i+") then\n",
  631 + color then " if eval_as_color(tbox,pos,_"+i+") is { error(e) then error(e), ok(__"+i+") then\n",
  632 + ccmode then " if eval_as_ccmode(tbox,pos,_"+i+") is { error(e) then error(e), ok(__"+i+") then\n",
  633 + int then " if eval_as_int(tbox,pos,_"+i+") is { error(e) then error(e), ok(__"+i+") then\n",
  634 + pint then " if eval_as_pint(tbox,pos,_"+i+") is { error(e) then error(e), ok(__"+i+") then\n",
  635 + nzint then " if eval_as_nzint(tbox,pos,_"+i+") is { error(e) then error(e), ok(__"+i+") then\n",
  636 + string then " if eval_as_string(tbox,pos,_"+i+") is { error(e) then error(e), ok(__"+i+") then\n",
  637 + symbol then " if eval_as_symbol(tbox,pos,_"+i+") is { error(e) then error(e), ok(__"+i+") then\n",
  638 + },
  639 + verb then " if eval_as_string(tbox,pos,_"+i+") is { error(e) then error(e), ok(__"+i+") then\n"
  640 + }) + make_with_evals(t,i+1)
  641 + }.
  642 +
  643 +define Int
  644 + num_non_maml_arities
  645 + (
  646 + Arity ar
  647 + ) =
  648 + if ar is
  649 + {
  650 + [ ] then 0,
  651 + [h . t] then if h is
  652 + {
  653 + maml then num_non_maml_arities(t),
  654 + maml(mb) then if mb is
  655 + {
  656 + any then num_non_maml_arities(t),
  657 + bool then 1 + num_non_maml_arities(t),
  658 + color then 1 + num_non_maml_arities(t),
  659 + ccmode then 1 + num_non_maml_arities(t),
  660 + int then 1 + num_non_maml_arities(t),
  661 + pint then 1 + num_non_maml_arities(t),
  662 + nzint then 1 + num_non_maml_arities(t),
  663 + string then 1 + num_non_maml_arities(t),
  664 + symbol then 1 + num_non_maml_arities(t),
  665 + },
  666 + verb then 1 + num_non_maml_arities(t)
  667 + }
  668 + }.
  669 +
  670 +define One
  671 + dump_eval_prim3
  672 + (
  673 + WStream fp
  674 + ) =
  675 + print(fp,"\npublic define MAML2 eval (Toolbox tbox, MAML1 m).");
  676 + print(fp,"\npublic define Result(MAML_Error,Value(String)) eval_as_string (Toolbox tbox, MAML_Pos pos, MAML1 m).");
  677 + print(fp,"\npublic define Result(MAML_Error,Value(Int)) eval_as_int (Toolbox tbox, MAML_Pos pos, MAML1 m).");
  678 + print(fp,"\npublic define Result(MAML_Error,Value(Int)) eval_as_pint (Toolbox tbox, MAML_Pos pos, MAML1 m).");
  679 + print(fp,"\npublic define Result(MAML_Error,Value(Bool)) eval_as_bool (Toolbox tbox, MAML_Pos pos, MAML1 m).");
  680 + print(fp,"\npublic define Result(MAML_Error,Value(CCMode)) eval_as_ccmode (Toolbox tbox, MAML_Pos pos, MAML1 m).");
  681 + print(fp,"\npublic define Result(MAML_Error,Value(String)) eval_as_color (Toolbox tbox, MAML_Pos pos, MAML1 m).");
  682 + print(fp,"\npublic define Result(MAML_Error,Value(String)) eval_as_symbol (Toolbox tbox, MAML_Pos pos, MAML1 m).\n");
  683 + print(fp,"\npublic define MAML2 eval_prim3 (Toolbox tbox, MAML_Prim3_MAML1 p) = \n");
  684 + print(fp," if p is\n");
  685 + print(fp," {\n");
  686 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  687 + " "+padn(name+(if arity is [] then "(pos" else "(pos,")+
  688 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then\n"+
  689 + make_with_evals(arity,0)+
  690 + " prim3("+name+(if arity is [] then "(pos" else "(pos,")+
  691 + stdvars_no_par(arity,(String v) |-> "_"+v,",")+"))"+constant_string(num_non_maml_arities(arity),'}')
  692 + ,primitives3),",\n"));
  693 + print(fp,"\n }.\n").
  694 +
  695 +
  696 +define One
  697 + dump_alpha_part_Prim3
  698 + (
  699 + WStream fp
  700 + ) =
  701 + print(fp,"\npublic define Maybe(MAML2) alpha_part(MAML2 m).\n");
  702 + print(fp,"\npublic define Maybe(MAML2) alpha_part(MAML_Prim3(MAML2) m) = \n");
  703 + print(fp," if m is\n");
  704 + print(fp," {\n");
  705 + print(fp,concat(map((PrimMark3 m) |-> since m is primitive3(name,_,arity,_,_),
  706 + " "+padn(name+
  707 + ( if arity is [] then "(pos)" else
  708 + "(pos,"+stdvars_no_par(arity,(String v) |-> v,",")+")"))+" then\n"+
  709 + concat(map_iterate((Int i, ParseMode mod) |-> if mod is
  710 + {
  711 + maml then " if alpha_part(_"+i+") is success(__"+i+") then success(__"+i+") else\n",
  712 + maml(mb) then if mb is
  713 + {
  714 + any then " if alpha_part(_"+i+") is success(__"+i+") then success(__"+i+") else\n"
  715 + bool then "",
  716 + color then "",
  717 + ccmode then "",
  718 + int then "",
  719 + pint then "",
  720 + nzint then "",
  721 + string then "",
  722 + symbol then ""
  723 + },
  724 + verb then ""
  725 + }, arity, 0, (Int i) |-> i+1))+" failure"
  726 + ,primitives3),",\n"));
  727 + print(fp,"\n }.\n").
  728 +
  729 +
  730 +
  731 +global define One
  732 + make_prim2_file
  733 + (
  734 + List(String) _
  735 + ) =
  736 + forget(make_directory("generated",default_directory_mode));
  737 + if file("generated/prim2.anubis",new) is
  738 + {
  739 + failure then print("Cannot create file 'generated/prim2.anubis'\n"),
  740 + success(filep) then with fp = (WStream)weaken(filep),
  741 +
  742 + print(fp,"\n\n This file was automatically generated from within ../maml4_private.anubis\n");
  743 + print(fp," by 'make_prim2_file'.\n");
  744 + print(fp,"\nread lexical_analysis/fast_lexer_5.anubis\n");
  745 + print(fp,"\nread ../maml4_types.anubis\n");
  746 + print(fp,"\npublic define MAML1 replace_vars_in_MAML(MAML1 m, List(MAML1) values).\n");
  747 + print(fp,"\npublic define MAML3 replace_vars_in_MAML(MAML2 m, List(MAML3) values).\n");
  748 + print(fp,"\npublic define MAML2 replace_vars_in_MAML(MAML2 m, List(MAML2) values).\n");
  749 + print(fp,"\npublic define MAML3 replace_vars_in_MAML(MAML2a m, List(MAML3) values).\n");
  750 + print(fp,"\npublic define List(MAML_Error) extract_errors(MAML2 m).\n");
  751 + dump_prims_names_format(fp);
  752 + print(fp,"\npublic define MAML_Pos make_pos(LexingTools t, LexerAux a).\n");
  753 + dump_prims_lexer_items(fp);
  754 + dump_make_parse_prim1(fp);
  755 + dump_make_parse_prim1_in_list(fp);
  756 + dump_replace_vars_in_prim1(fp);
  757 + print(fp,"\npublic define MAML1 make_lists(MAML1 m).\n");
  758 + dump_make_lists_prim1(fp);
  759 + print(fp,"\ndefine macro Value(Int) replace_vars_in_MAML(Value(Int) i, List(MAML3) vs) = i.");
  760 + print(fp,"\ndefine macro Value(Bool) replace_vars_in_MAML(Value(Bool) i, List(MAML3) vs) = i.");
  761 + print(fp,"\ndefine macro Value(String) replace_vars_in_MAML(Value(String) i, List(MAML3) vs) = i.\n");
  762 + print(fp,"\ndefine macro Value(Int) replace_vars_in_MAML(Value(Int) i, List(MAML2) vs) = i.");
  763 + print(fp,"\ndefine macro Value(Bool) replace_vars_in_MAML(Value(Bool) i, List(MAML2) vs) = i.");
  764 + print(fp,"\ndefine macro Value(String) replace_vars_in_MAML(Value(String) i, List(MAML2) vs) = i.\n");
  765 + dump_replace_vars_in_prim3(fp,"MAML2","MAML3");
  766 + dump_replace_vars_in_prim3(fp,"MAML2","MAML2");
  767 + dump_replace_vars_in_prim3(fp,"MAML2a","MAML3");
  768 + dump_replace_vars_in_prim3_MAML1(fp);
  769 + dump_make_parse_prim3(fp);
  770 + dump_make_parse_prim3_in_list(fp);
  771 + print(fp,"\npublic define List(MAML_Error) extract_errors(MAML3 m).");
  772 + print(fp,"\ndefine macro List(MAML_Error) extract_errors(Value(Int) i) = [].");
  773 + print(fp,"\ndefine macro List(MAML_Error) extract_errors(Value(String) i) = [].");
  774 + print(fp,"\ndefine macro List(MAML_Error) extract_errors(Value(Bool) i) = [].\n");
  775 + dump_make_extract_errors_prim3(fp,"MAML2");
  776 + dump_make_extract_errors_prim3(fp,"MAML3");
  777 + dump_html_formater(fp);
  778 + dump_arity_functions(fp);
  779 + print(fp,"\npublic define MAML2 glue_texts(MAML2 m).\n");
  780 + print(fp,"\npublic define MAML2b glue_texts(MAML2b m).\n");
  781 + print(fp,"\ndefine macro Value(Int) glue_texts(Value(Int) i) = i.");
  782 + print(fp,"\ndefine macro Value(String) glue_texts(Value(String) i) = i.");
  783 + print(fp,"\ndefine macro Value(Bool) glue_texts(Value(Bool) i) = i.\n");
  784 + dump_glue_texts_MAML2(fp);
  785 + dump_glue_texts_MAML2b(fp);
  786 + dump_map_MAML_Prim3(fp);
  787 + dump_map_MAML_Prim1(fp);
  788 + dump_map_MAML_Prim3_MAML1(fp);
  789 + dump_eval_prim3(fp);
  790 + dump_alpha_part_Prim3(fp);
  791 + unique
  792 + }.
  793 +
  794 +execute anbexec make_prim2_file
  795 +transmit generated/prim2.anubis
  796 +
  797 + At this point, we have the automatically generated tools.
  798 +
  799 +public define MAML_Pos
  800 + make_pos
  801 + (
  802 + LexingTools t,
  803 + LexerAux a
  804 + ) =
  805 + position(path(a),fname(a),line(t)(unique),column(t)(unique),offset(t)(unique)).
  806 +
  807 +
  808 +
  809 + *** Replacing variables, etc... in a VText.
  810 +
  811 +define Text
  812 + force_nth
  813 + (
  814 + Int i,
  815 + List(Text) l
  816 + ) =
  817 + if l is
  818 + {
  819 + [ ] then should_not_happen(t("")),
  820 + [h . t] then
  821 + if i =< 0
  822 + then h
  823 + else force_nth(i-1,t)
  824 + }.
  825 +
  826 +define MAML1
  827 + force_nth1
  828 + (
  829 + Int i,
  830 + List(MAML1) l
  831 + ) =
  832 + if l is
  833 + {
  834 + [ ] then should_not_happen(empty),
  835 + [h . t] then
  836 + if i =< 0
  837 + then h
  838 + else force_nth1(i-1,t)
  839 + }.
  840 +
  841 +
  842 + 'replace_vars_etc' is used in 'generated/prim2.anubis'.
  843 +
  844 +public define Text
  845 + replace_vars_etc
  846 + (
  847 + String path,
  848 + MAML_HTML_Options opts,
  849 + VText text,
  850 + List(Text) values
  851 + ) =
  852 + if text is
  853 + {
  854 + t(s) then t(s),
  855 + v(i) then force_nth(i-1,values),
  856 + fnsize then t(to_decimal(opts.note_font_size)),
  857 + textwidth then t(to_decimal(opts.text_width)),
  858 + vt1 + vt2 then replace_vars_etc(path,opts,vt1,values)+replace_vars_etc(path,opts,vt2,values)
  859 + }.
  860 +
  861 +
  862 + *** Translating messages to English.
  863 +
  864 +define String
  865 + to_English
  866 + (
  867 + LexicalError($T) e
  868 + ) =
  869 + if e is lex_error(b,t,a) then
  870 + to_string(b)+" at line "+t.line(unique).
  871 +
  872 +public define String
  873 + format
  874 + (
  875 + MAML_Pos p
  876 + ) =
  877 + since p is position(path,fname,line,col,off),
  878 + (path/fname)+" at "+(line+1)+":"+(col+1)+"["+off+"]". // +1 because we number lines and columns from 0
  879 + // whereas text editors generally number them from 1
  880 +
  881 +public define String
  882 + to_English
  883 + (
  884 + MAML_Error e
  885 + ) =
  886 + if e is
  887 + {
  888 + lexical(pos,le) then "Lexical error in '"+format(pos)+"': "+to_English(le),
  889 + lexical(pos,le) then "Lexical error in '"+format(pos)+"': "+to_English(le),
  890 + missing_end(path,fname) then "Missing $end in '"+(path/fname)+"'",
  891 + end_in_operand(pos) then "$end found within an operand in '"+format(pos)+"'",
  892 + end_in_list(pos) then "$end found within a list in '"+format(pos)+"'",
  893 + unknown_mark(pos,name) then "Unknown mark in '"+format(pos)+"': "+name,
  894 + premature_end_of_file(path,fname) then "Premature end of file in '"+(path/fname)+"'",
  895 + missing_operand(pos,name) then "Missing operand to "+name+" in '"+format(pos)+"'",
  896 + file_not_found(pos,path) then "File '"+path+"' not found in '"+format(pos)+"'.",
  897 + cannot_read_file(pos,path) then "Cannot read file '"+path+"' in '"+format(pos)+"'.",
  898 + cannot_open_file(path) then "Cannot open file '"+path+"'.",
  899 + cannot_create_file(path) then "Cannot create file '"+path+"'.",
  900 + cannot_write_file(path) then "Cannot write into file '"+path+"'.",
  901 + cannot_execute_latex then "Cannot execute LaTeX",
  902 + cannot_execute_dvipng then "Cannot execute dvipng",
  903 + png_file_corrupted(path) then "PNG file corrupted: '"+path+"'",
  904 + dvipng_error(code) then "dvipng error (return code = "+code+")",
  905 + regexpr(pos,ree) then "Error in regular expression: "+to_English(ree)+" in '"+format(pos)+"'",
  906 + latex_error(pos,logfname) then "LaTeX error in '"+format(pos)+"' (see log file '"+logfname+"')",
  907 + latex_error(code,logfname) then "LaTeX returned the error code "+code+" (see log file '"+logfname+"')",
  908 + integer_expected(pos) then "Integer expected in '"+format(pos)+"'",
  909 + must_be_a_color(pos,s) then "Operand '"+s+"' is not a valid color in '"+format(pos)+"'",
  910 + boolean_expected(pos,s) then "Operand '"+s+"' must be a boolean in '"+format(pos)+"'",
  911 + must_be_an_int(pos,s) then "Operand '"+s+"' must be an integer in '"+format(pos)+"'",
  912 + must_be_a_nzint(pos,s) then "Operand '"+s+"' must be a non zero integer in '"+format(pos)+"'",
  913 + must_be_a_positive_int(pos,s) then "Operand '"+s+"' must be a positive or zero integer in '"+format(pos)+"'",
  914 + must_be_a_symbol(pos,s) then "Operand '"+s+"' is not a valid symbol in '"+format(pos)+"'",
  915 + string_expected(pos,s) then "In '"+format(pos)+"', a character string was expected instead of '"+s+"'."
  916 + invalid_initial_counter_value(pos,v) then "Invalid initial counter value: "+v+" in '"+format(pos)+"'",
  917 + unknown_counter(pos,name) then "Unknown counter: '"+name+"' in '"+format(pos)+"'",
  918 + unknown_macro_name(pos,s) then "Unknown macro name '"+s+"' in '"+format(pos)+"'",
  919 + invalid_number_to_add(pos,v) then "Invalid number '"+v+"' to sadd to counter in '"+format(pos)+"'",
  920 + unknown_colorizer(name) then "Unknown colorizer '"+name+"'",
  921 + colorizer_already_exists(pos,name) then "In '"+format(pos)+"', colorizer '"+name+"' is already constructed.",
  922 + not_a_colorizercall_mode(pos,s) then "In '"+format(pos)+"', '"+s+"' is not a $colorizercall mode.",
  923 + unknown_accumulator(pos,name) then "In '"+format(pos)+"', unknown accumulator: '"+name+"'.",
  924 + invalid_apply_name(pos,name) then "In '"+format(pos)+"' invalid mark name for $apply: '"+name+"'."
  925 + bad_apply_arity(pos,name) then "In '"+format(pos)+"' invalid arity for $apply: '"+name+"'.",
  926 + not_a_list(pos,s) then "In '"+format(pos)+"', '"+s+"' should be a list.",
  927 + misplaced_right_bracket(pos) then "Misplaced right bracket in '"+format(pos)+"'.",
  928 + misplaced_right_par(pos) then "Misplaced right parenthese in '"+format(pos)+"'."
  929 + }.
  930 +
  931 +
  932 +
  933 +
  934 + *** Extracting errors from MAML syntax trees.
  935 +
  936 +public define String to_string(MAML1 m).
  937 +public define String to_string(MAML2 m).
  938 +public define String to_string(MAML3 m).
  939 +
  940 +public define MAML2
  941 + add_errors
  942 + (
  943 + List(MAML_Error) l
  944 + ) =
  945 + if l is
  946 + {
  947 + [ ] then empty,
  948 + [h . t] then error(h) + add_errors(t)
  949 + }.
  950 +
  951 +
  952 +define List(MAML_Error)
  953 + extract_errors_aux
  954 + (
  955 + MAML2 m
  956 + ) =
  957 + if m is
  958 + {
  959 + error(me) then [me],
  960 + erroneous(me,text) then [me],
  961 + empty then [],
  962 + false then [],
  963 + true then [],
  964 + text(value) then [],
  965 + variable(id) then [],
  966 + list(l,d) then flat(map(extract_errors_aux,l)),
  967 + alpha(m1) then extract_errors_aux(m1),
  968 + colorize(pos,cname,operand) then extract_errors_aux(operand), // cname is already a string
  969 + postpone(pos,t) then [],
  970 + prim3(p3) then extract_errors(p3),
  971 + m1 + m2 then extract_errors_aux(m1) + extract_errors_aux(m2)
  972 + }.
  973 +
  974 +public define List(MAML_Error)
  975 + extract_errors
  976 + (
  977 + MAML2 m
  978 + ) =
  979 + no_doubles(extract_errors_aux(m)).
  980 +
  981 +
  982 +define List(MAML_Error)
  983 + extract_errors_aux
  984 + (
  985 + MAML3 m
  986 + ) =
  987 + if m is
  988 + {
  989 + error(me) then [me],
  990 + erroneous(me,m1) then [me],
  991 + empty then [],
  992 + text(value) then [],
  993 + list(l) then flat(map(extract_errors_aux,l)),
  994 + postpone(pos,text) then [],
  995 + prim3(p3) then extract_errors(p3),
  996 + m1 + m2 then extract_errors_aux(m1) + extract_errors_aux(m2)
  997 + }.
  998 +
  999 +public define List(MAML_Error)
  1000 + extract_errors
  1001 + (
  1002 + MAML3 m
  1003 + ) =
  1004 + no_doubles(extract_errors_aux(m)).
  1005 +
  1006 +
  1007 +
  1008 +
  1009 +
  1010 +
  1011 + *** Formating a MAML syntax tree into a string.
  1012 +
  1013 +
  1014 +
  1015 +
  1016 + This is used when an operand of a mark must be seen as a string (for example, the name of a colorizer).
  1017 +
  1018 +
  1019 +public define String to_string (MAML1 m).
  1020 +public define String to_string (MAML2 m).
  1021 +
  1022 +
  1023 +
  1024 +define String
  1025 + to_string_aux // here we have length(d) = length(l)+1
  1026 + (
  1027 + List($M) l, // l is non empty (and $M is either MAML1 or MAML2)
  1028 + List(String) d, // d has the same length as l
  1029 + $M -> String to_string
  1030 + ) =
  1031 + if l is
  1032 + {
  1033 + [ ] then "",
  1034 + [l1 . ls] then if d is
  1035 + {
  1036 + [ ] then should_not_happen(""),
  1037 + [d1 . ds] then with rest = to_string_aux(ls,ds,to_string),
  1038 + to_string(l1)+d1+rest
  1039 + }
  1040 + }.
  1041 +
  1042 +
  1043 +define String
  1044 + to_string
  1045 + (
  1046 + List($M) l, // $M is either MAML1 or MAML2
  1047 + List(String) d, // decoration for the list
  1048 + $M -> String to_string
  1049 + ) =
  1050 + if d is
  1051 + {
  1052 + [ ] then // no decoration information available
  1053 + "["+concat(map(to_string,l),",")+"]",
  1054 + [d1 . ds1] then // decoration is available
  1055 + // special treatment if l is empty
  1056 + if l is
  1057 + {
  1058 + [ ] then if ds1 is
  1059 + {
  1060 + [ ] then should_not_happen(""),
  1061 + [d2 . _] then
  1062 + d1+d2
  1063 + },
  1064 + [_ . _] then
  1065 + d1+to_string_aux(l,ds1,to_string)
  1066 + }
  1067 + }.
  1068 +
  1069 +
  1070 +
  1071 +public define String
  1072 + to_string
  1073 + (
  1074 + MAML1 m
  1075 + ) =
  1076 + if m is
  1077 + {
  1078 + error(me) then red(to_English(me)),
  1079 + erroneous(me,m1) then to_string(m1),
  1080 + empty then "",
  1081 + text(value) then value,
  1082 + variable(id) then "$"+id,
  1083 + prim1(p1) then to_string(p1),
  1084 + list(l,d) then to_string(l,d,to_string),
  1085 + alpha(m1) then "$alphabetic("+to_string(m1)+")",
  1086 + colorize(pos,cname,op) then "$colorize("+to_string(cname)+")("+to_string(op)+")",
  1087 + define(pos,name,ar,val) then "$define("+name+")("+ar+")("+to_string(val)+")",
  1088 + undefine(pos,name) then "$undefine("+name+")",
  1089 + _if(pos,test,ift,iff) then "$if("+to_string(test)+")("+to_string(ift)+")("+to_string(iff)+")",
  1090 + prim3(p3) then to_string(p3),
  1091 + computed(m2) then to_string(m2),
  1092 + macro(pos,name,operands) then if operands is
  1093 + {
  1094 + [ ] then "$"+name,
  1095 + [_ . _] then "$"+name+concat(map((MAML1 a) |-> "("+to_string(a)+")",
  1096 + operands))
  1097 + },
  1098 + m1 + m2 then to_string(m1) + to_string(m2)
  1099 + }.
  1100 +
  1101 +public define String
  1102 + to_string_all
  1103 + (
  1104 + MAML2 m
  1105 + ).
  1106 +
  1107 +public define String
  1108 + to_string_all
  1109 + (
  1110 + MAML1 m
  1111 + ) =
  1112 + if m is
  1113 + {
  1114 + error(me) then red(to_English(me)),
  1115 + erroneous(me,m1) then "<erroneous>("+to_string_all(m1)+")",
  1116 + empty then "<empty>",
  1117 + text(value) then "<text>("+value+")",
  1118 + variable(id) then "$"+id,
  1119 + prim1(p1) then "<prim1>("+to_string(p1)+")",
  1120 + list(l,d) then "<list>["+concat(map(to_string_all,l),",")+"]",
  1121 + alpha(m1) then "$alphabetic("+to_string_all(m1)+")",
  1122 + colorize(pos,cname,op) then "$colorize("+to_string_all(cname)+")("+to_string_all(op)+")",
  1123 + define(pos,name,ar,val) then "$define("+name+")("+ar+")("+to_string_all(val)+")",
  1124 + undefine(pos,name) then "$undefine("+name+")",
  1125 + _if(pos,test,ift,iff) then "$if("+to_string_all(test)+")("+to_string_all(ift)+")("+to_string_all(iff)+")",
  1126 + prim3(p3) then "<prim3>("+to_string(p3)+")",
  1127 + computed(m2) then "<computed>("+to_string_all(m2)+")",
  1128 + macro(pos,name,operands) then if operands is
  1129 + {
  1130 + [ ] then "$"+name,
  1131 + [_ . _] then "$"+name+concat(map((MAML1 a) |-> "("+to_string_all(a)+")",
  1132 + operands))
  1133 + },
  1134 + m1 + m2 then to_string_all(m1)+"+"+to_string_all(m2)
  1135 + }.
  1136 +
  1137 +public define String
  1138 + to_string
  1139 + (
  1140 + MAML2 m
  1141 + ) =
  1142 + if m is
  1143 + {
  1144 + error(me) then red(to_English(me)),
  1145 + erroneous(me,m1) then to_string(m1),
  1146 + empty then "",
  1147 + false then "$false",
  1148 + true then "$true",
  1149 + text(value) then value,
  1150 + variable(id) then "$"+id,
  1151 + list(l,d) then to_string(l,d,to_string),
  1152 + alpha(m1) then "$alphabetic("+to_string(m1)+")",
  1153 + colorize(pos,cname,op) then "$colorize("+cname+","+to_string(op)+")",
  1154 + postpone(pos,text) then "$postpone("+to_string(text)+")",
  1155 + prim3(p3) then to_string(p3,to_string),
  1156 + m1 + m2 then to_string(m1) + to_string(m2)
  1157 + }.
  1158 +
  1159 +public define String
  1160 + to_string_all
  1161 + (
  1162 + MAML2 m
  1163 + ) =
  1164 + if m is
  1165 + {
  1166 + error(me) then red(to_English(me)),
  1167 + erroneous(me,m1) then to_string_all(m1),
  1168 + empty then "<empty>",
  1169 + false then "$false",
  1170 + true then "$true",
  1171 + text(value) then "<text>("+value+")",
  1172 + variable(id) then "$"+id,
  1173 + list(l,d) then "<list>["+concat(map(to_string_all,l),",")+"]",
  1174 + alpha(m1) then "$alphabetic("+to_string_all(m1)+")",
  1175 + colorize(pos,cname,op) then "$colorize("+cname+","+to_string_all(op)+")",
  1176 + postpone(pos,text) then "$postpone("+to_string_all(text)+")",
  1177 + prim3(p3) then "<prim3>("+to_string(p3,to_string)+")",
  1178 + m1 + m2 then to_string_all(m1) +"+"+ to_string_all(m2)
  1179 + }.
  1180 +
  1181 +public define String
  1182 + to_string
  1183 + (
  1184 + MAML2b m
  1185 + ) =
  1186 + if m is
  1187 + {
  1188 + error(me) then red(to_English(me)),
  1189 + erroneous(me,m1) then to_string(m1),
  1190 + empty then "",
  1191 + call(name) then "$call("+name+")",
  1192 + return then "$return",
  1193 + text(value) then value,
  1194 + variable(id) then "$"+id,
  1195 + list(l) then concat(map(to_string,l),"$,"),
  1196 + colorize(pos,cname,op) then "$colorize("+cname+","+to_string(op)+")",
  1197 + prim3(p3) then to_string(p3,to_string),
  1198 + m1 + m2 then to_string(m1) + to_string(m2)
  1199 + }.
  1200 +
  1201 +
  1202 +
  1203 +
  1204 +
  1205 +public define MAML2
  1206 + sum
  1207 + (
  1208 + List(MAML2) l
  1209 + ) =
  1210 + if l is
  1211 + {
  1212 + [ ] then empty,
  1213 + [h . t] then h + sum(t)
  1214 + }.
  1215 +
  1216 +public define MAML3
  1217 + sum
  1218 + (
  1219 + List(MAML3) l
  1220 + ) =
  1221 + if l is
  1222 + {
  1223 + [ ] then empty,
  1224 + [h . t] then h + sum(t)
  1225 + }.
  1226 +
  1227 +public define Text
  1228 + sum
  1229 + (
  1230 + List(Text) l
  1231 + ) =
  1232 + if l is
  1233 + {
  1234 + [ ] then t(""),
  1235 + [h . t] then h + sum(t)
  1236 + }.
  1237 +
  1238 + The replacement function below goes from MAML2 to MAML3. This replacement is used only during
  1239 + the colorization for replacing $1 in the value of a color rule.
  1240 +
  1241 +public define MAML3
  1242 + replace_vars_in_MAML
  1243 + (
  1244 + MAML2a body,
  1245 + List(MAML3) values
  1246 + ) =
  1247 + if body is
  1248 + {
  1249 + error(me) then error(me),
  1250 + erroneous(me,m1) then erroneous(me,m1),
  1251 + empty then empty,
  1252 + text(tx) then text(tx),
  1253 + variable(i) then if nth(i-1,values) is
  1254 + {
  1255 + failure then should_not_happen(empty),
  1256 + success(val) then val
  1257 + },
  1258 + list(l) then list(map((MAML2a m1) |-> replace_vars_in_MAML(m1,values),l)),
  1259 + prim3(p3) then replace_vars_in_prim3(p3,values),
  1260 + m1 + m2 then replace_vars_in_MAML(m1,values) + replace_vars_in_MAML(m2,values)
  1261 + }.
  1262 +
  1263 +
  1264 +public define MAML1
  1265 + replace_vars_in_MAML
  1266 + (
  1267 + MAML1 m,
  1268 + List(MAML1) values
  1269 + ) =
  1270 + if m is
  1271 + {
  1272 + error(me) then m,
  1273 + erroneous(me,text) then m,
  1274 + empty then m,
  1275 + text(value) then m,
  1276 + variable(id) then force_nth1(id-1,values),
  1277 + prim1(p1) then replace_vars_in_prim1(p1,values),
  1278 + list(l,d) then list(map((MAML1 m1) |-> replace_vars_in_MAML(m1,values),l),d),
  1279 + alpha(m1) then alpha(replace_vars_in_MAML(m1,values)),
  1280 + colorize(pos,cname,operand) then colorize(pos,cname,replace_vars_in_MAML(operand,values)),
  1281 + define(pos,name,ar,val) then define(pos,name,ar,replace_vars_in_MAML(val,values)),
  1282 + undefine(pos,name) then m,
  1283 + _if(pos,test,ift,iff) then _if(pos,replace_vars_in_MAML(test,values),
  1284 + replace_vars_in_MAML(ift,values),
  1285 + replace_vars_in_MAML(iff,values)),
  1286 + prim3(p3) then replace_vars_in_prim3(p3,values),
  1287 + computed(m2) then m,
  1288 + macro(pos,name,operands) then macro(pos,name,map((MAML1 m1) |-> replace_vars_in_MAML(m1,values),operands)),
  1289 + m1+m2 then replace_vars_in_MAML(m1,values) + replace_vars_in_MAML(m2,values)
  1290 + }.
  1291 +
  1292 +public define MAML2
  1293 + replace_vars_in_MAML
  1294 + (
  1295 + MAML2 body,
  1296 + List(MAML2) values
  1297 + ) =
  1298 + //iprint("replace_vars_in_MAML: body = "+to_string_all(body)+"\n");
  1299 + if body is
  1300 + {
  1301 + error(me) then body,
  1302 + erroneous(me,m1) then body,
  1303 + empty then body,
  1304 + false then body,
  1305 + true then body,
  1306 + text(tx) then body,
  1307 + variable(i) then if nth(i-1,values) is
  1308 + {
  1309 + failure then should_not_happen(empty),
  1310 + success(val) then //iprint("replace_vars_in_MAML: val = "+to_string_all(val)+"\n");
  1311 + val
  1312 + },
  1313 + list(l,d) then list(map((MAML2 m2) |-> replace_vars_in_MAML(m2,values),l),d),
  1314 + alpha(m1) then alpha(replace_vars_in_MAML(m1,values)),
  1315 + colorize(pos,cn,op) then colorize(pos,cn,replace_vars_in_MAML(op,values)),
  1316 + postpone(pos,text) then body,
  1317 + prim3(p3) then replace_vars_in_prim3(p3,values),
  1318 + m1 + m2 then replace_vars_in_MAML(m1,values) + replace_vars_in_MAML(m2,values)
  1319 + }.
  1320 +
  1321 +
  1322 + *** Constructing the initial macro tree (containing predefined macros).
  1323 +
  1324 + Definition of predefined macros. Notice that $comment cannot be externalized because of
  1325 + the mode of parsing ('verb') of its operand.
  1326 +
  1327 +
  1328 +define MAML_Pos ipos = position("internal","",0,0,0).
  1329 +
  1330 + define List(MacroDef)
  1331 + predefined_macros
  1332 + =
  1333 + [
  1334 + macro("error", [maml], empty), // this definition can be superseded by the user
  1335 + macro("comment", [verb], empty),
  1336 + macro("red", [maml], prim3(rgb(ipos,text("255,0,0"),variable(1)))),
  1337 + macro("blue", [maml], prim3(rgb(ipos,text("0,0,255"),variable(1)))),
  1338 + macro("green", [maml], prim3(rgb(ipos,text("0,255,0"),variable(1)))),
  1339 + macro("yellow", [maml], prim3(rgb(ipos,"255,255,0",variable(1)))),
  1340 + macro("grey", [maml], prim3(rgb(ipos,"120,120,120",variable(1)))),
  1341 +
  1342 + macro("section", [maml], prim3(sec(ipos,variable(1)))),
  1343 + macro("subsection", [maml], prim3(subsec(ipos,variable(1)))),
  1344 + macro("subsubsection", [maml], prim3(subsubsec(ipos,variable(1))))
  1345 + ].
  1346 +
  1347 +
  1348 + An adhoc iteration function used for constructing the initial macro tree.
  1349 +
  1350 +define $T
  1351 + iterate
  1352 + (
  1353 + ($D,$T) -> $T f,
  1354 + List($D) l,
  1355 + $T t
  1356 + ) =
  1357 + if l is
  1358 + {
  1359 + [ ] then t,
  1360 + [d1 . others] then
  1361 + iterate(f,others,f(d1,t))
  1362 + }.
  1363 +
  1364 + public define MacroTree
  1365 + initial_macro_tree
  1366 + =
  1367 + // a function for inserting a single definition
  1368 + with ins = (MacroDef def, MacroTree t) |-> insert(name(def),[def],t),
  1369 + iterate(ins,predefined_macros,new_tree(bt24cmp)).
  1370 +
  1371 +
  1372 + *** Counting errors.
  1373 +
  1374 + public define One
  1375 + count_error
  1376 + (
  1377 + Toolbox tbox
  1378 + ) =
  1379 + with v = tbox.keep.max_errors_v,
  1380 + v <- *v + 1.
  1381 +
  1382 + public define Bool
  1383 + too_many_errors
  1384 + (
  1385 + Toolbox tbox
  1386 + ) =
  1387 + *(tbox.keep.max_errors_v) =< 0.
  1388 +
  1389 +
  1390 + *** Getting the last definition (if any) of a macro.
  1391 +
  1392 +public define Maybe(MacroDef)
  1393 + get_macro_def
  1394 + (
  1395 + Toolbox tbox,
  1396 + String macro_name
  1397 + ) =
  1398 + if get(macro_name,*(tbox.keep.macro_tree_v)) is
  1399 + {
  1400 + failure then failure,
  1401 + success(l) then if l is
  1402 + {
  1403 + [ ] then failure,
  1404 + [h . _] then success(h)
  1405 + }
  1406 + }.
  1407 +
  1408 +
  1409 +public define Maybe(Int)
  1410 + get_macro_arity
  1411 + (
  1412 + Toolbox tbox,
  1413 + String macro_name
  1414 + ) =
  1415 + if get(macro_name,*(tbox.keep.arity_tree_v)) is
  1416 + {
  1417 + failure then failure,
  1418 + success(l) then if l is
  1419 + {
  1420 + [ ] then failure,
  1421 + [h . _] then success(h)
  1422 + }
  1423 + }.
  1424 +
  1425 +
  1426 + *** Dividing a 'Word32' by a 'Float'.
  1427 +
  1428 +public define Word32
  1429 + Word32 x / Float f
  1430 + =
  1431 + if to_Float(x) / f is
  1432 + {
  1433 + failure then x,
  1434 + success(q) then integral_part_to_Word32(q)
  1435 + }.
  1436 +
  1437 +
  1438 + *** Dividing a 'Float' by an 'Int'.
  1439 +
  1440 +public define Float
  1441 + Float f / Int n
  1442 + =
  1443 + if f/to_Float(n) is
  1444 + {
  1445 + failure then f,
  1446 + success(q) then q
  1447 + }.
  1448 +
  1449 +public define Int
  1450 + Int x / Float f
  1451 + =
  1452 + if to_Float(x)/f is
  1453 + {
  1454 + failure then x,
  1455 + success(q) then integral_part(q)
  1456 + }.
  1457 +
  1458 +
  1459 + *** Printing a message on 'stdout' in case '-verbose' option is set.
  1460 +
  1461 +public define macro $T
  1462 + if_verbose
  1463 + (
  1464 + Toolbox tbox,
  1465 + String before, // what must be printed before the term is executed
  1466 + $T term, // the term to be excuted
  1467 + String after // what must be printed after the term is executed
  1468 + ) =
  1469 + with v = verbose:tbox.keep.options,
  1470 + (if v then iprint(before) else unique);
  1471 + with result = term,
  1472 + (if v then iprint(after) else unique);
  1473 + result.
  1474 +
  1475 +
  1476 + *** Formating a Value(?).
  1477 +
  1478 +public define String
  1479 + to_decimal
  1480 + (
  1481 + Value(Int) v
  1482 + ) =
  1483 + since v is value(vh,vp), "$ifhtml("+to_decimal(vh)+")$ifpdf("+to_decimal(vp)+")".
  1484 +
  1485 +public define String
  1486 + to_string
  1487 + (
  1488 + Value(String) v
  1489 + ) =
  1490 + since v is value(vh,vp), "$ifhtml("+vh+")$ifpdf("+vp+")".
  1491 +
  1492 +define String
  1493 + format
  1494 + (
  1495 + Bool b
  1496 + ) =
  1497 + if b then "$true" else "$false".
  1498 +
  1499 +public define String
  1500 + to_string
  1501 + (
  1502 + Value(Bool) v
  1503 + ) =
  1504 + since v is value(vh,vp), "$ifhtml("+format(vh)+")$ifpdf("+format(vp)+")".
  1505 +
  1506 +public define String
  1507 + to_string
  1508 + (
  1509 + Value(CCMode) v
  1510 + ) =
  1511 + since v is value(vh,vp), "$ifhtml("+format(vh)+")$ifpdf("+format(vp)+")".
  1512 +
  1513 +
  1514 +
  1515 +
0 1516 \ No newline at end of file
... ...
anubis_dev/library/doc_tools/maml4_record.anubis 0 → 100644
  1 +
  2 +
  3 + MAML4
  4 +
  5 + Tools needed by marks requiring an immediate action.
  6 +
  7 +
  8 +transmit maml4_lexers.anubis
  9 +
  10 +
  11 + *** This file defines the following function:
  12 +
  13 +public define One record_definition (Toolbox tbox,
  14 + String name,
  15 + Int numargs,
  16 + MAML body).
  17 +public define One record_colorrule (Toolbox tbox,
  18 + String cname,
  19 + String regexpr,
  20 + MAML body).
  21 +public define Result(RegExprError,MAML) make_colorizer (Toolbox tbox,
  22 + String name).
  23 +public define MAML apply_colorizations (Toolbox tbox,
  24 + MAML m,
  25 + List(Colorizer) clrzrs).
  26 +public define One do_undefine (Toolbox tbox,
  27 + String name).
  28 +
  29 + --- That's all for the public part ! -------------------------------------------------
  30 +
  31 + The primitive marks which need to be handled are:
  32 +
  33 + $colorizer
  34 + $colorrule
  35 + $define
  36 + $input
  37 + $output
  38 + $undefine
  39 +
  40 + Other primitive marks don't need anything (at parse time).
  41 +
  42 + Macros need to be expanded (this is done in the parser).
  43 +
  44 + Create a constant 'maml' arity.
  45 +define List(ParseMode)
  46 + cst_maml_arity // for example: 3 |-> [maml,maml,maml]
  47 + (
  48 + Int n
  49 + ) =
  50 + if n =< 0 then [ ] else [maml . cst_maml_arity(n-1)].
  51 +
  52 +public define One
  53 + record_definition
  54 + (
  55 + Toolbox tbox,
  56 + String name,
  57 + Int numargs,
  58 + MAML body
  59 + ) =
  60 + with v = tbox.keep.macro_tree_v,
  61 + v <- update(name,*v,(Maybe(List(MacroDef)) mb_m) |-> if mb_m is
  62 + {
  63 + failure then success([macro(name,cst_maml_arity(numargs),body)])
  64 + success(l) then success([macro(name,cst_maml_arity(numargs),body) . l])
  65 + }).
  66 +
  67 +
  68 +
  69 +
  70 + *** Colorizing stuff.
  71 +
  72 +public define One
  73 + record_colorrule
  74 + (
  75 + Toolbox tbox,
  76 + String cname,
  77 + String regexpr,
  78 + MAML body
  79 + ) =
  80 + with v = tbox.keep.colorrules_v,
  81 + v <- [rule(cname,regexpr,body) . *v].
  82 +
  83 +
  84 + Parsing a string to be colorized.
  85 +
  86 +define MAML
  87 + color_parser
  88 + (
  89 + One -> LexOut(ColorToken,One) color_lexer
  90 + ) =
  91 + if color_lexer(unique) is
  92 + {
  93 + error(e) then empty,
  94 + ok(s) then if s is
  95 + {
  96 + end_of_input then empty,
  97 + color(c,tx) then replace_vars_in_MAML(c,[text(tx)]) + color_parser(color_lexer),
  98 + text(tx) then text(tx) + color_parser(color_lexer)
  99 + }
  100 + }.
  101 +
  102 +
  103 +
  104 + A colorizer is mainly a function of type 'String -> MAML' transforming a character string into
  105 + a 'colorized' MAML tree. The function below creates such a colorizer. It proceeds as follows:
  106 +
  107 + - it selects all color rules corresponding to the name of the colorizer,
  108 + - it creates a fast lexer description using these color rules, adding
  109 + two generic lexer items for all those sequences not recognized by the given
  110 + regular expressions (since everything in the text to be colorized must be kept),
  111 + - it calls 'make_saved_lexer' (from fast_lexer_5.anubis) in order to make the lexer,
  112 + - it construct the colorizing function by applying the above 'color_parser' to the
  113 + lexer just constructed.
  114 +
  115 +
  116 +define Result(RegExprError,String -> MAML) // the colorizing function
  117 + create_colorizer
  118 + (
  119 + Toolbox tbox,
  120 + String name, // of colorizer
  121 + List(ColorRule) rules
  122 + ) =
  123 + with myrules = map_select((ColorRule r) |->
  124 + if r is rule(n,_,_) then if n = name
  125 + then success(r)
  126 + else failure,
  127 + rules),
  128 + // 'reverse' is needed because the order conventions must be the same as in fast_lexer_5.anubis.
  129 + ldesc = (List(LexerItem(ColorToken,One)))reverse(
  130 + [
  131 + lexer_item(".", return((ByteArray b, LexingTools t, One u) |-> ok(text(to_string(b))))),
  132 + lexer_item("([# #r#t]+)|(#n)", return((ByteArray b, LexingTools t, One u) |-> ok(text(to_string(b)))))
  133 + . map((ColorRule r) |-> if r is rule(_,re,c) then
  134 + lexer_item(re,return((ByteArray b, LexingTools t, One u) |-> ok(color(c,to_string(b))))),myrules)
  135 + ]
  136 + ),
  137 + if if_verbose(tbox,"Making colorizer '"+name+"' ... ",make_saved_lexer(ldesc,end_of_input,'#'),"done\n") is
  138 + {
  139 + error(e) then error(e),
  140 + ok(lexer) then
  141 + ok((String text) |->
  142 + with lex = lexer(make_lexing_stream("",text),unique),
  143 + color_parser(lex))
  144 + }.
  145 +
  146 +
  147 +
  148 +
  149 + The function below returns the colorizing function associated to the name of a colorizer. If not
  150 + found it returns a function performing no colorisation at all (but preserving the text).
  151 +
  152 +define String -> MAML
  153 + get_colorizer
  154 + (
  155 + List(Colorizer) l,
  156 + String name
  157 + ) =
  158 + if l is
  159 + {
  160 + [ ] then (String s) |-> text(s),
  161 + [h . t] then since h is clrzr(n,f),
  162 + if n = name
  163 + then f
  164 + else get_colorizer(t,name)
  165 + }.
  166 +
  167 +
  168 +
  169 +public define Result(RegExprError,MAML)
  170 + make_colorizer
  171 + (
  172 + Toolbox tbox,
  173 + String name
  174 + ) =
  175 + if create_colorizer(tbox,name,*(tbox.keep.colorrules_v)) is
  176 + {
  177 + error(e) then error(e),
  178 + ok(f) then
  179 + with clrzrs_v = tbox.keep.colorizers_v,
  180 + clrzrs_v <- [clrzr(name,f) . *clrzrs_v];
  181 + ok(empty)
  182 + }.
  183 +
  184 +
  185 +define MAML colorize(MAML m, String -> MAML do_string).
  186 +
  187 +define List(MAML)
  188 + colorize_operands
  189 + (
  190 + Toolbox tbox,
  191 + List(Colorizer) clrzrs,
  192 + List(MAML) ops,
  193 + ) =
  194 + map((MAML m1) |-> apply_colorizations(tbox,m1,clrzrs) ,ops).
  195 +
  196 +
  197 +
  198 +define MAML
  199 + colorize
  200 + (
  201 + Toolbox tbox,
  202 + List(Colorizer) clrzrs,
  203 + MAML m,
  204 + String -> MAML do_string // the tool for colorizing strings
  205 + ) =
  206 + if m is
  207 + {
  208 + error(me) then m,
  209 + erroneous(me,m1) then erroneous(me,colorize(tbox,clrzrs,m1,do_string)),
  210 + empty then m,
  211 + text(value) then do_string(value),
  212 + variable(id) then m,
  213 + colorize(cname,text) then colorize(cname,colorize(tbox,clrzrs,text,do_string)),
  214 + render(name,operands) then render(name,colorize_operands(tbox,clrzrs,operands)),
  215 + render(name,operands) then render(name,colorize_operands(tbox,clrzrs,operands)),
  216 + macro(name,operands) then macro(name,map((MAML op) |-> colorize(tbox,clrzrs,op,do_string),operands)),
  217 + m1 + m2 then colorize(tbox,clrzrs,m1,do_string) + colorize(tbox,clrzrs,m2,do_string)
  218 + }.
  219 +
  220 + The function below looks for consecutive text("bla") and text("blu") and replaces them by text ("blablu"),
  221 + so that the colorizer can recognize a token spanning over several pieces of texts.
  222 +
  223 +define MAML
  224 + glue_texts
  225 + (
  226 + MAML m
  227 + ) =
  228 + if m is
  229 + {
  230 + error(me) then m,
  231 + erroneous(me,m1) then erroneous(me,glue_texts(m1)),
  232 + empty then m,
  233 + text(value) then m,
  234 + variable(id) then m,
  235 + colorize(cname,text) then colorize(cname,glue_texts(text)),
  236 + render(name,operands) then render(name,map(glue_texts,operands)),
  237 + render(name,operands) then render(name,map(glue_texts,operands)),
  238 + macro(name,operands) then macro(name,map(glue_texts,operands)),
  239 + m1 + m2 then
  240 + if m1 is text(t1)
  241 + then if m2 is text(t2)
  242 + then text(t1+t2)
  243 + else if m2 is m2a+m2b
  244 + then if m2a is text(t2a)
  245 + then glue_texts(text(t1+t2a)+m2b)
  246 + else glue_texts(m1)+glue_texts(m2)
  247 + else glue_texts(m1)+glue_texts(m2)
  248 + else if m1 is m1a+m1b
  249 + then if m1b is text(t1b)
  250 + then if m2 is text(t2)
  251 + then glue_texts(m1a+text(t1b+t2))
  252 + else glue_texts(m1)+glue_texts(m2)
  253 + else glue_texts(m1)+glue_texts(m2)
  254 + else glue_texts(m1)+glue_texts(m2)
  255 + }.
  256 +
  257 +
  258 + The function below is called when the MAML parsing is finished. It looks for colorize(<name>,<text>)
  259 + in a MAML tree and replaces them by <text> colorized by the colorizer <name>. The result is again
  260 + a MAML tree.
  261 +
  262 +public define MAML
  263 + apply_colorizations_aux
  264 + (
  265 + Toolbox tbox,
  266 + MAML m, // the MAML tree where colorizations are to be executed
  267 + List(Colorizer) clrzrs // the list of all colorizers
  268 + ) =
  269 + if m is
  270 + {
  271 + error(me) then m,
  272 + erroneous(me,m1) then erroneous(me,apply_colorizations_aux(tbox,m1,clrzrs)),
  273 + empty then m,
  274 + text(tx) then m,
  275 + variable(i) then m,
  276 + colorize(cname,txt) then with new_txt = apply_colorizations_aux(tbox,txt,clrzrs),
  277 + with do_string = get_colorizer(clrzrs,to_string(cname)),
  278 + colorize(tbox,clrzrs,glue_texts(new_txt),do_string),
  279 + render(name,args) then render(name,map((MAML m1) |-> apply_colorizations_aux(tbox,m1,clrzrs) ,args)),
  280 + render(name,args) then render(name,map((MAML m1) |-> apply_colorizations_aux(tbox,m1,clrzrs) ,args)),
  281 + macro(name,args) then macro(name,map((MAML m1) |-> apply_colorizations_aux(tbox,m1,clrzrs) ,args)),
  282 + m1 + m2 then apply_colorizations_aux(tbox,m1,clrzrs) + apply_colorizations_aux(tbox,m2,clrzrs)
  283 + }.
  284 +
  285 +
  286 +public define MAML
  287 + apply_colorizations
  288 + (
  289 + Toolbox tbox,
  290 + MAML m, // the MAML tree where colorizations are to be executed
  291 + List(Colorizer) clrzrs // the list of all colorizers
  292 + ) =
  293 + apply_colorizations_aux(tbox,check_all_forms(tbox,m),clrzrs).
  294 +
  295 +
  296 + *** Undefine.
  297 +
  298 + Remove the most recent definition of 'name'.
  299 +
  300 +public define One
  301 + do_undefine
  302 + (
  303 + Toolbox tbox,
  304 + String name
  305 + ) =
  306 + with v = tbox.keep.macro_tree_v,
  307 + v <- update(name,*v,
  308 + (Maybe(List(MacroDef)) mb_defs) |-> if mb_defs is
  309 + {
  310 + failure then failure,
  311 + success(l) then if l is
  312 + {
  313 + [ ] then failure,
  314 + [h . t] then success(t)
  315 + }
  316 + }).
  317 +
  318 +
0 319 \ No newline at end of file
... ...
anubis_dev/library/doc_tools/maml4_tutorial.maml 0 → 100644
  1 +
  2 +
  3 +
  4 + The MAML4 tutorial
  5 + (written in MAML4)
  6 +
  7 +
  8 +$begin
  9 +$define(article)(0)()
  10 +$define(tocsec)(1)($par$bold($1)$par)
  11 +$define(tocsubsubsec)(1)()
  12 +$define(subseclayout)(1)($par$big($bold($1))$par$par)
  13 +$input(basis.maml)
  14 +
  15 +
  16 +$// A counters for the catalog of marks
  17 +$pushcounter(markcount)(0)
  18 +
  19 +$// an accumulator for displaying a table of all mark names at the
  20 +$// beginning of the catalog section
  21 +$accumulator(tabmark)
  22 +
  23 +$define(marklo) $// marl layout
  24 + (1)
  25 + ($addtocounter(markcount)(1)$par$par$bold($countervalue(sec).$countervalue(markcount). $1)$par$par)
  26 +
  27 + $// A colorizer for MAML code
  28 +$colorrule(maml)(#$#/#/.*)($darkgreen($1))
  29 +$colorrule(maml)((#$[#,#[#]#(#)])|(#$[a-zA-Z#_][0-9a-zA-Z#_]*)|(#$#$))($bold($red($1)))
  30 +$colorrule(maml)(#$[0-9]+)($magenta($1))
  31 +$colorrule(maml)([0-9]+)($sienna($1))
  32 +$colorizer(maml)
  33 +
  34 +$// Some layout macros.
  35 +$define(p)(0)($par$par)
  36 +$define(title)(1)($center($big($big($bold($1)))))
  37 +$define(MAML)(0)($bold($rgb(180,0,0)(M)$rgb(0,120,0)(A)$rgb(80,80,80)(M)$rgb(0,0,220)(L)))
  38 +$define(em)(1)($italic($1))
  39 +$define(textcolor)(0)(100,20,20)
  40 +$define(mtt)(1)($tt($colorize(maml)($nolist($1))))
  41 +$define(mcode)(1)($code(230,235,220)($colorize(maml)($par$nolist($1)$par$par)))
  42 +$define(mcenter)(1)($par$center($colorize(maml)($nolist($1)))$par)
  43 +$define(argu)(1)($rgb(0,80,0)($bold($tt(<$1>))))
  44 +$define(LaTeX)(0)($latex(\LaTeX))
  45 +$define(unsafe)(0)($bold($rgb(220,0,0)(unsafe)))
  46 +$define(id)(1)($1)
  47 +$define(ptext)(1)($rgb(120,40,40)($1))
  48 +$define(fname)(1)($rgb(0,80,50)($tt($1)))
  49 +
  50 +
  51 +$// A system for displaying names of marks on several columns
  52 +$pushcounter(col)(0)
  53 +$define(advcol)(0)($if($equals($countervalue(col))(3))($setcounter(col)(0)$par)($addtocounter(col)(1)))
  54 +
  55 +$// Displaying marks in the catalog and accumulating links to them.
  56 +$define(mark0)(1)($append(tabmark)($box(20)()$box(120)($ref($1)($mtt($$$1)))$advcol)$label($1)$marklo($red($mtt($$$1))))
  57 +$define(mark1)(2)($append(tabmark)($box(20)()$box(120)($ref($1)($mtt($$$1)))$advcol)$label($1)$marklo($red($mtt($$$1$lpar$argu($2)$rpar))))
  58 +$define(mark2)(3)($append(tabmark)($box(20)()$box(120)($ref($1)($mtt($$$1)))$advcol)$label($1)$marklo($red($mtt($$$1$lpar$argu($2)$rpar$lpar$argu($3)$rpar))))
  59 +$define(mark3)(4)($append(tabmark)($box(20)()$box(120)($ref($1)($mtt($$$1)))$advcol)$label($1)$marklo($red($mtt($$$1$lpar$argu($2)$rpar$lpar$argu($3)$rpar$lpar$argu($4)$rpar))))
  60 +$define(mark4)(5)
  61 + ($append(tabmark)($box(20)()$box(120)($ref($1)($mtt($$$1)))$advcol)$label($1)$marklo($red($mtt($$$1$lpar$argu($2)$rpar$lpar$argu($3)$rpar$lpar$argu($4)$rpar$lpar$argu($5)$rpar))))
  62 +
  63 +
  64 +
  65 +
  66 + $/////////////////// Here begins the text //////////////////////////
  67 +
  68 +$title(The $MAML (version 4) Tutorial)
  69 +$title(and Reference)
  70 +$par$par$par
  71 +
  72 +$MAML (the $em(Minimalist Anubis Markup Language)) is an easy to use tool for writing texts. It provides
  73 +commands for using different $bold(font) $italic(styles), $big(font $big(sizes)), $red(colors), for making lists, tables,
  74 +sectionning units, inserting images
  75 +and
  76 +hypertext links, automatically making a table of contents,
  77 +and most sorts of things which are useful for writting texts which are agreable to read.
  78 +It is also able to automatically produce syntactic colorations. The $MAML
  79 +compiler produces HTML and PDF output files from a $MAML source text.
  80 +This documentation itself was written in $MAML.$p
  81 +
  82 +Despite its computing capabilities, $MAML is $em(not a programming language). It is a $em(text formating language).
  83 +Programming with $MAML is easy provided you write only very short pieces of programs. Making big programs in $MAML
  84 +would generate absolutely unreadable source texts (like what happens with $latex(\TeX)). We have managed to present
  85 +many (short) examples of $MAML programming in this tutorial, which helps to quickly understand the explanations.$p
  86 +
  87 +The very first version of $MAML was designed for allowing users on a forum to decorate their messages, and was
  88 +very rudimentary. This is
  89 +why $MAML was called $em(minimalist). This version 4 is now quite far from being $em(minimalist), but the name $MAML
  90 +remains (partly because it's funny when pronounced in French).
  91 +
  92 +$p
  93 +$center($bold(Table of Contents))$par
  94 +$tableofcontents
  95 +
  96 +
  97 +$////////////////////////////////////////////////////////////////////////////////:
  98 +$section(howto)(How to use $MAML)
  99 +$subsection(ascmdlinetool)(As a command line tool)
  100 +$MAML can be used as a command line tool. This tool can work to its full power
  101 +only if $mtt(pdflatex) and $mtt(dvipng) are installed on
  102 +your system. If they are not, you can still use $MAML, but the mark $mtt($$latex) will not work, and you will not be able
  103 +to produce a PDF output. See the Anubis library documentation for more precise explanations.
  104 +$par
  105 +$par
  106 +Assuming that the file $mtt(my_file.maml) contains some $MAML source text,
  107 +you just have to issue the command:
  108 +$mcode(anbexec maml my_file.maml)
  109 +and the $MAML compiler will produce a file named $mtt(my_file.maml.html) that you can view with your favorite browser.
  110 +$par
  111 +$par
  112 +This command line tool has several options that you can discover by typing:
  113 +$mcode(anbexec maml)
  114 +For example, the option $mtt(-pdf) produces a PDF output.
  115 +$p
  116 +
  117 +$subsection(fromyoursource)(From within your Anubis source code)
  118 +You may also want to use the $MAML compiler from within your Anubis source code. For example, you may want to use $MAML
  119 + on a web site.
  120 +In this case, have a look at the Anubis library documentation.
  121 +Notice that several $MAML marks are $unsafe for a use on the web. We explain in the library documentation
  122 +how to restrict $MAML to safe marks.$p
  123 +
  124 +
  125 +$subsection(aswebuser)(As a web user)
  126 +Since $MAML can be used in a web site (powered for example by the Anubis web server), it is possible to allow web users
  127 +(those persons visiting the web site) to write $MAML texts within web pages. In this case, the set of available $MAML
  128 +marks is restricted for ensuring the security of the web server.$p
  129 +
  130 +
  131 +
  132 +$//////////////////////////////////////////////////////////////////////////
  133 +$section(syntax)(The $MAML syntax)
  134 +$subsection(beginend)($mtt($$begin), $mtt($$end) and special characters)
  135 +When it reads a source text, the $MAML compiler ignores everything until the first occurrence of $ref(begin)($mtt($$begin)). After
  136 +this $em(mark), the compiler parses and evaluates the text until it finds $ref(end)($mtt($$end)). Then again, it ignores everything
  137 +until the next $mtt($$begin), and so on.$p
  138 +
  139 +Between $mtt($$begin) and $mtt($$end), the compiler considers all characters as neutral (i.e. they represent only
  140 +themselves), except the character $mtt($$). This character introduces a so-called $em(mark), which can have so-called
  141 +$em(operands). The operands are delimited by pairs of parentheses.
  142 +
  143 +Within an operand, all characters are considered as pure text, except the following:
  144 +$list(
  145 + $item the character $mtt($$),
  146 + $item the left and right parentheses $mtt($lpar) and $mtt($rpar). They are used for delimiting blocks of text.
  147 + $item the left and right square brackets $mtt($[) and $mtt($]). They are used for delimiting lists, and within such
  148 + lists, the comma $mtt($,) is used for separating the elements of the list. The comma is otherwise neutral.
  149 +)
  150 + Of course, the possibility exists of inserting these characters as usual neutral characters. It is enough to prefix
  151 + them by a $mtt($$). Hence, for example, $mtt($[) marks the beginning of a list, whereas $mtt($$$[) just represents a
  152 + left square bracket.$p
  153 +
  154 + The figure below sumarizes the above rules.
  155 +$mcode( $em($darkgreen(before $$begin everything is ignored))
  156 +
  157 + $$begin
  158 +
  159 + $em($navy(here, outside any operand of mark, only the character $$ is special))
  160 +
  161 + $$a_mark(... $em($darkred(here, $bold($$ $( $) $[) and $bold($]) are special)) ...)
  162 + (... $[ $em($sienna(and here, the comma also is special)) $]
  163 + ... $$another_mark( $em($darkred(here too, $bold($$ $( $) $[) and $bold($]) are special)) ...) ...
  164 + (... $$nolist($em($purple(but here, only $bold($$ $() and $bold($)) are special
  165 + even if we are within a list, but brackets
  166 + must still be balanced))) ...) )
  167 +
  168 + $$end
  169 +
  170 + $em($darkgreen(here again, everything is ignored))
  171 +
  172 + $$begin
  173 +
  174 + $em($navy(and here, it works again as above after the first $$begin))
  175 + $em($black(you can alternate $$begin and $$end any number of times))
  176 +
  177 + $em($black(etc... (and an $$end is required for closing each $$begin))))
  178 +
  179 +
  180 +$subsection(syntaxmark)(Marks)
  181 +This character $mtt($$) indicates
  182 +that what follows is a $em(mark). The name of the mark (a non empty sequence of characters among
  183 +$mtt($black(A...Za...z0...9))) and the underscore $mtt(_) and not beginning by a digit)
  184 +immediatly follows the character $mtt($dollar). The operands
  185 +of the mark follow this name, and each one must be delimited by a pair of parentheses. For example, if you
  186 +want to render some text in dark red, you can write this, where $mtt(rgb) is the name of the mark (this mark takes two operands):$par
  187 +$mcenter($mtt($$rgb(120,0,0)(This text is rendered in dark red.)))
  188 +which produces this:
  189 +$mcenter($rgb(120,0,0)(This text is rendered in dark red.))
  190 +
  191 +You shall learn below how to write $em(macros) in $MAML using the mark $ref(define)($mtt($$define)),
  192 +so that you can actually simplify the writing of the above. For example the name $MAML itself
  193 +is produced by the macro $mtt($$MAML) which is defined as follows:
  194 +$mcode($$define(MAML)(0) $$// defining the macro $$MAML taking zero operand
  195 + ($$bold($$rgb(180,0,0)(M)$$rgb(0,120,0)(A)$$rgb(80,80,80)(M)$$rgb(0,0,220)(L))))
  196 +
  197 +$subsection(linecomments)(Line comments)
  198 +Notice that you can put $em(line comments) into your $MAML source texts as follows:$p
  199 +$center($mtt($$// blah blah blah ...))$par
  200 +The mark $mtt($$//) and what follows until the end of the line are ignored by the compiler (but it keep
  201 +the new line charaters). This kind of comment can be
  202 +put everywhere, including within operands of marks, between the operands of a mark (as shown above) and between
  203 +a mark and its first operand.$p
  204 +
  205 +$subsection(balanced)(Parentheses must be balanced)
  206 +Each mark accepts a fixed number of operands. Since each operand must be delimited by a pair of parentheses
  207 +(which are not part of the operand itself), the
  208 +parentheses which are part of the operand (if any) must be balanced, otherwise the $MAML parser will not find the closing
  209 +parenthese. Nevertheless, you can still include unbalanced parentheses in an operand provided that you write them
  210 +$mtt($$lpar) (left parenthese) and $mtt($$rpar) (right parenthese).$p
  211 +
  212 +
  213 +$subsection(marknamedelim)(How mark names are delimited)
  214 +Also remark that between any two operands of a mark (and between the mark itself and its first operand), you cannot
  215 +write anything else than $em(white) characters (i.e. spaces, line-feeds, carriage-returns and tabulators), and line
  216 +comments. For example,
  217 +$mcode($$rgb(0,0,255)(My text))
  218 +is equivalent to
  219 +$mcode($$rgb (0,0,255) $$// this make a bright blue
  220 + (My Text))
  221 +But if you write this: $mtt($$rgb(0,0,255) a (My text)), the compiler will complain that an operand is missing (it
  222 +also indicates the path of the file and the line number where this happens).
  223 +$par
  224 +$par
  225 +$em(Remark:) The name of a mark is right delimited by the first character which is not an acceptable character
  226 +for such a name. If this character is a space, it is $em(not) discarded (unlike what the $latex(\TeX) compiler
  227 +does). Hence for example,
  228 +$mtt($$lpar x) (with just one space between $mtt($$lpar) and $mtt(x))
  229 +produces $lpar x (with a space between the parenthese and x),
  230 +so that it seems that there is no way to obtain $id($lpar)x (with nothing between the parenthese and x).
  231 +Actually, there is a simple trick to
  232 +obtain the later. Indeed, it is enough to define an $em(identity) macro as follows:
  233 +$mcode($$define(id)(1)($$1))
  234 +and to write $mtt($$id($$lpar)x).$p
  235 +
  236 +
  237 +
  238 +
  239 +$subsection(definingmarks)(Defining new marks with $mtt($$define))
  240 +We already saw examples of use of $mtt($$define) above. It's now time to give precisions about this possibility to
  241 +enrich the language with new marks, which is one of the most powerful tools we have at hand.$p
  242 +
  243 +The syntax of $mtt($$define) is as follows:$par
  244 +$mcenter($mtt($$define($argu(name))($argu(arity))($argu(value))))
  245 +where $argu(name) is the name you want to give to your new mark, $argu(arity) its $em(arity), i.e. the number of
  246 +operands it takes, and $argu(value) the value of the mark, which of course depends on the values of it's future operands, which
  247 +is the reason why $argu(value) contains so-called $MAML $em(variables) $mtt($$1), $mtt($$2), etc...$p
  248 +
  249 +Notice that if a macro with the same name $argu(name) is already defined, $mtt($$define) does not destroy this
  250 +previous definition of $argu(name). It pushes the new definition on a stack of definitions associated to this name. As a
  251 +consequence, when you use $mtt($$undefine($argu(name))), the most recent definition of name is poped off this stack (and
  252 +forgotten) and the previous one prevails again. See $ref(undefine)($mtt($$undefine)) for some examples.$p
  253 +
  254 +When the $MAML compiler encounters a $mtt($$define($argu(name))($argu(arity))($argu(value))), it doesn't evaluate
  255 +(i.e. it doesn't $em(compute)) $argu(name) nor $argu(arity). Consequently, these two operands must be written in their
  256 +definitive form.$p
  257 +
  258 +The third operand $argu(value) is only $em(partly evaluated) in the sens that macros are expanded within $argu(value),
  259 +but primitive marks are not executed (which is in any case mandatory since operands are not yet known).
  260 +This policy has two important consequences:
  261 +$list(
  262 + $item if $argu(value) contains a call to $argu(name), this call doesn't refer to the macro currently being defined,
  263 + but to its previous definition (if any). As a byproduct, this also forbids recursive definitions of macros, so
  264 + protecting the $MAML compiler against infinite loops.$p
  265 + $item $argu(value) cannot refer to a macro which is not yet defined (there are no forward references in $MAML), so
  266 + that the macro always keeps the meaning it has when it is defined, except that the values provided by primitive marks
  267 + will be computed only when the macro is used.
  268 +)
  269 +Nevertheless, you may want, especially if you are defining a customizable style of document for example, to define
  270 +macros making use of other macros which can be redefined by the user of your style file. The solution is first of all
  271 +to define these other macros conditionally, i.e. as follows:
  272 +$mcode($$if($$defined($argu(name)))()($$define($argu(name))(...)(...)))
  273 +that is that you provide a $em(default) definition, but only in case your user did not define $argu(name). Of course, this
  274 +implies that your user must define $argu(name) $em(before) writing $mtt($$input($argu(your style file))).$p
  275 +
  276 +$/////////////////////////////////////////////////////////////////////////
  277 +$section(style)(Be stylish)
  278 +The primitive $MAML marks are rather basic, and should preferably be used for creating macros.
  279 +In other words, it's better to first define (using the $mtt($$define) mark) the concepts you will use in your
  280 +text, rather than writing them from scratch at each occurrence. In some sens, defining these concepts is the same as
  281 +creating your own style. $p
  282 +
  283 +$subsection(basismaml)(The file $fname(basis.maml))
  284 +Notice that a file $fname(basis.maml) exists in $fname(library/doc_tools) which already contains macros of
  285 +common usage.
  286 +$p
  287 +
  288 +$subsection(styleexample)(An example)
  289 +It can be the case that some concept of your discourse has to be emphasized in a particular way, and that
  290 +you (arbitrarily) chosed to print it
  291 +in red. You should not use $mtt($$rgb(255,0,0)(...)) in the text. You should better first give a name (say $mtt(emph)) to
  292 +your concept, and define it near the beginning of the text:
  293 +$p
  294 +$mtt($$define(emph)(1)($$rgb(255,0,0)($$1)))
  295 +$p
  296 +and write $mtt($$emph(...)) in the text instead of $mtt($$rgb(255,0,0)(...)).
  297 +$p
  298 +This will structure your text in a useful semantic way, instead of a non significant way, making it easier
  299 +to later update.
  300 +It also has the advantage that you can later easily change the layout of the text by modifying
  301 +only the values in these $mtt($$define).
  302 +$p
  303 +$subsection(inputstyle)(Inputting a style file)
  304 +The $mtt($$input) mark let you $em(input) a $MAML source at any point of another $MAML source. Hence, you should
  305 +define your style in a file (say $mtt(mystyle.maml)) and put an $mtt($$input(mystyle.maml)) after the first $mtt($$begin)
  306 +of your source file. Notice that the input file also needs to contain a $mtt($$begin) and an $mtt($$end).$p
  307 +
  308 +
  309 +
  310 +$/////////////////////////////////////////////////////////////////////////////:
  311 +$section(colorize)(Automatic colorization)
  312 +$MAML has a simple system for automatic colorization of texts. Within a $MAML source text,
  313 +you can define one or several colorizers, and later apply them at will. Actually, by $em(colorization) we mean
  314 +something quite general, i.e. not dealing only with colors.$p
  315 +
  316 +$subsection(createcolorizer)(Creating a colorizer)
  317 +In order to create a colorizer, you must:
  318 +$list(
  319 + $item define one or several $italic(color rules),
  320 + $item when done, create the $italic(colorizer).
  321 +)
  322 +A color rule has the form:$par
  323 +$mcenter($mtt($$colorrule($argu(colorizer name))($argu(regular expression))($argu($MAML expression))))
  324 +The $argu(colorizer name) of the colorizer must be an ordinary symbol. The $argu(regular expression) must follow the syntax defined in
  325 +$fname(library/lexical_analysis/fast_lexer_5.anubis) (see the Anubis library documentation) and $em(is not evaluated), so
  326 +that it must be written in its definitive form.
  327 +The $argu($MAML expression) can contain the $MAML $em(variable)
  328 +$mtt($$1) which is replaced by the token (i.e. the character string recognized by the regular expression)
  329 +to be colorized.$par$par
  330 +
  331 +Once the color rules are setup, you can create the colorizer as follows:$par
  332 +$mcenter($mtt($$colorizer($argu(colorizer name))))
  333 +Then, you can colorize a text:$par
  334 +$mcenter($mtt($$colorize($argu(colorizer name))($argu(text))))
  335 +
  336 +$subsection(mycolorizer)(A colorizer example)
  337 +As an example, consider the following definition of a colorizer, which is used in this tutorial for colorizing
  338 +$MAML code:
  339 +$mcode( $$// line comments
  340 +$$colorrule(maml)(#$$#/#/.*)($$darkgreen($$1))
  341 + $$// mark names (inclusing inhibited characters)
  342 +$$colorrule(maml)($black((#$$$[#$,#$[#$]#(#)$])|(#$$$[a-zA-Z#_$]$[0-9a-zA-Z#_$]*)|(#$$#$$)))
  343 + ($$bold($$red($$1)))
  344 + $$// MAML variables
  345 +$$colorrule(maml)($black(#$$$[0-9$]+))($$magenta($$1))
  346 + $$// integers
  347 +$$colorrule(maml)($black($[0-9$]+))($$sienna($$1))
  348 + $$// creating the colorizer
  349 +$$colorizer(maml))
  350 +There are plenty of examples of use of this colorizer in this tutorial (including the above definition of the
  351 +$mtt(maml) colorizer$sp!), so that you can easily check that the result is coherent with the definition.$p
  352 +
  353 +Notice that we used $mtt($$bold) in the above definition, which is not a color per se. Actually any mark can be used, so
  354 +that colorizers can also be used for a purpose having nothing to do with colors.$p
  355 +
  356 +$subsection(colorizerprecedence)(Primitive marks and colorizers)
  357 +You also need to know what happens if the text to be colorized contains $MAML marks.
  358 +All macros are expanded before colorization applies, so that macros have no incidence on colorization, but they can be
  359 +used within a text to be colorized. $p
  360 +
  361 +Things are different for primitive marks. Indeed, how do you interpret for example
  362 +$p
  363 +$center($mtt($$colorize(maml)($black(This is $$rgb(120,0,0)(an example) text.))))
  364 +$par
  365 +It should be clear that $tt($$rgb) in this example should
  366 +have precedence over $mtt($$colorize), otherwise it would be useless. So, the behavior of $MAML is that it doesn't
  367 +apply a colorizer within the operands of primitive marks (it would be nevertheless meaningless in the case of the operand
  368 +$tt(120,0,0) of $tt($$rgb)).$p
  369 +
  370 +As a consequence, the above example gives
  371 +$colorize(maml)(This is $rgb(120,0,0)(an example) text.),
  372 +not $colorize(maml)(This is an example text.)$p
  373 +
  374 +Nevertheless, you can still colorize within an operand within a text to be colorized. For example,
  375 +$p
  376 +$center($mtt($$tt($$colorize(maml)($black($$$$bold($$darkgreen($$$$red(text))))))))
  377 +$par
  378 +produces $tt($colorize(maml)($$bold($darkgreen($$red(text))))), whereas
  379 +$p
  380 +$center($mtt($$tt($$colorize(maml)($black($$$$bold($$darkgreen($$colorize(maml)($$$$red(text)))))))))
  381 +$par
  382 +produces $tt($colorize(maml)($$bold($darkgreen($colorize(maml)($$red(text)))))).$p
  383 +
  384 +$subsection(severalcolorizers)(Using several colorizers together)
  385 +You can use several colorizers together. Below is another colorizer:
  386 +$mcode($$colorrule(funny)([a-e])($$rgb(10,0,130)($$sup($$1)))
  387 +$$colorrule(funny)([e-k])($$rgb(150,0,0)($$italic($$1)))
  388 +$$colorrule(funny)([l-p])($$rgb(100,100,0)($$big($$big($$1))))
  389 +$$colorrule(funny)([p-z])($$rgb(0,100,100)($$sub($$big($$1))))
  390 +$$colorizer(funny))
  391 +$colorrule(funny)([a-e])($rgb(10,0,130)($sup($1)))
  392 +$colorrule(funny)([e-k])($rgb(150,0,0)($italic($1)))
  393 +$colorrule(funny)([l-p])($rgb(100,100,0)($big($big($1))))
  394 +$colorrule(funny)([p-z])($rgb(0,100,100)($sub($big($1))))
  395 +$colorizer(funny)
  396 +If you write:
  397 +$mcode($$tt($$colorize(maml)
  398 + ($black($$$$bold(Some text $$colorize(funny)(with a piece of funny text) in it.)))))
  399 +you get $tt($colorize(maml)($$bold(Some text $colorize(funny)(with a piece of funny text) in it.)))$p
  400 +
  401 +
  402 +$subsection(colorizercall)(Calling a colorizer from within a colorizer)
  403 +Using several colorizers together can also help to solve particular colorizing problems, because the above is not the
  404 +whole story about $MAML colorizers. Indeed, we have another primitive mark:
  405 +$p
  406 +$center($mtt($$colorizercall($argu(mode))($argu(colorizer1))($argu(call))($argu(colorizer2))($argu(return))))
  407 +$par
  408 +which allows to $em(call) a colorizer (here $mtt($argu(colorizer2))) from within another colorizer (here $mtt($argu(colorizer1))).
  409 +The operands $mtt($argu(call)) and $mtt($argu(return)), which can be any $MAML expressions expanding into regular expressions, are used
  410 +as $em(call) and $em(return) instructions. In other words, when $mtt($argu(colorizer1)) encounters something matching the
  411 +regular expression $mtt($argu(call)) it calls $mtt($argu(colorizer2)) which will return when it founds something matching the
  412 +regular expression $mtt($argu(return)).$p
  413 +
  414 +The pieces of text matching $mtt($argu(call)) and $mtt($argu(return)) are colorized by $mtt($argu(colorizer1)) or by
  415 +$mtt($argu(colorizer2)), depending on the value of $argu(mode). There are four modes:
  416 +$list(
  417 + $item $mtt(ee) ($em(exclude-exclude)): both $argu(call) and $argu(return) are colorized by $argu(colorizer1),
  418 + $item $mtt(ei) ($em(exclude-include)): $argu(call) is colorized $argu(colorizer1) and $argu(return) by $argu(colorizer2),
  419 + $item $mtt(ie) ($em(include-exclude)): $argu(call) is colorized $argu(colorizer2) and $argu(return) by $argu(colorizer1),
  420 + $item $mtt(ii) ($em(include-include)): both $argu(call) and $argu(return) are colorized by $argu(colorizer2).
  421 +)
  422 +
  423 +
  424 +$subsection(colorcallexample)(A colorizer call example)
  425 +Consider the case of an Anubis source text, such as:
  426 +$ptext($code(255,255,255)($nolist(
  427 +
  428 + A function for computing the length of a list:
  429 +
  430 +public define Int
  431 + length
  432 + (
  433 + List($$T) l
  434 + ) =
  435 + if l is
  436 + {
  437 + [ ] then 0,
  438 + [h . t] then 1 + length(t)
  439 + }.
  440 +
  441 + Blah blah blah ...
  442 +
  443 +)))
  444 +This example contains a $em(paragraph) defining a function, which is surrounded by so-called $em(off-paragraph
  445 +comments). In order to colorize this text we need to be able to detect the beginning and the end of Anubis paragraphs.
  446 +This is not possible if we use only color rules as defined by $mtt($$colorrule), but it becomes possible if we also use
  447 +$mtt($$colorizercall).$p
  448 +
  449 +Indeed, we first define two colorizers, say $mtt(off) for off-paragraph comments and $mtt(in) for paragraphs.$p
  450 +
  451 +In this example, we deliberately chosed to have a head of case of the form $ptext([h . t]) in the conditional,
  452 +because it also contains an $em(end dot) (a dot followed by a space or a linefeed) which must not be confused
  453 +with the end dot closing the paragraph.$p
  454 +
  455 +In order to colorize the paragraph itself, we need something like:
  456 +$p
  457 +$center($mtt($$colorizercall(ii)(off)(#npublic)(in)(#.[# #r#n])))
  458 +$par
  459 +However, if we do that, the colorization of the paragraph will end at the end dot which is within the square brackets.
  460 +In order to avoid this, we must add another call:
  461 +$p
  462 +$center($mtt($$colorizercall(ii)(in)(#$[)(in)(#$])))
  463 +$par
  464 +(the sharp character, i.e. the escape character for regular expressions,
  465 +in front of the square brackets is necessary since square brackets are special characters
  466 +in regular expressions).
  467 +That way, the colorizer $mtt(in) will call itself when it reads an opening square bracket and return (to itself) when it reads the
  468 +corresponding closing square bracket.$p
  469 +
  470 +However, with these two call rules, the colorization is still not correct because when the opening bracket of $mtt([h .
  471 +t]) is seen the colorizer $mtt(in) calls itself, and the second instance of $mtt(in) returns on the end dot so that the
  472 +first instance of $mtt(in) returns on the closing bracket, and the $mtt(off) colorizer is active again at this
  473 +closing bracket. The solution is to define two distinct $mtt(in) colorizers, as shown below.$par
  474 +
  475 +$mcode($$colorrule(off)(.)($$darkgreen($$1))
  476 +$$colorrule(in1)(.)($$darkred($$1))
  477 +$$colorrule(in2)(.)($$rgb(0,100,100)($$1))
  478 +$$colorrule(in1)(#npublic[# #r#n]+define)($$tbgc(220,220,0)($$rgb(0,0,100)($$bold($$1))))
  479 +$$colorrule(in1)(#.[# #r#n])($$tbgc(220,220,0)($$rgb(0,0,100)($$bold($$1))))
  480 +$$colorizercall(ii)(off)(#npublic[# #r#n]+define)(in1)(#.[# #r#n])
  481 +$$colorizercall(ii)(in1)(#$[)(in2)(#$])
  482 +$$colorizercall(ii)(in2)(#$[)(in2)(#$])
  483 +$$colorizer(in1)
  484 +$$colorizer(in2)
  485 +$$colorizer(off))
  486 +
  487 +
  488 +$colorrule(off)(.)($darkgreen($1))
  489 +$colorrule(in1)(.)($darkred($1))
  490 +$colorrule(in2)(.)($rgb(0,100,100)($1))
  491 +$colorrule(in1)(#npublic[# #r#n]+define)($tbgc(220,220,0)($rgb(0,0,100)($bold($1))))
  492 +$colorrule(in1)(#.[# #r#n])($tbgc(220,220,0)($rgb(0,0,100)($bold($1))))
  493 +$colorizercall(ii)(off)(#npublic[# #r#n]+define)(in1)(#.[# #r#n])
  494 +$colorizercall(ii)(in1)(#[)(in2)(#])
  495 +$colorizercall(ii)(in2)(#[)(in2)(#])
  496 +$colorizer(in1)
  497 +$colorizer(in2)
  498 +$colorizer(off)
  499 +(we put a different color for $mtt(in1) and $mtt(in2) texts for showing where $mtt(in1) calls $mtt(in2) and where $mtt(in2)
  500 +returns).
  501 +Now, if we write $mtt($$code($$_ivory)($$colorize(off)($argu(the above example text)))), we get:
  502 +
  503 +$code($_ivory)($colorize(off)($nolist(
  504 +
  505 + A function for computing the length of a list:
  506 +
  507 +public define Int
  508 + length
  509 + (
  510 + List($$T) l
  511 + ) =
  512 + if l is
  513 + {
  514 + [ ] then 0,
  515 + [h . t] then 1 + length(t)
  516 + }.
  517 +
  518 + Blah blah blah ...
  519 +
  520 +)))
  521 +and more generally, this works for any depth of square brackets nesting.$p
  522 +
  523 +
  524 +$subsection(noncolor)(A non colorizing example.)
  525 +As said above, colorizers are more general than just a tool for colorizing text. For example, they can be used,
  526 +to some extent, for $em(parsing) a text.$p
  527 +
  528 +Assume that we have a text which is in CSV (comma separated values) format. Such texts are very common since every
  529 +database system is able to export its tables in this format. Below is an example of such a datum.
  530 +$mcode($$define(mycsvtable)(0)
  531 +(Ford,Max,32,New York
  532 +Jackson,Niel,64,Los Angeles
  533 +Kennedy,Justin,25,New York
  534 +Obama,Barack,55,Washington
  535 +Smith,John,24,Baltimore
  536 +Trump,Donald,70,New York))
  537 +
  538 +$define(mycsvtable)(0)
  539 +(Ford,Max,32,New York
  540 +Jackson,Niel,64,Los Angeles
  541 +Kennedy,Justin,25,New York
  542 +Obama,Barack,55,Washington
  543 +Smith,John,24,Baltimore
  544 +Trump,Donald,70,New York)
  545 +
  546 +
  547 +In this piece of text, the lines of the table are separated by linefeeds and the values in a line are separated by
  548 +commas. For simplicity, we assume that the values contain no comma and no linefeed. In a realistic situation, we would
  549 +have to enhance our example for handling (for example) commas which are within a pair of parentheses. This kind of
  550 +enhancement would require some $mtt($$colorizercall).$p
  551 +
  552 +We define the following colorizer.
  553 +$mcode($$pushcounter(col)(0)
  554 +$$pushcounter(line)(0)
  555 +$$colorrule(display)(#,)($$addtocounter(col)(1))
  556 +$$colorrule(display)(#n)
  557 + ($$addtocounter(line)(1)$$par$$box(40)($$countervalue(line))$$setcounter(col)(0))
  558 +$$colorrule(display)($[^#n#$,$]*)($$if($$equals(2)($$countervalue(col)))
  559 + ($$box(40)($$red($$1)))
  560 + ($$if($$equals(0)($$countervalue(col)))
  561 + ($$box(100)($$bold($$1)))
  562 + ($$box(100)($$1))))
  563 +$$colorizer(display))
  564 +
  565 +$pushcounter(col)(0)
  566 +$pushcounter(line)(0)
  567 +$colorrule(display)(#,)($addtocounter(col)(1))
  568 +$colorrule(display)(#n)($addtocounter(line)(1)$par$box(40)($countervalue(line))$setcounter(col)(0))
  569 +$colorrule(display)([^#n#,]*)($if($equals(2)($countervalue(col)))
  570 + ($box(40)($red($1)))($if($equals(0)($countervalue(col)))($box(100)($bold($1)))($box(100)($1))))
  571 +$colorizer(display)
  572 +If we write
  573 +$mcode($$colorize(display)(
  574 +$$mycsvtable))
  575 +
  576 +we obtain:
  577 +$par
  578 +$colorize(display)(
  579 +$mycsvtable)
  580 +$p
  581 +Notice that thanks to the counter $mtt(col), we can perform a different treatment on each column.
  582 +Also remark that the first line of
  583 +the table has a number in front of it because we added a linefeed in front of $mtt($$mycsvtable) within the second operand of
  584 +$mtt($$colorize).
  585 +$p
  586 +Now, we want to get this same text in the form of a list of lines, where each line is itself a list of values.
  587 +To this end, we define another $em(colorizer).
  588 +$mcode($$accumulator(table)
  589 +$$accumulator(line)
  590 + $$// without the line below, the commas would appear on the page
  591 +$$colorrule(parsecsv)(#$,)()
  592 +$$colorrule(parsecsv)(#n)($$append(table)($$content(line))$$accumulator(line))
  593 +$$colorrule(parsecsv)($[^#n#$,$]+)($$append(line)($$1))
  594 +$$colorizer(parsecsv)
  595 +$$colorize(parsecsv)($$mycsvtable
  596 +))
  597 +
  598 +$accumulator(table)
  599 +$accumulator(line)
  600 +$colorrule(parsecsv)(#,)()
  601 +$colorrule(parsecsv)(#n)($append(table)($content(line))$accumulator(line))
  602 +$colorrule(parsecsv)([^#n#,]+)($append(line)($1))
  603 +$colorizer(parsecsv)
  604 +$colorize(parsecsv)($mycsvtable
  605 +)
  606 +
  607 +Despite the fact that we wrote $mtt($$colorize), this doesn't produce any output because
  608 +the regular expressions cover all cases and the values in the color
  609 +rules contain only marks which produce side effects but no output.$p
  610 +
  611 +So, we expect that the accumulator $mtt(table) contains our list of lists.
  612 +To check that, we define:
  613 +$mcode($$define(putbox)(1)($$tbgc($$_azure)($$box(75)($$1)) )
  614 +$$define(putpar)(1)($$apply(putbox)($$1)$$par))
  615 +
  616 +$define(putbox)(1)($tbgc($_azure)($box(75)($1)) )
  617 +$define(putpar)(1)($apply(putbox)($1)$par)
  618 +
  619 +and write $mtt($$apply(putpar)($$content(table))), which produces
  620 +$p
  621 +$apply(putpar)($content(table))
  622 +$par
  623 +and $mtt($$apply(putpar)($$transpose($$content(table)))), which produces
  624 +$p
  625 +$apply(putpar)($transpose($content(table)))
  626 +$par
  627 +This last manipulation makes even more obvious the fact that we actually got our table in the form of
  628 +a list of lists.
  629 +
  630 +
  631 +
  632 +$p
  633 +$section(tools)(Other tools)
  634 +$MAML is $em(not a programming language). It is a $em(document formatting language). Nevertheless, it provides some
  635 +programming capabilities, but only those which are (to our opinion) required for the needs of the layout of the
  636 +document. Of course, this set of tools could be enlarged in the future.$p
  637 +
  638 +$subsection(arithmetics)(Elementary arithmetics)
  639 +$MAML is able to perform some elementary arithmetic operations on numbers (which are all relative integers). These
  640 +operations are:
  641 +$list(
  642 + $item $box(200)($mtt($$add($argu(m))($argu(n)))) addition of $argu(m) and $argu(n)
  643 + $item $box(200)($mtt($$minus($argu(m))($argu(n)))) substraction of $argu(n) from $argu(m)
  644 + $item $box(200)($mtt($$opp($argu(m)))) opposite of $argu(m)
  645 + $item $box(200)($mtt($$mul($argu(m))($argu(n)))) multiplication of $argu(m) by $argu(n)
  646 + $item $box(200)($mtt($$quotient($argu(m))($argu(n)))) quotient of the euclidian division of $argu(m) by $argu(n)
  647 + $item $box(200)($mtt($$remainder($argu(m))($argu(n)))) remainder of the euclidian division of $argu(m) by $argu(n)
  648 +)
  649 +In case of a division by zero, an error message is generated.$p
  650 +
  651 +$//////////////////////////////////////////////////////////////////////////////////
  652 +$subsection(booleans)(Booleans and control)
  653 +$MAML provides some rudimentary tools for better controling the $MAML compiler. $MAML recognizes the marks $mtt($$true) and
  654 +$mtt($$false) as $em(truth values) (aka. $em(booleans)). Other marks also produce booleans, such as
  655 +$mtt($$equals($argu(expr 1))($argu(expr 2))) and $mtt($$defined($argu(macro name))).$p
  656 +
  657 +These truth values can be used as $argu(test) in:$p
  658 +$center($mtt($$if($argu(test))($argu(if true))($argu(if false))))$par
  659 +The value of the above mark is $argu(if true) if $argu(test) is true and $argu(if false) otherwise, and of course
  660 +only one of $argu(if true) and $argu(if false) is evaluated.$p
  661 +
  662 +Notice that some logical operators can be defined:
  663 +$mcode($$define(and) (2) ($$if($$1)($$2)($$false))
  664 +$$define(or) (2) ($$if($$1)($$true)($$2))
  665 +$$define(neg) (1) ($$if($$1)($$false)($$true))
  666 +$$define(implies) (2) ($$or($$neg($$1))($$2)))
  667 +
  668 +
  669 +$/////////////////////////////////////////////////////////////////////////////
  670 +$subsection(counters)(Counters)
  671 +$MAML has a notion of $em(counter). You can create a counter with $mtt($$pushcounter($argu(name))($argu(init))), where
  672 +$argu(name) is the name of the new counter, and $argu(init) its initial value (which must be a positive, zero or
  673 +negative integer).$p
  674 +
  675 +You can get the value of a counter with $mtt($$countervalue($argu(name))) (giving a character string representing
  676 +the value in decimal notation, possibly prefixed by a minus sign).
  677 +You can modify the value of a counter with $mtt($$setcounter($argu(name))($argu(value))) and
  678 +$mtt($$addtocounter($argu(name))($argu(value))).$p
  679 +
  680 +You can destroy a counter with $mtt($$popcounter($argu(name))).$p
  681 +
  682 +Actually, for each counter name, $MAML manages a stack of counters. Consequently, if you create a new counter with the
  683 +same name as an already existing counter, the first counter is not destroyed and
  684 +becomes visible again when the second counter is destroyed.$p
  685 +
  686 +As an exemple, consider the following:
  687 +
  688 +
  689 +$mcode($$pushcounter(n)(0)
  690 +$$define(ga)(0)($$addtocounter(n)(1)$$countervalue(n)))
  691 +$pushcounter(n)(0)
  692 +$define(ga)(0)($addtocounter(n)(1)$countervalue(n))
  693 +
  694 +If we write: $mtt($$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga), we get:$p
  695 +$center ($ga $ga $ga $ga $ga $ga $ga $ga $ga $ga $ga $ga $ga)
  696 +Continuing that way, we can write:
  697 +$mcode($$pushcounter(n)(25)
  698 +$$countervalue(n)
  699 +$$popcounter(n)
  700 +$$countervalue(n))
  701 +and we get:
  702 +$center(
  703 +$pushcounter(n)(25)
  704 +$countervalue(n)
  705 +$popcounter(n)
  706 +$countervalue(n))
  707 +(as expected).$p
  708 +
  709 +
  710 +$subsection(lists)(Lists)
  711 +$MAML has a notion of $em(list). In order to create a list (say with three elements $mtt(a), $mtt(b) and $mtt(c)),
  712 +you can write $mtt($[a$,b$,c$]). If you write this outside any $MAML operand, you get this:
  713 +$p
  714 +[a,b,c]
  715 +$p
  716 +In other words, the square brackets and the comma are just seen as ordinary (neutral) characters (and there is no list
  717 +at all in this case). On the contrary, if you write $mtt($$red($[a$,b$,c$])), you get this:
  718 +$p
  719 +$red([a,b,c])
  720 +$p
  721 +This is first of all because the square brackets and the comma are recognized as special characters within an operand
  722 +(so that we now have an actual list), and because the rendering of a list consists in rendering its element one after the
  723 +other without any separator between them. Nevertheless, if we want to render the above list in red with the brackets
  724 +and the commas, it is enough to write $mtt($$red($$$[a$$$,b$$$,c$$$])):
  725 +$p
  726 +$red($[a$,b$,c$])
  727 +$p
  728 +
  729 +The square brackets and the comma, everywhere they are recognized as special characters $em(eat) the spaces on both
  730 +sides. This means that it is equivalent to write $mtt($$red($[a$,b$,c$])) and to write $mtt($$red( $[ a$, b $, c
  731 +$] )). However, be careful because an expression such as $mtt($$red($[a$,b$,c$])) is $em(not) a list and triggers
  732 +an error if written at a place where a list is required.$p
  733 +
  734 +List are useful because they can be manipulated by several primitive marks, such as:
  735 +$list(
  736 + $item $mtt($ref(reverse)($$reverse)($argu(list)))
  737 + $item $mtt($ref(sort)($$sort)($argu(list)))
  738 + $item $mtt($ref(length)($$length)($argu(list)))
  739 + $item $mtt($ref(sublist)($$sublist)($argu(start))($argu(end))($argu(list)))
  740 + $item $mtt($ref(apply)($$apply)($argu(mark name))($argu(list)))
  741 + $item $mtt($ref(transpose)($$transpose)($argu(list of lists)))
  742 +)
  743 +How these primitives marks operate is explained in the $ref(catalog)(catalog).$p
  744 +
  745 +There are circumstances where we want the square brackets and the comma to be considered as ordinary (neutral)
  746 +characters. For example, it should be the case for the second operand of
  747 +$ref(code)($mtt($$code($argu(color))($argu(computer code)))), and also in some operands of some other primitives.
  748 +To simplify the matter and to offer the maximal number of possibilities, primitives such as $mtt($$code) don't care
  749 +about that. This is why we propose the primitive $ref(nolist)($mtt($$nolist($argu(text)))) which inhibits the
  750 +recognition of the squares brackets and the comma within $argu(text). Hence, $mtt($$code) should be used as follows:
  751 +$p
  752 +$center($mtt($$code($argu(color))($$nolist($argu(computer code)))))
  753 +$par
  754 +and you can define a macro for handling this.$p
  755 +
  756 +As an example, consider the following list of words:
  757 +$mcode($$define(cities)(0)
  758 + ($[New York$,Paris$,Berlin$,Moscow$,Casablanca$,Cairo$,Athens$,Rio de Janeiro$]))
  759 +$define(cities)(0)([New York,Paris,Berlin,Moscow,Casablanca,Cairo,Athens,Rio de Janeiro])
  760 +
  761 +We can write:
  762 +$mcode($$pushcounter(n)(0)
  763 +$$define(number)(1)($$addtocounter(n)(1)$$box(20)($$countervalue(n).)$$1$$par)
  764 +$$define(a)(1)($$alphabetic($$1))
  765 +$$center($$apply(number)($$sort($$apply(a)($$cities)))))
  766 +which gives this:
  767 +$pushcounter(n)(0)
  768 +$define(number)(1)($addtocounter(n)(1)$box(20)($countervalue(n).)$1$par)
  769 +$define(a)(1)($alphabetic($1))
  770 +$center($apply(number)($sort($apply(a)($cities))))
  771 +
  772 +$p
  773 +
  774 +$///////////////////////////////////////////////////////////////////////////////////////////
  775 +$section(tips)(Tips and tricks)
  776 +If your text needs to display some computer code, it can be the case (depending on the programming language)
  777 +that this code uses dollar characters. This is the case of Anubis for example, since dollars are used by
  778 +type parameters. These dollars can make a problem since the dollar is also the escape character of $MAML.$par$par
  779 +
  780 +You can of course double the dollars in the computer text examples, but there are situations where we don't want to
  781 +do this, or just cannot do this. This is the case for example in the Anubis library, since some files are at the
  782 +same time $MAML files (compilable by $MAML), and Anubis file (compilable by $mtt(anubis)). In this case, we cannot
  783 +change anything to the text, and in particular, we cannot double the dollars. $par$par
  784 +
  785 +A solution, assuming for example that there are two type parameters $mtt($$T) and $mtt($$U) in the Anubis text, is to
  786 +define two macros:
  787 +$mcode($$define(T)(0)($$$$T)
  788 +$$define(U)(0)($$$$U))
  789 +so that the $MAML compiler will not be disturbed by these type parameters, which is rendered correctly.
  790 +Since this doesn't change anything in the
  791 +Anubis text itself (the above $mtt($$define) should be outside any Anubis paragraph), this doesn't change anything from the point
  792 +of view of the Anubis compiler. This trick can of course be applied to other programming languages.$p
  793 +
  794 +
  795 +$subsection(commonerrors)(Common errors)
  796 +Below are most of the errors the author made himself during the writting of this tutorial.
  797 +$list(
  798 +
  799 + $item Thinking that $mtt($$tbgc($$_red)($$box(100)())) produces a red rectangle of the given width
  800 + (with no text at all into it).
  801 + This actually produces a white rectangle. In order
  802 + to get this red rectangle, you need to write $mtt($$tbgc($$_red)($$box(100)($$sp))) (recall that $mtt($$sp) is
  803 + the so-called $em(non breakable space)).$p
  804 +
  805 + $item Using $mtt($$blahblah) instead of $mtt($$$$blahblah), i.e. forgetting to double the dollar when we want to render a dollar
  806 + character (or the contrary).$p
  807 +
  808 + $item Writing $tt(#$$//.*) instead of $tt(#$$#/#/.*) as a regular expression in order to colorize $MAML line comments.
  809 + Of course, the first form $em(is seen) as the beginning of a line comment, and the final result is quite surprising.
  810 +)
  811 +
  812 +$/////////////////////////////////////////////////////////////////////////////////
  813 +$section(toolsbasis)(Tools available in $fname(basis.maml))
  814 +This $MAML file provides some tools of common usage. In order to use these tools, you must write
  815 +$center($mtt($$input(basis.maml)))$par
  816 +after the first $mtt($$begin), but some tools require that you define a macro before this $mtt($$input).$p
  817 +
  818 +Some of the macros defined in this file can be redefined easily from within your source text. If this is not enough for
  819 +your needs, you still have the possibility to use a customized copy of $fname(basis.maml).$p
  820 +
  821 +
  822 +$subsection(colors)(Colors)
  823 +The file $fname(basis.maml) provides a small selection of colors in the form of macros taking zero operand. These macros are to be used
  824 +within the first operand of $mtt($$rgb), $mtt($$code) and $mtt($$tbgc), i.e. at a place where a color value in the
  825 +form $mtt(r,g,b) is expected.$p
  826 +$pushcounter(colorcnt)(0)
  827 +$define(sc)(2)($box(20)()$box(100)($$_$1)$tbgc($2)($sp$sp$sp$sp$sp$sp$sp$sp$sp$sp)$box(20)()$//
  828 +$if($equals(2)($countervalue(colorcnt)))($setcounter(colorcnt)(0)$par)($addtocounter(colorcnt)(1)))
  829 +
  830 +$sc(azure)($_azure)
  831 +$sc(black)($_black)
  832 +$sc(blue)($_blue)
  833 +$sc(caramel)($_caramel)
  834 +$sc(chocolate)($_chocolate)
  835 +$sc(cyan)($_cyan)
  836 +$sc(darkgreen)($_darkgreen)
  837 +$sc(gold)($_gold)
  838 +$sc(green)($_green)
  839 +$sc(grey)($_grey)
  840 +$sc(ivory)($_ivory)
  841 +$sc(lavender)($_lavender)
  842 +$sc(magenta)($_magenta)
  843 +$sc(navy)($_navy)
  844 +$sc(orange)($_orange)
  845 +$sc(pink)($_pink)
  846 +$sc(purple)($_purple)
  847 +$sc(red)($_red)
  848 +$sc(darkred)($_darkred)
  849 +$sc(salmon)($_salmon)
  850 +$sc(sienna)($_sienna)
  851 +$sc(turquoise)($_turquoise)
  852 +$sc(white)($_white)
  853 +$sc(yellow)($_yellow)
  854 +
  855 +$undefine(sc)
  856 +$p
  857 +The file also provide macros with the same name, but without the leading underscore,
  858 +taking one operand for directly colorizing texts. For example $mtt($$red(...)) is
  859 +equivalent to $mtt($$rgb($$_red)(...)).$p
  860 +
  861 +$subsection(stylearticle)(The style $mtt(article))
  862 +This $em(style) provides definitions for the marks $mtt($$section), $mtt($$subsection) and $mtt($$subsubsection) (which
  863 +are not primitive marks), and also defines a mark $mtt($$tableofcontents).$p
  864 +
  865 +$subsubsection(_)(How to use it)
  866 +In order to use this style, you must write:$p
  867 +$center($mtt($$define(article)(0)()))$par
  868 +$em(before) $mtt($$input(basis.maml)), because the style is conditionned by a $mtt($$if($$defined(article))...)
  869 +within $fname(basis.maml).$p
  870 +
  871 +The marks $mtt($$section), $mtt($$subsection) and $mtt($$subsubsection) take two operands. The first one must be a
  872 +symbol
  873 +which is the symbolic name you want to give to the section (it is used
  874 +for generating internal links, but you can also refer to the section with a $ref(ref)($mtt($$ref(...)(...)))).
  875 +The second one is the title of the section.$p
  876 +
  877 +The mark
  878 +$mtt($$tableofcontents) produces a table of contents and can be written anywhere because it contains a
  879 +$ref(postpone)($mtt($$postpone)),
  880 +so that it provides a complete table of contents regardless of its position in your source text.$p
  881 +
  882 +$subsubsection(_)(Customizing $mtt(article))
  883 +The lines of the table of contents are displayed by the marks $mtt($$tocsec),
  884 +$mtt($$tocsubsec) and $mtt($$tocsubsubsec). If you are not satisfied with the layout provided by these marks, you can
  885 +define your own versions, provided that you write your definitions $em(before) $mtt($$input(basis.maml)). These marks take only one
  886 +operand which is the line to be displayed. For example, you can define:$par
  887 +$mcenter($mtt($$define(tocsec)(1)($$par$$bold($$1)$$par)))
  888 +This will replace the default definition provided by $fname(basis.maml). This may be useful for example to redefine
  889 +$mtt($$tocsubsubsec) if you have
  890 +subsubsections in your text and don't want them to appear in the table of contents.$p
  891 +
  892 +The same is true for the marks $mtt($$seclayout), $mtt($$subseclayout) and $mtt($$subsubseclayout), which define the
  893 +layout of the section titles themselves. These marks take one operand which is the title itself.$p
  894 +
  895 +$subsection(book)(The style $mtt(book))
  896 +This style is the same as article, except that it also has a notion of chapter. Hence, it also defines the mark
  897 +$mtt($$chapter($argu(symbolic name))($argu(title))), and you can redefine the marks
  898 +$mtt($$tocchap($argu(title))) and $mtt($$chaplayout($argu(title))).$p
  899 +
  900 +
  901 +
  902 +$////////////////////////////////////////////////////////////////////////////:
  903 +$section(catalog)(The catalog of $MAML marks)
  904 +Below is a description of the $postpone($countervalue(markcount)) primitive $MAML marks.$p
  905 +$postpone($content(tabmark))
  906 +
  907 +
  908 + $mark1(accumulator)(name)
  909 + This mark creates a $em(variable) named $argu(name) called an $em(accumulator).
  910 + The content of an accumulator is always a list, and this list is empty when the accumulator is created. With the mark
  911 + $mtt($$append), you can add content to the accumulator. Each use of $mtt($$append) adds an element to end of the list
  912 + contained in the accumulator. At any time, you can get the content of the accumulator with $mtt($$content).$p
  913 +
  914 + An accumulator cannot be destroyed, but it can be reinitialized. Indeed, $mtt($$accumulator($argu(name))) empties the
  915 + accumulator if it already exists, and puts the empty list in it. Unlike counters and macros, there is no stack associated to an
  916 + accumulator name. For example:
  917 + $mcode($$accumulator(acc)
  918 +$$append(acc)(A)
  919 +$$append(acc)(B)
  920 +$$content(acc)
  921 +$$par
  922 +$$accumulator(acc)
  923 +$$append(acc)(C)
  924 +$$content(acc))
  925 + produces:
  926 + $p
  927 + $accumulator(acc)
  928 + $append(acc)(A)
  929 + $append(acc)(B)
  930 + $content(acc)
  931 + $par
  932 + $accumulator(acc)
  933 + $append(acc)(C)
  934 + $content(acc)
  935 + $p
  936 + Accumulators can be used in conjunction with $ref(postpone)($mtt($$postpone)) for constructing
  937 + tables of content and indexes.
  938 + See also $ref(append)($mtt($$append)) and $ref(content)($mtt($$content)).
  939 +
  940 + $mark2(addtocounter)(name)(value)
  941 + This marks adds $argu(value) to the most recent instance of the counter whose name is $argu(name).
  942 +
  943 + $mark2(append)(name)(text)
  944 + This mark appends $argu(text) at the end of the content of the $ref(accumulator)(accumulator) $argu(name). More
  945 + precisely, since the content of an accumulator is a list, the new content of the accumulator is the list obtained
  946 + by adding $argu(text) as the last element of this list.
  947 + See also $ref(accumulator)($mtt($$accumulator)) and $ref(content)($mtt($$content)).
  948 +
  949 + $mark2(apply)(name)(list)
  950 + This mark applies the macro whose name is $argu(name) to all elements of the list $argu(list). This creates a new list
  951 + of the same length. If $argu(list) is not a list, the result is the same as if it was a one element list.$p
  952 +
  953 + Notice that the first operand is the name of the macro to applied, but $em(without the leading $mtt($$)). In other words, this
  954 + operand is not the macro to apply but only its name. The corresponding macro must take just one operand. If not, an
  955 + error message is generated.$p
  956 +
  957 + Furthermore, the macro to be applied must take a unique operand, and notice that $argu(name) cannot be the name of
  958 + a primitive mark. It $em(must) be the name of a macro. Hence, if you want to apply a primitive mark, you must first
  959 + define an equivalent macro.$p
  960 +
  961 + As an example, consider the following:
  962 + $mcode($$define(mylist)(0)($[a$,b$,c$,d$])
  963 +$$mylist$$par
  964 +$$define(a)(1)(<$$red($$1)>)
  965 +$$apply(a)($$mylist))
  966 +which produces:$p
  967 +
  968 +$define(mylist)(0)([a,b,c,d])
  969 +$mylist$par
  970 +$define(a)(1)(<$red($1)>)
  971 +$apply(a)($mylist)
  972 +$p
  973 + See also $ref(box)($mtt($$box)) for a more sophisticated example.
  974 +
  975 +
  976 + $mark0(begin) This mark is looked for by $MAML before it parses anything (even within a file refered to by
  977 + $mtt($$input)). When $mtt($$begin) is found, $MAML parses the text until it
  978 + encounters the mark $mtt($$end). After this mark, $MAML continues ignoring everything until the next $mtt($$begin),
  979 + etc... $par$par
  980 +
  981 + Notice that this mecanism can also be used for inserting a comment:
  982 + $mcode($$end
  983 + ... your comment ...
  984 +$$begin)
  985 +
  986 + $mark1(big)(text) Prints its operand $argu(text) bigger. This mark can be nested. For example,
  987 + $list(
  988 + $item $box(200)($mtt($$big(text))) produces $big(text)
  989 + $item $box(200)($mtt($$big($$big(text)))) produces $big($big(text))
  990 + $item $box(200)($mtt($$big($$big($$big(text))))) produces $big($big($big(text)))
  991 + )
  992 +
  993 +
  994 + $mark1(bold)(text) The operand is rendered in $bold(bold).
  995 +
  996 + $mark2(box)(width)(text) This mark puts $argu(text) into an invisible box of width $argu(width). The text is left aligned
  997 + within the box. This mark can be used for simulating tabulators. For example,
  998 + $mcode($$define(tableline)(4)($$box(50)($$1) $$box(50)($$2) $$box(30)($$red($$3)) $$4 $$par)
  999 +
  1000 +$$tableline(Smith)(John)(24)(Baltimore)
  1001 +$$tableline(Ford) (Max) (32)(New York))
  1002 + produces:$par$par
  1003 + $define(tableline)(4)($box(50)($1) $box(50)($2) $box(30)($red($3)) $4 $par)
  1004 + $tableline(Smith)(John)(24)(Baltimore)
  1005 + $tableline(Ford) (Max) (32)(New York)
  1006 + $par
  1007 +
  1008 + $label(colortableexample)
  1009 + As an example, here is something more sophisticated. We construct a table similar to the table above,
  1010 + but we want it to be automatically sorted by the last names (first column) and to be in pajama stripes,
  1011 + in other words, so that odd numbered lines
  1012 + are shown on a different background color than even numbered lines. It is clear that the background color
  1013 + cannot be decided before the list is sorted, so that, after the list is sorted, we have to apply a macro
  1014 + to each element of the list. This is why we need to use the primitive mark $ref(apply)($mtt($$apply)).
  1015 + $mcode( $$// we first create a counter that we use as a flag
  1016 + $$// (taking the values 0 and 1 only)
  1017 +$$pushcounter(flag)(0)
  1018 + $$// we define a color depending on the value of the flag
  1019 + $$// and flipflopping the flag at each use
  1020 +$$define(linecolor)(0)
  1021 + ($$if($$equals(0)($$countervalue(flag)))
  1022 + ($$setcounter(flag)(1)$$_lavender)
  1023 + ($$setcounter(flag)(0)$$_ivory))
  1024 + $$// define the layout of a line of the table, and put an '$$alphabetic' in order
  1025 + $$// to tell MAML how to sort lines
  1026 +$$define(tableline)(4)
  1027 + ($$box(80)($$alphabetic($$1))$$box(80)($$2)$$box(50)($$red($$3))$$box(80)($$4)$$par)
  1028 + $$// define a macro for putting a backgroud color behind a line
  1029 +$$define(putbg)(1)($$tbgc($$linecolor)($$1))
  1030 + $$// sort the lines and apply this macro to each line
  1031 +$$center($$apply(putbg)($$sort(
  1032 +$[$$tableline(Smith)(John)(24)(Baltimore)$,
  1033 + $$tableline(Ford) (Max) (32)(New York)$,
  1034 + $$tableline(Jackson)(Niel)(64)(Los Angeles)$,
  1035 + $$tableline(Kennedy) (Justin) (25)(New York)$,
  1036 + $$tableline(Trump)(Donald)(70)(New York)$,
  1037 + $$tableline(Obama) (Barack)(55)(Washington)$]
  1038 +))))
  1039 +
  1040 +
  1041 +$pushcounter(flag)(0)
  1042 +$define(linecolor)(0)($if($equals(0)($countervalue(flag)))($setcounter(flag)(1)$_lavender)($setcounter(flag)(0)$_ivory))
  1043 +$define(tableline)(4)($box(80)($alphabetic($1))$box(80)($2)$box(50)($red($3))$box(80)($4)$par)
  1044 +$define(putbg)(1)($tbgc($linecolor)($1))
  1045 +$center($apply(putbg)($sort(
  1046 +[$tableline(Smith)(John)(24)(Baltimore),
  1047 + $tableline(Ford) (Max) (32)(New York),
  1048 + $tableline(Jackson)(Niel)(64)(Los Angeles),
  1049 + $tableline(Kennedy) (Justin) (25)(New York),
  1050 + $tableline(Trump)(Donald)(70)(New York),
  1051 + $tableline(Obama) (Barack)(55)(Washington)])))
  1052 +$p
  1053 +The macro $mtt($$pajamatable) defined in $fname(basis.maml) realises such a table and accepts the data in the form of a
  1054 +list of lists.
  1055 +
  1056 + $mark1(center)(text) This mark horizontally centers the $argu(text) in the page. For example,
  1057 + $mtt($$center(centered text)) produces:$par
  1058 + $mcenter(centered text)
  1059 +
  1060 + $mark2(code)(background color)(text) This marks is for writing computer code.
  1061 + The $argu(text) operand is formated using a fixed width
  1062 + (typewriter) font, spaces and newlines are taken into account, so that the result has essentially the same layout as the
  1063 + original. Nevertheless, $MAML marks are allowed within $argu(text), but some of them, such as $mtt($$list),
  1064 + can produce incoherent results. For example,
  1065 + $par
  1066 + $mcode($$define(T)(0)($$$$T) $$// so that MAML is not troubled by $$T
  1067 +$$code($$_lavender)($$nolist($black(
  1068 +define Int
  1069 + length
  1070 + (
  1071 + List($$T) l
  1072 + ) =
  1073 + if l is
  1074 + {
  1075 + [ ] then 0, // the list is empty
  1076 + [h . t] then 1+length(t)
  1077 + }.)
  1078 +$$undefine(T))))
  1079 + produces:
  1080 + $define(T)(0)($$T)
  1081 + $code($_lavender)($nolist(define Int
  1082 + length
  1083 + (
  1084 + List($T) l
  1085 + ) =
  1086 + if l is
  1087 + {
  1088 + [ ] then 0, // the list is empty
  1089 + [h . t] then 1+length(t)
  1090 + }.))
  1091 + $undefine(T)
  1092 + (You can also use a $ref(colorize)(colorizer) for colorizing the code.)
  1093 + $par$par
  1094 + See also $ref(tt)($mtt($$tt(...))) and $ref(verbatim)($mtt($$verbatim(...)))
  1095 +
  1096 + $mark2(colorize)(name)(text) See $ref(colorize)(Automatic colorization).
  1097 + $mark1(colorizer)(name) See $ref(colorize)(Automatic colorization).
  1098 + $mark4(colorizercall)(name)(regexpr)(name)(regexpr) See $ref(colorize)(Automatic colorization).
  1099 + $mark3(colorrule)(name)(regexpr)(text) See $ref(colorize)(Automatic colorization).
  1100 +
  1101 + $mark1(content)(name)
  1102 + The value of this mark is the content of the $ref(accumulator)(accumulator) $argu(name). Recall that this content
  1103 + is a list. See also $ref(accumulator)($mtt($$accumulator)) and $ref(append)($mtt($$append)).
  1104 +
  1105 + $mark1(countervalue)(name)
  1106 + This mark produces the value of the counter $argu(name) in decimal notation. See $ref(counters)(Counters).
  1107 +
  1108 + $mark3(define)(name)(number of operands)(value)
  1109 + This mark let you define new marks (i.e. $em(macros)). It takes three operands. The first operand $argu(name)
  1110 + is the name of the new mark. If it is
  1111 + already in use, the new definition masks the previous one until you use an $ref(undefine)($mtt($$undefine($argu(name)))).
  1112 + The name must be made only of letters $mtt(A...Z) and $mtt(a...z), decimal digits $mtt(0...9) and
  1113 + the underscore character, and must
  1114 + not begin by a digit. The second operand $argu(number of operands) is the number of operands your new mark will accept.
  1115 + It must
  1116 + be a positive or zero integer. The last operand $argu(value) is the value of the mark. This is a $MAML text, and it can
  1117 + contain marks of the form $mtt($$1), $mtt($$2), $mtt($$3), ... (called $MAML $em(variables)) which represent the operands
  1118 + of the mark, and which will later be replaced by the actual operands when the mark is used in the text.$p
  1119 +
  1120 + $mtt($$define) doesn't allow to define recursive macros. Nevertheless,
  1121 + see $ref(undefine)($mtt($$undefine)) where more explanations are given on the behavior of $mtt($$define).
  1122 +
  1123 +
  1124 + $mark1(defined)(name)
  1125 + This mark has a boolean value which is $em(true) if a macro is defined with name $argu(name) and $em(false)
  1126 + otherwise.
  1127 +
  1128 + $mark0(end) This mark indicates that the $MAML compiler should stop parsing until the next $mtt($$begin) (or the end
  1129 + of file). See $ref(begin)($mtt($$begin)).
  1130 +
  1131 + $mark2(equals)(expr 1)(expr 2)
  1132 + This mark has a boolean value which is $em(true) if $argu(expr 1) and $argu(expr 2) are equal. By $em(equal), we
  1133 + mean identical after $argu(expr 1) and $argu(expr 2) are computed.
  1134 +
  1135 + $mark0(false) This mark represents the truth value $em(false).
  1136 +
  1137 + $mark3(if)(test)(if true)(if false)
  1138 + This mark represents $argu(if true) if $argu(test) is true, and $argu(if false) otherwise. Only one of
  1139 + $argu(if true) and $argu(if false) is evaluated.
  1140 +
  1141 + $mark1(ifhtml)(text) The operand $argu(text) is present in the HTML output, but not in the $LaTeX nor in the PDF
  1142 + output.
  1143 +
  1144 + $mark1(ifpdf)(text) The operand $argu(text) is present in the $LaTeX and in the PDF
  1145 + output, but not in the HTML output.
  1146 +
  1147 + $mark2(image)(width)(file path)
  1148 + This mark inserts an image in the text. The operand $argu(width) is the width the image will have
  1149 + when displayed (in pixels in the case of HTML, and points in the case of $LaTeX), and $argu(file path) is the path of the file
  1150 + containing the image. For example,
  1151 + $mcode($$center($$image($$ifpdf(100)$$ifhtml(200))($$id($$thisfilepath)/cows.jpg)))
  1152 + produces:
  1153 + $mcenter($image($ifpdf(100)$ifhtml(200))($id($thisfilepath)/cows.jpg))
  1154 +
  1155 + Remark the presence of $mtt($$id($$thisfilepath)/) before the name of the file (which is here assumed to be
  1156 + in the same directory as the maml file containing the above expression). The mark $mtt($$thisfilepath) gives
  1157 + the absolute path of the file it is written into. Also, because we need to glue this path to the name of the image
  1158 + file, we use the macro $mtt($$id) defined by $mtt($$define(id)(1)($$1)). $p
  1159 +
  1160 + At the same time, you remark that the width of the image doesn't need to be given lexically and
  1161 + can be computed using $MAML marks.
  1162 +
  1163 +
  1164 + $mark1(input)(file name)
  1165 + This mark let you insert the content of another $MAML file. This other file could for example contain your own $MAML
  1166 + macros.$par$par
  1167 + Notice that the input file also needs to have a $mtt($$begin) and an $mtt($$end).
  1168 + In other words, when told to read another file by
  1169 + $mtt($$input) the $MAML compiler ignores everything in this other file until it finds a $mtt($$begin).
  1170 + $par$par
  1171 + This mark can be $unsafe on the web, except if you filter the operand. See the Anubis library documentation.
  1172 +
  1173 +
  1174 + $mark1(italic)(text) Prints its operand $argu(text) in $italic(italic).
  1175 +
  1176 + $mark0(item) Marks the begining of an $em(item) within a $ref(list)($mtt($$list))
  1177 +
  1178 + $mark1(label)(tag) This mark defines a $em(label) in the text, in other words, a position where to jump.
  1179 + This is to be used in conjunction with $ref(ref)($mtt($$ref)).
  1180 +
  1181 + $mark1(latex)(formula) This mark allows to include math formulas to be formated by $LaTeX.
  1182 + For example,
  1183 + $mcenter($mcode($$latex($dollar$$\int_0^\infty\frac{dx}{1+x^2}$dollar$dollar)))
  1184 + is rendered as:
  1185 + $latex($$\int_0^\infty\frac{dx}{1+x^2}$$)
  1186 + This mark should not be used for big pieces of $LaTeX
  1187 + text. It is mainly intended for math formulas, especially for HTML output where the formula is rendered
  1188 + as a PNG image with transparent background.
  1189 + $par$par
  1190 + You can use $mtt($$latex) in the text. The result is correctly aligned with the text. For example,$par
  1191 + $mcenter($mcode(the polynomial $$latex($$X^2+X+1$dollar) is of degree 2))
  1192 + is rendered as:
  1193 + $mcenter(the polynomial $latex($X^2+X+1$) is of degree 2)
  1194 +
  1195 + Unfortunatly, $latex(\TeX) is $unsafe as explained in $tlink(this document)(http://cseweb.ucsd.edu/~hovav/dist/texhack.pdf).
  1196 + Hence, you should forbid this mark for a web usage, except if you add a filter in order to reject all $LaTeX
  1197 + commands which don't belong to a given list of safe commands. This list doesn't need to be very long since the
  1198 + $mtt($$latex) mark is mainly used for inserting math formulas. See the Anubis library documentation to learn how
  1199 + to install this list of safe $LaTeX commands.
  1200 +
  1201 + $mark1(length)(list)
  1202 + This mark returns the number of elements in its operand which is supposed to be a list. If the operand is not a list,
  1203 + the result is $mtt(1) if the operand is not empty (i.e. if it contains at least one character), and $mtt(0) if it is
  1204 + empty.
  1205 +
  1206 + $mark1(list)(items) This mark allows to create a list. The operand $argu(items) must be a sequence of $em(items),
  1207 + i.e. texts which are all prefixed by the mark $ref(item)($mtt($$item)).$par$par
  1208 + Example:
  1209 + $mcode($$list(
  1210 + $$item Boys: $$list( $$item John $$item Max)
  1211 + $$item Girls: $$list($$item Julie $$item Geraldine $$item Sophia)))
  1212 + produces:
  1213 + $list(
  1214 + $item Boys: $list( $item John $item Max)
  1215 + $item Girls: $list($item Julie $item Geraldine $item Sophia))
  1216 +
  1217 + $mark0(lpar) This mark inserts a left (opening) parenthese into the text. You must use $mtt($$lpar) and/or
  1218 + $mtt($$rpar) if you want to introduce unbalanced parentheses within an operand of a mark.
  1219 +
  1220 + $mark2(mailto)(address)(text) This marks, which appears as $argu(text),
  1221 + creates a link which is supposed, in the HTML case, to open your mail agent in order to let you
  1222 + send an email to the indicated $argu(address). In the PDF case, the $argu(address) is just indicated between parentheses
  1223 + beside $argu(text).
  1224 + For example,$par
  1225 + $mcenter($mtt($$blue($$mailto(XZ32@planet.mars)(the martian)))) produces:
  1226 + $blue($mailto(XZ32@planet.mars)(the martian))$ifhtml( (you can try it)).
  1227 +
  1228 + $mark1(nolist)(text)
  1229 + This mark inhibits the recognition of the square brackets and the comma as list delimitors within $argu(text). See
  1230 + $ref(lists)(Lists).
  1231 +
  1232 + $mark1(note)(text) This mark produces a footnote containing $argu(text).
  1233 + In the case of $LaTeX/PDF this is a usual
  1234 + footnote.$ifpdf($note(Like this one.)) In the case of HTML, this is a popup which appears at the bottom of the browser's window when the mouse
  1235 + passes over this indication : $ifhtml($note(Here is the note !))$ifpdf(($sup(note))).$ifhtml( Try it !)
  1236 +
  1237 + $mark2(nth)(n)(list)
  1238 + This mark extracts the $argu(n)$sup(th) element of the list $argu(list). It generates an error if this element doesn't
  1239 + exist. Numbering begins at zero.
  1240 +
  1241 + $mark2(output)(file path)(text) This mark does not produce anything in the resulting HTML or PDF files, but outputs
  1242 + $argu(text) (without any modification) into the file $argu(file path).
  1243 + $par
  1244 + $par
  1245 + $mtt($$output) can be very $unsafe for the web. In any case it is not very useful on the web because web pages offer
  1246 + other ways of uploading files. So, the best is just to forbid it.
  1247 +
  1248 + $mark0(par) This marks generates a line break. You can use several $mtt($$par) in order to make some
  1249 + vertical space in your text.
  1250 + $par$par
  1251 + $em(Warning:) The MAML parser doesn't take newline characters into account (they are just read as spaces). Hence,
  1252 + using $mtt($$par) is often necessary. You can also define a macro inserting several such newlines. For example:
  1253 + $mcode($$define(p)(0)($$par$$par))
  1254 +
  1255 + $mark1(popcounter)(name)
  1256 + This mark destroys the most recent counter whose name is $argu(name).
  1257 +
  1258 + $mark1(postpone)(text)
  1259 + The $MAML text $argu(text) is evaluated only after the entire $MAML source is parsed and evaluated (including the
  1260 + sources obtained via $mtt($$input)).
  1261 + On the contrary, everything not within a $mtt($$postpone) is
  1262 + evaluated at the moment it is parsed. The mark $mtt($$postpone) is typically used in conjunction with $mtt($$accumulator),
  1263 + $mtt($$append) and $mtt($$content) for creating a table of contents at the beginning of a document. This is how
  1264 + the table of contents at the beginning of this tutorial was made.$p
  1265 +
  1266 + As another easy example, the sentence $em(Below is a description of the $postpone($countervalue(markcount))
  1267 + primitive $MAML marks.) that you can find just after the section title $ref(catalog)(The catalog of $MAML marks) contains a
  1268 + $mtt($$postpone($$countervalue(markcount))) producing the number $postpone($countervalue(markcount)) (where
  1269 + $mtt(markcount) is the name of the counter used for numbering the marks in this catalog).
  1270 +
  1271 + $mark2(pushcounter)(name)(init)
  1272 + This mark creates a new counter under the name $argu(name), with $argu(init) as its initial value. See
  1273 + $ref(counters)(Counters).
  1274 +
  1275 + $mark2(ref)(tag)(text)
  1276 + This mark creates an internal hyperlink. When clicked upon, this moves the text
  1277 + to the position of the $ref(label)($mtt($$label)) (this is a $mtt($$ref) !) with the same tag name.
  1278 +
  1279 + $mark1(reverse)(list)
  1280 + This mark return its operand (assumed to be a list), but in reverse order. If the operand is not a list, an error
  1281 + message is generated.
  1282 +
  1283 + $mark2(rgb)(color)(text) This mark sets the color of characters in $argu(text) to $argu(color), where
  1284 + $argu(color) has the form of three integers separated by commas, representing the intensities of red, green and blue.
  1285 + These numbers must be between 0 and 255. For example,$par
  1286 + $mcenter($mtt($$rgb(255,0,0)(the text)))
  1287 + produces:
  1288 + $mcenter($rgb(255,0,0)(the text))
  1289 + See also $ref(colors)(the predefined colors).
  1290 +
  1291 + $mark0(rpar) This mark inserts a right (closing) parenthese into the text. You must use $mtt($$lpar) and/or
  1292 + $mtt($$rpar) if you want to introduce unbalanced parentheses within an operand of a mark.
  1293 +
  1294 + $mark2(setcounter)(name)(value)
  1295 + This mark puts the value $argu(value) in the most recent counter whose name is $argu(name). See $ref(counters)(Counters).
  1296 +
  1297 + $mark1(sort)(list)
  1298 + This marks performs a quick sorting of its operand which is supposed to be a list. If the operand is not a list, it is
  1299 + returned as is.$p
  1300 +
  1301 + The sorting is always alphabetic, but it can be relative to any part of the elements in the list. In order to
  1302 + designate which part of an element of the list must be used for comparison, put the special mark
  1303 + $mtt($$alphabetic($argu(part))) around this part.$p
  1304 +
  1305 + At the rendering stage $mtt($$alphabetic($argu(part))) is just replaced by $mtt($argu(part)). See $ref(box)($mtt($$box))
  1306 + for an example.
  1307 +
  1308 + $mark0(sp) This mark (space) produces an unbreakable space (translated into $tt(&nbsp;) in HTML and $tt(~) in $latex(\LaTeX)).
  1309 +
  1310 + $mark1(sub)(text) This mark lowers $argu(text) and renders it in a smaller size. For example, $mtt(x$$sub(1))
  1311 + produces x$sub(1).
  1312 +
  1313 + $mark3(sublist)(start)(end)(list)
  1314 + The third operand of this mark is supposed to be a list. If it's not a list, an error message is generated.$p
  1315 +
  1316 + If it is a list, the result is the sublist beginning at element number $argu(start) (included) and finishing at
  1317 + element number $argu(end) (not included). Notice that numbering begins at $mtt(0), not $mtt(1).
  1318 + If the value of $argu(start) or $argu(end) is out of bounds, this value is
  1319 + replaced by the actual bound which is $mtt(0) for $argu(start) and the length of the list for $argu(end). For example,
  1320 +
  1321 + $mcode($$sublist(-3)(4)($nolist([a,b,c,d,e,f,g,h,i,j,k]))$$par
  1322 +$$sublist(0)(4)($nolist([a,b,c,d,e,f,g,h,i,j,k]))$$par
  1323 +$$sublist(1)(4)($nolist([a,b,c,d,e,f,g,h,i,j,k])))
  1324 + produces:$p
  1325 + $sublist(-3)(4)([a,b,c,d,e,f,g,h,i,j,k])$par
  1326 + $sublist(0)(4)([a,b,c,d,e,f,g,h,i,j,k])$par
  1327 + $sublist(1)(4)([a,b,c,d,e,f,g,h,i,j,k])
  1328 +
  1329 +
  1330 +
  1331 + $mark1(sup)(text) This mark raises $argu(text) and renders it in a smaller size. For example, $mtt(x$$sup(1))
  1332 + produces x$sup(1).
  1333 +
  1334 + $mark2(tbgc)(color)(text) This mark ($em(text background color)) shows $argu(text) over a background of color
  1335 + $argu(color). For example, $mtt($$tbgc($$_lavender)(Some text.))
  1336 + produces: $tbgc($_lavender)(Some text.)
  1337 + $par$par
  1338 + This is valuable for short texts. For long texts, $ref(code)($mtt($$code(...))) may be more
  1339 + appropriate.
  1340 +
  1341 + $mark0(thisfilepath)
  1342 + This marks provides the absolute path of the file it is written into.$p
  1343 +
  1344 + $mtt($$thisfilepath) is $unsafe for the web, because it can reveal an absolute path of your web server. You should forbid
  1345 + it.
  1346 +
  1347 + $mark2(tlink)(text)(url) This mark creates an hypertext link targeting the $argu(url), and shown as the clickable
  1348 + $argu(text) (which can also be an image). For example,
  1349 + $mcode($$tlink(Visit
  1350 + $$big($$blue(G)$$red(o)$$yellow(o)$$blue(g)$$green(l)$$red(e)))
  1351 + (http://www.google.com))
  1352 + produces
  1353 + $tlink(Visit
  1354 + $big($blue(G)$red(o)$yellow(o)$blue(g)$green(l)$red(e)))(http://www.google.com)$ifhtml( (that
  1355 + you can click upon)).
  1356 +
  1357 +
  1358 +
  1359 + $mark1(transpose)(list of lists)
  1360 + This mark $em(transposes) (somehow as in mathematics) a list of lists considered as a $em(matrix). As an example,
  1361 + we define:
  1362 +$mcode($$define(mylist)(0)($[$[a$,b$]$,$[c$,d$,e$]$,$[f$,g$]$])
  1363 +$$define(addbox)(1)($$box(16)($$1))
  1364 +$$define(separ)(1)($$apply(addbox)($$1)$$par))
  1365 +
  1366 +$define(mylist)(0)([[a,b],[c,d,e],[f,g]])
  1367 +$define(addbox)(1)($box(16)($1))
  1368 +$define(separ)(1)($apply(addbox)($1)$par)
  1369 +
  1370 +Now, if we write $mtt($$apply(separ)($$mylist)), we obtain:
  1371 +$p
  1372 +$apply(separ)($mylist)
  1373 +$par
  1374 +and if we write $mtt($$apply(separ)($$transpose($$mylist))), we obtain:
  1375 +$p
  1376 +$apply(separ)($transpose($mylist))
  1377 +$par
  1378 +
  1379 +
  1380 + Notice that if a line of the matrix is shorter than a subsequent line, $mtt($$transpose) automatically inserts $em(empty)
  1381 + (invisible) elements in the
  1382 + transposed matrix so that items which are in the same $em(line) in the original matrix are in the same $em(column) in the
  1383 + transposed matrix.$p
  1384 +
  1385 + This is useful (in conjunction with $ref(sublist)($mtt($$sublist))) and some $ref(arithmetics)(arithmetics)
  1386 + for example for displaying a list of items on several columns, with the first group of elements in the first
  1387 + column (not the first line), the next group of elements in the second column, and so on. This can be used for example
  1388 + for automatically producing an index on several columns. This is also used in this tutorial for displaying the list
  1389 + of all marks on four columns $ref(catalog)(at the beginning of this section).$p
  1390 +
  1391 + Below is a simple example. We want to sort a list of words in alphabetic order and to present them on two columns.
  1392 + $mcode( $$// define a list of words
  1393 +$$define(words)(0)
  1394 + ($[We$,want$,to$,sort$,a$,list$,of$,words$,and$,
  1395 + to$,present$,them$,in$,alphabetic$,order$,on$,two$,columns$]))
  1396 +
  1397 +$define(words)(0)
  1398 + ([We,want,to,sort,a,list,of,words,and,to,present,them,in,alphabetic,order,on,two,columns])
  1399 +
  1400 + We prepare the sorting of the list by applying a $mtt($$box(120)) and a $mtt($$alphabetic) to all elements.
  1401 + $mcode($$define(a)(1)($$box(120)($$alphabetic($$1))) $$// because $$apply accepts only macros
  1402 +$$define(sortedwords)(0)($$sort($$apply(a)($$words))))
  1403 +
  1404 +$define(a)(1)($box(120)($alphabetic($1)))
  1405 +$define(sortedwords)(0)($sort($apply(a)($words)))
  1406 +so that $mtt($$sortedwords) looks like this:
  1407 +$p
  1408 +$sortedwords
  1409 +$p
  1410 + Now, we compute the length of this list, divide it by $mtt(2) and add 1 if the remainder is not zero,
  1411 + so that we can cut our list in two lists
  1412 + of almost the same length (the first one with possibly one element more than the second one).
  1413 +$mcode($$define(halflen)(0)($$add($$quotient($$length($$sortedwords))(2))
  1414 + ($$if($$equals(0)($$remainder($$length($$sortedwords))(2)))(0)(1)))
  1415 +$$define(column1)(0)($$sublist(0)($$halflen)($$sortedwords))
  1416 +$$define(column2)(0)($$sublist($$halflen)($$length($$sortedwords))($$sortedwords)))
  1417 +
  1418 +$define(halflen)(0)($add($quotient($length($sortedwords))(2))
  1419 + ($if($equals(0)($remainder($length($sortedwords))(2)))(0)(1)))
  1420 +$define(column1)(0)($sublist(0)($halflen)($sortedwords))
  1421 +$define(column2)(0)($sublist($halflen)($length($sortedwords))($sortedwords))
  1422 +
  1423 +Finally, we can get the wanted result by writing:
  1424 +$define(putpar)(1)($1$par)
  1425 +$mcode($$define(putpar)(1)($$1$$par)
  1426 +$$center($$apply(putpar)($$transpose($[$$column1$,$$column2$]))))
  1427 +
  1428 +$center($apply(putpar)($transpose([$column1,$column2])))
  1429 +$p
  1430 + The macro $mtt($$multicolumns($argu(number of columns))($argu(items))) defined in $fname(basis.maml)
  1431 + is just a more general version of the above.
  1432 +
  1433 +
  1434 + $mark0(true) This mark represents the truth value $em(true).
  1435 +
  1436 + $mark1(tt)(text) This mark renders $argu(text) in fixed width (typewriter) font. It is similar to
  1437 + $ref(code)($mtt($$code(...))), with the difference that $argu(text) is put inline instead of as a separate block.
  1438 + For example, $mtt($$red($$tt(This)) is $$code(220,220,220)(an) example.)
  1439 + produces: $red($tt(This)) is $code(220,220,220)(an) example.
  1440 + $par$par
  1441 + See also $ref(code)($mtt($$code(...))) and $ref(verbatim)($mtt($$verbatim(...))).
  1442 +
  1443 + $mark1(undefine)(name) This mark allows to $em(undefine) a macro previously defined by $ref(define)($mtt($$define)).
  1444 + Actually, it removes only the last definition of the macro whose name is given, so that the previous definition of
  1445 + this same mark name (if any) is working again.
  1446 + If no macro with name $argu(name) exists, nothing happens. $par$par
  1447 +
  1448 + Example:
  1449 + $mcode($$define(emph)(1)($$italic($$1))
  1450 +$$emph(text1)$$par
  1451 +$$define(emph)(2)($$bold($$1):$$red($$2))
  1452 +$$emph(text2a)(text2b)$$par
  1453 +$$undefine(emph)
  1454 +$$emph(text3))
  1455 + produces:$par$par
  1456 +
  1457 +$define(emph)(1)($italic($1))
  1458 +$emph(text1)$par
  1459 +$define(emph)(2)($bold($1):$red($2))
  1460 +$emph(text2a)(text2b)$par
  1461 +$undefine(emph)
  1462 +$emph(text3)
  1463 + $par$par
  1464 + As a consequence, a $MAML text can safely be embedded into another $MAML text using $mtt($$input), provided
  1465 + that you $em(undefine) the macros defined in the embedded text at the end of the embedded text. $p
  1466 +
  1467 + As told in $ref(define)($mtt($$define)), $mtt($$define) doesn't allow recursion. However, if a macro with the same
  1468 + name is already defined, any usage of this macro name in the body of the new definition refers to the previous
  1469 + definition. For example,
  1470 + $mcode($$define(bu)(1)($$italic($$1))
  1471 +$$bu(Some text.)$$par
  1472 +$$define(bu)(2)($$rgb(120,0,0)($$bu($$1) $$2))
  1473 +$$bu(Text1)(Text2)) produces:$par$par
  1474 +
  1475 +
  1476 + $define(bu)(1)($italic($1))
  1477 + $bu(Some text.)$par
  1478 + $define(bu)(2)($rgb(120,0,0)($bu($1) $2))
  1479 + $bu(Text1)(Text2)$par
  1480 +
  1481 +
  1482 + $mark1(verbatim)(text) This marks reproduces its content without any change with two exceptions.
  1483 + Indeed, $MAML marks within
  1484 + $argu(text) are not interpreted, except the two marks $mtt($$lpar) and $mtt($$rpar), which allows you
  1485 + to produce unbalanced parentheses in $argu(text) despite the fact that actual parentheses $em(must) be
  1486 + balanced in $argu(text). Example:
  1487 + $par
  1488 + $mcode($$verbatim(In this ($$italic(text))(), ((parentheses) are) $$rpar$$rpar$$lpar balanced.))
  1489 + produces:
  1490 + $p
  1491 + $verbatim(In this ($italic(text))(), ((parentheses) are) $rpar$rpar$lpar balanced.)
  1492 + $p
  1493 + Nevertheless, colors are applied if $mtt($$verbatim(...)) is within a $mtt($$rgb(...)(...)). Indeed,
  1494 + $mcode($$rgb(255,0,0)($$verbatim(Red verbatim text))) produces:
  1495 + $rgb(255,0,0)($verbatim(Red verbatim text))
  1496 + On the contrary, $mcode($$colorize(maml)($$verbatim(Red verbatim text))) produces:
  1497 + $colorize(maml)($verbatim(Red verbatim text))
  1498 + because $mtt($$verbatim) is not a macro.
  1499 + $par
  1500 + $par
  1501 + See also $ref(code)($mtt($$code(...))) and $ref(tt)($mtt($$tt(...))).
  1502 + $p$p
  1503 +
  1504 +
  1505 +
  1506 +$ifhtml($par$par$par$par$par$par$par$par)
  1507 +
  1508 +$end
  1509 +
  1510 +
... ...
anubis_dev/library/doc_tools/maml4_tutorial.maml.html 0 → 100644
  1 +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  2 +<style>
  3 +body { counter-reset: section;
  4 + font-size: 12px; }
  5 +p { align: justify; width: 600px; }
  6 +h2 { counter-reset: subsection; }
  7 +h2::before { counter-increment: section;
  8 + content: counter(section) ". "; }
  9 +h3 { counter-reset: subsubsection; }
  10 +h3::before { counter-increment: subsection;
  11 + content: counter(section) "." counter(subsection) " "; }
  12 +h4::before { counter-increment: subsubsection;
  13 + content: counter(section) "." counter(subsection) "." counter(subsubsection) " "; }
  14 +.dropdown { position: relative;
  15 + display: inline-block; }
  16 +.drp-content { display: none;
  17 + position: fixed;
  18 + bottom: 10px;
  19 + right: 10px;
  20 + background-color: #ffcc00;
  21 + max-width: 500px;
  22 + box-shadow: 0px 16px 16px 0px rgba(0,0,0,0.6);
  23 + padding: 0px 6px;
  24 + z-index: 0; }
  25 +.dropdown:hover .drp-content { display: block;
  26 + z-index: 2; }
  27 +</style>
  28 +</head><body><center><table style="width: 600px; font-size:12px;"><tr><td><div style="text-align: justify; text-justify: inter-word; width: 600px;">
  29 +
  30 +
  31 +
  32 +
  33 +
  34 +
  35 +
  36 +
  37 +
  38 +
  39 +
  40 +
  41 +
  42 +
  43 +
  44 +
  45 +
  46 +
  47 +
  48 +
  49 +
  50 +
  51 +
  52 +
  53 +
  54 +
  55 +
  56 +
  57 +
  58 +
  59 +
  60 +
  61 +
  62 +
  63 +
  64 +
  65 +
  66 +
  67 +
  68 +
  69 +
  70 +
  71 +
  72 +
  73 +
  74 +
  75 +
  76 +
  77 +
  78 +
  79 +
  80 +
  81 +
  82 +
  83 +
  84 +
  85 +
  86 +
  87 +
  88 +
  89 +
  90 +
  91 +
  92 +
  93 +
  94 +
  95 +
  96 +
  97 +
  98 +
  99 +
  100 +
  101 +
  102 +
  103 +
  104 +
  105 +
  106 +
  107 +
  108 +
  109 +
  110 +
  111 +
  112 +
  113 +
  114 +
  115 +
  116 +
  117 +
  118 +
  119 +
  120 +
  121 +
  122 +
  123 +
  124 +
  125 +
  126 +
  127 +
  128 +
  129 +
  130 +
  131 +
  132 +
  133 +
  134 +
  135 +
  136 +
  137 +
  138 +
  139 +
  140 +
  141 +
  142 +
  143 +
  144 +
  145 +
  146 +
  147 +<center><table style="color: inherit; font-size: inherit;"><tr><td><big><big><strong>The <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> (version 4) Tutorial</strong></big></big></td></tr></table></center>
  148 +<center><table style="color: inherit; font-size: inherit;"><tr><td><big><big><strong>and Reference</strong></big></big></td></tr></table></center>
  149 +<br><br><br>
  150 +
  151 +<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> (the <em>Minimalist Anubis Markup Language</em>) is an easy to use tool for writing texts. It provides
  152 +commands for using different <strong>font</strong> <em>styles</em>, <big>font <big>sizes</big></big>, <div style="display: inline; color: rgb(255,000,000)">colors</div>, for making lists, tables,
  153 +sectionning units, inserting images
  154 +and
  155 +hypertext links, automatically making a table of contents,
  156 +and most sorts of things which are useful for writting texts which are agreable to read.
  157 +It is also able to automatically produce syntactic colorations. The <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>
  158 +compiler produces HTML and PDF output files from a <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> source text.
  159 +This documentation itself was written in <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>.<br><br>
  160 +
  161 +Despite its computing capabilities, <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> is <em>not a programming language</em>. It is a <em>text formating language</em>.
  162 +Programming with <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> is easy provided you write only very short pieces of programs. Making big programs in <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>
  163 +would generate absolutely unreadable source texts (like what happens with <img src="png/foAbejNaCwiT0Jzk31KqV0gRWsOY.png" width="25" height="14" style="vertical-align: -3px">). We have managed to present
  164 +many (short) examples of <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> programming in this tutorial, which helps to quickly understand the explanations.<br><br>
  165 +
  166 +The very first version of <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> was designed for allowing users on a forum to decorate their messages, and was
  167 +very rudimentary. This is
  168 +why <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> was called <em>minimalist</em>. This version 4 is now quite far from being <em>minimalist</em>, but the name <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>
  169 +remains (partly because it's funny when pronounced in French).
  170 +
  171 +<br><br>
  172 +<center><table style="color: inherit; font-size: inherit;"><tr><td><strong>Table of Contents</strong></td></tr></table></center><br>
  173 +<a rel="tag" href="#howto"><br><strong>1. How to use <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong></strong><br></a><a rel="tag" href="#ascmdlinetool"><div align="left" style="display: inline-block; width: 20px;"></div>1.1. As a command line tool<br></a><a rel="tag" href="#fromyoursource"><div align="left" style="display: inline-block; width: 20px;"></div>1.2. From within your Anubis source code<br></a><a rel="tag" href="#aswebuser"><div align="left" style="display: inline-block; width: 20px;"></div>1.3. As a web user<br></a><a rel="tag" href="#syntax"><br><strong>2. The <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> syntax</strong><br></a><a rel="tag" href="#beginend"><div align="left" style="display: inline-block; width: 20px;"></div>2.1. <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong></span> and special characters<br></a><a rel="tag" href="#syntaxmark"><div align="left" style="display: inline-block; width: 20px;"></div>2.2. Marks<br></a><a rel="tag" href="#linecomments"><div align="left" style="display: inline-block; width: 20px;"></div>2.3. Line comments<br></a><a rel="tag" href="#balanced"><div align="left" style="display: inline-block; width: 20px;"></div>2.4. Parentheses must be balanced<br></a><a rel="tag" href="#marknamedelim"><div align="left" style="display: inline-block; width: 20px;"></div>2.5. How mark names are delimited<br></a><a rel="tag" href="#definingmarks"><div align="left" style="display: inline-block; width: 20px;"></div>2.6. Defining new marks with <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span><br></a><a rel="tag" href="#style"><br><strong>3. Be stylish</strong><br></a><a rel="tag" href="#basismaml"><div align="left" style="display: inline-block; width: 20px;"></div>3.1. The file <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div><br></a><a rel="tag" href="#styleexample"><div align="left" style="display: inline-block; width: 20px;"></div>3.2. An example<br></a><a rel="tag" href="#inputstyle"><div align="left" style="display: inline-block; width: 20px;"></div>3.3. Inputting a style file<br></a><a rel="tag" href="#colorize"><br><strong>4. Automatic colorization</strong><br></a><a rel="tag" href="#createcolorizer"><div align="left" style="display: inline-block; width: 20px;"></div>4.1. Creating a colorizer<br></a><a rel="tag" href="#mycolorizer"><div align="left" style="display: inline-block; width: 20px;"></div>4.2. A colorizer example<br></a><a rel="tag" href="#colorizerprecedence"><div align="left" style="display: inline-block; width: 20px;"></div>4.3. Primitive marks and colorizers<br></a><a rel="tag" href="#severalcolorizers"><div align="left" style="display: inline-block; width: 20px;"></div>4.4. Using several colorizers together<br></a><a rel="tag" href="#colorizercall"><div align="left" style="display: inline-block; width: 20px;"></div>4.5. Calling a colorizer from within a colorizer<br></a><a rel="tag" href="#colorcallexample"><div align="left" style="display: inline-block; width: 20px;"></div>4.6. A colorizer call example<br></a><a rel="tag" href="#noncolor"><div align="left" style="display: inline-block; width: 20px;"></div>4.7. A non colorizing example.<br></a><a rel="tag" href="#tools"><br><strong>5. Other tools</strong><br></a><a rel="tag" href="#arithmetics"><div align="left" style="display: inline-block; width: 20px;"></div>5.1. Elementary arithmetics<br></a><a rel="tag" href="#booleans"><div align="left" style="display: inline-block; width: 20px;"></div>5.2. Booleans and control<br></a><a rel="tag" href="#counters"><div align="left" style="display: inline-block; width: 20px;"></div>5.3. Counters<br></a><a rel="tag" href="#lists"><div align="left" style="display: inline-block; width: 20px;"></div>5.4. Lists<br></a><a rel="tag" href="#tips"><br><strong>6. Tips and tricks</strong><br></a><a rel="tag" href="#commonerrors"><div align="left" style="display: inline-block; width: 20px;"></div>6.1. Common errors<br></a><a rel="tag" href="#toolsbasis"><br><strong>7. Tools available in <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div></strong><br></a><a rel="tag" href="#colors"><div align="left" style="display: inline-block; width: 20px;"></div>7.1. Colors<br></a><a rel="tag" href="#stylearticle"><div align="left" style="display: inline-block; width: 20px;"></div>7.2. The style <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">article</span><br></a><a rel="tag" href="#_"></a><a rel="tag" href="#_"></a><a rel="tag" href="#book"><div align="left" style="display: inline-block; width: 20px;"></div>7.3. The style <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">book</span><br></a><a rel="tag" href="#catalog"><br><strong>8. The catalog of <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks</strong><br></a>
  174 +
  175 +
  176 +
  177 +<a id="howto"></a><br><big><big><strong>1. How to use <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong></strong></big></big><br><br>
  178 +
  179 +<a id="ascmdlinetool"></a><br><big><strong>1.1. As a command line tool</strong></big><br><br>
  180 +
  181 +<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> can be used as a command line tool. This tool can work to its full power
  182 +only if <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">pdflatex</span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">dvipng</span> are installed on
  183 +your system. If they are not, you can still use <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>, but the mark <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$latex</div></strong></span> will not work, and you will not be able
  184 +to produce a PDF output. See the Anubis library documentation for more precise explanations.
  185 +<br>
  186 +<br>
  187 +Assuming that the file <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">my_file.maml</span> contains some <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> source text,
  188 +you just have to issue the command:
  189 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br>anbexec maml my_file.maml<br><br></pre>
  190 +and the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> compiler will produce a file named <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">my_file.maml.html</span> that you can view with your favorite browser.
  191 +<br>
  192 +<br>
  193 +This command line tool has several options that you can discover by typing:
  194 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br>anbexec maml<br><br></pre>
  195 +For example, the option <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">-pdf</span> produces a PDF output.
  196 +<br><br>
  197 +
  198 +<a id="fromyoursource"></a><br><big><strong>1.2. From within your Anubis source code</strong></big><br><br>
  199 +
  200 +You may also want to use the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> compiler from within your Anubis source code. For example, you may want to use <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>
  201 + on a web site.
  202 +In this case, have a look at the Anubis library documentation.
  203 +Notice that several <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks are <strong><div style="display: inline; color: rgb(220,0,0)">unsafe</div></strong> for a use on the web. We explain in the library documentation
  204 +how to restrict <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> to safe marks.<br><br>
  205 +
  206 +
  207 +<a id="aswebuser"></a><br><big><strong>1.3. As a web user</strong></big><br><br>
  208 +
  209 +Since <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> can be used in a web site (powered for example by the Anubis web server), it is possible to allow web users
  210 +(those persons visiting the web site) to write <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> texts within web pages. In this case, the set of available <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>
  211 +marks is restricted for ensuring the security of the web server.<br><br>
  212 +
  213 +
  214 +
  215 +
  216 +<a id="syntax"></a><br><big><big><strong>2. The <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> syntax</strong></big></big><br><br>
  217 +
  218 +<a id="beginend"></a><br><big><strong>2.1. <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong></span> and special characters</strong></big><br><br>
  219 +
  220 +When it reads a source text, the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> compiler ignores everything until the first occurrence of <a rel="tag" href="#begin"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span></a>. After
  221 +this <em>mark</em>, the compiler parses and evaluates the text until it finds <a rel="tag" href="#end"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong></span></a>. Then again, it ignores everything
  222 +until the next <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span>, and so on.<br><br>
  223 +
  224 +Between <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong></span>, the compiler considers all characters as neutral (i.e. they represent only
  225 +themselves), except the character <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">$</span>. This character introduces a so-called <em>mark</em>, which can have so-called
  226 +<em>operands</em>. The operands are delimited by pairs of parentheses.
  227 +
  228 +Within an operand, all characters are considered as pure text, except the following:
  229 +<span><ul>
  230 + <li> the character <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">$</span>,
  231 + <li> the left and right parentheses <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">(</span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">)</span>. They are used for delimiting blocks of text.
  232 + <li> the left and right square brackets <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">[</span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">]</span>. They are used for delimiting lists, and within such
  233 + lists, the comma <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">,</span> is used for separating the elements of the list. The comma is otherwise neutral.
  234 +</ul></span>
  235 + Of course, the possibility exists of inserting these characters as usual neutral characters. It is enough to prefix
  236 + them by a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">$</span>. Hence, for example, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">[</span> marks the beginning of a list, whereas <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$[</div></strong></span> just represents a
  237 + left square bracket.<br><br>
  238 +
  239 + The figure below sumarizes the above rules.
  240 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br> <em><div style="display: inline; color: rgb(000,100,000)">before $begin everything is ignored</div></em>
  241 +
  242 + <strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong>
  243 +
  244 + <em><div style="display: inline; color: rgb(000,000,128)">here, outside any operand of mark, only the character $ is special</div></em>
  245 +
  246 + <strong><div style="display: inline; color: rgb(255,000,000)">$a_mark</div></strong>(... <em><div style="display: inline; color: rgb(110,000,000)">here, <strong>$ ( ) [</strong> and <strong>]</strong> are special</div></em> ...)
  247 + (... [ <em><div style="display: inline; color: rgb(160,082,045)">and here, the comma also is special</div></em> ]
  248 + ... <strong><div style="display: inline; color: rgb(255,000,000)">$another_mark</div></strong>( <em><div style="display: inline; color: rgb(110,000,000)">here too, <strong>$ ( ) [</strong> and <strong>]</strong> are special</div></em> ...) ...
  249 + (... <strong><div style="display: inline; color: rgb(255,000,000)">$nolist</div></strong>(<em><div style="display: inline; color: rgb(160,032,240)">but here, only <strong>$ (</strong> and <strong>)</strong> are special
  250 + even if we are within a list, but brackets
  251 + must still be balanced</div></em>) ...) )
  252 +
  253 + <strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong>
  254 +
  255 + <em><div style="display: inline; color: rgb(000,100,000)">here again, everything is ignored</div></em>
  256 +
  257 + <strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong>
  258 +
  259 + <em><div style="display: inline; color: rgb(000,000,128)">and here, it works again as above after the first $begin</div></em>
  260 + <em><div style="display: inline; color: rgb(000,000,000)">you can alternate $begin and $end any number of times</div></em>
  261 +
  262 + <em><div style="display: inline; color: rgb(000,000,000)">etc... (and an $end is required for closing each $begin)</div></em><br><br></pre>
  263 +
  264 +
  265 +<a id="syntaxmark"></a><br><big><strong>2.2. Marks</strong></big><br><br>
  266 +
  267 +This character <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">$</span> indicates
  268 +that what follows is a <em>mark</em>. The name of the mark (a non empty sequence of characters among
  269 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(000,000,000)">A...Za...z0...9</div></span>) and the underscore <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">_</span> and not beginning by a digit)
  270 +immediatly follows the character <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">$</span>. The operands
  271 +of the mark follow this name, and each one must be delimited by a pair of parentheses. For example, if you
  272 +want to render some text in dark red, you can write this, where <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">rgb</span> is the name of the mark (this mark takes two operands):<br>
  273 +<br><center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">120</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(This text is rendered in dark red.)</span></td></tr></table></center><br>
  274 +which produces this:
  275 +<br><center><table style="color: inherit; font-size: inherit;"><tr><td><div style="display: inline; color: rgb(120,0,0)">This text is rendered in dark red.</div></td></tr></table></center><br>
  276 +
  277 +You shall learn below how to write <em>macros</em> in <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> using the mark <a rel="tag" href="#define"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span></a>,
  278 +so that you can actually simplify the writing of the above. For example the name <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> itself
  279 +is produced by the macro <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$MAML</div></strong></span> which is defined as follows:
  280 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(MAML)(<div style="display: inline; color: rgb(160,082,045)">0</div>) <div style="display: inline; color: rgb(000,100,000)">$// defining the macro $MAML taking zero operand</div>
  281 + (<strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">180</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(M)<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">120</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(A)<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">80</div>,<div style="display: inline; color: rgb(160,082,045)">80</div>,<div style="display: inline; color: rgb(160,082,045)">80</div>)(M)<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">220</div>)(L)))<br><br></pre>
  282 +
  283 +<a id="linecomments"></a><br><big><strong>2.3. Line comments</strong></big><br><br>
  284 +
  285 +Notice that you can put <em>line comments</em> into your <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> source texts as follows:<br><br>
  286 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(000,100,000)">$// blah blah blah ...</div></span></td></tr></table></center><br>
  287 +The mark <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(000,100,000)">$//</div></span> and what follows until the end of the line are ignored by the compiler (but it keep
  288 +the new line charaters). This kind of comment can be
  289 +put everywhere, including within operands of marks, between the operands of a mark (as shown above) and between
  290 +a mark and its first operand.<br><br>
  291 +
  292 +<a id="balanced"></a><br><big><strong>2.4. Parentheses must be balanced</strong></big><br><br>
  293 +
  294 +Each mark accepts a fixed number of operands. Since each operand must be delimited by a pair of parentheses
  295 +(which are not part of the operand itself), the
  296 +parentheses which are part of the operand (if any) must be balanced, otherwise the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> parser will not find the closing
  297 +parenthese. Nevertheless, you can still include unbalanced parentheses in an operand provided that you write them
  298 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$lpar</div></strong></span> (left parenthese) and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rpar</div></strong></span> (right parenthese).<br><br>
  299 +
  300 +
  301 +<a id="marknamedelim"></a><br><big><strong>2.5. How mark names are delimited</strong></big><br><br>
  302 +
  303 +Also remark that between any two operands of a mark (and between the mark itself and its first operand), you cannot
  304 +write anything else than <em>white</em> characters (i.e. spaces, line-feeds, carriage-returns and tabulators), and line
  305 +comments. For example,
  306 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">255</div>)(My text)<br><br></pre>
  307 +is equivalent to
  308 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong> (<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">255</div>) <div style="display: inline; color: rgb(000,100,000)">$// this make a bright blue</div>
  309 + (My Text)<br><br></pre>
  310 +But if you write this: <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">255</div>) a (My text)</span>, the compiler will complain that an operand is missing (it
  311 +also indicates the path of the file and the line number where this happens).
  312 +<br>
  313 +<br>
  314 +<em>Remark:</em> The name of a mark is right delimited by the first character which is not an acceptable character
  315 +for such a name. If this character is a space, it is <em>not</em> discarded (unlike what the <img src="png/foAbejNaCwiT0Jzk31KqV0gRWsOY.png" width="25" height="14" style="vertical-align: -3px"> compiler
  316 +does). Hence for example,
  317 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$lpar</div></strong> x</span> (with just one space between <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$lpar</div></strong></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">x</span>)
  318 +produces ( x (with a space between the parenthese and x),
  319 +so that it seems that there is no way to obtain (x (with nothing between the parenthese and x).
  320 +Actually, there is a simple trick to
  321 +obtain the later. Indeed, it is enough to define an <em>identity</em> macro as follows:
  322 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(id)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<div style="display: inline; color: rgb(255,000,255)">$1</div>)<br><br></pre>
  323 +and to write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$id</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$lpar</div></strong>)x</span>.<br><br>
  324 +
  325 +
  326 +
  327 +
  328 +<a id="definingmarks"></a><br><big><strong>2.6. Defining new marks with <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span></strong></big><br><br>
  329 +
  330 +We already saw examples of use of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span> above. It's now time to give precisions about this possibility to
  331 +enrich the language with new marks, which is one of the most powerful tools we have at hand.<br><br>
  332 +
  333 +The syntax of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span> is as follows:<br>
  334 +<br><center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;arity&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div>)</span></td></tr></table></center><br>
  335 +where <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> is the name you want to give to your new mark, <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;arity&gt;</span></strong></div> its <em>arity</em>, i.e. the number of
  336 +operands it takes, and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div> the value of the mark, which of course depends on the values of it's future operands, which
  337 +is the reason why <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div> contains so-called <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> <em>variables</em> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(255,000,255)">$1</div></span>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(255,000,255)">$2</div></span>, etc...<br><br>
  338 +
  339 +Notice that if a macro with the same name <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> is already defined, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span> does not destroy this
  340 +previous definition of <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>. It pushes the new definition on a stack of definitions associated to this name. As a
  341 +consequence, when you use <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$undefine</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span>, the most recent definition of name is poped off this stack (and
  342 +forgotten) and the previous one prevails again. See <a rel="tag" href="#undefine"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$undefine</div></strong></span></a> for some examples.<br><br>
  343 +
  344 +When the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> compiler encounters a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;arity&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div>)</span>, it doesn't evaluate
  345 +(i.e. it doesn't <em>compute</em>) <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> nor <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;arity&gt;</span></strong></div>. Consequently, these two operands must be written in their
  346 +definitive form.<br><br>
  347 +
  348 +The third operand <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div> is only <em>partly evaluated</em> in the sens that macros are expanded within <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div>,
  349 +but primitive marks are not executed (which is in any case mandatory since operands are not yet known).
  350 +This policy has two important consequences:
  351 +<span><ul>
  352 + <li> if <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div> contains a call to <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>, this call doesn't refer to the macro currently being defined,
  353 + but to its previous definition (if any). As a byproduct, this also forbids recursive definitions of macros, so
  354 + protecting the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> compiler against infinite loops.<br><br>
  355 + <li> <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div> cannot refer to a macro which is not yet defined (there are no forward references in <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>), so
  356 + that the macro always keeps the meaning it has when it is defined, except that the values provided by primitive marks
  357 + will be computed only when the macro is used.
  358 +</ul></span>
  359 +Nevertheless, you may want, especially if you are defining a customizable style of document for example, to define
  360 +macros making use of other macros which can be redefined by the user of your style file. The solution is first of all
  361 +to define these other macros conditionally, i.e. as follows:
  362 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$defined</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>))()(<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(...)(...))<br><br></pre>
  363 +that is that you provide a <em>default</em> definition, but only in case your user did not define <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>. Of course, this
  364 +implies that your user must define <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> <em>before</em> writing <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;your style file&gt;</span></strong></div>)</span>.<br><br>
  365 +
  366 +
  367 +<a id="style"></a><br><big><big><strong>3. Be stylish</strong></big></big><br><br>
  368 +
  369 +The primitive <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks are rather basic, and should preferably be used for creating macros.
  370 +In other words, it's better to first define (using the <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span> mark) the concepts you will use in your
  371 +text, rather than writing them from scratch at each occurrence. In some sens, defining these concepts is the same as
  372 +creating your own style. <br><br>
  373 +
  374 +<a id="basismaml"></a><br><big><strong>3.1. The file <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div></strong></big><br><br>
  375 +
  376 +Notice that a file <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div> exists in <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">library/doc_tools</span></div> which already contains macros of
  377 +common usage.
  378 +<br><br>
  379 +
  380 +<a id="styleexample"></a><br><big><strong>3.2. An example</strong></big><br><br>
  381 +
  382 +It can be the case that some concept of your discourse has to be emphasized in a particular way, and that
  383 +you (arbitrarily) chosed to print it
  384 +in red. You should not use <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">255</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(...)</span> in the text. You should better first give a name (say <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">emph</span>) to
  385 +your concept, and define it near the beginning of the text:
  386 +<br><br>
  387 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(emph)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">255</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(<div style="display: inline; color: rgb(255,000,255)">$1</div>))</span>
  388 +<br><br>
  389 +and write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$emph</div></strong>(...)</span> in the text instead of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">255</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(...)</span>.
  390 +<br><br>
  391 +This will structure your text in a useful semantic way, instead of a non significant way, making it easier
  392 +to later update.
  393 +It also has the advantage that you can later easily change the layout of the text by modifying
  394 +only the values in these <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span>.
  395 +<br><br>
  396 +<a id="inputstyle"></a><br><big><strong>3.3. Inputting a style file</strong></big><br><br>
  397 +
  398 +The <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong></span> mark let you <em>input</em> a <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> source at any point of another <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> source. Hence, you should
  399 +define your style in a file (say <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">mystyle.maml</span>) and put an <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong>(mystyle.maml)</span> after the first <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span>
  400 +of your source file. Notice that the input file also needs to contain a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span> and an <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong></span>.<br><br>
  401 +
  402 +
  403 +
  404 +
  405 +<a id="colorize"></a><br><big><big><strong>4. Automatic colorization</strong></big></big><br><br>
  406 +
  407 +<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> has a simple system for automatic colorization of texts. Within a <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> source text,
  408 +you can define one or several colorizers, and later apply them at will. Actually, by <em>colorization</em> we mean
  409 +something quite general, i.e. not dealing only with colors.<br><br>
  410 +
  411 +<a id="createcolorizer"></a><br><big><strong>4.1. Creating a colorizer</strong></big><br><br>
  412 +
  413 +In order to create a colorizer, you must:
  414 +<span><ul>
  415 + <li> define one or several <em>color rules</em>,
  416 + <li> when done, create the <em>colorizer</em>.
  417 +</ul></span>
  418 +A color rule has the form:<br>
  419 +<br><center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;regular expression&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> expression&gt;</span></strong></div>)</span></td></tr></table></center><br>
  420 +The <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer name&gt;</span></strong></div> of the colorizer must be an ordinary symbol. The <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;regular expression&gt;</span></strong></div> must follow the syntax defined in
  421 +<div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">library/lexical_analysis/fast_lexer_5.anubis</span></div> (see the Anubis library documentation) and <em>is not evaluated</em>, so
  422 +that it must be written in its definitive form.
  423 +The <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> expression&gt;</span></strong></div> can contain the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> <em>variable</em>
  424 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(255,000,255)">$1</div></span> which is replaced by the token (i.e. the character string recognized by the regular expression)
  425 +to be colorized.<br><br>
  426 +
  427 +Once the color rules are setup, you can create the colorizer as follows:<br>
  428 +<br><center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorizer</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer name&gt;</span></strong></div>)</span></td></tr></table></center><br>
  429 +Then, you can colorize a text:<br>
  430 +<br><center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></td></tr></table></center><br>
  431 +
  432 +<a id="mycolorizer"></a><br><big><strong>4.2. A colorizer example</strong></big><br><br>
  433 +
  434 +As an example, consider the following definition of a colorizer, which is used in this tutorial for colorizing
  435 +<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> code:
  436 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br> <div style="display: inline; color: rgb(000,100,000)">$// line comments</div>
  437 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(maml)(#$#/#/.*)(<strong><div style="display: inline; color: rgb(255,000,000)">$darkgreen</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  438 + <div style="display: inline; color: rgb(000,100,000)">$// mark names (inclusing inhibited characters)</div>
  439 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(maml)(<div style="display: inline; color: rgb(000,000,000)">(#$[#,#[#]#(#)])|(#$[a-zA-Z#_][0-9a-zA-Z#_]*)|(#$#$)</div>)
  440 + (<strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>)))
  441 + <div style="display: inline; color: rgb(000,100,000)">$// MAML variables</div>
  442 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(maml)(<div style="display: inline; color: rgb(000,000,000)">#$[0-9]+</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$magenta</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  443 + <div style="display: inline; color: rgb(000,100,000)">$// integers</div>
  444 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(maml)(<div style="display: inline; color: rgb(000,000,000)">[0-9]+</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$sienna</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  445 + <div style="display: inline; color: rgb(000,100,000)">$// creating the colorizer</div>
  446 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorizer</div></strong>(maml)<br><br></pre>
  447 +There are plenty of examples of use of this colorizer in this tutorial (including the above definition of the
  448 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">maml</span> colorizer&nbsp;!), so that you can easily check that the result is coherent with the definition.<br><br>
  449 +
  450 +Notice that we used <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong></span> in the above definition, which is not a color per se. Actually any mark can be used, so
  451 +that colorizers can also be used for a purpose having nothing to do with colors.<br><br>
  452 +
  453 +<a id="colorizerprecedence"></a><br><big><strong>4.3. Primitive marks and colorizers</strong></big><br><br>
  454 +
  455 +You also need to know what happens if the text to be colorized contains <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks.
  456 +All macros are expanded before colorization applies, so that macros have no incidence on colorization, but they can be
  457 +used within a text to be colorized. <br><br>
  458 +
  459 +Things are different for primitive marks. Indeed, how do you interpret for example
  460 +<br><br>
  461 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong>(maml)(<div style="display: inline; color: rgb(000,000,000)">This is $rgb(120,0,0)(an example) text.</div>)</span></td></tr></table></center>
  462 +<br>
  463 +It should be clear that <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">$rgb</span> in this example should
  464 +have precedence over <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong></span>, otherwise it would be useless. So, the behavior of <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> is that it doesn't
  465 +apply a colorizer within the operands of primitive marks (it would be nevertheless meaningless in the case of the operand
  466 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">120,0,0</span> of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">$rgb</span>).<br><br>
  467 +
  468 +As a consequence, the above example gives
  469 +This is <div style="display: inline; color: rgb(120,0,0)">an example</div> text.,
  470 +not This is an example text.<br><br>
  471 +
  472 +Nevertheless, you can still colorize within an operand within a text to be colorized. For example,
  473 +<br><br>
  474 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tt</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong>(maml)(<div style="display: inline; color: rgb(000,000,000)">$$bold($darkgreen($$red(text)))</div>))</span></td></tr></table></center>
  475 +<br>
  476 +produces <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(<div style="display: inline; color: rgb(000,100,000)">$red(text)</div>)</span>, whereas
  477 +<br><br>
  478 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tt</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong>(maml)(<div style="display: inline; color: rgb(000,000,000)">$$bold($darkgreen($colorize(maml)($$red(text))))</div>))</span></td></tr></table></center>
  479 +<br>
  480 +produces <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(<div style="display: inline; color: rgb(000,100,000)"><strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(text)</div>)</span>.<br><br>
  481 +
  482 +<a id="severalcolorizers"></a><br><big><strong>4.4. Using several colorizers together</strong></big><br><br>
  483 +
  484 +You can use several colorizers together. Below is another colorizer:
  485 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(funny)([a-e])(<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">10</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">130</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$sup</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>)))
  486 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(funny)([e-k])(<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">150</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$italic</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>)))
  487 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(funny)([l-p])(<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">100</div>,<div style="display: inline; color: rgb(160,082,045)">100</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))))
  488 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(funny)([p-z])(<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">100</div>,<div style="display: inline; color: rgb(160,082,045)">100</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$sub</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))))
  489 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorizer</div></strong>(funny)<br><br></pre>
  490 +
  491 +
  492 +
  493 +
  494 +
  495 +If you write:
  496 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$tt</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong>(maml)
  497 + (<div style="display: inline; color: rgb(000,000,000)">$$bold(Some text $colorize(funny)(with a piece of funny text) in it.)</div>))<br><br></pre>
  498 +you get <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(Some text <div style="display: inline; color: rgb(0,100,100)"><sub><big>w</big></sub></div><div style="display: inline; color: rgb(150,0,0)"><em>i</em></div><div style="display: inline; color: rgb(0,100,100)"><sub><big>t</big></sub></div><div style="display: inline; color: rgb(150,0,0)"><em>h</em></div> <div style="display: inline; color: rgb(10,0,130)"><sup>a</sup></div> <div style="display: inline; color: rgb(100,100,0)"><big><big>p</big></big></div><div style="display: inline; color: rgb(150,0,0)"><em>i</em></div><div style="display: inline; color: rgb(10,0,130)"><sup>e</sup></div><div style="display: inline; color: rgb(10,0,130)"><sup>c</sup></div><div style="display: inline; color: rgb(10,0,130)"><sup>e</sup></div> <div style="display: inline; color: rgb(100,100,0)"><big><big>o</big></big></div><div style="display: inline; color: rgb(150,0,0)"><em>f</em></div> <div style="display: inline; color: rgb(150,0,0)"><em>f</em></div><div style="display: inline; color: rgb(0,100,100)"><sub><big>u</big></sub></div><div style="display: inline; color: rgb(100,100,0)"><big><big>n</big></big></div><div style="display: inline; color: rgb(100,100,0)"><big><big>n</big></big></div><div style="display: inline; color: rgb(0,100,100)"><sub><big>y</big></sub></div> <div style="display: inline; color: rgb(0,100,100)"><sub><big>t</big></sub></div><div style="display: inline; color: rgb(10,0,130)"><sup>e</sup></div><div style="display: inline; color: rgb(0,100,100)"><sub><big>x</big></sub></div><div style="display: inline; color: rgb(0,100,100)"><sub><big>t</big></sub></div> in it.)</span><br><br>
  499 +
  500 +
  501 +<a id="colorizercall"></a><br><big><strong>4.5. Calling a colorizer from within a colorizer</strong></big><br><br>
  502 +
  503 +Using several colorizers together can also help to solve particular colorizing problems, because the above is not the
  504 +whole story about <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> colorizers. Indeed, we have another primitive mark:
  505 +<br><br>
  506 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorizercall</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;mode&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer1&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;call&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer2&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;return&gt;</span></strong></div>)</span></td></tr></table></center>
  507 +<br>
  508 +which allows to <em>call</em> a colorizer (here <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer2&gt;</span></strong></div></span>) from within another colorizer (here <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer1&gt;</span></strong></div></span>).
  509 +The operands <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;call&gt;</span></strong></div></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;return&gt;</span></strong></div></span>, which can be any <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> expressions expanding into regular expressions, are used
  510 +as <em>call</em> and <em>return</em> instructions. In other words, when <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer1&gt;</span></strong></div></span> encounters something matching the
  511 +regular expression <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;call&gt;</span></strong></div></span> it calls <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer2&gt;</span></strong></div></span> which will return when it founds something matching the
  512 +regular expression <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;return&gt;</span></strong></div></span>.<br><br>
  513 +
  514 +The pieces of text matching <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;call&gt;</span></strong></div></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;return&gt;</span></strong></div></span> are colorized by <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer1&gt;</span></strong></div></span> or by
  515 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer2&gt;</span></strong></div></span>, depending on the value of <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;mode&gt;</span></strong></div>. There are four modes:
  516 +<span><ul>
  517 + <li> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">ee</span> (<em>exclude-exclude</em>): both <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;call&gt;</span></strong></div> and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;return&gt;</span></strong></div> are colorized by <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer1&gt;</span></strong></div>,
  518 + <li> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">ei</span> (<em>exclude-include</em>): <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;call&gt;</span></strong></div> is colorized <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer1&gt;</span></strong></div> and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;return&gt;</span></strong></div> by <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer2&gt;</span></strong></div>,
  519 + <li> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">ie</span> (<em>include-exclude</em>): <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;call&gt;</span></strong></div> is colorized <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer2&gt;</span></strong></div> and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;return&gt;</span></strong></div> by <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer1&gt;</span></strong></div>,
  520 + <li> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">ii</span> (<em>include-include</em>): both <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;call&gt;</span></strong></div> and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;return&gt;</span></strong></div> are colorized by <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;colorizer2&gt;</span></strong></div>.
  521 +</ul></span>
  522 +
  523 +
  524 +<a id="colorcallexample"></a><br><big><strong>4.6. A colorizer call example</strong></big><br><br>
  525 +
  526 +Consider the case of an Anubis source text, such as:
  527 +<div style="display: inline; color: rgb(120,40,40)"><pre style="color: inherit; font-size: inherit; background-color: rgb(255,255,255); width: 600px;">
  528 +
  529 + A function for computing the length of a list:
  530 +
  531 +public define Int
  532 + length
  533 + (
  534 + List($T) l
  535 + ) =
  536 + if l is
  537 + {
  538 + [ ] then 0,
  539 + [h . t] then 1 + length(t)
  540 + }.
  541 +
  542 + Blah blah blah ...
  543 +
  544 +</pre></div>
  545 +This example contains a <em>paragraph</em> defining a function, which is surrounded by so-called <em>off-paragraph
  546 +comments</em>. In order to colorize this text we need to be able to detect the beginning and the end of Anubis paragraphs.
  547 +This is not possible if we use only color rules as defined by <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong></span>, but it becomes possible if we also use
  548 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorizercall</div></strong></span>.<br><br>
  549 +
  550 +Indeed, we first define two colorizers, say <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">off</span> for off-paragraph comments and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in</span> for paragraphs.<br><br>
  551 +
  552 +In this example, we deliberately chosed to have a head of case of the form <div style="display: inline; color: rgb(120,40,40)">h . t</div> in the conditional,
  553 +because it also contains an <em>end dot</em> (a dot followed by a space or a linefeed) which must not be confused
  554 +with the end dot closing the paragraph.<br><br>
  555 +
  556 +In order to colorize the paragraph itself, we need something like:
  557 +<br><br>
  558 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorizercall</div></strong>(ii)(off)(#npublic)(in)(#.[# #r#n])</span></td></tr></table></center>
  559 +<br>
  560 +However, if we do that, the colorization of the paragraph will end at the end dot which is within the square brackets.
  561 +In order to avoid this, we must add another call:
  562 +<br><br>
  563 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorizercall</div></strong>(ii)(in)(#[)(in)(#])</span></td></tr></table></center>
  564 +<br>
  565 +(the sharp character, i.e. the escape character for regular expressions,
  566 +in front of the square brackets is necessary since square brackets are special characters
  567 +in regular expressions).
  568 +That way, the colorizer <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in</span> will call itself when it reads an opening square bracket and return (to itself) when it reads the
  569 +corresponding closing square bracket.<br><br>
  570 +
  571 +However, with these two call rules, the colorization is still not correct because when the opening bracket of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">[h .
  572 +t]</span> is seen the colorizer <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in</span> calls itself, and the second instance of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in</span> returns on the end dot so that the
  573 +first instance of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in</span> returns on the closing bracket, and the <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">off</span> colorizer is active again at this
  574 +closing bracket. The solution is to define two distinct <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in</span> colorizers, as shown below.<br>
  575 +
  576 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(off)(.)(<strong><div style="display: inline; color: rgb(255,000,000)">$darkgreen</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  577 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(in<div style="display: inline; color: rgb(160,082,045)">1</div>)(.)(<strong><div style="display: inline; color: rgb(255,000,000)">$darkred</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  578 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(in<div style="display: inline; color: rgb(160,082,045)">2</div>)(.)(<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">100</div>,<div style="display: inline; color: rgb(160,082,045)">100</div>)(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  579 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(in<div style="display: inline; color: rgb(160,082,045)">1</div>)(#npublic[# #r#n]+define)(<strong><div style="display: inline; color: rgb(255,000,000)">$tbgc</div></strong>(<div style="display: inline; color: rgb(160,082,045)">220</div>,<div style="display: inline; color: rgb(160,082,045)">220</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">100</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))))
  580 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(in<div style="display: inline; color: rgb(160,082,045)">1</div>)(#.[# #r#n])(<strong><div style="display: inline; color: rgb(255,000,000)">$tbgc</div></strong>(<div style="display: inline; color: rgb(160,082,045)">220</div>,<div style="display: inline; color: rgb(160,082,045)">220</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">100</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))))
  581 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorizercall</div></strong>(ii)(off)(#npublic[# #r#n]+define)(in<div style="display: inline; color: rgb(160,082,045)">1</div>)(#.[# #r#n])
  582 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorizercall</div></strong>(ii)(in<div style="display: inline; color: rgb(160,082,045)">1</div>)(#[)(in<div style="display: inline; color: rgb(160,082,045)">2</div>)(#])
  583 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorizercall</div></strong>(ii)(in<div style="display: inline; color: rgb(160,082,045)">2</div>)(#[)(in<div style="display: inline; color: rgb(160,082,045)">2</div>)(#])
  584 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorizer</div></strong>(in<div style="display: inline; color: rgb(160,082,045)">1</div>)
  585 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorizer</div></strong>(in<div style="display: inline; color: rgb(160,082,045)">2</div>)
  586 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorizer</div></strong>(off)<br><br></pre>
  587 +
  588 +
  589 +
  590 +
  591 +
  592 +
  593 +
  594 +
  595 +
  596 +
  597 +
  598 +
  599 +
  600 +(we put a different color for <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in<div style="display: inline; color: rgb(160,082,045)">1</div></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in<div style="display: inline; color: rgb(160,082,045)">2</div></span> texts for showing where <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in<div style="display: inline; color: rgb(160,082,045)">1</div></span> calls <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in<div style="display: inline; color: rgb(160,082,045)">2</div></span> and where <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">in<div style="display: inline; color: rgb(160,082,045)">2</div></span>
  601 +returns).
  602 +Now, if we write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$_ivory</div></strong>)(<strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong>(off)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;the above example text&gt;</span></strong></div>))</span>, we get:
  603 +
  604 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,230,210); width: 600px;">
  605 +
  606 + <div style="display: inline; color: rgb(000,100,000)">A</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">f</div><div style="display: inline; color: rgb(000,100,000)">u</div><div style="display: inline; color: rgb(000,100,000)">n</div><div style="display: inline; color: rgb(000,100,000)">c</div><div style="display: inline; color: rgb(000,100,000)">t</div><div style="display: inline; color: rgb(000,100,000)">i</div><div style="display: inline; color: rgb(000,100,000)">o</div><div style="display: inline; color: rgb(000,100,000)">n</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">f</div><div style="display: inline; color: rgb(000,100,000)">o</div><div style="display: inline; color: rgb(000,100,000)">r</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">c</div><div style="display: inline; color: rgb(000,100,000)">o</div><div style="display: inline; color: rgb(000,100,000)">m</div><div style="display: inline; color: rgb(000,100,000)">p</div><div style="display: inline; color: rgb(000,100,000)">u</div><div style="display: inline; color: rgb(000,100,000)">t</div><div style="display: inline; color: rgb(000,100,000)">i</div><div style="display: inline; color: rgb(000,100,000)">n</div><div style="display: inline; color: rgb(000,100,000)">g</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">t</div><div style="display: inline; color: rgb(000,100,000)">h</div><div style="display: inline; color: rgb(000,100,000)">e</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">l</div><div style="display: inline; color: rgb(000,100,000)">e</div><div style="display: inline; color: rgb(000,100,000)">n</div><div style="display: inline; color: rgb(000,100,000)">g</div><div style="display: inline; color: rgb(000,100,000)">t</div><div style="display: inline; color: rgb(000,100,000)">h</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">o</div><div style="display: inline; color: rgb(000,100,000)">f</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">a</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">l</div><div style="display: inline; color: rgb(000,100,000)">i</div><div style="display: inline; color: rgb(000,100,000)">s</div><div style="display: inline; color: rgb(000,100,000)">t</div><div style="display: inline; color: rgb(000,100,000)">:</div>
  607 + <div style="display: inline; background-color: rgb(220,220,0); "><div style="display: inline; color: rgb(0,0,100)"><strong>
  608 +public define</strong></div></div><div style="display: inline; color: rgb(110,000,000)"> </div><div style="display: inline; color: rgb(110,000,000)">I</div><div style="display: inline; color: rgb(110,000,000)">n</div><div style="display: inline; color: rgb(110,000,000)">t</div>
  609 + <div style="display: inline; color: rgb(110,000,000)">l</div><div style="display: inline; color: rgb(110,000,000)">e</div><div style="display: inline; color: rgb(110,000,000)">n</div><div style="display: inline; color: rgb(110,000,000)">g</div><div style="display: inline; color: rgb(110,000,000)">t</div><div style="display: inline; color: rgb(110,000,000)">h</div>
  610 + <div style="display: inline; color: rgb(110,000,000)">(</div>
  611 + <div style="display: inline; color: rgb(110,000,000)">L</div><div style="display: inline; color: rgb(110,000,000)">i</div><div style="display: inline; color: rgb(110,000,000)">s</div><div style="display: inline; color: rgb(110,000,000)">t</div><div style="display: inline; color: rgb(110,000,000)">(</div><div style="display: inline; color: rgb(110,000,000)">$</div><div style="display: inline; color: rgb(110,000,000)">T</div><div style="display: inline; color: rgb(110,000,000)">)</div> <div style="display: inline; color: rgb(110,000,000)">l</div>
  612 + <div style="display: inline; color: rgb(110,000,000)">)</div><div style="display: inline; color: rgb(110,000,000)"> </div><div style="display: inline; color: rgb(110,000,000)">=</div>
  613 + <div style="display: inline; color: rgb(110,000,000)">i</div><div style="display: inline; color: rgb(110,000,000)">f</div><div style="display: inline; color: rgb(110,000,000)"> </div><div style="display: inline; color: rgb(110,000,000)">l</div><div style="display: inline; color: rgb(110,000,000)"> </div><div style="display: inline; color: rgb(110,000,000)">i</div><div style="display: inline; color: rgb(110,000,000)">s</div><div style="display: inline; color: rgb(110,000,000)"> </div>
  614 + <div style="display: inline; color: rgb(110,000,000)">{</div>
  615 + <div style="display: inline; color: rgb(0,100,100)">[</div><div style="display: inline; color: rgb(0,100,100)"> </div><div style="display: inline; color: rgb(0,100,100)">]</div> <div style="display: inline; color: rgb(110,000,000)">t</div><div style="display: inline; color: rgb(110,000,000)">h</div><div style="display: inline; color: rgb(110,000,000)">e</div><div style="display: inline; color: rgb(110,000,000)">n</div><div style="display: inline; color: rgb(110,000,000)"> </div><div style="display: inline; color: rgb(110,000,000)">0</div><div style="display: inline; color: rgb(110,000,000)">,</div><div style="display: inline; color: rgb(110,000,000)"> </div>
  616 + <div style="display: inline; color: rgb(0,100,100)">[</div><div style="display: inline; color: rgb(0,100,100)">h</div><div style="display: inline; color: rgb(0,100,100)"> </div><div style="display: inline; color: rgb(0,100,100)">.</div><div style="display: inline; color: rgb(0,100,100)"> </div><div style="display: inline; color: rgb(0,100,100)">t</div><div style="display: inline; color: rgb(0,100,100)">]</div><div style="display: inline; color: rgb(110,000,000)"> </div><div style="display: inline; color: rgb(110,000,000)">t</div><div style="display: inline; color: rgb(110,000,000)">h</div><div style="display: inline; color: rgb(110,000,000)">e</div><div style="display: inline; color: rgb(110,000,000)">n</div><div style="display: inline; color: rgb(110,000,000)"> </div><div style="display: inline; color: rgb(110,000,000)">1</div><div style="display: inline; color: rgb(110,000,000)"> </div><div style="display: inline; color: rgb(110,000,000)">+</div><div style="display: inline; color: rgb(110,000,000)"> </div><div style="display: inline; color: rgb(110,000,000)">l</div><div style="display: inline; color: rgb(110,000,000)">e</div><div style="display: inline; color: rgb(110,000,000)">n</div><div style="display: inline; color: rgb(110,000,000)">g</div><div style="display: inline; color: rgb(110,000,000)">t</div><div style="display: inline; color: rgb(110,000,000)">h</div><div style="display: inline; color: rgb(110,000,000)">(</div><div style="display: inline; color: rgb(110,000,000)">t</div><div style="display: inline; color: rgb(110,000,000)">)</div>
  617 + <div style="display: inline; color: rgb(110,000,000)">}</div><div style="display: inline; background-color: rgb(220,220,0); "><div style="display: inline; color: rgb(0,0,100)"><strong>. </strong></div></div>
  618 +
  619 + <div style="display: inline; color: rgb(000,100,000)">B</div><div style="display: inline; color: rgb(000,100,000)">l</div><div style="display: inline; color: rgb(000,100,000)">a</div><div style="display: inline; color: rgb(000,100,000)">h</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">b</div><div style="display: inline; color: rgb(000,100,000)">l</div><div style="display: inline; color: rgb(000,100,000)">a</div><div style="display: inline; color: rgb(000,100,000)">h</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">b</div><div style="display: inline; color: rgb(000,100,000)">l</div><div style="display: inline; color: rgb(000,100,000)">a</div><div style="display: inline; color: rgb(000,100,000)">h</div><div style="display: inline; color: rgb(000,100,000)"> </div><div style="display: inline; color: rgb(000,100,000)">.</div><div style="display: inline; color: rgb(000,100,000)">.</div><div style="display: inline; color: rgb(000,100,000)">.</div>
  620 +
  621 +</pre>
  622 +and more generally, this works for any depth of square brackets nesting.<br><br>
  623 +
  624 +
  625 +<a id="noncolor"></a><br><big><strong>4.7. A non colorizing example.</strong></big><br><br>
  626 +
  627 +As said above, colorizers are more general than just a tool for colorizing text. For example, they can be used,
  628 +to some extent, for <em>parsing</em> a text.<br><br>
  629 +
  630 +Assume that we have a text which is in CSV (comma separated values) format. Such texts are very common since every
  631 +database system is able to export its tables in this format. Below is an example of such a datum.
  632 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(mycsvtable)(<div style="display: inline; color: rgb(160,082,045)">0</div>)
  633 +(Ford,Max,<div style="display: inline; color: rgb(160,082,045)">32</div>,New York
  634 +Jackson,Niel,<div style="display: inline; color: rgb(160,082,045)">64</div>,Los Angeles
  635 +Kennedy,Justin,<div style="display: inline; color: rgb(160,082,045)">25</div>,New York
  636 +Obama,Barack,<div style="display: inline; color: rgb(160,082,045)">55</div>,Washington
  637 +Smith,John,<div style="display: inline; color: rgb(160,082,045)">24</div>,Baltimore
  638 +Trump,Donald,<div style="display: inline; color: rgb(160,082,045)">70</div>,New York)<br><br></pre>
  639 +
  640 +
  641 +
  642 +
  643 +In this piece of text, the lines of the table are separated by linefeeds and the values in a line are separated by
  644 +commas. For simplicity, we assume that the values contain no comma and no linefeed. In a realistic situation, we would
  645 +have to enhance our example for handling (for example) commas which are within a pair of parentheses. This kind of
  646 +enhancement would require some <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorizercall</div></strong></span>.<br><br>
  647 +
  648 +We define the following colorizer.
  649 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$pushcounter</div></strong>(col)(<div style="display: inline; color: rgb(160,082,045)">0</div>)
  650 +<strong><div style="display: inline; color: rgb(255,000,000)">$pushcounter</div></strong>(line)(<div style="display: inline; color: rgb(160,082,045)">0</div>)
  651 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(display)(#,)(<strong><div style="display: inline; color: rgb(255,000,000)">$addtocounter</div></strong>(col)(<div style="display: inline; color: rgb(160,082,045)">1</div>))
  652 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(display)(#n)
  653 + (<strong><div style="display: inline; color: rgb(255,000,000)">$addtocounter</div></strong>(line)(<div style="display: inline; color: rgb(160,082,045)">1</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong><strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">40</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(line))<strong><div style="display: inline; color: rgb(255,000,000)">$setcounter</div></strong>(col)(<div style="display: inline; color: rgb(160,082,045)">0</div>))
  654 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(display)([^#n#,]*)(<strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$equals</div></strong>(<div style="display: inline; color: rgb(160,082,045)">2</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(col)))
  655 + (<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">40</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>)))
  656 + (<strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$equals</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(col)))
  657 + (<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">100</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>)))
  658 + (<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">100</div>)(<div style="display: inline; color: rgb(255,000,255)">$1</div>))))
  659 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorizer</div></strong>(display)<br><br></pre>
  660 +
  661 +
  662 +
  663 +
  664 +
  665 +
  666 +
  667 +If we write
  668 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong>(display)(
  669 +<strong><div style="display: inline; color: rgb(255,000,000)">$mycsvtable</div></strong>)<br><br></pre>
  670 +
  671 +we obtain:
  672 +<br>
  673 +<br><div align="left" style="display: inline-block; width: 40px;">1</div><div align="left" style="display: inline-block; width: 100px;"><strong>Ford</strong></div><div align="left" style="display: inline-block; width: 100px;">Max</div><div align="left" style="display: inline-block; width: 40px;"><div style="display: inline; color: rgb(255,000,000)">32</div></div><div align="left" style="display: inline-block; width: 100px;">New York</div><br><div align="left" style="display: inline-block; width: 40px;">2</div><div align="left" style="display: inline-block; width: 100px;"><strong>Jackson</strong></div><div align="left" style="display: inline-block; width: 100px;">Niel</div><div align="left" style="display: inline-block; width: 40px;"><div style="display: inline; color: rgb(255,000,000)">64</div></div><div align="left" style="display: inline-block; width: 100px;">Los Angeles</div><br><div align="left" style="display: inline-block; width: 40px;">3</div><div align="left" style="display: inline-block; width: 100px;"><strong>Kennedy</strong></div><div align="left" style="display: inline-block; width: 100px;">Justin</div><div align="left" style="display: inline-block; width: 40px;"><div style="display: inline; color: rgb(255,000,000)">25</div></div><div align="left" style="display: inline-block; width: 100px;">New York</div><br><div align="left" style="display: inline-block; width: 40px;">4</div><div align="left" style="display: inline-block; width: 100px;"><strong>Obama</strong></div><div align="left" style="display: inline-block; width: 100px;">Barack</div><div align="left" style="display: inline-block; width: 40px;"><div style="display: inline; color: rgb(255,000,000)">55</div></div><div align="left" style="display: inline-block; width: 100px;">Washington</div><br><div align="left" style="display: inline-block; width: 40px;">5</div><div align="left" style="display: inline-block; width: 100px;"><strong>Smith</strong></div><div align="left" style="display: inline-block; width: 100px;">John</div><div align="left" style="display: inline-block; width: 40px;"><div style="display: inline; color: rgb(255,000,000)">24</div></div><div align="left" style="display: inline-block; width: 100px;">Baltimore</div><br><div align="left" style="display: inline-block; width: 40px;">6</div><div align="left" style="display: inline-block; width: 100px;"><strong>Trump</strong></div><div align="left" style="display: inline-block; width: 100px;">Donald</div><div align="left" style="display: inline-block; width: 40px;"><div style="display: inline; color: rgb(255,000,000)">70</div></div><div align="left" style="display: inline-block; width: 100px;">New York</div>
  674 +<br><br>
  675 +Notice that thanks to the counter <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">col</span>, we can perform a different treatment on each column.
  676 +Also remark that the first line of
  677 +the table has a number in front of it because we added a linefeed in front of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$mycsvtable</div></strong></span> within the second operand of
  678 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong></span>.
  679 +<br><br>
  680 +Now, we want to get this same text in the form of a list of lines, where each line is itself a list of values.
  681 +To this end, we define another <em>colorizer</em>.
  682 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong>(table)
  683 +<strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong>(line)
  684 + <div style="display: inline; color: rgb(000,100,000)">$// without the line below, the commas would appear on the page</div>
  685 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(parsecsv)(#,)()
  686 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(parsecsv)(#n)(<strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong>(table)(<strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong>(line))<strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong>(line))
  687 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(parsecsv)([^#n#,]+)(<strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong>(line)(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  688 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorizer</div></strong>(parsecsv)
  689 +<strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong>(parsecsv)(<strong><div style="display: inline; color: rgb(255,000,000)">$mycsvtable</div></strong>
  690 +)<br><br></pre>
  691 +
  692 +
  693 +
  694 +
  695 +
  696 +
  697 +
  698 +
  699 +
  700 +Despite the fact that we wrote <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong></span>, this doesn't produce any output because
  701 +the regular expressions cover all cases and the values in the color
  702 +rules contain only marks which produce side effects but no output.<br><br>
  703 +
  704 +So, we expect that the accumulator <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">table</span> contains our list of lists.
  705 +To check that, we define:
  706 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(putbox)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$tbgc</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$_azure</div></strong>)(<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">75</div>)(<div style="display: inline; color: rgb(255,000,255)">$1</div>)) )
  707 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(putpar)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(putbox)(<div style="display: inline; color: rgb(255,000,255)">$1</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>)<br><br></pre>
  708 +
  709 +
  710 +
  711 +
  712 +and write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(putpar)(<strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong>(table))</span>, which produces
  713 +<br><br>
  714 +<div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Ford</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Max</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">32</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">New York</div></div> <br><div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Jackson</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Niel</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">64</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Los Angeles</div></div> <br><div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Kennedy</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Justin</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">25</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">New York</div></div> <br><div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Obama</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Barack</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">55</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Washington</div></div> <br><div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Smith</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">John</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">24</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Baltimore</div></div> <br><div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Trump</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Donald</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">70</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">New York</div></div> <br>
  715 +<br>
  716 +and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(putpar)(<strong><div style="display: inline; color: rgb(255,000,000)">$transpose</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong>(table)))</span>, which produces
  717 +<br><br>
  718 +<div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Ford</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Jackson</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Kennedy</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Obama</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Smith</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Trump</div></div> <br><div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Max</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Niel</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Justin</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Barack</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">John</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Donald</div></div> <br><div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">32</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">64</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">25</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">55</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">24</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">70</div></div> <br><div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">New York</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Los Angeles</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">New York</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Washington</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">Baltimore</div></div> <div style="display: inline; background-color: rgb(190,210,210); "><div align="left" style="display: inline-block; width: 75px;">New York</div></div> <br>
  719 +<br>
  720 +This last manipulation makes even more obvious the fact that we actually got our table in the form of
  721 +a list of lists.
  722 +
  723 +
  724 +
  725 +<br><br>
  726 +<a id="tools"></a><br><big><big><strong>5. Other tools</strong></big></big><br><br>
  727 +
  728 +<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> is <em>not a programming language</em>. It is a <em>document formatting language</em>. Nevertheless, it provides some
  729 +programming capabilities, but only those which are (to our opinion) required for the needs of the layout of the
  730 +document. Of course, this set of tools could be enlarged in the future.<br><br>
  731 +
  732 +<a id="arithmetics"></a><br><big><strong>5.1. Elementary arithmetics</strong></big><br><br>
  733 +
  734 +<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> is able to perform some elementary arithmetic operations on numbers (which are all relative integers). These
  735 +operations are:
  736 +<span><ul>
  737 + <li> <div align="left" style="display: inline-block; width: 200px;"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$add</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div>)</span></div> addition of <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div> and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div>
  738 + <li> <div align="left" style="display: inline-block; width: 200px;"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$minus</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div>)</span></div> substraction of <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div> from <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div>
  739 + <li> <div align="left" style="display: inline-block; width: 200px;"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$opp</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div>)</span></div> opposite of <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div>
  740 + <li> <div align="left" style="display: inline-block; width: 200px;"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$mul</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div>)</span></div> multiplication of <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div> by <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div>
  741 + <li> <div align="left" style="display: inline-block; width: 200px;"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$quotient</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div>)</span></div> quotient of the euclidian division of <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div> by <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div>
  742 + <li> <div align="left" style="display: inline-block; width: 200px;"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$remainder</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div>)</span></div> remainder of the euclidian division of <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;m&gt;</span></strong></div> by <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div>
  743 +</ul></span>
  744 +In case of a division by zero, an error message is generated.<br><br>
  745 +
  746 +
  747 +<a id="booleans"></a><br><big><strong>5.2. Booleans and control</strong></big><br><br>
  748 +
  749 +<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> provides some rudimentary tools for better controling the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> compiler. <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> recognizes the marks <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$true</div></strong></span> and
  750 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$false</div></strong></span> as <em>truth values</em> (aka. <em>booleans</em>). Other marks also produce booleans, such as
  751 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$equals</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;expr 1&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;expr 2&gt;</span></strong></div>)</span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$defined</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;macro name&gt;</span></strong></div>)</span>.<br><br>
  752 +
  753 +These truth values can be used as <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;test&gt;</span></strong></div> in:<br><br>
  754 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;test&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if true&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if false&gt;</span></strong></div>)</span></td></tr></table></center><br>
  755 +The value of the above mark is <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if true&gt;</span></strong></div> if <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;test&gt;</span></strong></div> is true and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if false&gt;</span></strong></div> otherwise, and of course
  756 +only one of <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if true&gt;</span></strong></div> and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if false&gt;</span></strong></div> is evaluated.<br><br>
  757 +
  758 +Notice that some logical operators can be defined:
  759 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(and) (<div style="display: inline; color: rgb(160,082,045)">2</div>) (<strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>)(<div style="display: inline; color: rgb(255,000,255)">$2</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$false</div></strong>))
  760 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(or) (<div style="display: inline; color: rgb(160,082,045)">2</div>) (<strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$true</div></strong>)(<div style="display: inline; color: rgb(255,000,255)">$2</div>))
  761 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(neg) (<div style="display: inline; color: rgb(160,082,045)">1</div>) (<strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$false</div></strong>)(<strong><div style="display: inline; color: rgb(255,000,000)">$true</div></strong>))
  762 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(implies) (<div style="display: inline; color: rgb(160,082,045)">2</div>) (<strong><div style="display: inline; color: rgb(255,000,000)">$or</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$neg</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))(<div style="display: inline; color: rgb(255,000,255)">$2</div>))<br><br></pre>
  763 +
  764 +
  765 +
  766 +<a id="counters"></a><br><big><strong>5.3. Counters</strong></big><br><br>
  767 +
  768 +<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> has a notion of <em>counter</em>. You can create a counter with <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$pushcounter</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;init&gt;</span></strong></div>)</span>, where
  769 +<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> is the name of the new counter, and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;init&gt;</span></strong></div> its initial value (which must be a positive, zero or
  770 +negative integer).<br><br>
  771 +
  772 +You can get the value of a counter with <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span> (giving a character string representing
  773 +the value in decimal notation, possibly prefixed by a minus sign).
  774 +You can modify the value of a counter with <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$setcounter</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div>)</span> and
  775 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$addtocounter</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div>)</span>.<br><br>
  776 +
  777 +You can destroy a counter with <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$popcounter</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span>.<br><br>
  778 +
  779 +Actually, for each counter name, <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> manages a stack of counters. Consequently, if you create a new counter with the
  780 +same name as an already existing counter, the first counter is not destroyed and
  781 +becomes visible again when the second counter is destroyed.<br><br>
  782 +
  783 +As an exemple, consider the following:
  784 +
  785 +
  786 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$pushcounter</div></strong>(n)(<div style="display: inline; color: rgb(160,082,045)">0</div>)
  787 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(ga)(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$addtocounter</div></strong>(n)(<div style="display: inline; color: rgb(160,082,045)">1</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(n))<br><br></pre>
  788 +
  789 +
  790 +
  791 +If we write: <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong> <strong><div style="display: inline; color: rgb(255,000,000)">$ga</div></strong></span>, we get:<br><br>
  792 +<center><table style="color: inherit; font-size: inherit;"><tr><td>1 2 3 4 5 6 7 8 9 10 11 12 13</td></tr></table></center>
  793 +Continuing that way, we can write:
  794 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$pushcounter</div></strong>(n)(<div style="display: inline; color: rgb(160,082,045)">25</div>)
  795 +<strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(n)
  796 +<strong><div style="display: inline; color: rgb(255,000,000)">$popcounter</div></strong>(n)
  797 +<strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(n)<br><br></pre>
  798 +and we get:
  799 +<center><table style="color: inherit; font-size: inherit;"><tr><td>
  800 +
  801 +25
  802 +
  803 +13</td></tr></table></center>
  804 +(as expected).<br><br>
  805 +
  806 +
  807 +<a id="lists"></a><br><big><strong>5.4. Lists</strong></big><br><br>
  808 +
  809 +<strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> has a notion of <em>list</em>. In order to create a list (say with three elements <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">a</span>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">b</span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">c</span>),
  810 +you can write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">[a,b,c]</span>. If you write this outside any <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> operand, you get this:
  811 +<br><br>
  812 +[a,b,c]
  813 +<br><br>
  814 +In other words, the square brackets and the comma are just seen as ordinary (neutral) characters (and there is no list
  815 +at all in this case). On the contrary, if you write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>([a,b,c])</span>, you get this:
  816 +<br><br>
  817 +<div style="display: inline; color: rgb(255,000,000)">abc</div>
  818 +<br><br>
  819 +This is first of all because the square brackets and the comma are recognized as special characters within an operand
  820 +(so that we now have an actual list), and because the rendering of a list consists in rendering its element one after the
  821 +other without any separator between them. Nevertheless, if we want to render the above list in red with the brackets
  822 +and the commas, it is enough to write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$[</div></strong>a<strong><div style="display: inline; color: rgb(255,000,000)">$,</div></strong>b<strong><div style="display: inline; color: rgb(255,000,000)">$,</div></strong>c<strong><div style="display: inline; color: rgb(255,000,000)">$]</div></strong>)</span>:
  823 +<br><br>
  824 +<div style="display: inline; color: rgb(255,000,000)">[a,b,c]</div>
  825 +<br><br>
  826 +
  827 +The square brackets and the comma, everywhere they are recognized as special characters <em>eat</em> the spaces on both
  828 +sides. This means that it is equivalent to write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>([a,b,c])</span> and to write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>( [ a, b , c
  829 +] )</span>. However, be careful because an expression such as <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>([a,b,c])</span> is <em>not</em> a list and triggers
  830 +an error if written at a place where a list is required.<br><br>
  831 +
  832 +List are useful because they can be manipulated by several primitive marks, such as:
  833 +<span><ul>
  834 + <li> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><a rel="tag" href="#reverse">$reverse</a>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span>
  835 + <li> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><a rel="tag" href="#sort">$sort</a>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span>
  836 + <li> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><a rel="tag" href="#length">$length</a>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span>
  837 + <li> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><a rel="tag" href="#sublist">$sublist</a>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;start&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;end&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span>
  838 + <li> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><a rel="tag" href="#apply">$apply</a>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;mark name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span>
  839 + <li> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><a rel="tag" href="#transpose">$transpose</a>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list of lists&gt;</span></strong></div>)</span>
  840 +</ul></span>
  841 +How these primitives marks operate is explained in the <a rel="tag" href="#catalog">catalog</a>.<br><br>
  842 +
  843 +There are circumstances where we want the square brackets and the comma to be considered as ordinary (neutral)
  844 +characters. For example, it should be the case for the second operand of
  845 +<a rel="tag" href="#code"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;color&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;computer code&gt;</span></strong></div>)</span></a>, and also in some operands of some other primitives.
  846 +To simplify the matter and to offer the maximal number of possibilities, primitives such as <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong></span> don't care
  847 +about that. This is why we propose the primitive <a rel="tag" href="#nolist"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$nolist</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></a> which inhibits the
  848 +recognition of the squares brackets and the comma within <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>. Hence, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong></span> should be used as follows:
  849 +<br><br>
  850 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;color&gt;</span></strong></div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$nolist</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;computer code&gt;</span></strong></div>))</span></td></tr></table></center>
  851 +<br>
  852 +and you can define a macro for handling this.<br><br>
  853 +
  854 +As an example, consider the following list of words:
  855 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(cities)(<div style="display: inline; color: rgb(160,082,045)">0</div>)
  856 + ([New York,Paris,Berlin,Moscow,Casablanca,Cairo,Athens,Rio de Janeiro])<br><br></pre>
  857 +
  858 +
  859 +We can write:
  860 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$pushcounter</div></strong>(n)(<div style="display: inline; color: rgb(160,082,045)">0</div>)
  861 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(number)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$addtocounter</div></strong>(n)(<div style="display: inline; color: rgb(160,082,045)">1</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">20</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(n).)<div style="display: inline; color: rgb(255,000,255)">$1</div><strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>)
  862 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(a)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$alphabetic</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  863 +<strong><div style="display: inline; color: rgb(255,000,000)">$center</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(number)(<strong><div style="display: inline; color: rgb(255,000,000)">$sort</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(a)(<strong><div style="display: inline; color: rgb(255,000,000)">$cities</div></strong>))))<br><br></pre>
  864 +which gives this:
  865 +
  866 +
  867 +
  868 +<center><table style="color: inherit; font-size: inherit;"><tr><td><div align="left" style="display: inline-block; width: 20px;">1.</div>Athens<br><div align="left" style="display: inline-block; width: 20px;">2.</div>Berlin<br><div align="left" style="display: inline-block; width: 20px;">3.</div>Cairo<br><div align="left" style="display: inline-block; width: 20px;">4.</div>Casablanca<br><div align="left" style="display: inline-block; width: 20px;">5.</div>Moscow<br><div align="left" style="display: inline-block; width: 20px;">6.</div>New York<br><div align="left" style="display: inline-block; width: 20px;">7.</div>Paris<br><div align="left" style="display: inline-block; width: 20px;">8.</div>Rio de Janeiro<br></td></tr></table></center>
  869 +
  870 +<br><br>
  871 +
  872 +
  873 +<a id="tips"></a><br><big><big><strong>6. Tips and tricks</strong></big></big><br><br>
  874 +
  875 +If your text needs to display some computer code, it can be the case (depending on the programming language)
  876 +that this code uses dollar characters. This is the case of Anubis for example, since dollars are used by
  877 +type parameters. These dollars can make a problem since the dollar is also the escape character of <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>.<br><br>
  878 +
  879 +You can of course double the dollars in the computer text examples, but there are situations where we don't want to
  880 +do this, or just cannot do this. This is the case for example in the Anubis library, since some files are at the
  881 +same time <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> files (compilable by <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>), and Anubis file (compilable by <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">anubis</span>). In this case, we cannot
  882 +change anything to the text, and in particular, we cannot double the dollars. <br><br>
  883 +
  884 +A solution, assuming for example that there are two type parameters <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$T</div></strong></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$U</div></strong></span> in the Anubis text, is to
  885 +define two macros:
  886 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(T)(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$$</div></strong>T)
  887 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(U)(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$$</div></strong>U)<br><br></pre>
  888 +so that the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> compiler will not be disturbed by these type parameters, which is rendered correctly.
  889 +Since this doesn't change anything in the
  890 +Anubis text itself (the above <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span> should be outside any Anubis paragraph), this doesn't change anything from the point
  891 +of view of the Anubis compiler. This trick can of course be applied to other programming languages.<br><br>
  892 +
  893 +
  894 +<a id="commonerrors"></a><br><big><strong>6.1. Common errors</strong></big><br><br>
  895 +
  896 +Below are most of the errors the author made himself during the writting of this tutorial.
  897 +<span><ul>
  898 +
  899 + <li> Thinking that <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tbgc</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$_red</div></strong>)(<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">100</div>)())</span> produces a red rectangle of the given width
  900 + (with no text at all into it).
  901 + This actually produces a white rectangle. In order
  902 + to get this red rectangle, you need to write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tbgc</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$_red</div></strong>)(<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">100</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$sp</div></strong>))</span> (recall that <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sp</div></strong></span> is
  903 + the so-called <em>non breakable space</em>).<br><br>
  904 +
  905 + <li> Using <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$blahblah</div></strong></span> instead of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$$</div></strong>blahblah</span>, i.e. forgetting to double the dollar when we want to render a dollar
  906 + character (or the contrary).<br><br>
  907 +
  908 + <li> Writing <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">#$//.*</span> instead of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">#$#/#/.*</span> as a regular expression in order to colorize <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> line comments.
  909 + Of course, the first form <em>is seen</em> as the beginning of a line comment, and the final result is quite surprising.
  910 +</ul></span>
  911 +
  912 +
  913 +<a id="toolsbasis"></a><br><big><big><strong>7. Tools available in <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div></strong></big></big><br><br>
  914 +
  915 +This <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> file provides some tools of common usage. In order to use these tools, you must write
  916 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong>(basis.maml)</span></td></tr></table></center><br>
  917 +after the first <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span>, but some tools require that you define a macro before this <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong></span>.<br><br>
  918 +
  919 +Some of the macros defined in this file can be redefined easily from within your source text. If this is not enough for
  920 +your needs, you still have the possibility to use a customized copy of <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div>.<br><br>
  921 +
  922 +
  923 +<a id="colors"></a><br><big><strong>7.1. Colors</strong></big><br><br>
  924 +
  925 +The file <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div> provides a small selection of colors in the form of macros taking zero operand. These macros are to be used
  926 +within the first operand of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong></span>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tbgc</div></strong></span>, i.e. at a place where a color value in the
  927 +form <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">r,g,b</span> is expected.<br><br>
  928 +
  929 +
  930 +
  931 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_azure</div><div style="display: inline; background-color: rgb(190,210,210); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  932 +
  933 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_black</div><div style="display: inline; background-color: rgb(000,000,000); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  934 +
  935 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_blue</div><div style="display: inline; background-color: rgb(000,000,255); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  936 +<br>
  937 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_caramel</div><div style="display: inline; background-color: rgb(210,105,030); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  938 +
  939 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_chocolate</div><div style="display: inline; background-color: rgb(105,055,020); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  940 +
  941 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_cyan</div><div style="display: inline; background-color: rgb(000,255,255); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  942 +<br>
  943 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_darkgreen</div><div style="display: inline; background-color: rgb(000,100,000); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  944 +
  945 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_gold</div><div style="display: inline; background-color: rgb(255,195,000); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  946 +
  947 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_green</div><div style="display: inline; background-color: rgb(000,255,000); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  948 +<br>
  949 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_grey</div><div style="display: inline; background-color: rgb(190,190,190); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  950 +
  951 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_ivory</div><div style="display: inline; background-color: rgb(230,230,210); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  952 +
  953 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_lavender</div><div style="display: inline; background-color: rgb(200,200,220); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  954 +<br>
  955 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_magenta</div><div style="display: inline; background-color: rgb(255,000,255); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  956 +
  957 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_navy</div><div style="display: inline; background-color: rgb(000,000,128); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  958 +
  959 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_orange</div><div style="display: inline; background-color: rgb(255,165,000); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  960 +<br>
  961 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_pink</div><div style="display: inline; background-color: rgb(255,182,193); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  962 +
  963 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_purple</div><div style="display: inline; background-color: rgb(160,032,240); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  964 +
  965 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_red</div><div style="display: inline; background-color: rgb(255,000,000); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  966 +<br>
  967 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_darkred</div><div style="display: inline; background-color: rgb(110,000,000); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  968 +
  969 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_salmon</div><div style="display: inline; background-color: rgb(233,150,122); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  970 +
  971 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_sienna</div><div style="display: inline; background-color: rgb(160,082,045); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  972 +<br>
  973 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_turquoise</div><div style="display: inline; background-color: rgb(064,224,208); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  974 +
  975 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_white</div><div style="display: inline; background-color: rgb(255,255,255); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  976 +
  977 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 100px;">$_yellow</div><div style="display: inline; background-color: rgb(255,255,000); ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div align="left" style="display: inline-block; width: 20px;"></div>
  978 +<br>
  979 +
  980 +
  981 +<br><br>
  982 +The file also provide macros with the same name, but without the leading underscore,
  983 +taking one operand for directly colorizing texts. For example <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(...)</span> is
  984 +equivalent to <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$_red</div></strong>)(...)</span>.<br><br>
  985 +
  986 +<a id="stylearticle"></a><br><big><strong>7.2. The style <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">article</span></strong></big><br><br>
  987 +
  988 +This <em>style</em> provides definitions for the marks <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$section</div></strong></span>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$subsection</div></strong></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$subsubsection</div></strong></span> (which
  989 +are not primitive marks), and also defines a mark <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tableofcontents</div></strong></span>.<br><br>
  990 +
  991 +<a id="_"></a><br><strong>7.2.1. How to use it</strong><br>
  992 +
  993 +In order to use this style, you must write:<br><br>
  994 +<center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(article)(<div style="display: inline; color: rgb(160,082,045)">0</div>)()</span></td></tr></table></center><br>
  995 +<em>before</em> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong>(basis.maml)</span>, because the style is conditionned by a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$defined</div></strong>(article))...</span>
  996 +within <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div>.<br><br>
  997 +
  998 +The marks <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$section</div></strong></span>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$subsection</div></strong></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$subsubsection</div></strong></span> take two operands. The first one must be a
  999 +symbol
  1000 +which is the symbolic name you want to give to the section (it is used
  1001 +for generating internal links, but you can also refer to the section with a <a rel="tag" href="#ref"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$ref</div></strong>(...)(...)</span></a>).
  1002 +The second one is the title of the section.<br><br>
  1003 +
  1004 +The mark
  1005 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tableofcontents</div></strong></span> produces a table of contents and can be written anywhere because it contains a
  1006 +<a rel="tag" href="#postpone"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$postpone</div></strong></span></a>,
  1007 +so that it provides a complete table of contents regardless of its position in your source text.<br><br>
  1008 +
  1009 +<a id="_"></a><br><strong>7.2.2. Customizing <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">article</span></strong><br>
  1010 +
  1011 +The lines of the table of contents are displayed by the marks <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tocsec</div></strong></span>,
  1012 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tocsubsec</div></strong></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tocsubsubsec</div></strong></span>. If you are not satisfied with the layout provided by these marks, you can
  1013 +define your own versions, provided that you write your definitions <em>before</em> <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong>(basis.maml)</span>. These marks take only one
  1014 +operand which is the line to be displayed. For example, you can define:<br>
  1015 +<br><center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(tocsec)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong><strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>)</span></td></tr></table></center><br>
  1016 +This will replace the default definition provided by <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div>. This may be useful for example to redefine
  1017 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tocsubsubsec</div></strong></span> if you have
  1018 +subsubsections in your text and don't want them to appear in the table of contents.<br><br>
  1019 +
  1020 +The same is true for the marks <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$seclayout</div></strong></span>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$subseclayout</div></strong></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$subsubseclayout</div></strong></span>, which define the
  1021 +layout of the section titles themselves. These marks take one operand which is the title itself.<br><br>
  1022 +
  1023 +<a id="book"></a><br><big><strong>7.3. The style <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">book</span></strong></big><br><br>
  1024 +
  1025 +This style is the same as article, except that it also has a notion of chapter. Hence, it also defines the mark
  1026 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$chapter</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;symbolic name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;title&gt;</span></strong></div>)</span>, and you can redefine the marks
  1027 +<span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tocchap</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;title&gt;</span></strong></div>)</span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$chaplayout</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;title&gt;</span></strong></div>)</span>.<br><br>
  1028 +
  1029 +
  1030 +
  1031 +
  1032 +<a id="catalog"></a><br><big><big><strong>8. The catalog of <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks</strong></big></big><br><br>
  1033 +
  1034 +Below is a description of the 60 primitive <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks.<br><br>
  1035 +<div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#accumulator"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#addtocounter"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$addtocounter</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#append"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#apply"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#begin"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#big"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#bold"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#box"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#center"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$center</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#code"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#colorize"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#colorizer"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorizer</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#colorizercall"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorizercall</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#colorrule"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#content"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#countervalue"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#define"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#defined"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$defined</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#end"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#equals"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$equals</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#false"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$false</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#if"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#ifhtml"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$ifhtml</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#ifpdf"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$ifpdf</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#image"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$image</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#input"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#italic"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$italic</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#item"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$item</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#label"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$label</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#latex"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$latex</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#length"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$length</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#list"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$list</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#lpar"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$lpar</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#mailto"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$mailto</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#nolist"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$nolist</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#note"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$note</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#nth"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$nth</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#output"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$output</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#par"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#popcounter"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$popcounter</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#postpone"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$postpone</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#pushcounter"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$pushcounter</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#ref"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$ref</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#reverse"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$reverse</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#rgb"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#rpar"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rpar</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#setcounter"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$setcounter</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#sort"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sort</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#sp"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sp</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#sub"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sub</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#sublist"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sublist</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#sup"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sup</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#tbgc"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tbgc</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#thisfilepath"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$thisfilepath</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#tlink"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tlink</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#transpose"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$transpose</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#true"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$true</div></strong></span></a></div><br><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#tt"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tt</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#undefine"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$undefine</div></strong></span></a></div><div align="left" style="display: inline-block; width: 20px;"></div><div align="left" style="display: inline-block; width: 120px;"><a rel="tag" href="#verbatim"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$verbatim</div></strong></span></a></div>
  1036 +
  1037 +
  1038 + <a id="accumulator"></a><br><br><strong>8.1. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span></div></strong><br><br>
  1039 + This mark creates a <em>variable</em> named <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> called an <em>accumulator</em>.
  1040 + The content of an accumulator is always a list, and this list is empty when the accumulator is created. With the mark
  1041 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong></span>, you can add content to the accumulator. Each use of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong></span> adds an element to end of the list
  1042 + contained in the accumulator. At any time, you can get the content of the accumulator with <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong></span>.<br><br>
  1043 +
  1044 + An accumulator cannot be destroyed, but it can be reinitialized. Indeed, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span> empties the
  1045 + accumulator if it already exists, and puts the empty list in it. Unlike counters and macros, there is no stack associated to an
  1046 + accumulator name. For example:
  1047 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong>(acc)
  1048 +<strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong>(acc)(A)
  1049 +<strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong>(acc)(B)
  1050 +<strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong>(acc)
  1051 +<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>
  1052 +<strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong>(acc)
  1053 +<strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong>(acc)(C)
  1054 +<strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong>(acc)<br><br></pre>
  1055 + produces:
  1056 + <br><br>
  1057 +
  1058 +
  1059 +
  1060 + AB
  1061 + <br>
  1062 +
  1063 +
  1064 + C
  1065 + <br><br>
  1066 + Accumulators can be used in conjunction with <a rel="tag" href="#postpone"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$postpone</div></strong></span></a> for constructing
  1067 + tables of content and indexes.
  1068 + See also <a rel="tag" href="#append"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong></span></a> and <a rel="tag" href="#content"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong></span></a>.
  1069 +
  1070 + <a id="addtocounter"></a><br><br><strong>8.2. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$addtocounter</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div>)</span></div></strong><br><br>
  1071 + This marks adds <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div> to the most recent instance of the counter whose name is <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>.
  1072 +
  1073 + <a id="append"></a><br><br><strong>8.3. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br>
  1074 + This mark appends <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> at the end of the content of the <a rel="tag" href="#accumulator">accumulator</a> <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>. More
  1075 + precisely, since the content of an accumulator is a list, the new content of the accumulator is the list obtained
  1076 + by adding <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> as the last element of this list.
  1077 + See also <a rel="tag" href="#accumulator"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong></span></a> and <a rel="tag" href="#content"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong></span></a>.
  1078 +
  1079 + <a id="apply"></a><br><br><strong>8.4. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span></div></strong><br><br>
  1080 + This mark applies the macro whose name is <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> to all elements of the list <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>. This creates a new list
  1081 + of the same length. If <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div> is not a list, the result is the same as if it was a one element list.<br><br>
  1082 +
  1083 + Notice that the first operand is the name of the macro to applied, but <em>without the leading <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">$</span></em>. In other words, this
  1084 + operand is not the macro to apply but only its name. The corresponding macro must take just one operand. If not, an
  1085 + error message is generated.<br><br>
  1086 +
  1087 + Furthermore, the macro to be applied must take a unique operand, and notice that <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> cannot be the name of
  1088 + a primitive mark. It <em>must</em> be the name of a macro. Hence, if you want to apply a primitive mark, you must first
  1089 + define an equivalent macro.<br><br>
  1090 +
  1091 + As an example, consider the following:
  1092 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(mylist)(<div style="display: inline; color: rgb(160,082,045)">0</div>)([a,b,c,d])
  1093 +<strong><div style="display: inline; color: rgb(255,000,000)">$mylist</div></strong><strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>
  1094 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(a)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(&lt;<strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>)&gt;)
  1095 +<strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(a)(<strong><div style="display: inline; color: rgb(255,000,000)">$mylist</div></strong>)<br><br></pre>
  1096 +which produces:<br><br>
  1097 +
  1098 +
  1099 +abcd<br>
  1100 +
  1101 +&lt;<div style="display: inline; color: rgb(255,000,000)">a</div>&gt;&lt;<div style="display: inline; color: rgb(255,000,000)">b</div>&gt;&lt;<div style="display: inline; color: rgb(255,000,000)">c</div>&gt;&lt;<div style="display: inline; color: rgb(255,000,000)">d</div>&gt;
  1102 +<br><br>
  1103 + See also <a rel="tag" href="#box"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong></span></a> for a more sophisticated example.
  1104 +
  1105 +
  1106 + <a id="begin"></a><br><br><strong>8.5. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span></div></strong><br><br> This mark is looked for by <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> before it parses anything (even within a file refered to by
  1107 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong></span>). When <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span> is found, <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> parses the text until it
  1108 + encounters the mark <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong></span>. After this mark, <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> continues ignoring everything until the next <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span>,
  1109 + etc... <br><br>
  1110 +
  1111 + Notice that this mecanism can also be used for inserting a comment:
  1112 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong>
  1113 + ... your comment ...
  1114 +<strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong><br><br></pre>
  1115 +
  1116 + <a id="big"></a><br><br><strong>8.6. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> Prints its operand <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> bigger. This mark can be nested. For example,
  1117 + <span><ul>
  1118 + <li> <div align="left" style="display: inline-block; width: 200px;"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(text)</span></div> produces <big>text</big>
  1119 + <li> <div align="left" style="display: inline-block; width: 200px;"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(text))</span></div> produces <big><big>text</big></big>
  1120 + <li> <div align="left" style="display: inline-block; width: 200px;"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(text)))</span></div> produces <big><big><big>text</big></big></big>
  1121 + </ul></span>
  1122 +
  1123 +
  1124 + <a id="bold"></a><br><br><strong>8.7. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> The operand is rendered in <strong>bold</strong>.
  1125 +
  1126 + <a id="box"></a><br><br><strong>8.8. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;width&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This mark puts <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> into an invisible box of width <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;width&gt;</span></strong></div>. The text is left aligned
  1127 + within the box. This mark can be used for simulating tabulators. For example,
  1128 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(tableline)(<div style="display: inline; color: rgb(160,082,045)">4</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">50</div>)(<div style="display: inline; color: rgb(255,000,255)">$1</div>) <strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">50</div>)(<div style="display: inline; color: rgb(255,000,255)">$2</div>) <strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">30</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$3</div>)) <div style="display: inline; color: rgb(255,000,255)">$4</div> <strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>)
  1129 +
  1130 +<strong><div style="display: inline; color: rgb(255,000,000)">$tableline</div></strong>(Smith)(John)(<div style="display: inline; color: rgb(160,082,045)">24</div>)(Baltimore)
  1131 +<strong><div style="display: inline; color: rgb(255,000,000)">$tableline</div></strong>(Ford) (Max) (<div style="display: inline; color: rgb(160,082,045)">32</div>)(New York)<br><br></pre>
  1132 + produces:<br><br>
  1133 +
  1134 + <div align="left" style="display: inline-block; width: 50px;">Smith</div> <div align="left" style="display: inline-block; width: 50px;">John</div> <div align="left" style="display: inline-block; width: 30px;"><div style="display: inline; color: rgb(255,000,000)">24</div></div> Baltimore <br>
  1135 + <div align="left" style="display: inline-block; width: 50px;">Ford</div> <div align="left" style="display: inline-block; width: 50px;">Max</div> <div align="left" style="display: inline-block; width: 30px;"><div style="display: inline; color: rgb(255,000,000)">32</div></div> New York <br>
  1136 + <br>
  1137 +
  1138 + <a id="colortableexample"></a>
  1139 + As an example, here is something more sophisticated. We construct a table similar to the table above,
  1140 + but we want it to be automatically sorted by the last names (first column) and to be in pajama stripes,
  1141 + in other words, so that odd numbered lines
  1142 + are shown on a different background color than even numbered lines. It is clear that the background color
  1143 + cannot be decided before the list is sorted, so that, after the list is sorted, we have to apply a macro
  1144 + to each element of the list. This is why we need to use the primitive mark <a rel="tag" href="#apply"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong></span></a>.
  1145 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br> <div style="display: inline; color: rgb(000,100,000)">$// we first create a counter that we use as a flag </div>
  1146 + <div style="display: inline; color: rgb(000,100,000)">$// (taking the values 0 and 1 only)</div>
  1147 +<strong><div style="display: inline; color: rgb(255,000,000)">$pushcounter</div></strong>(flag)(<div style="display: inline; color: rgb(160,082,045)">0</div>)
  1148 + <div style="display: inline; color: rgb(000,100,000)">$// we define a color depending on the value of the flag </div>
  1149 + <div style="display: inline; color: rgb(000,100,000)">$// and flipflopping the flag at each use</div>
  1150 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(linecolor)(<div style="display: inline; color: rgb(160,082,045)">0</div>)
  1151 + (<strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$equals</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(flag)))
  1152 + (<strong><div style="display: inline; color: rgb(255,000,000)">$setcounter</div></strong>(flag)(<div style="display: inline; color: rgb(160,082,045)">1</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$_lavender</div></strong>)
  1153 + (<strong><div style="display: inline; color: rgb(255,000,000)">$setcounter</div></strong>(flag)(<div style="display: inline; color: rgb(160,082,045)">0</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$_ivory</div></strong>))
  1154 + <div style="display: inline; color: rgb(000,100,000)">$// define the layout of a line of the table, and put an '$alphabetic' in order</div>
  1155 + <div style="display: inline; color: rgb(000,100,000)">$// to tell MAML how to sort lines</div>
  1156 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(tableline)(<div style="display: inline; color: rgb(160,082,045)">4</div>)
  1157 + (<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">80</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$alphabetic</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">80</div>)(<div style="display: inline; color: rgb(255,000,255)">$2</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">50</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$3</div>))<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">80</div>)(<div style="display: inline; color: rgb(255,000,255)">$4</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>)
  1158 + <div style="display: inline; color: rgb(000,100,000)">$// define a macro for putting a backgroud color behind a line</div>
  1159 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(putbg)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$tbgc</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$linecolor</div></strong>)(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  1160 + <div style="display: inline; color: rgb(000,100,000)">$// sort the lines and apply this macro to each line</div>
  1161 +<strong><div style="display: inline; color: rgb(255,000,000)">$center</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(putbg)(<strong><div style="display: inline; color: rgb(255,000,000)">$sort</div></strong>(
  1162 +[<strong><div style="display: inline; color: rgb(255,000,000)">$tableline</div></strong>(Smith)(John)(<div style="display: inline; color: rgb(160,082,045)">24</div>)(Baltimore),
  1163 + <strong><div style="display: inline; color: rgb(255,000,000)">$tableline</div></strong>(Ford) (Max) (<div style="display: inline; color: rgb(160,082,045)">32</div>)(New York),
  1164 + <strong><div style="display: inline; color: rgb(255,000,000)">$tableline</div></strong>(Jackson)(Niel)(<div style="display: inline; color: rgb(160,082,045)">64</div>)(Los Angeles),
  1165 + <strong><div style="display: inline; color: rgb(255,000,000)">$tableline</div></strong>(Kennedy) (Justin) (<div style="display: inline; color: rgb(160,082,045)">25</div>)(New York),
  1166 + <strong><div style="display: inline; color: rgb(255,000,000)">$tableline</div></strong>(Trump)(Donald)(<div style="display: inline; color: rgb(160,082,045)">70</div>)(New York),
  1167 + <strong><div style="display: inline; color: rgb(255,000,000)">$tableline</div></strong>(Obama) (Barack)(<div style="display: inline; color: rgb(160,082,045)">55</div>)(Washington)]
  1168 +)))<br><br></pre>
  1169 +
  1170 +
  1171 +
  1172 +
  1173 +
  1174 +
  1175 +<center><table style="color: inherit; font-size: inherit;"><tr><td><div style="display: inline; background-color: rgb(200,200,220); "><div align="left" style="display: inline-block; width: 80px;">Ford</div><div align="left" style="display: inline-block; width: 80px;">Max</div><div align="left" style="display: inline-block; width: 50px;"><div style="display: inline; color: rgb(255,000,000)">32</div></div><div align="left" style="display: inline-block; width: 80px;">New York</div><br></div><div style="display: inline; background-color: rgb(230,230,210); "><div align="left" style="display: inline-block; width: 80px;">Jackson</div><div align="left" style="display: inline-block; width: 80px;">Niel</div><div align="left" style="display: inline-block; width: 50px;"><div style="display: inline; color: rgb(255,000,000)">64</div></div><div align="left" style="display: inline-block; width: 80px;">Los Angeles</div><br></div><div style="display: inline; background-color: rgb(200,200,220); "><div align="left" style="display: inline-block; width: 80px;">Kennedy</div><div align="left" style="display: inline-block; width: 80px;">Justin</div><div align="left" style="display: inline-block; width: 50px;"><div style="display: inline; color: rgb(255,000,000)">25</div></div><div align="left" style="display: inline-block; width: 80px;">New York</div><br></div><div style="display: inline; background-color: rgb(230,230,210); "><div align="left" style="display: inline-block; width: 80px;">Obama</div><div align="left" style="display: inline-block; width: 80px;">Barack</div><div align="left" style="display: inline-block; width: 50px;"><div style="display: inline; color: rgb(255,000,000)">55</div></div><div align="left" style="display: inline-block; width: 80px;">Washington</div><br></div><div style="display: inline; background-color: rgb(200,200,220); "><div align="left" style="display: inline-block; width: 80px;">Smith</div><div align="left" style="display: inline-block; width: 80px;">John</div><div align="left" style="display: inline-block; width: 50px;"><div style="display: inline; color: rgb(255,000,000)">24</div></div><div align="left" style="display: inline-block; width: 80px;">Baltimore</div><br></div><div style="display: inline; background-color: rgb(230,230,210); "><div align="left" style="display: inline-block; width: 80px;">Trump</div><div align="left" style="display: inline-block; width: 80px;">Donald</div><div align="left" style="display: inline-block; width: 50px;"><div style="display: inline; color: rgb(255,000,000)">70</div></div><div align="left" style="display: inline-block; width: 80px;">New York</div><br></div></td></tr></table></center>
  1176 +<br><br>
  1177 +The macro <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$pajamatable</div></strong></span> defined in <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div> realises such a table and accepts the data in the form of a
  1178 +list of lists.
  1179 +
  1180 + <a id="center"></a><br><br><strong>8.9. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$center</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This mark horizontally centers the <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> in the page. For example,
  1181 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$center</div></strong>(centered text)</span> produces:<br>
  1182 + <br><center><table style="color: inherit; font-size: inherit;"><tr><td>centered text</td></tr></table></center><br>
  1183 +
  1184 + <a id="code"></a><br><br><strong>8.10. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;background color&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This marks is for writing computer code.
  1185 + The <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> operand is formated using a fixed width
  1186 + (typewriter) font, spaces and newlines are taken into account, so that the result has essentially the same layout as the
  1187 + original. Nevertheless, <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks are allowed within <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>, but some of them, such as <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$list</div></strong></span>,
  1188 + can produce incoherent results. For example,
  1189 + <br>
  1190 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(T)(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$$</div></strong>T) <div style="display: inline; color: rgb(000,100,000)">$// so that MAML is not troubled by $T</div>
  1191 +<strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$_lavender</div></strong>)(<strong><div style="display: inline; color: rgb(255,000,000)">$nolist</div></strong>(<div style="display: inline; color: rgb(000,000,000)">
  1192 +define Int
  1193 + length
  1194 + (
  1195 + List($T) l
  1196 + ) =
  1197 + if l is
  1198 + {
  1199 + [ ] then 0, // the list is empty
  1200 + [h . t] then 1+length(t)
  1201 + }.</div>
  1202 +<strong><div style="display: inline; color: rgb(255,000,000)">$undefine</div></strong>(T)))<br><br></pre>
  1203 + produces:
  1204 +
  1205 + <pre style="color: inherit; font-size: inherit; background-color: rgb(200,200,220); width: 600px;">define Int
  1206 + length
  1207 + (
  1208 + List($T) l
  1209 + ) =
  1210 + if l is
  1211 + {
  1212 + [ ] then 0, // the list is empty
  1213 + [h . t] then 1+length(t)
  1214 + }.</pre>
  1215 +
  1216 + (You can also use a <a rel="tag" href="#colorize">colorizer</a> for colorizing the code.)
  1217 + <br><br>
  1218 + See also <a rel="tag" href="#tt"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tt</div></strong>(...)</span></a> and <a rel="tag" href="#verbatim"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$verbatim</div></strong>(...)</span></a>
  1219 +
  1220 + <a id="colorize"></a><br><br><strong>8.11. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> See <a rel="tag" href="#colorize">Automatic colorization</a>.
  1221 + <a id="colorizer"></a><br><br><strong>8.12. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorizer</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span></div></strong><br><br> See <a rel="tag" href="#colorize">Automatic colorization</a>.
  1222 + <a id="colorizercall"></a><br><br><strong>8.13. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorizercall</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;regexpr&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;regexpr&gt;</span></strong></div>)</span></div></strong><br><br> See <a rel="tag" href="#colorize">Automatic colorization</a>.
  1223 + <a id="colorrule"></a><br><br><strong>8.14. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$colorrule</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;regexpr&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> See <a rel="tag" href="#colorize">Automatic colorization</a>.
  1224 +
  1225 + <a id="content"></a><br><br><strong>8.15. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span></div></strong><br><br>
  1226 + The value of this mark is the content of the <a rel="tag" href="#accumulator">accumulator</a> <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>. Recall that this content
  1227 + is a list. See also <a rel="tag" href="#accumulator"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong></span></a> and <a rel="tag" href="#append"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong></span></a>.
  1228 +
  1229 + <a id="countervalue"></a><br><br><strong>8.16. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span></div></strong><br><br>
  1230 + This mark produces the value of the counter <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> in decimal notation. See <a rel="tag" href="#counters">Counters</a>.
  1231 +
  1232 + <a id="define"></a><br><br><strong>8.17. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;number of operands&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div>)</span></div></strong><br><br>
  1233 + This mark let you define new marks (i.e. <em>macros</em>). It takes three operands. The first operand <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>
  1234 + is the name of the new mark. If it is
  1235 + already in use, the new definition masks the previous one until you use an <a rel="tag" href="#undefine"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$undefine</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span></a>.
  1236 + The name must be made only of letters <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">A...Z</span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">a...z</span>, decimal digits <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(160,082,045)">0</div>...<div style="display: inline; color: rgb(160,082,045)">9</div></span> and
  1237 + the underscore character, and must
  1238 + not begin by a digit. The second operand <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;number of operands&gt;</span></strong></div> is the number of operands your new mark will accept.
  1239 + It must
  1240 + be a positive or zero integer. The last operand <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div> is the value of the mark. This is a <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> text, and it can
  1241 + contain marks of the form <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(255,000,255)">$1</div></span>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(255,000,255)">$2</div></span>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(255,000,255)">$3</div></span>, ... (called <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> <em>variables</em>) which represent the operands
  1242 + of the mark, and which will later be replaced by the actual operands when the mark is used in the text.<br><br>
  1243 +
  1244 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span> doesn't allow to define recursive macros. Nevertheless,
  1245 + see <a rel="tag" href="#undefine"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$undefine</div></strong></span></a> where more explanations are given on the behavior of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span>.
  1246 +
  1247 +
  1248 + <a id="defined"></a><br><br><strong>8.18. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$defined</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span></div></strong><br><br>
  1249 + This mark has a boolean value which is <em>true</em> if a macro is defined with name <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> and <em>false</em>
  1250 + otherwise.
  1251 +
  1252 + <a id="end"></a><br><br><strong>8.19. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong></span></div></strong><br><br> This mark indicates that the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> compiler should stop parsing until the next <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span> (or the end
  1253 + of file). See <a rel="tag" href="#begin"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span></a>.
  1254 +
  1255 + <a id="equals"></a><br><br><strong>8.20. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$equals</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;expr 1&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;expr 2&gt;</span></strong></div>)</span></div></strong><br><br>
  1256 + This mark has a boolean value which is <em>true</em> if <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;expr 1&gt;</span></strong></div> and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;expr 2&gt;</span></strong></div> are equal. By <em>equal</em>, we
  1257 + mean identical after <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;expr 1&gt;</span></strong></div> and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;expr 2&gt;</span></strong></div> are computed.
  1258 +
  1259 + <a id="false"></a><br><br><strong>8.21. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$false</div></strong></span></div></strong><br><br> This mark represents the truth value <em>false</em>.
  1260 +
  1261 + <a id="if"></a><br><br><strong>8.22. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;test&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if true&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if false&gt;</span></strong></div>)</span></div></strong><br><br>
  1262 + This mark represents <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if true&gt;</span></strong></div> if <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;test&gt;</span></strong></div> is true, and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if false&gt;</span></strong></div> otherwise. Only one of
  1263 + <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if true&gt;</span></strong></div> and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;if false&gt;</span></strong></div> is evaluated.
  1264 +
  1265 + <a id="ifhtml"></a><br><br><strong>8.23. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$ifhtml</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> The operand <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> is present in the HTML output, but not in the <img src="png/fNScTnBA4MH-qH_w0pRfArXeeKE8.png" width="36" height="14" style="vertical-align: -3px"> nor in the PDF
  1266 + output.
  1267 +
  1268 + <a id="ifpdf"></a><br><br><strong>8.24. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$ifpdf</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> The operand <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> is present in the <img src="png/fNScTnBA4MH-qH_w0pRfArXeeKE8.png" width="36" height="14" style="vertical-align: -3px"> and in the PDF
  1269 + output, but not in the HTML output.
  1270 +
  1271 + <a id="image"></a><br><br><strong>8.25. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$image</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;width&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;file path&gt;</span></strong></div>)</span></div></strong><br><br>
  1272 + This mark inserts an image in the text. The operand <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;width&gt;</span></strong></div> is the width the image will have
  1273 + when displayed (in pixels in the case of HTML, and points in the case of <img src="png/fNScTnBA4MH-qH_w0pRfArXeeKE8.png" width="36" height="14" style="vertical-align: -3px">), and <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;file path&gt;</span></strong></div> is the path of the file
  1274 + containing the image. For example,
  1275 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$center</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$image</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$ifpdf</div></strong>(<div style="display: inline; color: rgb(160,082,045)">100</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$ifhtml</div></strong>(<div style="display: inline; color: rgb(160,082,045)">200</div>))(<strong><div style="display: inline; color: rgb(255,000,000)">$id</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$thisfilepath</div></strong>)/cows.jpg))<br><br></pre>
  1276 + produces:
  1277 + <br><center><table style="color: inherit; font-size: inherit;"><tr><td><img src="/home/alp/amoi/Anubis1/anubis_dev/library/doc_tools//cows.jpg" width="200"></td></tr></table></center><br>
  1278 +
  1279 + Remark the presence of <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$id</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$thisfilepath</div></strong>)/</span> before the name of the file (which is here assumed to be
  1280 + in the same directory as the maml file containing the above expression). The mark <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$thisfilepath</div></strong></span> gives
  1281 + the absolute path of the file it is written into. Also, because we need to glue this path to the name of the image
  1282 + file, we use the macro <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$id</div></strong></span> defined by <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(id)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<div style="display: inline; color: rgb(255,000,255)">$1</div>)</span>. <br><br>
  1283 +
  1284 + At the same time, you remark that the width of the image doesn't need to be given lexically and
  1285 + can be computed using <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks.
  1286 +
  1287 +
  1288 + <a id="input"></a><br><br><strong>8.26. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;file name&gt;</span></strong></div>)</span></div></strong><br><br>
  1289 + This mark let you insert the content of another <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> file. This other file could for example contain your own <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong>
  1290 + macros.<br><br>
  1291 + Notice that the input file also needs to have a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span> and an <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$end</div></strong></span>.
  1292 + In other words, when told to read another file by
  1293 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong></span> the <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> compiler ignores everything in this other file until it finds a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$begin</div></strong></span>.
  1294 + <br><br>
  1295 + This mark can be <strong><div style="display: inline; color: rgb(220,0,0)">unsafe</div></strong> on the web, except if you filter the operand. See the Anubis library documentation.
  1296 +
  1297 +
  1298 + <a id="italic"></a><br><br><strong>8.27. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$italic</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> Prints its operand <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> in <em>italic</em>.
  1299 +
  1300 + <a id="item"></a><br><br><strong>8.28. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$item</div></strong></span></div></strong><br><br> Marks the begining of an <em>item</em> within a <a rel="tag" href="#list"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$list</div></strong></span></a>
  1301 +
  1302 + <a id="label"></a><br><br><strong>8.29. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$label</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;tag&gt;</span></strong></div>)</span></div></strong><br><br> This mark defines a <em>label</em> in the text, in other words, a position where to jump.
  1303 + This is to be used in conjunction with <a rel="tag" href="#ref"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$ref</div></strong></span></a>.
  1304 +
  1305 + <a id="latex"></a><br><br><strong>8.30. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$latex</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;formula&gt;</span></strong></div>)</span></div></strong><br><br> This mark allows to include math formulas to be formated by <img src="png/fNScTnBA4MH-qH_w0pRfArXeeKE8.png" width="36" height="14" style="vertical-align: -3px">.
  1306 + For example,
  1307 + <br><center><table style="color: inherit; font-size: inherit;"><tr><td><pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$latex</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$$</div></strong>\int_<div style="display: inline; color: rgb(160,082,045)">0</div>^\infty\frac{dx}{<div style="display: inline; color: rgb(160,082,045)">1</div>+x^<div style="display: inline; color: rgb(160,082,045)">2</div>}<strong><div style="display: inline; color: rgb(255,000,000)">$$</div></strong>)<br><br></pre></td></tr></table></center><br>
  1308 + is rendered as:
  1309 + <br><center><img src="png/fq22PnfBrYNx2fPr8NQyxy5tdO_A.png" width="72" height="36" style="vertical-align: -0px"></center><br>
  1310 + This mark should not be used for big pieces of <img src="png/fNScTnBA4MH-qH_w0pRfArXeeKE8.png" width="36" height="14" style="vertical-align: -3px">
  1311 + text. It is mainly intended for math formulas, especially for HTML output where the formula is rendered
  1312 + as a PNG image with transparent background.
  1313 + <br><br>
  1314 + You can use <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$latex</div></strong></span> in the text. The result is correctly aligned with the text. For example,<br>
  1315 + <br><center><table style="color: inherit; font-size: inherit;"><tr><td><pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br>the polynomial <strong><div style="display: inline; color: rgb(255,000,000)">$latex</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$X</div></strong>^<div style="display: inline; color: rgb(160,082,045)">2</div>+X+<div style="display: inline; color: rgb(160,082,045)">1</div><strong><div style="display: inline; color: rgb(255,000,000)">$)</div></strong> is of degree <div style="display: inline; color: rgb(160,082,045)">2</div><br><br></pre></td></tr></table></center><br>
  1316 + is rendered as:
  1317 + <br><center><table style="color: inherit; font-size: inherit;"><tr><td>the polynomial <img src="png/fyKx7xRolFAoYjXkjs4VdbNyRjAQ.png" width="77" height="16" style="vertical-align: -1px"> is of degree <div style="display: inline; color: rgb(160,082,045)">2</div></td></tr></table></center><br>
  1318 +
  1319 + Unfortunatly, <img src="png/foAbejNaCwiT0Jzk31KqV0gRWsOY.png" width="25" height="14" style="vertical-align: -3px"> is <strong><div style="display: inline; color: rgb(220,0,0)">unsafe</div></strong> as explained in <a href="http://cseweb.ucsd.edu/~hovav/dist/texhack.pdf">this document</a>.
  1320 + Hence, you should forbid this mark for a web usage, except if you add a filter in order to reject all <img src="png/fNScTnBA4MH-qH_w0pRfArXeeKE8.png" width="36" height="14" style="vertical-align: -3px">
  1321 + commands which don't belong to a given list of safe commands. This list doesn't need to be very long since the
  1322 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$latex</div></strong></span> mark is mainly used for inserting math formulas. See the Anubis library documentation to learn how
  1323 + to install this list of safe <img src="png/fNScTnBA4MH-qH_w0pRfArXeeKE8.png" width="36" height="14" style="vertical-align: -3px"> commands.
  1324 +
  1325 + <a id="length"></a><br><br><strong>8.31. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$length</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span></div></strong><br><br>
  1326 + This mark returns the number of elements in its operand which is supposed to be a list. If the operand is not a list,
  1327 + the result is <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(160,082,045)">1</div></span> if the operand is not empty (i.e. if it contains at least one character), and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(160,082,045)">0</div></span> if it is
  1328 + empty.
  1329 +
  1330 + <a id="list"></a><br><br><strong>8.32. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$list</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;items&gt;</span></strong></div>)</span></div></strong><br><br> This mark allows to create a list. The operand <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;items&gt;</span></strong></div> must be a sequence of <em>items</em>,
  1331 + i.e. texts which are all prefixed by the mark <a rel="tag" href="#item"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$item</div></strong></span></a>.<br><br>
  1332 + Example:
  1333 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$list</div></strong>(
  1334 + <strong><div style="display: inline; color: rgb(255,000,000)">$item</div></strong> Boys: <strong><div style="display: inline; color: rgb(255,000,000)">$list</div></strong>( <strong><div style="display: inline; color: rgb(255,000,000)">$item</div></strong> John <strong><div style="display: inline; color: rgb(255,000,000)">$item</div></strong> Max)
  1335 + <strong><div style="display: inline; color: rgb(255,000,000)">$item</div></strong> Girls: <strong><div style="display: inline; color: rgb(255,000,000)">$list</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$item</div></strong> Julie <strong><div style="display: inline; color: rgb(255,000,000)">$item</div></strong> Geraldine <strong><div style="display: inline; color: rgb(255,000,000)">$item</div></strong> Sophia))<br><br></pre>
  1336 + produces:
  1337 + <span><ul>
  1338 + <li> Boys: <span><ul> <li> John <li> Max</ul></span>
  1339 + <li> Girls: <span><ul><li> Julie <li> Geraldine <li> Sophia</ul></span></ul></span>
  1340 +
  1341 + <a id="lpar"></a><br><br><strong>8.33. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$lpar</div></strong></span></div></strong><br><br> This mark inserts a left (opening) parenthese into the text. You must use <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$lpar</div></strong></span> and/or
  1342 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rpar</div></strong></span> if you want to introduce unbalanced parentheses within an operand of a mark.
  1343 +
  1344 + <a id="mailto"></a><br><br><strong>8.34. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$mailto</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;address&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This marks, which appears as <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>,
  1345 + creates a link which is supposed, in the HTML case, to open your mail agent in order to let you
  1346 + send an email to the indicated <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;address&gt;</span></strong></div>. In the PDF case, the <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;address&gt;</span></strong></div> is just indicated between parentheses
  1347 + beside <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>.
  1348 + For example,<br>
  1349 + <br><center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$blue</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$mailto</div></strong>(XZ<div style="display: inline; color: rgb(160,082,045)">32</div>@planet.mars)(the martian))</span></td></tr></table></center><br> produces:
  1350 + <div style="display: inline; color: rgb(000,000,255)"><a href="mailto:XZ32@planet.mars">the martian</a></div> (you can try it).
  1351 +
  1352 + <a id="nolist"></a><br><br><strong>8.35. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$nolist</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br>
  1353 + This mark inhibits the recognition of the square brackets and the comma as list delimitors within <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>. See
  1354 + <a rel="tag" href="#lists">Lists</a>.
  1355 +
  1356 + <a id="note"></a><br><br><strong>8.36. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$note</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This mark produces a footnote containing <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>.
  1357 + In the case of <img src="png/fNScTnBA4MH-qH_w0pRfArXeeKE8.png" width="36" height="14" style="vertical-align: -3px">/PDF this is a usual
  1358 + footnote. In the case of HTML, this is a popup which appears at the bottom of the browser's window when the mouse
  1359 + passes over this indication : <div class="dropdown"><span>(<sup>note</sup>)</span>
  1360 + <div class="drp-content" style="font-size:10px; width:600-100; padding: 6px 6px 6px 6px;">Here is the note !</div></div>. Try it !
  1361 +
  1362 + <a id="nth"></a><br><br><strong>8.37. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$nth</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span></div></strong><br><br>
  1363 + This mark extracts the <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;n&gt;</span></strong></div><sup>th</sup> element of the list <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>. It generates an error if this element doesn't
  1364 + exist. Numbering begins at zero.
  1365 +
  1366 + <a id="output"></a><br><br><strong>8.38. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$output</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;file path&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This mark does not produce anything in the resulting HTML or PDF files, but outputs
  1367 + <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> (without any modification) into the file <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;file path&gt;</span></strong></div>.
  1368 + <br>
  1369 + <br>
  1370 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$output</div></strong></span> can be very <strong><div style="display: inline; color: rgb(220,0,0)">unsafe</div></strong> for the web. In any case it is not very useful on the web because web pages offer
  1371 + other ways of uploading files. So, the best is just to forbid it.
  1372 +
  1373 + <a id="par"></a><br><br><strong>8.39. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong></span></div></strong><br><br> This marks generates a line break. You can use several <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong></span> in order to make some
  1374 + vertical space in your text.
  1375 + <br><br>
  1376 + <em>Warning:</em> The MAML parser doesn't take newline characters into account (they are just read as spaces). Hence,
  1377 + using <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong></span> is often necessary. You can also define a macro inserting several such newlines. For example:
  1378 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(p)(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong><strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>)<br><br></pre>
  1379 +
  1380 + <a id="popcounter"></a><br><br><strong>8.40. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$popcounter</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span></div></strong><br><br>
  1381 + This mark destroys the most recent counter whose name is <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>.
  1382 +
  1383 + <a id="postpone"></a><br><br><strong>8.41. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$postpone</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br>
  1384 + The <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> text <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> is evaluated only after the entire <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> source is parsed and evaluated (including the
  1385 + sources obtained via <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong></span>).
  1386 + On the contrary, everything not within a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$postpone</div></strong></span> is
  1387 + evaluated at the moment it is parsed. The mark <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$postpone</div></strong></span> is typically used in conjunction with <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$accumulator</div></strong></span>,
  1388 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$append</div></strong></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$content</div></strong></span> for creating a table of contents at the beginning of a document. This is how
  1389 + the table of contents at the beginning of this tutorial was made.<br><br>
  1390 +
  1391 + As another easy example, the sentence <em>Below is a description of the 60
  1392 + primitive <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks.</em> that you can find just after the section title <a rel="tag" href="#catalog">The catalog of <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks</a> contains a
  1393 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$postpone</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$countervalue</div></strong>(markcount))</span> producing the number 60 (where
  1394 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">markcount</span> is the name of the counter used for numbering the marks in this catalog).
  1395 +
  1396 + <a id="pushcounter"></a><br><br><strong>8.42. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$pushcounter</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;init&gt;</span></strong></div>)</span></div></strong><br><br>
  1397 + This mark creates a new counter under the name <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>, with <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;init&gt;</span></strong></div> as its initial value. See
  1398 + <a rel="tag" href="#counters">Counters</a>.
  1399 +
  1400 + <a id="ref"></a><br><br><strong>8.43. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$ref</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;tag&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br>
  1401 + This mark creates an internal hyperlink. When clicked upon, this moves the text
  1402 + to the position of the <a rel="tag" href="#label"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$label</div></strong></span></a> (this is a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$ref</div></strong></span> !) with the same tag name.
  1403 +
  1404 + <a id="reverse"></a><br><br><strong>8.44. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$reverse</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span></div></strong><br><br>
  1405 + This mark return its operand (assumed to be a list), but in reverse order. If the operand is not a list, an error
  1406 + message is generated.
  1407 +
  1408 + <a id="rgb"></a><br><br><strong>8.45. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;color&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This mark sets the color of characters in <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> to <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;color&gt;</span></strong></div>, where
  1409 + <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;color&gt;</span></strong></div> has the form of three integers separated by commas, representing the intensities of red, green and blue.
  1410 + These numbers must be between 0 and 255. For example,<br>
  1411 + <br><center><table style="color: inherit; font-size: inherit;"><tr><td><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">255</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(the text)</span></td></tr></table></center><br>
  1412 + produces:
  1413 + <br><center><table style="color: inherit; font-size: inherit;"><tr><td><div style="display: inline; color: rgb(255,0,0)">the text</div></td></tr></table></center><br>
  1414 + See also <a rel="tag" href="#colors">the predefined colors</a>.
  1415 +
  1416 + <a id="rpar"></a><br><br><strong>8.46. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rpar</div></strong></span></div></strong><br><br> This mark inserts a right (closing) parenthese into the text. You must use <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$lpar</div></strong></span> and/or
  1417 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rpar</div></strong></span> if you want to introduce unbalanced parentheses within an operand of a mark.
  1418 +
  1419 + <a id="setcounter"></a><br><br><strong>8.47. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$setcounter</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div>)</span></div></strong><br><br>
  1420 + This mark puts the value <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;value&gt;</span></strong></div> in the most recent counter whose name is <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>. See <a rel="tag" href="#counters">Counters</a>.
  1421 +
  1422 + <a id="sort"></a><br><br><strong>8.48. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sort</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span></div></strong><br><br>
  1423 + This marks performs a quick sorting of its operand which is supposed to be a list. If the operand is not a list, it is
  1424 + returned as is.<br><br>
  1425 +
  1426 + The sorting is always alphabetic, but it can be relative to any part of the elements in the list. In order to
  1427 + designate which part of an element of the list must be used for comparison, put the special mark
  1428 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$alphabetic</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;part&gt;</span></strong></div>)</span> around this part.<br><br>
  1429 +
  1430 + At the rendering stage <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$alphabetic</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;part&gt;</span></strong></div>)</span> is just replaced by <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;part&gt;</span></strong></div></span>. See <a rel="tag" href="#box"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong></span></a>
  1431 + for an example.
  1432 +
  1433 + <a id="sp"></a><br><br><strong>8.49. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sp</div></strong></span></div></strong><br><br> This mark (space) produces an unbreakable space (translated into <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&amp;nbsp;</span> in HTML and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">~</span> in <img src="png/fNScTnBA4MH-qH_w0pRfArXeeKE8.png" width="36" height="14" style="vertical-align: -3px">).
  1434 +
  1435 + <a id="sub"></a><br><br><strong>8.50. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sub</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This mark lowers <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> and renders it in a smaller size. For example, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">x<strong><div style="display: inline; color: rgb(255,000,000)">$sub</div></strong>(<div style="display: inline; color: rgb(160,082,045)">1</div>)</span>
  1436 + produces x<sub>1</sub>.
  1437 +
  1438 + <a id="sublist"></a><br><br><strong>8.51. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sublist</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;start&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;end&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list&gt;</span></strong></div>)</span></div></strong><br><br>
  1439 + The third operand of this mark is supposed to be a list. If it's not a list, an error message is generated.<br><br>
  1440 +
  1441 + If it is a list, the result is the sublist beginning at element number <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;start&gt;</span></strong></div> (included) and finishing at
  1442 + element number <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;end&gt;</span></strong></div> (not included). Notice that numbering begins at <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(160,082,045)">0</div></span>, not <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(160,082,045)">1</div></span>.
  1443 + If the value of <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;start&gt;</span></strong></div> or <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;end&gt;</span></strong></div> is out of bounds, this value is
  1444 + replaced by the actual bound which is <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(160,082,045)">0</div></span> for <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;start&gt;</span></strong></div> and the length of the list for <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;end&gt;</span></strong></div>. For example,
  1445 +
  1446 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$sublist</div></strong>(-<div style="display: inline; color: rgb(160,082,045)">3</div>)(<div style="display: inline; color: rgb(160,082,045)">4</div>)([a,b,c,d,e,f,g,h,i,j,k])<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>
  1447 +<strong><div style="display: inline; color: rgb(255,000,000)">$sublist</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<div style="display: inline; color: rgb(160,082,045)">4</div>)([a,b,c,d,e,f,g,h,i,j,k])<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>
  1448 +<strong><div style="display: inline; color: rgb(255,000,000)">$sublist</div></strong>(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<div style="display: inline; color: rgb(160,082,045)">4</div>)([a,b,c,d,e,f,g,h,i,j,k])<br><br></pre>
  1449 + produces:<br><br>
  1450 + abcd<br>
  1451 + abcd<br>
  1452 + bcd
  1453 +
  1454 +
  1455 +
  1456 + <a id="sup"></a><br><br><strong>8.52. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sup</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This mark raises <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> and renders it in a smaller size. For example, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">x<strong><div style="display: inline; color: rgb(255,000,000)">$sup</div></strong>(<div style="display: inline; color: rgb(160,082,045)">1</div>)</span>
  1457 + produces x<sup>1</sup>.
  1458 +
  1459 + <a id="tbgc"></a><br><br><strong>8.53. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tbgc</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;color&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This mark (<em>text background color</em>) shows <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> over a background of color
  1460 + <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;color&gt;</span></strong></div>. For example, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tbgc</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$_lavender</div></strong>)(Some text.)</span>
  1461 + produces: <div style="display: inline; background-color: rgb(200,200,220); ">Some text.</div>
  1462 + <br><br>
  1463 + This is valuable for short texts. For long texts, <a rel="tag" href="#code"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong>(...)</span></a> may be more
  1464 + appropriate.
  1465 +
  1466 + <a id="thisfilepath"></a><br><br><strong>8.54. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$thisfilepath</div></strong></span></div></strong><br><br>
  1467 + This marks provides the absolute path of the file it is written into.<br><br>
  1468 +
  1469 + <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$thisfilepath</div></strong></span> is <strong><div style="display: inline; color: rgb(220,0,0)">unsafe</div></strong> for the web, because it can reveal an absolute path of your web server. You should forbid
  1470 + it.
  1471 +
  1472 + <a id="tlink"></a><br><br><strong>8.55. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tlink</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;url&gt;</span></strong></div>)</span></div></strong><br><br> This mark creates an hypertext link targeting the <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;url&gt;</span></strong></div>, and shown as the clickable
  1473 + <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> (which can also be an image). For example,
  1474 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$tlink</div></strong>(Visit
  1475 + <strong><div style="display: inline; color: rgb(255,000,000)">$big</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$blue</div></strong>(G)<strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(o)<strong><div style="display: inline; color: rgb(255,000,000)">$yellow</div></strong>(o)<strong><div style="display: inline; color: rgb(255,000,000)">$blue</div></strong>(g)<strong><div style="display: inline; color: rgb(255,000,000)">$green</div></strong>(l)<strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(e)))
  1476 + (http://www.google.com)<br><br></pre>
  1477 + produces
  1478 + <a href="http://www.google.com">Visit
  1479 + <big><div style="display: inline; color: rgb(000,000,255)">G</div><div style="display: inline; color: rgb(255,000,000)">o</div><div style="display: inline; color: rgb(255,255,000)">o</div><div style="display: inline; color: rgb(000,000,255)">g</div><div style="display: inline; color: rgb(000,255,000)">l</div><div style="display: inline; color: rgb(255,000,000)">e</div></big></a> (that
  1480 + you can click upon).
  1481 +
  1482 +
  1483 +
  1484 + <a id="transpose"></a><br><br><strong>8.56. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$transpose</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;list of lists&gt;</span></strong></div>)</span></div></strong><br><br>
  1485 + This mark <em>transposes</em> (somehow as in mathematics) a list of lists considered as a <em>matrix</em>. As an example,
  1486 + we define:
  1487 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(mylist)(<div style="display: inline; color: rgb(160,082,045)">0</div>)([[a,b],[c,d,e],[f,g]])
  1488 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(addbox)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">16</div>)(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  1489 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(separ)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(addbox)(<div style="display: inline; color: rgb(255,000,255)">$1</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>)<br><br></pre>
  1490 +
  1491 +
  1492 +
  1493 +
  1494 +
  1495 +Now, if we write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(separ)(<strong><div style="display: inline; color: rgb(255,000,000)">$mylist</div></strong>)</span>, we obtain:
  1496 +<br><br>
  1497 +<div align="left" style="display: inline-block; width: 16px;">a</div><div align="left" style="display: inline-block; width: 16px;">b</div><br><div align="left" style="display: inline-block; width: 16px;">c</div><div align="left" style="display: inline-block; width: 16px;">d</div><div align="left" style="display: inline-block; width: 16px;">e</div><br><div align="left" style="display: inline-block; width: 16px;">f</div><div align="left" style="display: inline-block; width: 16px;">g</div><br>
  1498 +<br>
  1499 +and if we write <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(separ)(<strong><div style="display: inline; color: rgb(255,000,000)">$transpose</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$mylist</div></strong>))</span>, we obtain:
  1500 +<br><br>
  1501 +<div align="left" style="display: inline-block; width: 16px;">a</div><div align="left" style="display: inline-block; width: 16px;">c</div><div align="left" style="display: inline-block; width: 16px;">f</div><br><div align="left" style="display: inline-block; width: 16px;">b</div><div align="left" style="display: inline-block; width: 16px;">d</div><div align="left" style="display: inline-block; width: 16px;">g</div><br><div align="left" style="display: inline-block; width: 16px;"></div><div align="left" style="display: inline-block; width: 16px;">e</div><br>
  1502 +<br>
  1503 +
  1504 +
  1505 + Notice that if a line of the matrix is shorter than a subsequent line, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$transpose</div></strong></span> automatically inserts <em>empty</em>
  1506 + (invisible) elements in the
  1507 + transposed matrix so that items which are in the same <em>line</em> in the original matrix are in the same <em>column</em> in the
  1508 + transposed matrix.<br><br>
  1509 +
  1510 + This is useful (in conjunction with <a rel="tag" href="#sublist"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sublist</div></strong></span></a>) and some <a rel="tag" href="#arithmetics">arithmetics</a>
  1511 + for example for displaying a list of items on several columns, with the first group of elements in the first
  1512 + column (not the first line), the next group of elements in the second column, and so on. This can be used for example
  1513 + for automatically producing an index on several columns. This is also used in this tutorial for displaying the list
  1514 + of all marks on four columns <a rel="tag" href="#catalog">at the beginning of this section</a>.<br><br>
  1515 +
  1516 + Below is a simple example. We want to sort a list of words in alphabetic order and to present them on two columns.
  1517 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br> <div style="display: inline; color: rgb(000,100,000)">$// define a list of words</div>
  1518 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(words)(<div style="display: inline; color: rgb(160,082,045)">0</div>)
  1519 + ([We,want,to,sort,a,list,of,words,and,
  1520 + to,present,them,in,alphabetic,order,on,two,columns])<br><br></pre>
  1521 +
  1522 +
  1523 +
  1524 + We prepare the sorting of the list by applying a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">120</div>)</span> and a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$alphabetic</div></strong></span> to all elements.
  1525 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(a)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$box</div></strong>(<div style="display: inline; color: rgb(160,082,045)">120</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$alphabetic</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))) <div style="display: inline; color: rgb(000,100,000)">$// because $apply accepts only macros</div>
  1526 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(sortedwords)(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$sort</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(a)(<strong><div style="display: inline; color: rgb(255,000,000)">$words</div></strong>)))<br><br></pre>
  1527 +
  1528 +
  1529 +
  1530 +so that <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$sortedwords</div></strong></span> looks like this:
  1531 +<br><br>
  1532 +<div align="left" style="display: inline-block; width: 120px;">a</div><div align="left" style="display: inline-block; width: 120px;">alphabetic</div><div align="left" style="display: inline-block; width: 120px;">and</div><div align="left" style="display: inline-block; width: 120px;">columns</div><div align="left" style="display: inline-block; width: 120px;">in</div><div align="left" style="display: inline-block; width: 120px;">list</div><div align="left" style="display: inline-block; width: 120px;">of</div><div align="left" style="display: inline-block; width: 120px;">on</div><div align="left" style="display: inline-block; width: 120px;">order</div><div align="left" style="display: inline-block; width: 120px;">present</div><div align="left" style="display: inline-block; width: 120px;">sort</div><div align="left" style="display: inline-block; width: 120px;">them</div><div align="left" style="display: inline-block; width: 120px;">to</div><div align="left" style="display: inline-block; width: 120px;">to</div><div align="left" style="display: inline-block; width: 120px;">two</div><div align="left" style="display: inline-block; width: 120px;">want</div><div align="left" style="display: inline-block; width: 120px;">We</div><div align="left" style="display: inline-block; width: 120px;">words</div>
  1533 +<br><br>
  1534 + Now, we compute the length of this list, divide it by <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><div style="display: inline; color: rgb(160,082,045)">2</div></span> and add 1 if the remainder is not zero,
  1535 + so that we can cut our list in two lists
  1536 + of almost the same length (the first one with possibly one element more than the second one).
  1537 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(halflen)(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$add</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$quotient</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$length</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$sortedwords</div></strong>))(<div style="display: inline; color: rgb(160,082,045)">2</div>))
  1538 + (<strong><div style="display: inline; color: rgb(255,000,000)">$if</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$equals</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$remainder</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$length</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$sortedwords</div></strong>))(<div style="display: inline; color: rgb(160,082,045)">2</div>)))(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<div style="display: inline; color: rgb(160,082,045)">1</div>)))
  1539 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(column<div style="display: inline; color: rgb(160,082,045)">1</div>)(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$sublist</div></strong>(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$halflen</div></strong>)(<strong><div style="display: inline; color: rgb(255,000,000)">$sortedwords</div></strong>))
  1540 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(column<div style="display: inline; color: rgb(160,082,045)">2</div>)(<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$sublist</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$halflen</div></strong>)(<strong><div style="display: inline; color: rgb(255,000,000)">$length</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$sortedwords</div></strong>))(<strong><div style="display: inline; color: rgb(255,000,000)">$sortedwords</div></strong>))<br><br></pre>
  1541 +
  1542 +
  1543 +
  1544 +
  1545 +
  1546 +Finally, we can get the wanted result by writing:
  1547 +
  1548 +<pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(putpar)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<div style="display: inline; color: rgb(255,000,255)">$1</div><strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>)
  1549 +<strong><div style="display: inline; color: rgb(255,000,000)">$center</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$apply</div></strong>(putpar)(<strong><div style="display: inline; color: rgb(255,000,000)">$transpose</div></strong>([<strong><div style="display: inline; color: rgb(255,000,000)">$column1</div></strong>,<strong><div style="display: inline; color: rgb(255,000,000)">$column2</div></strong>])))<br><br></pre>
  1550 +
  1551 +<center><table style="color: inherit; font-size: inherit;"><tr><td><div align="left" style="display: inline-block; width: 120px;">a</div><div align="left" style="display: inline-block; width: 120px;">present</div><br><div align="left" style="display: inline-block; width: 120px;">alphabetic</div><div align="left" style="display: inline-block; width: 120px;">sort</div><br><div align="left" style="display: inline-block; width: 120px;">and</div><div align="left" style="display: inline-block; width: 120px;">them</div><br><div align="left" style="display: inline-block; width: 120px;">columns</div><div align="left" style="display: inline-block; width: 120px;">to</div><br><div align="left" style="display: inline-block; width: 120px;">in</div><div align="left" style="display: inline-block; width: 120px;">to</div><br><div align="left" style="display: inline-block; width: 120px;">list</div><div align="left" style="display: inline-block; width: 120px;">two</div><br><div align="left" style="display: inline-block; width: 120px;">of</div><div align="left" style="display: inline-block; width: 120px;">want</div><br><div align="left" style="display: inline-block; width: 120px;">on</div><div align="left" style="display: inline-block; width: 120px;">We</div><br><div align="left" style="display: inline-block; width: 120px;">order</div><div align="left" style="display: inline-block; width: 120px;">words</div><br></td></tr></table></center>
  1552 +<br><br>
  1553 + The macro <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$multicolumns</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;number of columns&gt;</span></strong></div>)(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;items&gt;</span></strong></div>)</span> defined in <div style="display: inline; color: rgb(0,80,50)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">basis.maml</span></div>
  1554 + is just a more general version of the above.
  1555 +
  1556 +
  1557 + <a id="true"></a><br><br><strong>8.57. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$true</div></strong></span></div></strong><br><br> This mark represents the truth value <em>true</em>.
  1558 +
  1559 + <a id="tt"></a><br><br><strong>8.58. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tt</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This mark renders <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> in fixed width (typewriter) font. It is similar to
  1560 + <a rel="tag" href="#code"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong>(...)</span></a>, with the difference that <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> is put inline instead of as a separate block.
  1561 + For example, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(<strong><div style="display: inline; color: rgb(255,000,000)">$tt</div></strong>(This)) is <strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong>(<div style="display: inline; color: rgb(160,082,045)">220</div>,<div style="display: inline; color: rgb(160,082,045)">220</div>,<div style="display: inline; color: rgb(160,082,045)">220</div>)(an) example.</span>
  1562 + produces: <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">This</span></div> is <pre style="color: inherit; font-size: inherit; background-color: rgb(220,220,220); width: 600px;">an</pre> example.
  1563 + <br><br>
  1564 + See also <a rel="tag" href="#code"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong>(...)</span></a> and <a rel="tag" href="#verbatim"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$verbatim</div></strong>(...)</span></a>.
  1565 +
  1566 + <a id="undefine"></a><br><br><strong>8.59. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$undefine</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div>)</span></div></strong><br><br> This mark allows to <em>undefine</em> a macro previously defined by <a rel="tag" href="#define"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span></a>.
  1567 + Actually, it removes only the last definition of the macro whose name is given, so that the previous definition of
  1568 + this same mark name (if any) is working again.
  1569 + If no macro with name <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;name&gt;</span></strong></div> exists, nothing happens. <br><br>
  1570 +
  1571 + Example:
  1572 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(emph)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$italic</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  1573 +<strong><div style="display: inline; color: rgb(255,000,000)">$emph</div></strong>(text<div style="display: inline; color: rgb(160,082,045)">1</div>)<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>
  1574 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(emph)(<div style="display: inline; color: rgb(160,082,045)">2</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$bold</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>):<strong><div style="display: inline; color: rgb(255,000,000)">$red</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$2</div>))
  1575 +<strong><div style="display: inline; color: rgb(255,000,000)">$emph</div></strong>(text<div style="display: inline; color: rgb(160,082,045)">2</div>a)(text<div style="display: inline; color: rgb(160,082,045)">2</div>b)<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>
  1576 +<strong><div style="display: inline; color: rgb(255,000,000)">$undefine</div></strong>(emph)
  1577 +<strong><div style="display: inline; color: rgb(255,000,000)">$emph</div></strong>(text<div style="display: inline; color: rgb(160,082,045)">3</div>)<br><br></pre>
  1578 + produces:<br><br>
  1579 +
  1580 +
  1581 +<em>text1</em><br>
  1582 +
  1583 +<strong>text2a</strong>:<div style="display: inline; color: rgb(255,000,000)">text2b</div><br>
  1584 +
  1585 +<em>text3</em>
  1586 + <br><br>
  1587 + As a consequence, a <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> text can safely be embedded into another <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> text using <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$input</div></strong></span>, provided
  1588 + that you <em>undefine</em> the macros defined in the embedded text at the end of the embedded text. <br><br>
  1589 +
  1590 + As told in <a rel="tag" href="#define"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span></a>, <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong></span> doesn't allow recursion. However, if a macro with the same
  1591 + name is already defined, any usage of this macro name in the body of the new definition refers to the previous
  1592 + definition. For example,
  1593 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(bu)(<div style="display: inline; color: rgb(160,082,045)">1</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$italic</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>))
  1594 +<strong><div style="display: inline; color: rgb(255,000,000)">$bu</div></strong>(Some text.)<strong><div style="display: inline; color: rgb(255,000,000)">$par</div></strong>
  1595 +<strong><div style="display: inline; color: rgb(255,000,000)">$define</div></strong>(bu)(<div style="display: inline; color: rgb(160,082,045)">2</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">120</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$bu</div></strong>(<div style="display: inline; color: rgb(255,000,255)">$1</div>) <div style="display: inline; color: rgb(255,000,255)">$2</div>))
  1596 +<strong><div style="display: inline; color: rgb(255,000,000)">$bu</div></strong>(Text<div style="display: inline; color: rgb(160,082,045)">1</div>)(Text<div style="display: inline; color: rgb(160,082,045)">2</div>)<br><br></pre> produces:<br><br>
  1597 +
  1598 +
  1599 +
  1600 + <em>Some text.</em><br>
  1601 +
  1602 + <div style="display: inline; color: rgb(120,0,0)"><em>Text1</em> Text2</div><br>
  1603 +
  1604 +
  1605 + <a id="verbatim"></a><br><br><strong>8.60. <div style="display: inline; color: rgb(255,000,000)"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$verbatim</div></strong>(<div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>)</span></div></strong><br><br> This marks reproduces its content without any change with two exceptions.
  1606 + Indeed, <strong><div style="display: inline; color: rgb(180,0,0)">M</div><div style="display: inline; color: rgb(0,120,0)">A</div><div style="display: inline; color: rgb(80,80,80)">M</div><div style="display: inline; color: rgb(0,0,220)">L</div></strong> marks within
  1607 + <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> are not interpreted, except the two marks <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$lpar</div></strong></span> and <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rpar</div></strong></span>, which allows you
  1608 + to produce unbalanced parentheses in <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div> despite the fact that actual parentheses <em>must</em> be
  1609 + balanced in <div style="display: inline; color: rgb(0,80,0)"><strong><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;">&lt;text&gt;</span></strong></div>. Example:
  1610 + <br>
  1611 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$verbatim</div></strong>(In this (<strong><div style="display: inline; color: rgb(255,000,000)">$italic</div></strong>(text))(), ((parentheses) are) <strong><div style="display: inline; color: rgb(255,000,000)">$rpar</div></strong><strong><div style="display: inline; color: rgb(255,000,000)">$rpar</div></strong><strong><div style="display: inline; color: rgb(255,000,000)">$lpar</div></strong> balanced.)<br><br></pre>
  1612 + produces:
  1613 + <br><br>
  1614 + In this ($italic(text))(), ((parentheses) are) ))( balanced.
  1615 + <br><br>
  1616 + Nevertheless, colors are applied if <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$verbatim</div></strong>(...)</span> is within a <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(...)(...)</span>. Indeed,
  1617 + <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$rgb</div></strong>(<div style="display: inline; color: rgb(160,082,045)">255</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>,<div style="display: inline; color: rgb(160,082,045)">0</div>)(<strong><div style="display: inline; color: rgb(255,000,000)">$verbatim</div></strong>(Red verbatim text))<br><br></pre> produces:
  1618 + <div style="display: inline; color: rgb(255,0,0)">Red verbatim text</div>
  1619 + On the contrary, <pre style="color: inherit; font-size: inherit; background-color: rgb(230,235,220); width: 600px;"><br><strong><div style="display: inline; color: rgb(255,000,000)">$colorize</div></strong>(maml)(<strong><div style="display: inline; color: rgb(255,000,000)">$verbatim</div></strong>(Red verbatim text))<br><br></pre> produces:
  1620 + Red verbatim text
  1621 + because <span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$verbatim</div></strong></span> is not a macro.
  1622 + <br>
  1623 + <br>
  1624 + See also <a rel="tag" href="#code"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$code</div></strong>(...)</span></a> and <a rel="tag" href="#tt"><span style="font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;"><strong><div style="display: inline; color: rgb(255,000,000)">$tt</div></strong>(...)</span></a>.
  1625 + <br><br><br><br>
  1626 +
  1627 +
  1628 +
  1629 +<br><br><br><br><br><br><br><br>
  1630 +
  1631 +</div></td></tr></table></center></body></html>
0 1632 \ No newline at end of file
... ...
anubis_dev/library/doc_tools/maml4_types.anubis 0 → 100644
  1 +
  2 + MAML 4
  3 +
  4 + Most commonly used types.
  5 +
  6 +
  7 +transmit maml4_interface.anubis
  8 +
  9 +
  10 + *** Lexing modes.
  11 +
  12 + Depending on where we are in the source text, we use a different lexer
  13 +
  14 +public type LexMode:
  15 + skip, // skipping until the next $begin (or the end of file)
  16 + out, // parsing between $begin and $end
  17 + blank, // skipping until the next expected mark operand
  18 + in, // parsing MAML operands
  19 + verb. // parsing verbatim operands
  20 +
  21 +
  22 + *** Parsing modes.
  23 +
  24 + Some operands are parsed as MAML trees, but must have a certain 'form' after macros are expanded.
  25 + These 'forms' are formalized by:
  26 +
  27 +public type MustBe:
  28 + any, // can be anything
  29 + bool, // MAML boolean
  30 + color, // must be a color
  31 + ccmode, // colorizercall mode (ee, ei, ie or ii)
  32 + int, // must be an integer
  33 + pint, // must be a positive (or 0) integer
  34 + nzint, // must be a non zero integer (positive or negative)
  35 + string, // must be a character string (i.e must be free of MAML marks)
  36 + symbol. // must be a symbol
  37 +
  38 + How to parse an operand.
  39 +
  40 +public type ParseMode:
  41 + maml, // MAML mode producing any MAML tree
  42 + maml(MustBe), // MAML mode, but must produce the specified form.
  43 + verb. // verbatim mode
  44 +
  45 +
  46 + An 'arity' is a list of parse modes. Each primitive mark has an arity with a parse mode for each operand.
  47 +
  48 +public type alias Arity = List(ParseMode).
  49 +
  50 + *** Pure text.
  51 +
  52 + A replacement type for 'String' which avoids concatenations.
  53 +
  54 +public type Text:
  55 + t(String),
  56 + Text + Text.
  57 +
  58 + Convenience macros:
  59 +public define macro Text Text text + String s = text + t(s).
  60 +public define macro Text String s + Text text = t(s) + text.
  61 +
  62 +
  63 + *** Text with variables.
  64 +
  65 + The same one, but including the possibility to insert variables and some special
  66 + stuff into the text. These extra elements are treated by 'replace_vars_etc' (see maml4_private.anubis).
  67 +
  68 +public type VText:
  69 + t(String), // ordinary text
  70 + v(Int), // variable
  71 + fnsize, // to be replaced by the font size for footnotes
  72 + textwidth, // to be replaced by the width of text
  73 + VText+VText. // two consecutive pieces of VText
  74 +
  75 + Convenience macros:
  76 +public define macro VText VText text + String s = text + t(s).
  77 +public define macro VText String s + VText text = t(s) + text.
  78 +
  79 +
  80 +
  81 + *** Generating some types.
  82 +
  83 + In this section, a piece of program for automatically generating some type definitions.
  84 +
  85 + Decription of primitive marks.
  86 +
  87 + Recall that the MAML compiler works as follows:
  88 +
  89 + parse eval colorize html
  90 + <source text> --------> <MAML1> ------> <MAML2> ----------> <MAML3> --------> HTML
  91 + | latex
  92 + `-----------> LaTeX
  93 +
  94 + 'eval' is executed after each top level mark (together with its operands) is parsed.
  95 + 'colorize' is executed after the whole text is parsed and evaluated.
  96 +
  97 + We dispatch primitive marks into several categories:
  98 + - category 1: those which desappear after 'eval' (example: $addtocounter)
  99 + - category 2: special category for $colorize
  100 + - category 3: those which survive after 'colorize' (example: $rgb)
  101 +
  102 + 'Stackable' marks are those which must be push onto a stack during parsing, because we need to
  103 + know if we are currently within one of their operands. For example $latex doesn't produce a PNG
  104 + image if it is within $ifpdf. Also $latex produces a different MAML1 datum if it is within $note
  105 + (and not within $ifpdf), so as to adjust a reduction factor for PNG images.
  106 +
  107 +public type Stackable:
  108 + stack, // mark symbol (of type 'URenderPrim') must be pushed onto parser's stack
  109 + nostack. // mark symbol must not be pushed onto parser's stack
  110 +
  111 +
  112 +public type PrimMark1:
  113 + primitive1 (String name,
  114 + Stackable stackable,
  115 + Arity arity,
  116 + Maybe(String) prerender).
  117 +
  118 + Convenience functions:
  119 +define PrimMark1 primitive1(String name, Arity a) = primitive1(name,nostack,a,failure).
  120 +define PrimMark1 primitive1(String name, String prerender) = primitive1(name,nostack,[],success(prerender)).
  121 +
  122 + Primitive marks of category 1 are of two sorts:
  123 + 1a they produce an effect and return 'empty'
  124 + 1b they produce not effect and return an non empty item
  125 +
  126 +public define List(PrimMark1)
  127 + primitives1a
  128 + =
  129 + [ // effect producing primitives
  130 + // all the primitives below desappear after 'eval'
  131 + primitive1("accumulator", [maml(symbol)]),
  132 + primitive1("addtocounter", [maml(symbol),maml(int)]),
  133 + primitive1("append", [maml(symbol),maml]),
  134 + primitive1("colorizer", [maml(symbol)]),
  135 + primitive1("colorizercall", [maml(ccmode),maml(symbol),verb,maml(symbol),verb]),
  136 + primitive1("colorrule", [maml(symbol),verb,maml]),
  137 + primitive1("output", [maml(string),verb]),
  138 + primitive1("popcounter", [maml(symbol)]),
  139 + primitive1("pushcounter", [maml(symbol),maml(int)]),
  140 + primitive1("setcounter", [maml(symbol),maml(int)])
  141 + ].
  142 +
  143 +public define List(PrimMark1)
  144 + primitives1b
  145 + =
  146 + [
  147 + // no effect produced by these
  148 + // all the primitives below desappear after 'eval'
  149 + primitive1("add", [maml(int),maml(int)]),
  150 + primitive1("apply", [maml(symbol),maml]),
  151 + primitive1("content", [maml(symbol)]),
  152 + primitive1("countervalue", [maml(symbol)]),
  153 + primitive1("defined", [maml(symbol)]),
  154 + primitive1("dollar", "$"),
  155 + primitive1("equals", [maml,maml]),
  156 + primitive1("false", []),
  157 + primitive1("input", [maml(string)]),
  158 + primitive1("latex", [verb]),
  159 + primitive1("length", [maml]),
  160 + primitive1("lpar", "("),
  161 + primitive1("minus", [maml(int),maml(int)]),
  162 + primitive1("mul", [maml(int),maml(int)]),
  163 + primitive1("nolist", [maml]),
  164 + primitive1("opp", [maml(int)]),
  165 + primitive1("postpone", [maml]),
  166 + primitive1("quotient", [maml(int),maml(nzint)]),
  167 + primitive1("remainder", [maml(int),maml(nzint)]),
  168 + primitive1("reverse", [maml]),
  169 + primitive1("rpar", ")"),
  170 + primitive1("sort", [maml]),
  171 + primitive1("sublist", [maml(int),maml(int),maml]),
  172 + primitive1("thisfilepath", []),
  173 + primitive1("transpose", [maml]),
  174 + primitive1("true", []),
  175 + primitive1("verbatim", [verb])
  176 + ].
  177 +
  178 +
  179 +public define List(PrimMark1)
  180 + primitives1 = primitives1a + primitives1b.
  181 +
  182 +
  183 +public type PrimMark3:
  184 + primitive3 (String name, // name of mark
  185 + Stackable stackable, // see just above
  186 + Arity arity, // how to parse each operand
  187 + VText html_code, // how to produce HTML code
  188 + VText latex_code). // how to produce LaTeX code
  189 +
  190 +
  191 + Convenience function:
  192 +public define PrimMark3 primitive3 (String name, Arity arity, VText html_code, VText latex_code) =
  193 + primitive3(name,nostack,arity,html_code,latex_code).
  194 +
  195 +
  196 +public define List(PrimMark3)
  197 + primitives3
  198 + =
  199 + [
  200 + primitive3("big", [maml],
  201 + "<big>"+v(1)+"</big>",
  202 + "{\larger "+v(1)+"}"),
  203 + primitive3("bold", [maml],
  204 + "<strong>"+v(1)+"</strong>",
  205 + "{\bf "+v(1)+"}"),
  206 + primitive3("box", [maml(int),maml],
  207 + "<div align=\"left\" style=\"display: inline-block; width: "+
  208 + v(1)+"px;\">"+v(2)+"</div>",
  209 + "\\makebox["+v(1)+"px][l]{"+v(2)+"}"),
  210 + primitive3("center", [maml],
  211 + "<center><table style=\"color: inherit; font-size: inherit;\"><tr><td>"+
  212 + v(1)+"</td></tr></table></center>",
  213 + "\\begin{center}"+v(1)+"\\end{center}"),
  214 + primitive3("code", stack, [maml(color),maml],
  215 + "<pre style=\"color: inherit; font-size: inherit; background-color: rgb("+
  216 + v(1)+"); width: "+textwidth+"px;\">"+v(2)+"</pre>",
  217 + "\n\n{\\tt\\begin{tabularx}{\\textwidth}{>{\\columncolor[rgb]{"+v(1)+
  218 + "}}X}{}"+v(2)+"\\hfill{}\\end{tabularx}}\n\n"),
  219 + primitive3("displaylatex", [verb,verb,maml(int),maml(int),maml(int)],
  220 + "<br><center><img src=\""+v(2)+"\" width=\""+v(3)+
  221 + "\" height=\""+v(4)+
  222 + "\" style=\"vertical-align: -"+v(5)+"px\"></center><br>",
  223 + "{}"+v(1)+"{}"),
  224 + primitive3("ifhtml", [maml],
  225 + v(1),
  226 + t("")),
  227 + primitive3("ifpdf", stack, [maml],
  228 + t(""),
  229 + v(1)),
  230 + primitive3("image", [maml(int),maml(string)],
  231 + "<img src=\""+v(2)+"\" width=\""+v(1)+"\">",
  232 + "{\\includegraphics[width="+v(1)+"pt]{"+v(2)+"}}"),
  233 + primitive3("inlinelatex", [
  234 + verb, // original LaTeX text (to be copied into the LaTeX output
  235 + verb, // path of PNG image
  236 + maml(int), // width of PNG image
  237 + maml(int), // height of PNG image
  238 + maml(int) // number of pixels the PNG image must be shifted down
  239 + ],
  240 + "<img src=\""+v(2)+"\" width=\""+v(3)+
  241 + "\" height=\""+v(4)+
  242 + "\" style=\"vertical-align: -"+v(5)+"px\">",
  243 + "{}"+v(1)+"{}"),
  244 + primitive3("italic", [maml],
  245 + "<em>"+v(1)+"</em>",
  246 + "{\\it{}"+v(1)+"}"),
  247 + primitive3("item", [],
  248 + t("<li>"),
  249 + t("\\item ")),
  250 + primitive3("label", [maml(symbol)],
  251 + "<a id=\""+v(1)+"\"></a>",
  252 + "\\label{"+v(1)+"}"),
  253 + primitive3("list", [maml],
  254 + "<span><ul>"+v(1)+"</ul></span>",
  255 + "\\begin{liste}"+v(1)+"\\end{liste}"),
  256 + primitive3("mailto", [maml(string),maml],
  257 + "<a href=\"mailto:"+v(1)+"\">"+v(2)+"</a>",
  258 + "{"+v(2)+"} ({\\verb+"+v(1)+"+})"),
  259 + primitive3("note", stack, [maml],
  260 + "<div class=\"dropdown\"><span>(<sup>note</sup>)</span>
  261 + <div class=\"drp-content\" style=\"font-size:"+fnsize+
  262 + "px; width:"+textwidth+"-100; padding: 6px 6px 6px 6px;\">"+
  263 + v(1)+"</div></div>",
  264 + "{\\rm(\\footnote{"+v(1)+"})}"),
  265 + primitive3("par", [],
  266 + t("<br>"),
  267 + t("\\rule{1mm}{0mm}\n\n")),
  268 + primitive3("ref", [maml(symbol),maml],
  269 + "<a rel=\"tag\" href=\"#"+v(1)+"\">"+v(2)+"</a>",
  270 + v(2)+" (page \\pageref{"+v(1)+"})"),
  271 + primitive3("rgb", [maml(color),maml],
  272 + "<div style=\"display: inline; color: rgb("+v(1)+")\">"+v(2)+"</div>",
  273 + "{\\color[rgb]{"+v(1)+"}"+v(2)+"}"),
  274 + primitive3("sp", [],
  275 + t("&nbsp;"),
  276 + t("~")),
  277 + primitive3("sub", [maml],
  278 + "<sub>"+v(1)+"</sub>",
  279 + "{\\raisebox{-3pt}{\smaller{}"+v(1)+"}}"),
  280 + primitive3("sup", [maml],
  281 + "<sup>"+v(1)+"</sup>",
  282 + "{\\raisebox{3pt}{\smaller{}"+v(1)+"}}"),
  283 + primitive3("tbgc", [maml(color),maml],
  284 + "<div style=\"display: inline; background-color: rgb("+v(1)+"); \">"+
  285 + v(2)+"</div>",
  286 + "{\\definecolor{bgcol}{rgb}{"+v(1)+"}\\colorbox{bgcol}{"+v(2)+"}}"),
  287 + primitive3("tlink", [maml,maml(string)],
  288 + "<a href=\""+v(2)+"\">"+v(1)+"</a>",
  289 + v(1)+" ({\\tt{}"+v(2)+"})"),
  290 + primitive3("tt", [maml],
  291 + "<span style=\"font-family:'Lucida Console', monospace; font-size:inherit; font-style: normal;\">"
  292 + +v(1)+"</span>",
  293 + "{\\tt{"+v(1)+"}}"),
  294 + primitive3("verbatim", [verb],
  295 + "<br><pre>"+v(1)+"</pre><br>",
  296 + "\\begin{verbatim}"+v(1)+"\\end{verbatim}")
  297 + ].
  298 +
  299 +
  300 +
  301 +
  302 + Making the file 'generated/prim1.anubis':
  303 +
  304 +read tools/basis.anubis
  305 +
  306 +define One
  307 + dump_PrimName_type
  308 + (
  309 + WStream fp
  310 + ) =
  311 + print(fp,"\npublic type PrimName:\n");
  312 + print(fp,concat(map((PrimMark1 p) |-> " _"+name(p),primitives1),",\n"));
  313 + print(fp,",\n");
  314 + print(fp,concat(map((PrimMark3 p) |-> " "+name(p),primitives3),",\n"));
  315 + print(fp,".\n").
  316 +
  317 +define One
  318 + dump_prim_types
  319 + (
  320 + WStream fp
  321 + ) =
  322 + print(fp,"\npublic type Prim1:\n");
  323 + print(fp,concat(map((PrimMark1 m) |-> " _"+name(m)+"(MAML_Pos)",primitives1),",\n"));
  324 + print(fp,".\n");
  325 + print(fp,"\npublic type Prim3:\n");
  326 + print(fp,concat(map((PrimMark3 m) |-> " "+name(m)+"(MAML_Pos)",primitives3),",\n"));
  327 + print(fp,".\n").
  328 +
  329 +
  330 +define One
  331 + dump_MAML_Prim1_type
  332 + (
  333 + WStream fp
  334 + ) =
  335 + print(fp,"\npublic type MAML_Prim1:\n");
  336 + print(fp,concat(map((PrimMark1 m) |-> if m is primitive1(name,_,arity,_) then
  337 + " _"+name+(if arity is
  338 + {
  339 + [ ] then "(MAML_Pos)",
  340 + [_ . _] then "(MAML_Pos,"+concat(map((ParseMode mod) |-> if mod is
  341 + {
  342 + maml then "MAML1",
  343 + maml(_) then "MAML1",
  344 + verb then "MAML1"
  345 + },
  346 + arity),",")+")"
  347 + }),
  348 + primitives1),",\n"));
  349 + print(fp,".\n").
  350 +
  351 +
  352 +define One
  353 + dump_MAML_Prim3_type
  354 + (
  355 + WStream fp
  356 + ) =
  357 + print(fp,"\npublic type MAML_Prim3($M):\n");
  358 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  359 + " "+name+(if arity is
  360 + {
  361 + [ ] then "(MAML_Pos)",
  362 + [_ . _] then "(MAML_Pos,"+concat(map((ParseMode mod) |-> if mod is
  363 + {
  364 + maml then "$M",
  365 + maml(mb) then if mb is
  366 + {
  367 + any then "$M",
  368 + bool then "Value(Bool)",
  369 + color then "Value(String)",
  370 + ccmode then "Value(CCMode)",
  371 + int then "Value(Int)",
  372 + pint then "Value(Int)",
  373 + nzint then "Value(Int)",
  374 + string then "Value(String)",
  375 + symbol then "Value(String)"
  376 + },
  377 + verb then "Value(String)"
  378 + }, arity),",")+")"
  379 + }),
  380 + primitives3),",\n"));
  381 + print(fp,".\n").
  382 +
  383 +
  384 +define One
  385 + dump_MAML_Prim3_MAML1_type
  386 + (
  387 + WStream fp
  388 + ) =
  389 + print(fp,"\npublic type MAML_Prim3_MAML1:\n");
  390 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  391 + " "+name+(if arity is
  392 + {
  393 + [ ] then "(MAML_Pos)",
  394 + [_ . _] then "(MAML_Pos,"+concat(map((ParseMode mod) |-> "MAML1",
  395 + arity),",")+")"
  396 + }),
  397 + primitives3),",\n"));
  398 + print(fp,".\n").
  399 +
  400 +
  401 + *** Padding a string (used for generating 'generated/prim*.anubis').
  402 +
  403 +public define String
  404 + padn
  405 + (
  406 + String s
  407 + ) =
  408 + with n = (Int)30,
  409 + with l = length(s), if l > n then s else s+constant_string(n-l,' ').
  410 +
  411 +
  412 +
  413 +public define String
  414 + stdvars_no_par
  415 + (
  416 + Arity ar,
  417 + String -> String decorate,
  418 + String sep
  419 + ) =
  420 + if ar is [] then "" else
  421 + concat(map_iterate((Int n, ParseMode mod) |-> decorate("_"+n), ar, 0, (Int n) |-> n+1),sep).
  422 +
  423 +public define String
  424 + stdvars
  425 + (
  426 + Arity ar,
  427 + String -> String decorate,
  428 + String sep
  429 + ) =
  430 + "("+stdvars_no_par(ar,decorate,sep)+")".
  431 +
  432 +public define String
  433 + stdvars_no_par
  434 + (
  435 + Arity ar,
  436 + (String,ParseMode) -> String decorate,
  437 + String sep
  438 + ) =
  439 + if ar is [] then "" else
  440 + concat(map_iterate((Int n, ParseMode mod) |-> decorate("_"+n,mod), ar, 0, (Int n) |-> n+1),sep).
  441 +
  442 +public define String
  443 + stdvars
  444 + (
  445 + Arity ar,
  446 + (String,ParseMode) -> String decorate,
  447 + String sep
  448 + ) =
  449 + "("+stdvars_no_par(ar,decorate,sep)+")".
  450 +
  451 +
  452 +
  453 +define One
  454 + dump_to_string_Prim3_MAML1
  455 + (
  456 + WStream fp
  457 + ) =
  458 + print(fp,"\npublic define String to_string(MAML_Prim3_MAML1 p) =\n");
  459 + print(fp," if p is\n");
  460 + print(fp," {\n");
  461 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  462 + " "+padn(name+"(_,"+stdvars_no_par(arity,(String v) |-> v,",")+")")+" then \"$"+name+
  463 + stdvars(arity,(String v) |-> "\"+to_string("+v+")+\"",")(")+"\"",
  464 + primitives3),
  465 + ",\n"));
  466 + print(fp," }.\n").
  467 +
  468 +define One
  469 + dump_to_string_MAML_Prim3
  470 + (
  471 + WStream fp
  472 + ) =
  473 + print(fp,"\npublic define String to_string(MAML_Prim3($T) p, $T -> String to_str) =\n");
  474 + print(fp," if p is\n");
  475 + print(fp," {\n");
  476 + print(fp,concat(map((PrimMark3 m) |-> if m is primitive3(name,_,arity,_,_) then
  477 + " "+padn(name+"(_,"+
  478 + stdvars_no_par(arity,(String v) |-> v,",")+")")+" then \"$"+name+
  479 + stdvars(arity,(String v, ParseMode mod) |-> "\"+"+
  480 + (if mod is
  481 + {
  482 + maml then "to_str",
  483 + maml(mb) then if mb is
  484 + {
  485 + any then "to_str",
  486 + bool then "format",
  487 + color then "to_string", // 'to_string' is required even for strings,
  488 + ccmode then "format", // because they are actually of type Value(String)
  489 + int then "to_decimal",
  490 + pint then "to_decimal",
  491 + nzint then "to_decimal",
  492 + string then "to_string",
  493 + symbol then "to_string"
  494 + },
  495 + verb then "to_string"
  496 + })+
  497 + "("+v+")+\"",")(")+"\"",
  498 + primitives3),
  499 + ",\n"));
  500 + print(fp," }.\n").
  501 +
  502 +define One
  503 + dump_to_string_Prim1
  504 + (
  505 + WStream fp
  506 + ) =
  507 + print(fp,"\npublic define String to_string(MAML_Prim1 p) =\n");
  508 + print(fp," if p is\n");
  509 + print(fp," {\n");
  510 + print(fp,concat(map((PrimMark1 m) |-> if m is primitive1(name,_,arity,_) then
  511 + " _"+padn(name+
  512 + "(_,"+stdvars_no_par(arity,(String v) |-> v,",")+")")+" then \"$"
  513 + +(if name = "dollar" then "" else (name+
  514 + stdvars(arity,(String v) |-> "\"+to_string("+v+")+\"",")(")))+"\"",
  515 + primitives1),
  516 + ",\n"));
  517 + print(fp," }.\n").
  518 +
  519 +
  520 +define One
  521 + dump_1_to_PrimName
  522 + (
  523 + WStream fp
  524 + ) =
  525 + print(fp,"\npublic define PrimName to_PrimName(MAML_Prim1 p) =\n");
  526 + print(fp," if p is\n");
  527 + print(fp," {\n");
  528 + print(fp,concat(map((PrimMark1 m) |-> since m is primitive1(name,_,arity,_),
  529 + " _"+padn(name+stdvars([maml . arity],(String v) |-> v,","))+" then _"+name
  530 + ,primitives1),",\n"));
  531 + print(fp,"\n }.\n").
  532 +
  533 +define One
  534 + dump_3_to_PrimName
  535 + (
  536 + WStream fp
  537 + ) =
  538 + print(fp,"\npublic define PrimName to_PrimName(MAML_Prim3($M) p) =\n");
  539 + print(fp," if p is\n");
  540 + print(fp," {\n");
  541 + print(fp,concat(map((PrimMark3 m) |-> since m is primitive3(name,_,arity,_,_),
  542 + " "+padn(name+stdvars([maml . arity],(String v) |-> v,","))+" then "+name
  543 + ,primitives3),",\n"));
  544 + print(fp,"\n }.\n").
  545 +
  546 +
  547 +define One
  548 + dump_is_category_1a
  549 + (
  550 + WStream fp
  551 + ) =
  552 + print(fp,"\npublic define Bool is_category_1a(Prim1 p)=\n");
  553 + print(fp," if p is\n");
  554 + print(fp," {\n");
  555 + print(fp,concat(map((PrimMark1 m) |-> since m is primitive1(name,_,_,_),
  556 + " _"+padn(name+"(_)")+" then true",
  557 + primitives1a),",\n"));
  558 + print(fp,",\n");
  559 + print(fp,concat(map((PrimMark1 m) |-> since m is primitive1(name,_,_,_),
  560 + " _"+padn(name+"(_)")+" then false",
  561 + primitives1b),",\n"));
  562 + print(fp," }.\n").
  563 +
  564 +global define One
  565 + make_prim1_file
  566 + (
  567 + List(String) _
  568 + ) =
  569 + forget(make_directory("generated",default_directory_mode));
  570 + if file("generated/prim1.anubis",new) is
  571 + {
  572 + failure then print("Cannot create file 'generated/prim1.anubis'\n"),
  573 + success(filep) then with fp = (WStream)weaken(filep),
  574 +
  575 + print(fp,"\n\n This file was automatically generated from within ../maml4_types.anubis\n");
  576 + print(fp," by 'make_prim1_file'.\n");
  577 + print(fp,"\nread ../maml4_interface.anubis\n");
  578 + print(fp,"\npublic type MAML1:...");
  579 + print(fp,"\npublic type MAML2:...");
  580 + print(fp,"\npublic type CCMode:...");
  581 + print(fp,"\npublic type Value($T):...\n");
  582 + print(fp,"\npublic define String to_decimal(Value(Int) v).");
  583 + print(fp,"\npublic define String to_string(Value(String) v).");
  584 + print(fp,"\npublic define String to_string(Value(Bool) v).");
  585 + print(fp,"\npublic define String to_string(Value(CCMode) v).");
  586 + print(fp,"\npublic define String to_string(MAML1 m).\n");
  587 + print(fp,"\n The reason why the alternative names below have an\n underscore is that 'if' is a keyword in Anubis.\n");
  588 + dump_PrimName_type(fp);
  589 + dump_prim_types(fp);
  590 + dump_MAML_Prim1_type(fp);
  591 + dump_MAML_Prim3_type(fp);
  592 + dump_MAML_Prim3_MAML1_type(fp);
  593 + dump_is_category_1a(fp);
  594 + dump_1_to_PrimName(fp);
  595 + dump_3_to_PrimName(fp);
  596 + dump_to_string_Prim1(fp);
  597 + dump_to_string_Prim3_MAML1(fp);
  598 + dump_to_string_MAML_Prim3(fp);
  599 + unique
  600 + }.
  601 +
  602 +
  603 +execute anbexec make_prim1_file
  604 +transmit generated/prim1.anubis
  605 +
  606 + At this point, the types 'Prim1', 'Prim2' and 'Prim3' are defined.
  607 +
  608 +public type alias Stack = List(PrimName). // type of stack for the parser
  609 +
  610 +
  611 + *** Handling two values, one for HTML, the other one for PDF.
  612 +
  613 + This happens because of $ifhtml and $ifpdf.
  614 +
  615 +public type Value($T):
  616 + value($T for_html, // the value for HTML output
  617 + $T for_pdf). // the value for PDF output.
  618 +
  619 +
  620 +public type CCMode:
  621 + ee, // exclude-exclude
  622 + ei, // exclude-include
  623 + ie, // etc...
  624 + ii.
  625 +
  626 +public type CCMode1:
  627 + e, // exclude
  628 + i. // include
  629 +
  630 +
  631 +
  632 +
  633 + *** Types of tokens.
  634 +
  635 + Types of tokens for all MAML lexers.
  636 +
  637 +public type SkipToken:
  638 + end_of_input,
  639 + begin. // $begin
  640 +
  641 +public type OutToken:
  642 + end_of_input,
  643 + end, // i.e. $end (which is not the end of the input)
  644 + // primitives
  645 + prim1 (Prim1 name),
  646 + colorize (MAML_Pos pos),
  647 + define (MAML_Pos pos),
  648 + undefine (MAML_Pos pos),
  649 + _if (MAML_Pos pos),
  650 + prim3 (Prim3 name),
  651 + // ordinary text
  652 + text (String value),
  653 + // names of macros
  654 + macro (MAML_Pos pos,
  655 + String name).
  656 +
  657 +public type BlankToken:
  658 + end_of_input,
  659 + lpar.
  660 +
  661 +
  662 +public type InToken:
  663 + end_of_input,
  664 + end,
  665 + lpar,
  666 + rpar,
  667 + lbrk (String d), // d is the original token with whites on both sides of the bracket
  668 + rbrk (String d),
  669 + comma (String d),
  670 + prim1 (Prim1 name),
  671 + alpha (MAML_Pos pos),
  672 + colorize (MAML_Pos pos),
  673 + define (MAML_Pos pos),
  674 + undefine (MAML_Pos pos),
  675 + _if (MAML_Pos pos),
  676 + prim3 (Prim3 name),
  677 + text (String value),
  678 + macro (MAML_Pos pos,
  679 + String name),
  680 + variable (Int id).
  681 +
  682 +public type VerbToken:
  683 + end_of_input,
  684 + lpar,
  685 + rpar,
  686 + dollar,
  687 + text (String content).
  688 +
  689 +
  690 +
  691 +
  692 + *** Token types for cheking 'forms' of expanded MAML trees.
  693 +
  694 +public type ColorValueToken: // used for parsing colors: r,g,b
  695 + end_of_input,
  696 + int (Int),
  697 + comma.
  698 +
  699 +public type SymbolToken:
  700 + end_of_input,
  701 + symbol.
  702 +
  703 +
  704 +
  705 + *** The types of MAML syntax trees.
  706 +
  707 + MAML1 = what comes out of the parser
  708 + MAML2 = what comes out of the evaluator (prim1s and macros desappear)
  709 + MAML2a (colorize desappears)
  710 + MAML3 = what comes out of the colorizer (variables desappear)
  711 +
  712 +public type MAML2:...
  713 +
  714 +public type MAML1:
  715 + error (MAML_Error me),
  716 + erroneous (MAML_Error me,
  717 + MAML1 text), // erroneous text with the corresponding error
  718 + empty,
  719 + text (String value), // text not containing any mark
  720 + variable (Int id), // $1, $2, ...
  721 + prim1 (MAML_Prim1 p1),
  722 + list (List(MAML1) l,
  723 + List(String) deco),
  724 + alpha (MAML1 m), // used for sorting
  725 + colorize (MAML_Pos pos,
  726 + MAML1 cname,
  727 + MAML1 operand),
  728 + define (MAML_Pos pos,
  729 + String name,
  730 + Int arity,
  731 + MAML1 value),
  732 + undefine (MAML_Pos pos,
  733 + String name),
  734 + _if (MAML_Pos pos,
  735 + MAML1 test,
  736 + MAML1 iftrue,
  737 + MAML1 iffalse),
  738 + prim3 (MAML_Prim3_MAML1 p3),
  739 + computed (MAML2 cpted), // already computed object
  740 + macro (MAML_Pos pos,
  741 + String name, // user defined macro
  742 + List(MAML1) operands),
  743 + MAML1 + MAML1. // two consecutives pieces of MAML text
  744 +
  745 +public type MAML2:
  746 + error (MAML_Error me),
  747 + erroneous (MAML_Error me,
  748 + MAML1 text), // erroneous text with the corresponding error
  749 + empty,
  750 + false, // false and true desappear quickly (see 'maml4_eval.anubis')
  751 + true,
  752 + text (String value), // text not containing any mark
  753 + variable (Int id), // $1, $2, ...
  754 + list (List(MAML2) l,
  755 + List(String) deco),
  756 + alpha (MAML2 m), // used for sorting
  757 + colorize (MAML_Pos pos,
  758 + String cname,
  759 + MAML2 operand),
  760 + postpone (MAML_Pos pos,
  761 + MAML1 text),
  762 + prim3 (MAML_Prim3(MAML2) p3),
  763 + MAML2 + MAML2. // two consecutives pieces of MAML text
  764 +
  765 +public type MAML2b:
  766 + error (MAML_Error me),
  767 + erroneous (MAML_Error me,
  768 + MAML1 text), // erroneous text with the corresponding error
  769 + empty,
  770 + call (String cname),
  771 + return,
  772 + text (String value), // text not containing any mark
  773 + variable (Int id), // $1, $2, ...
  774 + list (List(MAML2b) l),
  775 + colorize (MAML_Pos pos,
  776 + String cname,
  777 + MAML2b operand),
  778 + prim3 (MAML_Prim3(MAML2b) p3),
  779 + MAML2b + MAML2b. // two consecutives pieces of MAML text
  780 +
  781 +public type MAML2a:
  782 + error (MAML_Error me),
  783 + erroneous (MAML_Error me,
  784 + MAML1 text), // erroneous text with the corresponding error
  785 + empty,
  786 + text (String value), // text not containing any mark
  787 + variable (Int id), // $1, $2, ...
  788 + list (List(MAML2a) l),
  789 + prim3 (MAML_Prim3(MAML2a) p3),
  790 + MAML2a + MAML2a. // two consecutives pieces of MAML text
  791 +
  792 +public type MAML3:
  793 + error (MAML_Error me),
  794 + erroneous (MAML_Error me,
  795 + MAML1 text), // erroneous text with the corresponding error
  796 + empty,
  797 + text (String value), // text not containing any mark
  798 + list (List(MAML3) l),
  799 + postpone (MAML_Pos pos,
  800 + MAML1 text),
  801 + prim3 (MAML_Prim3(MAML3) p3),
  802 + MAML3 + MAML3. // two consecutives pieces of MAML text
  803 +
  804 +public define MAML1 to_MAML1 (MAML2 m).
  805 +public define MAML1 to_MAML1 (MAML2a m).
  806 +public define MAML1 to_MAML1 (MAML3 m).
  807 +
  808 +
  809 +
  810 + public define MAML2 erroneous(MAML_Error e, MAML2 m).
  811 +
  812 + *** Colorizing.
  813 +
  814 +public type ColorRule:
  815 + rule (String colorizer_name,
  816 + String regular_expression,
  817 + MAML1 value). // an expression containing a $1 to be replaced by the token read
  818 +
  819 +public type ColorCall:
  820 + colorcall (CCMode mode,
  821 + String colorizer1_name,
  822 + String call, // regular expression
  823 + String colorizer2_name,
  824 + String return).
  825 +
  826 + public type Colorizer:
  827 + clrzr (String name, // of colorizer
  828 + String -> MAML2b handle_calls, // parser for handling calls
  829 + String -> MAML3 colorize). // parser for colorizing strings (see maml4_colorize.anubis)
  830 +
  831 +
  832 +
  833 + *** Tokens as they are returned by colorizer's lexers.
  834 +
  835 +
  836 +public type ColorToken:
  837 + end_of_input,
  838 + color (MAML1 value, // the MAML expression containing a $1 to be replaced
  839 + String text), // the token recognized by a user's regular expression
  840 + text (String text). // all parts of the text to be colorized which are not recognized
  841 + // by user's regular expressions. (see 'create_colorizer' in
  842 + // maml4_colorize.anubis)
  843 +
  844 +public type ColorCallToken:
  845 + end_of_input,
  846 + call (CCMode1 mode,
  847 + String cname,
  848 + String token),
  849 + return (CCMode1 mode,
  850 + String token),
  851 + text (String text).
  852 +
  853 +public type alias CallLexer = One -> Result(LexicalError(One),ColorCallToken).
  854 +public type alias CallLexerTree = TreeKV(String,LexingStream -> CallLexer).
  855 +public type alias ColorLexer = One -> Result(LexicalError(One),ColorToken).
  856 +public type alias ColorLexerTree = TreeKV(String,LexingStream -> ColorLexer).
  857 +
  858 +
  859 + *** The 'macro definitions B-tree'.
  860 +
  861 + Recorded definition of a macro.
  862 +
  863 +public type MacroDef:
  864 + macro (String name, // name of macro
  865 + List(ParseMode) arity, // here all operands are parsed as MAML text
  866 + // so that only the length of this list matters
  867 + MAML1 body). // body of definition of macro
  868 +
  869 + The 'macro tree' associates to each macro the list (stack) of its definitions (not a single definition,
  870 + so that when a macro is '$undefined', the previous definition prevails).
  871 +
  872 +public type alias MacroTree = TreeKV(String, // name of macro
  873 + List(MacroDef)). // stack of its definitions
  874 +
  875 + The same one but which contains only the arities.
  876 +public type alias ArityTree = TreeKV(String,
  877 + List(Int)).
  878 +
  879 +
  880 + *** Counters.
  881 +
  882 + The use can create a counters. Each counter has a name and an initial value. A counter is created by:
  883 +
  884 + $pushcounter(<name>)(<initial value>)
  885 +
  886 + The <name> must be a symbol and the <initial value> must be a (possibly negative) integer. The value of a counter
  887 + can be read by:
  888 +
  889 + $countervalue(<name>)
  890 +
  891 +
  892 + The value of a counter can be changed using:
  893 +
  894 + $addtocounter(<name>)(<value>)
  895 + $setcounter(<name>)(<value>)
  896 +
  897 + A counter can be destroyed using:
  898 +
  899 + $popcounter(<name>)
  900 +
  901 + Actually, for each <name> there is a stack of counters, so that $pushcounter can be used several times with
  902 + the sane <name>. At each $popcounter(<name>), the most recent counter with that name is detroyed so that the previous
  903 + one then prevails.
  904 +
  905 +
  906 +public type alias CounterTree = TreeKV(String,List(Int)).
  907 +public type alias AccumulatorTree = TreeKV(String,List(MAML2)).
  908 +
  909 +
  910 +
  911 +
  912 +
  913 + *** Parsing toolbox.
  914 +
  915 + A toolbox is used for parsing.
  916 +
  917 + When we encounter an '$input', we must construct a new toolbox. However, part of the current toolbox
  918 + must be kept because it is independent of the file currently parsed. This part is formalized as:
  919 +
  920 +public type alias SpecLex($Token) = (LexingStream,One) -> One -> LexOut($Token,One).
  921 +
  922 +public type ToolboxKeep:
  923 + toolboxkeep(
  924 + // user's options:
  925 + List(MAML_Option) options,
  926 + // lists of user defined stuff
  927 + Var(MacroTree) macro_tree_v,
  928 + Var(ArityTree) arity_tree_v,
  929 + Var(List(ColorRule)) colorrules_v,
  930 + Var(List(ColorCall)) colorcall_v,
  931 + Var(CallLexerTree) call_lexer_tree_v,
  932 + Var(ColorLexerTree) color_lexer_tree_v,
  933 + Var(CounterTree) counter_tree_v,
  934 + Var(AccumulatorTree) accumulator_tree_v,
  935 + Var(Int) max_errors_v, // counting errors
  936 + MAML_HTML_Options html_options // used to compute the 'reduction factor' for PNG images
  937 + // (see 'parse_latex' in maml4_parser.anubis)
  938 + ).
  939 +
  940 +
  941 + The complete toolbox:
  942 +
  943 +public type Toolbox:
  944 + toolbox (
  945 + String file_path, // absolute path of file currently parsed
  946 + String file_name, // name of file currently parsed
  947 + LexingStream ls, // lexing stream (allows to recover of positions in text)
  948 + One -> LexOut(SkipToken,One) skip_lex, // lexer for skipping until next $begin
  949 + One -> LexOut(OutToken,LexerAux) out_lex, // lexer for parsing between $begin and $end (but outside operands)
  950 + One -> LexOut(BlankToken,One) blank_lex, // lexer for skipping until expected operand
  951 + One -> LexOut(InToken,LexerAux) in_lex, // lexer for parsing MAML operands
  952 + One -> LexOut(VerbToken,One) verb_lex, // lexer for parsing verbatim operands
  953 + ToolboxKeep keep // part of toolbox to be kept over $inputs
  954 + ).
  955 +
  956 +
  957 +
  958 +
0 959 \ No newline at end of file
... ...
anubis_dev/library/doc_tools/png/fNScTnBA4MH-qH_w0pRfArXeeKE8.png 0 → 100644

1.06 KB

anubis_dev/library/doc_tools/png/foAbejNaCwiT0Jzk31KqV0gRWsOY.png 0 → 100644

861 Bytes

anubis_dev/library/doc_tools/png/fq22PnfBrYNx2fPr8NQyxy5tdO_A.png 0 → 100644

1.4 KB

anubis_dev/library/doc_tools/png/fyKx7xRolFAoYjXkjs4VdbNyRjAQ.png 0 → 100644

846 Bytes

anubis_dev/library/doc_tools/png/tNScTnBA4MH-qH_w0pRfArXeeKE8.png 0 → 100644

1.16 KB

anubis_dev/library/doc_tools/png/toAbejNaCwiT0Jzk31KqV0gRWsOY.png 0 → 100644

950 Bytes

anubis_dev/library/doc_tools/png/tyKx7xRolFAoYjXkjs4VdbNyRjAQ.png 0 → 100644

948 Bytes