xref: /netbsd-src/external/bsd/mdocml/dist/mandoc.3 (revision 544c191c349c1704c9d5e679d12ec15cff579663)
1*544c191cSchristos.\"	Id: mandoc.3,v 1.44 2018/12/30 00:49:55 schwarze Exp
248741257Sjoerg.\"
348741257Sjoerg.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
49508192eSchristos.\" Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
548741257Sjoerg.\"
648741257Sjoerg.\" Permission to use, copy, modify, and distribute this software for any
748741257Sjoerg.\" purpose with or without fee is hereby granted, provided that the above
848741257Sjoerg.\" copyright notice and this permission notice appear in all copies.
948741257Sjoerg.\"
1048741257Sjoerg.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1148741257Sjoerg.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1248741257Sjoerg.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1348741257Sjoerg.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1448741257Sjoerg.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1548741257Sjoerg.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1648741257Sjoerg.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1748741257Sjoerg.\"
18*544c191cSchristos.Dd December 30, 2018
1948741257Sjoerg.Dt MANDOC 3
2048741257Sjoerg.Os
2148741257Sjoerg.Sh NAME
2248741257Sjoerg.Nm mandoc ,
239ff1f2acSchristos.Nm deroff ,
2448741257Sjoerg.Nm mparse_alloc ,
25*544c191cSchristos.Nm mparse_copy ,
2648741257Sjoerg.Nm mparse_free ,
27fec65c98Schristos.Nm mparse_open ,
2848741257Sjoerg.Nm mparse_readfd ,
2948741257Sjoerg.Nm mparse_reset ,
30*544c191cSchristos.Nm mparse_result
3148741257Sjoerg.Nd mandoc macro compiler library
3248741257Sjoerg.Sh SYNOPSIS
33fec65c98Schristos.In sys/types.h
34*544c191cSchristos.In stdio.h
3548741257Sjoerg.In mandoc.h
36fec65c98Schristos.Pp
37fec65c98Schristos.Fd "#define ASCII_NBRSP"
38fec65c98Schristos.Fd "#define ASCII_HYPH"
39fec65c98Schristos.Fd "#define ASCII_BREAK"
40fec65c98Schristos.Ft struct mparse *
4148741257Sjoerg.Fo mparse_alloc
42fec65c98Schristos.Fa "int options"
43c9bcef03Schristos.Fa "enum mandoc_os oe_e"
44c9bcef03Schristos.Fa "char *os_s"
45fec65c98Schristos.Fc
46fec65c98Schristos.Ft void
4748741257Sjoerg.Fo mparse_free
4848741257Sjoerg.Fa "struct mparse *parse"
4948741257Sjoerg.Fc
50c5f73b34Sjoerg.Ft void
51*544c191cSchristos.Fo mparse_copy
52*544c191cSchristos.Fa "const struct mparse *parse"
53c5f73b34Sjoerg.Fc
549ff1f2acSchristos.Ft int
55fec65c98Schristos.Fo mparse_open
56fec65c98Schristos.Fa "struct mparse *parse"
57fec65c98Schristos.Fa "const char *fname"
58fec65c98Schristos.Fc
59*544c191cSchristos.Ft void
6048741257Sjoerg.Fo mparse_readfd
6148741257Sjoerg.Fa "struct mparse *parse"
6248741257Sjoerg.Fa "int fd"
6348741257Sjoerg.Fa "const char *fname"
6448741257Sjoerg.Fc
6548741257Sjoerg.Ft void
6648741257Sjoerg.Fo mparse_reset
6748741257Sjoerg.Fa "struct mparse *parse"
6848741257Sjoerg.Fc
69*544c191cSchristos.Ft struct roff_meta *
7048741257Sjoerg.Fo mparse_result
7148741257Sjoerg.Fa "struct mparse *parse"
729508192eSchristos.Fc
739ff1f2acSchristos.In roff.h
749ff1f2acSchristos.Ft void
759ff1f2acSchristos.Fo deroff
769ff1f2acSchristos.Fa "char **dest"
779ff1f2acSchristos.Fa "const struct roff_node *node"
78fec65c98Schristos.Fc
79fec65c98Schristos.In sys/types.h
80fec65c98Schristos.In mandoc.h
81fec65c98Schristos.In mdoc.h
8248741257Sjoerg.Vt extern const char * const * mdoc_argnames;
8348741257Sjoerg.Vt extern const char * const * mdoc_macronames;
84fec65c98Schristos.In sys/types.h
85fec65c98Schristos.In mandoc.h
86fec65c98Schristos.In man.h
879ff1f2acSchristos.Vt extern const char * const * man_macronames;
8848741257Sjoerg.Sh DESCRIPTION
8948741257SjoergThe
9048741257Sjoerg.Nm mandoc
9148741257Sjoerglibrary parses a
9248741257Sjoerg.Ux
9348741257Sjoergmanual into an abstract syntax tree (AST).
9448741257Sjoerg.Ux
9548741257Sjoergmanuals are composed of
9648741257Sjoerg.Xr mdoc 7
9748741257Sjoergor
9848741257Sjoerg.Xr man 7 ,
9948741257Sjoergand may be mixed with
10048741257Sjoerg.Xr roff 7 ,
10148741257Sjoerg.Xr tbl 7 ,
10248741257Sjoergand
10348741257Sjoerg.Xr eqn 7
10448741257Sjoerginvocations.
10548741257Sjoerg.Pp
10648741257SjoergThe following describes a general parse sequence:
10748741257Sjoerg.Bl -enum
10848741257Sjoerg.It
10948741257Sjoerginitiate a parsing sequence with
110fec65c98Schristos.Xr mchars_alloc 3
111fec65c98Schristosand
11248741257Sjoerg.Fn mparse_alloc ;
11348741257Sjoerg.It
114fec65c98Schristosopen a file with
115fec65c98Schristos.Xr open 2
116fec65c98Schristosor
117fec65c98Schristos.Fn mparse_open ;
118fec65c98Schristos.It
119fec65c98Schristosparse it with
12048741257Sjoerg.Fn mparse_readfd ;
12148741257Sjoerg.It
1229ff1f2acSchristosclose it with
1239ff1f2acSchristos.Xr close 2 ;
1249ff1f2acSchristos.It
125fec65c98Schristosretrieve the syntax tree with
12648741257Sjoerg.Fn mparse_result ;
12748741257Sjoerg.It
1289508192eSchristosif information about the validity of the input is needed, fetch it with
1299508192eSchristos.Fn mparse_updaterc ;
1309508192eSchristos.It
1319ff1f2acSchristositerate over parse nodes with starting from the
1329ff1f2acSchristos.Fa first
1339ff1f2acSchristosmember of the returned
134*544c191cSchristos.Vt struct roff_meta ;
13548741257Sjoerg.It
13648741257Sjoergfree all allocated memory with
137fec65c98Schristos.Fn mparse_free
138fec65c98Schristosand
139fec65c98Schristos.Xr mchars_free 3 ,
14048741257Sjoergor invoke
14148741257Sjoerg.Fn mparse_reset
1429ff1f2acSchristosand go back to step 2 to parse new files.
14348741257Sjoerg.El
144c5f73b34Sjoerg.Sh REFERENCE
145c5f73b34SjoergThis section documents the functions, types, and variables available
146c5f73b34Sjoergvia
147fec65c98Schristos.In mandoc.h ,
148fec65c98Schristoswith the exception of those documented in
149fec65c98Schristos.Xr mandoc_escape 3
150fec65c98Schristosand
151fec65c98Schristos.Xr mchars_alloc 3 .
152c5f73b34Sjoerg.Ss Types
153c5f73b34Sjoerg.Bl -ohang
154c5f73b34Sjoerg.It Vt "enum mandocerr"
155fec65c98SchristosAn error or warning message during parsing.
156c5f73b34Sjoerg.It Vt "enum mandoclevel"
157c5f73b34SjoergA classification of an
158fec65c98Schristos.Vt "enum mandocerr"
159c5f73b34Sjoergas regards system operation.
1609ff1f2acSchristosSee the DIAGNOSTICS section in
1619ff1f2acSchristos.Xr mandoc 1
1629ff1f2acSchristosregarding the meanings of the levels.
163c5f73b34Sjoerg.It Vt "struct mparse"
164c5f73b34SjoergAn opaque pointer to a running parse sequence.
165c5f73b34SjoergCreated with
166c5f73b34Sjoerg.Fn mparse_alloc
167c5f73b34Sjoergand freed with
168c5f73b34Sjoerg.Fn mparse_free .
169c5f73b34SjoergThis may be used across parsed input if
170c5f73b34Sjoerg.Fn mparse_reset
171c5f73b34Sjoergis called between parses.
172c5f73b34Sjoerg.El
173c5f73b34Sjoerg.Ss Functions
174c5f73b34Sjoerg.Bl -ohang
1759ff1f2acSchristos.It Fn deroff
176fec65c98SchristosObtain a text-only representation of a
1779ff1f2acSchristos.Vt struct roff_node ,
178fec65c98Schristosincluding text contained in its child nodes.
1799ff1f2acSchristosTo be used on children of the
1809ff1f2acSchristos.Fa first
1819ff1f2acSchristosmember of
182*544c191cSchristos.Vt struct roff_meta .
183fec65c98SchristosWhen it is no longer needed, the pointer returned from
1849ff1f2acSchristos.Fn deroff
185fec65c98Schristoscan be passed to
186fec65c98Schristos.Xr free 3 .
187c5f73b34Sjoerg.It Fn mparse_alloc
188c5f73b34SjoergAllocate a parser.
189fec65c98SchristosThe arguments have the following effect:
190fec65c98Schristos.Bl -tag -offset 5n -width inttype
191fec65c98Schristos.It Ar options
192fec65c98SchristosWhen the
193fec65c98Schristos.Dv MPARSE_MDOC
194fec65c98Schristosor
195fec65c98Schristos.Dv MPARSE_MAN
196fec65c98Schristosbit is set, only that parser is used.
197fec65c98SchristosOtherwise, the document type is automatically detected.
198fec65c98Schristos.Pp
199fec65c98SchristosWhen the
200fec65c98Schristos.Dv MPARSE_SO
201fec65c98Schristosbit is set,
202fec65c98Schristos.Xr roff 7
203fec65c98Schristos.Ic \&so
204fec65c98Schristosfile inclusion requests are always honoured.
205fec65c98SchristosOtherwise, if the request is the only content in an input file,
206fec65c98Schristosonly the file name is remembered, to be returned in the
207fec65c98Schristos.Fa sodest
208*544c191cSchristosfield of
209*544c191cSchristos.Vt struct roff_meta .
210fec65c98Schristos.Pp
211fec65c98SchristosWhen the
212fec65c98Schristos.Dv MPARSE_QUICK
213fec65c98Schristosbit is set, parsing is aborted after the NAME section.
214fec65c98SchristosThis is for example useful in
215fec65c98Schristos.Xr makewhatis 8
216fec65c98Schristos.Fl Q
217fec65c98Schristosto quickly build minimal databases.
218*544c191cSchristos.Pp
219*544c191cSchristosWhen the
220*544c191cSchristos.Dv MARSE_VALIDATE
221*544c191cSchristosbit is set,
222*544c191cSchristos.Fn mparse_result
223*544c191cSchristosruns the validation functions before returning the syntax tree.
224*544c191cSchristosThis is almost always required, except in certain debugging scenarios,
225*544c191cSchristosfor example to dump unvalidated syntax trees.
226c9bcef03Schristos.It Ar os_e
227c9bcef03SchristosOperating system to check base system conventions for.
228c9bcef03SchristosIf
229c9bcef03Schristos.Dv MANDOC_OS_OTHER ,
230c9bcef03Schristosthe system is automatically detected from
231c9bcef03Schristos.Ic \&Os ,
232c9bcef03Schristos.Fl Ios ,
233c9bcef03Schristosor
234c9bcef03Schristos.Xr uname 3 .
235c9bcef03Schristos.It Ar os_s
236fec65c98SchristosA default string for the
237fec65c98Schristos.Xr mdoc 7
238c9bcef03Schristos.Ic \&Os
239fec65c98Schristosmacro, overriding the
240fec65c98Schristos.Dv OSNAME
241fec65c98Schristospreprocessor definition and the results of
242fec65c98Schristos.Xr uname 3 .
2439ff1f2acSchristosPassing
2449ff1f2acSchristos.Dv NULL
2459ff1f2acSchristossets no default.
246fec65c98Schristos.El
247fec65c98Schristos.Pp
248c5f73b34SjoergThe same parser may be used for multiple files so long as
249c5f73b34Sjoerg.Fn mparse_reset
250c5f73b34Sjoergis called between parses.
251c5f73b34Sjoerg.Fn mparse_free
252c5f73b34Sjoergmust be called to free the memory allocated by this function.
25370f041f9SjoergDeclared in
25470f041f9Sjoerg.In mandoc.h ,
25570f041f9Sjoergimplemented in
25670f041f9Sjoerg.Pa read.c .
257c5f73b34Sjoerg.It Fn mparse_free
258c5f73b34SjoergFree all memory allocated by
259c5f73b34Sjoerg.Fn mparse_alloc .
26070f041f9SjoergDeclared in
26170f041f9Sjoerg.In mandoc.h ,
26270f041f9Sjoergimplemented in
26370f041f9Sjoerg.Pa read.c .
264*544c191cSchristos.It Fn mparse_copy
265*544c191cSchristosDump a copy of the input to the standard output; used for
266*544c191cSchristos.Fl man T Ns Cm man .
26770f041f9SjoergDeclared in
26870f041f9Sjoerg.In mandoc.h ,
26970f041f9Sjoergimplemented in
27070f041f9Sjoerg.Pa read.c .
271fec65c98Schristos.It Fn mparse_open
2729ff1f2acSchristosOpen the file for reading.
2739ff1f2acSchristosIf that fails and
274fec65c98Schristos.Fa fname
2759ff1f2acSchristosdoes not already end in
2769ff1f2acSchristos.Ql .gz ,
2779ff1f2acSchristostry again after appending
2789ff1f2acSchristos.Ql .gz .
2799ff1f2acSchristosSave the information whether the file is zipped or not.
2809ff1f2acSchristosReturn a file descriptor open for reading or -1 on failure.
281fec65c98SchristosIt can be passed to
282fec65c98Schristos.Fn mparse_readfd
283fec65c98Schristosor used directly.
284fec65c98SchristosDeclared in
285fec65c98Schristos.In mandoc.h ,
286fec65c98Schristosimplemented in
287fec65c98Schristos.Pa read.c .
288fec65c98Schristos.It Fn mparse_readfd
289fec65c98SchristosParse a file descriptor opened with
290fec65c98Schristos.Xr open 2
291fec65c98Schristosor
292fec65c98Schristos.Fn mparse_open .
293fec65c98SchristosPass the associated filename in
294fec65c98Schristos.Va fname .
295fec65c98SchristosThis function may be called multiple times with different parameters; however,
2969ff1f2acSchristos.Xr close 2
2979ff1f2acSchristosand
298c5f73b34Sjoerg.Fn mparse_reset
299c5f73b34Sjoergshould be invoked between parses.
30070f041f9SjoergDeclared in
30170f041f9Sjoerg.In mandoc.h ,
30270f041f9Sjoergimplemented in
30370f041f9Sjoerg.Pa read.c .
304c5f73b34Sjoerg.It Fn mparse_reset
305c5f73b34SjoergReset a parser so that
306c5f73b34Sjoerg.Fn mparse_readfd
307c5f73b34Sjoergmay be used again.
30870f041f9SjoergDeclared in
30970f041f9Sjoerg.In mandoc.h ,
31070f041f9Sjoergimplemented in
31170f041f9Sjoerg.Pa read.c .
312c5f73b34Sjoerg.It Fn mparse_result
313c5f73b34SjoergObtain the result of a parse.
3149508192eSchristosDeclared in
3159508192eSchristos.In mandoc.h ,
3169508192eSchristosimplemented in
3179508192eSchristos.Pa read.c .
318c5f73b34Sjoerg.El
319c5f73b34Sjoerg.Ss Variables
320c5f73b34Sjoerg.Bl -ohang
321c5f73b34Sjoerg.It Va man_macronames
3229ff1f2acSchristosThe string representation of a
3239ff1f2acSchristos.Xr man 7
3249ff1f2acSchristosmacro as indexed by
325c5f73b34Sjoerg.Vt "enum mant" .
326c5f73b34Sjoerg.It Va mdoc_argnames
3279ff1f2acSchristosThe string representation of an
3289ff1f2acSchristos.Xr mdoc 7
3299ff1f2acSchristosmacro argument as indexed by
330c5f73b34Sjoerg.Vt "enum mdocargt" .
331c5f73b34Sjoerg.It Va mdoc_macronames
3329ff1f2acSchristosThe string representation of an
3339ff1f2acSchristos.Xr mdoc 7
3349ff1f2acSchristosmacro as indexed by
335c5f73b34Sjoerg.Vt "enum mdoct" .
336c5f73b34Sjoerg.El
33748741257Sjoerg.Sh IMPLEMENTATION NOTES
33848741257SjoergThis section consists of structural documentation for
33948741257Sjoerg.Xr mdoc 7
34048741257Sjoergand
34148741257Sjoerg.Xr man 7
342c5f73b34Sjoergsyntax trees and strings.
343c5f73b34Sjoerg.Ss Man and Mdoc Strings
344c5f73b34SjoergStrings may be extracted from mdoc and man meta-data, or from text
345c5f73b34Sjoergnodes (MDOC_TEXT and MAN_TEXT, respectively).
346c5f73b34SjoergThese strings have special non-printing formatting cues embedded in the
347c5f73b34Sjoergtext itself, as well as
348c5f73b34Sjoerg.Xr roff 7
349c5f73b34Sjoergescapes preserved from input.
350c5f73b34SjoergImplementing systems will need to handle both situations to produce
351c5f73b34Sjoerghuman-readable text.
352c5f73b34SjoergIn general, strings may be assumed to consist of 7-bit ASCII characters.
353c5f73b34Sjoerg.Pp
354c5f73b34SjoergThe following non-printing characters may be embedded in text strings:
355c5f73b34Sjoerg.Bl -tag -width Ds
356c5f73b34Sjoerg.It Dv ASCII_NBRSP
357c5f73b34SjoergA non-breaking space character.
358c5f73b34Sjoerg.It Dv ASCII_HYPH
359c5f73b34SjoergA soft hyphen.
360fec65c98Schristos.It Dv ASCII_BREAK
361fec65c98SchristosA breakable zero-width space.
362c5f73b34Sjoerg.El
363c5f73b34Sjoerg.Pp
364c5f73b34SjoergEscape characters are also passed verbatim into text strings.
365c5f73b34SjoergAn escape character is a sequence of characters beginning with the
366c5f73b34Sjoergbackslash
367c5f73b34Sjoerg.Pq Sq \e .
368c5f73b34SjoergTo construct human-readable text, these should be intercepted with
369fec65c98Schristos.Xr mandoc_escape 3
370fec65c98Schristosand converted with one the functions described in
371fec65c98Schristos.Xr mchars_alloc 3 .
37248741257Sjoerg.Ss Man Abstract Syntax Tree
37348741257SjoergThis AST is governed by the ontological rules dictated in
37448741257Sjoerg.Xr man 7
37548741257Sjoergand derives its terminology accordingly.
37648741257Sjoerg.Pp
37748741257SjoergThe AST is composed of
3789ff1f2acSchristos.Vt struct roff_node
37948741257Sjoergnodes with element, root and text types as declared by the
38048741257Sjoerg.Va type
38148741257Sjoergfield.
38248741257SjoergEach node also provides its parse point (the
38348741257Sjoerg.Va line ,
3849ff1f2acSchristos.Va pos ,
38548741257Sjoergand
3869ff1f2acSchristos.Va sec
38748741257Sjoergfields), its position in the tree (the
38848741257Sjoerg.Va parent ,
38948741257Sjoerg.Va child ,
39048741257Sjoerg.Va next
39148741257Sjoergand
39248741257Sjoerg.Va prev
39348741257Sjoergfields) and some type-specific data.
39448741257Sjoerg.Pp
39548741257SjoergThe tree itself is arranged according to the following normal form,
39648741257Sjoergwhere capitalised non-terminals represent nodes.
39748741257Sjoerg.Pp
39848741257Sjoerg.Bl -tag -width "ELEMENTXX" -compact
39948741257Sjoerg.It ROOT
40048741257Sjoerg\(<- mnode+
40148741257Sjoerg.It mnode
40248741257Sjoerg\(<- ELEMENT | TEXT | BLOCK
40348741257Sjoerg.It BLOCK
40448741257Sjoerg\(<- HEAD BODY
40548741257Sjoerg.It HEAD
40648741257Sjoerg\(<- mnode*
40748741257Sjoerg.It BODY
40848741257Sjoerg\(<- mnode*
40948741257Sjoerg.It ELEMENT
41048741257Sjoerg\(<- ELEMENT | TEXT*
41148741257Sjoerg.It TEXT
412c5f73b34Sjoerg\(<- [[:ascii:]]*
41348741257Sjoerg.El
41448741257Sjoerg.Pp
41548741257SjoergThe only elements capable of nesting other elements are those with
416fec65c98Schristosnext-line scope as documented in
41748741257Sjoerg.Xr man 7 .
41848741257Sjoerg.Ss Mdoc Abstract Syntax Tree
41948741257SjoergThis AST is governed by the ontological
42048741257Sjoergrules dictated in
42148741257Sjoerg.Xr mdoc 7
42248741257Sjoergand derives its terminology accordingly.
42348741257Sjoerg.Qq In-line
42448741257Sjoergelements described in
42548741257Sjoerg.Xr mdoc 7
42648741257Sjoergare described simply as
42748741257Sjoerg.Qq elements .
42848741257Sjoerg.Pp
42948741257SjoergThe AST is composed of
4309ff1f2acSchristos.Vt struct roff_node
43148741257Sjoergnodes with block, head, body, element, root and text types as declared
43248741257Sjoergby the
43348741257Sjoerg.Va type
43448741257Sjoergfield.
43548741257SjoergEach node also provides its parse point (the
43648741257Sjoerg.Va line ,
4379ff1f2acSchristos.Va pos ,
43848741257Sjoergand
4399ff1f2acSchristos.Va sec
44048741257Sjoergfields), its position in the tree (the
44148741257Sjoerg.Va parent ,
44248741257Sjoerg.Va child ,
4439ff1f2acSchristos.Va last ,
44448741257Sjoerg.Va next
44548741257Sjoergand
44648741257Sjoerg.Va prev
44748741257Sjoergfields) and some type-specific data, in particular, for nodes generated
44848741257Sjoergfrom macros, the generating macro in the
44948741257Sjoerg.Va tok
45048741257Sjoergfield.
45148741257Sjoerg.Pp
45248741257SjoergThe tree itself is arranged according to the following normal form,
45348741257Sjoergwhere capitalised non-terminals represent nodes.
45448741257Sjoerg.Pp
45548741257Sjoerg.Bl -tag -width "ELEMENTXX" -compact
45648741257Sjoerg.It ROOT
45748741257Sjoerg\(<- mnode+
45848741257Sjoerg.It mnode
45948741257Sjoerg\(<- BLOCK | ELEMENT | TEXT
46048741257Sjoerg.It BLOCK
46148741257Sjoerg\(<- HEAD [TEXT] (BODY [TEXT])+ [TAIL [TEXT]]
46248741257Sjoerg.It ELEMENT
46348741257Sjoerg\(<- TEXT*
46448741257Sjoerg.It HEAD
46548741257Sjoerg\(<- mnode*
46648741257Sjoerg.It BODY
46748741257Sjoerg\(<- mnode* [ENDBODY mnode*]
46848741257Sjoerg.It TAIL
46948741257Sjoerg\(<- mnode*
47048741257Sjoerg.It TEXT
471c5f73b34Sjoerg\(<- [[:ascii:]]*
47248741257Sjoerg.El
47348741257Sjoerg.Pp
47448741257SjoergOf note are the TEXT nodes following the HEAD, BODY and TAIL nodes of
47548741257Sjoergthe BLOCK production: these refer to punctuation marks.
47648741257SjoergFurthermore, although a TEXT node will generally have a non-zero-length
47748741257Sjoergstring, in the specific case of
47848741257Sjoerg.Sq \&.Bd \-literal ,
47948741257Sjoergan empty line will produce a zero-length string.
48048741257SjoergMultiple body parts are only found in invocations of
48148741257Sjoerg.Sq \&Bl \-column ,
48248741257Sjoergwhere a new body introduces a new phrase.
48348741257Sjoerg.Pp
48448741257SjoergThe
48548741257Sjoerg.Xr mdoc 7
486c5f73b34Sjoergsyntax tree accommodates for broken block structures as well.
48748741257SjoergThe ENDBODY node is available to end the formatting associated
48848741257Sjoergwith a given block before the physical end of that block.
48948741257SjoergIt has a non-null
49048741257Sjoerg.Va end
49148741257Sjoergfield, is of the BODY
49248741257Sjoerg.Va type ,
49348741257Sjoerghas the same
49448741257Sjoerg.Va tok
49548741257Sjoergas the BLOCK it is ending, and has a
49648741257Sjoerg.Va pending
49748741257Sjoergfield pointing to that BLOCK's BODY node.
49848741257SjoergIt is an indirect child of that BODY node
49948741257Sjoergand has no children of its own.
50048741257Sjoerg.Pp
50148741257SjoergAn ENDBODY node is generated when a block ends while one of its child
50248741257Sjoergblocks is still open, like in the following example:
50348741257Sjoerg.Bd -literal -offset indent
50448741257Sjoerg\&.Ao ao
50548741257Sjoerg\&.Bo bo ac
50648741257Sjoerg\&.Ac bc
50748741257Sjoerg\&.Bc end
50848741257Sjoerg.Ed
50948741257Sjoerg.Pp
51048741257SjoergThis example results in the following block structure:
51148741257Sjoerg.Bd -literal -offset indent
51248741257SjoergBLOCK Ao
51348741257Sjoerg    HEAD Ao
51448741257Sjoerg    BODY Ao
51548741257Sjoerg        TEXT ao
51648741257Sjoerg        BLOCK Bo, pending -> Ao
51748741257Sjoerg            HEAD Bo
51848741257Sjoerg            BODY Bo
51948741257Sjoerg                TEXT bo
52048741257Sjoerg                TEXT ac
52148741257Sjoerg                ENDBODY Ao, pending -> Ao
52248741257Sjoerg                TEXT bc
52348741257SjoergTEXT end
52448741257Sjoerg.Ed
52548741257Sjoerg.Pp
52648741257SjoergHere, the formatting of the
527c9bcef03Schristos.Ic \&Ao
52848741257Sjoergblock extends from TEXT ao to TEXT ac,
52948741257Sjoergwhile the formatting of the
530c9bcef03Schristos.Ic \&Bo
53148741257Sjoergblock extends from TEXT bo to TEXT bc.
53248741257SjoergIt renders as follows in
53348741257Sjoerg.Fl T Ns Cm ascii
53448741257Sjoergmode:
53548741257Sjoerg.Pp
53648741257Sjoerg.Dl <ao [bo ac> bc] end
53748741257Sjoerg.Pp
53848741257SjoergSupport for badly-nested blocks is only provided for backward
53948741257Sjoergcompatibility with some older
54048741257Sjoerg.Xr mdoc 7
54148741257Sjoergimplementations.
54248741257SjoergUsing badly-nested blocks is
54348741257Sjoerg.Em strongly discouraged ;
54448741257Sjoergfor example, the
54548741257Sjoerg.Fl T Ns Cm html
546c9bcef03Schristosfront-end to
54748741257Sjoerg.Xr mandoc 1
548c9bcef03Schristosis unable to render them in any meaningful way.
54948741257SjoergFurthermore, behaviour when encountering badly-nested blocks is not
55048741257Sjoergconsistent across troff implementations, especially when using multiple
55148741257Sjoerglevels of badly-nested blocks.
55248741257Sjoerg.Sh SEE ALSO
55348741257Sjoerg.Xr mandoc 1 ,
5549ff1f2acSchristos.Xr man.cgi 3 ,
555fec65c98Schristos.Xr mandoc_escape 3 ,
5569ff1f2acSchristos.Xr mandoc_headers 3 ,
557fec65c98Schristos.Xr mandoc_malloc 3 ,
5589ff1f2acSchristos.Xr mansearch 3 ,
559fec65c98Schristos.Xr mchars_alloc 3 ,
5609ff1f2acSchristos.Xr tbl 3 ,
56148741257Sjoerg.Xr eqn 7 ,
56248741257Sjoerg.Xr man 7 ,
563c5f73b34Sjoerg.Xr mandoc_char 7 ,
56448741257Sjoerg.Xr mdoc 7 ,
56548741257Sjoerg.Xr roff 7 ,
56648741257Sjoerg.Xr tbl 7
56748741257Sjoerg.Sh AUTHORS
5689ff1f2acSchristos.An -nosplit
56948741257SjoergThe
57048741257Sjoerg.Nm
57148741257Sjoerglibrary was written by
5729ff1f2acSchristos.An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
5739ff1f2acSchristosand is maintained by
5749ff1f2acSchristos.An Ingo Schwarze Aq Mt schwarze@openbsd.org .
575