* Re: Description of Bl ... -width
2014-10-29 3:40 Description of Bl ... -width Anthony J. Bentley
@ 2014-10-30 20:15 ` Ingo Schwarze
0 siblings, 0 replies; 2+ messages in thread
From: Ingo Schwarze @ 2014-10-30 20:15 UTC (permalink / raw)
To: Anthony J. Bentley; +Cc: tech
Hi Anthony,
Anthony J. Bentley wrote on Tue, Oct 28, 2014 at 09:40:36PM -0600:
> I've spent a long time blindly typing ".Bl -tag -width Ds" without
> understanding what it meant. In the back of my mind I just assumed Ds
> triggered an indent of two characters, never noticing that the indent
> in the result is obviously not two characters.
>
> This is what mdoc(7) says about the -width argument to Bl:
>
> The -width and -offset arguments accept scaling widths as
> described in roff(7) or use the length of the given string.
You are right, that is incomplete.
> In reality:
>
> /*
> * 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.
> */
>
> The macro part is documented in mdoc(7), but only under Bd's -offset:
>
> -offset width Indent the display by the width, which may
> be one of the following:
> ...
> A macro invocation, which selects a predefined width
> associated with that macro. The most popular is the
> imaginary macro Ds, which resolves to 6n.
> ...
>
> It looks like Bl's -offset matches the manual and doesn't support
> determining macro widths.
Which, actually, was a bug.
By the way, there was another bug. Bl -offset treated "left",
"indent", and "indent-two" specially just like Bd -offset,
which it should not do.
> So that leaves just Bl's -width that is documented wrong.
It's true that Bl -width is documented incompletely,
but so is Bl -offset.
> Here is an attempt to fix it--does this make sense?
> But I'm not sure the paragraph flows very well now.
The fact that both -width and -offset were documented wrongly
allowed an easier fix that i committed together with the
required code changes and regression tests.
Thanks for the report!
Ingo
Log Message:
-----------
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@.
Modified Files:
--------------
mdocml:
mdoc.7
mdoc_html.c
mdoc_man.c
mdoc_term.c
mdoc_validate.c
Revision Data
-------------
Index: mdoc_man.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_man.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -Lmdoc_man.c -Lmdoc_man.c -u -p -r1.70 -r1.71
--- mdoc_man.c
+++ 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);
}
Index: mdoc_validate.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_validate.c,v
retrieving revision 1.253
retrieving revision 1.254
diff -Lmdoc_validate.c -Lmdoc_validate.c -u -p -r1.253 -r1.254
--- mdoc_validate.c
+++ mdoc_validate.c
@@ -70,6 +70,7 @@ static void check_args(struct mdoc *, s
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;
Index: mdoc_html.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_html.c,v
retrieving revision 1.208
retrieving revision 1.209
diff -Lmdoc_html.c -Lmdoc_html.c -u -p -r1.208 -r1.209
--- mdoc_html.c
+++ 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 struc
}
}
-/*
- * 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);
Index: mdoc_term.c
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc_term.c,v
retrieving revision 1.287
retrieving revision 1.288
diff -Lmdoc_term.c -Lmdoc_term.c -u -p -r1.287 -r1.288
--- mdoc_term.c
+++ 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 cha
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
Index: mdoc.7
===================================================================
RCS file: /usr/vhosts/mdocml.bsd.lv/cvs/mdocml/mdoc.7,v
retrieving revision 1.239
retrieving revision 1.240
diff -Lmdoc.7 -Lmdoc.7 -u -p -r1.239 -r1.240
--- mdoc.7
+++ 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
--
To unsubscribe send an email to tech+unsubscribe@mdocml.bsd.lv
^ permalink raw reply [flat|nested] 2+ messages in thread