summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2012-11-18 17:59:04 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2012-11-18 17:59:04 +0000
commitecfb480938628f1fc2ee71f996499d90349bf073 (patch)
treecb5d312fb938c27ea9f3cbad23bb6d4ceec35402
parent2e0e75c225e57631bfa49f67d7e25617436fea8b (diff)
Correct indentation for lists and displays inside lists.
Inspired by a diff from millert@, but implemented rather differently and with slightly better functionality. In particular, this one respects -offset and -width arguments found in the input file.
-rw-r--r--regress/usr.bin/mandoc/man/RS/Makefile4
-rw-r--r--regress/usr.bin/mandoc/man/RS/nested.in37
-rw-r--r--regress/usr.bin/mandoc/man/RS/nested.out_ascii31
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bd/Makefile4
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bd/nested.in42
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bd/nested.out_ascii29
-rw-r--r--regress/usr.bin/mandoc/mdoc/Bl/Makefile4
-rw-r--r--usr.bin/mandoc/mdoc_man.c111
8 files changed, 249 insertions, 13 deletions
diff --git a/regress/usr.bin/mandoc/man/RS/Makefile b/regress/usr.bin/mandoc/man/RS/Makefile
index f764eb519e7..ac5c2ff35d4 100644
--- a/regress/usr.bin/mandoc/man/RS/Makefile
+++ b/regress/usr.bin/mandoc/man/RS/Makefile
@@ -1,5 +1,5 @@
-# $OpenBSD: Makefile,v 1.2 2012/07/18 16:55:54 schwarze Exp $
+# $OpenBSD: Makefile,v 1.3 2012/11/18 17:59:03 schwarze Exp $
-REGRESS_TARGETS = breaking empty
+REGRESS_TARGETS = breaking empty nested
.include <bsd.regress.mk>
diff --git a/regress/usr.bin/mandoc/man/RS/nested.in b/regress/usr.bin/mandoc/man/RS/nested.in
new file mode 100644
index 00000000000..03c4b43c39d
--- /dev/null
+++ b/regress/usr.bin/mandoc/man/RS/nested.in
@@ -0,0 +1,37 @@
+.TH RS-NESTED 1 "November 18, 2012" OpenBSD
+.SH NAME
+RS-nested \- various blocks nested inside reset blocks
+.SH DESCRIPTION
+regular
+text
+.RS
+outer
+text (default indent)
+.RS
+inner
+text (default indent)
+.RE
+outer
+text
+.RE
+regular text
+.RS 4n
+outer text (4n)
+.RS 2n
+inner text (2n)
+.RE
+outer text
+.IP indent 8n
+text (8n)
+.TP 6n
+tag
+text (6n)
+.HP 12n
+hanged
+This is very long text.
+Let's see where it will break the line,
+and which indent the next line will have - hopefully 12n.
+.PP
+outer text
+.RE
+regular text
diff --git a/regress/usr.bin/mandoc/man/RS/nested.out_ascii b/regress/usr.bin/mandoc/man/RS/nested.out_ascii
new file mode 100644
index 00000000000..f36824e7e85
--- /dev/null
+++ b/regress/usr.bin/mandoc/man/RS/nested.out_ascii
@@ -0,0 +1,31 @@
+RS-NESTED(1) OpenBSD Reference Manual RS-NESTED(1)
+
+
+
+NNAAMMEE
+ RS-nested - various blocks nested inside reset blocks
+
+DDEESSCCRRIIPPTTIIOONN
+ regular text
+ outer text (default indent)
+ inner text (default indent)
+ outer text
+ regular text
+ outer text (4n)
+ inner text (2n)
+ outer text
+
+ indent text (8n)
+
+ tag text (6n)
+
+ hanged This is very long text. Let's see where it will break the
+ line, and which indent the next line will have -
+ hopefully 12n.
+
+ outer text
+ regular text
+
+
+
+OpenBSD November 18, 2012 RS-NESTED(1)
diff --git a/regress/usr.bin/mandoc/mdoc/Bd/Makefile b/regress/usr.bin/mandoc/mdoc/Bd/Makefile
index 25556d48e73..b687b3c7ecb 100644
--- a/regress/usr.bin/mandoc/mdoc/Bd/Makefile
+++ b/regress/usr.bin/mandoc/mdoc/Bd/Makefile
@@ -1,6 +1,6 @@
-# $OpenBSD: Makefile,v 1.7 2012/11/16 13:25:34 schwarze Exp $
+# $OpenBSD: Makefile,v 1.8 2012/11/18 17:59:03 schwarze Exp $
-REGRESS_TARGETS = empty blank offset-empty spacing break broken
+REGRESS_TARGETS = blank nested spacing empty offset-empty break broken
# groff-1.20.1 defect:
# - a display breaking another block continues indefinitely
diff --git a/regress/usr.bin/mandoc/mdoc/Bd/nested.in b/regress/usr.bin/mandoc/mdoc/Bd/nested.in
new file mode 100644
index 00000000000..a5455a61450
--- /dev/null
+++ b/regress/usr.bin/mandoc/mdoc/Bd/nested.in
@@ -0,0 +1,42 @@
+.Dd November 18, 2012
+.Dt BD-NESTED 1
+.Os OpenBSD
+.Sh NAME
+.Nm Bd-nested
+.Nd nested displays and lists
+.Sh DESCRIPTION
+regular
+text
+.Bd -ragged -offset indent
+outer
+text (default indent)
+.Bd -ragged -offset indent
+inner
+text (default indent)
+.Ed
+outer
+text
+.Ed
+regular
+text
+.Bd -ragged -offset 4n
+outer text (4n)
+.Bd -ragged -offset 2n
+inner text (2n)
+.Ed
+outer text
+.Bl -tag -width 6n
+.It tag
+text
+.El
+outer text
+.Ed
+regular text
+.Bl -tag -width 6n
+.It tag
+outer text
+.Bd -ragged -offset 2n
+inner text (2n)
+.Ed
+outer text
+.El
diff --git a/regress/usr.bin/mandoc/mdoc/Bd/nested.out_ascii b/regress/usr.bin/mandoc/mdoc/Bd/nested.out_ascii
new file mode 100644
index 00000000000..0ce7e4f5bdd
--- /dev/null
+++ b/regress/usr.bin/mandoc/mdoc/Bd/nested.out_ascii
@@ -0,0 +1,29 @@
+BD-NESTED(1) OpenBSD Reference Manual BD-NESTED(1)
+
+NNAAMMEE
+ BBdd--nneesstteedd - nested displays and lists
+
+DDEESSCCRRIIPPTTIIOONN
+ regular text
+
+ outer text (default indent)
+
+ inner text (default indent)
+ outer text
+ regular text
+
+ outer text (4n)
+
+ inner text (2n)
+ outer text
+
+ tag text
+ outer text
+ regular text
+
+ tag outer text
+
+ inner text (2n)
+ outer text
+
+OpenBSD November 18, 2012 OpenBSD
diff --git a/regress/usr.bin/mandoc/mdoc/Bl/Makefile b/regress/usr.bin/mandoc/mdoc/Bl/Makefile
index 06dabcfb0c5..089f8547b27 100644
--- a/regress/usr.bin/mandoc/mdoc/Bl/Makefile
+++ b/regress/usr.bin/mandoc/mdoc/Bl/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.13 2012/11/16 13:25:34 schwarze Exp $
+# $OpenBSD: Makefile,v 1.14 2012/11/18 17:59:03 schwarze Exp $
REGRESS_TARGETS = item inset diag ohang bullet dash enum hang tag
REGRESS_TARGETS += column extend nested
@@ -12,6 +12,6 @@ REGRESS_TARGETS += multitype multitag empty unclosed break broken
SKIP_GROFF ?= empty break broken
-SKIP_TMAN ?= column nested multitype multitag break broken
+SKIP_TMAN ?= column multitype multitag break broken
.include <bsd.regress.mk>
diff --git a/usr.bin/mandoc/mdoc_man.c b/usr.bin/mandoc/mdoc_man.c
index 7716852c6ed..a35f353e6a4 100644
--- a/usr.bin/mandoc/mdoc_man.c
+++ b/usr.bin/mandoc/mdoc_man.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_man.c,v 1.42 2012/11/17 00:25:20 schwarze Exp $ */
+/* $Id: mdoc_man.c,v 1.43 2012/11/18 17:59:03 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -250,6 +250,11 @@ static int outflags;
#define MMAN_An_split (1 << 8) /* author mode is "split" */
#define MMAN_An_nosplit (1 << 9) /* author mode is "nosplit" */
+#define BL_STACK_MAX 32
+
+static size_t Bl_stack[BL_STACK_MAX]; /* offsets [chars] */
+static int Bl_stack_post[BL_STACK_MAX]; /* add final .RE */
+static int Bl_stack_len; /* number of nested Bl blocks */
static int TPremain; /* characters before tag is full */
static struct {
@@ -384,6 +389,7 @@ print_offs(const char *v)
struct roffsu su;
size_t sz;
+ /* Convert v into a number (of characters). */
if (NULL == v || '\0' == *v || 0 == strcmp(v, "left"))
sz = 0;
else if (0 == strcmp(v, "indent"))
@@ -391,11 +397,29 @@ print_offs(const char *v)
else if (0 == strcmp(v, "indent-two"))
sz = 12;
else if (a2roffsu(v, &su, SCALE_MAX)) {
- print_word(v);
- return;
+ if (SCALE_EN == su.unit)
+ sz = su.scale;
+ else {
+ /*
+ * XXX
+ * If we are inside an enclosing list,
+ * there is no easy way to add the two
+ * indentations because they are provided
+ * in terms of different units.
+ */
+ print_word(v);
+ return;
+ }
} else
sz = strlen(v);
+ /*
+ * We are inside an enclosing list.
+ * Add the two indentations.
+ */
+ if (Bl_stack_len)
+ sz += Bl_stack[Bl_stack_len - 1];
+
snprintf(buf, sizeof(buf), "%ldn", sz);
print_word(buf);
}
@@ -410,6 +434,8 @@ print_width(const char *v, const struct mdoc_node *child, size_t defsz)
numeric = 1;
remain = 0;
+
+ /* Convert v into a number (of characters). */
if (NULL == v)
sz = defsz;
else if (a2roffsu(v, &su, SCALE_MAX)) {
@@ -426,6 +452,24 @@ print_width(const char *v, const struct mdoc_node *child, size_t defsz)
chsz = (NULL != child && MDOC_TEXT == child->type) ?
strlen(child->string) : 0;
+ /*
+ * If we are inside an enclosing list,
+ * preserve its indentation.
+ */
+ if (Bl_stack_len && Bl_stack[Bl_stack_len - 1]) {
+ print_line(".RS", 0);
+ snprintf(buf, sizeof(buf), "%ldn",
+ Bl_stack[Bl_stack_len - 1]);
+ print_word(buf);
+ }
+
+ /*
+ * Save our own indentation,
+ * such that child lists can use it.
+ */
+ Bl_stack[Bl_stack_len++] = sz + 2;
+
+ /* Set up the current list. */
if (defsz && chsz > sz)
print_block(".HP", 0);
else {
@@ -764,11 +808,28 @@ pre_bd(DECL_ARGS)
static void
post_bd(DECL_ARGS)
{
+ char buf[24];
+ /* Close out this display. */
print_line(".RE", MMAN_nl);
if (DISP_unfilled == n->norm->Bd.type ||
DISP_literal == n->norm->Bd.type)
print_line(".fi", MMAN_nl);
+
+ /*
+ * If we are inside an enclosing list and the current
+ * list item is not yet finished, restore the correct
+ * indentation for what remains of that item.
+ */
+ if (NULL != n->parent->next &&
+ Bl_stack_len && Bl_stack[Bl_stack_len - 1]) {
+ print_line(".RS", 0);
+ snprintf(buf, sizeof(buf), "%ldn",
+ Bl_stack[Bl_stack_len - 1]);
+ print_word(buf);
+ /* Remeber to close out this .RS block later. */
+ Bl_stack_post[Bl_stack_len - 1] = 1;
+ }
}
static int
@@ -1194,10 +1255,46 @@ post_it(DECL_ARGS)
}
break;
case (MDOC_BODY):
- if (LIST_column == bln->norm->Bl.type &&
- NULL != n->next) {
- putchar('\t');
- outflags &= ~MMAN_spc;
+ switch (bln->norm->Bl.type) {
+ case (LIST_bullet):
+ /* FALLTHROUGH */
+ case (LIST_dash):
+ /* FALLTHROUGH */
+ case (LIST_hyphen):
+ /* FALLTHROUGH */
+ case (LIST_enum):
+ /* FALLTHROUGH */
+ case (LIST_hang):
+ /* FALLTHROUGH */
+ case (LIST_tag):
+ assert(Bl_stack_len);
+ Bl_stack[--Bl_stack_len] = 0;
+
+ /*
+ * Our indentation had to be restored
+ * after a child display.
+ * Close out that indentation block now.
+ */
+ if (Bl_stack_post[Bl_stack_len]) {
+ print_line(".RE", MMAN_nl);
+ Bl_stack_post[Bl_stack_len] = 0;
+ }
+
+ /*
+ * We are inside an enclosing list.
+ * Restore the indentation of that list.
+ */
+ if (Bl_stack_len && Bl_stack[Bl_stack_len - 1])
+ print_line(".RE", MMAN_nl);
+ break;
+ case (LIST_column):
+ if (NULL != n->next) {
+ putchar('\t');
+ outflags &= ~MMAN_spc;
+ }
+ break;
+ default:
+ break;
}
break;
default: