diff options
-rw-r--r-- | Makefile | 19 | ||||
-rw-r--r-- | argv.c | 40 | ||||
-rw-r--r-- | external.png | bin | 0 -> 165 bytes | |||
-rw-r--r-- | index.sgml | 148 | ||||
-rw-r--r-- | mdoc.3 | 19 | ||||
-rw-r--r-- | mdocterm.c | 3 | ||||
-rw-r--r-- | style.css | 52 | ||||
-rw-r--r-- | term.c | 112 |
8 files changed, 310 insertions, 83 deletions
@@ -1,3 +1,5 @@ +.SUFFIXES: .html .sgml + VERSION = 1.3.0 CFLAGS += -W -Wall -Wstrict-prototypes -Wno-unused-parameter -g @@ -33,13 +35,20 @@ SRCS = macro.c mdoc.c hash.c strings.c xstd.c argv.c validate.c \ HEADS = mdoc.h private.h term.h mmain.h +SGMLS = index.sgml + +HTMLS = index.html + +STATICS = style.css external.png + MANS = mdoctree.1 mdocterm.1 mdoc.3 BINS = mdocterm mdoctree mdoclint -CLEAN = $(BINS) $(LNS) $(LLNS) $(LIBS) $(OBJS) +CLEAN = $(BINS) $(LNS) $(LLNS) $(LIBS) $(OBJS) $(HTMLS) -INSTALL = $(SRCS) $(HEADS) Makefile Makefile.port DESCR $(MANS) +INSTALL = $(SRCS) $(HEADS) Makefile Makefile.port DESCR $(MANS) \ + $(SGMLS) $(STATICS) FAIL = regress/test.empty \ regress/test.prologue.00 \ @@ -104,6 +113,8 @@ dist: mdocml-$(VERSION).tar.gz port: mdocml-oport-$(VERSION).tar.gz +www: $(HTMLS) + regress:: mdoclint @for f in $(FAIL); do \ echo "./mdoclint $$f" ; \ @@ -231,3 +242,7 @@ mdoctree: $(TREEOBJS) libmdoc.a mdoclint: $(LINTOBJS) libmdoc.a $(CC) $(CFLAGS) -o $@ $(LINTOBJS) libmdoc.a + +.sgml.html: + validate $< + cp -f $< $@ @@ -44,8 +44,6 @@ static int argv_single(struct mdoc *, int, struct mdoc_arg *, int *, char *); static int argv_multi(struct mdoc *, int, struct mdoc_arg *, int *, char *); -static int postargv(struct mdoc *, int, - const struct mdoc_arg *, int); static int pwarn(struct mdoc *, int, int, int); static int perr(struct mdoc *, int, int, int); @@ -59,9 +57,8 @@ static int perr(struct mdoc *, int, int, int); /* Error messages. */ #define EQUOTTERM (0) -#define EOFFSET (1) -#define EARGVAL (2) -#define EARGMANY (3) +#define EARGVAL (1) +#define EARGMANY (2) static int mdoc_argflags[MDOC_MAX] = { 0, /* \" */ @@ -183,10 +180,6 @@ perr(struct mdoc *mdoc, int line, int pos, int code) c = mdoc_perr(mdoc, line, pos, "unterminated quoted parameter"); break; - case (EOFFSET): - c = mdoc_perr(mdoc, line, pos, - "invalid value for offset argument"); - break; case (EARGVAL): c = mdoc_perr(mdoc, line, pos, "argument requires a value"); @@ -637,33 +630,6 @@ lookup(int tok, const char *argv) static int -postargv(struct mdoc *mdoc, int line, const struct mdoc_arg *v, int pos) -{ - - switch (v->arg) { - case (MDOC_Offset): - assert(v->value); - assert(v->value[0]); - if (xstrcmp(v->value[0], "left")) - break; - if (xstrcmp(v->value[0], "right")) - break; - if (xstrcmp(v->value[0], "center")) - break; - if (xstrcmp(v->value[0], "indent")) - break; - if (xstrcmp(v->value[0], "indent-two")) - break; - return(perr(mdoc, line, pos, EOFFSET)); - default: - break; - } - - return(1); -} - - -static int argv_multi(struct mdoc *mdoc, int line, struct mdoc_arg *v, int *pos, char *buf) { @@ -795,8 +761,6 @@ mdoc_argv(struct mdoc *mdoc, int line, int tok, ppos = *pos; if ( ! argv(mdoc, line, v, pos, buf)) return(ARGV_ERROR); - if ( ! postargv(mdoc, line, v, ppos)) - return(ARGV_ERROR); return(ARGV_ARG); } diff --git a/external.png b/external.png Binary files differnew file mode 100644 index 00000000..419c06fb --- /dev/null +++ b/external.png diff --git a/index.sgml b/index.sgml new file mode 100644 index 00000000..3e916032 --- /dev/null +++ b/index.sgml @@ -0,0 +1,148 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <meta name="resource-type" content="document"> + <link rel="stylesheet" href="style.css" type="text/css" media="all"> + <title>mdocml.bsd.lv</title> + </head> + <body> + <table width="600"> + <col width="100%"> + <tbody> + <tr> + <td> + <div class="head"> + <b>mdocml</b> – mdoc macro compiler + </div> + </td> + </tr> + <tr> + <td valign="top"> + <h1> + DESCRIPTION + </h1> + + <p> + <span class="nm">mdocml</span> is a suite of tools that compile “mdoc”, the roff macro + package of the BSD manual pages. The mission of <span class="nm">mdocml</span> is to deprecate <a + href="http://www.gnu.org/software/groff/" class="external">groff</a>, the GNU roff implementation, for + displaying BSD mdoc pages. groff amounts to over 60 000 lines of GPL C++ source, which is a + considerable encumbrance to BSD operating system. + </p> + + <p> + The core of <span class="nm">mdocml</span> is the libmdoc library, a validating scanner-parser producing + intermediate-form output from mdoc input. libmdoc is a simple, fast library operating on memory buffers + of mdoc input. Its intermediate output, an abstract syntax tree, is fully documented in the <span + class="man">mdoc(3)</span> reference manual. + </p> + + <p> + There are three utilities implementing <span class="man">mdoc(3)</span>: + </p> + + <ul> + <li><span class="man">mdocterm(1)</span> – formats mdoc input for display on the terminal + <li><span class="man">mdochtml(1)</span> – formats mdoc input as strict HTML (nascent) + <li><span class="man">mdoclint(1)</span> – validates mdoc input + <li><span class="man">mdoctree(1)</span> – prints input abstract syntax tree + </ul> + + <p> + The <span class="man">mdocterm(1)</span> utility is intended to deprecate usage of <a + href="http://www.gnu.org/software/groff/" class="external">groff</a> for displaying BSD manuals to the + terminal, either directly or cached as a “catman” page. + </p> + + <p> + <span class="attn">Please submit patches!</span> Although a significant implementation exists, work + remains for the backend library and especially the front-end utilities. See the <a + href="#contact">contact</a> information below to submit patches and bug reports. + </p> + </td> + </tr> + <tr> + <td> + <h1> + INSTALLING SOURCES + </h1> + + <h2> + nightly source + </h2> + + <p> + CVS sources are checkedout and snapshotted nightly. These may be found in the <a + href="/snapshots/">/snapshots/</a> directory. + </p> + + <p class="boxed"> + % cd /tmp<br> + % ftp -V -o- http://mdocml.bsd.lv/snapshots/mdocml.tgz | tar -zxf -<br> + % cd mdocml<br> + % make<br> + % make regress<br> + % make install + </p> + + <h2> + nightly port + </h2> + + <p> + The nightly snapshot is automatically converted into an OpenBSD port (ports for other BSD systems not + yet available). These may be found in the <a href="/ports-openbsd/">/ports-openbsd/</a> directory. + </p> + + <p> + If installing for the first time: + </p> + + <p class="boxed"> + % ftp -V -o- http://mdocml.bsd.lv/ports-openbsd/mdocml.tgz | tar -zxf -<br> + % cd mdocml<br> + % sudo make<br> + % sudo make install + </p> + + <p> + Subsequent installations: + </p> + + <p class="boxed"> + % sudo pkg_add -r mdocml + </p> + </td> + </tr> + <tr> + <td> + <h1> + CONTACT + </h1> + + <p> + Please contact Kristaps, kris<a class="external" + href="http://mailhide.recaptcha.net/d?k=01jt88xIsFONwVjHZmGpc4AQ==&c=sb5E6ulipc-eTnpTVqI-BQ==" + onclick="window.open('http://mailhide.recaptcha.net/d?k=01jt88xIsFONwVjHZmGpc4AQ==&c=sb5E6ulipc-eTnpTVqI-BQ==', + '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return + false;" title="Reveal this e-mail address">...</a>@kth.se, with questions, bug reports, patches, and so on. + </p> + + <p> + If you'd like to submit patches, please contact us beforehand in case larger changes are pending but not + checked in. If making a bug report, please make sure it's repeatable on the most current snapshot. + </p> + </td> + </tr> + <tr> + <td> + <div class="foot"> + Copyright © 2009 Kristaps Džonsons, $Date$ + </div> + </td> + </tr> + </tbody> + </table> + </body> +</html> @@ -99,7 +99,7 @@ Both functions (see and variables (see .Sx Variables ) may use the following types: -.Bl -ohang +.Bl -ohang -offset "XXXX" .\" LIST-ITEM .It Vt struct mdoc An opaque type defined in @@ -120,7 +120,7 @@ for details. .\" SUBSECTION .Ss Functions Function descriptions follow: -.Bl -ohang +.Bl -ohang -offset "XXXX" .\" LIST-ITEM .It Fn mdoc_alloc Allocates a parsing structure. The @@ -165,7 +165,7 @@ return 0, the data will be incomplete. .\" SUBSECTION .Ss Variables The following variables are also defined: -.Bl -ohang +.Bl -ohang -offset "XXXX" .\" LIST-ITEM .It Va mdoc_macronames An array of string-ified token names. @@ -213,7 +213,7 @@ field). The tree itself is arranged according to the following normal form, where capitalised non-terminals represent nodes. .Pp -.Bl -tag -width "ELEMENTXX" -compact +.Bl -tag -width "ELEMENTXX" -compact -offset "XXXX" .\" LIST-ITEM .It ROOT \(<- mnode+ @@ -272,7 +272,7 @@ Note that, if the last line of the file isn't newline-terminated, this will truncate the file's last character (see .Xr fgetln 3 ) . Further, this example does not error-check nor free memory upon failure. -.Bd -literal +.Bd -literal -offset "XXXX" struct mdoc *mdoc; struct mdoc_node *node; char *buf; @@ -318,6 +318,7 @@ is the default .Xr groff 1 system bundled with .Ox . +.\" PARAGRAPH .Pp Un-implemented: the .Sq \&Xc @@ -327,12 +328,19 @@ 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 @@ -340,6 +348,7 @@ 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 @@ -167,10 +167,9 @@ flushln(struct termp *p) for (j = 0; j < p->offset; j++) putchar(' '); vis = 0; - } else if (vis + vsz >= maxvis) { + } else if (vis + vsz >= maxvis) /* FIXME */ errx(1, "word breaks right margin"); - } /* * Write out the word and a trailing space. Omit the diff --git a/style.css b/style.css new file mode 100644 index 00000000..a8d6cbc5 --- /dev/null +++ b/style.css @@ -0,0 +1,52 @@ +body { color: #333333; + font-size: smaller; + font-family: Verdana, Tahoma, Arial, sans-serif; } + +p { margin-left: 40px; + text-align: justify; } + +table { margin-left: 40px; } + +ul { margin-left: 40px; } + +p.boxed { border: 1px solid #cccccc; + margin-left: 40px; + text-align: justify; + padding: 2px; + color: black; } + +h1 { font-weight: bold; + font-size: small; + font-family: Verdana, Tahoma, Arial, sans-serif; } + +h2 { font-weight: bold; + font-size: small; + margin-left: 20px; + margin-bottom: 0px; + font-family: Verdana, Tahoma, Arial, sans-serif; } + +h3 { font-size: small; + font-weight: normal; + margin-left: 20px; + margin-bottom: 0px; + font-family: Verdana, Tahoma, Arial, sans-serif; } + +span.man { color: #000000; border-bottom: 1px dotted #999999; } + +span.path { color: #000000; } + +span.nm { color: #000000; font-weight: bold; } + +span.attn { color: #000000; font-weight: bold; } + +div.head { border-bottom: 1px dotted #cccccc; + padding-bottom: 5px; + text-align: right; } + +div.foot { border-top: 1px dotted #cccccc; + padding-top: 5px; + font-size: smaller; + text-align: right; } + +a.external { background: transparent url(external.png) center right no-repeat; padding-right: 12px; } + @@ -30,6 +30,7 @@ */ /* FIXME: indent/tab. */ +/* FIXME: handle nested lists. */ #define TTYPE_PROG 0 #define TTYPE_CMD_FLAG 1 @@ -72,7 +73,8 @@ static int arg_hasattr(int, size_t, const struct mdoc_arg *); static int arg_getattr(int, size_t, const struct mdoc_arg *); -static size_t arg_offset(const char *); +static size_t arg_offset(const struct mdoc_arg *); +static size_t arg_width(const struct mdoc_arg *); /* * What follows describes prefix and postfix operations for the abstract @@ -94,6 +96,7 @@ DECL_POST(name); DECL_PREPOST(termp_aq); DECL_PREPOST(termp_ar); +DECL_PREPOST(termp_bd); DECL_PREPOST(termp_d1); DECL_PREPOST(termp_dq); DECL_PREPOST(termp_em); @@ -116,7 +119,6 @@ DECL_PREPOST(termp_sx); DECL_PREPOST(termp_va); DECL_PREPOST(termp_vt); -DECL_PRE(termp_bd); DECL_PRE(termp_bx); DECL_PRE(termp_ex); DECL_PRE(termp_nd); @@ -139,7 +141,7 @@ const struct termact __termacts[MDOC_MAX] = { { termp_pp_pre, NULL }, /* Pp */ { termp_d1_pre, termp_d1_post }, /* D1 */ { NULL, NULL }, /* Dl */ - { termp_bd_pre, NULL }, /* Bd */ + { termp_bd_pre, termp_bd_post }, /* Bd */ { NULL, NULL }, /* Ed */ { NULL, termp_bl_post }, /* Bl */ { NULL, NULL }, /* El */ @@ -242,15 +244,27 @@ const struct termact *termacts = __termacts; static size_t -arg_offset(const char *v) +arg_width(const struct mdoc_arg *arg) { - if (0 == strcmp(v, "indent")) + + /* TODO */ + assert(*arg->value); + return(strlen(*arg->value)); +} + + +static size_t +arg_offset(const struct mdoc_arg *arg) +{ + + /* TODO */ + assert(*arg->value); + if (0 == strcmp(*arg->value, "indent")) return(INDENT); - if (0 == strcmp(v, "indent-two")) + if (0 == strcmp(*arg->value, "indent-two")) return(INDENT * 2); - /* TODO */ - return(0); + return(strlen(*arg->value)); } @@ -308,7 +322,7 @@ termp_it_post(DECL_ARGS) const struct mdoc_node *n, *it; const struct mdoc_block *bl; int i; - size_t width; + size_t width, offset; /* * This (and termp_it_pre()) are the most complicated functions @@ -339,34 +353,32 @@ termp_it_post(DECL_ARGS) /* If `-tag', adjust our margins accordingly. */ if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) { + flushln(p); + + /* FIXME: this should auto-size. */ i = arg_getattr(MDOC_Width, bl->argc, bl->argv); - assert(i >= 0); - assert(1 == bl->argv[i].sz); - width = strlen(*bl->argv[i].value); /* XXX */ + width = i >= 0 ? arg_width(&bl->argv[i]) : 10; + + /* FIXME: nesting! Should happen at block. */ + i = arg_getattr(MDOC_Offset, bl->argc, bl->argv); + offset = i >= 0 ? arg_width(&bl->argv[i]) : 0; if (MDOC_HEAD == node->type) { - flushln(p); - /* FIXME: nested lists. */ p->rmargin = p->maxrmargin; + p->offset -= offset; p->flags &= ~TERMP_NOBREAK; } else { - flushln(p); - p->offset -= width + 1; + p->offset -= width; p->flags &= ~TERMP_NOLPAD; } - return; } if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) { i = arg_getattr(MDOC_Offset, bl->argc, bl->argv); - width = 0; - if (i >= 0) { - assert(1 == bl->argv[i].sz); - width = arg_offset(*bl->argv[i].value); - } + offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0; flushln(p); - p->offset -= width; + p->offset -= offset; return; } } @@ -379,7 +391,7 @@ termp_it_pre(DECL_ARGS) const struct mdoc_node *n, *it; const struct mdoc_block *bl; int i; - size_t width; + size_t width, offset; /* * Also see termp_it_post() for general comments. @@ -420,24 +432,27 @@ termp_it_pre(DECL_ARGS) assert(MDOC_HEAD == node->type || MDOC_BODY == node->type); + /* FIXME: see termp_it_post(). */ + /* If `-tag', adjust our margins accordingly. */ if (arg_hasattr(MDOC_Tag, bl->argc, bl->argv)) { + p->flags |= TERMP_NOSPACE; + i = arg_getattr(MDOC_Width, bl->argc, bl->argv); - assert(i >= 0); /* XXX */ - assert(1 == bl->argv[i].sz); - width = strlen(*bl->argv[i].value); /* XXX */ + width = i >= 0 ? arg_width(&bl->argv[i]) : 10; - /* FIXME: nested lists. */ + i = arg_getattr(MDOC_Offset, bl->argc, bl->argv); + offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0; if (MDOC_HEAD == node->type) { p->flags |= TERMP_NOBREAK; - p->flags |= TERMP_NOSPACE; + p->offset += offset; p->rmargin = p->offset + width; } else { p->flags |= TERMP_NOSPACE; p->flags |= TERMP_NOLPAD; - p->offset += width + 1; + p->offset += width; } return(1); } @@ -445,15 +460,11 @@ termp_it_pre(DECL_ARGS) /* If `-ohang', adjust left-margin. */ if (arg_hasattr(MDOC_Ohang, bl->argc, bl->argv)) { - width = 0; i = arg_getattr(MDOC_Offset, bl->argc, bl->argv); - if (i >= 0) { - assert(1 == bl->argv[i].sz); - width = arg_offset(*bl->argv[i].value); - } + offset = i >= 0 ? arg_offset(&bl->argv[i]) : 0; p->flags |= TERMP_NOSPACE; - p->offset += width; + p->offset += offset; return(1); } @@ -922,6 +933,7 @@ termp_bd_pre(DECL_ARGS) { const struct mdoc_block *bl; const struct mdoc_node *n; + int i; if (MDOC_BLOCK == node->type) { vspace(p); @@ -932,6 +944,13 @@ termp_bd_pre(DECL_ARGS) assert(MDOC_BLOCK == node->parent->type); bl = &node->parent->data.block; + + i = arg_getattr(MDOC_Offset, bl->argc, bl->argv); + if (-1 != i) { + assert(1 == bl->argv[i].sz); + p->offset += arg_offset(&bl->argv[i]); + } + if ( ! arg_hasattr(MDOC_Literal, bl->argc, bl->argv)) return(1); @@ -953,6 +972,27 @@ termp_bd_pre(DECL_ARGS) /* ARGSUSED */ +static void +termp_bd_post(DECL_ARGS) +{ + int i; + const struct mdoc_block *bl; + + if (MDOC_BODY != node->type) + return; + + assert(MDOC_BLOCK == node->parent->type); + bl = &node->parent->data.block; + + i = arg_getattr(MDOC_Offset, bl->argc, bl->argv); + if (-1 != i) { + assert(1 == bl->argv[i].sz); + p->offset -= arg_offset(&bl->argv[i]); + } +} + + +/* ARGSUSED */ static int termp_qq_pre(DECL_ARGS) { |