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