diff options
Diffstat (limited to 'macros/luatex/optex/base/verbatim.opm')
-rw-r--r-- | macros/luatex/optex/base/verbatim.opm | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/macros/luatex/optex/base/verbatim.opm b/macros/luatex/optex/base/verbatim.opm new file mode 100644 index 0000000000..ba2cf93dab --- /dev/null +++ b/macros/luatex/optex/base/verbatim.opm @@ -0,0 +1,267 @@ +%% This is part of OpTeX project, see http://petr.olsak.net/optex + +\_codedecl \begtt {Verbatim <2020-04-22>} % preloaded in format + + \_doc ---------------------------- + The internal parameters + \`\_ttskip`, \`\_ttpenalty`, \`\_viline`, \`\_vifile` and \`\_ttfont` + for verbatim macros are set. + \_cod ---------------------------- + +\_def\_ttskip{\_medskip} % space above and below \begtt, \verbinput +\_mathchardef\_ttpenalty=100 % penalty between lines in \begtt, \verbinput +\_newcount\_viline % last line number in \verbinput +\_newread\_vifile % file given by \verinput +\_def\_ttfont{\_tt} % default tt font + + \_doc ---------------------------- + \`\code``{<text>}` expands to `\detokenize{<text>}` when `\escapechar=-1`. In + order to do it more robust when it is used in `\write` then it expands as + noexpanded `\code<space>` (followed by space in its csname). This macro + does the real work. + + The \`\_printinverbatim``{<text>}` macro is used for `\code{<text>}` printing and for + \code{`}<text>\code{`} printing. It is defined as `\hbox`, so the in-verbatim <text> + will be never broken. But you can re-define this macro. + + When `\code` occurs in PDF outlines then it does the same as `\detokenize`. + The macro for preparing outlines sets `\escapechar` to $-1$ and uses + \^`\_regoul` token list before `\edef`. + + The `\code` is not `\proteced` because we want it expands to + `\unexpanded{\code<space>{<text>}}` in `\write` parameters. This protect the + expansions of the `\code` parameter (like `\\`, `\^` etc.). + \_cod ---------------------------- + +\_def\_code#1{\_unexpanded\_ea{\_csname _code \_endcsname{#1}}} +\_protected\_sdef{_code }#1{{\_escapechar=-1 \_ttfont \_the\_everyintt \_relax + \_ea\_printinverbatim\_ea{\_detokenize{#1}}}} +\_def\_printinverbatim#1{\_leavevmode\_hbox{#1}} + +\_regmacro {}{}{\_let\code=\_detokenize \_let\_code=\_detokenize} +\_public \code ; + + \_doc ---------------------------- + The \`\_setverb` macro sets all catcodes to \"verbatim mode". It should be used only + in a group, so we prepare a new catcode table with \"verbatim" catcodes and we define + it as\nl `\_catcodetable`\`\_verbatimcatcodes`. After the group is finished then + original catcode table is restored. + \_cod ---------------------------- + +\_newcatcodetable \_verbatimcatcodes +\_def\_setverb{\_begingroup + \_def\do##1{\_catcode`##1=12 } + \_dospecials + \_savecatcodetable\_verbatimcatcodes % all characters are normal + \_endgroup +} +\_setverb +\_def\_setverb{\_catcodetable\_verbatimcatcodes }% + + \_doc ---------------------------- + \`\activettchar``<char>` saves original catcode of previously declared `<char>` (if + such character was declared) using \`\_savedttchar` and \`\_savedttcharc` + values. Then new such values are stored. The declared charater is activated + by `\_adef` as a macro (active character) which opens a group, + does `\_setverb` and other settings and reads its parameter until second the same + character. This is done by the \`\_readverb` macro. Finally it prints scanned + `<text>` by \^`\_printinverbatim` and closes group. Suppose that `\activettchar"` is + used. Then the following work is schematically done: + \begtt + \_def "{\_begingroup \_setverb ... \_readverb} + \_def \_readverb #1"{\_printinverbatim{#1}\_endgroup} + \endtt + Note that the second occurrence of `"` is not active because `\_setverb` + deactivates it. + \_cod ---------------------------- + +\_def\_activettchar#1{% + \_ifx\_savedttchar\_undefined\_else \_catcode\_savedttchar=\_savedttcharc \_fi + \_chardef\_savedttchar=`#1 + \_chardef\_savedttcharc=\_catcode`#1 + \_adef{#1}{\_begingroup \_setverb \_adef{ }{\ }\_ttfont \_the\_everyintt\_relax \_readverb}% + \_def\_readverb ##1#1{\_printinverbatim{##1}\_endgroup}% +} +\_public \activettchar ; + + \_doc ---------------------------- + \`\begtt` is defined only as public. We don't need private `\_begtt` variant. + This macro is defined by `\eoldef`, so user can put a parameter at the + same line where `\begtt` is. This `#1` parameter is used after `\_everytt` + parameters settings, so user can change them locally. + + The `\begtt` macro opens group, does \^`\_setverb` and another preprocessing, sets + `\endlinechar` to `^^J` and reads the following text in verbatim mode + until \`\endtt` occurs. This scanning is done by \`\_startverb` macro which is + defined as: + \begtt \adef/{\bslash} + \_def\_startverb #1/endtt #2^^J{...} + \endtt + We must to ensure that the backslash in `\endtt` has category 12 (this is a + reason of the `\ea` chain in real code). + The `#2` is something between `\endtt` and end of the same line and it is simply + ignored. + + The `\_startverb` puts the scanned data to \`\_prepareverbdata`. It sets the data + to `\_tmpb` without changes by default, but you should re-define it in order + to do special changes, if you want. (For example, \^`\hisyntax` redefines + this macro.) The scanned data have `^^J` at each end of line and all spaces are + active characters (defined as {\visiblesp`\ `}). + Other characters have normal category 11 or 12. + + When `\_prepareverbdata` finishes then `\_startverb` runs \`\_printverb` loop + over each line of the data and does a final work: last skip plus `\noindent` + in the next paragraph. + + The `\_printverb` macro calls \`\_printverbline``{<line>}` to each scanned line of + verbatim text. This macro expect that it strarts in vertical mode and it must + do `\par` in order to return the vertical mode. The \`\_printverblinenum` + is used here: it does nothing when `\_ttline`\code{<0} else it prints the line + number using `\_llap`. + \_cod ---------------------------- + +\_eoldef \begtt#1{\_par \_wipeepar + \_vskip\_parskip \_ttskip + \_begingroup + \_setverb + \_ifnum\_ttline<0 \_let\_printverblinenum=\_relax \_else \_initverblinenum \_fi + \_adef{ }{\ }\_adef\^^I{\t}\_parindent=\_ttindent \_parskip=0pt + \_def\t{\_hskip \_dimexpr\_tabspaces em/2\_relax}% + \_the\_everytt \_relax #1\_relax \_ttfont + \_endlinechar=`^^J + \_startverb +} +\_ea\_def\_ea\_startverb \_ea#\_ea1\_csstring\\endtt#2^^J{% + \_prepareverbdata\_tmpb{#1^^J}% + \_ea\_printverb \_tmpb\_end + \_par + \_endgroup \_ttskip + \_isnextchar\_par{}{\_noindent}% +} +\_def\_printverb #1^^J#2{\_ifx\_end#2 + \_bgroup \_adef{ }{}\_def\t{}% + \_ifcat&\_egroup \_else\_egroup \_printverbline{#1}\_fi + \_else + \_printverbline{#1}% + \_ea \_printverb \_ea #2% + \_fi +} +\_def\_prepareverbdata#1#2{\_def#1{#2}} +\_def\_printverbline#1{\_penalty \_ttpenalty + \_indent \_printverblinenum \_kern\_ttshift #1\par} +\_def\_initverblinenum{\_tenrm \_thefontscale[700]\_ea\_let\_ea\_sevenrm\_the\_font} +\_def\_printverblinenum{\_global\_advance\_ttline by1 \_llap{\_sevenrm \_the\_ttline\_kern.9em}} + + \_doc ---------------------------- + Macro \`\verbinput` uses a file read previously or opens the given file. Then + it runs the parameter scanning by \`\_viscanparameter` and \`\_viscanminus`. + Finally the \`\_doverbinput` is run. At begining of `\_doverbinput`, we have + `\_viline`= number of lines already read using previous `\verbinput`, + `\_vinolines`= the number of lines we need to skip and `\_vidolnes`= the + number of lines we need to print. + Similar preparation is done as in `\begtt` after the group is opened. Then + we skip \`\_vinolines` lines in a loop a and we read \`\_vidolines` lines. The + read data is accumulated into `\_tmpb` macro. The next steps are equal to + the steps done in \^`\_startverb` macro: data are processed via + \^`\_prepareverbdata` and printed via \^`\_printverb` loop. + \_cod \_fin ---------------------- + +\_def\_verbinput #1(#2) #3 {\_par \_def\_tmpa{#3}% + \_def\_tmpb{#1}% cmds used in local group + \_ifx\_vifilename\_tmpa \_else + \_openin\_vifile={#3}% + \_global\_viline=0 \_global\_let\_vifilename=\_tmpa + \_ifeof\_vifile + \_opwarning{\_noexpand\verbinput - file "#3" is unable to reading} + \_ea\_ea\_ea\_skiptorelax + \_fi + \_fi + \_viscanparameter #2+\_relax +} +\_def\_skiptorelax#1\_relax{} + +\_def \_viscanparameter #1+#2\_relax{% + \_if$#2$\_viscanminus(#1)\_else \_viscanplus(#1+#2)\_fi +} +\_def\_viscanplus(#1+#2+){% + \_if$#1$\_tmpnum=\_viline + \_else \_ifnum#1<0 \_tmpnum=\_viline \_advance\_tmpnum by-#1 + \_else \_tmpnum=#1 + \_advance\_tmpnum by-1 + \_ifnum\_tmpnum<0 \_tmpnum=0 \_fi % (0+13) = (1+13) + \_fi \_fi + \_edef\_vinolines{\_the\_tmpnum}% + \_if$#2$\_def\_vidolines{0}\_else\_edef\_vidolines{#2}\_fi + \_doverbinput +} +\_def\_viscanminus(#1-#2){% + \_if$#1$\_tmpnum=0 + \_else \_tmpnum=#1 \_advance\_tmpnum by-1 \_fi + \_ifnum\_tmpnum<0 \_tmpnum=0 \_fi % (0-13) = (1-13) + \_edef\_vinolines{\_the\_tmpnum}% + \_if$#2$\_tmpnum=0 + \_else \_tmpnum=#2 \_advance\_tmpnum by-\_vinolines \_fi + \_edef\_vidolines{\_the\_tmpnum}% + \_doverbinput +} +\_def\_doverbinput{% + \_tmpnum=\_vinolines + \_advance\_tmpnum by-\_viline + \_ifnum\_tmpnum<0 + \_openin\_vifile={\_vifilename}% + \_global\_viline=0 + \_else + \_edef\_vinolines{\_the\_tmpnum}% + \_fi + \_vskip\_parskip \_ttskip \_wipeepar + \_begingroup + \_ifnum\_ttline<-1 \_let\_printverblinenum=\_relax \_else \_initverblinenum \_fi + \_setverb \_adef{ }{\ }\_adef\^^I{\t}\_parindent=\_ttindent \_parskip=0pt + \_def\t{\_hskip \_dimexpr\_tabspaces em/2\_relax}% + \_the\_everytt\_relax \_tmpb\_relax \_ttfont + \_endlinechar=`^^J \_tmpnum=0 + \_loop \_ifeof\_vifile \_tmpnum=\_vinolines\_space \_fi + \_ifnum\_tmpnum<\_vinolines\_space + \_vireadline \_advance\_tmpnum by1 \_repeat %% skip lines + \_edef\_ttlinesave{\_ttline=\_the\_ttline}% + \_ifnum\_ttline=-1 \_ttline=\_viline \_fi + \_tmpnum=0 \_def\_tmpb{}% + \_ifnum\_vidolines=0 \_tmpnum=-1 \_fi + \_ifeof\_vifile \_tmpnum=\_vidolines\_space \_fi + \_loop \_ifnum\_tmpnum<\_vidolines\_space + \_vireadline + \_ifnum\_vidolines=0 \_else\_advance\_tmpnum by1 \_fi + \_ifeof\_vifile \_tmpnum=\_vidolines\_space \_else \_visaveline \_fi %% save line + \_repeat + \_ea\_prepareverbdata \_ea \_tmpb\_ea{\_tmpb^^J}% + \_ea\_printverb \_tmpb\_end + \_global\_ttlinesave + \_par + \_endgroup + \_ttskip + \_isnextchar\_par{}{\_noindent}% +} +\_def\_vireadline{\_read\_vifile to \_tmp \_global\_advance\_viline by1 } +\_def\_visaveline{\_ea\_addto\_ea\_tmpb\_ea{\_tmp}} + +\_public \verbinput ; + + \_doc ----------------------------- + The \`\visiblesp` sets spaces as visible characters \char9251. + It redefines {\visiblesp`\ `} primitive, so it is useful for verbatim modes only. + \_cod ----------------------------- + +\_def \_visiblesp{\_ifx\_initunifonts\_relax \_def\ {\_char9251 }% + \_else \_def\ {\_char32 }\_fi} + +\_public \visiblesp ; + +\_endcode + +\_endinput + +History: +2020-04-22 ... \ttshift introduced +2020-04-06 ... \visiblesp added +2020-04-04 ... ^^I activated as \t for multiline verbatim + \verbinput <cmds> (...) <filename>, <cmds> added. |