For a full list of changes, see <http://mdocml.bsd.lv/ChangeLog.html>.
Thanks-to: Kristaps Dzonsons
-.\" $Id: mandoc_char.7,v 1.29 2009/11/16 09:52:47 kristaps Exp $
+.\" $Id: mandoc_char.7,v 1.31 2010/01/07 09:16:19 kristaps Exp $
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
.\"
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd November 19, 2009
+.Dd February 20, 2010
.Dt MANDOC_CHAR 7
.Os
.
.
.
.Sh DESCRIPTION
-This documents the special characters and predefined strings accepted by
+This page documents the special characters and predefined strings accepted by
.Xr mandoc 1
to format
.Xr mdoc 7
.
.Pp
Note that each output mode will have a different rendering of the
-characters. It's guaranteed that each input symbol will correspond to a
+characters.
+It's guaranteed that each input symbol will correspond to a
(more or less) meaningful output rendering, regardless the mode.
.
.
.
.Pp
Spacing:
-.Bl -column -compact -offset indent 10m 20m
+.Bl -column -compact -offset indent "Input" "Description"
.It Em Input Ta Em Description
.It \e~ Ta non-breaking, non-collapsing space
.It \e Ta breaking, non-collapsing n-width space
.
.Pp
Lines:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(ba Ta \(ba Ta bar
.It \e(br Ta \(br Ta box rule
.
.Pp
Text markers:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(ci Ta \(ci Ta circle
.It \e(bu Ta \(bu Ta bullet
.
.Pp
Legal symbols:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(co Ta \(co Ta copyright
.It \e(rg Ta \(rg Ta registered
.
.Pp
Punctuation:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(em Ta \(em Ta em-dash
.It \e(en Ta \(en Ta en-dash
.It \e(hy Ta \(hy Ta hyphen
-.It \e\e Ta \\ Ta back-slash
.It \ee Ta \e Ta back-slash
.It \e. Ta \. Ta period
.It \e(r! Ta \(r! Ta upside-down exclamation
.
.Pp
Quotes:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(Bq Ta \(Bq Ta right low double-quote
.It \e(bq Ta \(bq Ta right low single-quote
.
.Pp
Brackets:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "x[bracketrightbp]" Rendered Description
.It Em Input Ta Em Rendered Ta Em Description
.It \e(lB Ta \(lB Ta left bracket
.It \e(rB Ta \(rB Ta right bracket
.
.Pp
Arrows:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(<- Ta \(<- Ta left arrow
.It \e(-> Ta \(-> Ta right arrow
.
.Pp
Logical:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(AN Ta \(AN Ta logical and
.It \e(OR Ta \(OR Ta logical or
.
.Pp
Mathematical:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(pl Ta \(pl Ta plus
.It \e(mi Ta \(mi Ta minus
.
.Pp
Ligatures:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(ff Ta \(ff Ta ff ligature
.It \e(fi Ta \(fi Ta fi ligature
.
.Pp
Accents:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(a" Ta \(a" Ta Hungarian umlaut
.It \e(a- Ta \(a- Ta macron
.
.Pp
Accented letters:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e('A Ta \('A Ta acute A
.It \e('E Ta \('E Ta acute E
.
.Pp
Special letters:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(-D Ta \(-D Ta Eth
.It \e(Sd Ta \(Sd Ta eth
.
.Pp
Currency:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(Do Ta \(Do Ta dollar
.It \e(ct Ta \(ct Ta cent
.
.Pp
Units:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(de Ta \(de Ta degree
.It \e(%0 Ta \(%0 Ta per-thousand
.
.Pp
Greek letters:
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e(*A Ta \(*A Ta Alpha
.It \e(*B Ta \(*B Ta Beta
implementations:
.
.Pp
-.Bl -column -compact -offset indent 10m 10m 10m
+.Bl -column -compact -offset indent "Input" "Rendered" "Description"
.It Em Input Ta Em Rendered Ta Em Description
.It \e*(Ba Ta \*(Ba Ta vertical bar
.It \e*(Ne Ta \*(Ne Ta not equal
.Sh AUTHORS
The
.Nm
-utility was written by
+manual page was written by
.An Kristaps Dzonsons Aq kristaps@kth.se .
# $OpenBSD: Makefile,v 1.21 2009/10/27 21:40:07 schwarze Exp $
-VERSION=1.9.14
+VERSION=1.9.15
CFLAGS+=-DVERSION=\"${VERSION}\"
WARNS?= 3
-/* $Id: arch.c,v 1.5 2009/10/26 17:05:43 kristaps Exp $ */
+/* $Id: arch.c,v 1.6 2010/01/01 17:14:26 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: att.c,v 1.5 2009/10/26 17:05:44 kristaps Exp $ */
+/* $Id: att.c,v 1.6 2010/01/01 17:14:26 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: chars.c,v 1.13 2009/11/05 07:21:01 kristaps Exp $ */
+/* $Id: chars.c,v 1.16 2010/01/28 06:04:59 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#define CHARS_BOTH (CHARS_CHAR | CHARS_STRING)
};
-#define LINES_MAX 351
+#define LINES_MAX 350
#define CHAR(w, x, y, z, a, b) \
{ NULL, (w), (y), (a), (x), (z), (b), CHARS_CHAR },
if (NULL == (pp = htab[hash]))
return(NULL);
- if (NULL == pp->next) {
- if ( ! match(pp, p, sz, type))
- return(NULL);
-
- if (CHARS_HTML == tab->type) {
- *rsz = pp->htmlsz;
- return(pp->html);
- }
- *rsz = pp->asciisz;
- return(pp->ascii);
- }
-
for (prev = NULL; pp; pp = pp->next) {
if ( ! match(pp, p, sz, type)) {
prev = pp;
-/* $Id: chars.in,v 1.19 2009/11/05 07:21:02 kristaps Exp $ */
+/* $Id: chars.in,v 1.20 2010/01/05 19:51:10 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
CHAR("em", 2, "--", 2, "—", 7)
CHAR("en", 2, "-", 1, "–", 7)
CHAR("hy", 2, "-", 1, "‐", 7)
-CHAR("\\", 1, "\\", 1, "\\", 1)
CHAR("e", 1, "\\", 1, "\\", 1)
/* Units. */
-/* $Id: html.c,v 1.91 2009/11/16 08:46:58 kristaps Exp $ */
+/* $Id: html.c,v 1.96 2010/02/17 19:48:33 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
-#define DOCTYPE "-//W3C//DTD HTML 4.01//EN"
-#define DTD "http://www.w3.org/TR/html4/strict.dtd"
-
struct htmldata {
const char *name;
int flags;
#define HTML_CLRLINE (1 << 0)
#define HTML_NOSTACK (1 << 1)
+#define HTML_AUTOCLOSE (1 << 2) /* Tag has auto-closure. */
};
static const struct htmldata htmltags[TAG_MAX] = {
{"html", HTML_CLRLINE}, /* TAG_HTML */
{"head", HTML_CLRLINE}, /* TAG_HEAD */
{"body", HTML_CLRLINE}, /* TAG_BODY */
- {"meta", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_META */
+ {"meta", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_META */
{"title", HTML_CLRLINE}, /* TAG_TITLE */
{"div", HTML_CLRLINE}, /* TAG_DIV */
{"h1", 0}, /* TAG_H1 */
{"h2", 0}, /* TAG_H2 */
- {"p", HTML_CLRLINE}, /* TAG_P */
{"span", 0}, /* TAG_SPAN */
{"link", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_LINK */
- {"br", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_LINK */
+ {"br", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_BR */
{"a", 0}, /* TAG_A */
{"table", HTML_CLRLINE}, /* TAG_TABLE */
- {"col", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_COL */
+ {"col", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_COL */
{"tr", HTML_CLRLINE}, /* TAG_TR */
{"td", HTML_CLRLINE}, /* TAG_TD */
{"li", HTML_CLRLINE}, /* TAG_LI */
{"ul", HTML_CLRLINE}, /* TAG_UL */
{"ol", HTML_CLRLINE}, /* TAG_OL */
- {"base", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_BASE */
};
static const char *const htmlfonts[HTMLFONT_MAX] = {
"summary",
};
-#ifdef __linux__
-extern int getsubopt(char **, char * const *, char **);
-#endif
-
-
static void print_spec(struct html *, const char *, size_t);
static void print_res(struct html *, const char *, size_t);
static void print_ctag(struct html *, enum htmltag);
+static void print_doctype(struct html *);
+static void print_xmltype(struct html *);
static int print_encode(struct html *, const char *, int);
static void print_metaf(struct html *, enum roffdeco);
+static void print_attr(struct html *,
+ const char *, const char *);
+static void *ml_alloc(char *, enum htmltype);
-void *
-html_alloc(char *outopts)
+static void *
+ml_alloc(char *outopts, enum htmltype type)
{
struct html *h;
const char *toks[4];
exit(EXIT_FAILURE);
}
+ h->type = type;
h->tags.head = NULL;
h->ords.head = NULL;
h->symtab = chars_init(CHARS_HTML);
return(h);
}
+void *
+html_alloc(char *outopts)
+{
+
+ return(ml_alloc(outopts, HTML_HTML_4_01_STRICT));
+}
+
+
+void *
+xhtml_alloc(char *outopts)
+{
+
+ return(ml_alloc(outopts, HTML_XHTML_1_0_STRICT));
+}
+
void
html_free(void *p)
}
+static void
+print_attr(struct html *h, const char *key, const char *val)
+{
+ printf(" %s=\"", key);
+ (void)print_encode(h, val, 1);
+ putchar('\"');
+}
+
+
struct tag *
print_otag(struct html *h, enum htmltag tag,
int sz, const struct htmlpair *p)
int i;
struct tag *t;
+ /* Push this tags onto the stack of open scopes. */
+
if ( ! (HTML_NOSTACK & htmltags[tag].flags)) {
t = malloc(sizeof(struct tag));
if (NULL == t) {
if ( ! (HTML_CLRLINE & htmltags[tag].flags))
putchar(' ');
+ /* Print out the tag name and attributes. */
+
printf("<%s", htmltags[tag].name);
- for (i = 0; i < sz; i++) {
- printf(" %s=\"", htmlattrs[p[i].key]);
- assert(p->val);
- (void)print_encode(h, p[i].val, 1);
- putchar('\"');
+ for (i = 0; i < sz; i++)
+ print_attr(h, htmlattrs[p[i].key], p[i].val);
+
+ /* Add non-overridable attributes. */
+
+ if (TAG_HTML == tag && HTML_XHTML_1_0_STRICT == h->type) {
+ print_attr(h, "xmlns", "http://www.w3.org/1999/xhtml");
+ print_attr(h, "xml:lang", "en");
+ print_attr(h, "lang", "en");
}
+
+ /* Accomodate for XML "well-formed" singleton escaping. */
+
+ if (HTML_AUTOCLOSE & htmltags[tag].flags)
+ switch (h->type) {
+ case (HTML_XHTML_1_0_STRICT):
+ putchar('/');
+ break;
+ default:
+ break;
+ }
+
putchar('>');
h->flags |= HTML_NOSPACE;
}
-/* ARGSUSED */
void
-print_gen_doctype(struct html *h)
+print_gen_decls(struct html *h)
+{
+
+ print_xmltype(h);
+ print_doctype(h);
+}
+
+
+static void
+print_xmltype(struct html *h)
+{
+ const char *decl;
+
+ switch (h->type) {
+ case (HTML_XHTML_1_0_STRICT):
+ decl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ break;
+ default:
+ decl = NULL;
+ break;
+ }
+
+ if (NULL == decl)
+ return;
+
+ printf("%s\n", decl);
+}
+
+
+static void
+print_doctype(struct html *h)
{
+ const char *doctype;
+ const char *dtd;
+ const char *name;
+
+ switch (h->type) {
+ case (HTML_HTML_4_01_STRICT):
+ name = "HTML";
+ doctype = "-//W3C//DTD HTML 4.01//EN";
+ dtd = "http://www.w3.org/TR/html4/strict.dtd";
+ break;
+ default:
+ name = "html";
+ doctype = "-//W3C//DTD XHTML 1.0 Strict//EN";
+ dtd = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";
+ break;
+ }
- printf("<!DOCTYPE HTML PUBLIC \"%s\" \"%s\">", DOCTYPE, DTD);
+ printf("<!DOCTYPE %s PUBLIC \"%s\" \"%s\">\n",
+ name, doctype, dtd);
}
-/* $Id: html.h,v 1.21 2009/11/16 06:07:49 kristaps Exp $ */
+/* $Id: html.h,v 1.22 2010/01/29 14:39:38 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
TAG_DIV,
TAG_H1,
TAG_H2,
- TAG_P,
TAG_SPAN,
TAG_LINK,
TAG_BR,
TAG_LI,
TAG_UL,
TAG_OL,
- TAG_BASE,
TAG_MAX
};
do { (p)->key = ATTR_SUMMARY; \
(p)->val = (v); } while (/* CONSTCOND */ 0)
+enum htmltype {
+ HTML_HTML_4_01_STRICT,
+ HTML_XHTML_1_0_STRICT
+};
+
struct html {
int flags;
#define HTML_NOSPACE (1 << 0)
struct tag *metaf;
enum htmlfont metal;
enum htmlfont metac;
+ enum htmltype type;
};
struct roffsu;
-void print_gen_doctype(struct html *);
+void print_gen_decls(struct html *);
void print_gen_head(struct html *);
struct tag *print_ofont(struct html *, enum htmlfont);
struct tag *print_otag(struct html *, enum htmltag,
-/* $Id: lib.c,v 1.5 2009/10/26 17:05:44 kristaps Exp $ */
+/* $Id: lib.c,v 1.6 2010/01/01 17:14:27 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: main.c,v 1.57 2009/11/02 08:29:25 kristaps Exp $ */
+/* $Id: main.c,v 1.59 2010/01/29 14:39:38 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
# endif
#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */
-#ifdef __linux__
-extern int getsubopt(char **, char * const *, char **);
-extern size_t strlcat(char *, const char *, size_t);
-#endif
-
typedef void (*out_mdoc)(void *, const struct mdoc *);
typedef void (*out_man)(void *, const struct man *);
typedef void (*out_free)(void *);
OUTT_ASCII = 0,
OUTT_TREE,
OUTT_HTML,
+ OUTT_XHTML,
OUTT_LINT
};
if ( ! (curp->outman && curp->outmdoc)) {
switch (curp->outtype) {
+ case (OUTT_XHTML):
+ curp->outdata = xhtml_alloc(curp->outopts);
+ curp->outman = html_man;
+ curp->outmdoc = html_mdoc;
+ curp->outfree = html_free;
+ break;
case (OUTT_HTML):
curp->outdata = html_alloc(curp->outopts);
curp->outman = html_man;
*tflags = OUTT_TREE;
else if (0 == strcmp(arg, "html"))
*tflags = OUTT_HTML;
+ else if (0 == strcmp(arg, "xhtml"))
+ *tflags = OUTT_XHTML;
else {
fprintf(stderr, "%s: Bad argument\n", arg);
return(0);
-/* $Id: main.h,v 1.1 2009/10/13 10:57:25 kristaps Exp $ */
+/* $Id: main.h,v 1.2 2010/01/29 14:39:38 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
*/
void *html_alloc(char *);
+void *xhtml_alloc(char *);
void html_mdoc(void *, const struct mdoc *);
void html_man(void *, const struct man *);
void html_free(void *);
-.\" $Id: man.3,v 1.10 2009/10/03 16:36:06 kristaps Exp $
+.\" $Id: man.3,v 1.12 2010/02/17 19:22:01 kristaps Exp $
.\"
-.\" 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
.\" purpose with or without fee is hereby granted, provided that the above
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd November 6, 2009
+.Dd February 20, 2010
.Dt MAN 3
.Os
.\" SECTION
and variables (see
.Sx Variables )
may use the following types:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Vt struct man
An opaque type defined in
.\" SUBSECTION
.Ss Functions
Function descriptions follow:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Fn man_alloc
Allocates a parsing structure. The
.\" SUBSECTION
.Ss Variables
The following variables are also defined:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Va man_macronames
An array of string-ified token names.
The tree itself is arranged according to the following normal form,
where capitalised non-terminals represent nodes.
.Pp
-.Bl -tag -width "ELEMENTXX" -compact -offset "XXXX"
+.Bl -tag -width "ELEMENTXX" -compact
.\" LIST-ITEM
.It ROOT
\(<- mnode+
The following example reads lines from stdin and parses them, operating
on the finished parse tree with
.Fn parsed .
-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 -offset "XXXX"
+This example does not error-check nor free memory upon failure.
+.Bd -literal -offset indent
struct man *man;
struct man_node *node;
char *buf;
line = 1;
man = man_alloc(NULL, 0, NULL);
+buf = NULL;
+alloc_len = 0;
-while ((buf = fgetln(fp, &len))) {
- buf[len - 1] = '\\0';
- if ( ! man_parseln(man, line, buf))
- errx(1, "man_parseln");
- line++;
+while ((len = getline(&buf, &alloc_len, stdin)) >= 0) {
+ if (len && buflen[len - 1] = '\en')
+ buf[len - 1] = '\e0';
+ if ( ! man_parseln(man, line, buf))
+ errx(1, "man_parseln");
+ line++;
}
+free(buf);
+
if ( ! man_endparse(man))
- errx(1, "man_endparse");
+ errx(1, "man_endparse");
if (NULL == (node = man_node(man)))
- errx(1, "man_node");
+ errx(1, "man_node");
parsed(man, node);
man_free(man);
The
.Nm
utility was written by
-.An Kristaps Dzonsons Aq kristaps@kth.se .
+.An Kristaps Dzonsons Aq kristaps@bsd.lv .
-.\" $Id: man.7,v 1.54 2009/11/16 08:46:59 kristaps Exp $
+.\" $Id: man.7,v 1.55 2010/01/07 19:10:09 kristaps Exp $
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
.\"
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd November 19, 2009
+.Dd February 20, 2010
.Dt MAN 7
.Os
.
-/* $Id: man.c,v 1.46 2009/11/02 08:40:31 kristaps Exp $ */
+/* $Id: man.c,v 1.49 2010/01/07 10:24:43 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
const char *, size_t);
static int macrowarn(struct man *, int, const char *);
-#ifdef __linux__
-extern size_t strlcpy(char *, const char *, size_t);
-#endif
-
const struct man_node *
man_node(const struct man *m)
man_ptext(struct man *m, int line, char *buf)
{
int i, j;
+ char sv;
/* Literal free-form text whitespace is preserved. */
for (i = 0; ' ' == buf[i]; i++)
/* Skip leading whitespace. */ ;
- if (0 == buf[i]) {
+
+ if ('\0' == buf[i]) {
+ /* Trailing whitespace? */
+ if (i && ' ' == buf[i - 1])
+ if ( ! man_pwarn(m, line, i - 1, WTSPACE))
+ return(0);
if ( ! pstring(m, line, 0, &buf[i], 0))
return(0);
goto descope;
if (i && ' ' == buf[i] && '\\' == buf[i - 1])
continue;
- buf[i++] = 0;
+ sv = buf[i];
+ buf[i++] = '\0';
+
if ( ! pstring(m, line, j, &buf[j], (size_t)(i - j)))
return(0);
+ /* Trailing whitespace? Check at overwritten byte. */
+
+ if (' ' == sv && '\0' == buf[i])
+ if ( ! man_pwarn(m, line, i - 1, WTSPACE))
+ return(0);
+
for ( ; ' ' == buf[i]; i++)
/* Skip trailing whitespace. */ ;
j = i;
- if (0 == buf[i])
+
+ /* Trailing whitespace? */
+
+ if (' ' == buf[i - 1] && '\0' == buf[i])
+ if ( ! man_pwarn(m, line, i - 1, WTSPACE))
+ return(0);
+
+ if ('\0' == buf[i])
break;
}
i++;
while (buf[i] && ' ' == buf[i])
i++;
- if (0 == buf[i])
+ if ('\0' == buf[i])
goto out;
}
/* Copy the first word into a nil-terminated buffer. */
for (j = 0; j < 4; j++, i++) {
- if (0 == (mac[j] = buf[i]))
+ if ('\0' == (mac[j] = buf[i]))
break;
else if (' ' == buf[i])
break;
while (buf[i] && ' ' == buf[i])
i++;
+ /* Trailing whitespace? */
+
+ if ('\0' == buf[i] && ' ' == buf[i - 1])
+ if ( ! man_pwarn(m, ln, i - 1, WTSPACE))
+ goto err;
+
/* Remove prior ELINE macro, if applicable. */
if (m->flags & MAN_ELINE) {
-/* $Id: man_action.c,v 1.24 2009/11/02 06:22:45 kristaps Exp $ */
+/* $Id: man_action.c,v 1.25 2010/01/01 17:14:27 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: man_argv.c,v 1.1 2009/08/13 11:45:29 kristaps Exp $ */
+/* $Id: man_argv.c,v 1.2 2010/01/01 17:14:28 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: man_hash.c,v 1.15 2009/09/23 11:53:45 kristaps Exp $ */
+/* $Id: man_hash.c,v 1.16 2010/01/01 17:14:28 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: man_html.c,v 1.24 2009/11/16 08:46:59 kristaps Exp $ */
+/* $Id: man_html.c,v 1.26 2010/01/29 14:39:38 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
static int man_SM_pre(MAN_ARGS);
static int man_SS_pre(MAN_ARGS);
-#ifdef __linux__
-extern size_t strlcpy(char *, const char *, size_t);
-extern size_t strlcat(char *, const char *, size_t);
-#endif
-
static const struct htmlman mans[MAN_MAX] = {
{ man_br_pre, NULL }, /* br */
{ NULL, NULL }, /* TH */
h = (struct html *)arg;
- print_gen_doctype(h);
+ print_gen_decls(h);
t = print_otag(h, TAG_HTML, 0, NULL);
print_man(man_meta(m), man_node(m), h);
-/* $Id: man_macro.c,v 1.29 2009/10/24 05:45:05 kristaps Exp $ */
+/* $Id: man_macro.c,v 1.30 2010/01/01 17:14:28 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: man_term.c,v 1.54 2009/11/12 08:21:05 kristaps Exp $ */
+/* $Id: man_term.c,v 1.55 2010/01/01 17:14:28 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
void (*post)(DECL_ARGS);
};
-#ifdef __linux__
-extern size_t strlcpy(char *, const char *, size_t);
-extern size_t strlcat(char *, const char *, size_t);
-#endif
-
static int a2width(const struct man_node *);
static int a2height(const struct man_node *);
-/* $Id: man_validate.c,v 1.27 2009/11/02 06:22:45 kristaps Exp $ */
+/* $Id: man_validate.c,v 1.28 2010/01/01 17:14:28 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-.\" $Id: mandoc.1,v 1.48 2009/11/16 09:52:47 kristaps Exp $
+.\" $Id: mandoc.1,v 1.50 2010/01/29 14:39:38 kristaps Exp $
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
.\"
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd November 19, 2009
+.Dd February 20, 2010
.Dt MANDOC 1
.Os
.
Produce strict HTML-4.01 output, with a sane default style. See
.Sx HTML Output .
.
+.It Fl T Ns Ar xhtml
+Produce strict XHTML-1.0 output, with a sane default style. See
+.Sx XHTML Output .
+.
.It Fl T Ns Ar tree
Produce an indented parse tree.
.
.Ss HTML Output
Output produced by
.Fl T Ns Ar html
-comforms to HTML-4.01 strict.
+conforms to HTML-4.01 strict.
.Pp
Font styles and page structure are applied using CSS2. By default, no
font style is applied to any text, although CSS2 is hard-coded to format
Special characters are rendered in decimal-encoded UTF-8.
.
.
+.Ss XHTML Output
+Output produced by
+.Fl T Ns Ar xhtml
+conforms to XHTML-1.0 strict.
+.Pp
+See
+.Sx HTML Output
+for details; beyond generating XHTML tags instead of HTML tags, these
+output modes are identical.
+.
+.
.Sh EXAMPLES
To page manuals to the terminal:
.
.El
.
.
-.Ss HTML Compatibility
+.Ss HTML/XHTML Compatibility
.Bl -bullet -compact
.It
The
.Sh CAVEATS
The
.Fl T Ns Ar html
+and
+.Fl T Ns Ar xhtml
CSS2 styling used for
.Fl m Ns Ar doc
input lists does not render properly in brain-dead browsers, such as
Internet Explorer 6 and earlier.
.Pp
In
-.Fl T Ns Ar html ,
+.Fl T Ns Ar html
+and
+.Fl T Ns Ar xhtml ,
the maximum size of an element attribute is determined by
.Dv BUFSIZ ,
which is usually 1024 bytes. Be aware of this when setting long link
.Pp
The
.Fl T Ns Ar html
-output mode doesn't render the
+and
+.Fl T Ns Ar xhtml
+output modes don't render the
.Sq \es
font size escape documented in
.Xr mdoc 7
-/* $Id: mandoc.c,v 1.8 2009/11/05 10:16:01 kristaps Exp $ */
+/* $Id: mandoc.c,v 1.10 2010/01/05 19:51:10 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#if defined(__linux__) || defined(__MINT__)
-# define _GNU_SOURCE /* strptime() */
-#endif
#include <sys/types.h>
return(0);
switch (*p) {
- case ('\\'):
- /* FALLTHROUGH */
case ('\''):
/* FALLTHROUGH */
case ('`'):
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd November 11, 2009
+.Dd February 20, 2010
.Dt MANUALS 7
.Os
.\" SECTION
to version-control your work. If you wish the last check-in to effect
your document's date, use the following RCS tag for the date macro:
.Pp
-.Dl \&.Dd $Mdocdate$
+.Dl \&.Dd $Mdocdate: July 27 2009 $
.\" SUBSECTION
.Ss Viewing
mdoc documents may be paged to your terminal with
-.\" $Id: mdoc.3,v 1.35 2009/10/03 16:36:06 kristaps Exp $
+.\" $Id: mdoc.3,v 1.37 2010/02/17 19:22:01 kristaps Exp $
.\"
-.\" 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
.\" purpose with or without fee is hereby granted, provided that the above
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd November 11, 2009
+.Dd February 20, 2010
.Dt MDOC 3
.Os
.\" SECTION
and variables (see
.Sx Variables )
may use the following types:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Vt struct mdoc
An opaque type defined in
.\" SUBSECTION
.Ss Functions
Function descriptions follow:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Fn mdoc_alloc
Allocates a parsing structure. The
.\" SUBSECTION
.Ss Variables
The following variables are also defined:
-.Bl -ohang -offset "XXXX"
+.Bl -ohang
.\" LIST-ITEM
.It Va mdoc_macronames
An array of string-ified token names.
The tree itself is arranged according to the following normal form,
where capitalised non-terminals represent nodes.
.Pp
-.Bl -tag -width "ELEMENTXX" -compact -offset "XXXX"
+.Bl -tag -width "ELEMENTXX" -compact
.\" LIST-ITEM
.It ROOT
\(<- mnode+
The following example reads lines from stdin and parses them, operating
on the finished parse tree with
.Fn parsed .
-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 -offset "XXXX"
+This example does not error-check nor free memory upon failure.
+.Bd -literal -offset indent
struct mdoc *mdoc;
const struct mdoc_node *node;
char *buf;
line = 1;
mdoc = mdoc_alloc(NULL, 0, NULL);
+buf = NULL;
+alloc_len = 0;
-while ((buf = fgetln(fp, &len))) {
- buf[len - 1] = '\\0';
- if ( ! mdoc_parseln(mdoc, line, buf))
- errx(1, "mdoc_parseln");
- line++;
+while ((len = getline(&buf, &alloc_len, stdin)) >= 0) {
+ if (len && buflen[len - 1] = '\en')
+ buf[len - 1] = '\e0';
+ if ( ! mdoc_parseln(mdoc, line, buf))
+ errx(1, "mdoc_parseln");
+ line++;
}
if ( ! mdoc_endparse(mdoc))
- errx(1, "mdoc_endparse");
+ errx(1, "mdoc_endparse");
if (NULL == (node = mdoc_node(mdoc)))
- errx(1, "mdoc_node");
+ errx(1, "mdoc_node");
parsed(mdoc, node);
mdoc_free(mdoc);
The
.Nm
utility was written by
-.An Kristaps Dzonsons Aq kristaps@kth.se .
+.An Kristaps Dzonsons Aq kristaps@bsd.lv .
.\" SECTION
.Sh CAVEATS
.Bl -dash -compact
-.\" $Id: mdoc.7,v 1.78 2009/11/16 09:52:47 kristaps Exp $
+.\" $Id: mdoc.7,v 1.84 2010/02/17 19:22:50 kristaps Exp $
.\"
.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
.\"
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd November 19, 2009
+.Dd February 20, 2010
.Dt MDOC 7
.Os
.
macro(s) must precede the
.Sx \&Nd
macro.
+.Pp
+See
+.Sx \&Nm
+and
+.Sx \&Nd .
.
.It Em LIBRARY
The name of the library containing the documented material, which is
.Ed
.Pp
See
-.Sx \&Lb
-for details.
+.Sx \&Lb .
.
.It Em SYNOPSIS
Documents the utility invocation syntax, function call syntax, or device
.Pp
Manuals not in these sections generally don't need a
.Em SYNOPSIS .
+.Pp
+See
+.Sx \&Op ,
+.Sx \&Cd ,
+.Sx \&Fn ,
+.Sx \&Ft ,
+and
+.Sx \&Vt .
.
.It Em DESCRIPTION
This expands upon the brief, one-line description in
Print verbose information.
\&.El
.Ed
+.Pp
Manuals not documenting a command won't include the above fragment.
.
.It Em IMPLEMENTATION NOTES
discouraged.
.Pp
See
-.Sx \&Bl No \-diag .
+.Sx \&Bl
+.Fl diag .
.
.It Em ERRORS
Documents error handling in sections 2, 3, and 9.
.It Sx \&Ql Ta Yes Ta Yes
.It Sx \&Qq Ta Yes Ta Yes
.It Sx \&Sq Ta Yes Ta Yes
+.It Sx \&Vt Ta Yes Ta Yes
.El
+.Pp
+Note that the
+.Sx \&Vt
+macro is a
+.Sx Block partial-implicit
+only when invoked as the first macro
+in a SYNOPSIS section line, else it is
+.Sx In-line .
.
.
.Ss In-line
.It Sx \&Ux Ta Yes Ta Yes Ta n
.It Sx \&Va Ta Yes Ta Yes Ta n
.It Sx \&Vt Ta Yes Ta Yes Ta >0
-.It Sx \&Xr Ta Yes Ta Yes Ta >0, <3
+.It Sx \&Xr Ta Yes Ta Yes Ta >0
.It Sx \&br Ta \&No Ta \&No Ta 0
.It Sx \&sp Ta \&No Ta \&No Ta 1
.El
.Ss \&Bf
.Ss \&Bk
.Ss \&Bl
-.
+.\" Begins a list composed of one or more list entries. A list entry is
+.\" specified by the
+.\" .Sx \&It
+.\" macro, which consists of a head and optional body. By default, a list
+.\" is preceded by a blank line. A list must specify one of the following
+.\" list types:
+.\" .Bl -tag -width 12n
+.\" .It Fl bullet
+.\" A list offset by a bullet. The head of list entries must be empty.
+.\" List entry bodies are justified after the bullet.
+.\" .It Fl column
+.\" A columnated list. The number of columns is specified as arguments to
+.\" the
+.\" .Sx \&Bl
+.\" macro (the deprecated form of following the invocation of
+.\" .Fl column
+.\" is also accepted). Arguments dictate the width of columns specified in
+.\" list entries. List entry bodies must be left empty. Columns specified
+.\" in the list entry head are justified to their position in the sequence
+.\" of columns.
+.\" .It Fl dash
+.\" A list offset by a dash (hyphen). The head of list entries must be
+.\" empty. List entry bodies are justified past the dash.
+.\" .It Fl diag
+.\" Like
+.\" .Fl inset
+.\" lists, but with additional formatting to the head.
+.\" .It Fl enum
+.\" A list offset by a number indicating list entry position. The head of
+.\" list entries must be empty. List entry bodies are justified past the
+.\" enumeration.
+.\" .It Fl hang
+.\" Like
+.\" .Fl tag ,
+.\" but instead of list bodies justifying to the head on the first line,
+.\" they trail the head text.
+.\" .It Fl hyphen
+.\" Synonym for
+.\" .Fl dash .
+.\" .It Fl inset
+.\" Like
+.\" .Fl tag ,
+.\" but list entry bodies aren't justified.
+.\" .It Fl item
+.\" An un-justified list. This produces blocks of text.
+.\" .It Fl ohang
+.\" List bodies are placed on the line following the head.
+.\" .It Fl tag
+.\" A list offset by list entry heads. List entry bodies are justified
+.\" after the head.
+.\" .El
+.\" .Pp
+.\" More...
+.\" .
.Ss \&Bo
Begins a block enclosed by square brackets. Does not have any head
arguments.
.Ss \&Fc
.Ss \&Fd
.Ss \&Fl
+Command-line flag. Used when listing arguments to command-line
+utilities. Prints a fixed-width hyphen
+.Sq \-
+before each delimited argument. If no arguments are provided, a hyphen
+is still printed.
+.Pp
+Examples:
+.Bd -literal -offset indent
+\&.Fl a b c
+\&.Fl
+\&.Op Fl o Ns Ar file
+.Ed
+.Pp
+See also
+.Sx \&Cm .
+.
.Ss \&Fn
.Ss \&Fo
.Ss \&Fr
.
.Ss \&Va
.Ss \&Vt
+A variable type. This is also used for indicating global variables in the
+SYNOPSIS section, in which case a variable name is also specified. Note that
+it accepts
+.Sx Block partial-implicit
+syntax when invoked as the first macro in the SYNOPSIS section, else it
+accepts ordinary
+.Sx In-line
+syntax.
+.Pp
+Note that this should not be confused with
+.Sx \&Ft ,
+which is used for function return types.
+.Pp
+Examples:
+.Bd -literal -offset indent
+\&.Vt unsigned char
+\&.Vt extern const char * const sys_signame[] ;
+.Ed
+.Pp
+See also
+.Sx \&Ft
+and
+.Sx \&Va .
+.
.Ss \&Xc
.Ss \&Xo
.Ss \&Xr
+Link to another manual
+.Pq Qq cross-reference .
+Its calling syntax is
+.Pp
+.D1 \. Ns Sx \&Xr Cm name section
+.Pp
+The
+.Cm name
+and
+.Cm section
+are the name and section of the linked manual. If
+.Cm section
+is followed by non-punctuation, an
+.Sx \&Ns
+is inserted into the token stream. This behaviour is for compatibility
+with
+.Xr groff 1 .
+.Pp
+Examples:
+.Bd -literal -offset indent
+\&.Xr mandoc 1
+\&.Xr mandoc 1 ;
+\&.Xr mandoc 1 s behaviour
+.Ed
+.
.Ss \&br
.Ss \&sp
.
.Pp
.Bl -dash -compact
.It
+The comment syntax
+.Sq \e."
+is no longer accepted.
+.It
+In
+.Xr groff 1 ,
+the
+.Sx \&Pa
+macro does not format its arguments when used in the FILES section under
+certain list types. This irregular behaviour has been discontinued.
+.It
+Historic
+.Xr groff 1
+does not print a dash for empty
+.Sx \&Fl
+arguments. This behaviour has been discontinued.
+.It
.Xr groff 1
behaves strangely (even between versions) when specifying
.Sq \ef
Negative scaling units are now truncated to zero instead of creating
interesting conditions, such as with
.Sx \&sp
-.Cm \-1i .
+.Fl 1i .
Furthermore, the
.Sq f
scaling unit, while accepted, is rendered as the default unit.
-/* $Id: mdoc.c,v 1.113 2009/10/30 05:58:38 kristaps Exp $ */
+/* $Id: mdoc.c,v 1.116 2010/01/07 10:24:43 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
"Nm", "Op", "Ot", "Pa",
"Rv", "St", "Va", "Vt",
/* LINTED */
- "Xr", "\%A", "\%B", "\%D",
+ "Xr", "%A", "%B", "%D",
/* LINTED */
- "\%I", "\%J", "\%N", "\%O",
+ "%I", "%J", "%N", "%O",
/* LINTED */
- "\%P", "\%R", "\%T", "\%V",
+ "%P", "%R", "%T", "%V",
"Ac", "Ao", "Aq", "At",
"Bc", "Bf", "Bo", "Bq",
"Bsx", "Bx", "Db", "Dc",
"Fr", "Ud", "Lb", "Lp",
"Lk", "Mt", "Brq", "Bro",
/* LINTED */
- "Brc", "\%C", "Es", "En",
+ "Brc", "%C", "Es", "En",
/* LINTED */
- "Dx", "\%Q", "br", "sp",
+ "Dx", "%Q", "br", "sp",
/* LINTED */
- "\%U"
+ "%U"
};
const char *const __mdoc_argnames[MDOC_ARG_MAX] = {
static int pstring(struct mdoc *, int, int,
const char *, size_t);
-#ifdef __linux__
-extern size_t strlcpy(char *, const char *, size_t);
-#endif
-
-
const struct mdoc_node *
mdoc_node(const struct mdoc *m)
{
parsetext(struct mdoc *m, int line, char *buf)
{
int i, j;
+ char sv;
if (SEC_NONE == m->lastnamed)
return(mdoc_perr(m, line, 0, ETEXTPROL));
for (i = 0; ' ' == buf[i]; i++)
/* Skip leading whitespace. */ ;
- if (0 == buf[i])
+
+ if ('\0' == buf[i])
return(mdoc_perr(m, line, 0, ENOBLANK));
/*
if (i && ' ' == buf[i] && '\\' == buf[i - 1])
continue;
- buf[i++] = 0;
+ sv = buf[i];
+ buf[i++] = '\0';
+
if ( ! pstring(m, line, j, &buf[j], (size_t)(i - j)))
return(0);
+ /* Trailing whitespace? Check at overwritten byte. */
+
+ if (' ' == sv && '\0' == buf[i])
+ if ( ! mdoc_pwarn(m, line, i - 1, ETAILWS))
+ return(0);
+
for ( ; ' ' == buf[i]; i++)
/* Skip trailing whitespace. */ ;
j = i;
- if (0 == buf[i])
+
+ /* Trailing whitespace? */
+
+ if (' ' == buf[i - 1] && '\0' == buf[i])
+ if ( ! mdoc_pwarn(m, line, i - 1, ETAILWS))
+ return(0);
+
+ if ('\0' == buf[i])
break;
}
/* Empty lines are ignored. */
- if (0 == buf[1])
+ if ('\0' == buf[1])
return(1);
i = 1;
i++;
while (buf[i] && ' ' == buf[i])
i++;
- if (0 == buf[i])
+ if ('\0' == buf[i])
return(1);
}
/* Copy the first word into a nil-terminated buffer. */
for (j = 0; j < 4; j++, i++) {
- if (0 == (mac[j] = buf[i]))
+ if ('\0' == (mac[j] = buf[i]))
break;
else if (' ' == buf[i])
break;
while (buf[i] && ' ' == buf[i])
i++;
+ /* Trailing whitespace? */
+
+ if ('\0' == buf[i] && ' ' == buf[i - 1])
+ if ( ! mdoc_pwarn(m, ln, i - 1, ETAILWS))
+ goto err;
+
/*
* Begin recursive parse sequence. Since we're at the start of
* the line, we don't need to do callable/parseable checks.
-/* $Id: mdoc_action.c,v 1.49 2009/11/02 06:22:45 kristaps Exp $ */
+/* $Id: mdoc_action.c,v 1.50 2010/01/01 17:14:29 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
const struct mdoc_node *, size_t);
static inline int order_rs(int);
-#ifdef __linux__
-extern size_t strlcat(char *, const char *, size_t);
-#endif
-
static int post_ar(POST_ARGS);
static int post_at(POST_ARGS);
static int post_bl(POST_ARGS);
-/* $Id: mdoc_argv.c,v 1.32 2009/10/30 05:58:38 kristaps Exp $ */
+/* $Id: mdoc_argv.c,v 1.33 2010/01/01 17:14:29 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: mdoc_hash.c,v 1.11 2009/09/17 07:41:28 kristaps Exp $ */
+/* $Id: mdoc_hash.c,v 1.12 2010/01/01 17:14:29 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: mdoc_html.c,v 1.48 2009/11/16 08:46:59 kristaps Exp $ */
+/* $Id: mdoc_html.c,v 1.54 2010/01/30 08:42:20 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
-#include <sys/param.h>
#include <assert.h>
#include <ctype.h>
const struct mdoc_node *n, \
struct html *h
+#ifndef MIN
+#define MIN(a,b) ((/*CONSTCOND*/(a)<(b))?(a):(b))
+#endif
+
struct htmlmdoc {
int (*pre)(MDOC_ARGS);
void (*post)(MDOC_ARGS);
static int mdoc_xr_pre(MDOC_ARGS);
static int mdoc_xx_pre(MDOC_ARGS);
-#ifdef __linux__
-extern size_t strlcpy(char *, const char *, size_t);
-extern size_t strlcat(char *, const char *, size_t);
-#endif
-
static const struct htmlmdoc mdocs[MDOC_MAX] = {
{mdoc_ap_pre, NULL}, /* Ap */
{NULL, NULL}, /* Dd */
h = (struct html *)arg;
- print_gen_doctype(h);
+ print_gen_decls(h);
t = print_otag(h, TAG_HTML, 0, NULL);
print_mdoc(mdoc_meta(m), mdoc_node(m), h);
print_tagq(h, t);
PAIR_CLASS_INIT(&tag, "flag");
print_otag(h, TAG_SPAN, 1, &tag);
- if (MDOC_Fl == n->tok) {
- print_text(h, "\\-");
+
+ /* `Cm' has no leading hyphen. */
+
+ if (MDOC_Cm == n->tok)
+ return(1);
+
+ print_text(h, "\\-");
+
+ /* A blank `Fl' should incur a subsequent space. */
+
+ if (n->child)
h->flags |= HTML_NOSPACE;
- }
+
return(1);
}
struct htmlpair tag;
struct roffsu su;
- if (SEC_SYNOPSIS == n->sec) {
- if (n->next && MDOC_Vt != n->next->tok) {
+ if (MDOC_BLOCK == n->type) {
+ if (n->prev && MDOC_Vt != n->prev->tok) {
SCALE_VS_INIT(&su, 1);
- bufcat_su(h, "margin-bottom", &su);
+ bufcat_su(h, "margin-top", &su);
PAIR_STYLE_INIT(&tag, h);
print_otag(h, TAG_DIV, 1, &tag);
} else
print_otag(h, TAG_DIV, 0, NULL);
- }
+
+ return(1);
+ } else if (MDOC_HEAD == n->type)
+ return(0);
PAIR_CLASS_INIT(&tag, "type");
print_otag(h, TAG_SPAN, 1, &tag);
-/* $Id: mdoc_macro.c,v 1.38 2009/10/26 17:05:44 kristaps Exp $ */
+/* $Id: mdoc_macro.c,v 1.42 2010/02/17 19:28:11 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
#define REWIND_NOHALT (1 << 1)
#define REWIND_HALT (1 << 2)
+static int ctx_synopsis(MACRO_PROT_ARGS);
static int obsolete(MACRO_PROT_ARGS);
static int blk_part_exp(MACRO_PROT_ARGS);
static int in_line_eoln(MACRO_PROT_ARGS);
{ in_line_eoln, 0 }, /* Rv */
{ in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */
{ in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */
- { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */
- { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */
+ { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */
+ { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */
{ in_line_eoln, 0 }, /* %A */
{ in_line_eoln, 0 }, /* %B */
{ in_line_eoln, 0 }, /* %D */
case (MDOC_Qq):
/* FALLTHROUGH */
case (MDOC_Sq):
+ /* FALLTHROUGH */
+ case (MDOC_Vt):
assert(MDOC_TAIL != type);
if (type == p->type && tok == p->tok)
return(REWIND_REWIND);
static int
blk_exp_close(MACRO_PROT_ARGS)
{
- int j, c, lastarg, maxargs, flushed;
+ int j, c, lastarg, maxargs, flushed;
char *p;
switch (tok) {
cnt++;
if ( ! mdoc_word_alloc(m, line, la, p))
return(0);
+
+ /*
+ * `Fl' macros have their scope re-opened with each new
+ * word so that the `-' can be added to each one without
+ * having to parse out spaces.
+ */
+ if (0 == lastpunct && MDOC_Fl == tok) {
+ if ( ! rew_elem(m, tok))
+ return(0);
+ lastpunct = 1;
+ }
}
if (0 == lastpunct && ! rew_elem(m, tok))
case (MDOC_Ux):
maxargs = 0;
break;
+ case (MDOC_Xr):
+ maxargs = 2;
+ break;
default:
maxargs = 1;
break;
flushed = 1;
}
+ /*
+ * XXX: this is a hack to work around groff's ugliness
+ * as regards `Xr' and extraneous arguments. It should
+ * ideally be deprecated behaviour, but because this is
+ * code is no here, it's unlikely to be removed.
+ */
+ if (MDOC_Xr == tok && j == maxargs) {
+ if ( ! mdoc_elem_alloc(m, line, ppos, MDOC_Ns, NULL))
+ return(0);
+ if ( ! rew_elem(m, MDOC_Ns))
+ return(0);
+ }
+
if ( ! mdoc_word_alloc(m, line, la, p))
return(0);
}
}
+/* ARGSUSED */
+static int
+ctx_synopsis(MACRO_PROT_ARGS)
+{
+
+ /* If we're not in the SYNOPSIS, go straight to in-line. */
+ if (SEC_SYNOPSIS != m->lastsec)
+ return(in_line(m, tok, line, ppos, pos, buf));
+
+ /* If we're a nested call, same place. */
+ if (ppos > 1)
+ return(in_line(m, tok, line, ppos, pos, buf));
+
+ /*
+ * XXX: this will open a block scope; however, if later we end
+ * up formatting the block scope, then child nodes will inherit
+ * the formatting. Be careful.
+ */
+
+ return(blk_part_imp(m, tok, line, ppos, pos, buf));
+}
+
+
/* ARGSUSED */
static int
obsolete(MACRO_PROT_ARGS)
-/* $Id: mdoc_strings.c,v 1.13 2009/11/02 06:22:46 kristaps Exp $ */
+/* $Id: mdoc_strings.c,v 1.14 2010/01/01 17:14:30 kristaps Exp $ */
/*
* Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: mdoc_term.c,v 1.102 2009/11/12 05:50:12 kristaps Exp $ */
+/* $Id: mdoc_term.c,v 1.110 2010/01/30 08:42:21 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
struct termpair {
struct termpair *ppair;
- int flag;
int count;
};
static void print_bvspace(struct termp *,
const struct mdoc_node *,
const struct mdoc_node *);
-static void print_mdoc_node(DECL_ARGS);
+static void print_mdoc_node(DECL_ARGS);
static void print_mdoc_head(DECL_ARGS);
static void print_mdoc_nodelist(DECL_ARGS);
static void print_foot(DECL_ARGS);
-#ifdef __linux__
-extern size_t strlcpy(char *, const char *, size_t);
-extern size_t strlcat(char *, const char *, size_t);
-#endif
-
static void termp____post(DECL_ARGS);
static void termp_an_post(DECL_ARGS);
static void termp_aq_post(DECL_ARGS);
static int termp_ss_pre(DECL_ARGS);
static int termp_under_pre(DECL_ARGS);
static int termp_ud_pre(DECL_ARGS);
+static int termp_vt_pre(DECL_ARGS);
static int termp_xr_pre(DECL_ARGS);
static int termp_xx_pre(DECL_ARGS);
{ termp_rv_pre, NULL }, /* Rv */
{ NULL, NULL }, /* St */
{ termp_under_pre, NULL }, /* Va */
- { termp_under_pre, termp_vt_post }, /* Vt */
+ { termp_vt_pre, termp_vt_post }, /* Vt */
{ termp_xr_pre, NULL }, /* Xr */
{ NULL, termp____post }, /* %A */
{ termp_under_pre, termp____post }, /* %B */
if ( ! a2roffsu(arg->value[pos], &su, SCALE_MAX))
SCALE_HS_INIT(&su, strlen(arg->value[pos]));
- /* XXX: pachemu? */
- return(term_hspan(&su) + 2);
+ return(term_hspan(&su));
}
}
+/*
+ * Return 1 if an argument has a particular argument value or 0 if it
+ * does not. See arg_getattr().
+ */
static int
arg_hasattr(int arg, const struct mdoc_node *n)
{
}
+/*
+ * Get the index of an argument in a node's argument list or -1 if it
+ * does not exist. See arg_getattrs().
+ */
static int
arg_getattr(int v, const struct mdoc_node *n)
{
}
+/*
+ * Walk through the argument list for a node and fill an array "vals"
+ * with the positions of the argument structures listed in "keys".
+ * Return the number of elements that were written into "vals", which
+ * can be zero.
+ */
static int
arg_getattrs(const int *keys, int *vals,
size_t sz, const struct mdoc_node *n)
}
+/*
+ * Determine how much space to print out before block elements of `It'
+ * (and thus `Bl') and `Bd'. And then go ahead and print that space,
+ * too.
+ */
static void
print_bvspace(struct termp *p,
const struct mdoc_node *bl,
const struct mdoc_node *bl, *nn;
char buf[7];
int i, type, keys[3], vals[3];
- size_t width, offset;
+ size_t width, offset, ncols, dcol;
if (MDOC_BLOCK == n->type) {
print_bvspace(p, n->parent->parent, n);
bl = n->parent->parent->parent;
- /* Save parent attributes. */
-
- pair->flag = p->flags;
-
- /* Get list width and offset. */
+ /* Get list width, offset, and list type from argument list. */
keys[0] = MDOC_Width;
keys[1] = MDOC_Offset;
vals[0] = vals[1] = vals[2] = -1;
- width = offset = 0;
-
- (void)arg_getattrs(keys, vals, 3, bl);
+ arg_getattrs(keys, vals, 3, bl);
type = arg_listtype(bl);
assert(-1 != type);
- /* Calculate real width and offset. */
+ /*
+ * First calculate width and offset. This is pretty easy unless
+ * we're a -column list, in which case all prior columns must
+ * be accounted for.
+ */
+
+ width = offset = 0;
+
+ if (vals[1] >= 0)
+ offset = a2offs(&bl->args->argv[vals[1]]);
switch (type) {
case (MDOC_Column):
if (MDOC_BODY == n->type)
break;
/*
- * Work around groff's column handling. The offset is
- * equal to the sum of all widths leading to the current
- * column (plus the -offset value). If this column
- * exceeds the stated number of columns, the width is
- * set as 0, else it's the stated column width (later
- * the 0 will be adjusted to default 10 or, if in the
- * last column case, set to stretch to the margin).
+ * Imitate groff's column handling:
+ * - For each earlier column, add its width.
+ * - For less than 5 columns, add four more blanks per
+ * column.
+ * - For exactly 5 columns, add three more blank per
+ * column.
+ * - For more than 5 columns, add only one column.
*/
- for (i = 0, nn = n->prev; nn &&
- i < (int)bl->args->argv[vals[2]].sz;
+ ncols = bl->args->argv[vals[2]].sz;
+ /* LINTED */
+ dcol = ncols < 5 ? 4 : ncols == 5 ? 3 : 1;
+
+ for (i = 0, nn = n->prev;
+ nn && i < (int)ncols;
nn = nn->prev, i++)
- offset += a2width
+ offset += dcol + a2width
(&bl->args->argv[vals[2]], i);
- /* Whether exceeds maximum column. */
- if (i < (int)bl->args->argv[vals[2]].sz)
- width = a2width(&bl->args->argv[vals[2]], i);
- else
- width = 0;
- if (vals[1] >= 0)
- offset += a2offs(&bl->args->argv[vals[1]]);
+ /*
+ * When exceeding the declared number of columns, leave
+ * the remaining widths at 0. This will later be
+ * adjusted to the default width of 10, or, for the last
+ * column, stretched to the right margin.
+ */
+ if (i >= (int)ncols)
+ break;
+
+ /*
+ * Use the declared column widths, extended as explained
+ * in the preceding paragraph.
+ */
+ width = a2width(&bl->args->argv[vals[2]], i) + dcol;
break;
default:
- if (vals[0] >= 0)
- width = a2width(&bl->args->argv[vals[0]], 0);
- if (vals[1] >= 0)
- offset += a2offs(&bl->args->argv[vals[1]]);
+ if (vals[0] < 0)
+ break;
+
+ /*
+ * Note: buffer the width by 2, which is groff's magic
+ * number for buffering single arguments. See the above
+ * handling for column for how this changes.
+ */
+ width = a2width(&bl->args->argv[vals[0]], 0) + 2;
break;
}
}
/*
- * Pad and break control. This is the tricker part. Lists with
- * set right-margins for the head get TERMP_NOBREAK because, if
- * they overrun the margin, they wrap to the new margin.
- * Correspondingly, the body for these types don't left-pad, as
- * the head will pad out to to the right.
+ * Pad and break control. This is the tricky part. These flags
+ * are documented in term_flushln() in term.c. Note that we're
+ * going to unset all of these flags in termp_it_post() when we
+ * exit.
*/
switch (type) {
* right-most column is filled to the right margin.
*/
if (MDOC_HEAD == n->type &&
- MDOC_BODY == n->next->type)
+ MDOC_BODY == n->next->type &&
+ p->rmargin < p->maxrmargin)
p->rmargin = p->maxrmargin;
break;
default:
break;
case (MDOC_Enum):
(pair->ppair->ppair->count)++;
- (void)snprintf(buf, sizeof(buf), "%d.",
+ snprintf(buf, sizeof(buf), "%d.",
pair->ppair->ppair->count);
term_word(p, buf);
break;
{
int type;
- if (MDOC_BODY != n->type && MDOC_HEAD != n->type)
+ if (MDOC_BLOCK == n->type)
return;
type = arg_listtype(n->parent->parent->parent);
break;
}
- p->flags = pair->flag;
+ /*
+ * Now that our output is flushed, we can reset our tags. Since
+ * only `It' sets these flags, we're free to assume that nobody
+ * has munged them in the meanwhile.
+ */
+
+ p->flags &= ~TERMP_DANGLE;
+ p->flags &= ~TERMP_NOBREAK;
+ p->flags &= ~TERMP_TWOSPACE;
+ p->flags &= ~TERMP_NOLPAD;
+ p->flags &= ~TERMP_HANG;
}
term_fontpush(p, TERMFONT_BOLD);
term_word(p, "\\-");
- p->flags |= TERMP_NOSPACE;
+
+ /* A blank `Fl' should incur a subsequent space. */
+
+ if (n->child)
+ p->flags |= TERMP_NOSPACE;
+
return(1);
}
}
+static int
+termp_vt_pre(DECL_ARGS)
+{
+
+ if (MDOC_ELEM == n->type)
+ return(termp_under_pre(p, pair, m, n));
+ else if (MDOC_HEAD == n->type)
+ return(0);
+ else if (MDOC_BLOCK == n->type)
+ return(1);
+
+ return(termp_under_pre(p, pair, m, n));
+}
+
+
/* ARGSUSED */
static void
termp_vt_post(DECL_ARGS)
{
- if (n->sec != SEC_SYNOPSIS)
+ if (MDOC_BLOCK != n->type)
return;
if (n->next && MDOC_Vt == n->next->tok)
term_newln(p);
{
assert(n->child && MDOC_TEXT == n->child->type);
- if (0 == strcmp("on", n->child->string)) {
+ if (0 == strcmp("on", n->child->string))
p->flags &= ~TERMP_NONOSPACE;
- p->flags &= ~TERMP_NOSPACE;
- } else
+ else
p->flags |= TERMP_NONOSPACE;
return(0);
-/* $Id: mdoc_validate.c,v 1.54 2009/11/02 06:22:46 kristaps Exp $ */
+/* $Id: mdoc_validate.c,v 1.58 2010/02/17 19:28:11 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
static int err_count(struct mdoc *, const char *,
int, const char *, int);
-#ifdef __linux__
-extern size_t strlcat(char *, const char *, size_t);
-#endif
-
static int berr_ge1(POST_ARGS);
static int bwarn_ge1(POST_ARGS);
static int ebool(POST_ARGS);
static int eerr_eq0(POST_ARGS);
static int eerr_eq1(POST_ARGS);
static int eerr_ge1(POST_ARGS);
-static int eerr_le2(POST_ARGS);
static int eerr_le1(POST_ARGS);
static int ewarn_ge1(POST_ARGS);
static int herr_eq0(POST_ARGS);
static int post_sh_body(POST_ARGS);
static int post_sh_head(POST_ARGS);
static int post_st(POST_ARGS);
+static int post_vt(POST_ARGS);
static int pre_an(PRE_ARGS);
static int pre_bd(PRE_ARGS);
static int pre_bl(PRE_ARGS);
static v_post posts_st[] = { eerr_eq1, post_st, NULL };
static v_post posts_text[] = { eerr_ge1, NULL };
static v_post posts_text1[] = { eerr_eq1, NULL };
+static v_post posts_vt[] = { post_vt, NULL };
static v_post posts_wline[] = { bwarn_ge1, herr_eq0, NULL };
static v_post posts_wtext[] = { ewarn_ge1, NULL };
-static v_post posts_xr[] = { eerr_ge1, eerr_le2, NULL };
+static v_post posts_xr[] = { eerr_ge1, NULL };
static v_pre pres_an[] = { pre_an, NULL };
static v_pre pres_bd[] = { pre_display, pre_bd, NULL };
static v_pre pres_bl[] = { pre_bl, NULL };
{ pres_rv, NULL }, /* Rv */
{ NULL, posts_st }, /* St */
{ NULL, NULL }, /* Va */
- { NULL, posts_text }, /* Vt */
+ { NULL, posts_vt }, /* Vt */
{ NULL, posts_xr }, /* Xr */
{ NULL, posts_text }, /* %A */
{ NULL, posts_text }, /* %B */ /* FIXME: can be used outside Rs/Re. */
CHECK_BODY_DEFN(ge1, err, err_child_gt, 0) /* berr_ge1() */
CHECK_ELEM_DEFN(ge1, warn, warn_child_gt, 0) /* ewarn_gt1() */
CHECK_ELEM_DEFN(eq1, err, err_child_eq, 1) /* eerr_eq1() */
-CHECK_ELEM_DEFN(le2, err, err_child_lt, 3) /* eerr_le2() */
CHECK_ELEM_DEFN(le1, err, err_child_lt, 2) /* eerr_le1() */
CHECK_ELEM_DEFN(eq0, err, err_child_eq, 0) /* eerr_eq0() */
CHECK_ELEM_DEFN(ge1, err, err_child_gt, 0) /* eerr_ge1() */
}
+static int
+post_vt(POST_ARGS)
+{
+ const struct mdoc_node *n;
+
+ /*
+ * The Vt macro comes in both ELEM and BLOCK form, both of which
+ * have different syntaxes (yet more context-sensitive
+ * behaviour). ELEM types must have a child; BLOCK types,
+ * specifically the BODY, should only have TEXT children.
+ */
+
+ if (MDOC_ELEM == mdoc->last->type)
+ return(eerr_ge1(mdoc));
+ if (MDOC_BODY != mdoc->last->type)
+ return(1);
+
+ for (n = mdoc->last->child; n; n = n->next)
+ if (MDOC_TEXT != n->type)
+ if ( ! mdoc_nwarn(mdoc, n, EBADCHILD))
+ return(0);
+
+ return(1);
+}
+
+
static int
post_nm(POST_ARGS)
{
if (NULL == mdoc->last->child)
return(1);
+ /*
+ * We only allow certain children of `Bl'. This is usually on
+ * `It', but apparently `Sm' occurs here and there, so we let
+ * that one through, too.
+ */
+
/* LINTED */
for (n = mdoc->last->child; n; n = n->next) {
- if (MDOC_BLOCK == n->type)
- if (MDOC_It == n->tok)
- continue;
+ if (MDOC_BLOCK == n->type && MDOC_It == n->tok)
+ continue;
+ if (MDOC_Sm == n->tok)
+ continue;
return(mdoc_nerr(mdoc, n, EBADCHILD));
}
-/* $Id: msec.c,v 1.5 2009/10/26 17:05:44 kristaps Exp $ */
+/* $Id: msec.c,v 1.6 2010/01/01 17:14:30 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: out.c,v 1.11 2009/11/12 08:21:05 kristaps Exp $ */
+/* $Id: out.c,v 1.12 2010/01/01 17:14:30 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
(t) = 3; } \
while (/* CONSTCOND */ 0)
-#ifdef __linux__
-extern size_t strlcat(char *, const char *, size_t);
-#endif
-
/*
* Convert a `scaling unit' to a consistent form, or fail. Scaling
* units are documented in groff.7, mdoc.7, man.7.
-/* $Id: st.c,v 1.5 2009/10/26 17:05:44 kristaps Exp $ */
+/* $Id: st.c,v 1.6 2010/01/01 17:14:30 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: term.c,v 1.127 2009/11/12 08:21:06 kristaps Exp $ */
+/* $Id: term.c,v 1.128 2010/01/01 17:14:30 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: tree.c,v 1.18 2009/10/30 18:53:09 kristaps Exp $ */
+/* $Id: tree.c,v 1.19 2010/01/01 17:14:31 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
*
-/* $Id: vol.c,v 1.5 2009/10/26 17:05:45 kristaps Exp $ */
+/* $Id: vol.c,v 1.6 2010/01/01 17:14:31 kristaps Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
*