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