* mandoc: In the tbl(7) layout parser, use the roff(7) numerical
@ 2025-01-05 18:14 schwarze
0 siblings, 0 replies; only message in thread
From: schwarze @ 2025-01-05 18:14 UTC (permalink / raw)
To: source
Log Message:
-----------
In the tbl(7) layout parser, use the roff(7) numerical expression parser
to support arithmetic operations in column width modifiers.
Documentation authors ought to focus on semantic markup and avoid trying
to manipulate presentational details. Consequently, using tbl(7) is
discouraged in the first place, using column width modifiers even more
so, and complicating them by performing arithmetics yet more so.
However, the madhouse called DocBook relies on this feature.
For example, DocBook XSL version 1.79.2 generates man(7)+tbl(7) code
that abuses arithmetics in column width modifiers to format things
as simple and mundane as numbered lists, resulting in atrocious layout
that is very hard to read. Last year, tb@ reported git-reset(1)
as an example of an affected manual page.
Properly parsing the width in the tbl(7) parser allows removal of some
incomplete ad-hoc parsing from the tbl(7) formatter, where it didn't
really belong.
Modified Files:
--------------
mandoc:
mandoc.1
mandoc.h
mandoc_msg.c
out.c
tbl.c
tbl.h
tbl_layout.c
mandoc/regress/tbl/mod:
width.in
width.out_ascii
Revision Data
-------------
Index: tbl_layout.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/tbl_layout.c,v
diff -Ltbl_layout.c -Ltbl_layout.c -u -p -r1.50 -r1.51
--- tbl_layout.c
+++ tbl_layout.c
@@ -1,8 +1,8 @@
/* $Id$ */
/*
- * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2012, 2014, 2015, 2017, 2020, 2021
+ * Copyright (c) 2012, 2014, 2015, 2017, 2020, 2021, 2025
* Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2009, 2010, 2011 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
@@ -67,7 +67,6 @@ mods(struct tbl_node *tbl, struct tbl_ce
{
char *endptr;
unsigned long spacing;
- size_t sz;
int isz;
enum mandoc_esc fontesc;
@@ -138,20 +137,27 @@ mod:
cp->flags |= TBL_CELL_UP;
goto mod;
case 'w':
- sz = 0;
if (p[*pos] == '(') {
(*pos)++;
- while (p[*pos + sz] != '\0' && p[*pos + sz] != ')')
- sz++;
- } else
- while (isdigit((unsigned char)p[*pos + sz]))
- sz++;
- if (sz) {
- free(cp->wstr);
- cp->wstr = mandoc_strndup(p + *pos, sz);
- *pos += sz;
- if (p[*pos] == ')')
+ isz = 0;
+ if (roff_evalnum(ln, p, pos, &isz, 'n', 1) == 0 ||
+ p[*pos] != ')')
+ mandoc_msg(MANDOCERR_TBLLAYOUT_WIDTH,
+ ln, *pos, "%s", p + *pos);
+ else {
+ /* Convert from BU to EN and round. */
+ cp->width = (isz + 11) /24;
(*pos)++;
+ }
+ } else {
+ cp->width = 0;
+ while (isdigit((unsigned char)p[*pos])) {
+ cp->width *= 10;
+ cp->width += p[(*pos)++] - '0';
+ }
+ if (cp->width == 0)
+ mandoc_msg(MANDOCERR_TBLLAYOUT_WIDTH,
+ ln, *pos, "%s", p + *pos);
}
goto mod;
case 'x':
Index: tbl.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/tbl.c,v
diff -Ltbl.c -Ltbl.c -u -p -r1.46 -r1.47
--- tbl.c
+++ tbl.c
@@ -118,7 +118,6 @@ tbl_free(struct tbl_node *tbl)
while (rp->first != NULL) {
cp = rp->first;
rp->first = cp->next;
- free(cp->wstr);
free(cp);
}
free(rp);
Index: mandoc_msg.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/mandoc_msg.c,v
diff -Lmandoc_msg.c -Lmandoc_msg.c -u -p -r1.20 -r1.21
--- mandoc_msg.c
+++ mandoc_msg.c
@@ -1,6 +1,6 @@
/* $OpenBSD: mandoc_msg.c,v 1.8 2020/01/19 17:59:01 schwarze Exp $ */
/*
- * Copyright (c) 2014-2022 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014-2022, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -192,6 +192,7 @@ static const char *const type_message[MA
"empty tbl layout",
"invalid character in tbl layout",
"unmatched parenthesis in tbl layout",
+ "ignoring invalid column width in tbl layout",
"ignoring excessive spacing in tbl layout",
"tbl without any data cells",
"ignoring data in spanned tbl cell",
Index: mandoc.h
===================================================================
RCS file: /home/cvs/mandoc/mandoc/mandoc.h,v
diff -Lmandoc.h -Lmandoc.h -u -p -r1.282 -r1.283
--- mandoc.h
+++ mandoc.h
@@ -1,6 +1,6 @@
/* $Id$ */
/*
- * Copyright (c) 2012-2022 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2012-2022, 2025 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -193,6 +193,7 @@ enum mandocerr {
MANDOCERR_TBLLAYOUT_NONE, /* empty tbl layout */
MANDOCERR_TBLLAYOUT_CHAR, /* invalid character in tbl layout: char */
MANDOCERR_TBLLAYOUT_PAR, /* unmatched parenthesis in tbl layout */
+ MANDOCERR_TBLLAYOUT_WIDTH, /* invalid column width in tbl layout */
MANDOCERR_TBLLAYOUT_SPC, /* ignoring excessive spacing in tbl layout */
MANDOCERR_TBLDATA_NONE, /* tbl without any data cells */
MANDOCERR_TBLDATA_SPAN, /* ignoring data in spanned tbl cell: data */
Index: mandoc.1
===================================================================
RCS file: /home/cvs/mandoc/mandoc/mandoc.1,v
diff -Lmandoc.1 -Lmandoc.1 -u -p -r1.267 -r1.268
--- mandoc.1
+++ mandoc.1
@@ -1,6 +1,6 @@
.\" $Id$
.\"
-.\" Copyright (c) 2012, 2014-2023 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2012, 2014-2023, 2025 Ingo Schwarze <schwarze@openbsd.org>
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
@@ -1896,6 +1896,12 @@ The invalid character is discarded.
A table layout specification contains an opening parenthesis,
but no matching closing parenthesis.
The rest of the input line, starting from the parenthesis, has no effect.
+.It Sy "ignoring invalid column width in tbl layout"
+.Pq tbl
+A column width specifier in a table layout is empty, zero, or not a valid
+numerical expression.
+The width specifier is ignored and the column is made wide enough
+to accomodate all its data cells.
.It Sy "ignoring excessive spacing in tbl layout"
.Pq tbl
A spacing modifier in a table layout is unreasonably large.
Index: tbl.h
===================================================================
RCS file: /home/cvs/mandoc/mandoc/tbl.h,v
diff -Ltbl.h -Ltbl.h -u -p -r1.2 -r1.3
--- tbl.h
+++ tbl.h
@@ -51,7 +51,6 @@ enum tbl_cellt {
*/
struct tbl_cell {
struct tbl_cell *next; /* Layout cell to the right. */
- char *wstr; /* Min width represented as a string. */
size_t width; /* Minimum column width. */
size_t spacing; /* To the right of the column. */
int vert; /* Width of subsequent vertical line. */
Index: out.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/out.c,v
diff -Lout.c -Lout.c -u -p -r1.85 -r1.86
--- out.c
+++ out.c
@@ -117,7 +117,6 @@ void
tblcalc(struct rofftbl *tbl, const struct tbl_span *sp_first,
size_t offset, size_t rmargin)
{
- struct roffsu su;
const struct tbl_opts *opts;
const struct tbl_span *sp;
const struct tbl_dat *dp;
@@ -159,13 +158,6 @@ tblcalc(struct rofftbl *tbl, const struc
continue;
/* Handle explicit width specifications. */
-
- if (dp->layout->wstr != NULL &&
- dp->layout->width == 0 &&
- a2roffsu(dp->layout->wstr, &su, SCALE_EN)
- != NULL)
- dp->layout->width =
- (*tbl->sulen)(&su, tbl->arg);
if (col->width < dp->layout->width)
col->width = dp->layout->width;
if (dp->layout->spacing != SIZE_MAX &&
Index: width.out_ascii
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/tbl/mod/width.out_ascii,v
diff -Lregress/tbl/mod/width.out_ascii -Lregress/tbl/mod/width.out_ascii -u -p -r1.4 -r1.5
--- regress/tbl/mod/width.out_ascii
+++ regress/tbl/mod/width.out_ascii
@@ -4,9 +4,53 @@ N\bNA\bAM\bME\bE
tbl-mod-width - width modifier in table layout
D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
- normal text
+ Bare numbers without parentheses use EN units:
+ +---+------+
+ |a | abcd |
+ +---+------+
+
+ Explicit scaling units and rounding - metric:
+ +-----+
+ |1cm |
+ +-----+
+
+ Explicit scaling units and rounding - pica:
+ +---+
+ |P |
+ +---+
+ +----+
+ |2P |
+ +----+
+
+ Explicit scaling units and rounding - points:
+ +----+
+ |25p |
+ +----+
+ +-----+
+ |26p |
+ +-----+
+
+ Explicit scaling units and rounding - basic units:
+ +----+
+ |84u |
+ +----+
+ +-----+
+ |85u |
+ +-----+
+
+ Multiplication:
+ +-------+--------+--------+--------+
+ |3n*2u | 3u*2n | 3u*2 | 3*2u |
+ +-------+--------+--------+--------+
+
+ Division:
+ +--------+----------+--------+--------+
+ |14n/2u | 384n/2n | 12/2u | 288/2 |
+ +--------+----------+--------+--------+
+
+ Data section containing text blocks:
+---+------+----+------+
|a | abcd | a | abcd |
+---+------+----+------+
-OpenBSD June 8, 2017 TBL-MOD-WIDTH(1)
+OpenBSD January 4, 2025 TBL-MOD-WIDTH(1)
Index: width.in
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/tbl/mod/width.in,v
diff -Lregress/tbl/mod/width.in -Lregress/tbl/mod/width.in -u -p -r1.3 -r1.4
--- regress/tbl/mod/width.in
+++ regress/tbl/mod/width.in
@@ -1,12 +1,76 @@
-.\" $OpenBSD: width.in,v 1.3 2017/07/04 14:53:27 schwarze Exp $
-.TH TBL-MOD-WIDTH 1 "June 8, 2017"
+.\" $OpenBSD: width.in,v 1.4 2025/01/05 18:03:51 schwarze Exp $
+.TH TBL-MOD-WIDTH 1 "January 4, 2025"
.SH NAME
tbl-mod-width \- width modifier in table layout
.SH DESCRIPTION
-normal text
+Bare numbers without parentheses use EN units:
.TS
box tab(:);
-lw2 | lw(2n) | lw(0.16i) | lw2 .
+Lw2 | Lw3 .
+a:abcd
+.TE
+.PP
+Explicit scaling units and rounding \(en metric:
+.TS
+box tab(:);
+Lw(1c).
+1cm
+.TE
+.PP
+Explicit scaling units and rounding \(en pica:
+.TS
+box tab(:);
+Lw(1P).
+P
+.TE
+.TS
+box tab(:);
+Lw(2P).
+2P
+.TE
+.PP
+Explicit scaling units and rounding \(en points:
+.TS
+box tab(:);
+Lw(25p).
+25p
+.TE
+.TS
+box tab(:);
+Lw(26p).
+26p
+.TE
+.PP
+Explicit scaling units and rounding \(en basic units:
+.TS
+box tab(:);
+Lw(84u).
+84u
+.TE
+.TS
+box tab(:);
+Lw(85u).
+85u
+.TE
+.PP
+Multiplication:
+.TS
+box tab(:);
+Lw(3n*2u) | Lw(3u*2n) | Lw(3u*2) | Cw(3*2u).
+3n*2u:3u*2n:3u*2:3*2u
+.TE
+.PP
+Division:
+.TS
+box tab(:);
+Lw(14n/2u) | Lw(384n/2n) | Lw(12/2u) | Lw(288/2).
+14n/2u:384n/2n:12/2u:288/2
+.TE
+.PP
+Data section containing text blocks:
+.TS
+box tab(:);
+lw2 | lw(2n) | lw(2m) | lw2 .
a:abcd:T{
a
T}:T{
--
To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2025-01-05 18:14 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-05 18:14 mandoc: In the tbl(7) layout parser, use the roff(7) numerical schwarze
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).