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