summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2014-10-30 20:10:02 +0000
committerIngo Schwarze <schwarze@openbsd.org>2014-10-30 20:10:02 +0000
commitb1573399d364f789f4e71b2dc02d52688bdd1605 (patch)
treeb001869ef99a8d43fed78d8b8891370fbebd7e8c
parent43e328cce4bb9763404660bc28b055e4959842f3 (diff)
downloadmandoc-b1573399d364f789f4e71b2dc02d52688bdd1605.tar.gz
Major bugsquashing with respect to -offset and -width:
1. Support specifying the .Bd and .Bl -offset as a macro default width; while here, simplify the code handling the same for .Bl -width. 2. Correct handling of .Bl -offset arguments: unlike .Bd -offset, the arguments "left", "indent", and "indent-two" have no special meaning. 3. Fix the scaling of string length -offset and -width arguments in -Thtml. Triggered by an incomplete documentation patch from bentley@.
-rw-r--r--mdoc.77
-rw-r--r--mdoc_html.c40
-rw-r--r--mdoc_man.c16
-rw-r--r--mdoc_term.c37
-rw-r--r--mdoc_validate.c60
5 files changed, 56 insertions, 104 deletions
diff --git a/mdoc.7 b/mdoc.7
index 1799628e..9aa77fd1 100644
--- a/mdoc.7
+++ b/mdoc.7
@@ -937,8 +937,11 @@ The
.Fl width
and
.Fl offset
-arguments accept scaling widths as described in
-.Xr roff 7
+arguments accept macro names as described for
+.Sx \&Bd
+.Fl offset ,
+scaling widths as described in
+.Xr roff 7 ,
or use the length of the given string.
The
.Fl offset
diff --git a/mdoc_html.c b/mdoc_html.c
index 1038f3a9..04d3883e 100644
--- a/mdoc_html.c
+++ b/mdoc_html.c
@@ -56,7 +56,6 @@ static void synopsis_pre(struct html *,
const struct mdoc_node *);
static void a2width(const char *, struct roffsu *);
-static void a2offs(const char *, struct roffsu *);
static void mdoc_root_post(MDOC_ARGS);
static int mdoc_root_pre(MDOC_ARGS);
@@ -281,7 +280,7 @@ a2width(const char *p, struct roffsu *su)
{
if ( ! a2roffsu(p, su, SCALE_MAX)) {
- su->unit = SCALE_BU;
+ su->unit = SCALE_EN;
su->scale = html_strlen(p);
}
}
@@ -328,27 +327,6 @@ synopsis_pre(struct html *h, const struct mdoc_node *n)
}
}
-/*
- * Calculate the scaling unit passed in an `-offset' argument. This
- * uses either a native scaling unit (e.g., 1i, 2m), one of a set of
- * predefined strings (indent, etc.), or the string length of the value.
- */
-static void
-a2offs(const char *p, struct roffsu *su)
-{
-
- /* FIXME: "right"? */
-
- if (0 == strcmp(p, "left"))
- SCALE_HS_INIT(su, 0);
- else if (0 == strcmp(p, "indent"))
- SCALE_HS_INIT(su, INDENT);
- else if (0 == strcmp(p, "indent-two"))
- SCALE_HS_INIT(su, INDENT * 2);
- else if ( ! a2roffsu(p, su, SCALE_MAX))
- SCALE_HS_INIT(su, html_strlen(p));
-}
-
static void
print_mdoc(MDOC_ARGS)
{
@@ -994,7 +972,7 @@ mdoc_bl_pre(MDOC_ARGS)
/* Set the block's left-hand margin. */
if (n->norm->Bl.offs) {
- a2offs(n->norm->Bl.offs, &su);
+ a2width(n->norm->Bl.offs, &su);
bufcat_su(h, "margin-left", &su);
}
@@ -1160,9 +1138,17 @@ mdoc_bd_pre(MDOC_ARGS)
return(1);
}
- SCALE_HS_INIT(&su, 0);
- if (n->norm->Bd.offs)
- a2offs(n->norm->Bd.offs, &su);
+ /* Handle the -offset argument. */
+
+ if (n->norm->Bd.offs == NULL ||
+ ! strcmp(n->norm->Bd.offs, "left"))
+ SCALE_HS_INIT(&su, 0);
+ else if ( ! strcmp(n->norm->Bd.offs, "indent"))
+ SCALE_HS_INIT(&su, INDENT);
+ else if ( ! strcmp(n->norm->Bd.offs, "indent-two"))
+ SCALE_HS_INIT(&su, INDENT * 2);
+ else
+ a2width(n->norm->Bd.offs, &su);
bufinit(h);
bufcat_su(h, "margin-left", &su);
diff --git a/mdoc_man.c b/mdoc_man.c
index 50999427..309b508f 100644
--- a/mdoc_man.c
+++ b/mdoc_man.c
@@ -112,7 +112,7 @@ static int pre_xr(DECL_ARGS);
static void print_word(const char *);
static void print_line(const char *, int);
static void print_block(const char *, int);
-static void print_offs(const char *);
+static void print_offs(const char *, int);
static void print_width(const char *,
const struct mdoc_node *, size_t);
static void print_count(int *);
@@ -416,7 +416,7 @@ print_block(const char *s, int newflags)
}
static void
-print_offs(const char *v)
+print_offs(const char *v, int keywords)
{
char buf[24];
struct roffsu su;
@@ -425,11 +425,11 @@ print_offs(const char *v)
print_line(".RS", MMAN_Bk_susp);
/* Convert v into a number (of characters). */
- if (NULL == v || '\0' == *v || 0 == strcmp(v, "left"))
+ if (NULL == v || '\0' == *v || (keywords && !strcmp(v, "left")))
sz = 0;
- else if (0 == strcmp(v, "indent"))
+ else if (keywords && !strcmp(v, "indent"))
sz = 6;
- else if (0 == strcmp(v, "indent-two"))
+ else if (keywords && !strcmp(v, "indent-two"))
sz = 12;
else if (a2roffsu(v, &su, SCALE_MAX)) {
if (SCALE_EN == su.unit)
@@ -876,7 +876,7 @@ pre_bd(DECL_ARGS)
print_line(".nf", 0);
if (0 == n->norm->Bd.comp && NULL != n->parent->prev)
outflags |= MMAN_sp;
- print_offs(n->norm->Bd.offs);
+ print_offs(n->norm->Bd.offs, 1);
return(1);
}
@@ -963,7 +963,7 @@ pre_bl(DECL_ARGS)
* just nest and do not add up their indentation.
*/
if (n->norm->Bl.offs) {
- print_offs(n->norm->Bl.offs);
+ print_offs(n->norm->Bl.offs, 0);
Bl_stack[Bl_stack_len++] = 0;
}
@@ -1048,7 +1048,7 @@ static int
pre_dl(DECL_ARGS)
{
- print_offs("6n");
+ print_offs("6n", 0);
return(1);
}
diff --git a/mdoc_term.c b/mdoc_term.c
index 95643e27..78c81b32 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -51,7 +51,6 @@ struct termact {
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 void print_bvspace(struct termp *,
const struct mdoc_node *,
@@ -550,27 +549,6 @@ a2width(const struct termp *p, const char *v)
return(term_hspan(p, &su));
}
-static size_t
-a2offs(const struct termp *p, const char *v)
-{
- struct roffsu su;
-
- if ('\0' == *v)
- return(0);
- else if (0 == strcmp(v, "left"))
- return(0);
- else if (0 == strcmp(v, "indent"))
- return(term_len(p, p->defindent + 1));
- else if (0 == strcmp(v, "indent-two"))
- return(term_len(p, (p->defindent + 1) * 2));
- else if ( ! a2roffsu(v, &su, SCALE_MAX)) {
- SCALE_HS_INIT(&su, term_strlen(p, v));
- su.scale /= term_strlen(p, "0");
- }
-
- return(term_hspan(p, &su));
-}
-
/*
* 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,
@@ -659,7 +637,7 @@ termp_it_pre(DECL_ARGS)
width = offset = 0;
if (bl->norm->Bl.offs)
- offset = a2offs(p, bl->norm->Bl.offs);
+ offset = a2width(p, bl->norm->Bl.offs);
switch (type) {
case LIST_column:
@@ -1581,8 +1559,17 @@ termp_bd_pre(DECL_ARGS)
} else if (MDOC_HEAD == n->type)
return(0);
- if (n->norm->Bd.offs)
- p->offset += a2offs(p, n->norm->Bd.offs);
+ /* Handle the -offset argument. */
+
+ if (n->norm->Bd.offs == NULL ||
+ ! strcmp(n->norm->Bd.offs, "left"))
+ /* nothing */;
+ else if ( ! strcmp(n->norm->Bd.offs, "indent"))
+ p->offset += term_len(p, p->defindent + 1);
+ else if ( ! strcmp(n->norm->Bd.offs, "indent-two"))
+ p->offset += term_len(p, (p->defindent + 1) * 2);
+ else
+ p->offset += a2width(p, n->norm->Bd.offs);
/*
* If -ragged or -filled are specified, the block does nothing
diff --git a/mdoc_validate.c b/mdoc_validate.c
index 2e3d0066..977bf073 100644
--- a/mdoc_validate.c
+++ b/mdoc_validate.c
@@ -70,6 +70,7 @@ static void check_args(struct mdoc *, struct mdoc_node *);
static int child_an(const struct mdoc_node *);
static enum mdoc_sec a2sec(const char *);
static size_t macro2len(enum mdoct);
+static void rewrite_macro2len(char **);
static int ebool(POST_ARGS);
static int berr_ge1(POST_ARGS);
@@ -88,7 +89,6 @@ static int post_bf(POST_ARGS);
static int post_bk(POST_ARGS);
static int post_bl(POST_ARGS);
static int post_bl_block(POST_ARGS);
-static int post_bl_block_width(POST_ARGS);
static int post_bl_block_tag(POST_ARGS);
static int post_bl_head(POST_ARGS);
static int post_bx(POST_ARGS);
@@ -597,6 +597,7 @@ pre_bl(PRE_ARGS)
mdoc->parse, argv->line,
argv->pos, "Bl -width %s",
argv->value[0]);
+ rewrite_macro2len(argv->value);
n->norm->Bl.width = argv->value[0];
break;
case MDOC_Offset:
@@ -611,6 +612,7 @@ pre_bl(PRE_ARGS)
mdoc->parse, argv->line,
argv->pos, "Bl -offset %s",
argv->value[0]);
+ rewrite_macro2len(argv->value);
n->norm->Bl.offs = argv->value[0];
break;
default:
@@ -758,6 +760,7 @@ pre_bd(PRE_ARGS)
mdoc->parse, argv->line,
argv->pos, "Bd -offset %s",
argv->value[0]);
+ rewrite_macro2len(argv->value);
n->norm->Bd.offs = argv->value[0];
break;
case MDOC_Compact:
@@ -1336,10 +1339,6 @@ post_bl_block(POST_ARGS)
if ( ! post_bl_block_tag(mdoc))
return(0);
assert(n->norm->Bl.width);
- } else if (NULL != n->norm->Bl.width) {
- if ( ! post_bl_block_width(mdoc))
- return(0);
- assert(n->norm->Bl.width);
}
for (ni = n->body->child; ni; ni = ni->next) {
@@ -1379,50 +1378,27 @@ post_bl_block(POST_ARGS)
return(1);
}
-static int
-post_bl_block_width(POST_ARGS)
+/*
+ * If the argument of -offset or -width is a macro,
+ * replace it with the associated default width.
+ */
+void
+rewrite_macro2len(char **arg)
{
size_t width;
- int i;
enum mdoct tok;
- struct mdoc_node *n;
- char buf[24];
-
- n = mdoc->last;
- /*
- * Calculate the real width of a list from the -width string,
- * which may contain a macro (with a known default width), a
- * literal string, or a scaling width.
- *
- * If the value to -width is a macro, then we re-write it to be
- * the macro's width as set in share/tmac/mdoc/doc-common.
- */
-
- if (0 == strcmp(n->norm->Bl.width, "Ds"))
+ if (*arg == NULL)
+ return;
+ else if ( ! strcmp(*arg, "Ds"))
width = 6;
- else if (MDOC_MAX == (tok = mdoc_hash_find(n->norm->Bl.width)))
- return(1);
+ else if ((tok = mdoc_hash_find(*arg)) == MDOC_MAX)
+ return;
else
width = macro2len(tok);
- /* The value already exists: free and reallocate it. */
-
- assert(n->args);
-
- for (i = 0; i < (int)n->args->argc; i++)
- if (MDOC_Width == n->args->argv[i].arg)
- break;
-
- assert(i < (int)n->args->argc);
-
- (void)snprintf(buf, sizeof(buf), "%un", (unsigned int)width);
- free(n->args->argv[i].value[0]);
- n->args->argv[i].value[0] = mandoc_strdup(buf);
-
- /* Set our width! */
- n->norm->Bl.width = n->args->argv[i].value[0];
- return(1);
+ free(*arg);
+ mandoc_asprintf(arg, "%zun", width);
}
static int
@@ -1437,7 +1413,7 @@ post_bl_block_tag(POST_ARGS)
* Calculate the -width for a `Bl -tag' list if it hasn't been
* provided. Uses the first head macro. NOTE AGAIN: this is
* ONLY if the -width argument has NOT been provided. See
- * post_bl_block_width() for converting the -width string.
+ * rewrite_macro2len() for converting the -width string.
*/
sz = 10;