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