summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/mandoc/Makefile4
-rw-r--r--usr.bin/mandoc/html.c40
-rw-r--r--usr.bin/mandoc/html.h8
-rw-r--r--usr.bin/mandoc/libman.h5
-rw-r--r--usr.bin/mandoc/libmdoc.h5
-rw-r--r--usr.bin/mandoc/main.c8
-rw-r--r--usr.bin/mandoc/man.35
-rw-r--r--usr.bin/mandoc/man.c5
-rw-r--r--usr.bin/mandoc/man_html.c5
-rw-r--r--usr.bin/mandoc/man_term.c5
-rw-r--r--usr.bin/mandoc/mandoc.123
-rw-r--r--usr.bin/mandoc/mandoc.h45
-rw-r--r--usr.bin/mandoc/mdoc.349
-rw-r--r--usr.bin/mandoc/mdoc.7243
-rw-r--r--usr.bin/mandoc/mdoc.c34
-rw-r--r--usr.bin/mandoc/mdoc.h35
-rw-r--r--usr.bin/mandoc/mdoc_action.c47
-rw-r--r--usr.bin/mandoc/mdoc_argv.c7
-rw-r--r--usr.bin/mandoc/mdoc_html.c216
-rw-r--r--usr.bin/mandoc/mdoc_macro.c13
-rw-r--r--usr.bin/mandoc/mdoc_term.c150
-rw-r--r--usr.bin/mandoc/mdoc_validate.c260
-rw-r--r--usr.bin/mandoc/regs.h51
-rw-r--r--usr.bin/mandoc/roff.360
-rw-r--r--usr.bin/mandoc/roff.724
-rw-r--r--usr.bin/mandoc/roff.c185
-rw-r--r--usr.bin/mandoc/term.c52
-rw-r--r--usr.bin/mandoc/term.h30
-rw-r--r--usr.bin/mandoc/term_ascii.c62
-rw-r--r--usr.bin/mandoc/term_ps.c849
-rw-r--r--usr.bin/mandoc/tree.c3
31 files changed, 1526 insertions, 1002 deletions
diff --git a/usr.bin/mandoc/Makefile b/usr.bin/mandoc/Makefile
index 0ef7c42b411..45cb7994050 100644
--- a/usr.bin/mandoc/Makefile
+++ b/usr.bin/mandoc/Makefile
@@ -1,8 +1,8 @@
-# $OpenBSD: Makefile,v 1.42 2010/06/29 15:49:52 schwarze Exp $
+# $OpenBSD: Makefile,v 1.43 2010/07/13 01:09:12 schwarze Exp $
.include <bsd.own.mk>
-VERSION=1.10.3
+VERSION=1.10.4
CFLAGS+=-DVERSION=\"${VERSION}\"
CFLAGS+=-W -Wall -Wstrict-prototypes
diff --git a/usr.bin/mandoc/html.c b/usr.bin/mandoc/html.c
index b348afccba7..16cdb29fd8e 100644
--- a/usr.bin/mandoc/html.c
+++ b/usr.bin/mandoc/html.c
@@ -1,6 +1,6 @@
-/* $Id: html.c,v 1.11 2010/06/27 20:28:56 schwarze Exp $ */
+/* $Id: html.c,v 1.12 2010/07/13 01:09:12 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 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
@@ -389,8 +389,15 @@ print_otag(struct html *h, enum htmltag tag,
t = NULL;
if ( ! (HTML_NOSPACE & h->flags))
- if ( ! (HTML_CLRLINE & htmltags[tag].flags))
- putchar(' ');
+ if ( ! (HTML_CLRLINE & htmltags[tag].flags)) {
+ /* Manage keeps! */
+ if ( ! (HTML_KEEP & h->flags)) {
+ if (HTML_PREKEEP & h->flags)
+ h->flags |= HTML_KEEP;
+ putchar(' ');
+ } else
+ printf("&#160;");
+ }
/* Print out the tag name and attributes. */
@@ -480,11 +487,11 @@ print_doctype(struct html *h)
void
-print_text(struct html *h, const char *p)
+print_text(struct html *h, const char *word)
{
- if (*p && 0 == *(p + 1))
- switch (*p) {
+ if (word[0] && '\0' == word[1])
+ switch (word[0]) {
case('.'):
/* FALLTHROUGH */
case(','):
@@ -507,19 +514,26 @@ print_text(struct html *h, const char *p)
break;
}
- if ( ! (h->flags & HTML_NOSPACE))
- putchar(' ');
+ if ( ! (HTML_NOSPACE & h->flags)) {
+ /* Manage keeps! */
+ if ( ! (HTML_KEEP & h->flags)) {
+ if (HTML_PREKEEP & h->flags)
+ h->flags |= HTML_KEEP;
+ putchar(' ');
+ } else
+ printf("&#160;");
+ }
- assert(p);
- if ( ! print_encode(h, p, 0))
+ assert(word);
+ if ( ! print_encode(h, word, 0))
h->flags &= ~HTML_NOSPACE;
/*
* Note that we don't process the pipe: the parser sees it as
* punctuation, but we don't in terms of typography.
*/
- if (*p && 0 == *(p + 1))
- switch (*p) {
+ if (word[0] && '\0' == word[1])
+ switch (word[0]) {
case('('):
/* FALLTHROUGH */
case('['):
diff --git a/usr.bin/mandoc/html.h b/usr.bin/mandoc/html.h
index 7bb789c98d0..bd973499cc0 100644
--- a/usr.bin/mandoc/html.h
+++ b/usr.bin/mandoc/html.h
@@ -1,6 +1,6 @@
-/* $Id: html.h,v 1.6 2010/04/07 23:15:05 schwarze Exp $ */
+/* $Id: html.h,v 1.7 2010/07/13 01:09:12 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 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
@@ -110,7 +110,9 @@ enum htmltype {
struct html {
int flags;
#define HTML_NOSPACE (1 << 0)
-#define HTML_IGNDELIM (1 << 2)
+#define HTML_IGNDELIM (1 << 1)
+#define HTML_KEEP (1 << 2)
+#define HTML_PREKEEP (1 << 3)
struct tagq tags;
struct ordq ords;
void *symtab;
diff --git a/usr.bin/mandoc/libman.h b/usr.bin/mandoc/libman.h
index e26ab2a660d..0ef8b2143d5 100644
--- a/usr.bin/mandoc/libman.h
+++ b/usr.bin/mandoc/libman.h
@@ -1,6 +1,6 @@
-/* $Id: libman.h,v 1.23 2010/06/27 21:54:41 schwarze Exp $ */
+/* $Id: libman.h,v 1.24 2010/07/13 01:09:12 schwarze Exp $ */
/*
- * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * 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
@@ -17,7 +17,6 @@
#ifndef LIBMAN_H
#define LIBMAN_H
-#include "regs.h"
#include "man.h"
enum man_next {
diff --git a/usr.bin/mandoc/libmdoc.h b/usr.bin/mandoc/libmdoc.h
index c4e0f7b99d4..53ba8bae361 100644
--- a/usr.bin/mandoc/libmdoc.h
+++ b/usr.bin/mandoc/libmdoc.h
@@ -1,6 +1,6 @@
-/* $Id: libmdoc.h,v 1.40 2010/07/01 22:31:52 schwarze Exp $ */
+/* $Id: libmdoc.h,v 1.41 2010/07/13 01:09:12 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 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
@@ -17,7 +17,6 @@
#ifndef LIBMDOC_H
#define LIBMDOC_H
-#include "regs.h"
#include "mdoc.h"
enum mdoc_next {
diff --git a/usr.bin/mandoc/main.c b/usr.bin/mandoc/main.c
index d676aa49007..53b4e7b81e3 100644
--- a/usr.bin/mandoc/main.c
+++ b/usr.bin/mandoc/main.c
@@ -1,6 +1,7 @@
-/* $Id: main.c,v 1.41 2010/07/01 15:36:59 schwarze Exp $ */
+/* $Id: main.c,v 1.42 2010/07/13 01:09:12 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -27,7 +28,6 @@
#include <unistd.h>
#include "mandoc.h"
-#include "regs.h"
#include "main.h"
#include "mdoc.h"
#include "man.h"
@@ -142,13 +142,13 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"no title in document",
"missing list type",
"missing display type",
+ "missing font type",
"line argument(s) will be lost",
"body argument(s) will be lost",
"generic fatal error",
"column syntax is inconsistent",
- "missing font type",
"displays may not be nested",
"unsupported display type",
"blocks badly nested",
diff --git a/usr.bin/mandoc/man.3 b/usr.bin/mandoc/man.3
index 2edd6a0a88a..8f42388e7bd 100644
--- a/usr.bin/mandoc/man.3
+++ b/usr.bin/mandoc/man.3
@@ -1,4 +1,4 @@
-.\" $Id: man.3,v 1.12 2010/06/27 21:54:42 schwarze Exp $
+.\" $Id: man.3,v 1.13 2010/07/13 01:09:12 schwarze Exp $
.\"
.\" Copyright (c) 2009-2010 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 27 2010 $
+.Dd $Mdocdate: July 13 2010 $
.Dt MAN 3
.Os
.Sh NAME
@@ -29,7 +29,6 @@
.Nd man macro compiler library
.Sh SYNOPSIS
.In mandoc.h
-.In regs.h
.In man.h
.Vt extern const char * const * man_macronames;
.Ft "struct man *"
diff --git a/usr.bin/mandoc/man.c b/usr.bin/mandoc/man.c
index 71acf9fd042..9ac7f5f9ad9 100644
--- a/usr.bin/mandoc/man.c
+++ b/usr.bin/mandoc/man.c
@@ -1,6 +1,6 @@
-/* $Id: man.c,v 1.35 2010/06/27 21:54:42 schwarze Exp $ */
+/* $Id: man.c,v 1.36 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 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
@@ -24,7 +24,6 @@
#include <string.h>
#include "mandoc.h"
-#include "regs.h"
#include "libman.h"
#include "libmandoc.h"
diff --git a/usr.bin/mandoc/man_html.c b/usr.bin/mandoc/man_html.c
index bbe7a7aedef..8b77f129bb6 100644
--- a/usr.bin/mandoc/man_html.c
+++ b/usr.bin/mandoc/man_html.c
@@ -1,6 +1,6 @@
-/* $Id: man_html.c,v 1.16 2010/06/27 21:54:42 schwarze Exp $ */
+/* $Id: man_html.c,v 1.17 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 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
@@ -25,7 +25,6 @@
#include "mandoc.h"
#include "out.h"
#include "html.h"
-#include "regs.h"
#include "man.h"
#include "main.h"
diff --git a/usr.bin/mandoc/man_term.c b/usr.bin/mandoc/man_term.c
index 868f93a6058..dfb4463f1e7 100644
--- a/usr.bin/mandoc/man_term.c
+++ b/usr.bin/mandoc/man_term.c
@@ -1,6 +1,6 @@
-/* $Id: man_term.c,v 1.43 2010/06/27 21:54:42 schwarze Exp $ */
+/* $Id: man_term.c,v 1.44 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 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
@@ -24,7 +24,6 @@
#include "mandoc.h"
#include "out.h"
-#include "regs.h"
#include "man.h"
#include "term.h"
#include "chars.h"
diff --git a/usr.bin/mandoc/mandoc.1 b/usr.bin/mandoc/mandoc.1
index 7fa4db7dc13..e0fa0b163df 100644
--- a/usr.bin/mandoc/mandoc.1
+++ b/usr.bin/mandoc/mandoc.1
@@ -1,6 +1,6 @@
-.\" $OpenBSD: mandoc.1,v 1.34 2010/06/29 15:49:52 schwarze Exp $
+.\" $OpenBSD: mandoc.1,v 1.35 2010/07/13 01:09:13 schwarze Exp $
.\"
-.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+.\" 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
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 29 2010 $
+.Dd $Mdocdate: July 13 2010 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -302,8 +302,10 @@ PostScript
.Qq Adobe-3.0
Level-2 pages may be generated by
.Fl T Ns Cm ps .
-Output pages are US-letter sized and rendered in fixed, 10-point Courier
-font.
+Output pages default to letter sized and are rendered in the Times font
+family, 11-point.
+Margins are calculated as 1/9 the page length and width.
+Line-height is 1.4m.
.Pp
Special characters are rendered as in
.Sx ASCII Output .
@@ -316,9 +318,18 @@ arguments are accepted:
The paper size
.Ar name
may be one of
-.Ar a4
+.Ar a3 ,
+.Ar a4 ,
+.Ar a5 ,
+.Ar legal ,
or
.Ar letter .
+You may also manually specify dimensions as
+.Ar NNxNN ,
+width by height in millimetres.
+If an unknown value is encountered,
+.Ar letter
+is used.
.El
.Ss XHTML Output
Output produced by
diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h
index 6abf61d9405..53b239b57f5 100644
--- a/usr.bin/mandoc/mandoc.h
+++ b/usr.bin/mandoc/mandoc.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc.h,v 1.9 2010/07/01 15:36:59 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.10 2010/07/13 01:09:13 schwarze Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -17,10 +17,13 @@
#ifndef MANDOC_H
#define MANDOC_H
+/*
+ * This contains declarations that are available system-wide.
+ */
+
#define ASCII_NBRSP 31 /* non-breaking space */
#define ASCII_HYPH 30 /* breakable hyphen */
-
__BEGIN_DECLS
enum mandocerr {
@@ -81,6 +84,7 @@ enum mandocerr {
MANDOCERR_NOTITLE, /* no title in document */
MANDOCERR_LISTTYPE, /* missing list type */
MANDOCERR_DISPTYPE, /* missing display type */
+ MANDOCERR_FONTTYPE, /* missing font type */
MANDOCERR_ARGSLOST, /* line argument(s) will be lost */
MANDOCERR_BODYLOST, /* body argument(s) will be lost */
@@ -88,8 +92,6 @@ enum mandocerr {
MANDOCERR_COLUMNS, /* column syntax is inconsistent */
/* FIXME: this should be a MANDOCERR_ERROR */
- MANDOCERR_FONTTYPE, /* missing font type */
- /* FIXME: this should be a MANDOCERR_ERROR */
MANDOCERR_NESTEDDISP, /* displays may not be nested */
MANDOCERR_BADDISP, /* unsupported display type */
MANDOCERR_SCOPEFATAL, /* blocks badly nested */
@@ -107,8 +109,39 @@ enum mandocerr {
MANDOCERR_MAX
};
-typedef int (*mandocmsg)(enum mandocerr,
- void *, int, int, const char *);
+enum regs {
+ REG_nS = 0, /* register: nS */
+ REG__MAX
+};
+
+/*
+ * A single register entity. If "set" is zero, the value of the
+ * register should be the default one, which is per-register. It's
+ * assumed that callers know which type in "v" corresponds to which
+ * register value.
+ */
+struct reg {
+ int set; /* whether set or not */
+ union {
+ unsigned u; /* unsigned integer */
+ } v;
+};
+
+/*
+ * The primary interface to setting register values is in libroff,
+ * although libmdoc and libman from time to time will manipulate
+ * registers (such as `.Sh SYNOPSIS' enabling REG_nS).
+ */
+struct regset {
+ struct reg regs[REG__MAX];
+};
+
+/*
+ * Callback function for warnings, errors, and fatal errors as they
+ * occur in the compilers libroff, libmdoc, and libman.
+ */
+typedef int (*mandocmsg)(enum mandocerr, void *,
+ int, int, const char *);
__END_DECLS
diff --git a/usr.bin/mandoc/mdoc.3 b/usr.bin/mandoc/mdoc.3
index 70efdb6e3fd..f498c8c9624 100644
--- a/usr.bin/mandoc/mdoc.3
+++ b/usr.bin/mandoc/mdoc.3
@@ -1,6 +1,7 @@
-.\" $Id: mdoc.3,v 1.10 2010/06/29 17:10:29 schwarze Exp $
+.\" $Id: mdoc.3,v 1.11 2010/07/13 01:09:13 schwarze Exp $
.\"
-.\" Copyright (c) 2009-2010 Kristaps Dzonsons <kristaps@bsd.lv>
+.\" Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+.\" Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 29 2010 $
+.Dd $Mdocdate: July 13 2010 $
.Dt MDOC 3
.Os
.Sh NAME
@@ -29,7 +30,6 @@
.Nd mdoc macro compiler library
.Sh SYNOPSIS
.In mandoc.h
-.In regs.h
.In mdoc.h
.Vt extern const char * const * mdoc_macronames;
.Vt extern const char * const * mdoc_argnames;
@@ -257,10 +257,10 @@ an empty line will produce a zero-length string.
Multiple body parts are only found in invocations of
.Sq \&Bl \-column ,
where a new body introduces a new phrase.
-.Ss Badly nested blocks
-A special kind of node is available to end the formatting
-associated with a given block before the physical end of that block.
-Such an ENDBODY node has a non-null
+.Ss Badly-nested Blocks
+The ENDBODY node is available to end the formatting associated
+with a given block before the physical end of that block.
+It has a non-null
.Va end
field, is of the BODY
.Va type ,
@@ -297,25 +297,32 @@ BLOCK Ao
TEXT end
.Ed
.Pp
-Here, the formatting of the Ao block extends from TEXT ao to TEXT ac,
-while the formatting of the Bo block extends from TEXT bo to TEXT bc,
-rendering like this in
+Here, the formatting of the
+.Sq \&Ao
+block extends from TEXT ao to TEXT ac,
+while the formatting of the
+.Sq \&Bo
+block extends from TEXT bo to TEXT bc.
+It renders as follows in
.Fl T Ns Cm ascii
mode:
+.Pp
.Dl <ao [bo ac> bc] end
-Support for badly nested blocks is only provided for backward
+.Pp
+Support for badly-nested blocks is only provided for backward
compatibility with some older
.Xr mdoc 7
implementations.
-Using them in new code is stronly discouraged:
-Some frontends, in particular
-.Fl T Ns Cm html ,
-are unable to render them in any meaningful way,
-many other
-.Xr mdoc 7
-implementations do not support them, and even for those that do,
-the behaviour is not well-defined, in particular when using multiple
-levels of badly nested blocks.
+Using badly-nested blocks is
+.Em strongly discouraged :
+the
+.Fl T Ns Cm html
+and
+.Fl T Ns Cm xhtml
+front-ends are unable to render them in any meaningful way.
+Furthermore, behaviour when encountering badly-nested blocks is not
+consistent across troff implementations, especially when using multiple
+levels of badly-nested blocks.
.Sh EXAMPLES
The following example reads lines from stdin and parses them, operating
on the finished parse tree with
diff --git a/usr.bin/mandoc/mdoc.7 b/usr.bin/mandoc/mdoc.7
index 2f1d0650f8a..3cc5c858ff2 100644
--- a/usr.bin/mandoc/mdoc.7
+++ b/usr.bin/mandoc/mdoc.7
@@ -1,6 +1,7 @@
-.\" $Id: mdoc.7,v 1.38 2010/07/01 15:36:59 schwarze Exp $
+.\" $Id: mdoc.7,v 1.39 2010/07/13 01:09:13 schwarze Exp $
.\"
-.\" Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+.\" Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+.\" Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 1 2010 $
+.Dd $Mdocdate: July 13 2010 $
.Dt MDOC 7
.Os
.Sh NAME
@@ -1063,6 +1064,14 @@ Closes a
block. Does not have any tail arguments.
.Ss \&Bd
Begins a display block.
+Its syntax is as follows:
+.Bd -ragged -offset indent
+.Pf \. Sx \&Bd
+.Fl type
+.Op Fl offset Ar width
+.Op Fl compact
+.Ed
+.Pp
A display is collection of macros or text which may be collectively
offset or justified in a manner different from that
of the enclosing context.
@@ -1087,9 +1096,9 @@ Centre-justify each line.
The type must be provided first.
Secondary arguments are as follows:
.Bl -tag -width 12n -offset indent
-.It Fl offset Ar width
+.It Fl offset Ar val
Offset by the value of
-.Ar width ,
+.Ar val ,
which is interpreted as one of the following, specified in order:
.Bl -item
.It
@@ -1100,7 +1109,7 @@ the width of standard indentation;
twice
.Ar indent ;
.Ar left ,
-which has no effect ;
+which has no effect;
.Ar right ,
which justifies to the right margin; and
.Ar center ,
@@ -1121,10 +1130,6 @@ As the calculated string length of the opaque string.
If not provided an argument, it will be ignored.
.It Fl compact
Do not assert a vertical space before the block.
-.It Fl file Ar file
-Prepend the file
-.Ar file
-before any text or macros within the block.
.El
.Pp
Examples:
@@ -1139,28 +1144,75 @@ See also
and
.Sx \&Dl .
.Ss \&Bf
+Change the font mode for a scoped block of text.
+Its syntax is as follows:
+.Bd -ragged -offset indent
+.Pf \. Sx \&Bf
+.Oo
+.Fl emphasis | literal | symbolic |
+.Cm \&Em | \&Li | \&Sy
+.Oc
+.Ed
+.Pp
+The
+.Fl emphasis
+and
+.Cm \&Em
+argument are equivalent, as are
+.Fl symbolic
+and
+.Cm \&Sy,
+and
+.Fl literal
+and
+.Cm \&Li .
+Without an argument, this macro does nothing.
+The font mode continues until broken by a new font mode in a nested
+scope or
+.Sx \&Ef
+is encountered.
+.Pp
+See also
+.Sx \&Li ,
+.Sx \&Ef ,
+and
+.Sx \&Sy .
.Ss \&Bk
-Begins a keep block, containing a collection of macros or text
-to be kept together in the output.
-One argument is required; additional arguments are ignored.
-Currently, the only argument implemented is
-.Fl words ,
-requesting to keep together all words of the contained text
-on the same output line.
-A
-.Fl lines
-argument to keep together all lines of the contained text
-on the same page has been desired for a long time,
-but has never been implemented.
+Begins a collection of macros or text not breaking the line.
+Its syntax is as follows:
.Pp
-Examples:
+.D1 Pf \. Sx \&Bk Fl words
+.Pp
+Subsequent arguments are ignored.
+The
+.Fl words
+argument is required.
+.Pp
+Each line within a keep block is kept intact, so the following example
+will not break within each
+.Sx \&Op
+macro line:
.Bd -literal -offset indent
\&.Bk \-words
-\&.Op o Ar output_file
+\&.Op Fl f Ar flags
+\&.Op Fl o Ar output
\&.Ek
.Ed
+.Pp
+Be careful in using over-long lines within a keep block!
+Doing so will clobber the right margin.
.Ss \&Bl
Begins a list composed of one or more list entries.
+Its syntax is as follows:
+.Bd -ragged -offset indent
+.Pf \. Sx \&Bl
+.Fl type
+.Op Fl width Ar val
+.Op Fl offset Ar val
+.Op Fl compact
+.Op HEAD ...
+.Ed
+.Pp
A list is associated with a type, which is a required argument.
Other arguments are
.Fl width ,
@@ -1629,8 +1681,23 @@ See also
and
.Sx \&Ux .
.Ss \&Ec
+Close a scope started by
+.Sx \&Eo .
+Its syntax is as follows:
+.Pp
+.D1 Pf \. Sx \&Ec Op Cm TERM
+.Pp
+The
+.Cm TERM
+argument is used as the enclosure tail, for example, specifying \e(rq
+will emulate
+.Sx \&Dc .
.Ss \&Ed
+End a display context started by
+.Sx \&Bd .
.Ss \&Ef
+Ends a font mode context started by
+.Sx \&Bf .
.Ss \&Ek
Ends a keep context started by
.Sx \&Bk .
@@ -1651,7 +1718,18 @@ Examples:
.D1 \&.Em Warnings!
.D1 \&.Em Remarks :
.Ss \&En
+This macro is obsolete and not implemented.
.Ss \&Eo
+An arbitrary enclosure.
+Its syntax is as follows:
+.Pp
+.D1 Pf \. Sx \&Eo Op Cm TERM
+.Pp
+The
+.Cm TERM
+argument is used as the enclosure head, for example, specifying \e(lq
+will emulate
+.Sx \&Do .
.Ss \&Er
Display error constants.
.Pp
@@ -1662,6 +1740,7 @@ Examples:
See also
.Sx \&Dv .
.Ss \&Es
+This macro is obsolete and not implemented.
.Ss \&Ev
Environmental variables such as those specified in
.Xr environ 7 .
@@ -1712,6 +1791,8 @@ Examples:
See also
.Sx \&Fo .
.Ss \&Fc
+Ends a function context started by
+.Sx \&Fo .
.Ss \&Fd
Historically used to document include files.
This usage has been deprecated in favour of
@@ -1833,7 +1914,24 @@ See also
and
.Sx \&Ux .
.Ss \&Hf
+This macro is obsolete and not implemented.
.Ss \&Ic
+Designate an internal or interactive command.
+This is similar to
+.Sx \&Cm
+but used for instructions rather than values.
+.Pp
+Examples:
+.D1 \&.Ic hash
+.D1 \&.Ic alias
+.Pp
+Note that using
+.Sx \&Bd No Fl literal
+or
+.Sx \&D1
+is preferred for displaying code; the
+.Sx \&Ic
+macro is used when referring to specific instructions.
.Ss \&In
An
.Qq include
@@ -1956,6 +2054,9 @@ Examples:
.D1 \&.Lb libz
.D1 \&.Lb mdoc
.Ss \&Li
+Denotes text that should be in a literal font mode.
+Note that this is a presentation term and should not be used for
+stylistically decorating technical terms.
.Ss \&Lk
Format a hyperlink.
Its syntax is as follows:
@@ -1969,6 +2070,8 @@ Examples:
See also
.Sx \&Mt .
.Ss \&Lp
+Synonym for
+.Sx \&Pp .
.Ss \&Ms
.Ss \&Mt
Format a
@@ -1981,6 +2084,29 @@ Its syntax is as follows:
Examples:
.D1 \&.Mt discuss@manpages.bsd.lv
.Ss \&Nd
+A one-line description of the manual's content.
+This may only be invoked in the
+.Em SYNOPSIS
+section subsequent the
+.Sx \&Nm
+macro.
+.Pp
+Examples:
+.D1 \&.Sx \&Nd mdoc language reference
+.D1 \&.Sx \&Nd format and display UNIX manuals
+.Pp
+The
+.Sx \&Nd
+macro technically accepts child macros and terminates with a subsequent
+.Sx \&Sh
+invocation.
+Do not assume this behaviour: some
+.Xr whatis 1
+database generators are not smart enough to parse more than the line
+arguments and will display macros verbatim.
+.Pp
+See also
+.Sx \&Nm .
.Ss \&Nm
The name of the manual page, or \(em in particular in section 1, 6,
and 8 pages \(em of an additional command or feature documented in
@@ -2019,6 +2145,12 @@ macro rather than
.Sx \&Nm
to mark up the name of the manual page.
.Ss \&No
+A
+.Qq noop
+macro used to terminate prior macro contexts.
+.Pp
+Examples:
+.D1 \&.Sx \&Fl ab \&No cd \&Fl ef
.Ss \&Ns
.Ss \&Nx
Format the NetBSD version provided as an argument, or a default value if
@@ -2038,8 +2170,30 @@ See also
and
.Sx \&Ux .
.Ss \&Oc
+Closes multi-line
+.Sx \&Oo
+context.
.Ss \&Oo
+Multi-line version of
+.Sx \&Op .
+.Pp
+Examples:
+.Bd -literal -offset indent
+\&.Oo
+\&.Op Fl flag Ns Ar value
+\&.Oc
+.Ed
.Ss \&Op
+Command-line option.
+Used when listing options to command-line utilities.
+Prints the argument(s) in brackets.
+.Pp
+Examples:
+.D1 \&.Op \&Fl a \&Ar b
+.D1 \&.Op \&Ar a | b
+.Pp
+See also
+.Sx \&Oo .
.Ss \&Os
Document operating system version.
This is the mandatory third macro of
@@ -2088,11 +2242,43 @@ See also
and
.Sx \&Ux .
.Ss \&Pa
+A file-system path.
+.Pp
+Examples:
+.D1 \&.Pa /usr/bin/mandoc
+.D1 \&.Pa /usr/share/man/man7/mdoc.7
+.Pp
+See also
+.Sx \&Lk .
.Ss \&Pc
+Close parenthesised context opened by
+.Sx \&Po .
.Ss \&Pf
+Removes the space
+.Pq Qq prefix
+between its arguments.
+Its syntax is as follows:
+.Pp
+.D1 Pf \. \&Pf Cm prefix suffix
+.Pp
+The
+.Cm suffix
+argument may be a macro.
+.Pp
+Examples:
+.D1 \&.Pf \e. \&Sx \&Pf \&Cm prefix suffix
.Ss \&Po
+Multi-line version of
+.Sx \&Pq .
.Ss \&Pp
+Break a paragraph.
+This will assert vertical space between prior and subsequent macros
+and/or text.
.Ss \&Pq
+Parenthesised enclosure.
+.Pp
+See also
+.Sx \&Po .
.Ss \&Qc
.Ss \&Ql
.Ss \&Qo
@@ -2173,6 +2359,11 @@ See also
and
.Sx \&Ox .
.Ss \&Va
+A variable name.
+.Pp
+Examples:
+.D1 \&.Va foo
+.D1 \&.Va const char *bar ;
.Ss \&Vt
A variable type.
This is also used for indicating global variables in the
@@ -2330,9 +2521,9 @@ Display offsets
and
.Fl offset Ar right
are disregarded in mandoc.
-Furthermore, the
+Furthermore, troff specifies a
.Fl file Ar file
-argument is not supported in mandoc.
+argument that is not supported in mandoc.
Lastly, since text is not right-justified in mandoc (or even groff),
.Fl ragged
and
diff --git a/usr.bin/mandoc/mdoc.c b/usr.bin/mandoc/mdoc.c
index f32708f770c..1debb670eaf 100644
--- a/usr.bin/mandoc/mdoc.c
+++ b/usr.bin/mandoc/mdoc.c
@@ -1,6 +1,7 @@
-/* $Id: mdoc.c,v 1.60 2010/07/01 22:31:52 schwarze Exp $ */
+/* $Id: mdoc.c,v 1.61 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -25,7 +26,6 @@
#include <time.h>
#include "mandoc.h"
-#include "regs.h"
#include "libmdoc.h"
#include "libmandoc.h"
@@ -510,10 +510,26 @@ mdoc_word_alloc(struct mdoc *m, int line, int pos, const char *p)
}
-void
+static void
mdoc_node_free(struct mdoc_node *p)
{
+ /*
+ * XXX: if these end up being problematic in terms of memory
+ * management and dereferencing freed blocks, then make them
+ * into reference-counted double-pointers.
+ */
+
+ if (MDOC_Bd == p->tok && MDOC_BLOCK == p->type)
+ if (p->data.Bd)
+ free(p->data.Bd);
+ if (MDOC_Bl == p->tok && MDOC_BLOCK == p->type)
+ if (p->data.Bl)
+ free(p->data.Bl);
+ if (MDOC_Bf == p->tok && MDOC_HEAD == p->type)
+ if (p->data.Bf)
+ free(p->data.Bf);
+
if (p->string)
free(p->string);
if (p->args)
@@ -606,7 +622,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
*/
if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
- LIST_column == n->data.Bl.type) {
+ LIST_column == n->data.Bl->type) {
/* `Bl' is open without any children. */
m->flags |= MDOC_FREECOL;
return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
@@ -615,7 +631,7 @@ mdoc_ptext(struct mdoc *m, int line, char *buf, int offs)
if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
NULL != n->parent &&
MDOC_Bl == n->parent->tok &&
- LIST_column == n->parent->data.Bl.type) {
+ LIST_column == n->parent->data.Bl->type) {
/* `Bl' has block-level `It' children. */
m->flags |= MDOC_FREECOL;
return(mdoc_macro(m, MDOC_It, line, offs, &offs, buf));
@@ -727,7 +743,7 @@ macrowarn(struct mdoc *m, int ln, const char *buf, int offs)
* Parse a macro line, that is, a line beginning with the control
* character.
*/
-int
+static int
mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
{
enum mdoct tok;
@@ -821,7 +837,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
*/
if (MDOC_Bl == n->tok && MDOC_BODY == n->type &&
- LIST_column == n->data.Bl.type) {
+ LIST_column == n->data.Bl->type) {
m->flags |= MDOC_FREECOL;
if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
goto err;
@@ -837,7 +853,7 @@ mdoc_pmacro(struct mdoc *m, int ln, char *buf, int offs)
if (MDOC_It == n->tok && MDOC_BLOCK == n->type &&
NULL != n->parent &&
MDOC_Bl == n->parent->tok &&
- LIST_column == n->parent->data.Bl.type) {
+ LIST_column == n->parent->data.Bl->type) {
m->flags |= MDOC_FREECOL;
if ( ! mdoc_macro(m, MDOC_It, ln, sv, &sv, buf))
goto err;
diff --git a/usr.bin/mandoc/mdoc.h b/usr.bin/mandoc/mdoc.h
index f1d430170da..738db7976ef 100644
--- a/usr.bin/mandoc/mdoc.h
+++ b/usr.bin/mandoc/mdoc.h
@@ -1,6 +1,6 @@
-/* $Id: mdoc.h,v 1.30 2010/06/29 17:10:29 schwarze Exp $ */
+/* $Id: mdoc.h,v 1.31 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 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
@@ -252,7 +252,7 @@ struct mdoc_arg {
enum mdoc_endbody {
ENDBODY_NOT = 0,
ENDBODY_SPACE,
- ENDBODY_NOSPACE,
+ ENDBODY_NOSPACE
};
enum mdoc_list {
@@ -279,6 +279,19 @@ enum mdoc_disp {
DISP_literal
};
+enum mdoc_auth {
+ AUTH__NONE = 0,
+ AUTH_split,
+ AUTH_nosplit
+};
+
+enum mdoc_font {
+ FONT__NONE = 0,
+ FONT_Em,
+ FONT_Li,
+ FONT_Sy
+};
+
struct mdoc_bd {
const char *offs; /* -offset */
enum mdoc_disp type; /* -ragged, etc. */
@@ -290,6 +303,16 @@ struct mdoc_bl {
const char *offs; /* -offset */
enum mdoc_list type; /* -tag, -enum, etc. */
int comp; /* -compact */
+ size_t ncols; /* -column arg count */
+ const char **cols; /* -column val ptr */
+};
+
+struct mdoc_bf {
+ enum mdoc_font font; /* font */
+};
+
+struct mdoc_an {
+ enum mdoc_auth auth; /* -split, etc. */
};
/* Node in AST. */
@@ -321,8 +344,10 @@ struct mdoc_node {
enum mdoc_endbody end; /* BODY */
union {
- struct mdoc_bl Bl;
- struct mdoc_bd Bd;
+ struct mdoc_an An;
+ struct mdoc_bd *Bd;
+ struct mdoc_bf *Bf;
+ struct mdoc_bl *Bl;
} data;
};
diff --git a/usr.bin/mandoc/mdoc_action.c b/usr.bin/mandoc/mdoc_action.c
index 6ce87d3ef2f..d6abb75fcc4 100644
--- a/usr.bin/mandoc/mdoc_action.c
+++ b/usr.bin/mandoc/mdoc_action.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_action.c,v 1.42 2010/07/01 22:31:52 schwarze Exp $ */
+/* $Id: mdoc_action.c,v 1.43 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 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
@@ -28,6 +28,11 @@
#include "libmdoc.h"
#include "libmandoc.h"
+/*
+ * FIXME: this file is deprecated. All future "actions" should be
+ * pushed into mdoc_validate.c.
+ */
+
#define POST_ARGS struct mdoc *m, struct mdoc_node *n
#define PRE_ARGS struct mdoc *m, struct mdoc_node *n
@@ -687,7 +692,7 @@ post_bl_tagwidth(POST_ARGS)
n->args->argv[i].value[0] = mandoc_strdup(buf);
/* Set our width! */
- n->data.Bl.width = n->args->argv[i].value[0];
+ n->data.Bl->width = n->args->argv[i].value[0];
return(1);
}
@@ -710,9 +715,9 @@ post_bl_width(POST_ARGS)
* the macro's width as set in share/tmac/mdoc/doc-common.
*/
- if (0 == strcmp(n->data.Bl.width, "Ds"))
+ if (0 == strcmp(n->data.Bl->width, "Ds"))
width = 6;
- else if (MDOC_MAX == (tok = mdoc_hash_find(n->data.Bl.width)))
+ else if (MDOC_MAX == (tok = mdoc_hash_find(n->data.Bl->width)))
return(1);
else if (0 == (width = mdoc_macro2len(tok)))
return(mdoc_nmsg(m, n, MANDOCERR_BADWIDTH));
@@ -732,7 +737,7 @@ post_bl_width(POST_ARGS)
n->args->argv[i].value[0] = mandoc_strdup(buf);
/* Set our width! */
- n->data.Bl.width = n->args->argv[i].value[0];
+ n->data.Bl->width = n->args->argv[i].value[0];
return(1);
}
@@ -748,7 +753,7 @@ post_bl_head(POST_ARGS)
int i, c;
struct mdoc_node *np, *nn, *nnp;
- if (LIST_column != n->data.Bl.type)
+ if (LIST_column != n->data.Bl->type)
return(1);
else if (NULL == n->child)
return(1);
@@ -773,6 +778,9 @@ post_bl_head(POST_ARGS)
np->args->argv[c].value = mandoc_malloc
((size_t)n->nchild * sizeof(char *));
+ n->data.Bl->ncols = np->args->argv[c].sz;
+ n->data.Bl->cols = (const char **)np->args->argv[c].value;
+
for (i = 0, nn = n->child; nn; i++) {
np->args->argv[c].value[i] = nn->string;
nn->string = NULL;
@@ -790,8 +798,6 @@ post_bl_head(POST_ARGS)
static int
post_bl(POST_ARGS)
{
- struct mdoc_node *nn;
- const char *ww;
if (MDOC_HEAD == n->type)
return(post_bl_head(m, n));
@@ -806,28 +812,16 @@ post_bl(POST_ARGS)
* rewritten into real lengths).
*/
- ww = n->data.Bl.width;
-
- if (LIST_tag == n->data.Bl.type && NULL == n->data.Bl.width) {
+ if (LIST_tag == n->data.Bl->type && NULL == n->data.Bl->width) {
if ( ! post_bl_tagwidth(m, n))
return(0);
- } else if (NULL != n->data.Bl.width) {
+ } else if (NULL != n->data.Bl->width) {
if ( ! post_bl_width(m, n))
return(0);
} else
return(1);
- assert(n->data.Bl.width);
-
- /* If it has changed, propogate new width to children. */
-
- if (ww == n->data.Bl.width)
- return(1);
-
- for (nn = n->child; nn; nn = nn->next)
- if (MDOC_Bl == nn->tok)
- nn->data.Bl.width = n->data.Bl.width;
-
+ assert(n->data.Bl->width);
return(1);
}
@@ -958,9 +952,10 @@ pre_bd(PRE_ARGS)
if (MDOC_BODY != n->type)
return(1);
- if (DISP_literal == n->data.Bd.type)
+ assert(n->data.Bd);
+ if (DISP_literal == n->data.Bd->type)
m->flags |= MDOC_LITERAL;
- if (DISP_unfilled == n->data.Bd.type)
+ if (DISP_unfilled == n->data.Bd->type)
m->flags |= MDOC_LITERAL;
return(1);
diff --git a/usr.bin/mandoc/mdoc_argv.c b/usr.bin/mandoc/mdoc_argv.c
index a556aa1d768..61d5dbbce58 100644
--- a/usr.bin/mandoc/mdoc_argv.c
+++ b/usr.bin/mandoc/mdoc_argv.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_argv.c,v 1.31 2010/06/26 17:56:43 schwarze Exp $ */
+/* $Id: mdoc_argv.c,v 1.32 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 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
@@ -355,7 +355,8 @@ mdoc_args(struct mdoc *m, int line, int *pos,
if (MDOC_Bl == n->tok)
break;
- if (n && LIST_column == n->data.Bl.type) {
+ assert(n->data.Bl);
+ if (n && LIST_column == n->data.Bl->type) {
fl |= ARGS_TABSEP;
fl &= ~ARGS_DELIM;
}
diff --git a/usr.bin/mandoc/mdoc_html.c b/usr.bin/mandoc/mdoc_html.c
index 60e257c2078..b088164f931 100644
--- a/usr.bin/mandoc/mdoc_html.c
+++ b/usr.bin/mandoc/mdoc_html.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_html.c,v 1.24 2010/06/29 17:10:29 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.25 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 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
@@ -26,7 +26,6 @@
#include "mandoc.h"
#include "out.h"
#include "html.h"
-#include "regs.h"
#include "mdoc.h"
#include "main.h"
@@ -69,6 +68,8 @@ static int mdoc_aq_pre(MDOC_ARGS);
static int mdoc_ar_pre(MDOC_ARGS);
static int mdoc_bd_pre(MDOC_ARGS);
static int mdoc_bf_pre(MDOC_ARGS);
+static void mdoc_bk_post(MDOC_ARGS);
+static int mdoc_bk_pre(MDOC_ARGS);
static void mdoc_bl_post(MDOC_ARGS);
static int mdoc_bl_pre(MDOC_ARGS);
static void mdoc_bq_post(MDOC_ARGS);
@@ -233,7 +234,7 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = {
{NULL, NULL}, /* Fc */
{mdoc_op_pre, mdoc_op_post}, /* Oo */
{NULL, NULL}, /* Oc */
- {NULL, NULL}, /* Bk */
+ {mdoc_bk_pre, mdoc_bk_post}, /* Bk */
{NULL, NULL}, /* Ek */
{mdoc_bt_pre, NULL}, /* Bt */
{NULL, NULL}, /* Hf */
@@ -433,11 +434,23 @@ print_mdoc_node(MDOC_ARGS)
print_text(h, n->string);
return;
default:
- if (mdocs[n->tok].pre && !n->end)
+ if (mdocs[n->tok].pre && ENDBODY_NOT == n->end)
child = (*mdocs[n->tok].pre)(m, n, h);
break;
}
+ if (HTML_KEEP & h->flags) {
+ if (n->prev && n->prev->line != n->line) {
+ h->flags &= ~HTML_KEEP;
+ h->flags |= HTML_PREKEEP;
+ } else if (NULL == n->prev) {
+ if (n->parent && n->parent->line != n->line) {
+ h->flags &= ~HTML_KEEP;
+ h->flags |= HTML_PREKEEP;
+ }
+ }
+ }
+
if (child && n->child)
print_mdoc_nodelist(m, n->child, h);
@@ -449,7 +462,7 @@ print_mdoc_node(MDOC_ARGS)
mdoc_root_post(m, n, h);
break;
default:
- if (mdocs[n->tok].post && !n->end)
+ if (mdocs[n->tok].post && ENDBODY_NOT == n->end)
(*mdocs[n->tok].post)(m, n, h);
break;
}
@@ -732,17 +745,70 @@ mdoc_op_post(MDOC_ARGS)
static int
mdoc_nm_pre(MDOC_ARGS)
{
- struct htmlpair tag;
+ struct htmlpair tag;
+ struct roffsu su;
+ const char *cp;
- if (NULL == n->child && NULL == m->name)
- return(1);
+ /*
+ * Accomodate for `Nm' being both an element (which may have
+ * NULL children AND no m->name) and a block.
+ */
- synopsis_pre(h, n);
+ cp = NULL;
+
+ if (MDOC_ELEM == n->type) {
+ if (NULL == n->child && NULL == m->name)
+ return(1);
+ synopsis_pre(h, n);
+ PAIR_CLASS_INIT(&tag, "name");
+ print_otag(h, TAG_SPAN, 1, &tag);
+ if (NULL == n->child)
+ print_text(h, m->name);
+ } else if (MDOC_BLOCK == n->type) {
+ synopsis_pre(h, n);
+
+ bufcat_style(h, "clear", "both");
+ if (n->head->child || m->name) {
+ if (n->head->child && MDOC_TEXT ==
+ n->head->child->type)
+ cp = n->head->child->string;
+ if (NULL == cp || '\0' == *cp)
+ cp = m->name;
+
+ SCALE_HS_INIT(&su, (double)strlen(cp));
+ bufcat_su(h, "padding-left", &su);
+ }
+
+ PAIR_STYLE_INIT(&tag, h);
+ print_otag(h, TAG_DIV, 1, &tag);
+ } else if (MDOC_HEAD == n->type) {
+ if (NULL == n->child && NULL == m->name)
+ return(1);
+
+ if (n->child && MDOC_TEXT == n->child->type)
+ cp = n->child->string;
+ if (NULL == cp || '\0' == *cp)
+ cp = m->name;
+
+ SCALE_HS_INIT(&su, (double)strlen(cp));
+
+ bufcat_style(h, "float", "left");
+ bufcat_su(h, "min-width", &su);
+ SCALE_INVERT(&su);
+ bufcat_su(h, "margin-left", &su);
+
+ PAIR_STYLE_INIT(&tag, h);
+ print_otag(h, TAG_DIV, 1, &tag);
+
+ if (NULL == n->child)
+ print_text(h, m->name);
+ } else if (MDOC_BODY == n->type) {
+ SCALE_HS_INIT(&su, 2);
+ bufcat_su(h, "margin-left", &su);
+ PAIR_STYLE_INIT(&tag, h);
+ print_otag(h, TAG_DIV, 1, &tag);
+ }
- PAIR_CLASS_INIT(&tag, "name");
- print_otag(h, TAG_SPAN, 1, &tag);
- if (NULL == n->child)
- print_text(h, m->name);
return(1);
}
@@ -1017,7 +1083,7 @@ mdoc_it_head_pre(MDOC_ARGS, enum mdoc_list type, struct roffsu *width)
static int
mdoc_it_pre(MDOC_ARGS)
{
- int i, wp, comp;
+ int i, comp;
const struct mdoc_node *bl, *nn;
struct roffsu width, offs;
enum mdoc_list type;
@@ -1034,11 +1100,12 @@ mdoc_it_pre(MDOC_ARGS)
SCALE_HS_INIT(&offs, 0);
- type = bl->data.Bl.type;
- comp = bl->data.Bl.comp;
+ assert(bl->data.Bl);
+ type = bl->data.Bl->type;
+ comp = bl->data.Bl->comp;
- if (bl->data.Bl.offs)
- a2offs(bl->data.Bl.offs, &offs);
+ if (bl->data.Bl->offs)
+ a2offs(bl->data.Bl->offs, &offs);
switch (type) {
case (LIST_enum):
@@ -1055,18 +1122,8 @@ mdoc_it_pre(MDOC_ARGS)
break;
}
- if (bl->data.Bl.width)
- a2width(bl->data.Bl.width, &width);
-
- wp = -1;
- for (i = 0; bl->args && i < (int)bl->args->argc; i++)
- switch (bl->args->argv[i].arg) {
- case (MDOC_Column):
- wp = i; /* Save for later. */
- break;
- default:
- break;
- }
+ if (bl->data.Bl->width)
+ a2width(bl->data.Bl->width, &width);
/* Override width in some cases. */
@@ -1091,8 +1148,8 @@ mdoc_it_pre(MDOC_ARGS)
for (i = 0; nn && nn != n; nn = nn->next)
if (MDOC_BODY == nn->type)
i++;
- if (i < (int)bl->args->argv[wp].sz)
- a2width(bl->args->argv[wp].value[i], &width);
+ if (i < (int)bl->data.Bl->ncols)
+ a2width(bl->data.Bl->cols[i], &width);
}
if (MDOC_HEAD == n->type)
@@ -1114,7 +1171,8 @@ mdoc_bl_pre(MDOC_ARGS)
return(0);
if (MDOC_BLOCK != n->type)
return(1);
- if (LIST_enum != n->data.Bl.type)
+ assert(n->data.Bl);
+ if (LIST_enum != n->data.Bl->type)
return(1);
ord = malloc(sizeof(struct ord));
@@ -1138,7 +1196,7 @@ mdoc_bl_post(MDOC_ARGS)
if (MDOC_BLOCK != n->type)
return;
- if (LIST_enum != n->data.Bl.type)
+ if (LIST_enum != n->data.Bl->type)
return;
ord = h->ords.head;
@@ -1353,10 +1411,11 @@ mdoc_bd_pre(MDOC_ARGS)
SCALE_VS_INIT(&su, 0);
- if (n->data.Bd.offs)
- a2offs(n->data.Bd.offs, &su);
+ assert(n->data.Bd);
+ if (n->data.Bd->offs)
+ a2offs(n->data.Bd->offs, &su);
- comp = n->data.Bd.comp;
+ comp = n->data.Bd->comp;
/* FIXME: -centered, etc. formatting. */
/* FIXME: does not respect -offset ??? */
@@ -1383,8 +1442,8 @@ mdoc_bd_pre(MDOC_ARGS)
return(1);
}
- if (DISP_unfilled != n->data.Bd.type &&
- DISP_literal != n->data.Bd.type)
+ if (DISP_unfilled != n->data.Bd->type &&
+ DISP_literal != n->data.Bd->type)
return(1);
PAIR_CLASS_INIT(&tag[0], "lit");
@@ -1955,46 +2014,33 @@ mdoc_ap_pre(MDOC_ARGS)
static int
mdoc_bf_pre(MDOC_ARGS)
{
- int i;
struct htmlpair tag[2];
struct roffsu su;
if (MDOC_HEAD == n->type)
return(0);
- else if (MDOC_BLOCK != n->type)
+ else if (MDOC_BODY != n->type)
return(1);
- PAIR_CLASS_INIT(&tag[0], "lit");
-
- if (n->head->child) {
- if ( ! strcmp("Em", n->head->child->string))
- PAIR_CLASS_INIT(&tag[0], "emph");
- else if ( ! strcmp("Sy", n->head->child->string))
- PAIR_CLASS_INIT(&tag[0], "symb");
- else if ( ! strcmp("Li", n->head->child->string))
- PAIR_CLASS_INIT(&tag[0], "lit");
- } else {
- for (i = 0; n->args && i < (int)n->args->argc; i++)
- switch (n->args->argv[i].arg) {
- case (MDOC_Symbolic):
- PAIR_CLASS_INIT(&tag[0], "symb");
- break;
- case (MDOC_Literal):
- PAIR_CLASS_INIT(&tag[0], "lit");
- break;
- case (MDOC_Emphasis):
- PAIR_CLASS_INIT(&tag[0], "emph");
- break;
- default:
- break;
- }
- }
+ assert(n->data.Bf);
- /* FIXME: div's have spaces stripped--we want them. */
+ if (FONT_Em == n->data.Bf->font)
+ PAIR_CLASS_INIT(&tag[0], "emph");
+ else if (FONT_Sy == n->data.Bf->font)
+ PAIR_CLASS_INIT(&tag[0], "symb");
+ else if (FONT_Li == n->data.Bf->font)
+ PAIR_CLASS_INIT(&tag[0], "lit");
+ else
+ PAIR_CLASS_INIT(&tag[0], "none");
+ /*
+ * We want this to be inline-formatted, but needs to be div to
+ * accept block children.
+ */
bufcat_style(h, "display", "inline");
SCALE_HS_INIT(&su, 1);
- bufcat_su(h, "margin-right", &su);
+ /* Needs a left-margin for spacing. */
+ bufcat_su(h, "margin-left", &su);
PAIR_STYLE_INIT(&tag[1], h);
print_otag(h, TAG_DIV, 2, tag);
return(1);
@@ -2190,3 +2236,35 @@ mdoc__x_post(MDOC_ARGS)
h->flags |= HTML_NOSPACE;
print_text(h, n->next ? "," : ".");
}
+
+
+/* ARGSUSED */
+static int
+mdoc_bk_pre(MDOC_ARGS)
+{
+
+ switch (n->type) {
+ case (MDOC_BLOCK):
+ break;
+ case (MDOC_HEAD):
+ return(0);
+ case (MDOC_BODY):
+ h->flags |= HTML_PREKEEP;
+ break;
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+
+ return(1);
+}
+
+
+/* ARGSUSED */
+static void
+mdoc_bk_post(MDOC_ARGS)
+{
+
+ if (MDOC_BODY == n->type)
+ h->flags &= ~(HTML_KEEP | HTML_PREKEEP);
+}
diff --git a/usr.bin/mandoc/mdoc_macro.c b/usr.bin/mandoc/mdoc_macro.c
index acaee57329e..c145394864b 100644
--- a/usr.bin/mandoc/mdoc_macro.c
+++ b/usr.bin/mandoc/mdoc_macro.c
@@ -1,6 +1,7 @@
-/* $Id: mdoc_macro.c,v 1.53 2010/07/01 22:31:52 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.54 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -30,7 +31,7 @@ enum rew { /* see rew_dohalt() */
REWIND_THIS,
REWIND_MORE,
REWIND_LATER,
- REWIND_ERROR,
+ REWIND_ERROR
};
static int blk_full(MACRO_PROT_ARGS);
@@ -410,7 +411,7 @@ rew_dohalt(enum mdoct tok, enum mdoc_type type,
* In particular, always skip block end markers,
* and let all blocks rewind Nm children.
*/
- if (p->end || MDOC_Nm == p->tok ||
+ if (ENDBODY_NOT != p->end || MDOC_Nm == p->tok ||
(MDOC_BLOCK == p->type &&
! (MDOC_EXPLICIT & mdoc_macros[tok].flags)))
return(REWIND_MORE);
@@ -566,6 +567,7 @@ rew_sub(enum mdoc_type t, struct mdoc *m,
! mdoc_body_alloc(m, n->line, n->pos, n->tok))
return(0);
}
+
return(1);
}
@@ -650,7 +652,7 @@ blk_exp_close(MACRO_PROT_ARGS)
/* Remember the start of our own body. */
if (MDOC_BODY == n->type && atok == n->tok) {
- if ( ! n->end)
+ if (ENDBODY_NOT == n->end)
body = n;
continue;
}
@@ -1146,6 +1148,7 @@ blk_full(MACRO_PROT_ARGS)
return(1);
}
}
+
/* Close out scopes to remain in a consistent state. */
if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
diff --git a/usr.bin/mandoc/mdoc_term.c b/usr.bin/mandoc/mdoc_term.c
index 90c6fde3ba7..acb170d2382 100644
--- a/usr.bin/mandoc/mdoc_term.c
+++ b/usr.bin/mandoc/mdoc_term.c
@@ -1,6 +1,7 @@
-/* $Id: mdoc_term.c,v 1.94 2010/07/01 15:36:59 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.95 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -26,7 +27,6 @@
#include "mandoc.h"
#include "out.h"
#include "term.h"
-#include "regs.h"
#include "mdoc.h"
#include "chars.h"
#include "main.h"
@@ -53,8 +53,6 @@ static size_t a2width(const struct termp *, const char *);
static size_t a2height(const struct termp *, const char *);
static size_t a2offs(const struct termp *, const char *);
-static int arg_hasattr(int, const struct mdoc_node *);
-static int arg_getattr(int, const struct mdoc_node *);
static void print_bvspace(struct termp *,
const struct mdoc_node *,
const struct mdoc_node *);
@@ -324,25 +322,41 @@ print_mdoc_node(DECL_ARGS)
if (MDOC_TEXT == n->type)
term_word(p, n->string);
- else if (termacts[n->tok].pre && !n->end)
+ else if (termacts[n->tok].pre && ENDBODY_NOT == n->end)
chld = (*termacts[n->tok].pre)(p, &npair, m, n);
+ /*
+ * Keeps only work until the end of a line. If a keep was
+ * invoked in a prior line, revert it to PREKEEP.
+ */
+
+ if (TERMP_KEEP & p->flags) {
+ if (n->prev && n->prev->line != n->line) {
+ p->flags &= ~TERMP_KEEP;
+ p->flags |= TERMP_PREKEEP;
+ } else if (NULL == n->prev) {
+ if (n->parent && n->parent->line != n->line) {
+ p->flags &= ~TERMP_KEEP;
+ p->flags |= TERMP_PREKEEP;
+ }
+ }
+ }
+
if (chld && n->child)
print_mdoc_nodelist(p, &npair, m, n->child);
term_fontpopq(p, font);
- if (MDOC_TEXT != n->type &&
- termacts[n->tok].post &&
- ! (MDOC_ENDED & n->flags)) {
- (*termacts[n->tok].post)(p, &npair, m, n);
+ if (MDOC_TEXT != n->type && termacts[n->tok].post &&
+ ! (MDOC_ENDED & n->flags)) {
+ (void)(*termacts[n->tok].post)(p, &npair, m, n);
/*
* Explicit end tokens not only call the post
* handler, but also tell the respective block
* that it must not call the post handler again.
*/
- if (n->end)
+ if (ENDBODY_NOT != n->end)
n->pending->flags |= MDOC_ENDED;
/*
@@ -525,38 +539,6 @@ a2offs(const struct termp *p, const char *v)
/*
- * 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)
-{
-
- return(-1 != arg_getattr(arg, n));
-}
-
-
-/*
- * Get the index of an argument in a node's argument list or -1 if it
- * does not exist.
- */
-static int
-arg_getattr(int v, const struct mdoc_node *n)
-{
- int i;
-
- if (NULL == n->args)
- return(0);
-
- for (i = 0; i < (int)n->args->argc; i++)
- if (n->args->argv[i].arg == v)
- return(i);
-
- return(-1);
-}
-
-
-/*
* 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.
@@ -570,9 +552,9 @@ print_bvspace(struct termp *p,
term_newln(p);
- if (MDOC_Bd == bl->tok && bl->data.Bd.comp)
+ if (MDOC_Bd == bl->tok && bl->data.Bd->comp)
return;
- if (MDOC_Bl == bl->tok && bl->data.Bl.comp)
+ if (MDOC_Bl == bl->tok && bl->data.Bl->comp)
return;
/* Do not vspace directly after Ss/Sh. */
@@ -591,13 +573,13 @@ print_bvspace(struct termp *p,
/* A `-column' does not assert vspace within the list. */
- if (MDOC_Bl == bl->tok && LIST_column == bl->data.Bl.type)
+ if (MDOC_Bl == bl->tok && LIST_column == bl->data.Bl->type)
if (n->prev && MDOC_It == n->prev->tok)
return;
/* A `-diag' without body does not vspace. */
- if (MDOC_Bl == bl->tok && LIST_diag == bl->data.Bl.type)
+ if (MDOC_Bl == bl->tok && LIST_diag == bl->data.Bl->type)
if (n->prev && MDOC_It == n->prev->tok) {
assert(n->prev->body);
if (NULL == n->prev->body->child)
@@ -641,7 +623,7 @@ termp_it_pre(DECL_ARGS)
{
const struct mdoc_node *bl, *nn;
char buf[7];
- int i, col;
+ int i;
size_t width, offset, ncols, dcol;
enum mdoc_list type;
@@ -651,7 +633,8 @@ termp_it_pre(DECL_ARGS)
}
bl = n->parent->parent->parent;
- type = bl->data.Bl.type;
+ assert(bl->data.Bl);
+ type = bl->data.Bl->type;
/*
* First calculate width and offset. This is pretty easy unless
@@ -661,16 +644,14 @@ termp_it_pre(DECL_ARGS)
width = offset = 0;
- if (bl->data.Bl.offs)
- offset = a2offs(p, bl->data.Bl.offs);
+ if (bl->data.Bl->offs)
+ offset = a2offs(p, bl->data.Bl->offs);
switch (type) {
case (LIST_column):
if (MDOC_HEAD == n->type)
break;
- col = arg_getattr(MDOC_Column, bl);
-
/*
* Imitate groff's column handling:
* - For each earlier column, add its width.
@@ -680,7 +661,8 @@ termp_it_pre(DECL_ARGS)
* column.
* - For more than 5 columns, add only one column.
*/
- ncols = bl->args->argv[col].sz;
+ ncols = bl->data.Bl->ncols;
+
/* LINTED */
dcol = ncols < 5 ? term_len(p, 4) :
ncols == 5 ? term_len(p, 3) : term_len(p, 1);
@@ -694,7 +676,7 @@ termp_it_pre(DECL_ARGS)
nn->prev && i < (int)ncols;
nn = nn->prev, i++)
offset += dcol + a2width
- (p, bl->args->argv[col].value[i]);
+ (p, bl->data.Bl->cols[i]);
/*
* When exceeding the declared number of columns, leave
@@ -709,10 +691,10 @@ termp_it_pre(DECL_ARGS)
* Use the declared column widths, extended as explained
* in the preceding paragraph.
*/
- width = a2width(p, bl->args->argv[col].value[i]) + dcol;
+ width = a2width(p, bl->data.Bl->cols[i]) + dcol;
break;
default:
- if (NULL == bl->data.Bl.width)
+ if (NULL == bl->data.Bl->width)
break;
/*
@@ -720,8 +702,8 @@ termp_it_pre(DECL_ARGS)
* number for buffering single arguments. See the above
* handling for column for how this changes.
*/
- assert(bl->data.Bl.width);
- width = a2width(p, bl->data.Bl.width) + term_len(p, 2);
+ assert(bl->data.Bl->width);
+ width = a2width(p, bl->data.Bl->width) + term_len(p, 2);
break;
}
@@ -983,7 +965,7 @@ termp_it_post(DECL_ARGS)
if (MDOC_BLOCK == n->type)
return;
- type = n->parent->parent->parent->data.Bl.type;
+ type = n->parent->parent->parent->data.Bl->type;
switch (type) {
case (LIST_item):
@@ -1137,10 +1119,10 @@ termp_an_post(DECL_ARGS)
return;
}
- if (arg_hasattr(MDOC_Split, n)) {
+ if (AUTH_split == n->data.An.auth) {
p->flags &= ~TERMP_NOSPLIT;
p->flags |= TERMP_SPLIT;
- } else {
+ } else if (AUTH_nosplit == n->data.An.auth) {
p->flags &= ~TERMP_SPLIT;
p->flags |= TERMP_NOSPLIT;
}
@@ -1644,8 +1626,9 @@ termp_bd_pre(DECL_ARGS)
} else if (MDOC_HEAD == n->type)
return(0);
- if (n->data.Bd.offs)
- p->offset += a2offs(p, n->data.Bd.offs);
+ assert(n->data.Bd);
+ if (n->data.Bd->offs)
+ p->offset += a2offs(p, n->data.Bd->offs);
/*
* If -ragged or -filled are specified, the block does nothing
@@ -1655,8 +1638,8 @@ termp_bd_pre(DECL_ARGS)
* lines are allowed.
*/
- if (DISP_literal != n->data.Bd.type &&
- DISP_unfilled != n->data.Bd.type)
+ if (DISP_literal != n->data.Bd->type &&
+ DISP_unfilled != n->data.Bd->type)
return(1);
tabwidth = p->tabwidth;
@@ -1693,8 +1676,9 @@ termp_bd_post(DECL_ARGS)
rm = p->rmargin;
rmax = p->maxrmargin;
- if (DISP_literal == n->data.Bd.type ||
- DISP_unfilled == n->data.Bd.type)
+ assert(n->data.Bd);
+ if (DISP_literal == n->data.Bd->type ||
+ DISP_unfilled == n->data.Bd->type)
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
p->flags |= TERMP_NOSPACE;
@@ -2019,9 +2003,11 @@ termp_fo_pre(DECL_ARGS)
return(1);
}
+ if (NULL == n->child)
+ return(0);
+
/* XXX: we drop non-initial arguments as per groff. */
- assert(n->child);
assert(n->child->string);
term_fontpush(p, TERMFONT_BOLD);
term_word(p, n->child->string);
@@ -2051,30 +2037,19 @@ termp_fo_post(DECL_ARGS)
static int
termp_bf_pre(DECL_ARGS)
{
- const struct mdoc_node *nn;
if (MDOC_HEAD == n->type)
return(0);
else if (MDOC_BLOCK != n->type)
return(1);
- if (NULL == (nn = n->head->child)) {
- if (arg_hasattr(MDOC_Emphasis, n))
- term_fontpush(p, TERMFONT_UNDER);
- else if (arg_hasattr(MDOC_Symbolic, n))
- term_fontpush(p, TERMFONT_BOLD);
- else
- term_fontpush(p, TERMFONT_NONE);
-
- return(1);
- }
+ assert(n->data.Bf);
- assert(MDOC_TEXT == nn->type);
- if (0 == strcmp("Em", nn->string))
+ if (FONT_Em == n->data.Bf->font)
term_fontpush(p, TERMFONT_UNDER);
- else if (0 == strcmp("Sy", nn->string))
+ else if (FONT_Sy == n->data.Bf->font)
term_fontpush(p, TERMFONT_BOLD);
- else
+ else
term_fontpush(p, TERMFONT_NONE);
return(1);
@@ -2164,15 +2139,18 @@ termp_bk_pre(DECL_ARGS)
switch (n->type) {
case (MDOC_BLOCK):
- return(1);
+ break;
case (MDOC_HEAD):
return(0);
case (MDOC_BODY):
p->flags |= TERMP_PREKEEP;
- return(1);
+ break;
default:
abort();
+ /* NOTREACHED */
}
+
+ return(1);
}
diff --git a/usr.bin/mandoc/mdoc_validate.c b/usr.bin/mandoc/mdoc_validate.c
index bdd143a3ff2..2b1fc088bf7 100644
--- a/usr.bin/mandoc/mdoc_validate.c
+++ b/usr.bin/mandoc/mdoc_validate.c
@@ -1,6 +1,6 @@
-/* $Id: mdoc_validate.c,v 1.64 2010/07/02 17:41:05 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.65 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 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
@@ -150,7 +150,7 @@ const struct valids mdoc_valids[MDOC_MAX] = {
{ NULL, posts_notext }, /* Pp */
{ pres_d1, posts_wline }, /* D1 */
{ pres_d1, posts_wline }, /* Dl */
- { pres_bd, posts_bd_bk }, /* Bd */
+ { pres_bd, posts_bd_bk }, /* Bd */
{ NULL, NULL }, /* Ed */
{ pres_bl, posts_bl }, /* Bl */
{ NULL, NULL }, /* El */
@@ -454,6 +454,11 @@ check_text(struct mdoc *mdoc, int line, int pos, char *p)
{
int c;
+ /*
+ * FIXME: we absolutely cannot let \b get through or it will
+ * destroy some assumptions in terms of format.
+ */
+
for ( ; *p; p++, pos++) {
if ('\t' == *p) {
if ( ! (MDOC_LITERAL & mdoc->flags))
@@ -528,17 +533,23 @@ pre_display(PRE_ARGS)
static int
pre_bl(PRE_ARGS)
{
- int i, comp, dup;
- const char *offs, *width;
- enum mdoc_list lt;
+ int i, comp, dup;
+ const char *offs, *width;
+ enum mdoc_list lt;
+ struct mdoc_node *np;
if (MDOC_BLOCK != n->type) {
- assert(n->parent);
- assert(MDOC_BLOCK == n->parent->type);
- assert(MDOC_Bl == n->parent->tok);
- assert(LIST__NONE != n->parent->data.Bl.type);
- memcpy(&n->data.Bl, &n->parent->data.Bl,
- sizeof(struct mdoc_bl));
+ if (ENDBODY_NOT != n->end) {
+ assert(n->pending);
+ np = n->pending->parent;
+ } else
+ np = n->parent;
+
+ assert(np);
+ assert(MDOC_BLOCK == np->type);
+ assert(MDOC_Bl == np->tok);
+ assert(np->data.Bl);
+ n->data.Bl = np->data.Bl;
return(1);
}
@@ -548,7 +559,8 @@ pre_bl(PRE_ARGS)
* ones. If we find no list type, we default to LIST_item.
*/
- assert(LIST__NONE == n->data.Bl.type);
+ assert(NULL == n->data.Bl);
+ n->data.Bl = mandoc_calloc(1, sizeof(struct mdoc_bl));
/* LINTED */
for (i = 0; n->args && i < (int)n->args->argc; i++) {
@@ -592,18 +604,18 @@ pre_bl(PRE_ARGS)
break;
/* Set list arguments. */
case (MDOC_Compact):
- dup = n->data.Bl.comp;
+ dup = n->data.Bl->comp;
comp = 1;
break;
case (MDOC_Width):
- dup = (NULL != n->data.Bl.width);
+ dup = (NULL != n->data.Bl->width);
width = n->args->argv[i].value[0];
break;
case (MDOC_Offset):
/* NB: this can be empty! */
if (n->args->argv[i].sz) {
offs = n->args->argv[i].value[0];
- dup = (NULL != n->data.Bl.offs);
+ dup = (NULL != n->data.Bl->offs);
break;
}
if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV))
@@ -617,29 +629,37 @@ pre_bl(PRE_ARGS)
return(0);
if (comp && ! dup)
- n->data.Bl.comp = comp;
+ n->data.Bl->comp = comp;
if (offs && ! dup)
- n->data.Bl.offs = offs;
+ n->data.Bl->offs = offs;
if (width && ! dup)
- n->data.Bl.width = width;
+ n->data.Bl->width = width;
/* Check: multiple list types. */
- if (LIST__NONE != lt && n->data.Bl.type != LIST__NONE)
+ if (LIST__NONE != lt && n->data.Bl->type != LIST__NONE)
if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTREP))
return(0);
/* Assign list type. */
- if (LIST__NONE != lt && n->data.Bl.type == LIST__NONE)
- n->data.Bl.type = lt;
+ if (LIST__NONE != lt && n->data.Bl->type == LIST__NONE) {
+ n->data.Bl->type = lt;
+ /* Set column information, too. */
+ if (LIST_column == lt) {
+ n->data.Bl->ncols =
+ n->args->argv[i].sz;
+ n->data.Bl->cols = (const char **)
+ n->args->argv[i].value;
+ }
+ }
/* The list type should come first. */
- if (n->data.Bl.type == LIST__NONE)
- if (n->data.Bl.width ||
- n->data.Bl.offs ||
- n->data.Bl.comp)
+ if (n->data.Bl->type == LIST__NONE)
+ if (n->data.Bl->width ||
+ n->data.Bl->offs ||
+ n->data.Bl->comp)
if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTFIRST))
return(0);
@@ -648,10 +668,10 @@ pre_bl(PRE_ARGS)
/* Allow lists to default to LIST_item. */
- if (LIST__NONE == n->data.Bl.type) {
+ if (LIST__NONE == n->data.Bl->type) {
if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_LISTTYPE))
return(0);
- n->data.Bl.type = LIST_item;
+ n->data.Bl->type = LIST_item;
}
/*
@@ -660,9 +680,9 @@ pre_bl(PRE_ARGS)
* and must also be warned.
*/
- switch (n->data.Bl.type) {
+ switch (n->data.Bl->type) {
case (LIST_tag):
- if (n->data.Bl.width)
+ if (n->data.Bl->width)
break;
if (mdoc_nmsg(mdoc, n, MANDOCERR_NOWIDTHARG))
break;
@@ -676,7 +696,7 @@ pre_bl(PRE_ARGS)
case (LIST_inset):
/* FALLTHROUGH */
case (LIST_item):
- if (NULL == n->data.Bl.width)
+ if (NULL == n->data.Bl->width)
break;
if (mdoc_nmsg(mdoc, n, MANDOCERR_WIDTHARG))
break;
@@ -692,21 +712,28 @@ pre_bl(PRE_ARGS)
static int
pre_bd(PRE_ARGS)
{
- int i, dup, comp;
- enum mdoc_disp dt;
- const char *offs;
+ int i, dup, comp;
+ enum mdoc_disp dt;
+ const char *offs;
+ struct mdoc_node *np;
if (MDOC_BLOCK != n->type) {
- assert(n->parent);
- assert(MDOC_BLOCK == n->parent->type);
- assert(MDOC_Bd == n->parent->tok);
- assert(DISP__NONE != n->parent->data.Bd.type);
- memcpy(&n->data.Bd, &n->parent->data.Bd,
- sizeof(struct mdoc_bd));
+ if (ENDBODY_NOT != n->end) {
+ assert(n->pending);
+ np = n->pending->parent;
+ } else
+ np = n->parent;
+
+ assert(np);
+ assert(MDOC_BLOCK == np->type);
+ assert(MDOC_Bd == np->tok);
+ assert(np->data.Bd);
+ n->data.Bd = np->data.Bd;
return(1);
}
- assert(DISP__NONE == n->data.Bd.type);
+ assert(NULL == n->data.Bd);
+ n->data.Bd = mandoc_calloc(1, sizeof(struct mdoc_bd));
/* LINTED */
for (i = 0; n->args && i < (int)n->args->argc; i++) {
@@ -737,7 +764,7 @@ pre_bd(PRE_ARGS)
/* NB: this can be empty! */
if (n->args->argv[i].sz) {
offs = n->args->argv[i].value[0];
- dup = (NULL != n->data.Bd.offs);
+ dup = (NULL != n->data.Bd->offs);
break;
}
if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_IGNARGV))
@@ -745,7 +772,7 @@ pre_bd(PRE_ARGS)
break;
case (MDOC_Compact):
comp = 1;
- dup = n->data.Bd.comp;
+ dup = n->data.Bd->comp;
break;
default:
abort();
@@ -760,26 +787,26 @@ pre_bd(PRE_ARGS)
/* Make our auxiliary assignments. */
if (offs && ! dup)
- n->data.Bd.offs = offs;
+ n->data.Bd->offs = offs;
if (comp && ! dup)
- n->data.Bd.comp = comp;
+ n->data.Bd->comp = comp;
/* Check whether a type has already been assigned. */
- if (DISP__NONE != dt && n->data.Bd.type != DISP__NONE)
+ if (DISP__NONE != dt && n->data.Bd->type != DISP__NONE)
if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_DISPREP))
return(0);
/* Make our type assignment. */
- if (DISP__NONE != dt && n->data.Bd.type == DISP__NONE)
- n->data.Bd.type = dt;
+ if (DISP__NONE != dt && n->data.Bd->type == DISP__NONE)
+ n->data.Bd->type = dt;
}
- if (DISP__NONE == n->data.Bd.type) {
+ if (DISP__NONE == n->data.Bd->type) {
if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_DISPTYPE))
return(0);
- n->data.Bd.type = DISP_ragged;
+ n->data.Bd->type = DISP_ragged;
}
return(1);
@@ -826,13 +853,20 @@ static int
pre_an(PRE_ARGS)
{
- if (NULL == n->args || 1 == n->args->argc)
+ if (NULL == n->args)
return(1);
- mdoc_vmsg(mdoc, MANDOCERR_SYNTARGCOUNT,
- n->line, n->pos,
- "line arguments == 1 (have %d)",
- n->args->argc);
- return(0);
+ if (n->args->argc > 1)
+ if ( ! mdoc_nmsg(mdoc, n, MANDOCERR_ARGCOUNT))
+ return(0);
+
+ if (MDOC_Split == n->args->argv[0].arg)
+ n->data.An.auth = AUTH_split;
+ else if (MDOC_Nosplit == n->args->argv[0].arg)
+ n->data.An.auth = AUTH_nosplit;
+ else
+ abort();
+
+ return(1);
}
@@ -908,38 +942,74 @@ pre_dd(PRE_ARGS)
static int
post_bf(POST_ARGS)
{
- char *p;
- struct mdoc_node *head;
+ struct mdoc_node *np;
+ int arg;
- if (MDOC_BLOCK != mdoc->last->type)
+ /*
+ * Unlike other data pointers, these are "housed" by the HEAD
+ * element, which contains the goods.
+ */
+
+ if (MDOC_HEAD != mdoc->last->type) {
+ if (ENDBODY_NOT != mdoc->last->end) {
+ assert(mdoc->last->pending);
+ np = mdoc->last->pending->parent->head;
+ } else if (MDOC_BLOCK != mdoc->last->type) {
+ np = mdoc->last->parent->head;
+ } else
+ np = mdoc->last->head;
+
+ assert(np);
+ assert(MDOC_HEAD == np->type);
+ assert(MDOC_Bf == np->tok);
+ assert(np->data.Bf);
+ mdoc->last->data.Bf = np->data.Bf;
return(1);
+ }
- head = mdoc->last->head;
+ np = mdoc->last;
+ assert(MDOC_BLOCK == np->parent->type);
+ assert(MDOC_Bf == np->parent->tok);
+ np->data.Bf = mandoc_calloc(1, sizeof(struct mdoc_bf));
- if (mdoc->last->args && head->child) {
- /* FIXME: this should provide a default. */
- mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SYNTARGVCOUNT);
- return(0);
- } else if (mdoc->last->args)
- return(1);
+ /*
+ * Cannot have both argument and parameter.
+ * If neither is specified, let it through with a warning.
+ */
- if (NULL == head->child || MDOC_TEXT != head->child->type) {
- /* FIXME: this should provide a default. */
- mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_SYNTARGVCOUNT);
+ if (np->parent->args && np->child) {
+ mdoc_nmsg(mdoc, np, MANDOCERR_SYNTARGVCOUNT);
return(0);
+ } else if (NULL == np->parent->args && NULL == np->child)
+ return(mdoc_nmsg(mdoc, np, MANDOCERR_FONTTYPE));
+
+ /* Extract argument into data. */
+
+ if (np->parent->args) {
+ arg = np->parent->args->argv[0].arg;
+ if (MDOC_Emphasis == arg)
+ np->data.Bf->font = FONT_Em;
+ else if (MDOC_Literal == arg)
+ np->data.Bf->font = FONT_Li;
+ else if (MDOC_Symbolic == arg)
+ np->data.Bf->font = FONT_Sy;
+ else
+ abort();
+ return(1);
}
- p = head->child->string;
+ /* Extract parameter into data. */
- if (0 == strcmp(p, "Em"))
- return(1);
- else if (0 == strcmp(p, "Li"))
- return(1);
- else if (0 == strcmp(p, "Sy"))
- return(1);
+ if (0 == strcmp(np->child->string, "Em"))
+ np->data.Bf->font = FONT_Em;
+ else if (0 == strcmp(np->child->string, "Li"))
+ np->data.Bf->font = FONT_Li;
+ else if (0 == strcmp(np->child->string, "Sy"))
+ np->data.Bf->font = FONT_Sy;
+ else if ( ! mdoc_nmsg(mdoc, np, MANDOCERR_FONTTYPE))
+ return(0);
- mdoc_nmsg(mdoc, head, MANDOCERR_FONTTYPE);
- return(0);
+ return(1);
}
@@ -1017,16 +1087,14 @@ post_at(POST_ARGS)
static int
post_an(POST_ARGS)
{
+ struct mdoc_node *np;
- if (mdoc->last->args) {
- if (NULL == mdoc->last->child)
- return(1);
- return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_ARGCOUNT));
- }
-
- if (mdoc->last->child)
+ np = mdoc->last;
+ if (AUTH__NONE != np->data.An.auth && np->child)
+ return(mdoc_nmsg(mdoc, np, MANDOCERR_ARGCOUNT));
+ if (AUTH__NONE != np->data.An.auth || np->child)
return(1);
- return(mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_NOARGS));
+ return(mdoc_nmsg(mdoc, np, MANDOCERR_NOARGS));
}
@@ -1042,7 +1110,8 @@ post_it(POST_ARGS)
return(1);
n = mdoc->last->parent->parent;
- lt = n->data.Bl.type;
+ assert(n->data.Bl);
+ lt = n->data.Bl->type;
if (LIST__NONE == lt) {
mdoc_nmsg(mdoc, mdoc->last, MANDOCERR_LISTTYPE);
@@ -1085,14 +1154,8 @@ post_it(POST_ARGS)
return(0);
break;
case (LIST_column):
- cols = -1;
- for (i = 0; i < (int)n->args->argc; i++)
- if (MDOC_Column == n->args->argv[i].arg) {
- cols = (int)n->args->argv[i].sz;
- break;
- }
+ cols = (int)n->data.Bl->ncols;
- assert(-1 != cols);
assert(NULL == mdoc->last->head->child);
if (NULL == mdoc->last->body->child)
@@ -1131,13 +1194,8 @@ post_bl_head(POST_ARGS)
assert(mdoc->last->parent);
n = mdoc->last->parent;
- if (LIST_column == n->data.Bl.type) {
- for (i = 0; i < (int)n->args->argc; i++)
- if (MDOC_Column == n->args->argv[i].arg)
- break;
- assert(i < (int)n->args->argc);
-
- if (n->args->argv[i].sz && mdoc->last->nchild) {
+ if (LIST_column == n->data.Bl->type) {
+ if (n->data.Bl->ncols && mdoc->last->nchild) {
mdoc_nmsg(mdoc, n, MANDOCERR_COLUMNS);
return(0);
}
diff --git a/usr.bin/mandoc/regs.h b/usr.bin/mandoc/regs.h
deleted file mode 100644
index b06f981689f..00000000000
--- a/usr.bin/mandoc/regs.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* $Id: regs.h,v 1.2 2010/07/03 15:59:05 schwarze Exp $ */
-/*
- * Copyright (c) 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
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef REGS_H
-#define REGS_H
-
-__BEGIN_DECLS
-
-enum regs {
- REG_nS = 0, /* nS */
- REG__MAX
-};
-
-struct reg {
- int set; /* whether set or not */
- union {
- unsigned u; /* unsigned integer */
- } v;
-};
-
-/*
- * Registers are non-scoped state. These can be manipulated directly in
- * libroff or indirectly in libman or libmdoc by macros. These should
- * be implemented sparingly (we are NOT roffdoc!) and documented fully
- * in roff.7.
- */
-struct regset {
- struct reg regs[REG__MAX];
-};
-
-char *roff_setstr(const char *, const char *);
-char *roff_getstr(const char *);
-char *roff_getstrn(const char *, size_t);
-void roff_freestr(void);
-
-__END_DECLS
-
-#endif /*!REGS_H*/
diff --git a/usr.bin/mandoc/roff.3 b/usr.bin/mandoc/roff.3
index 85e558fbe8c..b9d1fd41982 100644
--- a/usr.bin/mandoc/roff.3
+++ b/usr.bin/mandoc/roff.3
@@ -1,4 +1,4 @@
-.\" $Id: roff.3,v 1.3 2010/07/03 15:59:05 schwarze Exp $
+.\" $Id: roff.3,v 1.4 2010/07/13 01:09:13 schwarze Exp $
.\"
.\" Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 3 2010 $
+.Dd $Mdocdate: July 13 2010 $
.Dt ROFF 3
.Os
.Sh NAME
@@ -27,7 +27,6 @@
.Nd roff macro compiler library
.Sh SYNOPSIS
.In mandoc.h
-.In regs.h
.In roff.h
.Ft "struct roff *"
.Fo roff_alloc
@@ -50,15 +49,6 @@
.Fc
.Ft void
.Fn roff_reset "struct roff *roff"
-.In regs.h
-.Ft "char *"
-.Fn roff_setstr "const char *name" "const char *string"
-.Ft "char *"
-.Fn roff_getstr "const char *name"
-.Ft "char *"
-.Fn roff_getstrn "const char *name" "size_t len"
-.Ft void
-.Fn roff_freestr void
.Sh DESCRIPTION
The
.Nm
@@ -154,52 +144,6 @@ Returns 0 on failure, 1 on success.
Signals that the parse is complete.
Returns 0 on failure, 1 on success.
.El
-.Sh USER-DEFINED STRINGS
-Strings defined by the
-.Xr roff 7
-.Sx \&ds
-instruction are saved using the
-.Fn roff_setstr
-function and retrieved using the
-.Fn roff_getstr
-and
-.Fn roff_getstrn
-functions.
-.Pp
-These functions take the name of the string to be accessed
-as their first argument.
-While
-.Fn roff_getstr
-requires the name to be null-terminated,
-.Fn roff_getstrn
-accepts non-terminated strings, but requires the length of the name
-to be specified.
-.Pp
-The second argument to
-.Fn roff_setstr
-is the new value of the string.
-It will be copied to internal storage, so both pointers to constant
-strings and pointers to volatile storage are acceptable.
-.Pp
-All of these functions return a pointer to the new value of the string
-in internal storage, which should be considered read-only, so use
-.Xr strdup 3
-on it as appropriate.
-The read functions return NULL when a string of the specified name
-is not available or empty, and
-.Fn roff_setstr
-returns NULL when memory allocation fails.
-In the latter case, the string will remain unset.
-.Pp
-The function
-.Fn roff_freestr
-clears all user-defined strings.
-It always succeeds.
-Both
-.Fn roff_reset
-and
-.Fn roff_free
-call it.
.Sh EXAMPLES
See
.Pa main.c
diff --git a/usr.bin/mandoc/roff.7 b/usr.bin/mandoc/roff.7
index 3ac36e13e3e..d7bff4d0401 100644
--- a/usr.bin/mandoc/roff.7
+++ b/usr.bin/mandoc/roff.7
@@ -1,6 +1,7 @@
-.\" $Id: roff.7,v 1.6 2010/06/27 21:54:42 schwarze Exp $
+.\" $Id: roff.7,v 1.7 2010/07/13 01:09:13 schwarze Exp $
.\"
.\" Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+.\" Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 27 2010 $
+.Dd $Mdocdate: July 13 2010 $
.Dt ROFF 7
.Os
.Sh NAME
@@ -91,11 +92,20 @@ The syntax of this macro is the same as that of
except that a leading argument must be specified.
It is ignored, as are its children.
.Ss \&ds
-Define a string.
-This macro is intended to have two arguments,
-the name of the string to define and its content.
-Currently, it is ignored including its arguments,
-and the number of arguments is not checked.
+Define a reserved word.
+Its syntax is as follows:
+.Pp
+.D1 Pf \. Sx \&ds No Cm key val
+.Pp
+The
+.Cm key
+and
+.Cm val
+strings are space-separated.
+The
+.Cm key
+values may be invoked in subsequent text by using \e*(NN for two-letter
+pairs, \e*N for one-letter, and \e*[NNN] for arbitrary-length values.
.Ss \&de1
The syntax of this macro is the same as that of
.Sx \&ig ,
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index 32cd7423de3..4522f786a82 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,6 +1,7 @@
-/* $Id: roff.c,v 1.7 2010/07/03 15:59:05 schwarze Exp $ */
+/* $Id: roff.c,v 1.8 2010/07/13 01:09:13 schwarze Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -27,8 +28,8 @@
#include <stdio.h>
#include "mandoc.h"
-#include "regs.h"
#include "roff.h"
+#include "libmandoc.h"
#define RSTACK_MAX 128
@@ -60,6 +61,13 @@ enum roffrule {
ROFFRULE_DENY
};
+
+struct roffstr {
+ char *name; /* key of symbol */
+ char *string; /* current value */
+ struct roffstr *next; /* next in list */
+};
+
struct roff {
struct roffnode *last; /* leaf of stack */
mandocmsg msg; /* err/warn/fatal messages */
@@ -67,6 +75,7 @@ struct roff {
enum roffrule rstack[RSTACK_MAX]; /* stack of !`ie' rules */
int rstackpos; /* position in rstack */
struct regset *regs; /* read/writable registers */
+ struct roffstr *first_string;
};
struct roffnode {
@@ -100,12 +109,6 @@ struct roffmac {
struct roffmac *next;
};
-struct roffstr {
- char *name;
- char *string;
- struct roffstr *next;
-} *first_string;
-
static enum rofferr roff_block(ROFF_ARGS);
static enum rofferr roff_block_text(ROFF_ARGS);
static enum rofferr roff_block_sub(ROFF_ARGS);
@@ -115,9 +118,16 @@ static enum rofferr roff_cond(ROFF_ARGS);
static enum rofferr roff_cond_text(ROFF_ARGS);
static enum rofferr roff_cond_sub(ROFF_ARGS);
static enum rofferr roff_ds(ROFF_ARGS);
+static enum roffrule roff_evalcond(const char *, int *);
+static void roff_freestr(struct roff *);
+static const char *roff_getstrn(const struct roff *,
+ const char *, size_t);
static enum rofferr roff_line(ROFF_ARGS);
static enum rofferr roff_nr(ROFF_ARGS);
-static enum roffrule roff_evalcond(const char *, int *);
+static int roff_res(struct roff *, int,
+ char **, size_t *, int, int *);
+static void roff_setstr(struct roff *,
+ const char *, const char *);
/* See roff_hash_find() */
@@ -267,7 +277,7 @@ roff_free1(struct roff *r)
while (r->last)
roffnode_pop(r);
- roff_freestr();
+ roff_freestr(r);
}
@@ -308,6 +318,72 @@ roff_alloc(struct regset *regs, const mandocmsg msg, void *data)
}
+/*
+ * Pre-filter each and every line for reserved words (one beginning with
+ * `\*', e.g., `\*(ab'). These must be handled before the actual line
+ * is processed.
+ */
+static int
+roff_res(struct roff *r, int ln, char **bufp,
+ size_t *szp, int pos, int *offs)
+{
+ const char *cp, *cpp, *st, *res;
+ int i, maxl;
+ size_t nsz;
+ char *n;
+
+ for (cp = &(*bufp)[pos]; (cpp = strstr(cp, "\\*")); cp++) {
+ cp = cpp + 2;
+ switch (*cp) {
+ case ('('):
+ cp++;
+ maxl = 2;
+ break;
+ case ('['):
+ cp++;
+ maxl = 0;
+ break;
+ default:
+ maxl = 1;
+ break;
+ }
+
+ st = cp;
+
+ for (i = 0; 0 == maxl || i < maxl; i++, cp++) {
+ if ('\0' == *cp)
+ return(1); /* Error. */
+ if (0 == maxl && ']' == *cp)
+ break;
+ }
+
+ res = roff_getstrn(r, st, (size_t)i);
+
+ if (NULL == res) {
+ cp -= maxl ? 1 : 0;
+ continue;
+ }
+
+ nsz = *szp + strlen(res) + 1;
+ n = mandoc_malloc(nsz);
+
+ *n = '\0';
+
+ strlcat(n, *bufp, (size_t)(cpp - *bufp + 1));
+ strlcat(n, res, nsz);
+ strlcat(n, cp + (maxl ? 0 : 1), nsz);
+
+ free(*bufp);
+
+ *bufp = n;
+ *szp = nsz;
+ return(0);
+ }
+
+ return(1);
+}
+
+
enum rofferr
roff_parseln(struct roff *r, int ln, char **bufp,
size_t *szp, int pos, int *offs)
@@ -316,6 +392,14 @@ roff_parseln(struct roff *r, int ln, char **bufp,
int ppos;
/*
+ * Run the reserved-word filter only if we have some reserved
+ * words to fill in.
+ */
+
+ if (r->first_string && ! roff_res(r, ln, bufp, szp, pos, offs))
+ return(ROFF_RERUN);
+
+ /*
* First, if a scope is open and we're not a macro, pass the
* text through the macro's filter. If a scope isn't open and
* we're not a macro, just let it through.
@@ -325,7 +409,8 @@ roff_parseln(struct roff *r, int ln, char **bufp,
t = r->last->tok;
assert(roffs[t].text);
return((*roffs[t].text)
- (r, t, bufp, szp, ln, pos, pos, offs));
+ (r, t, bufp, szp,
+ ln, pos, pos, offs));
} else if ( ! ROFF_CTL((*bufp)[pos]))
return(ROFF_CONT);
@@ -338,7 +423,8 @@ roff_parseln(struct roff *r, int ln, char **bufp,
t = r->last->tok;
assert(roffs[t].sub);
return((*roffs[t].sub)
- (r, t, bufp, szp, ln, pos, pos, offs));
+ (r, t, bufp, szp,
+ ln, pos, pos, offs));
}
/*
@@ -353,7 +439,8 @@ roff_parseln(struct roff *r, int ln, char **bufp,
assert(roffs[t].proc);
return((*roffs[t].proc)
- (r, t, bufp, szp, ln, ppos, pos, offs));
+ (r, t, bufp, szp,
+ ln, ppos, pos, offs));
}
@@ -880,7 +967,7 @@ roff_ds(ROFF_ARGS)
*end = '\0';
}
- roff_setstr(name, string);
+ roff_setstr(r, name, string);
return(ROFF_IGN);
}
@@ -924,73 +1011,53 @@ roff_nr(ROFF_ARGS)
}
-char *
-roff_setstr(const char *name, const char *string)
+static void
+roff_setstr(struct roff *r, const char *name, const char *string)
{
struct roffstr *n;
char *namecopy;
- n = first_string;
+ n = r->first_string;
while (n && strcmp(name, n->name))
n = n->next;
- if (n) {
- free(n->string);
- } else {
- if (NULL == (namecopy = strdup(name)))
- return(NULL);
- if (NULL == (n = malloc(sizeof(struct roffstr)))) {
- free(n);
- return(NULL);
- }
- n->name = namecopy;
- n->next = first_string;
- first_string = n;
- }
- if (string)
- n->string = strdup(string);
- else
- n->string = NULL;
- return(n->string);
-}
-char *
-roff_getstr(const char *name)
-{
- struct roffstr *n;
+ if (NULL == n) {
+ namecopy = mandoc_strdup(name);
+ n = mandoc_malloc(sizeof(struct roffstr));
+ n->name = namecopy;
+ n->next = r->first_string;
+ r->first_string = n;
+ } else
+ free(n->string);
- n = first_string;
- while (n && strcmp(name, n->name))
- n = n->next;
- if (n)
- return(n->string);
- else
- return(NULL);
+ n->string = string ? strdup(string) : NULL;
}
-char *
-roff_getstrn(const char *name, size_t len)
+
+static const char *
+roff_getstrn(const struct roff *r, const char *name, size_t len)
{
- struct roffstr *n;
+ const struct roffstr *n;
- n = first_string;
+ n = r->first_string;
while (n && (strncmp(name, n->name, len) || '\0' != n->name[len]))
n = n->next;
- if (n)
- return(n->string);
- else
- return(NULL);
+
+ return(n ? n->string : NULL);
}
-void
-roff_freestr(void)
+
+static void
+roff_freestr(struct roff *r)
{
struct roffstr *n, *nn;
- for (n = first_string; n; n = nn) {
+ for (n = r->first_string; n; n = nn) {
free(n->name);
free(n->string);
nn = n->next;
free(n);
}
- first_string = NULL;
+
+ r->first_string = NULL;
}
diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c
index 45b603616af..459c17a3d7b 100644
--- a/usr.bin/mandoc/term.c
+++ b/usr.bin/mandoc/term.c
@@ -1,6 +1,7 @@
-/* $Id: term.c,v 1.43 2010/07/03 15:59:05 schwarze Exp $ */
+/* $Id: term.c,v 1.44 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -26,7 +27,6 @@
#include "mandoc.h"
#include "chars.h"
#include "out.h"
-#include "regs.h"
#include "term.h"
#include "main.h"
@@ -374,11 +374,6 @@ res(struct termp *p, const char *word, size_t len)
size_t sz;
rhs = chars_a2res(p->symtab, word, len, &sz);
- if (NULL == rhs) {
- rhs = roff_getstrn(word, len);
- if (rhs)
- sz = strlen(rhs);
- }
if (rhs)
encode(p, rhs, sz);
}
@@ -655,6 +650,7 @@ term_strlen(const struct termp *p, const char *cp)
}
+/* ARGSUSED */
size_t
term_vspan(const struct termp *p, const struct roffsu *su)
{
@@ -694,39 +690,11 @@ term_vspan(const struct termp *p, const struct roffsu *su)
size_t
term_hspan(const struct termp *p, const struct roffsu *su)
{
- double r;
-
- /* XXX: CM, IN, and PT are approximations. */
-
- switch (su->unit) {
- case (SCALE_CM):
- r = 4 * su->scale;
- break;
- case (SCALE_IN):
- /* XXX: this is an approximation. */
- r = 10 * su->scale;
- break;
- case (SCALE_PC):
- r = (10 * su->scale) / 6;
- break;
- case (SCALE_PT):
- r = (10 * su->scale) / 72;
- break;
- case (SCALE_MM):
- r = su->scale / 1000; /* FIXME: double-check. */
- break;
- case (SCALE_VS):
- r = su->scale * 2 - 1; /* FIXME: double-check. */
- break;
- default:
- r = su->scale;
- break;
- }
+ double v;
- if (r < 0.0)
- r = 0.0;
- return((size_t)/* LINTED */
- r);
+ v = ((*p->hspan)(p, su));
+ if (v < 0.0)
+ v = 0.0;
+ return((size_t) /* LINTED */
+ v);
}
-
-
diff --git a/usr.bin/mandoc/term.h b/usr.bin/mandoc/term.h
index 726915f3ec4..ff2585a814e 100644
--- a/usr.bin/mandoc/term.h
+++ b/usr.bin/mandoc/term.h
@@ -1,6 +1,6 @@
-/* $Id: term.h,v 1.24 2010/06/29 14:41:28 schwarze Exp $ */
+/* $Id: term.h,v 1.25 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 2008, 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
@@ -42,25 +42,27 @@ enum termfont {
typedef void (*term_margin)(struct termp *, const void *);
struct termp_ps {
- int psstate; /* state of ps output */
+ int flags;
#define PS_INLINE (1 << 0) /* we're in a word */
#define PS_MARGINS (1 << 1) /* we're in the margins */
- size_t pscol; /* visible column (points) */
- size_t psrow; /* visible row (points) */
+#define PS_NEWPAGE (1 << 2) /* new page, no words yet */
+ size_t pscol; /* visible column (AFM units) */
+ size_t psrow; /* visible row (AFM units) */
char *psmarg; /* margin buf */
size_t psmargsz; /* margin buf size */
size_t psmargcur; /* cur index in margin buf */
char last; /* character buffer */
enum termfont lastf; /* last set font */
+ size_t scale; /* font scaling factor */
size_t pages; /* number of pages shown */
- size_t lineheight; /* each line's height (points) */
- size_t top; /* body top (points) */
- size_t bottom; /* body bottom (points) */
- size_t height; /* total height (points) */
- size_t width; /* total width (points) */
- size_t left; /* body left (points) */
- size_t header; /* header position (points) */
- size_t footer; /* footer position (points) */
+ size_t lineheight; /* line height (AFM units) */
+ size_t top; /* body top (AFM units) */
+ size_t bottom; /* body bottom (AFM units) */
+ size_t height; /* page height (AFM units */
+ size_t width; /* page width (AFM units) */
+ size_t left; /* body left (AFM units) */
+ size_t header; /* header pos (AFM units) */
+ size_t footer; /* footer pos (AFM units) */
};
struct termp {
@@ -103,6 +105,8 @@ struct termp {
void (*endline)(struct termp *);
void (*advance)(struct termp *, size_t);
size_t (*width)(const struct termp *, char);
+ double (*hspan)(const struct termp *,
+ const struct roffsu *);
const void *argf; /* arg for headf/footf */
union {
struct termp_ps ps;
diff --git a/usr.bin/mandoc/term_ascii.c b/usr.bin/mandoc/term_ascii.c
index da20706ac42..21b1abbe226 100644
--- a/usr.bin/mandoc/term_ascii.c
+++ b/usr.bin/mandoc/term_ascii.c
@@ -1,6 +1,6 @@
-/* $Id: term_ascii.c,v 1.2 2010/06/26 19:08:00 schwarze Exp $ */
+/* $Id: term_ascii.c,v 1.3 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ * Copyright (c) 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
@@ -30,12 +30,14 @@
#include "term.h"
#include "main.h"
-static void ascii_endline(struct termp *);
-static void ascii_letter(struct termp *, char);
-static void ascii_begin(struct termp *);
+static double ascii_hspan(const struct termp *,
+ const struct roffsu *);
+static size_t ascii_width(const struct termp *, char);
static void ascii_advance(struct termp *, size_t);
+static void ascii_begin(struct termp *);
static void ascii_end(struct termp *);
-static size_t ascii_width(const struct termp *, char);
+static void ascii_endline(struct termp *);
+static void ascii_letter(struct termp *, char);
void *
@@ -51,12 +53,13 @@ ascii_alloc(char *outopts)
p->tabwidth = 5;
p->defrmargin = 78;
- p->type = TERMTYPE_CHAR;
- p->letter = ascii_letter;
+ p->advance = ascii_advance;
p->begin = ascii_begin;
p->end = ascii_end;
p->endline = ascii_endline;
- p->advance = ascii_advance;
+ p->hspan = ascii_hspan;
+ p->letter = ascii_letter;
+ p->type = TERMTYPE_CHAR;
p->width = ascii_width;
toks[0] = "width";
@@ -79,6 +82,7 @@ ascii_alloc(char *outopts)
}
+/* ARGSUSED */
static size_t
ascii_width(const struct termp *p, char c)
{
@@ -139,3 +143,43 @@ ascii_advance(struct termp *p, size_t len)
for (i = 0; i < len; i++)
putchar(' ');
}
+
+
+/* ARGSUSED */
+static double
+ascii_hspan(const struct termp *p, const struct roffsu *su)
+{
+ double r;
+
+ /*
+ * Approximate based on character width. These are generated
+ * entirely by eyeballing the screen, but appear to be correct.
+ */
+
+ switch (su->unit) {
+ case (SCALE_CM):
+ r = 4 * su->scale;
+ break;
+ case (SCALE_IN):
+ r = 10 * su->scale;
+ break;
+ case (SCALE_PC):
+ r = (10 * su->scale) / 6;
+ break;
+ case (SCALE_PT):
+ r = (10 * su->scale) / 72;
+ break;
+ case (SCALE_MM):
+ r = su->scale / 1000;
+ break;
+ case (SCALE_VS):
+ r = su->scale * 2 - 1;
+ break;
+ default:
+ r = su->scale;
+ break;
+ }
+
+ return(r);
+}
+
diff --git a/usr.bin/mandoc/term_ps.c b/usr.bin/mandoc/term_ps.c
index eb06b309c4f..44fa34e6f10 100644
--- a/usr.bin/mandoc/term_ps.c
+++ b/usr.bin/mandoc/term_ps.c
@@ -1,6 +1,6 @@
-/* $Id: term_ps.c,v 1.5 2010/06/29 15:49:52 schwarze Exp $ */
+/* $Id: term_ps.c,v 1.6 2010/07/13 01:09:13 schwarze Exp $ */
/*
- * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
+ * Copyright (c) 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
@@ -27,13 +27,22 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <unistd.h>
#include "out.h"
#include "main.h"
#include "term.h"
+/* Convert PostScript point "x" to an AFM unit. */
+#define PNT2AFM(p, x) /* LINTED */ \
+ (size_t)((double)(x) * (1000.0 / (double)(p)->engine.ps.scale))
+
+/* Convert an AFM unit "x" to a PostScript points */
+#define AFM2PNT(p, x) /* LINTED */ \
+ (size_t)((double)(x) / (1000.0 / (double)(p)->engine.ps.scale))
+
struct glyph {
- int wx; /* WX in AFM */
+ size_t wx; /* WX in AFM */
};
struct font {
@@ -49,296 +58,296 @@ struct font {
*/
static const struct font fonts[TERMFONT__MAX] = {
- { "Courier", {
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
+ { "Times-Roman", {
+ { 250 },
+ { 333 },
+ { 408 },
+ { 500 },
+ { 500 },
+ { 833 },
+ { 778 },
+ { 333 },
+ { 333 },
+ { 333 },
+ { 500 },
+ { 564 },
+ { 250 },
+ { 333 },
+ { 250 },
+ { 278 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 278 },
+ { 278 },
+ { 564 },
+ { 564 },
+ { 564 },
+ { 444 },
+ { 921 },
+ { 722 },
+ { 667 },
+ { 667 },
+ { 722 },
+ { 611 },
+ { 556 },
+ { 722 },
+ { 722 },
+ { 333 },
+ { 389 },
+ { 722 },
+ { 611 },
+ { 889 },
+ { 722 },
+ { 722 },
+ { 556 },
+ { 722 },
+ { 667 },
+ { 556 },
+ { 611 },
+ { 722 },
+ { 722 },
+ { 944 },
+ { 722 },
+ { 722 },
+ { 611 },
+ { 333 },
+ { 278 },
+ { 333 },
+ { 469 },
+ { 500 },
+ { 333 },
+ { 444 },
+ { 500 },
+ { 444 },
+ { 500},
+ { 444},
+ { 333},
+ { 500},
+ { 500},
+ { 278},
+ { 278},
+ { 500},
+ { 278},
+ { 778},
+ { 500},
+ { 500},
+ { 500},
+ { 500},
+ { 333},
+ { 389},
+ { 278},
+ { 500},
+ { 500},
+ { 722},
+ { 500},
+ { 500},
+ { 444},
+ { 480},
+ { 200},
+ { 480},
+ { 541},
} },
- { "Courier-Bold", {
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
+ { "Times-Bold", {
+ { 250 },
+ { 333 },
+ { 555 },
+ { 500 },
+ { 500 },
+ { 1000 },
+ { 833 },
+ { 333 },
+ { 333 },
+ { 333 },
+ { 500 },
+ { 570 },
+ { 250 },
+ { 333 },
+ { 250 },
+ { 278 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 333 },
+ { 333 },
+ { 570 },
+ { 570 },
+ { 570 },
+ { 500 },
+ { 930 },
+ { 722 },
+ { 667 },
+ { 722 },
+ { 722 },
+ { 667 },
+ { 611 },
+ { 778 },
+ { 778 },
+ { 389 },
+ { 500 },
+ { 778 },
+ { 667 },
+ { 944 },
+ { 722 },
+ { 778 },
+ { 611 },
+ { 778 },
+ { 722 },
+ { 556 },
+ { 667 },
+ { 722 },
+ { 722 },
+ { 1000 },
+ { 722 },
+ { 722 },
+ { 667 },
+ { 333 },
+ { 278 },
+ { 333 },
+ { 581 },
+ { 500 },
+ { 333 },
+ { 500 },
+ { 556 },
+ { 444 },
+ { 556 },
+ { 444 },
+ { 333 },
+ { 500 },
+ { 556 },
+ { 278 },
+ { 333 },
+ { 556 },
+ { 278 },
+ { 833 },
+ { 556 },
+ { 500 },
+ { 556 },
+ { 556 },
+ { 444 },
+ { 389 },
+ { 333 },
+ { 556 },
+ { 500 },
+ { 722 },
+ { 500 },
+ { 500 },
+ { 444 },
+ { 394 },
+ { 220 },
+ { 394 },
+ { 520 },
} },
- { "Courier-Oblique", {
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
- { 600 },
+ { "Times-Italic", {
+ { 250 },
+ { 333 },
+ { 420 },
+ { 500 },
+ { 500 },
+ { 833 },
+ { 778 },
+ { 333 },
+ { 333 },
+ { 333 },
+ { 500 },
+ { 675 },
+ { 250 },
+ { 333 },
+ { 250 },
+ { 278 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 333 },
+ { 333 },
+ { 675 },
+ { 675 },
+ { 675 },
+ { 500 },
+ { 920 },
+ { 611 },
+ { 611 },
+ { 667 },
+ { 722 },
+ { 611 },
+ { 611 },
+ { 722 },
+ { 722 },
+ { 333 },
+ { 444 },
+ { 667 },
+ { 556 },
+ { 833 },
+ { 667 },
+ { 722 },
+ { 611 },
+ { 722 },
+ { 611 },
+ { 500 },
+ { 556 },
+ { 722 },
+ { 611 },
+ { 833 },
+ { 611 },
+ { 556 },
+ { 556 },
+ { 389 },
+ { 278 },
+ { 389 },
+ { 422 },
+ { 500 },
+ { 333 },
+ { 500 },
+ { 500 },
+ { 444 },
+ { 500 },
+ { 444 },
+ { 278 },
+ { 500 },
+ { 500 },
+ { 278 },
+ { 278 },
+ { 444 },
+ { 278 },
+ { 722 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 500 },
+ { 389 },
+ { 389 },
+ { 278 },
+ { 500 },
+ { 444 },
+ { 667 },
+ { 444 },
+ { 444 },
+ { 389 },
+ { 400 },
+ { 275 },
+ { 400 },
+ { 541 },
} },
};
@@ -359,13 +368,15 @@ static const struct font fonts[TERMFONT__MAX] = {
} while (/* CONSTCOND */ 0)
-static void ps_letter(struct termp *, char);
+static double ps_hspan(const struct termp *,
+ const struct roffsu *);
+static size_t ps_width(const struct termp *, char);
+static void ps_advance(struct termp *, size_t);
static void ps_begin(struct termp *);
static void ps_end(struct termp *);
-static void ps_advance(struct termp *, size_t);
static void ps_endline(struct termp *);
static void ps_fclose(struct termp *);
-static size_t ps_width(const struct termp *, char);
+static void ps_letter(struct termp *, char);
static void ps_pclose(struct termp *);
static void ps_pletter(struct termp *, int);
static void ps_printf(struct termp *, const char *, ...);
@@ -377,57 +388,100 @@ void *
ps_alloc(char *outopts)
{
struct termp *p;
- size_t pagex, pagey, margin;
+ size_t pagex, pagey, marginx, marginy, lineheight;
const char *toks[2];
+ const char *pp;
char *v;
if (NULL == (p = term_alloc(TERMENC_ASCII)))
return(NULL);
- /* Default is USA letter. */
- pagex = 612;
- pagey = 792;
- margin = 72;
-
- p->type = TERMTYPE_PS;
- p->letter = ps_letter;
+ p->advance = ps_advance;
p->begin = ps_begin;
p->end = ps_end;
- p->advance = ps_advance;
p->endline = ps_endline;
+ p->hspan = ps_hspan;
+ p->letter = ps_letter;
+ p->type = TERMTYPE_PS;
p->width = ps_width;
-
+
toks[0] = "paper";
toks[1] = NULL;
+ pp = NULL;
+
while (outopts && *outopts)
switch (getsubopt(&outopts, UNCONST(toks), &v)) {
case (0):
- if (0 == strcasecmp(v, "a4")) {
- pagex = 595;
- pagey = 842;
- } else if (0 == strcasecmp(v, "letter")) {
- pagex = 612;
- pagey = 792;
- }
+ pp = v;
break;
default:
break;
}
- assert(margin * 2 < pagex);
- assert(margin * 2 < pagey);
+ /* Default to US letter (millimetres). */
+
+ pagex = 216;
+ pagey = 279;
+
+ /*
+ * The ISO-269 paper sizes can be calculated automatically, but
+ * it would require bringing in -lm for pow() and I'd rather not
+ * do that. So just do it the easy way for now. Since this
+ * only happens once, I'm not terribly concerned.
+ */
+
+ if (pp && strcasecmp(pp, "letter")) {
+ if (0 == strcasecmp(pp, "a3")) {
+ pagex = 297;
+ pagey = 420;
+ } else if (0 == strcasecmp(pp, "a4")) {
+ pagex = 210;
+ pagey = 297;
+ } else if (0 == strcasecmp(pp, "a5")) {
+ pagex = 148;
+ pagey = 210;
+ } else if (0 == strcasecmp(pp, "legal")) {
+ pagex = 216;
+ pagey = 356;
+ } else if (2 != sscanf(pp, "%zux%zu", &pagex, &pagey))
+ fprintf(stderr, "%s: Unknown paper\n", pp);
+ } else if (NULL == pp)
+ pp = "letter";
+
+ /*
+ * This MUST be defined before any PNT2AFM or AFM2PNT
+ * calculations occur.
+ */
+
+ p->engine.ps.scale = 11;
+
+ /* Remember millimetres -> AFM units. */
+
+ pagex = PNT2AFM(p, ((double)pagex * 2.834));
+ pagey = PNT2AFM(p, ((double)pagey * 2.834));
+
+ /* Margins are 1/9 the page x and y. */
+
+ marginx = /* LINTED */
+ (size_t)((double)pagex / 9.0);
+ marginy = /* LINTED */
+ (size_t)((double)pagey / 9.0);
+
+ /* Line-height is 1.4em. */
+
+ lineheight = PNT2AFM(p, ((double)p->engine.ps.scale * 1.4));
p->engine.ps.width = pagex;
p->engine.ps.height = pagey;
- p->engine.ps.header = pagey - (margin / 2);
- p->engine.ps.top = pagey - margin;
- p->engine.ps.footer = (margin / 2);
- p->engine.ps.bottom = margin;
- p->engine.ps.left = margin;
- p->engine.ps.lineheight = 12;
-
- p->defrmargin = pagex - (margin * 2);
+ p->engine.ps.header = pagey - (marginy / 2) - (lineheight / 2);
+ p->engine.ps.top = pagey - marginy;
+ p->engine.ps.footer = (marginy / 2) - (lineheight / 2);
+ p->engine.ps.bottom = marginy;
+ p->engine.ps.left = marginx;
+ p->engine.ps.lineheight = lineheight;
+
+ p->defrmargin = pagex - (marginx * 2);
return(p);
}
@@ -460,7 +514,7 @@ ps_printf(struct termp *p, const char *fmt, ...)
* into our growable margin buffer.
*/
- if ( ! (PS_MARGINS & p->engine.ps.psstate)) {
+ if ( ! (PS_MARGINS & p->engine.ps.flags)) {
vprintf(fmt, ap);
va_end(ap);
return;
@@ -489,7 +543,7 @@ ps_putchar(struct termp *p, char c)
/* See ps_printf(). */
- if ( ! (PS_MARGINS & p->engine.ps.psstate)) {
+ if ( ! (PS_MARGINS & p->engine.ps.flags)) {
putchar(c);
return;
}
@@ -513,12 +567,14 @@ ps_end(struct termp *p)
* well as just one.
*/
- assert(0 == p->engine.ps.psstate);
- assert('\0' == p->engine.ps.last);
- assert(p->engine.ps.psmarg && p->engine.ps.psmarg[0]);
- printf("%s", p->engine.ps.psmarg);
- p->engine.ps.pages++;
- printf("showpage\n");
+ if ( ! (PS_NEWPAGE & p->engine.ps.flags)) {
+ assert(0 == p->engine.ps.flags);
+ assert('\0' == p->engine.ps.last);
+ assert(p->engine.ps.psmarg && p->engine.ps.psmarg[0]);
+ printf("%s", p->engine.ps.psmarg);
+ p->engine.ps.pages++;
+ printf("showpage\n");
+ }
printf("%%%%Trailer\n");
printf("%%%%Pages: %zu\n", p->engine.ps.pages);
@@ -543,7 +599,7 @@ ps_begin(struct termp *p)
}
p->engine.ps.psmargcur = 0;
- p->engine.ps.psstate = PS_MARGINS;
+ p->engine.ps.flags = PS_MARGINS;
p->engine.ps.pscol = p->engine.ps.left;
p->engine.ps.psrow = p->engine.ps.header;
@@ -558,9 +614,9 @@ ps_begin(struct termp *p)
(*p->footf)(p, p->argf);
(*p->endline)(p);
- p->engine.ps.psstate &= ~PS_MARGINS;
+ p->engine.ps.flags &= ~PS_MARGINS;
- assert(0 == p->engine.ps.psstate);
+ assert(0 == p->engine.ps.flags);
assert(p->engine.ps.psmarg);
assert('\0' != p->engine.ps.psmarg[0]);
@@ -578,22 +634,18 @@ ps_begin(struct termp *p)
printf("%%%%Orientation: Portrait\n");
printf("%%%%Pages: (atend)\n");
printf("%%%%PageOrder: Ascend\n");
- printf("%%%%Orientation: Portrait\n");
printf("%%%%DocumentMedia: Default %zu %zu 0 () ()\n",
- p->engine.ps.width,
- p->engine.ps.height);
+ AFM2PNT(p, p->engine.ps.width),
+ AFM2PNT(p, p->engine.ps.height));
printf("%%%%DocumentNeededResources: font");
for (i = 0; i < (int)TERMFONT__MAX; i++)
printf(" %s", fonts[i].name);
printf("\n%%%%EndComments\n");
- printf("%%%%Page: %zu %zu\n",
- p->engine.ps.pages + 1,
- p->engine.ps.pages + 1);
-
- ps_setfont(p, TERMFONT_NONE);
p->engine.ps.pscol = p->engine.ps.left;
p->engine.ps.psrow = p->engine.ps.top;
+ p->engine.ps.flags |= PS_NEWPAGE;
+ ps_setfont(p, TERMFONT_NONE);
}
@@ -601,19 +653,36 @@ static void
ps_pletter(struct termp *p, int c)
{
int f;
+
+ /*
+ * If we haven't opened a page context, then output that we're
+ * in a new page and make sure the font is correctly set.
+ */
+
+ if (PS_NEWPAGE & p->engine.ps.flags) {
+ printf("%%%%Page: %zu %zu\n",
+ p->engine.ps.pages + 1,
+ p->engine.ps.pages + 1);
+ ps_printf(p, "/%s %zu selectfont\n",
+ fonts[(int)p->engine.ps.lastf].name,
+ p->engine.ps.scale);
+ p->engine.ps.flags &= ~PS_NEWPAGE;
+ }
/*
* If we're not in a PostScript "word" context, then open one
* now at the current cursor.
*/
- if ( ! (PS_INLINE & p->engine.ps.psstate)) {
+ if ( ! (PS_INLINE & p->engine.ps.flags)) {
ps_printf(p, "%zu %zu moveto\n(",
- p->engine.ps.pscol,
- p->engine.ps.psrow);
- p->engine.ps.psstate |= PS_INLINE;
+ AFM2PNT(p, p->engine.ps.pscol),
+ AFM2PNT(p, p->engine.ps.psrow));
+ p->engine.ps.flags |= PS_INLINE;
}
+ assert( ! (PS_NEWPAGE & p->engine.ps.flags));
+
/*
* We need to escape these characters as per the PostScript
* specification. We would also escape non-graphable characters
@@ -639,13 +708,13 @@ ps_pletter(struct termp *p, int c)
if (c <= 32 || (c - 32 > MAXCHAR)) {
ps_putchar(p, ' ');
- p->engine.ps.pscol += (fonts[f].gly[0].wx / 100);
+ p->engine.ps.pscol += fonts[f].gly[0].wx;
return;
}
- ps_putchar(p, c);
+ ps_putchar(p, (char)c);
c -= 32;
- p->engine.ps.pscol += (fonts[f].gly[c].wx / 100);
+ p->engine.ps.pscol += fonts[f].gly[c].wx;
}
@@ -659,11 +728,11 @@ ps_pclose(struct termp *p)
* or anything).
*/
- if ( ! (PS_INLINE & p->engine.ps.psstate))
+ if ( ! (PS_INLINE & p->engine.ps.flags))
return;
ps_printf(p, ") show\n");
- p->engine.ps.psstate &= ~PS_INLINE;
+ p->engine.ps.flags &= ~PS_INLINE;
}
@@ -688,7 +757,7 @@ ps_fclose(struct termp *p)
p->engine.ps.last = '\0';
}
- if ( ! (PS_INLINE & p->engine.ps.psstate))
+ if ( ! (PS_INLINE & p->engine.ps.flags))
return;
ps_pclose(p);
@@ -773,7 +842,16 @@ ps_endline(struct termp *p)
* lines, we'll do nasty stuff.
*/
- if (PS_MARGINS & p->engine.ps.psstate)
+ if (PS_MARGINS & p->engine.ps.flags)
+ return;
+
+ /* Left-justify. */
+
+ p->engine.ps.pscol = p->engine.ps.left;
+
+ /* If we haven't printed anything, return. */
+
+ if (PS_NEWPAGE & p->engine.ps.flags)
return;
/*
@@ -781,7 +859,6 @@ ps_endline(struct termp *p)
* showpage and restart our row.
*/
- p->engine.ps.pscol = p->engine.ps.left;
if (p->engine.ps.psrow >= p->engine.ps.lineheight +
p->engine.ps.bottom) {
p->engine.ps.psrow -= p->engine.ps.lineheight;
@@ -790,12 +867,11 @@ ps_endline(struct termp *p)
assert(p->engine.ps.psmarg && p->engine.ps.psmarg[0]);
printf("%s", p->engine.ps.psmarg);
- printf("%%%%Page: %zu %zu\n",
- p->engine.ps.pages + 1,
- p->engine.ps.pages + 1);
printf("showpage\n");
p->engine.ps.pages++;
p->engine.ps.psrow = p->engine.ps.top;
+ assert( ! (PS_NEWPAGE & p->engine.ps.flags));
+ p->engine.ps.flags |= PS_NEWPAGE;
}
@@ -804,8 +880,18 @@ ps_setfont(struct termp *p, enum termfont f)
{
assert(f < TERMFONT__MAX);
- ps_printf(p, "/%s 10 selectfont\n", fonts[(int)f].name);
p->engine.ps.lastf = f;
+
+ /*
+ * If we're still at the top of the page, let the font-setting
+ * be delayed until we actually have stuff to print.
+ */
+
+ if (PS_NEWPAGE & p->engine.ps.flags)
+ return;
+
+ ps_printf(p, "/%s %zu selectfont\n",
+ fonts[(int)f].name, p->engine.ps.scale);
}
@@ -815,8 +901,55 @@ ps_width(const struct termp *p, char c)
{
if (c <= 32 || c - 32 >= MAXCHAR)
- return(fonts[(int)TERMFONT_NONE].gly[0].wx / 100);
+ return(fonts[(int)TERMFONT_NONE].gly[0].wx);
c -= 32;
- return(fonts[(int)TERMFONT_NONE].gly[(int)c].wx / 100);
+ return(fonts[(int)TERMFONT_NONE].gly[(int)c].wx);
}
+
+
+static double
+ps_hspan(const struct termp *p, const struct roffsu *su)
+{
+ double r;
+
+ /*
+ * All of these measurements are derived by converting from the
+ * native measurement to AFM units.
+ */
+
+ switch (su->unit) {
+ case (SCALE_CM):
+ r = PNT2AFM(p, su->scale * 28.34);
+ break;
+ case (SCALE_IN):
+ r = PNT2AFM(p, su->scale * 72);
+ break;
+ case (SCALE_PC):
+ r = PNT2AFM(p, su->scale * 12);
+ break;
+ case (SCALE_PT):
+ r = PNT2AFM(p, su->scale * 100);
+ break;
+ case (SCALE_EM):
+ r = su->scale *
+ fonts[(int)TERMFONT_NONE].gly[109 - 32].wx;
+ break;
+ case (SCALE_MM):
+ r = PNT2AFM(p, su->scale * 2.834);
+ break;
+ case (SCALE_EN):
+ r = su->scale *
+ fonts[(int)TERMFONT_NONE].gly[110 - 32].wx;
+ break;
+ case (SCALE_VS):
+ r = su->scale * p->engine.ps.lineheight;
+ break;
+ default:
+ r = su->scale;
+ break;
+ }
+
+ return(r);
+}
+
diff --git a/usr.bin/mandoc/tree.c b/usr.bin/mandoc/tree.c
index 82c7e09bf57..b775ca1edc7 100644
--- a/usr.bin/mandoc/tree.c
+++ b/usr.bin/mandoc/tree.c
@@ -1,4 +1,4 @@
-/* $Id: tree.c,v 1.9 2010/06/29 17:10:30 schwarze Exp $ */
+/* $Id: tree.c,v 1.10 2010/07/13 01:09:13 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -20,7 +20,6 @@
#include <time.h>
#include "mandoc.h"
-#include "regs.h"
#include "mdoc.h"
#include "man.h"
#include "main.h"