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