blob: 5e56503bd87b2a998b7dcf658cab0643ede0fde2 (
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
|
%% This is part of OpTeX project, see http://petr.olsak.net/optex
\_codedecl \newif {Special if-macros, is-macros and loops <2020-02-27>} % preloaded in format
\_doc ----------------------------
The `\newif` macro works like in plain \TeX. It means that
after `\newif\ifxxx` you can use `\xxxtrue` or
`\xxxfalse` to set the boolean value and use `\ifxxx true\else false\fi`
to test this value. The defalut value is false.
The macro `\_newifi` enables to declare `\_ifxxx` and to use `\_xxxtrue` and
`\_xxxfalse`. This means that it is usable for _prefixed macros.
\_cod ----------------------------
\_def\_newif #1{\_ea\_newifA \_string #1\_relax#1}
\_ea\_def \_ea\_newifA \_string\if #1\_relax#2{%
\_sdef{#1true}{\_let#2=\_iftrue}%
\_sdef{#1false}{\_let#2=\_iffalse}%
\_let#2=\_iffalse
}
\_def\_newifi #1{\_ea\_newifiA \string#1\_relax#1}
\_ea\_def \_ea\_newifiA \string\_if #1\_relax#2{%
\_sdef{_#1true}{\_let#2=\_iftrue}%
\_sdef{_#1false}{\_let#2=\_iffalse}%
\_let#2=\_iffalse
}
\_doc ----------------------------
The `\loop <codeA> \ifsomething <codeB> \repeat` loops `<codeA> <codeB>`
until `\ifsomething` is false. Then `<codeB>` is not executed and loop is
finished. This works like in plain \TeX, but implementation is soewhat
better (you can use `\else` clause after the `\ifsomething`).
There are public version `\loop...\repeat` and private version
`\_loop...\_repeat`. You canot mix both versions in one loop.
\_cod ----------------------------
\_def \_loop #1\_repeat{\_def\_body{#1}\_iterate}
\_def \loop #1\repeat{\_def\_body{#1}\_iterate}
\_let \_repeat=\_fi % this makes \loop...\if...\repeat skippable
\_let \repeat=\_fi
\_def \_iterate {\_body \_ea \_iterate \_fi}
\_doc ----------------------------
The macro `\isnextchar <char>{<codeA>}{<codeB>}` executes `<codeA>` if next
character is equal to <char>. Else the `<codeB>` is executed. The macro is
not expandable.
\_cod ----------------------------
\_long\_def\_isnextchar#1#2#3{\_begingroup\_toks0={\_endgroup#2}\_toks1={\_endgroup#3}%
\_let\_tmp=#1\_futurelet\_next\_isnextcharA
}
\_def\_isnextcharA{\_the\_toks\_ifx\_tmp\_next0\_else1\_fi\_space}
\_doc ----------------------------
The macro `\isempty{<text>}\iftrue <codeA>\else <codeB>\fi` executes <codeA>
if <text> is empty and <codeB> if it is non-empty. You can use
`\isempty{<text>}\iffalse <codeB>\else <codeA>\fi` too. This macro is
expandable.
There are a collection of macros with commnon syntax:
`\issomething<params>\iftrue` or `\issomething<params>\iffalse`.
The `\iftrue` or `\iffalse` is a part of this syntax because we need to keep
skippable nested `\if` conditions.
We read this `\iftrue` or `\iffalse` into unseparated parameter and repeat
it because we need to remove an optional space before this command.
\_cod ----------------------------
\_def \_isempty #1#2{\_ea\_ifx\_ea\_relax\_detokenize{#1}\_relax
\_else \_ea\_unless \_fi #2}
\_def \_isnoempty #1#2{\_ea\_ifx\_ea\_relax\_detokenize{#1}\_relax
\_ea\_unless \_fi #2}
\_def \_istoksempty #1{\_ea\_isempty\_ea{\_the#1}}
\_doc ----------------------------
`\isequal{<textA>}{<textB>}\iftrue` is true if the <textA> and <textB> are
equal, only from strings point of view, category codes are ignored.
The macro is expandable.
\_cod ----------------------------
\_def\_isequal#1#2#3{\_directlua{%
if "\_luaescapestring{\_detokenize{#1}}"=="\_luaescapestring{\_detokenize{#2}}"
then else tex.print("\_nbb unless") end}#3}
\_doc ----------------------------
`\ismacro\macro{text}\iftrue` is true if macro is defined as {<text>}.
Category codes are ignored in this testing. The macro is expandable.
\_cod ----------------------------
\_def\_ismacro#1{\_ea\_isequal\_ea{#1}}
\_doc ----------------------------
`\isinlist\list{<text>}\iftrue` is true if the
`<text>` is included the macro body of the `\list`.
The catogory code are relevant here. THe macro is not expandable.
\_cod ----------------------------
\_def\_isdefined #1#2{\_ifcsname #1\_endcsname \_else \_ea\_unless \_fi #2}
\_doc ----------------------------
`\isdefined{<csname>}\iftrue` is true if `\<csname>` is defined.
\_cod ----------------------------
\_long\_def\_isinlist#1#2{\_begingroup
\_long\_def\_tmp##1#2##2\_end/_{\_endgroup\_isnoempty{##2}}%
\_ea\_tmp#1\_endlistsep#2\_end/_%
}
\_doc ----------------------------
`\isfile{<filename>}\iftrue` is true if the file <filename> exists and are
readable by \TeX.
\_cod \_fin ----------------------
\_newread \_testin
\_def\_isfile #1{%
\_openin\_testin ={#1}\_relax
\_ifeof\_testin \_ea\_unless
\_else \_closein\_testin
\_fi
}
\_public
\newif \isnextchar \isempty \isequal \ismacro \isdefined \isinlist \isfile ;
\_endcode
|