summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/more-macros.opm
blob: 4f4c4d113bc7f7cff3dddbbcaee73e26845ed5ea (plain)
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
%% This is part of OpTeX project, see http://petr.olsak.net/optex

\_codedecl \eoldef {OpTeX useful macos <2020-03-15>} % preloaded in format

\_newcatcodetable \_optexcatcodes
\_savecatcodetable\_optexcatcodes

\_def\_normalcatcodes {\_catcodetable\_optexcatcodes \_savecatcodetable0 \_catcodetable0 }

\_newcatcodetable \_plaintexcatcodes
\_public 
   \optexcatcodes \plaintexcatcodes ;

{\_catcode`_=8 \savecatcodetable\plaintexcatcodes}

% \catcodetable stack
% use \setctable<num> ... \setctable<num> ... \restorectable ... \restorectable

\_newcount\_currctable \_currctable=0
\_catcodetable0

\_def\_setctable#1{\_edef\_ctablelist{{\_the\_currctable}\_ctablelist}%
   \_catcodetable#1\_relax \_currctable=#1\_relax
}
\_def\_restorectable{\_ea\_restorectableA\_ctablelist\_relax}
\_def\_restorectableA#1#2\_relax{%
   \_ifx^#2^\_opwarning
      {You can't use \_noindent\restorectable without previous \_string\setctable}%
   \_else \_def\_ctablelist{#2}\_catcodetable#1\_relax \_currctable=#1\_relax \_fi
}
\_def\_ctablelist{.}

\_def\_opinput #1{\_setctable\_optexcatcodes \_input "#1" \_restorectable}


% \optdef \foo [opt-default] #1#2{...\the\opt...},  usage \foo {}{} or \foo [opt] {}{}

\_def\_optdef#1[#2]{% 
   \_def#1{\_opt={#2}\_isnextchar[{\_cs{_oA:\_string#1}}{\_cs{_oB:\_string#1}}}% 
   \_sdef{_oA:\_string#1}[##1]{\_opt={##1}\_cs{_oB:\string#1\_nospaceafter}}% 
   \_sdef{_oB:\_string#1\_nospaceafter}% 
} 
\_def\_nospaceafter#1{\_ea#1\_romannumeral-`\.}

\_newtoks\_opt

% \eoldef \foo #1{thex to end of line is: #1}

\_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{}

\_def\_bracedparam#1{\_ifcsname _\_csstring #1:M\_endcsname
    \_csname _\_csstring #1:M\_ea \_endcsname
    \_else \_csname __in\_csstring #1:M\_ea \_endcsname \_fi
} 


\_public \opt \optdef \eoldef \skiptoeol ;

\_catcode`!=3 \_catcode`?=3
\_def\_replstring #1#2#3{%  \replstring #1{stringA}{stringB}
   \_long\_def\_replacestringsA##1#2{\_def #1{##1}\_replacestringsB}%
   \_long\_def\_replacestringsB##1#2{\_ifx!##1\_relax \_else \_addto #1{#3##1}%
      \_ea\_replacestringsB\_fi}%      
   \_ea\_replacestringsA #1?#2!#2%
   \_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}}

% \keepinputnames ... \input foo ... \lastinputname -> foo

\_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)}}

\def\catcode{\_catcode\_string} % more robust in cases \catcode` or \catcode"

% \removespaces text with spaces {} -> textwithspaces

\_def\_removespaces #1 {\_isempty{#1}\_iffalse #1\_ea\_removespaces\_fi}

   \_doc ----------------------------
   `\trycs{<csname>}{<text>} expands to \<csname> if it is defined else to <text>.
   \_cod ----------------------------

\_def \_trycs#1#2{\_ifcsname #1\_endcsname \_csname #1\_endcsname \_else #2\_fi}

   \_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:
   {\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.
   \_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`.