version 1.11, 2009/02/25 17:02:47 |
version 1.41, 2010/05/30 22:56:02 |
|
|
.\" $Id$ |
.\" $Id$ |
.\" |
.\" |
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se> |
.\" Copyright (c) 2009-2010 Kristaps Dzonsons <kristaps@bsd.lv> |
.\" |
.\" |
.\" Permission to use, copy, modify, and distribute this software for any |
.\" Permission to use, copy, modify, and distribute this software for any |
.\" purpose with or without fee is hereby granted, provided that the |
.\" purpose with or without fee is hereby granted, provided that the above |
.\" above copyright notice and this permission notice appear in all |
.\" copyright notice and this permission notice appear in all copies. |
.\" copies. |
|
.\" |
.\" |
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
.\" WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
.\" AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
.\" TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
.\" PERFORMANCE OF THIS SOFTWARE. |
.\" |
.\" |
|
.Dd $Mdocdate$ |
.Dd $Mdocdate$ |
.Dt mdoc 3 |
.Dt MDOC 3 |
.Os |
.Os |
.\" SECTION |
|
.Sh NAME |
.Sh NAME |
|
.Nm mdoc , |
.Nm mdoc_alloc , |
.Nm mdoc_alloc , |
.Nm mdoc_parseln , |
|
.Nm mdoc_endparse , |
.Nm mdoc_endparse , |
.Nm mdoc_node , |
.Nm mdoc_free , |
.Nm mdoc_meta , |
.Nm mdoc_meta , |
.Nm mdoc_free |
.Nm mdoc_node , |
|
.Nm mdoc_parseln , |
|
.Nm mdoc_reset |
.Nd mdoc macro compiler library |
.Nd mdoc macro compiler library |
.\" SECTION |
|
.Sh SYNOPSIS |
.Sh SYNOPSIS |
.Fd #include <mdoc.h> |
.In mandoc.h |
|
.In mdoc.h |
.Vt extern const char * const * mdoc_macronames; |
.Vt extern const char * const * mdoc_macronames; |
.Vt extern const char * const * mdoc_argnames; |
.Vt extern const char * const * mdoc_argnames; |
.Ft "struct mdoc *" |
.Ft "struct mdoc *" |
.Fn mdoc_alloc "void *data" "const struct mdoc_cb *cb" |
.Fn mdoc_alloc "void *data" "int pflags" "mandocmsg msgs" |
|
.Ft int |
|
.Fn mdoc_endparse "struct mdoc *mdoc" |
.Ft void |
.Ft void |
.Fn mdoc_free "struct mdoc *mdoc" |
.Fn mdoc_free "struct mdoc *mdoc" |
|
.Ft "const struct mdoc_meta *" |
|
.Fn mdoc_meta "const struct mdoc *mdoc" |
|
.Ft "const struct mdoc_node *" |
|
.Fn mdoc_node "const struct mdoc *mdoc" |
.Ft int |
.Ft int |
.Fn mdoc_parseln "struct mdoc *mdoc" "int line" "char *buf" |
.Fn mdoc_parseln "struct mdoc *mdoc" "int line" "char *buf" |
.Ft "const struct mdoc_node *" |
|
.Fn mdoc_node "struct mdoc *mdoc" |
|
.Ft "const struct mdoc_meta *" |
|
.Fn mdoc_meta "struct mdoc *mdoc" |
|
.Ft int |
.Ft int |
.Fn mdoc_endparse "struct mdoc *mdoc" |
.Fn mdoc_reset "struct mdoc *mdoc" |
.\" SECTION |
|
.Sh DESCRIPTION |
.Sh DESCRIPTION |
The |
The |
.Nm mdoc |
.Nm mdoc |
library parses lines of mdoc input into an abstract syntax tree. |
library parses lines of |
.Dq mdoc , |
|
which is used to format BSD manual pages, is a macro package of the |
|
.Dq roff |
|
language. The |
|
.Nm |
|
library implements only those macros documented in the |
|
.Xr mdoc 7 |
.Xr mdoc 7 |
and |
input |
.Xr mdoc.samples 7 |
into an abstract syntax tree (AST). |
manuals. Documents with |
|
.Xr refer 1 , |
|
.Xr eqn 1 |
|
and other pre-processor sections aren't accomodated. |
|
.\" PARAGRAPH |
|
.Pp |
.Pp |
.Nm |
|
is |
|
.Ud |
|
.\" PARAGRAPH |
|
.Pp |
|
In general, applications initiate a parsing sequence with |
In general, applications initiate a parsing sequence with |
.Fn mdoc_alloc , |
.Fn mdoc_alloc , |
parse each line in a document with |
parse each line in a document with |
.Fn mdoc_parseln , |
.Fn mdoc_parseln , |
close the parsing session with |
close the parsing session with |
.Fn mdoc_endparse , |
.Fn mdoc_endparse , |
operate over the syntax tree returned by |
operate over the syntax tree returned by |
.Fn mdoc_node |
.Fn mdoc_node |
and |
and |
.Fn mdoc_meta , |
.Fn mdoc_meta , |
then free all allocated memory with |
then free all allocated memory with |
.Fn mdoc_free . |
.Fn mdoc_free . |
|
The |
|
.Fn mdoc_reset |
|
function may be used in order to reset the parser for another input |
|
sequence. |
See the |
See the |
.Sx EXAMPLES |
.Sx EXAMPLES |
section for a full example. |
section for a simple example. |
.\" PARAGRAPH |
|
.Pp |
.Pp |
This section further defines the |
This section further defines the |
.Sx Types , |
.Sx Types , |
.Sx Functions |
.Sx Functions |
and |
and |
.Sx Variables |
.Sx Variables |
available to programmers. Following that, |
available to programmers. |
.Sx Character Encoding |
Following that, the |
describes input format. Lastly, |
.Sx Abstract Syntax Tree |
.Sx Abstract Syntax Tree , |
section documents the output tree. |
documents the output tree. |
|
.\" SUBSECTION |
|
.Ss Types |
.Ss Types |
Both functions (see |
Both functions (see |
.Sx Functions ) |
.Sx Functions ) |
and variables (see |
and variables (see |
.Sx Variables ) |
.Sx Variables ) |
may use the following types: |
may use the following types: |
.Bl -ohang -offset "XXXX" |
.Bl -ohang |
.\" LIST-ITEM |
|
.It Vt struct mdoc |
.It Vt struct mdoc |
An opaque type defined in |
An opaque type defined in |
.Pa mdoc.c . |
.Pa mdoc.c . |
Its values are only used privately within the library. |
Its values are only used privately within the library. |
.\" LIST-ITEM |
|
.It Vt struct mdoc_cb |
|
A set of message callbacks defined in |
|
.Pa mdoc.h . |
|
.\" LIST-ITEM |
|
.It Vt struct mdoc_node |
.It Vt struct mdoc_node |
A parsed node. Defined in |
A parsed node. |
|
Defined in |
.Pa mdoc.h . |
.Pa mdoc.h . |
See |
See |
.Sx Abstract Syntax Tree |
.Sx Abstract Syntax Tree |
for details. |
for details. |
|
.It Vt mandocmsg |
|
A function callback type defined in |
|
.Pa mandoc.h . |
.El |
.El |
.\" SUBSECTION |
|
.Ss Functions |
.Ss Functions |
Function descriptions follow: |
Function descriptions follow: |
.Bl -ohang -offset "XXXX" |
.Bl -ohang |
.\" LIST-ITEM |
|
.It Fn mdoc_alloc |
.It Fn mdoc_alloc |
Allocates a parsing structure. The |
Allocates a parsing structure. |
|
The |
.Fa data |
.Fa data |
pointer is passed to callbacks in |
pointer is passed to |
.Fa cb , |
.Fa msgs . |
which are documented further in the header file. Returns NULL on |
The |
failure. If non-NULL, the pointer must be freed with |
.Fa pflags |
|
arguments are defined in |
|
.Pa mdoc.h . |
|
Returns NULL on failure. |
|
If non-NULL, the pointer must be freed with |
.Fn mdoc_free . |
.Fn mdoc_free . |
.\" LIST-ITEM |
.It Fn mdoc_reset |
|
Reset the parser for another parse routine. |
|
After its use, |
|
.Fn mdoc_parseln |
|
behaves as if invoked for the first time. |
|
If it returns 0, memory could not be allocated. |
.It Fn mdoc_free |
.It Fn mdoc_free |
Free all resources of a parser. The pointer is no longer valid after |
Free all resources of a parser. |
invocation. |
The pointer is no longer valid after invocation. |
.\" LIST-ITEM |
|
.It Fn mdoc_parseln |
.It Fn mdoc_parseln |
Parse a nil-terminated line of input. This line should not contain the |
Parse a nil-terminated line of input. |
trailing newline. Returns 0 on failure, 1 on success. The input buffer |
This line should not contain the trailing newline. |
|
Returns 0 on failure, 1 on success. |
|
The input buffer |
.Fa buf |
.Fa buf |
is modified by this function. |
is modified by this function. |
.\" LIST-ITEM |
|
.It Fn mdoc_endparse |
.It Fn mdoc_endparse |
Signals that the parse is complete. Note that if |
Signals that the parse is complete. |
|
Note that if |
.Fn mdoc_endparse |
.Fn mdoc_endparse |
is called subsequent to |
is called subsequent to |
.Fn mdoc_node , |
.Fn mdoc_node , |
the resulting tree is incomplete. Returns 0 on failure, 1 on success. |
the resulting tree is incomplete. |
.\" LIST-ITEM |
Returns 0 on failure, 1 on success. |
.It Fn mdoc_node |
.It Fn mdoc_node |
Returns the first node of the parse. Note that if |
Returns the first node of the parse. |
|
Note that if |
.Fn mdoc_parseln |
.Fn mdoc_parseln |
or |
or |
.Fn mdoc_endparse |
.Fn mdoc_endparse |
return 0, the tree will be incomplete. |
return 0, the tree will be incomplete. |
.It Fn mdoc_meta |
.It Fn mdoc_meta |
Returns the document's parsed meta-data. If this information has not |
Returns the document's parsed meta-data. |
yet been supplied or |
If this information has not yet been supplied or |
.Fn mdoc_parseln |
.Fn mdoc_parseln |
or |
or |
.Fn mdoc_endparse |
.Fn mdoc_endparse |
return 0, the data will be incomplete. |
return 0, the data will be incomplete. |
.El |
.El |
.\" SUBSECTION |
|
.Ss Variables |
.Ss Variables |
The following variables are also defined: |
The following variables are also defined: |
.Bl -ohang -offset "XXXX" |
.Bl -ohang |
.\" LIST-ITEM |
|
.It Va mdoc_macronames |
.It Va mdoc_macronames |
An array of string-ified token names. |
An array of string-ified token names. |
.\" LIST-ITEM |
|
.It Va mdoc_argnames |
.It Va mdoc_argnames |
An array of string-ified token argument names. |
An array of string-ified token argument names. |
.El |
.El |
.\" SUBSECTION |
|
.Ss Character Encoding |
|
The |
|
.Xr mdoc 3 |
|
library accepts only printable ASCII characters as defined by |
|
.Xr isprint 3 . |
|
Non-ASCII character sequences are escaped with an escape character |
|
.Sq \\ |
|
and followed by either an open-parenthesis |
|
.Sq \&( |
|
for two-character sequences; an open-bracket |
|
.Sq \&[ |
|
for n-character sequences (terminated at a close-bracket |
|
.Sq \&] ) ; |
|
or one of a small set of single characters for other escapes. |
|
.\" SUBSECTION |
|
.Ss Abstract Syntax Tree |
.Ss Abstract Syntax Tree |
The |
The |
.Nm |
.Nm |
functions produce an abstract syntax tree (AST) describing the input |
functions produce an abstract syntax tree (AST) describing input in a |
lines in a regular form. It may be reviewed at any time with |
regular form. |
|
It may be reviewed at any time with |
.Fn mdoc_nodes ; |
.Fn mdoc_nodes ; |
however, if called before |
however, if called before |
.Fn mdoc_endparse , |
.Fn mdoc_endparse , |
or after |
or after |
.Fn mdoc_endparse |
.Fn mdoc_endparse |
or |
or |
.Fn mdoc_parseln |
.Fn mdoc_parseln |
fail, it may be incomplete. |
fail, it may be incomplete. |
.\" PARAGRAPH |
|
.Pp |
.Pp |
The AST is composed of |
This AST is governed by the ontological |
|
rules dictated in |
|
.Xr mdoc 7 |
|
and derives its terminology accordingly. |
|
.Qq In-line |
|
elements described in |
|
.Xr mdoc 7 |
|
are described simply as |
|
.Qq elements . |
|
.Pp |
|
The AST is composed of |
.Vt struct mdoc_node |
.Vt struct mdoc_node |
nodes with block, head, body, element, root and text types as declared |
nodes with block, head, body, element, root and text types as declared |
by the |
by the |
.Va type |
.Va type |
field. Each node also provides its parse point (the |
field. |
|
Each node also provides its parse point (the |
.Va line , |
.Va line , |
.Va sec , |
.Va sec , |
and |
and |
|
|
fields), its position in the tree (the |
fields), its position in the tree (the |
.Va parent , |
.Va parent , |
.Va child , |
.Va child , |
.Va next |
.Va next |
and |
and |
.Va prev |
.Va prev |
fields) and type-specific data (the |
fields) and some type-specific data. |
.Va data |
|
field). |
|
.\" PARAGRAPH |
|
.Pp |
.Pp |
The tree itself is arranged according to the following normal form, |
The tree itself is arranged according to the following normal form, |
where capitalised non-terminals represent nodes. |
where capitalised non-terminals represent nodes. |
.Pp |
.Pp |
.Bl -tag -width "ELEMENTXX" -compact -offset "XXXX" |
.Bl -tag -width "ELEMENTXX" -compact |
.\" LIST-ITEM |
|
.It ROOT |
.It ROOT |
\(<- mnode+ |
\(<- mnode+ |
.It mnode |
.It mnode |
\(<- BLOCK | ELEMENT | TEXT |
\(<- BLOCK | ELEMENT | TEXT |
.It BLOCK |
.It BLOCK |
\(<- (HEAD [TEXT])+ [BODY [TEXT]] [TAIL [TEXT]] |
\(<- HEAD [TEXT] (BODY [TEXT])+ [TAIL [TEXT]] |
.It BLOCK |
|
\(<- BODY [TEXT] [TAIL [TEXT]] |
|
.It ELEMENT |
.It ELEMENT |
\(<- TEXT* |
\(<- TEXT* |
.It HEAD |
.It HEAD |
Line 252 where capitalised non-terminals represent nodes. |
|
Line 231 where capitalised non-terminals represent nodes. |
|
.It TAIL |
.It TAIL |
\(<- mnode+ |
\(<- mnode+ |
.It TEXT |
.It TEXT |
\(<- [[:alpha:]]* |
\(<- [[:printable:],0x1e]* |
.El |
.El |
.\" PARAGRAPH |
|
.Pp |
.Pp |
Of note are the TEXT nodes following the HEAD, BODY and TAIL nodes of |
Of note are the TEXT nodes following the HEAD, BODY and TAIL nodes of |
the BLOCK production. These refer to punctuation marks. Furthermore, |
the BLOCK production: these refer to punctuation marks. |
although a TEXT node will generally have a non-zero-length string, in |
Furthermore, although a TEXT node will generally have a non-zero-length |
the specific case of |
string, in the specific case of |
.Sq \&.Bd \-literal , |
.Sq \&.Bd \-literal , |
an empty line will produce a zero-length string. |
an empty line will produce a zero-length string. |
.\" PARAGRAPH |
Multiple body parts are only found in invocations of |
.Pp |
.Sq \&Bl \-column , |
The rule-of-thumb for mapping node types to macros follows. In-line |
where a new body introduces a new phrase. |
elements, such as |
|
.Sq \&.Em foo , |
|
are classified as ELEMENT nodes, which can only contain text. |
|
Multi-line elements, such as |
|
.Sq \&.Sh , |
|
are BLOCK elements, where the HEAD constitutes line contents and the |
|
BODY constitutes subsequent lines. In-line elements with matching |
|
pairs, such as |
|
.Sq \&.So |
|
and |
|
.Sq \&.Sc , |
|
are BLOCK elements with no HEAD tag. The only exception to this is |
|
.Sq \&.Eo |
|
and |
|
.Sq \&.Ec , |
|
which has a HEAD and TAIL node corresponding to the enclosure string. |
|
TEXT nodes, obviously, constitute text, and the ROOT node is the |
|
document's root. |
|
.\" SECTION |
|
.Sh EXAMPLES |
.Sh EXAMPLES |
The following example reads lines from stdin and parses them, operating |
The following example reads lines from stdin and parses them, operating |
on the finished parse tree with |
on the finished parse tree with |
.Fn parsed . |
.Fn parsed . |
Note that, if the last line of the file isn't newline-terminated, this |
This example does not error-check nor free memory upon failure. |
will truncate the file's last character (see |
.Bd -literal -offset indent |
.Xr fgetln 3 ) . |
|
Further, this example does not error-check nor free memory upon failure. |
|
.Bd -literal -offset "XXXX" |
|
struct mdoc *mdoc; |
struct mdoc *mdoc; |
struct mdoc_node *node; |
const struct mdoc_node *node; |
char *buf; |
char *buf; |
size_t len; |
size_t len; |
int line; |
int line; |
|
|
line = 1; |
line = 1; |
mdoc = mdoc_alloc(NULL, NULL); |
mdoc = mdoc_alloc(NULL, 0, NULL); |
|
buf = NULL; |
|
alloc_len = 0; |
|
|
while ((buf = fgetln(fp, &len))) { |
while ((len = getline(&buf, &alloc_len, stdin)) >= 0) { |
buf[len - 1] = '\\0'; |
if (len && buflen[len - 1] = '\en') |
if ( ! mdoc_parseln(mdoc, line, buf)) |
buf[len - 1] = '\e0'; |
errx(1, "mdoc_parseln"); |
if ( ! mdoc_parseln(mdoc, line, buf)) |
line++; |
errx(1, "mdoc_parseln"); |
|
line++; |
} |
} |
|
|
if ( ! mdoc_endparse(mdoc)) |
if ( ! mdoc_endparse(mdoc)) |
errx(1, "mdoc_endparse"); |
errx(1, "mdoc_endparse"); |
if (NULL == (node = mdoc_node(mdoc))) |
if (NULL == (node = mdoc_node(mdoc))) |
errx(1, "mdoc_node"); |
errx(1, "mdoc_node"); |
|
|
parsed(mdoc, node); |
parsed(mdoc, node); |
mdoc_free(mdoc); |
mdoc_free(mdoc); |
.Ed |
.Ed |
.\" SECTION |
.Pp |
|
Please see |
|
.Pa main.c |
|
in the source archive for a rigorous reference. |
.Sh SEE ALSO |
.Sh SEE ALSO |
.Xr mdoc 7 , |
.Xr mandoc 1 , |
.Xr mdoc.samples 7 , |
.Xr mdoc 7 |
.Xr groff 1 , |
|
.Xr mdocml 1 |
|
.\" SECTION |
|
.Sh AUTHORS |
.Sh AUTHORS |
The |
The |
.Nm |
.Nm |
utility was written by |
library was written by |
.An Kristaps Dzonsons Aq kristaps@kth.se . |
.An Kristaps Dzonsons Aq kristaps@bsd.lv . |
.\" SECTION |
|
.Sh BUGS |
|
Bugs, un-implemented macros and incompabilities are documented in this |
|
section. The baseline for determining whether macro parsing is |
|
.Qq incompatible |
|
is the default |
|
.Xr groff 1 |
|
system bundled with |
|
.Ox . |
|
.\" PARAGRAPH |
|
.Pp |
|
Un-implemented: the |
|
.Sq \&Xc |
|
and |
|
.Sq \&Xo |
|
macros aren't handled when used to span lines for the |
|
.Sq \&It |
|
macro. Such usage is specifically discouraged in |
|
.Xr mdoc.samples 7 . |
|
.\" PARAGRAPH |
|
.Pp |
|
Bugs: when |
|
.Sq \&It \-column |
|
is invoked, whitespace is not stripped around |
|
.Sq \&Ta |
|
or tab-character separators. |
|
.\" PARAGRAPH |
|
.Pp |
|
Bugs: elements within columns for |
|
.Sq \&It \-column |
|
are not yet supported. |
|
.\" PARAGRAPH |
|
.Pp |
|
Incompatible: the |
|
.Sq \&At |
|
macro only accepts a single parameter. Furthermore, several macros |
|
.Pf ( Sq \&Pp , |
|
.Sq \&It , |
|
and possibly others) accept multiple arguments with a warning. |
|
.\" PARAGRAPH |
|
.Pp |
|
Incompatible: only those macros specified by |
|
.Xr mdoc.samples 7 |
|
and |
|
.Xr mdoc 7 |
|
for |
|
.Ox |
|
are supported; support for |
|
.Nx |
|
and other |
|
.Bx |
|
systems is in progress. |
|