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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
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\_space
\_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.
|