# Assembled with the script 'compile.pss' # create a dummy newline so that doc structures work even # on the first line of the file/stream. add "nl*" push start: read testclass [:space:] jumptrue block.end.12947 # count words per line with the accumulator a+ whilenot [:space:] put # image structure delimiters testis "[[" jumptrue 4 testis "]]" jumptrue 2 jump block.end.10986 put add "*" push jump parse block.end.10986: # an image position indicators, default is centre? testis ">>>" jumptrue 6 testis "<<<" jumptrue 4 testis "ccc" jumptrue 2 jump block.end.11108 put clear add "float*" push jump parse block.end.11108: # quotes for image captions. I will use """ to delimit # image captions, but not multiline. Because a run-away multiline # quote will eat up the whole document. Or use word parsing here testbegins "\"\"\"" jumpfalse block.end.11622 put clop clop clop testends "\"\"\"" jumpfalse 3 testis "\"\"\"" jumpfalse 2 jump block.end.11411 clear add "quote*" push jump parse block.end.11411: clear get whilenot ["\n] testeof jumptrue block.end.11476 read block.end.11476: testeof jumptrue block.end.11493 read block.end.11493: testeof jumptrue block.end.11510 read block.end.11510: testends "\"\"\"" jumptrue block.end.11568 put clear add "word*" push jump parse block.end.11568: put clear add "quote*" push jump parse block.end.11622: # widths for images in format eg 20% testends "%" jumpfalse 5 testis "%" jumptrue 3 testclass [0123456789%] jumptrue 2 jump block.end.11747 put clear add "width*" push jump parse block.end.11747: # image width in point format testends "pt" jumpfalse 5 testis "pt" jumptrue 3 testclass [0123456789pt] jumptrue 2 jump block.end.11867 put clear add "width*" push jump parse block.end.11867: testends "cm" jumpfalse 5 testis "cm" jumptrue 3 testclass [0123456789cm] jumptrue 2 jump block.end.11953 put clear add "width*" push jump parse block.end.11953: testends "mm" jumpfalse 5 testis "mm" jumptrue 3 testclass [0123456789mm] jumptrue 2 jump block.end.12039 put clear add "width*" push jump parse block.end.12039: testends "em" jumpfalse 5 testis "em" jumptrue 3 testclass [0123456789em] jumptrue 2 jump block.end.12125 put clear add "width*" push jump parse block.end.12125: # create an image file token for images. #E".png",E".jpg",E".jpeg",E".bmp",E".gif" { # these are the formats that pdflatex can handle testends ".png" jumptrue 10 testends ".jpg" jumptrue 8 testends ".jpeg" jumptrue 6 testends ".eps" jumptrue 4 testends ".pdf" jumptrue 2 jump block.end.12371 clear add "imfile*" push jump parse block.end.12371: # date and datelist tokens # post elimiate this enddatelist token testis "[/dates]" jumptrue 4 testis "[/date]" jumptrue 2 jump block.end.12533 put clear add "enddatelist*" push jump parse block.end.12533: testclass [0-9] jumpfalse block.end.12600 put clear add "number*" push jump parse block.end.12600: # case insensitive month names lower testis "jan" jumptrue 48 testis "january" jumptrue 46 testis "feb" jumptrue 44 testis "february" jumptrue 42 testis "mar" jumptrue 40 testis "march" jumptrue 38 testis "apr" jumptrue 36 testis "april" jumptrue 34 testis "may" jumptrue 32 testis "jun" jumptrue 30 testis "june" jumptrue 28 testis "jul" jumptrue 26 testis "july" jumptrue 24 testis "aug" jumptrue 22 testis "august" jumptrue 20 testis "sep" jumptrue 18 testis "sept" jumptrue 16 testis "september" jumptrue 14 testis "oct" jumptrue 12 testis "october" jumptrue 10 testis "nov" jumptrue 8 testis "november" jumptrue 6 testis "dec" jumptrue 4 testis "december" jumptrue 2 jump block.end.12903 put clear add "month*" push jump parse block.end.12903: clear add "word*" push jump parse block.end.12947: # keep leading space in newline token? testclass [\n] jumpfalse block.end.13185 # set accumulator == 0 so that we can count words # per line (and know which is the first word) zero nochars while [ ] put clear add "nl*" push jump parse block.end.13185: testclass [\r\t ] jumpfalse block.end.13223 clear testeof jumptrue block.end.13221 jump start block.end.13221: block.end.13223: parse: # for debugging, add % as a latex comment. add "%%> line " ll add " char " cc add ": " print clear unstack print stack add "\n" print clear # ------------------ # Datelists: including numbers/months/dates # I will try to put all datelist related stuff here for the # sake of organisation. pop pop pop pop # A 4 token datelist test. This needs to come first after the # parse> label because there is no special date list start token # (a date can start a datelist or continue it). # need to preserve the nl* token because other markup requires it. testis "datelist*text*date*nl*" jumpfalse block.end.14489 clear # if text is empty (meaning a date with no text) we need to # add some text or else LaTeX may think that we are nesting # a list. ++ get testis "" jumptrue 4 testclass [:space:] jumptrue 2 jump block.end.14081 clear add "..." put block.end.14081: -- clear # already have \item start get add " " ++ get ++ # also, put a \verbatim in [] because text is not escaped?? add "\n \\item[" get add "] " # add add an empty text token to avoid dealing with dates # with no text. -- -- put clear ++ put -- clear add "\n" ++ ++ put -- -- clear add "datelist*text*nl*" push push push jump parse block.end.14489: push push push push pop pop # --------------- # 2 token datelist reductions. #---------------- # dates for datelists # dates begin on a newline and each date begins a list item. # start a new datelist (we have already checked above for # an existing datelist with the rules datelist*text*date* and # datelist*date* testis "date*nl*" jumpfalse block.end.15127 clear add "\n \\item[" get add "]" put # add an empty text* token so that we dont have to worry # about dates with no text clear ++ put -- clear add "\n" ++ ++ put -- -- clear add "datelist*text*nl*" push push push jump parse block.end.15127: # ------------------ # 2 token datelists reductions # vanish numbers if not first on line or preceded by month* testends "number*" jumpfalse 9 testis "number*" jumptrue 7 testbegins "nl*" jumptrue 5 testbegins "bl*" jumptrue 3 testbegins "month*" jumpfalse 2 jump block.end.15356 replace "number*" "word*" push push jump parse block.end.15356: testbegins "number*" jumpfalse 9 testis "number*" jumptrue 7 testends "nl*" jumptrue 5 testends "bl*" jumptrue 3 testends "month*" jumpfalse 2 jump block.end.15465 replace "number*" "word*" push push jump parse block.end.15465: # vanish months if not between day/year or first on line # this should allow eg "aug 2022" and "30 aug 2022" testends "month*" jumpfalse 9 testis "month*" jumptrue 7 testbegins "nl*" jumptrue 5 testbegins "bl*" jumptrue 3 testbegins "number*" jumpfalse 2 jump block.end.15686 replace "month*" "word*" push push jump parse block.end.15686: testbegins "month*" jumpfalse 5 testis "month*" jumptrue 3 testends "number*" jumpfalse 2 jump block.end.15777 replace "month*" "word*" push push jump parse block.end.15777: # tokenlist: # --- >> 4dots codeblock codeline emline nl text uutext uuword word # month number date datelist ulist olist dlist # remove pesky newline tokens, 4dots handled elsewhere #"nl*text*","nl*word*","nl*emline*","nl*codeline*", #"nl*codeblock*" # vanish nl/bl when not needed. testis "nl*date*" jumptrue 36 testis "bl*date*" jumptrue 34 testis "nl*enddatelist*" jumptrue 32 testis "bl*enddatelist*" jumptrue 30 testis "nl*ulist*" jumptrue 28 testis "bl*ulist*" jumptrue 26 testis "nl*olist*" jumptrue 24 testis "bl*olist*" jumptrue 22 testis "nl*dlist*" jumptrue 20 testis "bl*dlist*" jumptrue 18 testis "nl*datelist*" jumptrue 16 testis "bl*datelist*" jumptrue 14 testis "nl*codeline*" jumptrue 12 testis "bl*codeline*" jumptrue 10 testis "nl*codeblock*" jumptrue 8 testis "bl*codeblock*" jumptrue 6 testis "nl*emline*" jumptrue 4 testis "bl*emline*" jumptrue 2 jump block.end.16479 # delete nl token clop clop clop push clear # ignore newline get -- put ++ clear jump parse block.end.16479: # vanish enddatelist* if it wasnt already reduced. testbegins "enddatelist*" jumpfalse 3 testis "enddatelist*" jumpfalse 2 jump block.end.16635 replace "enddatelist*" "text*" push push jump parse block.end.16635: pop # ----------------- # 3 token datelists testis "text*text*enddatelist*" jumpfalse block.end.16838 clear get ++ get -- put clear ++ put -- add "text*enddatelist*" push push jump parse block.end.16838: # vanish strange date tokens. testis "month*number*month*" jumpfalse block.end.16967 clear add "word*word*word*" push push push jump parse block.end.16967: # finish off the date list # we will make enddatelist chew up previous text tokens so: # enddatelist ::= text enddatelist # This allows to resolve # text ::= datelist*text*text*enddatelist* # This in turn allows us to include more markup in lists. # Each token is responsible for turning itself into text* when # it is no longer needed. testis "datelist*text*enddatelist*" jumpfalse block.end.17836 clear # if text is empty (meaning a date with no text) we need to # add some text or else LaTeX may think that we are nesting # a list. ++ get testis "" jumptrue 4 testclass [:space:] jumptrue 2 jump block.end.17569 clear add "..." put block.end.17569: -- clear add "\n \\begin{description}[style=nextline]\n" get add "\n " ++ get -- add "\n \\end{description}\n\n" put clear # insert the blankline attribute add "\n\n" ++ put -- clear add "text*" push jump parse block.end.17836: # ------------------------- # 5 token datelist reductions pop pop # resolve dates, but need to leave the trailing newline # because it is used for many other things testis "nl*number*month*number*nl*" jumptrue 4 testis "bl*number*month*number*nl*" jumptrue 2 jump block.end.19155 clear ++ get -- # make sure 1st number is a valid day number testis "0" jumptrue 8 testis "00" jumptrue 6 testis "000" jumptrue 4 testis "0000" jumptrue 2 jump block.end.18254 clear add "word*word*word*" push push push jump parse block.end.18254: clip clip # >2 digits, not day number testis "" jumptrue block.end.18388 clear add "word*word*word*" push push push jump parse block.end.18388: clear ++ get -- # is valid day number (01-31 or 1-31) # this is tricky clear # now check the year number ++ ++ ++ get -- -- -- clip clip # less than 3 digits not allowed for year testbegins "0" jumptrue 4 testis "" jumptrue 2 jump block.end.18705 clear add "word*word*word*" push push push jump parse block.end.18705: clip clip # >4 digits, not a year testis "" jumptrue block.end.18835 clear add "word*word*word*" push push push jump parse block.end.18835: # now assemble date value ++ get add " " ++ get add " " ++ get lower replace "jan " "January " replace "feb " "February " replace "mar " "March " -- -- -- put clear # conserve trainling newline add "\n" ++ put -- clear add "date*nl*" push push jump parse block.end.19155: # end datelist parsing push push push push push # ------------- # General token parsing. # 1 token pop testis "nl*" jumpfalse block.end.19298 nop block.end.19298: # here we classify words into other tokens # we can use accumulator with a+ a- to determine if current # word is the first word of the line, or even count number of # words per line. This should simplify grammar items such as # nl/--- and nl/star/ etc # another advantage, is that we can dispense with tokens such as # ---, >> etc and not have to get rid of them later. testis "word*" jumpfalse block.end.27259 clear get # no numbers in headings! testclass [A-Z] jumpfalse block.end.19796 clear add "uuword*" push jump parse block.end.19796: # at least three --- on a newline marks a code block start # use 'count;' here to simplify. The token --- probably doesnt # need to exist. testbegins "---" jumpfalse 3 testclass [-] jumptrue 2 jump block.end.20001 clear add "---*" push jump parse block.end.20001: testis ">>" jumpfalse block.end.20039 add "*" push jump parse block.end.20039: # subheading marker testbegins "...." jumpfalse 3 testclass [.] jumptrue 2 jump block.end.20120 clear add "4dots*" push jump parse block.end.20120: # dash is used for lists # only make a dash token if it is first word on the line testis "-" jumpfalse block.end.20316 clear count testis "1" jumpfalse block.end.20292 clear add "dash*" push jump parse block.end.20292: clear get block.end.20316: # ordered list start token # only make token if it is first word on the line testis "o/-" jumptrue 6 testis "O/-" jumptrue 4 testis "0/-" jumptrue 2 jump block.end.20527 clear count testis "1" jumpfalse block.end.20503 clear put add "olist*" push jump parse block.end.20503: clear get block.end.20527: # unordered list start token testis "u/-" jumptrue 4 testis "U/-" jumptrue 2 jump block.end.20680 clear count testis "1" jumpfalse block.end.20656 clear put add "ulist*" push jump parse block.end.20656: clear get block.end.20680: # definition/description list start token # need to parse a bit differently because of the desc testis "d/-" jumptrue 4 testis "D/-" jumptrue 2 jump block.end.21162 clear count testis "1" jumpfalse block.end.21138 clear # read description here, but have to escape special # verb cant go in here. Special chars will crash this. add "\n \\item[" whilenot [\n:] add "]" put # remove ":" or \n testeof jumptrue block.end.21085 read block.end.21085: clear add "dlist*" push jump parse block.end.21138: clear get block.end.21162: # star on newline marks emphasis, list or code description # probably dont need star token. testis "*" jumpfalse block.end.21700 # check that * is 1st 'word' on line using accumulator clear count testis "1" jumptrue block.end.21388 clear add "*" block.end.21388: testis "1" jumpfalse block.end.21694 clear while [ \t\f] clear whilenot [\n] cap put clear # this is a trick, because we want special LaTeX chars to # be escaped. So, will add \\emph{} after next replace code. add "::EMPH::" get put #add "emline*"; push; .reparse block.end.21694: block.end.21700: # need to escape % # } \ and others # & % $ # _ { } ~ ^ \ # \textasciitilde, \textasciicircum, and \textbackslash replace "\\" "\\textbackslash " replace "&" "\\&" replace "%" "\\%" replace "$" "\\$" replace "#" "\\#" replace "_" "\\_" replace "{" "\\{" replace "}" "\\}" replace "~" "\\textasciitilde" replace "^" "\\textasciicircum" replace ">" "\\textgreater " replace "<" "\\textless " replace "LaTeX" "\\LaTeX{}" # now make the emphasis line token, after special chars have # been escaped. testbegins "::EMPH::" jumpfalse block.end.22411 replace "::EMPH::" " \\emph{" add "}" put clear add "emline*" push jump parse block.end.22411: # If a previous test has matched, then the workspace should # be clear, and so none of the following will match. # graphical key representations testbegins "[" jumpfalse 3 testends "]" jumptrue 2 jump block.end.23002 replace "[esc]" "\\Esc" replace "[enter]" "\\Enter" replace "[return]" "\\Enter" replace "[insert]" "\\Ins" replace "[shift]" "\\Shift" replace "[delete]" "\\Del" replace "[home]" "\\Home" # keys defined by 'keystroke' package, can make new ones. # \Enter \Del \Ins \Esc \Shift \Ctrl \Home # \End \PgUp \PgDown \PrtSc \Scroll \Break block.end.23002: #replace '\\n' "\\textbackslash n"; #replace '\\f' "\\textbackslash f"; #replace '\\r' "\\textbackslash r"; #replace '\\t' "\\textbackslash t"; put # urls, not so important for LaTex (and pdf) output. # Dont really need a token because we can render immediately # Could maybe render them as footnotes testbegins "http://" jumptrue 10 testbegins "https://" jumptrue 8 testbegins "www." jumptrue 6 testbegins "ftp://" jumptrue 4 testbegins "sftp://" jumptrue 2 jump block.end.23544 # clear; add "url*"; push; .reparse # render as fixed pitch font clear add "\\url{" get add "}" put clear block.end.23544: # format acronyms as a small capital font, case insensitive lower testis "antlr" jumptrue 14 testis "pdf" jumptrue 12 testis "json" jumptrue 10 testis "ebnf" jumptrue 8 testis "bnf" jumptrue 6 testis "dns" jumptrue 4 testis "html" jumptrue 2 jump block.end.23745 clear add "\\textsc{\\textbf{" get add "}}" put clear block.end.23745: # restore the mixed-case version of the input word testis "" jumptrue block.end.23824 clear get block.end.23824: # filenames, could be elided with quoted filenames testis "parse>" jumptrue 120 testis "print" jumptrue 118 testis "pop" jumptrue 116 testis "push" jumptrue 114 testis "get" jumptrue 112 testis "put" jumptrue 110 testis ".reparse" jumptrue 108 testis ".restart" jumptrue 106 testis "add" jumptrue 104 testis "sed" jumptrue 102 testis "awk" jumptrue 100 testis "grep" jumptrue 98 testis "pep" jumptrue 96 testis "nom" jumptrue 94 testis "less" jumptrue 92 testis "stdin" jumptrue 90 testis "stdout" jumptrue 88 testis "bash" jumptrue 86 testis "lex" jumptrue 84 testis "yacc" jumptrue 82 testis "flex" jumptrue 80 testis "bison" jumptrue 78 testis "lalr" jumptrue 76 testis "gnu" jumptrue 74 testends ".h" jumptrue 72 testends ".c" jumptrue 70 testends ".a" jumptrue 68 testends ".txt" jumptrue 66 testends ".doc" jumptrue 64 testends ".py" jumptrue 62 testends ".rb" jumptrue 60 testends ".rs" jumptrue 58 testends ".java" jumptrue 56 testends ".class" jumptrue 54 testends ".tcl" jumptrue 52 testends ".tk" jumptrue 50 testends ".sw" jumptrue 48 testends ".js" jumptrue 46 testends ".go" jumptrue 44 testends ".pp" jumptrue 42 testends ".pss" jumptrue 40 testends ".cpp" jumptrue 38 testends ".pl" jumptrue 36 testends ".html" jumptrue 34 testends ".pdf" jumptrue 32 testends ".tex" jumptrue 30 testends ".sh" jumptrue 28 testends ".css" jumptrue 26 testends ".out" jumptrue 24 testends ".log" jumptrue 22 testends ".png" jumptrue 20 testends ".jpg" jumptrue 18 testends ".jpeg" jumptrue 16 testends ".bmp" jumptrue 14 testends ".mp3" jumptrue 12 testends ".wav" jumptrue 10 testends "aux" jumptrue 8 testends ".tar" jumptrue 6 testends ".gz" jumptrue 4 testends "/" jumptrue 2 jump block.end.24434 clear add "\\texttt{" get add "}" put clear block.end.24434: # mark up language names testis "python" jumptrue 20 testis "java" jumptrue 18 testis "ruby" jumptrue 16 testis "perl" jumptrue 14 testis "tcl" jumptrue 12 testis "rust" jumptrue 10 testis "swift" jumptrue 8 testis "markdown" jumptrue 6 testis "c" jumptrue 4 testis "c++" jumptrue 2 jump block.end.24619 clear add "\\textit{\\texttt{" get add "}}" put clear block.end.24619: # paths and directories ? testbegins "../" jumpfalse 3 testis "../" jumpfalse 2 jump block.end.24733 clear add "\\texttt{" get add "}" put clear block.end.24733: testbegins "\"" jumpfalse 7 testends "\"" jumpfalse 5 testis "\"\"" jumptrue 3 testis "\"" jumpfalse 2 jump block.end.25995 # filenames in quotes clip clop put # quoted uppercase words in headings testclass [A-Z] jumpfalse block.end.25021 # add LaTeX curly quotes to the heading word clear add "``" get add "''" put clear add "uuword*" push jump parse block.end.25021: # markup language names testis "python" jumptrue 22 testis "java" jumptrue 20 testis "ruby" jumptrue 18 testis "perl" jumptrue 16 testis "tcl" jumptrue 14 testis "rust" jumptrue 12 testis "swift" jumptrue 10 testis "markdown" jumptrue 8 testis "c" jumptrue 6 testis "c++" jumptrue 4 testis "forth" jumptrue 2 jump block.end.25227 clear add "``\\textit{\\texttt{" get add "}}''" put clear block.end.25227: # markup filenames and some unix and pep/nom names as fixed-pitch # font. testis "pep" jumptrue 110 testis "parse>" jumptrue 108 testis "print" jumptrue 106 testis "pop" jumptrue 104 testis "push" jumptrue 102 testis "get" jumptrue 100 testis "put" jumptrue 98 testis ".reparse" jumptrue 96 testis ".restart" jumptrue 94 testis "add" jumptrue 92 testis "sed" jumptrue 90 testis "awk" jumptrue 88 testis "grep" jumptrue 86 testis "pep" jumptrue 84 testis "nom" jumptrue 82 testis "less" jumptrue 80 testis "stdin" jumptrue 78 testis "stdout" jumptrue 76 testis "bash" jumptrue 74 testends ".h" jumptrue 72 testends ".c" jumptrue 70 testends ".a" jumptrue 68 testends ".txt" jumptrue 66 testends ".doc" jumptrue 64 testends ".py" jumptrue 62 testends ".rb" jumptrue 60 testends ".rs" jumptrue 58 testends ".java" jumptrue 56 testends ".class" jumptrue 54 testends ".tcl" jumptrue 52 testends ".tk" jumptrue 50 testends ".sw" jumptrue 48 testends ".js" jumptrue 46 testends ".go" jumptrue 44 testends ".pp" jumptrue 42 testends ".pss" jumptrue 40 testends ".cpp" jumptrue 38 testends ".pl" jumptrue 36 testends ".html" jumptrue 34 testends ".pdf" jumptrue 32 testends ".tex" jumptrue 30 testends ".sh" jumptrue 28 testends ".css" jumptrue 26 testends ".out" jumptrue 24 testends ".log" jumptrue 22 testends ".png" jumptrue 20 testends ".jpg" jumptrue 18 testends ".jpeg" jumptrue 16 testends ".bmp" jumptrue 14 testends ".mp3" jumptrue 12 testends ".wav" jumptrue 10 testends "aux" jumptrue 8 testends ".tar" jumptrue 6 testends ".gz" jumptrue 4 testends ";" jumptrue 2 jump block.end.25854 clear add "``\\texttt{" get add "}''" put clear block.end.25854: # everything else in quotes (but only words without spaces!) testis "" jumptrue block.end.25989 clear add "``\\textit{" get add "}''" put clear block.end.25989: block.end.25995: # filenames # crude pattern checking. testbegins "/" jumpfalse 3 testis "/" jumpfalse 2 jump block.end.26278 clip testends "." jumpfalse block.end.26130 clear add "\\texttt{" get add "}" put clear block.end.26130: clip testends "." jumpfalse block.end.26201 clear add "\\texttt{" get add "}" put clear block.end.26201: clip testends "." jumpfalse block.end.26272 clear add "\\texttt{" get add "}" put clear block.end.26272: block.end.26278: # emphasis is *likethis* (only words, not phrases) testbegins "*" jumpfalse 5 testends "*" jumpfalse 3 testis "**" jumpfalse 2 jump block.end.26451 clip clop put clear add "\\textbf{\\emph{" get add "}}" put clear block.end.26451: # && starting a line marks the document title # the document 'title' after && or first heading, & has already # been escaped testis "\\&\\&" jumpfalse block.end.26816 clear count testis "1" jumpfalse block.end.26810 clear while [ \t\f] clear whilenot [\n] put clear add "\\centerline{\\Large \\bf " get add "} \\medskip \n" put clear block.end.26810: block.end.26816: # A quote, starting the line testis "quote:" jumpfalse block.end.27230 clear count testis "1" jumpfalse block.end.27224 # \begin{center} # {\huge \`\`}\textit{$quote}{\huge ''} # \textsc{$quoteauthor} # \end{center} clear while [ \t\f] clear whilenot [\n] put clear add "\\begin{center}{\\huge ``}\\textit{" get add "}{\\huge ''}\\end{center} \n" put clear block.end.27224: block.end.27230: clear add "word*" block.end.27259: pop # ------------- # 2 tokens #-------------------- # images # standard format is [[*imfile*quote*width*float*]]* # A width is "50%" or "200pt"; float is left/right/center # imfile is a image file name. quote/width/float are optional # tokens. The order of tokens is mandatory # remove newline and blank line tokens when parsing # images. But this is tricky, because we want to preserve # them otherwise. # remove nl/bl tokens in image formats testis "[[*nl*" jumptrue 20 testis "[[*bl*" jumptrue 18 testis "imfile*nl*" jumptrue 16 testis "imfile*bl*" jumptrue 14 testis "quote*nl*" jumptrue 12 testis "quote*bl*" jumptrue 10 testis "width*nl*" jumptrue 8 testis "width*bl*" jumptrue 6 testis "float*nl*" jumptrue 4 testis "float*bl*" jumptrue 2 jump block.end.27895 push clear jump parse block.end.27895: # vanish [[ if not followed by imfile testbegins "[[*" jumpfalse 5 testis "[[*" jumptrue 3 testends "imfile*" jumpfalse 2 jump block.end.28020 replace "[[*" "word*" push push jump parse block.end.28020: # vanish ]] testends "]]*" jumpfalse 11 testis "]]*" jumptrue 9 testbegins "imfile*" jumptrue 7 testbegins "float*" jumptrue 5 testbegins "quote*" jumptrue 3 testbegins "width*" jumpfalse 2 jump block.end.28154 replace "]]*" "word*" push push jump parse block.end.28154: # vanish imfiles testbegins "imfile*" jumpfalse 11 testis "imfile*" jumptrue 9 testends "float*" jumptrue 7 testends "quote*" jumptrue 5 testends "width*" jumptrue 3 testends "]]*" jumpfalse 2 jump block.end.28298 replace "imfile*" "word*" push push jump parse block.end.28298: testends "imfile*" jumpfalse 3 testbegins "[[*" jumpfalse 2 jump block.end.28377 replace "imfile*" "word*" push push jump parse block.end.28377: # vanish quotes testbegins "quote*" jumpfalse 9 testis "quote*" jumptrue 7 testends "float*" jumptrue 5 testends "width*" jumptrue 3 testends "]]*" jumpfalse 2 jump block.end.28505 replace "quote*" "word*" push push jump parse block.end.28505: testends "quote*" jumpfalse 5 testis "quote*" jumptrue 3 testbegins "imfile*" jumpfalse 2 jump block.end.28596 replace "quote*" "word*" push push jump parse block.end.28596: # vanish widths testbegins "width*" jumpfalse 7 testis "width*" jumptrue 5 testends "float*" jumptrue 3 testends "]]*" jumpfalse 2 jump block.end.28713 replace "width*" "word*" push push jump parse block.end.28713: testends "width*" jumpfalse 7 testis "width*" jumptrue 5 testbegins "quote*" jumptrue 3 testbegins "imfile*" jumpfalse 2 jump block.end.28815 replace "width*" "word*" push push jump parse block.end.28815: # vanish floats testbegins "float*" jumpfalse 5 testis "float*" jumptrue 3 testends "]]*" jumpfalse 2 jump block.end.28921 replace "float*" "word*" push push jump parse block.end.28921: testends "float*" jumpfalse 9 testis "float*" jumptrue 7 testbegins "width*" jumptrue 5 testbegins "quote*" jumptrue 3 testbegins "imfile*" jumpfalse 2 jump block.end.29034 replace "float*" "word*" push push jump parse block.end.29034: # Add missing attributes here. This is a technique for # providing "optionality" in pep/nom scripts testis "width*]]*" jumpfalse block.end.29345 clear add "width*float*]]*" push push push # also add an appropriate attribute for a center float -- -- get ++ put clear -- put ++ ++ jump parse block.end.29345: testis "quote*]]*" jumptrue 4 testis "quote*float*" jumptrue 2 jump block.end.29590 replace "quote*" "quote*width*" push push push # now transfer the attributes and add null quote -- -- get ++ put # or add an appropriate width clear -- put ++ ++ jump parse block.end.29590: testis "imfile*]]*" jumptrue 6 testis "imfile*width*" jumptrue 4 testis "imfile*float*" jumptrue 2 jump block.end.29878 replace "imfile*" "imfile*quote*" push push push # ws should be clear # now transfer the attributes and add null quote -- -- get ++ put # or put a null quote here. clear -- put ++ ++ jump parse block.end.29878: # End image token manipulation # ellide text testis "text*text*" jumptrue 16 testis "word*text*" jumptrue 14 testis "word*word*" jumptrue 12 testis "text*word*" jumptrue 10 testis "word*uuword*" jumptrue 8 testis "text*uuword*" jumptrue 6 testis "uutext*word*" jumptrue 4 testis "uuword*word*" jumptrue 2 jump block.end.30137 clear get add " " ++ get -- put clear add "text*" push jump parse block.end.30137: # tokenlist: # --- >> 4dots codeblock codeline emline nl text uutext uuword word # codeblock, # remove pesky newline tokens, 4dots handled elsewhere # not really working # "nl*text*","nl*word*","nl*emline*","nl*codeline*", # "nl*codeblock*" { # # delete nl token # clop; clop; clop; push; clear; # # ignore newline # get; --; put; ++; clear; # .reparse # } # testis "nl*text*" jumptrue 8 testis "nl*word*" jumptrue 6 testis "bl*text*" jumptrue 4 testis "bl*word*" jumptrue 2 jump block.end.30652 clear get ++ get -- put clear add "text*" push jump parse block.end.30652: testis "nl*dash*" jumpfalse block.end.30745 clear get ++ get -- put clear add "dash*" push jump parse block.end.30745: testis "nl*emline*" jumptrue 4 testis "bl*emline*" jumptrue 2 jump block.end.30850 clear ++ get -- put clear add "emline*" push jump parse block.end.30850: # We are using a dummy nl* token at the start of the doc, so the # codeblock* codeline* etc tokens are not able to be the first token # of the document. So we can remove the !"codeblock*". clause. # multiline codeblocks with no caption testends "codeblock*" jumpfalse 5 testis "codeblock*" jumptrue 3 testbegins "emline*" jumpfalse 2 jump block.end.31308 replace "codeblock*" "text*" push push clear add "\n\n \\begin{tabular}{l}\n " -- get add " \\end{tabular} \n" put ++ clear jump parse block.end.31308: # single line code with no caption testends "codeline*" jumpfalse 5 testis "codeline*" jumptrue 3 testbegins "emline*" jumpfalse 2 jump block.end.31555 replace "codeline*" "text*" push push clear add "\n\n \\begin{tabular}{l}\n " -- get add " \\end{tabular} \n" put ++ clear jump parse block.end.31555: # eliminate emline* tokens (not followed by codeblock/line) # the logic is slightly different because emline* is significant before # other tokens, not after. # also, consider emline*text*nl* testbegins "emline*" jumpfalse 7 testends "nl*" jumptrue 5 testends "codeline*" jumptrue 3 testends "codeblock*" jumpfalse 2 jump block.end.32110 replace "emline*" "text*" push push # make emline display on its own line, even when not # followed by codeline/codeblock. LaTeX will treat a blank line # as a paragraph break, but \newline or \\ could be used. -- -- add "\n\n" get add "\n\n" put clear jump parse block.end.32110: # remove insignificant 4dots* tokens, # 4 dots (....) marks a subheading and always comes at the end of # all capitals line. Just replacing the 4dots token with a text # token is safer and more logical. testends "4dots*" jumpfalse 5 testbegins "uutext*" jumptrue 3 testbegins "uuword*" jumpfalse 2 jump block.end.32417 replace "4dots*" "text*" push push jump parse block.end.32417: # remove insignificant ---* tokens testends "---*" jumpfalse 5 testbegins "nl*" jumptrue 3 testbegins "bl*" jumpfalse 2 jump block.end.32569 clear get add " " ++ get -- put clear add "text*" push jump parse block.end.32569: # remove insignificant >>* tokens # lets assume that codelines cant start a document? Or lets # generate a dummy nl* token at the start of the document to # make parsing easier. testends ">>*" jumpfalse 5 testbegins "nl*" jumptrue 3 testbegins "bl*" jumpfalse 2 jump block.end.32920 #clear; get; add " "; ++; get; --; put; clear; #add "text*"; push; .reparse replace ">>*" "text*" push push jump parse block.end.32920: # ellide upper case text testis "uuword*uuword*" jumptrue 4 testis "uutext*uuword*" jumptrue 2 jump block.end.33076 clear get add " " ++ get -- put clear add "uutext*" push jump parse block.end.33076: # a blank line token for terminating lists etc # bl/bl should not happen really testis "nl*nl*" jumptrue 6 testis "bl*nl*" jumptrue 4 testis "bl*bl*" jumptrue 2 jump block.end.33268 clear get ++ get -- put clear add "bl*" push jump parse block.end.33268: # code line (starts with >>) testis "bl*>>*" jumptrue 4 testis "nl*>>*" jumptrue 2 jump block.end.33612 # ignore leading space. clear while [ \t\f] clear # escape | so it doesnt terminate the verb environment. # but how to do it? or use lstlisting whilenot [\n] put clear add " \\verb| " get add " |\n" put clear add "codeline*" push jump parse block.end.33612: # code block marker testis "bl*---*" jumptrue 4 testis "nl*---*" jumptrue 2 jump block.end.33931 clear until ",,," clip clip clip # remove excessive indentation. replace "\n " "\n" put while [,] clear add "\n \\begin{lstlisting}[breaklines]" get add "\n \\end{lstlisting} \n" put clear add "codeblock*" push jump parse block.end.33931: # a code block with its preceding description testis "emline*codeblock*" jumpfalse block.end.34175 clear add "\n\n \\begin{tabular}{l}\n " get add " \\\\ " ++ get -- add " \\end{tabular} \n" put clear add "text*" push jump parse block.end.34175: # a code line with its preceding description # add some tabular LaTeX markup here. testis "emline*codeline*" jumpfalse block.end.34490 clear add "\n\n \\begin{tabular}{l}\n " get add " \\\\ \n" ++ get -- add " \\end{tabular} \n" #add " \\end{figure}"; put clear add "text*" push jump parse block.end.34490: # probably indicates an empty - at the end of a list # add a dummy text token testis "olist*bl*" jumptrue 6 testis "ulist*bl*" jumptrue 4 testis "dlist*bl*" jumptrue 2 jump block.end.34737 push clear add "empty" put clear add "\n\n" ++ put -- clear add "text*bl*" push push jump parse block.end.34737: # or use this to terminate the list, and so allow nested lists testis "olist*dash*" jumptrue 6 testis "ulist*dash*" jumptrue 4 testis "dlist*dash*" jumptrue 2 jump block.end.34939 push clear add "empty" put clear add "text*dash*" push push jump parse block.end.34939: pop # ------------- # 3 tokens testis "olist*word*dash*" jumptrue 12 testis "ulist*word*dash*" jumptrue 10 testis "dlist*word*dash*" jumptrue 8 testis "olist*word*bl*" jumptrue 6 testis "ulist*word*bl*" jumptrue 4 testis "dlist*word*bl*" jumptrue 2 jump block.end.35182 replace "word*" "text*" # or dont reparse # push; push; push; .reparse block.end.35182: # eliminate dashes that are not part of a list # eg: ulist*dash* olist*text*dash* dlist*word*dash* # the logic is tricky, how do we know there are really 3 tokens # here, and not 2. This is the problem with negative tests. # doesnt matter because not altering attributes here. testends "dash*" jumpfalse block.end.35606 testbegins "ulist*text*" jumptrue 5 testbegins "olist*text*" jumptrue 3 testbegins "dlist*text*" jumpfalse 2 jump block.end.35602 replace "dash*" "text*" push push push jump parse block.end.35602: block.end.35606: testis "olist*text*dash*" jumpfalse block.end.35730 clear get add "\n \\item " ++ get -- put clear add "olist*" push jump parse block.end.35730: # could be ellided, but for readability, no testis "ulist*text*dash*" jumpfalse block.end.35900 clear get add "\n \\item " ++ get -- put clear add "ulist*" push jump parse block.end.35900: # testis "dlist*text*dash*" jumpfalse block.end.36291 clear # already have \item start get add " " ++ get -- # also, put a \verbatim in [] because text is not escaped?? # The definition term is delimited by a newline or a ":" character add "\n \\item[" whilenot [\n:] add "] " put # get rid of the trailing ":" testeof jumptrue block.end.36247 read block.end.36247: clear add "dlist*" push jump parse block.end.36291: # finish off the ordered list, also could finish it off with # ulist*dash* ?? testis "olist*text*bl*" jumpfalse block.end.36654 clear add "\n \\begin{enumerate}\n" get add "\n \\item " ++ get -- add "\n \\end{enumerate}\n\n" put clear # insert the blankline attribute add "\n\n" ++ put -- clear add "text*bl*" push push jump parse block.end.36654: # finish off the unordered list testis "ulist*text*bl*" jumpfalse block.end.36965 clear add "\n \\begin{itemize}\n" get add "\n \\item " ++ get -- add "\n \\end{itemize}\n\n" put clear # insert the blankline attribute add "\n\n" ++ put -- clear add "text*bl*" push push jump parse block.end.36965: # finish off the description list testis "dlist*text*bl*" jumpfalse block.end.37407 # or check here if it is D/- or d/- for nextline style # or use \hfill \\ on each item which also works clear add "\n \\begin{description}[style=nextline]\n" get add "\n " ++ get -- add "\n \\end{description}\n\n" put clear # insert the blankline attribute add "\n\n" ++ put -- clear add "text*bl*" push push jump parse block.end.37407: # top level headings, all upper case on the line in the source document. # dont need a "heading" token because we dont parse the document as a # heirarchy, we just render things as we find them in the stream. testis "nl*uutext*nl*" jumptrue 8 testis "nl*uuword*nl*" jumptrue 6 testis "bl*uutext*nl*" jumptrue 4 testis "bl*uuword*nl*" jumptrue 2 jump block.end.38380 clear # Check that heading is at least 4 chars ++ get -- clip clip clip testis "" jumpfalse block.end.37856 add "nl*text*nl*" push push push jump parse block.end.37856: clear # make headings capital case ++ get # capitalise even 1st word in latex curly quotes # add "<>>" jumpfalse 2 jump block.end.41163 clear add "c" block.end.41163: testis "ccc" jumpfalse block.end.41193 clear add "c" block.end.41193: # centre testis "<<<" jumpfalse block.end.41232 clear add "l" block.end.41232: # left testis ">>>" jumpfalse block.end.41269 clear add "r" block.end.41269: # right put clear add "\n\\begin{wrapfigure}{" # position attribute get add "}{" # width attribute -- get add "}\n" add "\\includegraphics[width=" # width attribute again get -- -- add "]{" # image file name get -- add "}" add "\n\\centering\n" # the * removes the "figure" prefix add "\\caption*{" # get the quote attribute ++ ++ get -- -- add "}\n\\end{wrapfigure}" put clear add "text*" push jump parse block.end.41786: # example: 75% page width # \includegraphics[width=0.75\textwidth]{image/test.jpg} push push push push push push testeof jumpfalse block.end.46517 # or use 'unstack' but does it adjust the tape pointer? pop pop pop pop pop pop # "nl*word*","nl*text*" have already been dealt with. # we would like "permissive" parsing, because this is just # a document format, not code, so will just check for starting # text token #"text*nl*","text*bl","text*" { testbegins "text*" jumptrue 4 testbegins "word*" jumptrue 2 jump block.end.46319 # show the token parse stack at the top of the document ++ put clear add "%% Document parse-stack is: " get add "\n" -- clear # make a valid LaTeX document add "\n" add " %% \n" add " %% -------------------------------------------\n" add " %% latex generated by: mark.latex.pss \n" add " %% from source file : \n" add " %% on: \n" add " %% -------------------------------------------\n" add "\n" add " \\documentclass[a4paper,12pt]{article}\n" add " \\usepackage[margin=4pt,noheadfoot]{geometry}\n" add " \\usepackage{color} %% to use colours, use 'xcolor' for more\n" add " \\usepackage{multicol} %% for multiple columns\n" add " \\usepackage{keystroke} %% for keyboard key images\n" add " \\usepackage[toc]{multitoc} %% for multi column table of contents\n" add " \\usepackage{tocloft} %% to customize the table of contents\n" add " \\setcounter{tocdepth}{2} %% only display 2 levels in the contents\n" add " \\setlength{\\cftbeforesecskip}{0cm} %% make the toc more compact\n" add " \\usepackage{listings} %% for nice code listings\n" add " \\usepackage{caption} %% \n" add " \\lstset{\n" add " captionpos=t,\n" add " language=bash,\n" add " basicstyle=\\ttfamily, %% fixed pitch font\n" add " xleftmargin=0pt, %% margin on the left outside the frames\n" add " framexleftmargin=0pt,\n" add " framexrightmargin=0pt,\n" add " framexbottommargin=5pt,\n" add " framextopmargin=5pt,\n" add " breaklines=true, %% break long code lines\n" add " breakatwhitespace=false, %% break long code lines anywhere\n" add " breakindent=10pt, %% reduce the indent from 20pt to 10\n" add " postbreak=\\mbox{{\\color{blue}\\small$\\Rightarrow$\\space}}, %% mark with arrow\n" add " showstringspaces=false, %% dont show spaces within strings\n" add " framerule=2pt, %% thickness of the frames\n" add " frame=top,frame=bottom,\n" add " rulecolor=\\color{lightgrey}, \n" add " % frame=l\n" add " % define special comment delimiters '##(' and ')'\n" add " % moredelim=[s][\\color{grey}\\itshape\\footnotesize\\ttfamily]{~(}{)},\n" add " } %% source code settings\n" add " \\usepackage{graphicx} %% to include images\n" add " \\usepackage{fancybox} %% boxes with rounded corners\n" add " \\usepackage{wrapfig} %% flow text around tables, images\n" add " \\usepackage{tabularx} %% change width of tables\n" add " \\usepackage[table]{xcolor} %% alternate row colour tables\n" add " \\usepackage{booktabs} %% for heavier rules in tables\n" add " \\usepackage[small,compact]{titlesec} %% sections more compact, less space\n" add " \\usepackage{enumitem} %% more compact and better lists\n" add " \\setlist{noitemsep} %% reduce list item spacing\n" add " \\usepackage{hyperref} %% make urls into hyperlinks\n" add " \\hypersetup{ %% add pdftex if only pdf output is required\n" add " colorlinks=false, %% set up the colours for the hyperlinks\n" add " linkcolor=black, %% internal document links black\n" add " urlcolor=black, %% url links black\n" add " frenchlinks=true,\n" add " bookmarks=true, pdfpagemode=UseOutlines}\n" add "\n" add " \\geometry{ left=1.0in,right=1.0in,top=1.0in,bottom=1.0in }\n" add " %% define some colours to use\n" add " \\definecolor{lightgrey}{gray}{0.70}\n" add " \\definecolor{grey}{gray}{0.30}\n" add "\n" add " %% titlesec: create framed section headings\n" add " %% \\titleformat{\\section}[frame]{\\normalfont}\n" add " %% {\\filleft \\footnotesize \\enspace Section \\thesection\\enspace\\enspace}\n" add " %% {3pt} {\\bfseries\\itshape\\filright}\n" add "\n" add " \\title{The Pep/nom parsing language and machine}\n" add " \\author{m.j.bishop}\n" add " \\date{\\today}\n" add " \\setlength{\\parindent}{0pt}\n" add " %% \\setlength{\\parskip}{1ex}\n" add "\n" add " %% label lists with stars\n" add " \\renewcommand{\\labelitemi}{$\\star$}\n" add "\n" add " \\parindent=0pt\n" add " \\parskip=6pt\n" add " \\begin{document}\n" add "\n" add " " get add "\n\\end{document} \n" add "\n\n %% Document parsed as text*!\n" # show parse-stack at end of doc as well ++ add " %% Document parse-stack is: " get add "\n" -- print quit block.end.46319: stack add "Document parsed unusually!\n" add "Stack at line " ll add " char " cc add ": " print clear unstack print stack add "\n" print clear quit block.end.46517: jump start