Imported Upstream version 1.22.3
[platform/upstream/groff.git] / contrib / hdtbl / hdmisc.tmac-u
1 .ig
2
3 hdmisc.tmac
4
5 This file is part of groff, the GNU roff type-setting system.
6
7 Copyright (C) 2005-2018 Free Software Foundation, Inc.
8 written by Joachim Walsdorff <Joachim.Walsdorff@urz.uni-heidelberg.de>.
9
10 groff is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
14
15 groff is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23 ..
24 .
25 .
26 .\" %beginstrip%
27 .
28 .if d t*getarg \
29 .  nx
30 .
31 .
32 .\"     ******************************************************************
33 .\"     **      Some macros and default settings needed by hdtbl        **
34 .\"     ******************************************************************
35 .
36 .
37 .\"     Utility macro:  .getarg <key> ...
38 .\"
39 .\"             Get macro argument.  This macro searches <key> in the
40 .\"             remaining arguments and assigns its value to a string
41 .\"             register named <key>.  The following syntax forms are
42 .\"             recognized.
43 .\"
44 .\"                     <key>=<val>     Assign <val> to string <key>.
45 .\"                                     <val> must not contain spaces.
46 .\"                     <key>='<val>'   Assign <val> to string <key>.
47 .\"                                     <val> can contain spaces.
48 .\"                     <key>=          Assign '=' to string <key>.
49 .\"                     <key>           Assign 'key' to string <key>.
50 .\"
51 .\"             After return, the string 'args' contains the remaining
52 .\"             arguments.
53 .\"
54 .\"             Example: With the definition of string 'foo' as
55 .\"
56 .\"                     .ds foo aaa=xxx bbb ccc='yyy zzz' ddd= eee
57 .\"
58 .\"             a call to 'getarg' with
59 .\"
60 .\"                     .getarg ccc \*[foo]
61 .\"
62 .\"             sets string 'ccc' to value 'yyy zzz'.  The string 'args'
63 .\"             now contains 'aaa=xxx bbb ddd= eee'.  An additional call
64 .\"             like
65 .\"
66 .\"                     .getarg ddd \*[args]
67 .\"
68 .\"             sets string 'ddd' to value '=', and 'args' contains
69 .\"             'aaa=xxx bbb eee'.
70 .de t*getarg
71 .  ds \\$1
72 .  ds args
73 .
74 .  if (\\n[.$] < 2) \
75 .    return
76 .
77 .  ds $1 \\$1\"
78 .  shift
79 .
80 .  length * \\*[$1]
81 .  while \\n[.$] \{\
82 .    ds * "\\$1\"
83 .    ds ** "\\$1\"
84 .    length ** \\*[**]
85 .    shift
86 .    if (\\n[*] > \\n[**]) \{\
87 .      as args " "\\*[**]"\"                    value too short, repeat
88 .      continue
89 .    \}
90 .    substring * 0 (\\n[*] - 1)
91 .    \" The surrounding \? escapes emulate string comparison.
92 .    ie !"\?\\*[$1]\?"\?\\*[*]\?" \{\
93 .      as args " "\\*[**]"\"                    key not found, repeat
94 .      continue
95 .    \}
96 .    el \{\
97 .      ie "\?\\*[**]\?"\?\\*[$1]\?" \
98 .        ds \\*[$1] \\*[$1]\"                   return key as string
99 .      el \{\
100 .        ie "\?\\*[**]\?"\?\\*[$1]=\?" \
101 .          ds \\*[$1] =\"                       return '='
102 .        el \{\
103 .          substring ** (\\n[*] + 1) -1
104 .          ds * \\*[**]\"
105 .          substring * 0 0
106 .
107 .          \" check whether value starts with quote
108 .          if "\?\\*[*]\?"\?'\?" \{\
109 .            substring ** 1 -1
110 .            ds * \\*[**]\"
111 .            substring * -1 -1
112 .
113 .            \" search final quote
114 .            ie "\?\\*[*]\?"\?'\?" \
115 .              substring ** 0 -2
116 .            el \{\
117 .              as \\*[$1] \\*[**] \"            not found, append argument
118 .
119 .              while 1 \{\
120 .                ds ** \\$1\"                   get next argument
121 .                ds * \\$1\"
122 .                shift
123 .                substring * -1 -1
124 .
125 .                if "\?\\*[*]\?"\?'\?" \{\
126 .                  substring ** 0 -2
127 .                  break                \"      break if no final quote
128 .                \}
129 .
130 .                as \\*[$1] \\*[**] \"          otherwise append and repeat
131 .              \}
132 .          \}\}
133 .
134 .          as \\*[$1] \\*[**]\"
135 .        \}
136 .
137 .        as args " \\$@\"
138 .    \}\}
139 .
140 .    return
141 .  \}
142 ..
143 .
144 .
145 .\"     Utility macro:  .index <string1> <string2>
146 .\"
147 .\"             Check whether <string2> is a substring of <string1> and
148 .\"             return its position in number register 't*index', starting
149 .\"             with 1.  If not found, return 0.  If <string2> is empty,
150 .\"             set 't*index' to -999.
151 .de t*index
152 .  if "\\$2"" \{\
153 .    nr t*index -999
154 .    return
155 .  \}
156 .
157 .  length ** \\$1\a
158 .  length $2 \\$2
159 .  nr * 0-1 1
160 .
161 .  while (\\n+[*] < \\n[**]) \{\
162 .    ds * \\$1\a\"
163 .    substring * \\n[*] (\\n[*] + \\n[$2] - 1)
164 .    \" The surrounding \? escapes emulate string comparison.
165 .    if "\?\\*[*]\?"\?\\$2\?" \
166 .      break
167 .  \}
168 .
169 .  ie (\\n[*] == \\n[**]) \
170 .    nr t*index 0
171 .  el \
172 .    nr t*index (\\n[*] + 1)
173 ..
174 .
175 .
176 .\"     ******************************************************************
177 .\"     ********        non-accumulating space .t*SP [v]        **********
178 .\"     **                                                              **
179 .\"     **      nl vor erster Seite -1, oben auf Seite 0 resp. tH       **
180 .\"     **      .k nach .sp oder .br 0,                                 **
181 .\"     **              sonst Laenge der angefangenen Zeile             **
182 .\"     **      Der Merker M# fuer vorangegangenes .t*SP wird in .HM am **
183 .\"     **      Seitenanfang zurueckgesetzt.                            **
184 .\"     **      ganz richtig ist .sp + .br = .br + .sp = .sp            **
185 .\"     ******************************************************************
186 .de t*SP
187 .  if (\\n[nl] < 0) \
188 .    br                 \"      start very first page
189 .  nr * \\n[.p]         \"      save current page length
190 .
191 .  ie "\\$1"" \
192 .    pl +1              \"      without arg increase page length by 1v
193 .  el \
194 .    pl +\\$1           \"      otherwise use \\$1
195 .
196 .  nr ** (\\n[.p] - \\n[*])     \" ** now holds arg for .t*SP in base units
197 .  pl \\n[*]u           \"      restore page length
198 .
199 .  \" we do nothing at start of new page or column
200 .  if ((\\n[nl] - \\n[tH]) & (\\n[nl] - \\n[<<]) : \\n[.k]) \{\
201 .    ie ((\\n[.d] - \\n[M#]) : \\n[.k]) \{\
202 .      sp \\n[**]u      \"      execute .sp
203 .      nr S# \\n[**]    \"      store ** in S#
204 .    \}
205 .    el \{\
206 .      if (\\n[**] - \\n[S#]) \{\
207 .        sp (\\n[**]u - \\n[S#]u)\"     emit difference to previous .t*SP
208 .        nr S# \\n[**]  \"      store ** in S#
209 .    \}\}
210 .
211 .    nr M# \\n[.d]      \"      store vertical position .d in M#
212 .  \}
213 ..
214 .
215 .
216 .\"     ******************************************************************
217 .\"     **              Perform all arguments once                      **
218 .\"     **                      P1 is nestable                          **
219 .\"     ******************************************************************
220 .de t*P1
221 .  \" 'while' command is about five times faster than recursion!
222 .  while \\n[.$] \{\
223 .    nop \\$1
224 .    shift
225 .  \}
226 ..
227 .
228 .
229 .\"     ******************************************************************
230 .\"     **      Hilfsmakro zum Einstellen von Schriftgroesse und        **
231 .\"     **      Zeilenabstand, bezogen auf Anfangswerte \n[t*s]         **
232 .\"     **      und \n[t*v] sowie fuer Hyphenation:                     **
233 .\"     **              .t*pv s v hy# hart;  macht .br                  **
234 .\"     **      Bei 4. Argument setzen der Register s und v und hy.     **
235 .\"     **      Fuer angefangene Zeile die vorgefundenen Einstellungen  **
236 .\"     **                                                              **
237 .\"     **   Auxiliary macro to set internal registers for font size    **
238 .\"     **   and line spacing, relative to initial values \n[t*s] and   **
239 .\"     **   \n[t*v]. Optionally sets hyphenation. A fourth argument    **
240 .\"     **   initializes internal registers to global default values.   **
241 .\"     ******************************************************************
242 .de t*pv
243 .  br
244 .
245 .  if \\n[.$] \
246 .    ps (\\n[t*s]u * \\$1z / 1z)
247 .
248 .  ie (\\n[.$] - 1) \
249 .    vs (\\n[t*v]u * \\$2p / 1p)
250 .  el \{\
251 .    vs (\\n[t*v]u * \\$1p / 1p)
252 .    return
253 .  \}
254 .
255 .  if !""\\$3" \
256 .    hy \\$3
257 .
258 .  if !""\\$4" \{\
259 .    nr t*v \\n[.v]
260 .    nr t*s \\n[.ps]
261 .    nr t*hy \\n[.hy]
262 .  \}
263 ..
264 .
265 .
266 .\"     ******************************************************************
267 .\"     **              Hilfsmakros pop/pops/popr (pop stackelement):   **
268 .\"     **              pop or popr:    pop register                    **
269 .\"     **              pops:           pop string                      **
270 .\"     **              .pop[s|r] reg|string stackname                  **
271 .\"     **                  reg|string: name of reg/string to get the   **
272 .\"     **                       popped element                         **
273 .\"     **                  stack: name of stack                        **
274 .\"     ******************************************************************
275 .de *pop
276 .  ie "\\$1"pops" \
277 .    ds \\$2 \\$4\"             pop first stackelement
278 .  el \
279 .    nr \\$2 \\$4
280 .
281 .  ds $3 \\$3\"                 remember stackname
282 .  shift 4              \"      shift four args
283 .
284 .  ds \\*[$3] "\\$@\"           fill stack with remaining elements
285 ..
286 .
287 .de pop
288 .  *pop \\$0 \\$1 \\$2 \\*[\\$2]
289 ..
290 .
291 .als popr pop
292 .als pops pop
293 .
294 .
295 .\"     ******************************************************************
296 .\"     **              process diversion                               **
297 .\"     ******************************************************************
298 .de t*DI
299 .  nr * \\n[.u]
300 .  nf           \"      diversion is already formatted - output it unchanged
301 .  \\$1         \"      output the diversion ...
302 .  rm \\$1      \"      ... and remove it
303 .  if \\n[*] \
304 .    fi         \"      reactivate formatting
305 ..
306 .
307 .\"     ******************************************************************
308 .\"     **              error checking at end                           **
309 .\"     ******************************************************************
310 .de t*EM
311 .
312 .  if !"\\*[t*kept]"" \{\
313 .    tm1 "hdtbl: Not all tables have been printed.
314 .    tm1 "       Add '.bp' at the end of your document.
315 .  \}
316 .  if !"\\*[t*held]"" \{\
317 .    tm1 "hdtbl: There are held tables which haven't been printed.
318 .    tm1 "       Add '.t*free' at the end of your document.
319 .  \}
320 .  if \\n[t*#] \
321 .    tm hdtbl: Missing '.ETB' macro; last .TBL in \\*[t*FN] at line \\*[t*LN].
322 ..
323 .
324 .
325 .\" ====================================================================
326 .\" Editor settings
327 .\" ====================================================================
328 .
329 .\" Local Variables:
330 .\" mode: nroff
331 .\" fill-column: 72
332 .\" End:
333 .\" vim: set filetype=groff textwidth=72: