maml4_tutorial.maml 84.4 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758



                          The MAML4 tutorial       
                          (written in MAML4)            
       
                          
$begin       
$define(article)(0)()
$define(tocsec)(1)($par$bold($1)$par)
$define(tocsubsubsec)(1)()
$define(subseclayout)(1)($par$big($bold($1))$par$par)
$input(basis.maml)


$// A counters for the catalog of marks
$pushcounter(markcount)(0)

$// an accumulator for displaying a table of all mark names at the 
$// beginning of the catalog section 
$accumulator(tabmark)

$define(marklo)  $// marl layout 
       (1)
       ($addtocounter(markcount)(1)$par$par$bold($countervalue(sec).$countervalue(markcount). $1)$par$par)
       
  $// A colorizer for MAML code
$colorrule(maml)(#$#/#/.*)($darkgreen($1))
$colorrule(maml)((#$[#,#[#]#(#)])|(#$[a-zA-Z#_][0-9a-zA-Z#_]*)|(#$#$))($bold($darkred($1)))
$colorrule(maml)(#$[0-9]+)($magenta($1))
$colorrule(maml)([0-9]+)($sienna($1))
$colorizer(maml)

$// Some layout macros.        
$define(p)(0)($par$par)
$define(title)(1)($center($big($big($bold($1)))))
$define(MAML)(0)($bold($rgb(180,0,0)(M)$rgb(0,120,0)(A)$rgb(80,80,80)(M)$rgb(0,0,220)(L)))
$define(em)(1)($italic($1))
$define(textcolor)(0)(100,20,20)
$define(mtt)(1)($tt($colorize(maml)($nolist($1))))
$define(mcode)(1)($code(230,235,220)($colorize(maml)($par$nolist($1)$par$par)))
$define(mcenter)(1)($par$center($colorize(maml)($nolist($1)))$par)
$define(argu)(1)($rgb(0,80,0)($bold($tt(<$1>))))
$define(LaTeX)(0)($latex(\LaTeX))
$define(unsafe)(0)($bold($rgb(220,0,0)(unsafe)))
$define(id)(1)($1)
$define(ptext)(1)($rgb(120,40,40)($1))
$define(fname)(1)($rgb(0,80,50)($tt($1)))


$// A system for displaying names of marks on several columns
$//$pushcounter(catacol)(0)
$//$define(advcol)(0)($if($equals($countervalue(catacol))(3))($setcounter(catacol)(0)$par)($addtocounter(catacol)(1)))

$// Displaying marks in the catalog and accumulating links to them. 
$define(mark0)(1)
  ($append(tabmark)($1)$label($1)$marklo($mtt($$$1)))
$define(mark1)(2)
  ($append(tabmark)($1)$label($1)$marklo($mtt($$$1$lpar$argu($2)$rpar)))
$define(mark2)(3)
  ($append(tabmark)($1)$label($1)$marklo($mtt($$$1$lpar$argu($2)$rpar$lpar$argu($3)$rpar)))
$define(mark3)(4)
  ($append(tabmark)($1)$label($1)$marklo($mtt($$$1$lpar$argu($2)$rpar$lpar$argu($3)$rpar$lpar$argu($4)$rpar)))
$define(mark4)(5)
  ($append(tabmark)($1)$label($1)$marklo($mtt($$$1$lpar$argu($2)$rpar$lpar$argu($3)$rpar$lpar$argu($4)$rpar$lpar$argu($5)$rpar)))

  


     $/////////////////// Here begins the text ////////////////////////// 
     
$title(The $MAML  (version 4) Tutorial)
$title(and Reference)
$par$par$par

$MAML   (the $em(Minimalist Anubis Markup Language)) is an easy to use tool for writing texts. It provides
commands for using different $bold(font) $italic(styles), $big(font $big(sizes)), $red(colors), for making lists, tables, 
sectionning units, inserting images
and 
hypertext links, automatically making a table of contents, 
and most sorts of things which are useful for writting texts which are agreable to read. 
It is also able to automatically produce syntactic colorations. The $MAML   
compiler produces HTML and PDF output files from a $MAML  source text. 
This documentation itself was written in $MAML.$p

Despite its computing capabilities, $MAML is $em(not a programming language). It is a $em(text formating language).
Programming with $MAML is easy provided you write only very short pieces of programs. Making big programs in $MAML
would generate absolutely unreadable source texts (like what happens with $latex(\TeX)). We have managed to present 
many (short) examples of $MAML programming in this tutorial, which helps to quickly understand the explanations.$p

The very first version of $MAML was designed for allowing users on a forum to decorate their messages, and was 
very rudimentary. This is
why $MAML was called $em(minimalist). This version 4 is now quite far from being $em(minimalist), but the name $MAML 
remains (partly because it's funny when pronounced in French and English).

$p
$center($bold(Table of Contents))$par
$tableofcontents


$////////////////////////////////////////////////////////////////////////////////:
$section(howto)(How to use $MAML)
$subsection(ascmdlinetool)(As a command line tool)
$MAML can be used as a command line tool. This tool can work to its full power 
only if $mtt(pdflatex) and $mtt(dvipng) are installed on
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
to produce a PDF output. See the Anubis library documentation for more precise explanations. 
$par
$par
Assuming that the file $mtt(my_file.maml) contains some $MAML  source text, 
you just have to issue the command:
$mcode(anbexec maml my_file.maml)
and the $MAML  compiler will produce a file named $mtt(my_file.maml.html) that you can view with your favorite browser.
$par
$par
This command line tool has several options that you can discover by typing:
$mcode(anbexec maml)
For example, the option $mtt(-pdf) produces a PDF output. 
$p

$subsection(fromyoursource)(From within your Anubis source code)
You may also want to use the $MAML  compiler from within your Anubis source code. For example, you may want to use $MAML
 on a web site. 
In this case, have a look at the Anubis library documentation.
Notice that several $MAML  marks are $unsafe  for a use on the web. We explain in the library documentation 
how to restrict $MAML to safe marks.$p


$subsection(aswebuser)(As a web user)
Since $MAML can be used in a web site (powered for example by the Anubis web server), it is possible to allow web users
(those persons visiting the web site) to write $MAML texts within web pages. In this case, the set of available $MAML
marks is restricted for ensuring the security of the web server.$p 



$//////////////////////////////////////////////////////////////////////////
$section(syntax)(The $MAML  syntax)
$subsection(beginend)($mtt($$begin), $mtt($$end) and special characters)
When it reads a source text, the $MAML  compiler ignores everything until the first occurrence of $ref(begin)($mtt($$begin)). After
this $em(mark), the compiler parses and evaluates the text until it finds $ref(end)($mtt($$end)). Then again, it ignores everything  
until the next $mtt($$begin), and so on.$p

Between $mtt($$begin) and $mtt($$end), the compiler considers all characters as neutral (i.e. they represent only
themselves), except the character $mtt($$). This character introduces a so-called $em(mark), which can have so-called
$em(operands). The operands are delimited by pairs of parentheses.   

Within an operand, all characters are considered as pure text, except the following:
$list(
  $item the character $mtt($$), 
  $item the left and right parentheses $mtt($lpar) and $mtt($rpar). They are used for delimiting blocks of text.
  $item the left and right square brackets $mtt($[) and $mtt($]). They are used for delimiting lists, and within such
  lists, the comma $mtt($,) is used for separating the elements of the list. The comma is otherwise neutral. 
)
  Of course, the possibility exists of inserting these characters as usual neutral characters. It is enough to prefix
  them by a $mtt($$). Hence, for example, $mtt($[) marks the beginning of a list, whereas $mtt($$$[) just represents a
  left square bracket.$p
  
  The figure below sumarizes the above rules.
$mcode(   $em($darkgreen(before $$begin everything is ignored))
   
   $$begin

      $em($navy(here, outside any operand of mark, only the character $$ is special))
   
      $$a_mark(...  $em($darkred(here, $bold($$ $( $) $[) and $bold($]) are special))  ...)
        (...  $[  $em($sienna(and here, the comma also is special))    $]
            ... $$another_mark(  $em($darkred(here too, $bold($$ $( $) $[) and $bold($]) are special)) ...) ... 
                  (... $$nolist($em($purple(but here, only $bold($$ $() and $bold($)) are special
                               even if we are within a list, but brackets
                               must still be balanced))) ...) )
   
   $$end
   
   $em($darkgreen(here again, everything is ignored))
   
   $$begin
   
      $em($navy(and here, it works again as above after the first $$begin))
      $em($black(you can alternate $$begin and $$end any number of times))
   
   $em($black(etc... (and an $$end is required for closing each $$begin)))) 


$subsection(syntaxmark)(Marks)
This character $mtt($$) indicates
that what follows is a $em(mark). The name of the mark (a non empty sequence of characters among 
$mtt($black(A...Za...z0...9))) and the underscore $mtt(_) and not beginning by a digit) 
immediatly follows the character $mtt($dollar). The operands
of the mark follow this name, and each one must be delimited by a pair of parentheses. For example, if you
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
$mcenter($mtt($$rgb(120,0,0)(This text is rendered in dark red.)))
which produces this: 
$mcenter($rgb(120,0,0)(This text is rendered in dark red.))

You shall learn below how to write $em(macros) in $MAML using the mark $ref(define)($mtt($$define)),
so that you can actually simplify the writing of the above. For example the name $MAML  itself
is produced by the macro $mtt($$MAML) which is defined as follows:
$mcode($$define(MAML)(0)   $$// defining the macro $$MAML taking zero operand
   ($$bold($$rgb(180,0,0)(M)$$rgb(0,120,0)(A)$$rgb(80,80,80)(M)$$rgb(0,0,220)(L))))

$subsection(linecomments)(Line comments)
Notice that you can put $em(line comments) into your $MAML source texts as follows:$p
$center($mtt($$// blah blah blah ...))$par
The mark $mtt($$//) and what follows until the end of the line are ignored by the compiler (but it keep
the new line charaters). This kind of comment can be
put everywhere, including within operands of marks, between the operands of a mark (as shown above) and between 
a mark and its first operand.$p

$subsection(balanced)(Parentheses must be balanced)
Each mark accepts a fixed number of operands. Since each operand must be delimited by a pair of parentheses 
(which are not part of the operand itself), the
parentheses which are part of the operand (if any) must be balanced, otherwise the $MAML  parser will not find the closing
parenthese. Nevertheless, you can still include unbalanced parentheses in an operand provided that you write them 
$mtt($$lpar) (left parenthese) and $mtt($$rpar) (right parenthese).$p


$subsection(marknamedelim)(How mark names are delimited)
Also remark that between any two operands of a mark (and between the mark itself and its first operand), you cannot
write anything else than $em(white) characters (i.e. spaces, line-feeds, carriage-returns and tabulators), and line 
comments. For example, 
$mcode($$rgb(0,0,255)(My text))
is equivalent to
$mcode($$rgb    (0,0,255)  $$// this make a bright blue
   (My Text))
But if you write this: $mtt($$rgb(0,0,255)  a  (My text)), the compiler will complain that an operand is missing (it
also indicates the path of the file and the line number where this happens). 
$par
$par
$em(Remark:) The name of a mark is right delimited by the first character which is not an acceptable character
for such a name. If this character is a space, it is $em(not) discarded (unlike what the $latex(\TeX)  compiler 
does). Hence for example, 
$mtt($$lpar x) (with just one space between $mtt($$lpar) and $mtt(x)) 
produces $lpar x (with a space between the parenthese and x), 
so that it seems that there is no way to obtain $id($lpar)x (with nothing between the parenthese and x). 
Actually, there is a simple trick to
obtain the later. Indeed, it is enough to define an $em(identity) macro as follows:
$mcode($$define(id)(1)($$1))
and to write $mtt($$id($$lpar)x).$p




$subsection(definingmarks)(Defining new marks with $mtt($$define))
We already saw examples of use of $mtt($$define) above. It's now time to give precisions about this possibility to
enrich the language with new marks, which is one of the most powerful tools we have at hand.$p

The syntax of $mtt($$define) is as follows:$par
$mcenter($mtt($$define($argu(name))($argu(arity))($argu(value))))
where $argu(name) is the name you want to give to your new mark, $argu(arity) its $em(arity), i.e. the number of
operands it takes, and $argu(value) the value of the mark, which of course depends on the values of it's future operands, which
is the reason why $argu(value) contains so-called $MAML $em(variables) $mtt($$1), $mtt($$2), etc...$p

Notice that if a macro with the same name $argu(name) is already defined, $mtt($$define) does not destroy this
previous definition of $argu(name). It pushes the new definition on a stack of definitions associated to this name. As a
consequence, when you use $mtt($$undefine($argu(name))), the most recent definition of name is poped off this stack (and
forgotten) and the previous one prevails again. See $ref(undefine)($mtt($$undefine)) for some examples.$p

When the $MAML compiler encounters a $mtt($$define($argu(name))($argu(arity))($argu(value))), it doesn't evaluate
(i.e. it doesn't $em(compute)) $argu(name) nor $argu(arity). Consequently, these two operands must be written in their
definitive form.$p

The third operand $argu(value) is only $em(partly evaluated) in the sens that macros are expanded within $argu(value),
but primitive marks are not executed (which is in any case mandatory since operands are not yet known). 
This policy has two important consequences:
$list(
  $item if $argu(value) contains a call to $argu(name), this call doesn't refer to the macro currently being defined,
  but to its previous definition (if any). As a byproduct, this also forbids recursive definitions of macros, so
  protecting the $MAML compiler against infinite loops.$p
  $item $argu(value) cannot refer to a macro which is not yet defined (there are no forward references in $MAML), so
  that the macro always keeps the meaning it has when it is defined, except that the values provided by primitive marks
  will be computed only when the macro is used.  
)
Nevertheless, you may want, especially if you are defining a customizable style of document for example, to define
macros making use of other macros which can be redefined by the user of your style file. The solution is first of all 
to define these other macros conditionally, i.e. as follows:
$mcode($$if($$defined($argu(name)))()($$define($argu(name))(...)(...)))
that is that you provide a $em(default) definition, but only in case your user did not define $argu(name). Of course, this
implies that your user must define $argu(name) $em(before) writing $mtt($$input($argu(your style file))).$p

$subsection(definewithindefine)($mtt($$define) within $mtt($$define))
You may wonder what happens if we write something like:
$mcode($$define(m1)(1)( ... $$define(m2)(1)(...  $$1  ...)  ... ))
Does this $mtt($$1) represent the operand of $mtt(m1) or the operand of $mtt(m2)$sp?$p 

The answer is that it represents
the operand of $mtt(m1) and that the operand of $mtt(m2) is represented by $mtt($$2). More generally, if we have a
$mtt($$define) within a $mtt($$define), the names of the variables of the second (inner) $mtt($$define) are $em(shifted) by the
number of variables of the first (outer) $mtt($$define). As another example, in 
$mcode($$define(m1)(2)
       ($tbgc($_pink)(  $argu(zone 1)  $$define(m2)(4)
                       ($tbgc($_yellow)(  $argu(zone 2)  $$define(m3)(3)
                                       ($tbgc($_azure)(  $argu(zone 3)  ))
                          $argu(zone 2)  ))
          $argu(zone 1)  )))
the valid variables are:
$list(
  $item $mtt($$1) to $mtt($$2) in $argu(zone 1) 
  $item $mtt($$1) to $mtt($$6) in $argu(zone 2)
  $item $mtt($$1) to $mtt($$9) in $argu(zone 3)   
)
In other words, the variables of an inner $mtt($$define) do not hide the variables of an outer $mtt($$define).$p

As an example, consider the following $MAML code:
$mcode($$define()()($$define()()()))



$subsection(memorymarks)(Marks remember their birth environment)
When you define a new mark with $mtt($$define), you can include in the body of the definition a reference to a counter or to
an accumulator. For example, you can write:
$mcode($$pushcounter(n)(0)
$$define(count)(0)($$addtocounter(n)(1)$$countervalue(n)))
$pushcounter(n)(0)
$define(count)(0)($addtocounter(n)(1)$countervalue(n))
Then if you write $mtt($$count $$count $$count), you get $mtt($count $count $count).$p

Now, what if you write $mtt($$count $$count $$pushcounter(n)(7)$$count)$sp? 

$count $count $pushcounter(n)(17)$count


$p
$/////////////////////////////////////////////////////////////////////////
$section(style)(Be stylish)
The primitive $MAML  marks are rather basic, and should preferably be used for creating macros. 
In other words, it's better to first define (using the $mtt($$define) mark) the concepts you will use in your 
text, rather than writing them from scratch at each occurrence. In some sens, defining these concepts is the same as
creating your own style. $p

$subsection(basismaml)(The file $fname(basis.maml))
Notice that a file $fname(basis.maml) exists in $fname(library/doc_tools) which already contains macros of 
common usage. 
$p

$subsection(styleexample)(An example)
It can be the case that some concept of your discourse has to be emphasized in a particular way, and that
you (arbitrarily) chosed to print it 
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
your concept, and define it near the beginning of the text:
$p
$mtt($$define(emph)(1)($$rgb(255,0,0)($$1)))
$p
and write $mtt($$emph(...)) in the text instead of $mtt($$rgb(255,0,0)(...)).
$p
This will structure your text in a useful semantic way, instead of a non significant way, making it easier
to later update. 
It also has the advantage that you can later easily change the layout of the text by modifying
only the values in these $mtt($$define). 
$p
$subsection(inputstyle)(Inputting a style file)
The $mtt($$input) mark let you $em(input) a $MAML  source at any point of another $MAML  source. Hence, you should
define your style in a file (say $mtt(mystyle.maml)) and put an $mtt($$input(mystyle.maml)) after the first $mtt($$begin)
of your source file. Notice that the input file also needs to contain a $mtt($$begin) and an $mtt($$end).$p



$p
$section(tools)(Basic tools)
$MAML is $em(not a programming language). It is a $em(document formatting language). Nevertheless, it provides some
programming capabilities, but only those which are (to our opinion) required for the needs of the layout of the
document. Of course, this set of tools could be enlarged in the future.$p

$subsection(arithmetics)(Elementary arithmetics)
$MAML is able to perform some elementary arithmetic operations on numbers (which are all relative integers). These
operations are:
$list(
  $item $box(200)($mtt($$add($argu(m))($argu(n))))         addition of $argu(m) and $argu(n)
  $item $box(200)($mtt($$minus($argu(m))($argu(n))))       substraction of $argu(n) from $argu(m)
  $item $box(200)($mtt($$opp($argu(m))))                   opposite of $argu(m)
  $item $box(200)($mtt($$mul($argu(m))($argu(n))))         multiplication of $argu(m) by $argu(n)
  $item $box(200)($mtt($$quotient($argu(m))($argu(n))))    quotient of the euclidian division of $argu(m) by $argu(n)
  $item $box(200)($mtt($$remainder($argu(m))($argu(n))))   remainder of the euclidian division of $argu(m) by $argu(n)
)
In case of a division by zero, an error message is generated.$p

$//////////////////////////////////////////////////////////////////////////////////
$subsection(booleans)(Booleans and control)
$MAML provides some rudimentary tools for better controling the $MAML compiler. $MAML recognizes the marks $mtt($$true) and
$mtt($$false) as $em(truth values) (aka. $em(booleans)). Other marks also produce booleans, such as 
$mtt($$equals($argu(expr 1))($argu(expr 2))) and $mtt($$defined($argu(macro name))).$p

These truth values can be used as $argu(test) in:$p
$center($mtt($$if($argu(test))($argu(if true))($argu(if false))))$par
The value of the above mark is $argu(if true) if $argu(test) is true and $argu(if false) otherwise, and of course
only one of $argu(if true) and $argu(if false) is evaluated.$p 

Notice that some logical operators can be defined:
$mcode($$define(and)        (2)   ($$if($$1)($$2)($$false))
$$define(or)         (2)   ($$if($$1)($$true)($$2))
$$define(neg)        (1)   ($$if($$1)($$false)($$true))
$$define(implies)    (2)   ($$or($$neg($$1))($$2)))


$/////////////////////////////////////////////////////////////////////////////
$subsection(counters)(Counters)
$MAML has a notion of $em(counter). You can create a counter with $mtt($$pushcounter($argu(name))($argu(init))), where
$argu(name) is the name of the new counter, and $argu(init) its initial value (which must be a positive, zero or
negative integer).$p

You can get the value of a counter with $mtt($$countervalue($argu(name))) (giving a character string representing 
the value in decimal notation, possibly prefixed by a minus sign).
You can modify the value of a counter with $mtt($$setcounter($argu(name))($argu(value))) and 
$mtt($$addtocounter($argu(name))($argu(value))).$p

You can destroy a counter with $mtt($$popcounter($argu(name))).$p

Actually, for each counter name, $MAML manages a stack of counters. Consequently, if you create a new counter with the
same name as an already existing counter, the first counter is not destroyed and 
becomes visible again when the second counter is destroyed.$p

As an exemple, consider the following:


$mcode($$pushcounter(n)(0)
$$define(ga)(0)($$addtocounter(n)(1)$$countervalue(n)))
$pushcounter(n)(0)
$define(ga)(0)($addtocounter(n)(1)$countervalue(n))

If we write: $mtt($$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga $$ga), we get:$p
$center          ($ga  $ga  $ga  $ga  $ga  $ga  $ga  $ga  $ga  $ga  $ga  $ga  $ga)
Continuing that way, we can write:
$mcode($$pushcounter(n)(25)
$$countervalue(n)
$$popcounter(n)
$$countervalue(n))
and we get: 
$center(
$pushcounter(n)(25)
$countervalue(n)
$popcounter(n)
$countervalue(n))
(as expected).$p


$subsection(lists)(Lists)
$MAML has a notion of $em(list). In order to create a list (say with three elements $mtt(a), $mtt(b) and $mtt(c)), 
you can write $mtt($[a$,b$,c$]). If you write this outside any $MAML operand, you get this:
$p
[a,b,c]
$p
In other words, the square brackets and the comma are just seen as ordinary (neutral) characters (and there is no list
at all in this case). On the contrary, if you write $mtt($$red($[a$,b$,c$])), you get this:
$p
$red([a,b,c])
$p
This is first of all because the square brackets and the comma are recognized as special characters within an operand
(so that we now have an actual list), and because the rendering of a list consists in rendering its element one after the
other without any separator between them. Nevertheless, if we want to render the above list in red with the brackets 
and the commas, it is enough to write $mtt($$red($$$[a$$$,b$$$,c$$$])):
$p 
$red($[a$,b$,c$])
$p

The square brackets and the comma, everywhere they are recognized as special characters $em(eat) the spaces on both
sides. This means that it is equivalent to write $mtt($$red($[a$,b$,c$])) and to write $mtt($$red(  $[  a$,    b   $, c
$]   )). However, be careful because an expression such as $mtt($$red($[a$,b$,c$])) is $em(not) a list 
(because it is enclosed into $mtt($$red)) and triggers 
an error if written at a place where a list is required.$p

List are useful because they can be manipulated by several primitive marks, such as: 
$list(
  $item $mtt($ref(reverse)($$reverse)($argu(list)))
  $item $mtt($ref(sort)($$sort)($argu(list)))
  $item $mtt($ref(length)($$length)($argu(list)))
  $item $mtt($ref(sublist)($$sublist)($argu(start))($argu(end))($argu(list)))
  $item $mtt($ref(apply)($$apply)($argu(mark name))($argu(list)))
  $item $mtt($ref(transpose)($$transpose)($argu(list of lists)))
)
How these primitives marks operate is explained in the $ref(catalog)(catalog).$p

There are circumstances where we want the square brackets and the comma to be considered as ordinary (neutral)
characters. For example, it should be the case for the second operand of
$ref(code)($mtt($$code($argu(color))($argu(computer code)))), and also in some operands of some other primitives. 
To simplify the matter and to offer the maximal number of possibilities, primitives such as $mtt($$code) don't care
about that. This is why we propose the primitive $ref(nolist)($mtt($$nolist($argu(text)))) which inhibits the
recognition of the squares brackets and the comma within $argu(text). Hence, $mtt($$code) should be used as follows:
$p
$center($mtt($$code($argu(color))($$nolist($argu(computer code)))))
$par
and you can define a macro for handling this.$p

As an example, consider the following list of words:
$mcode($$define(cities)(0)
  ($[New York$,Paris$,Berlin$,Moscow$,Casablanca$,Cairo$,Athens$,Rio de Janeiro$]))
$define(cities)(0)([New York,Paris,Berlin,Moscow,Casablanca,Cairo,Athens,Rio de Janeiro])

We can write:
$mcode($$pushcounter(n)(0)
$$define(number)(1)($$addtocounter(n)(1)$$box(20)($$countervalue(n).)$$1$$par)
$$define(a)(1)($$alphabetic($$1))
$$center($$apply(number)($$sort($$apply(a)($$cities)))))
which gives this:
$pushcounter(n)(0)
$define(number)(1)($addtocounter(n)(1)$box(20)($countervalue(n).)$1$par)
$define(a)(1)($alphabetic($1))
$center($apply(number)($sort($apply(a)($cities))))
$p

$subsection(loadadm)(Loading a library of Anubis functions)
It is possible to load a set of Anubis functions that will be automatically transformed into primitive marks. This is
done by the mark $mtt($$loadadm).$p

Such a library is a secondary Anubis module. This module must be generated as follows:
$code($_azure)(

global define MAML_Library
   my_maml_library
   =
   ...

)
This library can be loaded from within a $MAML text by $mtt($$loadadm(my_maml_library)). Immediately after this mark, 
the new marks defined in the library are available.$p

The type $tt(MAML_Library) is defined in
$fname(doc_tools/maml_library_tools.anubis) together with other required types and some tools. 
The type $tt(MAML_Library) is as follows:
$code($_azure)(

public type MAML_Library: 
   maml_library  (List(MAML_Mark)). 

)
and the type $tt(MAML_Mark) is as follows:
$code($_azure)(

public type MAML_Mark:
   f0    (String   name, 
          (MAML_Tools) -> MAML), 
   f1    (String   name, 
          (MAML_Tools,MAML) -> MAML),
   f2    (String   name, 
          (MAML_Tools,MAML,MAML) -> MAML), 
   f3    (String   name, 
          (MAML_Tools,MAML,MAML,MAML) -> MAML), 
   f4    (String   name, 
          (MAML_Tools,MAML,MAML,MAML,MAML) -> MAML), 
   f5    (String   name, 
          (MAML_Tools,MAML,MAML,MAML,MAML,MAML) -> MAML), 
   f6    (String   name, 
          (MAML_Tools,MAML,MAML,MAML,MAML,MAML,MAML) -> MAML).  

)
so that you can define new marks of all arities from $mtt(0) to $mtt(6). The file 
$fname(maml_library_tools.anubis) contains several tools useful for programming $MAML primitives. For example, a
primitive for computing the length of list can be defined as follows:
$code($_azure)(

   f1("length",
       (MAML_Tools tbox, MAML m1) |->  
          if is_list(m1) is 
          {
            failure    then error(not_a_list(m1)), 
            success(l) then text(to_decimal(length(l)))
          })

)
This produces a $MAML mark whose name is $mtt($$length) accepting a single operand, which must be a list.$p

The functions $tt(is_list) and $tt(not_a_list) are defined in $fname(maml_library_tools.anubis), 
whereas $tt(to_decimal) and $tt(length) are standard functions of the Anubis library. The functions
$tt(error) and $tt(text) are the names of two alternatives of the type $tt(MAML). More detailed explanations are given
in $fname(maml_library_tools.anubis), and in the Anubis library documentation.  

$p




$/////////////////////////////////////////////////////////////////////////////:
$section(colorize)(Automatic colorization)
$MAML has a simple system for automatic colorization of texts. Within a $MAML source text, 
you can define one or several colorizers, and later apply them at will. Actually, by $em(colorization) we mean 
something quite general, i.e. not dealing only with colors, as we shall see below.$p

$subsection(createcolorizer)(Creating a colorizer)
In order to create a colorizer, you must:
$list(
  $item define one or several $italic(color rules),
  $item when done, create the $italic(colorizer). 
)
A color rule has the form:$par
$mcenter($mtt($$colorrule($argu(colorizer name))($argu(regular expression))($argu($MAML expression))))
The $argu(colorizer name) of the colorizer must be an ordinary symbol. The $argu(regular expression) must follow the syntax defined in 
$fname(library/lexical_analysis/fast_lexer_5.anubis) (see the Anubis library documentation) and $em(is not evaluated), so
that it must be written in its definitive form. 
The $argu($MAML expression) can contain the $MAML  $em(variable)
$mtt($$1) which is replaced by the token (i.e. the character string recognized by the regular expression) 
to be colorized.$par$par

Once the color rules are setup, you can create the colorizer as follows:$par
$mcenter($mtt($$colorizer($argu(colorizer name))))
Then, you can colorize a text:$par
$mcenter($mtt($$colorize($argu(colorizer name))($argu(text))))

$subsection(mycolorizer)(A colorizer example)
As an example, consider the following definition of a colorizer, which is used in this tutorial for colorizing 
$MAML code:
$mcode(  $$// line comments
$$colorrule(maml)(#$$#/#/.*)($$darkgreen($$1))
  $$// mark names (including inhibited characters)
$$colorrule(maml)($black((#$$$[#$,#$[#$]#(#)$])|(#$$$[a-zA-Z#_$]$[0-9a-zA-Z#_$]*)|(#$$#$$)))
                 ($$bold($$darkred($$1)))
  $$// MAML variables
$$colorrule(maml)($black(#$$$[0-9$]+))($$magenta($$1))
  $$// integers
$$colorrule(maml)($black($[0-9$]+))($$sienna($$1))
  $$// creating the colorizer
$$colorizer(maml))
There are plenty of examples of use of this colorizer in this tutorial (including the above definition of the 
$mtt(maml) colorizer$sp!), so that you can easily check that the result is coherent with the definition. Notice that
we added a $mtt($$black) around regular expressions above, which explains why digits are not colorized in these expressions.$p 

We also used $mtt($$bold) in the above definition, which is not a color per se. Actually any mark can be used, so
that colorizers can also be used for a purpose having nothing to do with colors. Examples are comming below.$p

$subsection(colorizerprecedence)(Primitive marks and colorizers)
You also need to know what happens if the text to be colorized contains $MAML marks. 
All macros are expanded before colorization applies, so that macros have no incidence on colorization, but they can be
used within a text to be colorized. $p

Things are different for primitive marks. Indeed, how do you interpret for example
$p
$center($mtt($$colorize(maml)($black(This is $$rgb(120,0,0)(an example) text.))))
$par
It should be clear that $tt($$rgb) in this example should
have precedence over $mtt($$colorize), otherwise it would be useless. So, the behavior of $MAML is that it doesn't
apply a colorizer within the operands of primitive marks (it would be nevertheless meaningless in the case of the operand
$tt(120,0,0) of $tt($$rgb)).$p

As a consequence, the above example gives
$colorize(maml)(This is $rgb(120,0,0)(an example) text.), 
not $colorize(maml)(This is an example text.)$p

Nevertheless, you can still colorize within an operand within a text to be colorized. For example, 
$p
$center($mtt($$tt($$colorize(maml)($black($$$$bold($$darkgreen($$$$red(text))))))))
$par
produces $tt($colorize(maml)($$bold($darkgreen($$red(text))))), whereas
$p
$center($mtt($$tt($$colorize(maml)($black($$$$bold($$darkgreen($$colorize(maml)($$$$red(text)))))))))
$par
produces $tt($colorize(maml)($$bold($darkgreen($colorize(maml)($$red(text)))))).$p

$subsection(severalcolorizers)(Using several colorizers together)
You can use several colorizers together. Below is another colorizer:
$mcode($$colorrule(funny)([a-e])($$rgb(10,0,130)($$sup($$1)))
$$colorrule(funny)([e-k])($$rgb(150,0,0)($$italic($$1)))
$$colorrule(funny)([l-p])($$rgb(100,100,0)($$big($$1)))
$$colorrule(funny)([p-z])($$rgb(0,100,100)($$sub($$big($$1))))
$$colorizer(funny))
$colorrule(funny)([a-e])($rgb(10,0,130)($sup($1)))
$colorrule(funny)([e-k])($rgb(150,0,0)($italic($1)))
$colorrule(funny)([l-p])($rgb(100,100,0)($big($1)))
$colorrule(funny)([p-z])($rgb(0,100,100)($sub($big($1))))
$colorizer(funny)
If you write: 
$mcode($$tt($$colorize(maml)
   ($$$$bold(Some text $$colorize(funny)(with a piece of funny text) in it.))))
you get $tt($colorize(maml)($$bold(Some text $colorize(funny)(with a piece of funny text) in it.)))$p


$subsection(colorizercall)(Calling a colorizer from within a colorizer)
Using several colorizers together can also help to solve particular colorizing problems, because the above is not the
whole story about $MAML colorizers. Indeed, we have another primitive mark:
$p
$center($mtt($$colorizercall($argu(mode))($argu(colorizer1))($argu(call))($argu(colorizer2))($argu(return))))
$par
which allows to $em(call) a colorizer (here $mtt($argu(colorizer2))) from within another colorizer (here $mtt($argu(colorizer1))). 
The operands $mtt($argu(call)) and $mtt($argu(return)), which can be any $MAML expressions expanding into regular expressions, are used
as $em(call) and $em(return) instructions. In other words, when $mtt($argu(colorizer1)) encounters something matching the
regular expression $mtt($argu(call)) it calls $mtt($argu(colorizer2)) which will return when it founds something matching the
regular expression $mtt($argu(return)).$p

The pieces of text matching $mtt($argu(call)) and $mtt($argu(return)) are colorized by $mtt($argu(colorizer1)) or by
$mtt($argu(colorizer2)), depending on the value of $argu(mode). There are four modes:
$list(
  $item $mtt(ee) ($em(exclude-exclude)): both $argu(call) and $argu(return) are colorized by $argu(colorizer1), 
  $item $mtt(ei) ($em(exclude-include)): $argu(call) is colorized $argu(colorizer1) and $argu(return) by $argu(colorizer2), 
  $item $mtt(ie) ($em(include-exclude)): $argu(call) is colorized $argu(colorizer2) and $argu(return) by $argu(colorizer1), 
  $item $mtt(ii) ($em(include-include)): both $argu(call) and $argu(return) are colorized by $argu(colorizer2).  
)


$subsection(colorcallexample)(A colorizer call example)
Consider the case of an Anubis source text, such as:
$ptext($code(255,255,255)($nolist(

   A function for computing the length of a list:
   
public define Int
   length
   (
     List($$T)   l
   ) =
   if l is 
   {
     [ ]     then 0, 
     [h . t] then 1 + length(t)
   }.
   
   Blah blah blah ...
   
)))
This example contains a $em(paragraph) defining a function, which is surrounded by so-called $em(off-paragraph
comments). In order to colorize this text we need to be able to detect the beginning and the end of Anubis paragraphs.
This is not possible if we use only color rules as defined by $mtt($$colorrule), but it becomes possible if we also use
$mtt($$colorizercall).$p

Indeed, we first define two colorizers, say $mtt(off) for off-paragraph comments and $mtt(in) for paragraphs.$p

In this example, we deliberately chosed to have a head of case of the form $ptext($nolist([h . t])) in the conditional,
because it also contains an $em(end dot) (a dot followed by a space or a linefeed) which must not be confused 
with the end dot closing the paragraph.$p 

In order to colorize the paragraph itself, we need something like:
$p
$center($mtt($$colorizercall(ii)(off)(#npublic)(in)(#.[# #r#n])))
$par
However, if we do that, the colorization of the paragraph will end at the end dot which is within the square brackets.
In order to avoid this, we must add another call:
$p
$center($mtt($$colorizercall(ii)(in)(#$[)(in)(#$])))
$par
(the sharp character, i.e. the escape character for regular expressions, 
in front of the square brackets is necessary since square brackets are special characters
in regular expressions). 
That way, the colorizer $mtt(in) will call itself when it reads an opening square bracket and return (to itself) when it reads the
corresponding closing square bracket.$p 

However, with these two call rules, the colorization is still not correct because when the opening bracket of $mtt([h .
t]) is seen the colorizer $mtt(in) calls itself, and the second instance of $mtt(in) returns on the end dot so that the
first instance of $mtt(in) returns on the closing bracket, and the $mtt(off) colorizer is active again at this
closing bracket. The solution is to define two distinct $mtt(in) colorizers, as shown below.$par

$mcode($$colorrule(off)(.)($$darkgreen($$1))
$$colorrule(in1)(.)($$darkred($$1))
$$colorrule(in2)(.)($$rgb(0,100,100)($$1))
$$colorrule(in1)(#npublic[# #r#n]+define)($$tbgc(220,220,0)($$rgb(0,0,100)($$bold($$1))))
$$colorrule(in1)(#.[# #r#n])($$tbgc(220,220,0)($$rgb(0,0,100)($$bold($$1))))
$$colorizercall(ii)(off)(#npublic[# #r#n]+define)(in1)(#.[# #r#n])
$$colorizercall(ii)(in1)(#$[)(in2)(#$])
$$colorizercall(ii)(in2)(#$[)(in2)(#$])
$$colorizer(in1)
$$colorizer(in2)
$$colorizer(off))


$colorrule(off)(.)($darkgreen($1))
$colorrule(in1)(.)($darkred($1))
$colorrule(in2)(.)($rgb(0,100,100)($1))
$colorrule(in1)(#npublic[# #r#n]+define)($tbgc(220,220,0)($rgb(0,0,100)($bold($1))))
$colorrule(in1)(#.[# #r#n])($tbgc(220,220,0)($rgb(0,0,100)($bold($1))))
$colorizercall(ii)(off)(#npublic[# #r#n]+define)(in1)(#.[# #r#n])
$colorizercall(ii)(in1)(#[)(in2)(#])
$colorizercall(ii)(in2)(#[)(in2)(#])
$colorizer(in1)
$colorizer(in2)
$colorizer(off)
(we put a different color for $mtt(in1) and $mtt(in2) texts for showing where $mtt(in1) calls $mtt(in2) and where $mtt(in2) 
returns). 
Now, if we write $mtt($$code($$_ivory)($$colorize(off)($argu(the above example text)))), we get:

$code($_ivory)($colorize(off)($nolist(

   A function for computing the length of a list:
   
public define Int
   length
   (
     List($$T)   l
   ) =
   if l is 
   {
     [ ]     then 0, 
     [h . t] then 1 + length(t)
   }. 
   
   Blah blah blah ...
   
)))
and more generally, this works for any depth of square brackets nesting.$p 


$subsection(noncolor)(A non colorizing example.)
As said above, colorizers are more general than just a tool for colorizing text. For example, they can be used,
to some extent, for $em(parsing) a text.$p

Assume that we have a text which is in CSV (comma separated values) format. Such texts are very common since every
database system is able to export its tables in this format. Below is an example of such a datum.
$mcode($$define(mycsvtable)(0)
(Ford,Max,32,New York
Jackson,Niel,64,Los Angeles
Kennedy,Justin,25,New York
Obama,Barack,55,Washington
Smith,John,24,Baltimore
Trump,Donald,70,New York))

$define(mycsvtable)(0)
(Ford,Max,32,New York
Jackson,Niel,64,Los Angeles
Kennedy,Justin,25,New York
Obama,Barack,55,Washington
Smith,John,24,Baltimore
Trump,Donald,70,New York)


In this piece of text, the lines of the table are separated by linefeeds and the values in a line are separated by
commas. For simplicity, we assume that the values contain no comma and no linefeed. In a realistic situation, we would
have to enhance our example for handling (for example) commas which are within a pair of parentheses. This kind of
enhancement would require some $mtt($$colorizercall).$p 

We define the following colorizer.
$mcode(  $$// a counter for columns
$$pushcounter(col)(0)
  $$// a counter for lines
$$pushcounter(line)(0)
  $$// we count one column when we see a comma
$$colorrule(display)(#,)($$addtocounter(col)(1))
  $$// we count one line and reset the column counter when we see a linefeed
  $$// and at the same time we introduce some space and the line number on
  $$// the left of the line
$$colorrule(display)(#n)
   ($$addtocounter(line)(1)$$par$$box(40)($$countervalue(line))$$setcounter(col)(0))
  $$// detect values and colorize them differently depending on the column number
$$colorrule(display)($[^#n#$,$]*)($$if($$equals(2)($$countervalue(col)))
         ($$box(40)($$red($$1)))
         ($$if($$equals(0)($$countervalue(col)))
              ($$box(100)($$bold($$1)))
              ($$box(100)($$1))))
  $$// create the colorizer
$$colorizer(display))

$pushcounter(col)(0)
$pushcounter(line)(0)
$colorrule(display)(#,)($addtocounter(col)(1))
$colorrule(display)(#n)($addtocounter(line)(1)$par$box(40)($countervalue(line))$setcounter(col)(0))
$colorrule(display)([^#n#,]*)($if($equals(2)($countervalue(col)))
         ($box(40)($red($1)))($if($equals(0)($countervalue(col)))($box(100)($bold($1)))($box(100)($1))))
$colorizer(display)
If we write
$mcode($$colorize(display)(
$$mycsvtable)) 

we obtain:
$par
$colorize(display)(
$mycsvtable)
$p
Notice that thanks to the counter $mtt(col), we can perform a different treatment on each column. 
Also remark that the first line of
the table has a number in front of it because we added a linefeed in front of $mtt($$mycsvtable) within the second operand of 
$mtt($$colorize). 
$p
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.
To this end, we define another $em(colorizer).
$mcode(  $$// an accumulator for holding the final result
$$accumulator(table)
  $$// an accumulator which is reinitialized at each line
$$accumulator(line)
  $$// without the line below, the commas would appear on the page
$$colorrule(parsecsv)(#$,)()
  $$// the role for recording a complete line 
$$colorrule(parsecsv)(#n)($$append(table)($$content(line))$$accumulator(line))
  $$// the rule for recording a value
$$colorrule(parsecsv)($[^#n#$,$]+)($$append(line)($$1))
  $$// make the colorizer
$$colorizer(parsecsv)
  $$// and compute our list of lists
$$colorize(parsecsv)($$mycsvtable
))

$accumulator(table)
$accumulator(line)
$colorrule(parsecsv)(#,)()
$colorrule(parsecsv)(#n)($append(table)($content(line))$accumulator(line))
$colorrule(parsecsv)([^#n#,]+)($append(line)($1))
$colorizer(parsecsv)
$colorize(parsecsv)($mycsvtable
)

Despite the fact that we wrote $mtt($$colorize), this doesn't produce any output because 
the regular expressions capture everything in the text and the values in the color 
rules contain only marks which produce side effects but no output.$p

So, we expect that the accumulator $mtt(table) contains our list of lists. 
To check that, we define:
$mcode($$define(putbox)(1)($$tbgc($$_azure)($$box(75)($$1)) )
$$define(putpar)(1)($$apply(putbox)($$1)$$par))

$define(putbox)(1)($tbgc($_azure)($box(75)($1)) )
$define(putpar)(1)($apply(putbox)($1)$par)

and write $mtt($$apply(putpar)($$content(table))), which produces
$p
$apply(putpar)($content(table))
$par
and $mtt($$apply(putpar)($$transpose($$content(table)))), which produces
$p
$apply(putpar)($transpose($content(table)))
$par
This last manipulation makes even more obvious the fact that we actually got our table in the form of 
a list of lists. 
$p




$///////////////////////////////////////////////////////////////////////////////////////////
$section(tips)(Tips and tricks)
If your text needs to display some computer code, it can be the case (depending on the programming language) 
that this code uses dollar characters. This is the case of Anubis for example, since dollars are used by
type parameters. These dollars can make a problem since the dollar is also the escape character of $MAML.$par$par

You can of course double the dollars in the computer text examples, but there are situations where we don't want to 
do this, or just cannot do this. This is the case for example in the Anubis library, since some files are at the 
same time $MAML  files (compilable by $MAML), and Anubis file (compilable by $mtt(anubis)). In this case, we cannot
change anything to the text, and in particular, we cannot double the dollars. $par$par

A solution, assuming for example that there are two type parameters $mtt($$T) and $mtt($$U) in the Anubis text, is to
define two macros:
$mcode($$define(T)(0)($$$$T)
$$define(U)(0)($$$$U))
so that the $MAML  compiler will not be disturbed by these type parameters, which is rendered correctly. 
Since this doesn't change anything in the
Anubis text itself (the above $mtt($$define) should be outside any Anubis paragraph), this doesn't change anything from the point 
of view of the Anubis compiler. This trick can of course be applied to other programming languages.$p


$subsection(guidelinesweb)(Guidelines for using $MAML on the web)
Using $MAML on the web requires some care in order not to put your web server into an unsecure situation.$p

Using $MAML on the web means allowing your web users to write 
$MAML texts within a JavaScript text editor or within a $tt(<textarea>) HTML object for example. When the web user
clicks on the $bold(submit) button (or whatever plays this role), a piece of $MAML text arrives on the server. It would
be dangerous to compile it directly because the web user could for example get confidential files by using $mtt($$input)
or put viruses on your server by using $mtt($$output), and probably destroy your server by many other means.$p

This is the reason why the incoming text must be wrapped into another $MAML text before being submitted to the $MAML
compiler. We have adopted a very simple and flexible way of insuring your web server security as far as $MAML is
concerned. Indeed, we have the primitive mark $mtt($$noprimitive) which forbids the direct use of a primitive mark 
(except $ref(noprimitive)(a small number of them) which are not dangerous) for
the rest of the text. Hence, if you append $mtt($$noprimitive) in front of the incomming text, any call to a primitive in
this text is rejected. Notice that the marks comming from a library loaded by $mtt($$loadadm) are still allowed 
after $mtt($$noprimitive), so that you should not load any library containing some dangerous stuff. If you want to 
forbid the marks from the libraries as well, use $mtt($$nolibrary). The marks comming from the libraries can then only 
be used through your macros, just as what happens for primitives.$p

Nevertheless, $MAML can't do much without using primitives (and possibly library marks), 
but it will use them only though the macros you define
yourself in the preambule of the wrapper text, and of course before $mtt($$noprimitive) and $mtt($$nolibrary), 
otherwise your macros 
could not do much. Now, its up to you to define the
macros your web users are allowed to write down. Depending on how you do that, your server is more or less in danger.
For example if you define:
$mcode($$define(out)(2)($$output($$1)($$2)))
your web users will be able to use $mtt($$output). Hence, you must $em(filter) the use of primitives with your macros.
For example, if you want to give access to a (probably registered) user to a personal directory, you can provide macros
such as:
$mcode(  $$// define an error message
$$define(msg)(0)(Only letters, digits and underscore allowed in file names)
  $$// create a colorizer for restricting the usage of file names
$$colorrule(checkfilename)([a-zA-Z0-9_]+)($$1)
  $$// forbid anything else
$$colorrule(checkfilename)(.)($$error($$msg))
$$colorrule(checkfilename)(#n)($$error($$msg))
$$colorizer(checkfilename)
  $$// define two macros for your web users
$$define(output)(2)($$output($argu(userpath)/$$colorize(checkfilename)($$1))($$2))
$$define(input)(1)($$input($argu(userpath)/$$colorize(checkfilename)($$1))))
Of course, $argu(userpath) is a path that you generate on the fly when you create the wrapper text 
for your web user.$p

Be sure that you prefectly understand the meaning of regular expressions before doing this. For example, if you allow
the dot in file names, the web user could write two consecutive dots in a file name, which means the parent directory,
and so on. 
$p

Designing a safe set of macros for the web is not as easy as it may seem. We have one such paranoid 
set already defined in $fname(doc_tools/maml_web_macros.maml).$p


$subsection(commonerrors)(Common errors)
Below are most of the errors the author made himself during the writting of this tutorial, plus some errors he did not
make but which are likely to happen. 
$list(

  $item Thinking that $mtt($$tbgc($$_red)($$box(100)())) produces a red rectangle of the given width 
  (with no text at all into it). 
  This actually produces a white rectangle. In order
  to get this red rectangle, you need to write $mtt($$tbgc($$_red)($$box(100)($$sp))) (recall that $mtt($$sp) is 
  the so-called $em(non breakable space)).$p 

  $item Using $mtt($$blahblah) instead of $mtt($$$$blahblah), i.e. forgetting to double the dollar when we want to render a dollar
  character (or the contrary).$p

  $item Writing $tt(#$$//.*) instead of $tt(#$$#/#/.*) as a regular expression in order to colorize $MAML line comments.
  Of course, the first form $em(is seen) as the beginning of a line comment, and the final result is quite surprising.$p
  
  $item Forgetting to shift variable names in case of a $mtt($$define) within a $mtt($$define). 
)

$/////////////////////////////////////////////////////////////////////////////////
$section(toolsbasis)(Tools available in $fname(basis.maml))
This $MAML file provides some tools of common usage. In order to use these tools, you must write
$center($mtt($$input(basis.maml)))$par
after the first $mtt($$begin), but some tools require that you define a macro before this $mtt($$input).$p

Some of the macros defined in this file can be redefined easily from within your source text. If this is not enough for
your needs, you still have the possibility to use a customized copy of $fname(basis.maml).$p


$subsection(colors)(Colors)
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
within the first operand of $mtt($$rgb), $mtt($$code) and $mtt($$tbgc), i.e. at a place where a color value in the 
form $mtt(r,g,b) is expected.$p  
$pushcounter(colorcnt)(0)
$define(sc)(2)($box(20)()$box(100)($$_$1)$tbgc($2)($sp$sp$sp$sp$sp$sp$sp$sp$sp$sp)$box(20)()$//
$if($equals(2)($countervalue(colorcnt)))($setcounter(colorcnt)(0)$par)($addtocounter(colorcnt)(1)))

$sc(azure)($_azure)  
$sc(black)($_black)
$sc(blue)($_blue)
$sc(caramel)($_caramel)
$sc(chocolate)($_chocolate)
$sc(cyan)($_cyan)
$sc(darkgreen)($_darkgreen)
$sc(gold)($_gold)
$sc(green)($_green)
$sc(grey)($_grey)
$sc(ivory)($_ivory)            
$sc(lavender)($_lavender)
$sc(magenta)($_magenta)
$sc(navy)($_navy)
$sc(orange)($_orange)
$sc(pink)($_pink)
$sc(purple)($_purple)
$sc(red)($_red)
$sc(darkred)($_darkred)
$sc(salmon)($_salmon)
$sc(sienna)($_sienna)
$sc(turquoise)($_turquoise)
$sc(white)($_white)
$sc(yellow)($_yellow)

$undefine(sc)
$p
The file also provide macros with the same name, but without the leading underscore, 
taking one operand for directly colorizing texts. For example $mtt($$red(...)) is
equivalent to $mtt($$rgb($$_red)(...)).$p

$subsection(stylearticle)(The style $mtt(article))
This $em(style) provides definitions for the marks $mtt($$section), $mtt($$subsection) and $mtt($$subsubsection) (which
are not primitive marks), and also defines a mark $mtt($$tableofcontents).$p

$subsubsection(_)(How to use it)
In order to use this style, you must write:$p
$center($mtt($$define(article)(0)()))$par
$em(before) $mtt($$input(basis.maml)), because the style is conditionned by a $mtt($$if($$defined(article))...) 
within $fname(basis.maml).$p

The marks $mtt($$section), $mtt($$subsection) and $mtt($$subsubsection) take two operands. The first one must be a
symbol  
which is the symbolic name you want to give to the section (it is used
for generating internal links, but you can also refer to the section with a $ref(ref)($mtt($$ref(...)(...)))). 
The second one is the title of the section.$p

The mark
$mtt($$tableofcontents) produces a table of contents and can be written anywhere because it contains a 
$ref(postpone)($mtt($$postpone)),
so that it provides a complete table of contents regardless of its position in your source text.$p

$subsubsection(_)(Customizing $mtt(article))
The lines of the table of contents are displayed by the marks $mtt($$tocsec), 
$mtt($$tocsubsec) and $mtt($$tocsubsubsec). If you are not satisfied with the layout provided by these marks, you can
define your own versions, provided that you write your definitions $em(before) $mtt($$input(basis.maml)). These marks take only one
operand which is the line to be displayed. For example, you can define:$par
$mcenter($mtt($$define(tocsec)(1)($$par$$bold($$1)$$par)))
This will replace the default definition provided by $fname(basis.maml). This may be useful for example to redefine
$mtt($$tocsubsubsec) if you have 
subsubsections in your text and don't want them to appear in the table of contents.$p

The same is true for the marks $mtt($$seclayout), $mtt($$subseclayout) and $mtt($$subsubseclayout),  which define the
layout of the section titles themselves. These marks take one operand which is the title itself.$p

$subsection(book)(The style $mtt(book))
This style is the same as article, except that it also has a notion of chapter. Hence, it also defines the mark
$mtt($$chapter($argu(symbolic name))($argu(title))), and you can redefine the marks  
$mtt($$tocchap($argu(title))) and  $mtt($$chaplayout($argu(title))).$p



$////////////////////////////////////////////////////////////////////////////:
$section(catalog)(The catalog of $MAML  marks)
Below is a description of the $postpone($countervalue(markcount)) primitive $MAML marks.$p

  $// Produce a table of contents on 4 columns for the catalog
$define(putboxmark)(1)($box(130)($ref($1)($mtt($$$1))))
$define(displaymarkgroup)(1)($apply(putboxmark)($1)$par)
$postpone($center($apply(displaymarkgroup)($transpose($groupby
  ($if($equals(0)($remainder($countervalue(markcount))(4)))
      ($quotient($countervalue(markcount))(4))
      ($add(1)($quotient($countervalue(markcount))(4))))($content(tabmark))))))



  $mark1(accumulator)(name)
  This mark creates a $em(variable) named $argu(name) called an $em(accumulator). 
  The content of an accumulator is always a list, and this list is empty when the accumulator is created. With the mark 
  $mtt($$append), you can add content to the accumulator. Each use of $mtt($$append) adds an element to the end of the list
  contained in the accumulator. At any time, you can get the content of the accumulator with $mtt($$content).$p 

  An accumulator cannot be destroyed, but it can be reinitialized. Indeed, $mtt($$accumulator($argu(name))) empties the 
  accumulator if it already exists, and puts the empty list in it. Unlike counters and macros, there is no stack associated to an 
  accumulator name. For example:
  $mcode($$accumulator(acc)
$$append(acc)(A)
$$append(acc)(B)
$$content(acc)
$$par
$$accumulator(acc)
$$append(acc)(C)
$$content(acc))
  produces:
  $p
  $accumulator(acc)
  $append(acc)(A)
  $append(acc)(B)
  $content(acc)
  $par
  $accumulator(acc)
  $append(acc)(C)
  $content(acc)
  $p
  Accumulators can be used in conjunction with $ref(postpone)($mtt($$postpone)) for constructing 
  tables of content and indexes. 
  See also $ref(append)($mtt($$append)) and $ref(content)($mtt($$content)).

  $mark2(addtocounter)(name)(value)
  This marks adds $argu(value) to the most recent instance of the counter whose name is $argu(name). 

  $mark2(append)(name)(text)
  This mark appends $argu(text) at the end of the content of the $ref(accumulator)(accumulator) $argu(name). More
  precisely, since the content of an accumulator is a list, the new content of the accumulator is the list obtained 
  by adding $argu(text) as the last element of this list. 
  See also $ref(accumulator)($mtt($$accumulator)) and $ref(content)($mtt($$content)).

  $mark2(apply)(name)(list)
  This mark applies the macro whose name is $argu(name) to all elements of the list $argu(list). This creates a new list
  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
  
  Notice that the first operand is the name of the macro to applied, but $em(without the leading $mtt($$)). In other words, this
  operand is not the macro to apply but only its name. The corresponding macro must take just one operand. If not, an
  error message is generated.$p
  
  Furthermore, the macro to be applied must take a unique operand, and notice that $argu(name) cannot be the name of 
  a primitive mark. It $em(must) be the name of a macro. Hence, if you want to apply a primitive mark, you must first
  define an equivalent macro.$p
  
  As an example, consider the following:
  $mcode($$define(mylist)(0)($[a$,b$,c$,d$])
$$mylist$$par
$$define(a)(1)(<$$red($$1)>)
$$apply(a)($$mylist))
which produces:$p
  
$define(mylist)(0)([a,b,c,d])
$mylist$par
$define(a)(1)(<$red($1)>)
$apply(a)($mylist)
$p
   See also $ref(box)($mtt($$box)) for a more sophisticated example.


  $mark0(begin) This mark is looked for by $MAML  before it parses anything (even within a file refered to by
  $mtt($$input)).  When $mtt($$begin) is found, $MAML   parses the text until it
  encounters the mark $mtt($$end). After this mark, $MAML  continues ignoring everything until the next $mtt($$begin),
  etc... $par$par
  
  Notice that this mecanism can also be used for inserting a comment:
  $mcode($$end
     ... your comment ...
$$begin)
  
  $mark1(big)(text) Prints its operand $argu(text) bigger. This mark can be nested. For example, 
  $list(
    $item $box(200)($mtt($$big(text))) produces $big(text)
    $item $box(200)($mtt($$big($$big(text)))) produces $big($big(text))
    $item $box(200)($mtt($$big($$big($$big(text))))) produces $big($big($big(text)))
  )

  
  $mark1(bold)(text) The operand is rendered in $bold(bold).
  
  $mark2(box)(width)(text) This mark puts $argu(text) into an invisible box of width $argu(width). The text is left aligned
  within the box. This mark can be used for simulating tabulators. For example, 
  $mcode($$define(tableline)(4)($$box(50)($$1) $$box(50)($$2) $$box(30)($$red($$3)) $$4 $$par)
  
$$tableline(Smith)(John)(24)(Baltimore)
$$tableline(Ford) (Max) (32)(New York))
  produces:$par$par
  $define(tableline)(4)($box(50)($1) $box(50)($2) $box(30)($red($3)) $4 $par)
  $tableline(Smith)(John)(24)(Baltimore)
  $tableline(Ford) (Max) (32)(New York)
  $par
  
  $label(colortableexample)
  As an example, here is something more sophisticated. We construct a table similar to the table above, 
  but we want it to be automatically sorted by the last names (first column) and to be in pajama stripes, 
  in other words, so that odd numbered lines 
  are shown on a different background color than even numbered lines. It is clear that the background color
  cannot be decided before the list is sorted, so that, after the list is sorted, we have to apply a macro
  to each element of the list. This is why we need to use the primitive mark $ref(apply)($mtt($$apply)).
  $mcode(  $$// we first create a counter that we use as a flag 
  $$// (taking the values 0 and 1 only)
$$pushcounter(flag)(0)
  $$// we define a color depending on the value of the flag 
  $$// and flipflopping the flag at each use
$$define(linecolor)(0)
  ($$if($$equals(0)($$countervalue(flag)))
       ($$setcounter(flag)(1)$$_lavender)
       ($$setcounter(flag)(0)$$_ivory))  
  $$// define the layout of a line of the table, and put an '$$alphabetic' in order
  $$// to tell MAML how to sort lines
$$define(tableline)(4)
  ($$box(80)($$alphabetic($$1))$$box(80)($$2)$$box(50)($$red($$3))$$box(80)($$4)$$par)
  $$// define a macro for putting a backgroud color behind a line
$$define(putbg)(1)($$tbgc($$linecolor)($$1))
  $$// sort the lines and apply this macro to each line
$$center($$apply(putbg)($$sort(
$[$$tableline(Smith)(John)(24)(Baltimore)$,
 $$tableline(Ford) (Max) (32)(New York)$,
 $$tableline(Jackson)(Niel)(64)(Los Angeles)$,
 $$tableline(Kennedy) (Justin) (25)(New York)$,
 $$tableline(Trump)(Donald)(70)(New York)$,
 $$tableline(Obama) (Barack)(55)(Washington)$]
))))


$pushcounter(flag)(0)
$define(linecolor)(0)($if($equals(0)($countervalue(flag)))($setcounter(flag)(1)$_lavender)($setcounter(flag)(0)$_ivory))  
$define(tableline)(4)($box(80)($alphabetic($1))$box(80)($2)$box(50)($red($3))$box(80)($4)$par)
$define(putbg)(1)($tbgc($linecolor)($1))
$center($apply(putbg)($sort(
[$tableline(Smith)(John)(24)(Baltimore),
 $tableline(Ford) (Max) (32)(New York),
 $tableline(Jackson)(Niel)(64)(Los Angeles),
 $tableline(Kennedy) (Justin) (25)(New York),
 $tableline(Trump)(Donald)(70)(New York),
 $tableline(Obama) (Barack)(55)(Washington)])))
$p
The macro $mtt($$pajamatable) defined in $fname(basis.maml) realises such a table and accepts the data in the form of a
list of lists.

  $mark1(center)(text) This mark horizontally centers the $argu(text) in the page. For example, 
  $mtt($$center(centered text)) produces:$par
  $mcenter(centered text)
  
  $mark2(code)(background color)(text) This marks is for writing computer code. 
  The $argu(text) operand is formated using a fixed width
  (typewriter) font, spaces and newlines are taken into account, so that the result has essentially the same layout as the
  original.  Nevertheless, $MAML  marks are allowed within $argu(text), but some of them, such as $mtt($$list), 
  can produce incoherent results. For example, 
  $par
  $mcode($$define(T)(0)($$$$T)  $$// so that MAML is not troubled by $$T
$$code($$_lavender)($$nolist($black(
define Int
  length
  (
    List($$T) l
  ) =
  if l is 
  {
    [ ]      then 0,  // the list is empty
    [h . t]  then 1+length(t)    
  }.)
$$undefine(T))))
  produces:
  $define(T)(0)($$T)
  $code($_lavender)($nolist(define Int
  length
  (
    List($T) l
  ) =
  if l is 
  {
    [ ]      then 0,  // the list is empty
    [h . t]  then 1+length(t)    
  }.))
  $undefine(T)
  (You can also use a $ref(colorize)(colorizer) for colorizing the code.)
  $par$par
  See also $ref(tt)($mtt($$tt(...))) and $ref(verbatim)($mtt($$verbatim(...)))
  
  $mark2(colorize)(name)(text) See $ref(colorize)(Automatic colorization).
  $mark1(colorizer)(name)  See $ref(colorize)(Automatic colorization).
  $mark4(colorizercall)(name)(regexpr)(name)(regexpr)  See $ref(colorize)(Automatic colorization).
  $mark3(colorrule)(name)(regexpr)(text)  See $ref(colorize)(Automatic colorization).
    
  $mark1(content)(name)
  The value of this mark is the content of the $ref(accumulator)(accumulator) $argu(name). Recall that this content
  is a list. See also $ref(accumulator)($mtt($$accumulator)) and $ref(append)($mtt($$append)).
  
  $mark1(countervalue)(name)
  This mark produces the value of the counter $argu(name) in decimal notation. See $ref(counters)(Counters). 
  
  $mark3(define)(name)(number of operands)(value)
    This mark let you define new marks (i.e. $em(macros)). It takes three operands. The first operand $argu(name) 
    is the name of the new mark. If it is 
    already in use, the new definition masks the previous one until you use an $ref(undefine)($mtt($$undefine($argu(name)))).
    The name must be made only of letters $mtt(A...Z) and $mtt(a...z), decimal digits $mtt(0...9) and 
    the underscore character, and must
    not begin by a digit. The second operand $argu(number of operands) is the number of operands your new mark will accept. 
    It must
    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
    contain marks of the form $mtt($$1), $mtt($$2), $mtt($$3), ... (called $MAML  $em(variables)) which represent the operands
    of the mark, and which will later be replaced by the actual operands when the mark is used in the text.$p
    
    $mtt($$define) doesn't allow to define recursive macros. Nevertheless,  
    see $ref(undefine)($mtt($$undefine)) where more explanations are given on the behavior of $mtt($$define). 
    

  $mark1(defined)(name)
    This mark has a boolean value which is $em(true) if a macro is defined with name $argu(name) and $em(false)
    otherwise. 
    
  $mark0(end) This mark indicates that the $MAML compiler should stop parsing until the next $mtt($$begin) (or the end 
  of file). See $ref(begin)($mtt($$begin)). 
  
  $mark2(equals)(expr 1)(expr 2)
    This mark has a boolean value which is $em(true) if $argu(expr 1) and $argu(expr 2) are equal. By $em(equal), we
    mean identical after $argu(expr 1) and $argu(expr 2) are computed. 
  
  $mark1(error)(text)
  This mark produces an error message. This is useful when you write macros whose operands must satisfy a particular
  property. The operand $argu(text) is the text of the message. This text can contain the $MAML mark $mtt($$position)
  (taking no operand) 
  which will be replaced by the position (file path + line number + column number) in the source text where your macro
  is used. 
    
  $mark0(false) This mark represents the truth value $em(false). 
  
  $mark2(groupby)(n)(list)
  This mark accepts a positive non zero integer $argu(n) as its first operand and a list $argu(list) 
  as its second operand. The result is a
  list of lists, where all lists, except possibly the last one, have length $argu(n). For example,
  $mcode($$define(putbox)(1)($$box(20)(($$1)))
$$define(putpar)(1)($$1$$par)
$$apply(putpar)($$groupby(4)($$apply(putbox)($nolist([a,b,c,d,e,f,g,h,i,j])))))
produces:$p
  
$define(putbox)(1)($box(20)(($1)))
$define(putpar)(1)($1$par)
$apply(putpar)($groupby(4)($apply(putbox)([a,b,c,d,e,f,g,h,i,j])))
$p
$em(Remark): This is typically used for displaying a list of items on several columns. In this case, we also have to
$ref(transpose)(transpose) the list since the actual flow of rendering is by lines, not by columns. But then, the number
to be given as the first operand of $mtt($$groupby) is not so obvious. Indeed, if the length of the list is divisible by
the wanted number of columns, the quotient is the right answer, but if not, we must add $mtt(1) to this quotient,
otherwise we shall have one column too many.  


  $mark3(if)(test)(if true)(if false)
    This mark represents $argu(if true) if $argu(test) is true, and $argu(if false) otherwise. Only one of
    $argu(if true) and $argu(if false) is evaluated. 
  
  $mark1(ifhtml)(text) The operand $argu(text) is present in the HTML output, but not in the $LaTeX  nor in the PDF
  output. 
  
  $mark1(ifpdf)(text) The operand $argu(text) is present in the $LaTeX  and in the PDF
  output, but not in the HTML output.
    
  $mark2(image)(width)(file path)
    This mark inserts an image in the text. The operand $argu(width) is the width the image will have
    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
    containing the image. For example, 
    $mcode($$center($$image($$ifpdf(100)$$ifhtml(200))($$id($$thisfilepath)/cows.jpg))) 
    produces:
    $mcenter($image($ifpdf(100)$ifhtml(200))($id($thisfilepath)/cows.jpg))
    
    Remark the presence of $mtt($$id($$thisfilepath)/) before the name of the file (which is here assumed to be
    in the same directory as the maml file containing the above expression). The mark $mtt($$thisfilepath) gives
    the absolute path of the file it is written into. Also, because we need to glue this path to the name of the image
    file, we use the macro $mtt($$id) defined by $mtt($$define(id)(1)($$1)). $p
    
    At the same time, you remark that the width of the image doesn't need to be given lexically and 
    can be computed using $MAML marks. 
    
    
  $mark1(input)(file name)
  This mark let you insert the content of another $MAML  file. This other file could for example contain your own $MAML
  macros.$par$par
  Notice that the input file also needs to have a $mtt($$begin) and an $mtt($$end). 
  In other words, when told to read another file by
  $mtt($$input) the $MAML  compiler ignores everything in this other file until it finds a $mtt($$begin). 
  $par$par
  This mark can be $unsafe  on the web, except if you filter the operand. See the Anubis library documentation. 
  
    
  $mark1(italic)(text) Prints its operand $argu(text) in $italic(italic).
  
  $mark0(item) Marks the begining of an $em(item) within a $ref(list)($mtt($$list))
  
  $mark1(label)(tag) This mark defines a $em(label) in the text, in other words, a position where to jump. 
  This is to be used in conjunction with $ref(ref)($mtt($$ref)). 
  
  $mark1(latex)(formula) This mark allows to include math formulas to be formated by $LaTeX. 
     For example, 
     $mcenter($mcode($$latex($dollar$$\int_0^\infty\frac{dx}{1+x^2}$dollar$dollar)))
     is rendered as: 
     $latex($$\int_0^\infty\frac{dx}{1+x^2}$$) 
     This mark should not be used for big pieces of $LaTeX   
     text. It is mainly intended for math formulas, especially for HTML output where the formula is rendered
     as a PNG image with transparent background. 
     $par$par
     You can use $mtt($$latex) in the text. The result is correctly aligned with the text. For example,$par
     $mcenter($mcode(the polynomial $$latex($black($$X^2+X+1$$)) is of degree 2))
     is rendered as:
     $mcenter(the polynomial $latex($X^2+X+1$) is of degree 2)
     
  Unfortunatly, $latex(\TeX) is $unsafe  as explained in $tlink(this document)(http://cseweb.ucsd.edu/~hovav/dist/texhack.pdf).
  Hence, you should forbid this mark for a web usage, except if you add a filter in order to reject all $LaTeX
  commands which don't belong to a given list of safe commands. This list doesn't need to be very long since the
  $mtt($$latex) mark is mainly used for inserting math formulas. See the Anubis library documentation to learn how 
  to install this list of safe $LaTeX  commands. 
  
  $mark1(length)(list)
  This mark returns the number of elements in its operand which is supposed to be a list. If the operand is not a list,
  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
  empty.
     
  $mark1(list)(items) This mark allows to create a list (not in the sens of $MAML $ref(lists)(lists), 
  but as a sequence of indented items in the output). 
  The operand $argu(items) must be a sequence of $em(items), 
  i.e. texts which are all prefixed by the mark $ref(item)($mtt($$item)).$par$par
  Example:
  $mcode($$list(
    $$item Boys: $$list( $$item John $$item Max)
    $$item Girls: $$list($$item Julie $$item Geraldine $$item Sophia)))
  produces:
 $list(
    $item Boys: $list( $item John $item Max)
    $item Girls: $list($item Julie $item Geraldine $item Sophia))  
     
  $mark1(loadadm)(module name)  
  This mark loads the secondary Anubis module whose path is given. The Anubis type of this module must be 
  $tt(MAML_Library) as explained in the section $ref(loadadm)(Loading a library of Anubis functions).$p
  
  Of course, this results in an error if the module is either not found, of another type, compiled with another version
  of Anubis, etc... If the loading succeeds the Anubis functions defined in the library become automatically new $MAML
  marks. 
  
  $mark0(lpar) This mark inserts a left (opening) parenthese into the text. You must use $mtt($$lpar) and/or
  $mtt($$rpar) (or alternatively $mtt($$$() and $mtt($$$))) if you want to introduce unbalanced parentheses 
  within an operand of a mark.
     
  $mark2(mailto)(address)(text) This marks, which appears as $argu(text), 
  creates a link which is supposed, in the HTML case, to open your mail agent in order to let you
  send an email to the indicated $argu(address). In the PDF case, the $argu(address) is just indicated between parentheses
  beside $argu(text). 
  For example,$par
  $mcenter($mtt($$blue($$mailto(XZ32@planet.mars)(the martian)))) produces: 
  $blue($mailto(XZ32@planet.mars)(the martian))$ifhtml( (you can try it)). 

  $mark1(nolist)(text)
  This mark inhibits the recognition of the square brackets and the comma as list delimitors within $argu(text). See
  $ref(lists)(Lists).  
  
  $mark0(noprimitive)
  This mark disables the use of all primitive marks until the end of the document, except for the marks
  $mtt($$alphabetic), $mtt($$colorize), $mtt($$define), $mtt($$if) and $mtt($$undefine). Hence, after $mtt($$noprimitive), 
  only the
  macros, the marks listed above and the marks coming from a library via 
  $mtt($$loadadm) are allowed. This can be used for securing the usage of $MAML by web users, 
  since the macros you define before $mtt($$noprimitive) can filter their operands. See
  $ref(guidelinesweb)(the guidelines for the web). 
  
  $mark1(note)(text) This mark produces a footnote containing $argu(text). 
  In the case of $LaTeX/PDF  this is a usual
  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
  passes over this indication : $ifhtml($note(Here is the note !))$ifpdf(($sup(note))).$ifhtml( Try it !)
  
  $mark2(nth)(n)(list)
  This mark extracts the $argu(n)$sup(th) element of the list $argu(list). It generates an error if this element doesn't
  exist. Numbering begins at zero. 
  
  $mark2(output)(file path)(text) This mark does not produce anything in the resulting HTML or PDF files, but outputs
  $argu(text) (without any modification) into the file $argu(file path).
  $par
  $par
  $mtt($$output) can be very $unsafe  for the web. In any case it is not very useful on the web because web pages offer
  other ways of uploading files. So, the best is just to forbid it. 
  
  $mark0(par) This marks generates a line break. You can use several $mtt($$par) in order to make some
  vertical space in your text. 
  $par$par
  $em(Warning:) The MAML parser doesn't take newline characters into account (they are just read as spaces). Hence,
  using $mtt($$par) is often necessary. You can also define a macro inserting several such newlines. For example:
  $mcode($$define(p)(0)($$par$$par))
  
        
  
  $mark1(popcounter)(name)
  This mark destroys the most recent counter whose name is $argu(name). 
  
  $mark1(postpone)(text)
  The $MAML text $argu(text) is evaluated only after the entire $MAML source is parsed and evaluated (including the 
  sources obtained via $mtt($$input)). 
  On the contrary, everything not within a $mtt($$postpone) is 
  evaluated at the moment it is parsed. The mark $mtt($$postpone) is typically used in conjunction with $mtt($$accumulator), 
  $mtt($$append) and $mtt($$content) for creating a table of contents at the beginning of a document. This is how
  the table of contents at the beginning of this tutorial was made.$p
  
  As another easy example, the sentence $em(Below is a description of the $postpone($countervalue(markcount)) 
  primitive $MAML marks.) that you can find just after the section title $ref(catalog)(The catalog of $MAML marks) contains a 
  $mtt($$postpone($$countervalue(markcount))) producing the number $postpone($countervalue(markcount)) (where
  $mtt(markcount) is the name of the counter used for numbering the marks in this catalog). 
  
  $mark2(pushcounter)(name)(init)
  This mark creates a new counter under the name $argu(name), with $argu(init) as its initial value. See
  $ref(counters)(Counters). 
  
  $mark2(ref)(tag)(text) 
  This mark creates an internal hyperlink. When clicked upon, this moves the text
  to the position of the $ref(label)($mtt($$label)) (this is a $mtt($$ref) !) with the same tag name. 
  
  $mark1(reverse)(list)
  This mark return its operand (assumed to be a list), but in reverse order. If the operand is not a list, an error
  message is generated. 
  
  $mark2(rgb)(color)(text) This mark sets the color of characters in $argu(text) to $argu(color), where
  $argu(color) has the form of three integers separated by commas, representing the intensities of red, green and blue. 
  These numbers must be between 0 and 255. For example,$par 
  $mcenter($mtt($$rgb(255,0,0)(the text)))
  produces:
  $mcenter($rgb(255,0,0)(the text))
  See also $ref(colors)(the predefined colors). 
  
  $mark0(rpar) This mark inserts a right (closing) parenthese into the text. You must use $mtt($$lpar) and/or
  $mtt($$rpar) (or alternatively $mtt($$$() and $mtt($$$))) if you want to introduce unbalanced parentheses within 
  an operand of a mark. 

  $mark2(setcounter)(name)(value)
  This mark puts the value $argu(value) in the most recent counter whose name is $argu(name). See $ref(counters)(Counters).
  
  $mark1(sort)(list)
  This marks performs a quick sorting of its operand which is supposed to be a list. If the operand is not a list, an
  error message is generated.$p
  
  The sorting is always alphabetic, but it can be relative to any part of the elements in the list. In order to
  designate which part of an element of the list must be used for comparison, put the special mark
  $mtt($$alphabetic($argu(part))) around this part.$p
  
  At the rendering stage $mtt($$alphabetic($argu(part))) is just replaced by $mtt($argu(part)). See $ref(box)($mtt($$box))
  for an example.  
  
  $mark0(sp) This mark (space) produces an unbreakable space (translated into $tt(&nbsp;) in HTML and $tt(~) in $latex(\LaTeX)). 
  
  $mark1(sub)(text) This mark lowers $argu(text) and renders it in a smaller size. For example, $mtt(x$$sub(1))
  produces x$sub(1). 

  $mark3(sublist)(start)(end)(list)
  The third operand of this mark is supposed to be a list. If it's not a list, an error message is generated.$p
  
  If it is a list, the result is the sublist beginning at element number $argu(start) (included) and finishing at
  element number $argu(end) (not included). Notice that numbering begins at $mtt(0), not $mtt(1).  
  If the value of $argu(start) or $argu(end) is out of bounds, this value is
  replaced by the actual bound which is $mtt(0) for $argu(start) and the length of the list for $argu(end). For example,
  
  $mcode($$sublist(-3)(4)($nolist([a,b,c,d,e,f,g,h,i,j,k]))$$par
$$sublist(0)(4)($nolist([a,b,c,d,e,f,g,h,i,j,k]))$$par
$$sublist(1)(4)($nolist([a,b,c,d,e,f,g,h,i,j,k])))
  produces:$p
  $sublist(-3)(4)([a,b,c,d,e,f,g,h,i,j,k])$par
  $sublist(0)(4)([a,b,c,d,e,f,g,h,i,j,k])$par
  $sublist(1)(4)([a,b,c,d,e,f,g,h,i,j,k])
  
  
  
  $mark1(sup)(text) This mark raises $argu(text) and renders it in a smaller size. For example, $mtt(x$$sup(1))
  produces x$sup(1). 
  
  $mark2(tbgc)(color)(text) This mark ($em(text background color)) shows $argu(text) over a background of color
  $argu(color). For example, $mtt($$tbgc($$_lavender)(Some text.))
  produces: $tbgc($_lavender)(Some text.) 
  $par$par
  This is valuable for short texts. For long texts, $ref(code)($mtt($$code(...))) may be more 
  appropriate. 
  
  $mark0(thisfilepath)
    This marks provides the absolute path of the file it is written into.$p
    
    $mtt($$thisfilepath) is $unsafe for the web, because it can reveal an absolute path of your web server. You should forbid
    it. 
  
  $mark2(tlink)(text)(url) This mark creates an hypertext link targeting the $argu(url), and shown as the clickable
  $argu(text) (which can also be an image).  For example, 
  $mcode($$tlink(Visit 
   $$big($$blue(G)$$red(o)$$yellow(o)$$blue(g)$$green(l)$$red(e)))
      (http://www.google.com))
  produces 
  $tlink(Visit 
     $big($blue(G)$red(o)$yellow(o)$blue(g)$green(l)$red(e)))(http://www.google.com)$ifhtml( (that 
  you can click upon)).  
  
  

  $mark1(transpose)(list of lists)
  This mark $em(transposes) (somehow as in mathematics) a list of lists considered as a $em(matrix). As an example,
  we define:
$mcode($$define(mylist)(0)($[$[a$,b$]$,$[c$,d$,e$]$,$[f$,g$]$])
$$define(addbox)(1)($$box(16)($$1))
$$define(separ)(1)($$apply(addbox)($$1)$$par))  
  
$define(mylist)(0)([[a,b],[c,d,e],[f,g]])
$define(addbox)(1)($box(16)($1))
$define(separ)(1)($apply(addbox)($1)$par)

Now, if we write $mtt($$apply(separ)($$mylist)), we obtain:
$p
$apply(separ)($mylist)
$par
and if we write $mtt($$apply(separ)($$transpose($$mylist))), we obtain:
$p
$apply(separ)($transpose($mylist))
$par
  
  
   Notice that if a line of the matrix is shorter than a subsequent line, $mtt($$transpose) automatically inserts $em(empty) 
   (invisible) elements in the
   transposed matrix so that items which are in the same $em(line) in the original matrix are in the same $em(column) in the
   transposed matrix.$p 
 
   This is useful (in conjunction with $ref(sublist)($mtt($$sublist))) and some $ref(arithmetics)(arithmetics) 
   for example for displaying a list of items on several columns, with the first group of elements in the first
   column (not the first line), the next group of elements in the second column, and so on. This can be used for example
   for automatically producing an index on several columns. This is also used in this tutorial for displaying the list
   of all marks on four columns $ref(catalog)(at the beginning of this section).$p
   
   Below is a simple example. We want to sort a list of words in alphabetic order and to present them on two columns. 
   $mcode(  $$// define a list of words
$$define(words)(0)
      ($[We$,want$,to$,sort$,a$,list$,of$,words$,and$,
        to$,present$,them$,in$,alphabetic$,order$,on$,two$,columns$]))

$define(words)(0)
  ([We,want,to,sort,a,list,of,words,and,to,present,them,in,alphabetic,order,on,two,columns])

   We prepare the sorting of the list by applying a $mtt($$box(120)) and a $mtt($$alphabetic) to all elements.
   $mcode($$define(a)(1)($$box(120)($$alphabetic($$1)))   $$// because $$apply accepts only macros
$$define(sortedwords)(0)($$sort($$apply(a)($$words))))   

$define(a)(1)($box(120)($alphabetic($1)))
$define(sortedwords)(0)($sort($apply(a)($words)))
so that $mtt($$sortedwords) looks like this:
$p
$sortedwords
$p
   Now, we compute the length of this list, divide it by $mtt(2) and add 1 if the remainder is not zero, 
   so that we can cut our list in two lists 
   of almost the same length (the first one with possibly one element more than the second one). 
$mcode($$define(halflen)(0)($$add($$quotient($$length($$sortedwords))(2))
  ($$if($$equals(0)($$remainder($$length($$sortedwords))(2)))(0)(1)))
$$define(column1)(0)($$sublist(0)($$halflen)($$sortedwords))   
$$define(column2)(0)($$sublist($$halflen)($$length($$sortedwords))($$sortedwords)))

$define(halflen)(0)($add($quotient($length($sortedwords))(2))
         ($if($equals(0)($remainder($length($sortedwords))(2)))(0)(1)))
$define(column1)(0)($sublist(0)($halflen)($sortedwords))   
$define(column2)(0)($sublist($halflen)($length($sortedwords))($sortedwords))   

Finally, we can get the wanted result by writing:
$define(putpar)(1)($1$par)
$mcode($$define(putpar)(1)($$1$$par)
$$center($$apply(putpar)($$transpose($[$$column1$,$$column2$]))))

$center($apply(putpar)($transpose([$column1,$column2])))
$p
   
   

  $mark0(true) This mark represents the truth value $em(true). 

  $mark1(tt)(text) This mark renders $argu(text) in fixed width (typewriter) font. It is similar to 
  $ref(code)($mtt($$code(...))), with the difference that $argu(text) is put inline instead of as a separate block. 
  For example, $mtt($$red($$tt(This)) is $$code(220,220,220)(an) example.)
  produces: $red($tt(This)) is $code(220,220,220)(an) example.
  $par$par
  See also $ref(code)($mtt($$code(...))) and $ref(verbatim)($mtt($$verbatim(...))).
  
  $mark1(undefine)(name) This mark allows to $em(undefine) a macro previously defined by $ref(define)($mtt($$define)). 
  Actually, it removes only the last definition of the macro whose name is given, so that the previous definition of
  this same mark name (if any) is working again. 
  If no macro with name $argu(name) exists, nothing happens. $par$par
  
  Example:
  $mcode($$define(emph)(1)($$italic($$1))
$$emph(text1)$$par
$$define(emph)(2)($$bold($$1):$$red($$2))
$$emph(text2a)(text2b)$$par
$$undefine(emph)
$$emph(text3))
  produces:$par$par
  
$define(emph)(1)($italic($1))
$emph(text1)$par
$define(emph)(2)($bold($1):$red($2))
$emph(text2a)(text2b)$par
$undefine(emph)
$emph(text3) 
  $par$par
  As a consequence, a $MAML  text can safely be embedded into another $MAML  text using $mtt($$input), provided
  that you $em(undefine) the macros defined in the embedded text at the end of the embedded text. $p
  
  As told in $ref(define)($mtt($$define)), $mtt($$define) doesn't allow recursion. However, if a macro with the same
  name is already defined, any usage of this macro name in the body of the new definition refers to the previous
  definition. For example, 
  $mcode($$define(bu)(1)($$italic($$1))
$$bu(Some text.)$$par
$$define(bu)(2)($$rgb(120,0,0)($$bu($$1) $$2))
$$bu(Text1)(Text2)) produces:$par$par


  $define(bu)(1)($italic($1))
  $bu(Some text.)$par
  $define(bu)(2)($rgb(120,0,0)($bu($1) $2))
  $bu(Text1)(Text2)$par 

  
  $mark1(verbatim)(text) This marks reproduces its content without any change with two exceptions. 
  Indeed, $MAML  marks within 
  $argu(text) are not interpreted, except the two marks $mtt($$lpar) and $mtt($$rpar), which allows you
  to produce unbalanced parentheses in $argu(text) despite the fact that actual parentheses $em(must) be 
  balanced in $argu(text). Example: 
  $par
  $mcode($$verbatim(In this ($$italic(text))(), ((parentheses) are) $$rpar$$rpar$$lpar balanced.))
  produces:
  $p
  $verbatim(In this ($italic(text))(), ((parentheses) are) $rpar$rpar$lpar balanced.)
  $p
  Nevertheless, colors are applied if $mtt($$verbatim(...)) is within a $mtt($$rgb(...)(...)). Indeed, 
  $mcode($$rgb(255,0,0)($$verbatim(Red verbatim text))) produces:
  $rgb(255,0,0)($verbatim(Red verbatim text))
  On the contrary, $mcode($$colorize(maml)($$verbatim(Red verbatim text))) produces:
  $colorize(maml)($verbatim(Red verbatim text))
  because $mtt($$verbatim) is not a macro. 
  $par 
  $par
  See also $ref(code)($mtt($$code(...))) and $ref(tt)($mtt($$tt(...))).
  $p$p
  
$center($big($big($big($big($colorize(funny)(Enjoy !))))))
  
$ifhtml($par$par$par$par$par$par$par$par)

$end