[BACK]Return to mandoc.3 CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Annotation of mandoc/mandoc.3, Revision 1.37

1.37    ! schwarze    1: .\"    $Id: mandoc.3,v 1.36 2016/01/08 17:48:09 schwarze Exp $
1.1       kristaps    2: .\"
                      3: .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.36      schwarze    4: .\" Copyright (c) 2010-2016 Ingo Schwarze <schwarze@openbsd.org>
1.1       kristaps    5: .\"
                      6: .\" Permission to use, copy, modify, and distribute this software for any
                      7: .\" purpose with or without fee is hereby granted, provided that the above
                      8: .\" copyright notice and this permission notice appear in all copies.
                      9: .\"
                     10: .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11: .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12: .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13: .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14: .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15: .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16: .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17: .\"
1.35      schwarze   18: .Dd $Mdocdate: January 8 2016 $
1.1       kristaps   19: .Dt MANDOC 3
                     20: .Os
                     21: .Sh NAME
                     22: .Nm mandoc ,
1.37    ! schwarze   23: .Nm deroff ,
        !            24: .Nm mandocmsg ,
1.14      kristaps   25: .Nm man_mparse ,
1.37    ! schwarze   26: .Nm man_validate ,
        !            27: .Nm mdoc_validate ,
1.1       kristaps   28: .Nm mparse_alloc ,
                     29: .Nm mparse_free ,
1.14      kristaps   30: .Nm mparse_getkeep ,
                     31: .Nm mparse_keep ,
1.26      schwarze   32: .Nm mparse_open ,
1.1       kristaps   33: .Nm mparse_readfd ,
                     34: .Nm mparse_reset ,
1.2       kristaps   35: .Nm mparse_result ,
                     36: .Nm mparse_strerror ,
                     37: .Nm mparse_strlevel
1.1       kristaps   38: .Nd mandoc macro compiler library
                     39: .Sh SYNOPSIS
1.25      schwarze   40: .In sys/types.h
1.1       kristaps   41: .In mandoc.h
1.31      schwarze   42: .Pp
1.24      schwarze   43: .Fd "#define ASCII_NBRSP"
                     44: .Fd "#define ASCII_HYPH"
                     45: .Fd "#define ASCII_BREAK"
1.25      schwarze   46: .Ft struct mparse *
1.1       kristaps   47: .Fo mparse_alloc
1.25      schwarze   48: .Fa "int options"
1.1       kristaps   49: .Fa "enum mandoclevel wlevel"
1.23      schwarze   50: .Fa "mandocmsg mmsg"
                     51: .Fa "char *defos"
1.1       kristaps   52: .Fc
                     53: .Ft void
1.24      schwarze   54: .Fo (*mandocmsg)
                     55: .Fa "enum mandocerr errtype"
                     56: .Fa "enum mandoclevel level"
                     57: .Fa "const char *file"
                     58: .Fa "int line"
                     59: .Fa "int col"
                     60: .Fa "const char *msg"
                     61: .Fc
                     62: .Ft void
1.1       kristaps   63: .Fo mparse_free
                     64: .Fa "struct mparse *parse"
                     65: .Fc
1.23      schwarze   66: .Ft const char *
1.14      kristaps   67: .Fo mparse_getkeep
                     68: .Fa "const struct mparse *parse"
                     69: .Fc
                     70: .Ft void
                     71: .Fo mparse_keep
                     72: .Fa "struct mparse *parse"
                     73: .Fc
1.35      schwarze   74: .Ft int
1.26      schwarze   75: .Fo mparse_open
                     76: .Fa "struct mparse *parse"
                     77: .Fa "const char *fname"
                     78: .Fc
                     79: .Ft "enum mandoclevel"
1.1       kristaps   80: .Fo mparse_readfd
                     81: .Fa "struct mparse *parse"
                     82: .Fa "int fd"
                     83: .Fa "const char *fname"
                     84: .Fc
                     85: .Ft void
                     86: .Fo mparse_reset
                     87: .Fa "struct mparse *parse"
                     88: .Fc
                     89: .Ft void
                     90: .Fo mparse_result
                     91: .Fa "struct mparse *parse"
1.37    ! schwarze   92: .Fa "struct roff_man **man"
1.25      schwarze   93: .Fa "char **sodest"
1.2       kristaps   94: .Fc
                     95: .Ft "const char *"
                     96: .Fo mparse_strerror
                     97: .Fa "enum mandocerr"
                     98: .Fc
                     99: .Ft "const char *"
                    100: .Fo mparse_strlevel
                    101: .Fa "enum mandoclevel"
1.1       kristaps  102: .Fc
1.37    ! schwarze  103: .In roff.h
        !           104: .Ft void
        !           105: .Fo deroff
        !           106: .Fa "char **dest"
        !           107: .Fa "const struct roff_node *node"
        !           108: .Fc
1.25      schwarze  109: .In sys/types.h
1.24      schwarze  110: .In mandoc.h
                    111: .In mdoc.h
1.37    ! schwarze  112: .Vt extern const char * const * mdoc_argnames;
        !           113: .Vt extern const char * const * mdoc_macronames;
1.25      schwarze  114: .Ft void
1.37    ! schwarze  115: .Fo mdoc_validate
        !           116: .Fa "struct roff_man *mdoc"
1.24      schwarze  117: .Fc
1.25      schwarze  118: .In sys/types.h
1.24      schwarze  119: .In mandoc.h
                    120: .In man.h
1.37    ! schwarze  121: .Vt extern const char * const * man_macronames;
1.24      schwarze  122: .Ft "const struct mparse *"
                    123: .Fo man_mparse
1.37    ! schwarze  124: .Fa "const struct roff_man *man"
1.24      schwarze  125: .Fc
1.37    ! schwarze  126: .Ft void
        !           127: .Fo man_validate
        !           128: .Fa "struct roff_man *man"
1.24      schwarze  129: .Fc
1.1       kristaps  130: .Sh DESCRIPTION
                    131: The
                    132: .Nm mandoc
                    133: library parses a
                    134: .Ux
                    135: manual into an abstract syntax tree (AST).
                    136: .Ux
                    137: manuals are composed of
                    138: .Xr mdoc 7
                    139: or
                    140: .Xr man 7 ,
                    141: and may be mixed with
                    142: .Xr roff 7 ,
                    143: .Xr tbl 7 ,
                    144: and
                    145: .Xr eqn 7
                    146: invocations.
                    147: .Pp
                    148: The following describes a general parse sequence:
                    149: .Bl -enum
                    150: .It
                    151: initiate a parsing sequence with
1.27      schwarze  152: .Xr mchars_alloc 3
                    153: and
1.1       kristaps  154: .Fn mparse_alloc ;
                    155: .It
1.31      schwarze  156: open a file with
                    157: .Xr open 2
                    158: or
                    159: .Fn mparse_open ;
                    160: .It
                    161: parse it with
1.1       kristaps  162: .Fn mparse_readfd ;
                    163: .It
1.34      schwarze  164: close it with
                    165: .Xr close 2 ;
                    166: .It
1.31      schwarze  167: retrieve the syntax tree with
1.1       kristaps  168: .Fn mparse_result ;
                    169: .It
1.37    ! schwarze  170: depending on whether the
        !           171: .Fa macroset
        !           172: member of the returned
        !           173: .Vt struct roff_man
        !           174: is
        !           175: .Dv MACROSET_MDOC
        !           176: or
        !           177: .Dv MACROSET_MAN ,
        !           178: validate it with
        !           179: .Fn mdoc_validate
1.1       kristaps  180: or
1.37    ! schwarze  181: .Fn man_validate ,
        !           182: respectively;
        !           183: .It
        !           184: iterate over parse nodes with starting from the
        !           185: .Fa first
        !           186: member of the returned
        !           187: .Vt struct roff_man ;
1.1       kristaps  188: .It
                    189: free all allocated memory with
1.27      schwarze  190: .Fn mparse_free
                    191: and
                    192: .Xr mchars_free 3 ,
1.1       kristaps  193: or invoke
                    194: .Fn mparse_reset
1.37    ! schwarze  195: and go back to step 2 to parse new files.
1.3       kristaps  196: .El
                    197: .Sh REFERENCE
                    198: This section documents the functions, types, and variables available
                    199: via
1.25      schwarze  200: .In mandoc.h ,
                    201: with the exception of those documented in
                    202: .Xr mandoc_escape 3
                    203: and
                    204: .Xr mchars_alloc 3 .
1.3       kristaps  205: .Ss Types
                    206: .Bl -ohang
                    207: .It Vt "enum mandocerr"
1.31      schwarze  208: An error or warning message during parsing.
1.3       kristaps  209: .It Vt "enum mandoclevel"
1.11      kristaps  210: A classification of an
1.23      schwarze  211: .Vt "enum mandocerr"
1.11      kristaps  212: as regards system operation.
1.37    ! schwarze  213: See the DIAGNOSTICS section in
        !           214: .Xr mandoc 1
        !           215: regarding the meanings of the levels.
1.3       kristaps  216: .It Vt "struct mparse"
1.11      kristaps  217: An opaque pointer to a running parse sequence.
                    218: Created with
                    219: .Fn mparse_alloc
                    220: and freed with
                    221: .Fn mparse_free .
                    222: This may be used across parsed input if
                    223: .Fn mparse_reset
                    224: is called between parses.
1.3       kristaps  225: .It Vt "mandocmsg"
1.31      schwarze  226: A prototype for a function to handle error and warning
1.11      kristaps  227: messages emitted by the parser.
1.3       kristaps  228: .El
                    229: .Ss Functions
                    230: .Bl -ohang
1.37    ! schwarze  231: .It Fn deroff
1.25      schwarze  232: Obtain a text-only representation of a
1.37    ! schwarze  233: .Vt struct roff_node ,
1.25      schwarze  234: including text contained in its child nodes.
1.37    ! schwarze  235: To be used on children of the
        !           236: .Fa first
        !           237: member of
        !           238: .Vt struct roff_man .
1.25      schwarze  239: When it is no longer needed, the pointer returned from
1.37    ! schwarze  240: .Fn deroff
1.25      schwarze  241: can be passed to
                    242: .Xr free 3 .
1.14      kristaps  243: .It Fn man_mparse
                    244: Get the parser used for the current output.
1.18      schwarze  245: Declared in
                    246: .In man.h ,
                    247: implemented in
                    248: .Pa man.c .
1.37    ! schwarze  249: .It Fn man_validate
        !           250: Validate the
        !           251: .Dv MACROSET_MAN
        !           252: parse tree obtained with
1.4       kristaps  253: .Fn mparse_result .
1.18      schwarze  254: Declared in
                    255: .In man.h ,
                    256: implemented in
                    257: .Pa man.c .
1.37    ! schwarze  258: .It Fn mdoc_validate
        !           259: Validate the
        !           260: .Dv MACROSET_MDOC
        !           261: parse tree obtained with
1.4       kristaps  262: .Fn mparse_result .
1.18      schwarze  263: Declared in
                    264: .In mdoc.h ,
                    265: implemented in
                    266: .Pa mdoc.c .
1.3       kristaps  267: .It Fn mparse_alloc
1.4       kristaps  268: Allocate a parser.
1.23      schwarze  269: The arguments have the following effect:
                    270: .Bl -tag -offset 5n -width inttype
1.25      schwarze  271: .It Ar options
                    272: When the
1.23      schwarze  273: .Dv MPARSE_MDOC
                    274: or
1.25      schwarze  275: .Dv MPARSE_MAN
                    276: bit is set, only that parser is used.
                    277: Otherwise, the document type is automatically detected.
                    278: .Pp
                    279: When the
                    280: .Dv MPARSE_SO
                    281: bit is set,
                    282: .Xr roff 7
                    283: .Ic \&so
                    284: file inclusion requests are always honoured.
                    285: Otherwise, if the request is the only content in an input file,
                    286: only the file name is remembered, to be returned in the
                    287: .Fa sodest
                    288: argument of
                    289: .Fn mparse_result .
                    290: .Pp
                    291: When the
                    292: .Dv MPARSE_QUICK
                    293: bit is set, parsing is aborted after the NAME section.
                    294: This is for example useful in
                    295: .Xr makewhatis 8
                    296: .Fl Q
                    297: to quickly build minimal databases.
1.23      schwarze  298: .It Ar wlevel
                    299: Can be set to
1.31      schwarze  300: .Dv MANDOCLEVEL_BADARG ,
1.23      schwarze  301: .Dv MANDOCLEVEL_ERROR ,
                    302: or
                    303: .Dv MANDOCLEVEL_WARNING .
                    304: Messages below the selected level will be suppressed.
                    305: .It Ar mmsg
                    306: A callback function to handle errors and warnings.
                    307: See
                    308: .Pa main.c
                    309: for an example.
1.37    ! schwarze  310: If printing of error messages is not desired,
        !           311: .Dv NULL
        !           312: may be passed.
1.23      schwarze  313: .It Ar defos
                    314: A default string for the
                    315: .Xr mdoc 7
                    316: .Sq \&Os
                    317: macro, overriding the
                    318: .Dv OSNAME
                    319: preprocessor definition and the results of
                    320: .Xr uname 3 .
1.37    ! schwarze  321: Passing
        !           322: .Dv NULL
        !           323: sets no default.
1.23      schwarze  324: .El
                    325: .Pp
1.4       kristaps  326: The same parser may be used for multiple files so long as
                    327: .Fn mparse_reset
                    328: is called between parses.
                    329: .Fn mparse_free
                    330: must be called to free the memory allocated by this function.
1.18      schwarze  331: Declared in
                    332: .In mandoc.h ,
                    333: implemented in
                    334: .Pa read.c .
1.3       kristaps  335: .It Fn mparse_free
1.4       kristaps  336: Free all memory allocated by
                    337: .Fn mparse_alloc .
1.18      schwarze  338: Declared in
                    339: .In mandoc.h ,
                    340: implemented in
                    341: .Pa read.c .
1.14      kristaps  342: .It Fn mparse_getkeep
                    343: Acquire the keep buffer.
                    344: Must follow a call of
                    345: .Fn mparse_keep .
1.18      schwarze  346: Declared in
                    347: .In mandoc.h ,
                    348: implemented in
                    349: .Pa read.c .
1.14      kristaps  350: .It Fn mparse_keep
                    351: Instruct the parser to retain a copy of its parsed input.
                    352: This can be acquired with subsequent
                    353: .Fn mparse_getkeep
                    354: calls.
1.18      schwarze  355: Declared in
                    356: .In mandoc.h ,
                    357: implemented in
                    358: .Pa read.c .
1.26      schwarze  359: .It Fn mparse_open
1.32      schwarze  360: Open the file for reading.
                    361: If that fails and
1.26      schwarze  362: .Fa fname
1.32      schwarze  363: does not already end in
                    364: .Ql .gz ,
                    365: try again after appending
                    366: .Ql .gz .
                    367: Save the information whether the file is zipped or not.
1.35      schwarze  368: Return a file descriptor open for reading or -1 on failure.
1.26      schwarze  369: It can be passed to
                    370: .Fn mparse_readfd
                    371: or used directly.
                    372: Declared in
                    373: .In mandoc.h ,
                    374: implemented in
                    375: .Pa read.c .
1.3       kristaps  376: .It Fn mparse_readfd
1.30      schwarze  377: Parse a file descriptor opened with
                    378: .Xr open 2
                    379: or
1.29      schwarze  380: .Fn mparse_open .
1.30      schwarze  381: Pass the associated filename in
                    382: .Va fname .
1.29      schwarze  383: This function may be called multiple times with different parameters; however,
1.34      schwarze  384: .Xr close 2
                    385: and
1.4       kristaps  386: .Fn mparse_reset
                    387: should be invoked between parses.
1.18      schwarze  388: Declared in
                    389: .In mandoc.h ,
                    390: implemented in
                    391: .Pa read.c .
1.3       kristaps  392: .It Fn mparse_reset
1.4       kristaps  393: Reset a parser so that
                    394: .Fn mparse_readfd
                    395: may be used again.
1.18      schwarze  396: Declared in
                    397: .In mandoc.h ,
                    398: implemented in
                    399: .Pa read.c .
1.3       kristaps  400: .It Fn mparse_result
1.4       kristaps  401: Obtain the result of a parse.
1.37    ! schwarze  402: One of the two pointers will be filled in.
1.18      schwarze  403: Declared in
                    404: .In mandoc.h ,
                    405: implemented in
                    406: .Pa read.c .
1.3       kristaps  407: .It Fn mparse_strerror
1.4       kristaps  408: Return a statically-allocated string representation of an error code.
1.18      schwarze  409: Declared in
                    410: .In mandoc.h ,
                    411: implemented in
                    412: .Pa read.c .
1.3       kristaps  413: .It Fn mparse_strlevel
1.4       kristaps  414: Return a statically-allocated string representation of a level code.
1.18      schwarze  415: Declared in
                    416: .In mandoc.h ,
                    417: implemented in
                    418: .Pa read.c .
1.3       kristaps  419: .El
                    420: .Ss Variables
                    421: .Bl -ohang
                    422: .It Va man_macronames
1.37    ! schwarze  423: The string representation of a
        !           424: .Xr man 7
        !           425: macro as indexed by
1.4       kristaps  426: .Vt "enum mant" .
1.3       kristaps  427: .It Va mdoc_argnames
1.37    ! schwarze  428: The string representation of an
        !           429: .Xr mdoc 7
        !           430: macro argument as indexed by
1.4       kristaps  431: .Vt "enum mdocargt" .
1.3       kristaps  432: .It Va mdoc_macronames
1.37    ! schwarze  433: The string representation of an
        !           434: .Xr mdoc 7
        !           435: macro as indexed by
1.4       kristaps  436: .Vt "enum mdoct" .
1.1       kristaps  437: .El
                    438: .Sh IMPLEMENTATION NOTES
                    439: This section consists of structural documentation for
                    440: .Xr mdoc 7
                    441: and
                    442: .Xr man 7
1.11      kristaps  443: syntax trees and strings.
                    444: .Ss Man and Mdoc Strings
                    445: Strings may be extracted from mdoc and man meta-data, or from text
                    446: nodes (MDOC_TEXT and MAN_TEXT, respectively).
                    447: These strings have special non-printing formatting cues embedded in the
                    448: text itself, as well as
                    449: .Xr roff 7
                    450: escapes preserved from input.
                    451: Implementing systems will need to handle both situations to produce
                    452: human-readable text.
                    453: In general, strings may be assumed to consist of 7-bit ASCII characters.
                    454: .Pp
                    455: The following non-printing characters may be embedded in text strings:
                    456: .Bl -tag -width Ds
                    457: .It Dv ASCII_NBRSP
                    458: A non-breaking space character.
                    459: .It Dv ASCII_HYPH
                    460: A soft hyphen.
1.25      schwarze  461: .It Dv ASCII_BREAK
                    462: A breakable zero-width space.
1.11      kristaps  463: .El
                    464: .Pp
                    465: Escape characters are also passed verbatim into text strings.
                    466: An escape character is a sequence of characters beginning with the
                    467: backslash
                    468: .Pq Sq \e .
                    469: To construct human-readable text, these should be intercepted with
1.25      schwarze  470: .Xr mandoc_escape 3
                    471: and converted with one the functions described in
                    472: .Xr mchars_alloc 3 .
1.1       kristaps  473: .Ss Man Abstract Syntax Tree
                    474: This AST is governed by the ontological rules dictated in
                    475: .Xr man 7
                    476: and derives its terminology accordingly.
                    477: .Pp
                    478: The AST is composed of
1.37    ! schwarze  479: .Vt struct roff_node
1.1       kristaps  480: nodes with element, root and text types as declared by the
                    481: .Va type
                    482: field.
                    483: Each node also provides its parse point (the
                    484: .Va line ,
1.37    ! schwarze  485: .Va pos ,
1.1       kristaps  486: and
1.37    ! schwarze  487: .Va sec
1.1       kristaps  488: fields), its position in the tree (the
                    489: .Va parent ,
                    490: .Va child ,
                    491: .Va next
                    492: and
                    493: .Va prev
                    494: fields) and some type-specific data.
                    495: .Pp
                    496: The tree itself is arranged according to the following normal form,
                    497: where capitalised non-terminals represent nodes.
                    498: .Pp
                    499: .Bl -tag -width "ELEMENTXX" -compact
                    500: .It ROOT
                    501: \(<- mnode+
                    502: .It mnode
                    503: \(<- ELEMENT | TEXT | BLOCK
                    504: .It BLOCK
                    505: \(<- HEAD BODY
                    506: .It HEAD
                    507: \(<- mnode*
                    508: .It BODY
                    509: \(<- mnode*
                    510: .It ELEMENT
                    511: \(<- ELEMENT | TEXT*
                    512: .It TEXT
1.11      kristaps  513: \(<- [[:ascii:]]*
1.1       kristaps  514: .El
                    515: .Pp
                    516: The only elements capable of nesting other elements are those with
1.25      schwarze  517: next-line scope as documented in
1.1       kristaps  518: .Xr man 7 .
                    519: .Ss Mdoc Abstract Syntax Tree
                    520: This AST is governed by the ontological
                    521: rules dictated in
                    522: .Xr mdoc 7
                    523: and derives its terminology accordingly.
                    524: .Qq In-line
                    525: elements described in
                    526: .Xr mdoc 7
                    527: are described simply as
                    528: .Qq elements .
                    529: .Pp
                    530: The AST is composed of
1.37    ! schwarze  531: .Vt struct roff_node
1.1       kristaps  532: nodes with block, head, body, element, root and text types as declared
                    533: by the
                    534: .Va type
                    535: field.
                    536: Each node also provides its parse point (the
                    537: .Va line ,
1.37    ! schwarze  538: .Va pos ,
1.1       kristaps  539: and
1.37    ! schwarze  540: .Va sec
1.1       kristaps  541: fields), its position in the tree (the
                    542: .Va parent ,
                    543: .Va child ,
1.36      schwarze  544: .Va last ,
1.1       kristaps  545: .Va next
                    546: and
                    547: .Va prev
                    548: fields) and some type-specific data, in particular, for nodes generated
                    549: from macros, the generating macro in the
                    550: .Va tok
                    551: field.
                    552: .Pp
                    553: The tree itself is arranged according to the following normal form,
                    554: where capitalised non-terminals represent nodes.
                    555: .Pp
                    556: .Bl -tag -width "ELEMENTXX" -compact
                    557: .It ROOT
                    558: \(<- mnode+
                    559: .It mnode
                    560: \(<- BLOCK | ELEMENT | TEXT
                    561: .It BLOCK
                    562: \(<- HEAD [TEXT] (BODY [TEXT])+ [TAIL [TEXT]]
                    563: .It ELEMENT
                    564: \(<- TEXT*
                    565: .It HEAD
                    566: \(<- mnode*
                    567: .It BODY
                    568: \(<- mnode* [ENDBODY mnode*]
                    569: .It TAIL
                    570: \(<- mnode*
                    571: .It TEXT
1.11      kristaps  572: \(<- [[:ascii:]]*
1.1       kristaps  573: .El
                    574: .Pp
                    575: Of note are the TEXT nodes following the HEAD, BODY and TAIL nodes of
                    576: the BLOCK production: these refer to punctuation marks.
                    577: Furthermore, although a TEXT node will generally have a non-zero-length
                    578: string, in the specific case of
                    579: .Sq \&.Bd \-literal ,
                    580: an empty line will produce a zero-length string.
                    581: Multiple body parts are only found in invocations of
                    582: .Sq \&Bl \-column ,
                    583: where a new body introduces a new phrase.
                    584: .Pp
                    585: The
                    586: .Xr mdoc 7
1.5       kristaps  587: syntax tree accommodates for broken block structures as well.
1.1       kristaps  588: The ENDBODY node is available to end the formatting associated
                    589: with a given block before the physical end of that block.
                    590: It has a non-null
                    591: .Va end
                    592: field, is of the BODY
                    593: .Va type ,
                    594: has the same
                    595: .Va tok
                    596: as the BLOCK it is ending, and has a
                    597: .Va pending
                    598: field pointing to that BLOCK's BODY node.
                    599: It is an indirect child of that BODY node
                    600: and has no children of its own.
                    601: .Pp
                    602: An ENDBODY node is generated when a block ends while one of its child
                    603: blocks is still open, like in the following example:
                    604: .Bd -literal -offset indent
                    605: \&.Ao ao
                    606: \&.Bo bo ac
                    607: \&.Ac bc
                    608: \&.Bc end
                    609: .Ed
                    610: .Pp
                    611: This example results in the following block structure:
                    612: .Bd -literal -offset indent
                    613: BLOCK Ao
                    614:     HEAD Ao
                    615:     BODY Ao
                    616:         TEXT ao
                    617:         BLOCK Bo, pending -> Ao
                    618:             HEAD Bo
                    619:             BODY Bo
                    620:                 TEXT bo
                    621:                 TEXT ac
                    622:                 ENDBODY Ao, pending -> Ao
                    623:                 TEXT bc
                    624: TEXT end
                    625: .Ed
                    626: .Pp
                    627: Here, the formatting of the
                    628: .Sq \&Ao
                    629: block extends from TEXT ao to TEXT ac,
                    630: while the formatting of the
                    631: .Sq \&Bo
                    632: block extends from TEXT bo to TEXT bc.
                    633: It renders as follows in
                    634: .Fl T Ns Cm ascii
                    635: mode:
                    636: .Pp
                    637: .Dl <ao [bo ac> bc] end
                    638: .Pp
                    639: Support for badly-nested blocks is only provided for backward
                    640: compatibility with some older
                    641: .Xr mdoc 7
                    642: implementations.
                    643: Using badly-nested blocks is
                    644: .Em strongly discouraged ;
                    645: for example, the
                    646: .Fl T Ns Cm html
                    647: and
                    648: .Fl T Ns Cm xhtml
                    649: front-ends to
                    650: .Xr mandoc 1
                    651: are unable to render them in any meaningful way.
                    652: Furthermore, behaviour when encountering badly-nested blocks is not
1.25      schwarze  653: consistent across troff implementations, especially when using multiple
1.1       kristaps  654: levels of badly-nested blocks.
                    655: .Sh SEE ALSO
                    656: .Xr mandoc 1 ,
1.37    ! schwarze  657: .Xr man.cgi 3 ,
1.25      schwarze  658: .Xr mandoc_escape 3 ,
1.37    ! schwarze  659: .Xr mandoc_headers 3 ,
1.25      schwarze  660: .Xr mandoc_malloc 3 ,
1.37    ! schwarze  661: .Xr mansearch 3 ,
1.25      schwarze  662: .Xr mchars_alloc 3 ,
1.37    ! schwarze  663: .Xr tbl 3 ,
1.1       kristaps  664: .Xr eqn 7 ,
                    665: .Xr man 7 ,
1.6       kristaps  666: .Xr mandoc_char 7 ,
1.1       kristaps  667: .Xr mdoc 7 ,
                    668: .Xr roff 7 ,
                    669: .Xr tbl 7
                    670: .Sh AUTHORS
1.37    ! schwarze  671: .An -nosplit
1.1       kristaps  672: The
                    673: .Nm
                    674: library was written by
1.37    ! schwarze  675: .An Kristaps Dzonsons Aq Mt kristaps@bsd.lv
        !           676: and is maintained by
        !           677: .An Ingo Schwarze Aq Mt schwarze@openbsd.org .

CVSweb