diff options
Diffstat (limited to 'macros/luatex/optex/more-macros.opm')
-rw-r--r-- | macros/luatex/optex/more-macros.opm | 194 |
1 files changed, 136 insertions, 58 deletions
diff --git a/macros/luatex/optex/more-macros.opm b/macros/luatex/optex/more-macros.opm index 4f4c4d113b..64cbcd84c9 100644 --- a/macros/luatex/optex/more-macros.opm +++ b/macros/luatex/optex/more-macros.opm @@ -2,19 +2,45 @@ \_codedecl \eoldef {OpTeX useful macos <2020-03-15>} % preloaded in format -\_newcatcodetable \_optexcatcodes -\_savecatcodetable\_optexcatcodes + \_doc ----------------------------- + We define \`\opinput` `{<file name>}` macro which + does `\input {<file name>}` but catocodes are set to normal catcodes + (like \OpTeX/ initializes them) and the catodes setting is return back to + the current values when the file is read. You can use `\optinput` + in any situation inside the document and you will be sure that the file + is read correctly with correct catcode settings. + + In order to achieve this, we declare \`\optexcatcodes` catcode table + and \`\plaintexcatocdes`. They save the commonly used catcode tables. + Note that `\catcodetable` is a part of \LuaTeX/ extension. + The catcodetable stack is implemented by \OpTeX/ macros. + The \`\setctable` `<catcode table>` pushes + current catcode table to the stack and activates catcodes from + the `<catcode table>`. The \`\restorectable` returns to the saved catocdes + from the catcode table stack. So, the `\opinput` macro can be implemented simply: + \_cod ----------------------------- -\_def\_normalcatcodes {\_catcodetable\_optexcatcodes \_savecatcodetable0 \_catcodetable0 } +\_def\_opinput #1{\_setctable\_optexcatcodes \_input "#1" \_restorectable} +\_newcatcodetable \_optexcatcodes \_newcatcodetable \_plaintexcatcodes -\_public - \optexcatcodes \plaintexcatcodes ; +\_public \optexcatcodes \plaintexcatcodes \opinput ; + +\_savecatcodetable\_optexcatcodes {\_catcode`_=8 \savecatcodetable\plaintexcatcodes} -% \catcodetable stack -% use \setctable<num> ... \setctable<num> ... \restorectable ... \restorectable + \_doc ----------------------------- + The implementation of the catcodetable stack follows. + + The current catodes are + managed in the `\catcodetable0`. If the `\setctable` is used first (or at + the outer level of the stack), then the `\catcodetable0` is pushed to the + stack and the current table is re-set to the given `<catcode table>`. + The numbers of these tables are stacked to the \`\_ctablelist` macro. + The `\restorectable` reads the last saved catcode table number from the + `\_ctablelist` and uses it. + \_cod ----------------------------- \_newcount\_currctable \_currctable=0 \_catcodetable0 @@ -30,10 +56,32 @@ } \_def\_ctablelist{.} -\_def\_opinput #1{\_setctable\_optexcatcodes \_input "#1" \_restorectable} +\_public \setctable \restorectable ; + \_doc ----------------------------- + When a special macro is defined with different catcodes then + \`\normalcatcodes` can be used at the end of such definition. + The normal catcodes are restored. + The macro reads + catcodes from `\optecatodes` table and sets it to the main catcode table 0. + \_cod ----------------------------- -% \optdef \foo [opt-default] #1#2{...\the\opt...}, usage \foo {}{} or \foo [opt] {}{} +\_def\_normalcatcodes {\_catcodetable\_optexcatcodes \_savecatcodetable0 \_catcodetable0 } +\_public \normalcatodes ; + + \_doc ----------------------------- + The declarator \`\optdef``\macro [<opt default>] <params>{<replacement text>}` + defines the `\macro` with the optional parameter followed by normal parameters + declared in `<params>`. The optional parameter must be used as the first + first parameter in brackets `[...]`. If it isn't used then <opt default> + is taken into account. The `<replacement text>` can use `\the\opt` + because optional parameter is saved to the \`\opt` tokens register. + Note the difference from \LaTeX/ concept where the optional parameter is + in `#1`. \OpTeX/ uses `#1` as the first normal parameter (if declared). + + The \`\_nospaceafter` ignores the following optional space at expand + processor level using the negative `\romannumeral` trick. + \_cod ----------------------------- \_def\_optdef#1[#2]{% \_def#1{\_opt={#2}\_isnextchar[{\_cs{_oA:\_string#1}}{\_cs{_oB:\_string#1}}}% @@ -41,25 +89,47 @@ \_sdef{_oB:\_string#1\_nospaceafter}% } \_def\_nospaceafter#1{\_ea#1\_romannumeral-`\.} - \_newtoks\_opt -% \eoldef \foo #1{thex to end of line is: #1} +\_public \opt \optdef ; + + \_doc ----------------------------- + The declarator \`\eoldef``\macro #1{<replacement text>}` defines a `\macro` + which scans its parameter to the end of the current line. + This is the parameter `#1` which can be used in the `<replacement text>`. + The catcode of the `\endlinechar` is reset temporarily when the parameter is scanned. + + The macro defined by `\eoldef` cannot be used with its parameter inside + other macros because the catcode dancing is not possible here. But the + \`\bracedparam``\macro{<parameter>}` can be used here. The `\bracedparam` + is a prefix which re-sets temporarily the `\macro` to a `\macro` with + normal one parameter. + + The \`\skiptoeol` macro reads the text to the end of the current line + and ignores it. + \_cod ----------------------------- \_def\_eoldef #1{\_def #1{\_begingroup \_catcode`\^^M=12 \_eoldefA #1}% \_ea\_def\_csname _\_csstring #1:M\_endcsname} \_catcode`\^^M=12 % \_def\_eoldefA #1#2^^M{\_endgroup\_csname _\_csstring #1:M\_endcsname{#2}}% \_normalcatcodes % -\_eoldef\_skiptoeol#1{} +\_eoldef\_skiptoeol#1{} \_def\_bracedparam#1{\_ifcsname _\_csstring #1:M\_endcsname \_csname _\_csstring #1:M\_ea \_endcsname \_else \_csname __in\_csstring #1:M\_ea \_endcsname \_fi } +\_public \eoldef \skiptoeol \bracedparam ; - -\_public \opt \optdef \eoldef \skiptoeol ; + \_doc ----------------------------- + The \`\replstring``\macro{<textA>}{<textB>}` + replaces all occurrences of `<textA>` by `<textB>` in the `\macro` body. + The `\macro` must be defined without parameters. The occurrences of + `<textA>` are not replaced if they are \"hidden" in braces, for example + `...{...<textA>...}...`. The category codes in the `<textA>` must exactly + match. + \_cod ----------------------------- \_catcode`!=3 \_catcode`?=3 \_def\_replstring #1#2#3{% \replstring #1{stringA}{stringB} @@ -70,69 +140,77 @@ \_long\_def\_replacestringsA##1?{\_def #1{##1}}\_ea\_replacestringsA #1} \_normalcatcodes -\_def\_remfirstunderscore#1{\_ea\_remfirstunderscoreA#1\_relax#1} -\_def\_remfirstunderscoreA#1#2\_relax#3{\_if _#1\_def#3{#2}\_fi} - -\_ea\_def \_ea\_meaningsepare \_ea#\_ea1\_string m#2:#3->#4^{{#1}{#3}{#4}} +\_public \replstring ; -% \keepinputnames ... \input foo ... \lastinputname -> foo + \_doc ----------------------------- + The \`\catcode` primitive is redefined here. Why? + There is very common cases like \code{\\catcode`}`<something>` + or `\catcode"<number>` but these characters + \code{\`} or \code{"} can be set as active (typically by `\activettchar` macro). + Nothing problematic happens if re-defined `\catcode` is used in this case. -\_def\_keepinputnames{\_directlua{% - callback.register("find_read_file", - function (id, name) - input_file_name = name - return name - end) -}} -\_def\_lastinputname{\_directlua{tex.print(input_file_name)}} + If you really need primitive `\catcode` then you can use `\_catcode`. + \_cod ----------------------------- \def\catcode{\_catcode\_string} % more robust in cases \catcode` or \catcode" -% \removespaces text with spaces {} -> textwithspaces + \_doc ----------------------------- + The \`\removespaces` `<text with spaces >{}` expands to <textwithoutspaces>. + \nl + The `\_ea`\`\ignorept``\the<dimen>` expands to a decimal + number `\the<dimen>` but without `pt` unit. + \nl + The \`\ignoreit``<token>` just ignores the `<token>`. + \_cod ----------------------------- \_def\_removespaces #1 {\_isempty{#1}\_iffalse #1\_ea\_removespaces\_fi} +\_ea\_def \_ea\_ignorept \_ea#\_ea1\detokenize{pt}{#1} +\_def\_ignoreit#1{} - \_doc ---------------------------- - `\trycs{<csname>}{<text>} expands to \<csname> if it is defined else to <text>. - \_cod ---------------------------- +\public \removespaces \ignorept \ignoreit ; + + \_doc ----------------------------- + You can use expandable \`\bp``{<dimen>}` convertor from + \TeX/ `<dimen>` (or from an expression accepted by + `\dimexpr` primitive) to a decimal value in big points + (used as natural unit in the PDF format). So, you can write, for example: + \begtt + \pdfliteral{q \_bp{.3\hsize-2mm} \_bp{2mm} m 0 \_bp{-4mm} l S Q} + \endtt + You can use expandable \`\expr``{<expression>}` for analogical purposes. + It expands to the value of the `<expression>` at expand processor level + with \`\_decdigits` digits after decimal point. + The `<expression>` can include `+-*/()` and decimal numbers in common syntax. + + The usage of prefixed versions \`\_expr` or \`\_bp` is more recommended + because user can re-define the control sequences `\expr` or `\bp`. + \_cod ----------------------------- + +\_def\_decdigits{3} % digits after decimal point in \_bp and \_expr outputs. +\_def\_pttopb{% + \_directlua{tex.print(string.format('\_pcent.\_decdigits f', + token.scan_dimen()/65781.76))}% pt to bp conversion +} +\def\_bp#1{\_ea\_pttopb\_dimexpr#1\_relax} +\def\_expr#1{\_directlua{tex.print(string.format('\_pcent.\_decdigits f',#1))}} -\_def \_trycs#1#2{\_ifcsname #1\_endcsname \_csname #1\_endcsname \_else #2\_fi} +\_public \expr \bp ; \_doc ------------------ - The pair {`\_doc ... \cod`} is used for documenting macros and to - printing the third part of main \OpTeX/ documentation: The - implementation. The syntax is: + The pair {\`\_doc` ... \`\_cod`} is used for documenting macros and to + printing the technical documentation of the \OpTeX/. The syntax is: {\begtt \_doc <ignored text> <documentation> \_cod <ignored text> - \endtt} - The last {\_cod} in the file must be followed by `\_fin`. This is a - signal, that the following code does not ends by next `\_doc` but by - {`\_endcode`} command. The {`\_doc...\cod`} is redefined in macros used - for documentation printing. - - The <documentation> (and <ignored text> too) must be <balanced text>. - It means that you canot document only `{` but you must document `}` too. + \endtt + } + The `<documentation>` (and `<ignored text>` too) must be `<balanced text>`. + It means that you cannot document only the `{` but you must document the `}` too. \_cod ------------------ \_long\_def\_doc #1\_cod {\_skiptoeol} -\_ea \_def \_ea\_ignorept \_ea#\_ea1\detokenize{pt}{#1} -\_def\_ignoreit#1{} - -\public - \setctable \restorectable - \normalcatodes \opt \optdef \eoldef \bracedparam \replstring - \keepinputnames \lastinputname \removespaces \trycs - \ignorept \ignoreit ; - \_endcode % ------------------------------------- - -The `\ignoreit` macro ignores next token. The \ignorept macro used ike this: -\begtt -\ea\ignorept \the\dimen... -\endtt -consumes the "pt" phrase appended to dimen value by `\the`. |