]>
Commit | Line | Data |
---|---|---|
07d021a6 | 1 | divert(-1) -*-Text-*- |
9bcc06ef RP |
2 | ` Copyright (c) 1991 Free Software Foundation, Inc.' |
3 | ` This file defines and documents the M4 macros used ' | |
4 | ` to preprocess some GNU manuals' | |
5 | ` $Id$' | |
07d021a6 JG |
6 | |
7 | I. INTRODUCTION | |
8 | ||
9 | This collection of M4 macros is meant to help in pre-processing texinfo | |
10 | files to allow configuring them by hosts; for example, the reader of an | |
11 | as manual who only has access to a 386 may not really want to see crud about | |
12 | VAXen. | |
13 | ||
14 | A preprocessor is used, rather than extending texinfo, because this | |
15 | way we can hack the conditionals in only one place; otherwise we would | |
16 | have to write TeX macros, update makeinfo, and update the Emacs | |
17 | info-formatting functions. | |
18 | ||
19 | II. COMPATIBILITY | |
20 | ||
21 | These macros should work with GNU m4 and System V m4; they do not work | |
22 | with Sun or Berkeley M4. | |
23 | ||
24 | III. USAGE | |
25 | ||
26 | A. M4 INVOCATION | |
27 | Assume this file is called "pretex.m4". Then, to preprocess a | |
28 | document "mybook.texinfo" you might do something like the following: | |
29 | ||
30 | m4 pretex.m4 none.m4 PARTIC.m4 mybook.texinfo >mybook-PARTIC.texinfo | |
31 | ||
32 | ---where your path is set to find GNU or SysV "m4", and the other m4 | |
33 | files mentioned are as follows: | |
34 | ||
35 | none.m4: A file that defines, as 0, all the options you might | |
36 | want to turn on using the conditionals defined below. | |
37 | Unlike the C preprocessor, m4 does not default | |
38 | undefined macros to 0. For example, here is a "none.m4" | |
39 | I have been using: | |
40 | _divert__(-1) | |
41 | ||
42 | _define__(<_ALL_ARCH__>,<0>) | |
43 | _define__(<_INTERNALS__>,<0>) | |
44 | ||
45 | _define__(<_AMD29K__>,<0>) | |
46 | _define__(<_I80386__>,<0>) | |
47 | _define__(<_I960__>,<0>) | |
48 | _define__(<_M680X0__>,<0>) | |
49 | _define__(<_SPARC__>,<0>) | |
50 | _define__(<_VAX__>,<0>) | |
51 | ||
52 | _divert__<> | |
53 | ||
54 | PARTIC.m4: A file that turns on whichever options you actually | |
55 | want the manual configured for, in this particular | |
56 | instance. Its contents are similar to one or more of | |
57 | the lines in "none.m4", but of course the second | |
58 | argument to _define__ is <1> rather than <0>. | |
59 | ||
92d30360 | 60 | This is also a convenient place to _define__ any macros |
07d021a6 JG |
61 | that you want to expand to different text for |
62 | different configurations---for example, the name of | |
63 | the program being described. | |
64 | ||
65 | Naturally, these are just suggested conventions; you could put your macro | |
66 | definitions in any files or combinations of files you like. | |
67 | ||
68 | These macros use the characters < and > as m4 quotes; if you need | |
69 | these characters in your text, you will also want to use the macros | |
70 | _0__ and _1__ from this package---see the description of "Quote | |
71 | Handling" in the "Implementation" section below. | |
72 | ||
73 | B. WHAT GOES IN THE PRE-TEXINFO SOURCE | |
74 | ||
75 | For the most part, the text of your book. In addition, you can | |
92d30360 | 76 | have text that is included only conditionally, using the macros |
07d021a6 JG |
77 | _if__ and _fi__ defined below. They BOTH take an argument! This is |
78 | primarily meant for readability (so a human can more easily see what | |
79 | conditional end matches what conditional beginning), but the argument | |
80 | is actually used in the _fi__ as well as the _if__ implementation. | |
81 | You should always give a _fi__ the same argument as its matching | |
82 | _if__. Other arguments may appear to work for a while, but are almost | |
83 | certain to produce the wrong output for some configurations. | |
84 | ||
85 | For example, here is an excerpt from the very beginning of the | |
86 | documentation for GNU as, to name the info file appropriately for | |
87 | different configurations: | |
88 | _if__(_ALL_ARCH__) | |
89 | @setfilename as.info | |
90 | _fi__(_ALL_ARCH__) | |
91 | _if__(_M680X0__ && !_ALL_ARCH__) | |
92 | @setfilename as-m680x0.info | |
93 | _fi__(_M680X0__ && !_ALL_ARCH__) | |
94 | _if__(_AMD29K__ && !_ALL_ARCH__) | |
95 | @setfilename as-29k.info | |
96 | _fi__(_AMD29K__ && !_ALL_ARCH__) | |
97 | ||
98 | Note that you can use Boolean expressions in the arguments; the | |
92d30360 | 99 | expression language is that of the built-in m4 macro `eval', described |
07d021a6 JG |
100 | in the m4 manual. |
101 | ||
102 | IV. IMPLEMENTATION | |
103 | ||
104 | A.PRIMITIVE RENAMING | |
105 | First, we redefine m4's built-ins to avoid conflict with plain text. | |
106 | The naming convention used is that our macros all begin with a single | |
107 | underbar and end with two underbars. The asymmetry is meant to avoid | |
108 | conflict with some other conventions (which we may want to document) that | |
109 | are intended to avoid conflict, like ANSI C predefined macros. | |
110 | ||
111 | define(`_undefine__',defn(`undefine')) | |
112 | define(`_define__',defn(`define')) | |
113 | define(`_defn__',defn(`defn')) | |
114 | define(`_ppf__',`_define__(`_$1__',_defn__(`$1'))_undefine__(`$1')') | |
115 | _ppf__(`builtin') | |
116 | _ppf__(`changecom') | |
117 | _ppf__(`changequote') | |
118 | _ppf__(`decr') | |
119 | _ppf__(`define') | |
120 | _ppf__(`defn') | |
121 | _ppf__(`divert') | |
9bcc06ef | 122 | _ppf__(`divnum') |
07d021a6 JG |
123 | _ppf__(`dnl') |
124 | _ppf__(`dumpdef') | |
125 | _ppf__(`errprint') | |
9bcc06ef | 126 | _ppf__(`esyscmd') |
07d021a6 | 127 | _ppf__(`eval') |
9bcc06ef | 128 | _ppf__(`format') |
07d021a6 JG |
129 | _ppf__(`ifdef') |
130 | _ppf__(`ifelse') | |
131 | _ppf__(`include') | |
132 | _ppf__(`incr') | |
133 | _ppf__(`index') | |
134 | _ppf__(`len') | |
135 | _ppf__(`m4exit') | |
136 | _ppf__(`m4wrap') | |
137 | _ppf__(`maketemp') | |
9bcc06ef | 138 | _ppf__(`patsubst') |
07d021a6 JG |
139 | _ppf__(`popdef') |
140 | _ppf__(`pushdef') | |
92d30360 | 141 | _ppf__(`regexp') |
07d021a6 JG |
142 | _ppf__(`shift') |
143 | _ppf__(`sinclude') | |
144 | _ppf__(`substr') | |
145 | _ppf__(`syscmd') | |
146 | _ppf__(`sysval') | |
147 | _ppf__(`traceoff') | |
148 | _ppf__(`traceon') | |
149 | _ppf__(`translit') | |
150 | _ppf__(`undefine') | |
151 | _ppf__(`undivert') | |
9bcc06ef | 152 | _ppf__(`unix') |
07d021a6 JG |
153 | |
154 | B. QUOTE HANDLING. | |
155 | ||
156 | The characters used as quotes by M4, by default, are unfortunately | |
157 | quite likely to occur in ordinary text. To avoid surprises, we will | |
158 | use the characters <> ---which are just as suggestive (more so to | |
159 | Francophones, perhaps) but a little less common in text (save for | |
160 | those poor Francophones. You win some, you lose some). Still, we | |
161 | expect also to have to set < and > occasionally in text; to do that, | |
162 | we define a macro to turn off quote handling (_0__) and a macro to | |
163 | turn it back on (_1__), according to our convention. | |
164 | ||
165 | BEWARE: This seems to make < and > unusable as relational operations | |
166 | in calls to the builtin "eval". So far I've gotten | |
167 | along without; but a better choice may be possible. | |
168 | ||
169 | Note that we postponed this for a while, for convenience in discussing | |
170 | the issue and in the primitive renaming---not to mention in defining | |
171 | _0__ and _1__ themselves! However, the quote redefinitions MUST | |
172 | precede the _if__ / _fi__ definitions, because M4 will expand the text | |
173 | as given---if we use the wrong quotes here, we will get the wrong | |
174 | quotes when we use the conditionals. | |
175 | ||
176 | _define__(_0__,`_changequote__(\ 1,\ 2)')_define__(_1__,`_changequote__(<,>)') | |
177 | _1__ | |
178 | ||
179 | C. CONDITIONALS | |
180 | ||
181 | We define two macros, _if__ and _fi__. BOTH take arguments! This is | |
182 | meant both to help the human reader match up a _fi__ with its | |
183 | corresponding _if__ and to aid in the implementation. You may use the | |
184 | full expression syntax supported by M4 (see docn of `eval' builtin in | |
185 | the m4 manual). | |
186 | ||
187 | The conditional macros are carefully defined to avoid introducing | |
188 | extra whitespace (i.e., blank lines or blank characters). One side | |
189 | effect exists--- | |
190 | ||
191 | BEWARE: text following an `_if__' on the same line is | |
192 | DISCARDED even if the condition is true; text | |
193 | following a `_fi__' on the same line is also | |
194 | always discarded. | |
195 | ||
196 | The recommended convention is to always place _if__ and _fi__ on a | |
197 | line by themselves. This will also aid the human reader. TeX won't | |
198 | care about the line breaks; as for info, you may want to insert calls | |
199 | to `@refill' at the end of paragraphs containing conditionalized text, | |
200 | where you don't want line breaks separating unconditional from | |
201 | conditional text. info formatting will then give you nice looking | |
202 | paragraphs in the info file. | |
203 | ||
204 | Nesting: conditionals are designed to nest, in the following way: | |
205 | *nothing* is output between an outer pair of false conditionals, even | |
206 | if there are true conditionals inside. A false conditional "defeats" | |
207 | all conditionals within it. The counter _IF_FS__ is used to | |
208 | implement this; kindly avoid redefining it directly. | |
209 | ||
210 | _define__(<_IF_FS__>,<0>) | |
9bcc06ef RP |
211 | |
212 | NOTE: The definitions for our "pushf" and "popf" macros use eval | |
213 | rather than incr and decr, because GNU m4 (0.75) tries to call eval | |
214 | for us when we say "incr" or "decr"---but doesn't notice we've changed | |
215 | eval's name. | |
216 | ||
07d021a6 JG |
217 | _define__( |
218 | <_pushf__>, | |
219 | <_define__(<_IF_FS__>, | |
9bcc06ef | 220 | _eval__((_IF_FS__)+1))>) |
07d021a6 JG |
221 | _define__( |
222 | <_popf__>, | |
223 | <_ifelse__(0,_IF_FS__, | |
224 | <<>_dnl__<>>, | |
9bcc06ef | 225 | <_define__(<_IF_FS__>,_eval__((_IF_FS__)-1))>)>) |
07d021a6 JG |
226 | |
227 | _define__( | |
228 | <_if__>, | |
229 | <_ifelse__(1,_eval__( ($1) ), | |
230 | <<>_dnl__<>>, | |
231 | <_pushf__<>_divert__(-1)>)>) | |
232 | _define__( | |
233 | <_fi__>, | |
234 | <_ifelse__(1,_eval__( ($1) ), | |
235 | <<>_dnl__<>>, | |
236 | <_popf__<>_ifelse__(0,_IF_FS__, | |
237 | <_divert__<>_dnl__<>>,<>)>)>) | |
238 | ||
239 | D. CHAPTER/SECTION MACRO | |
240 | In a parametrized manual, the heading level may need to be calculated; | |
241 | for example, a manual that has a chapter on machine dependencies | |
242 | should be conditionally structured as follows: | |
243 | - IF the manual is configured for a SINGLE machine type, use | |
244 | the chapter heading for that machine type, and run headings down | |
245 | from there (top level for a particular machine is chapter, then within | |
246 | that we have section, subsection etc); | |
247 | - ELSE, if MANY machine types are described in the chapter, | |
248 | use a generic chapter heading such as "@chapter Machine Dependencies", | |
249 | use "section" for the top level description of EACH machine, and run | |
250 | headings down from there (top level for a particular machine is | |
251 | section, then within that we have subsection, subsubsection etc). | |
252 | ||
253 | The macro <_CHAPSEC__> is for this purpose: its argument is evaluated (so | |
254 | you can construct expressions to express choices such as above), then | |
255 | expands as follows: | |
256 | 0: @chapter | |
257 | 1: @section | |
258 | 2: @subsection | |
259 | 3: @subsubsection | |
260 | ...and so on. | |
261 | ||
262 | _define__(<_CHAPSEC__>,<@_cs__(_eval__($1))>) | |
263 | _define__(<_cs__>,<_ifelse__( | |
264 | 0, $1, <chapter>, | |
265 | 1, $1, <section>, | |
266 | <sub<>_cs__(_eval__($1 - 1))>)>) | |
267 | ||
268 | _divert__<>_dnl__<> |