source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Implement w layout specifier (minimum column width).
@ 2017-06-08 18:11 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2017-06-08 18:11 UTC (permalink / raw)
  To: source

Log Message:
-----------
Implement w layout specifier (minimum column width).
Improve width calculation of text blocks.
Reduces the groff/mandoc diff in Base+Xenocara by about 800 lines.

Modified Files:
--------------
    mdocml:
        mandoc.h
        out.c
        out.h
        tbl.7
        tbl.c
        tbl_data.c
        tbl_html.c
        tbl_layout.c
        tbl_term.c
    mdocml/regress/tbl/mod:
        Makefile

Added Files:
-----------
    mdocml/regress/tbl/mod:
        width.in
        width.out_ascii

Revision Data
-------------
Index: tbl_html.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/tbl_html.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -Ltbl_html.c -Ltbl_html.c -u -p -r1.20 -r1.21
--- tbl_html.c
+++ tbl_html.c
@@ -31,22 +31,48 @@
 static	void	 html_tblopen(struct html *, const struct tbl_span *);
 static	size_t	 html_tbl_len(size_t, void *);
 static	size_t	 html_tbl_strlen(const char *, void *);
+static	size_t	 html_tbl_sulen(const struct roffsu *, void *);
 
 
 static size_t
 html_tbl_len(size_t sz, void *arg)
 {
-
 	return sz;
 }
 
 static size_t
 html_tbl_strlen(const char *p, void *arg)
 {
-
 	return strlen(p);
 }
 
+static size_t
+html_tbl_sulen(const struct roffsu *su, void *arg)
+{
+	switch (su->unit) {
+	case SCALE_FS:  /* 2^16 basic units */
+		return su->scale * 65536.0 / 24.0;
+	case SCALE_IN:  /* 10 characters per inch */
+		return su->scale * 10.0;
+	case SCALE_CM:  /* 2.54 cm per inch */
+		return su->scale * 10.0 / 2.54;
+	case SCALE_PC:  /* 6 pica per inch */
+	case SCALE_VS:
+		return su->scale * 10.0 / 6.0;
+	case SCALE_EN:
+	case SCALE_EM:
+		return su->scale;
+	case SCALE_PT:  /* 12 points per pica */
+		return su->scale * 10.0 / 6.0 / 12.0;
+	case SCALE_BU:  /* 24 basic units per character */
+		return su->scale / 24.0;
+	case SCALE_MM:  /* 1/1000 inch */
+		return su->scale / 100.0;
+	default:
+		abort();
+	}
+}
+
 static void
 html_tblopen(struct html *h, const struct tbl_span *sp)
 {
@@ -56,6 +82,7 @@ html_tblopen(struct html *h, const struc
 	if (h->tbl.cols == NULL) {
 		h->tbl.len = html_tbl_len;
 		h->tbl.slen = html_tbl_strlen;
+		h->tbl.sulen = html_tbl_sulen;
 		tblcalc(&h->tbl, sp, 0);
 	}
 
Index: tbl.7
===================================================================
RCS file: /home/cvs/mdocml/mdocml/tbl.7,v
retrieving revision 1.26
retrieving revision 1.27
diff -Ltbl.7 -Ltbl.7 -u -p -r1.26 -r1.27
--- tbl.7
+++ tbl.7
@@ -1,7 +1,7 @@
 .\"	$Id$
 .\"
 .\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
-.\" Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2014, 2015, 2017 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
@@ -245,7 +245,7 @@ Emit a double-vertical bar instead of da
 .Pp
 Keys may be followed by a set of modifiers.
 A modifier is either a modifier key or a natural number for specifying
-the minimum width of a column.
+the spacing to the right of the column.
 The following case-insensitive modifier keys are available:
 .Bl -tag -width 2n
 .It Cm b
@@ -284,8 +284,7 @@ Currently ignored.
 Move cell content up by half a table line.
 Currently ignored.
 .It Cm w
-Specify minimum column width.
-Currently ignored.
+Specify the minimum column width.
 .It Cm x
 After determining the width of all other columns, distribute the
 rest of the line length among all columns having the
@@ -300,7 +299,7 @@ minimum width 10, followed by vertical b
 column of minimum width 10, another vertical bar, then a column using
 bold font justified about the decimal point in numbers:
 .Pp
-.Dl c10 | l10 | nfB
+.Dl cw10 | lw10 | nfB
 .Ss Data
 The data section follows the last layout row.
 By default, cells in a data section are delimited by a tab.
Index: tbl_data.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/tbl_data.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -Ltbl_data.c -Ltbl_data.c -u -p -r1.41 -r1.42
--- tbl_data.c
+++ tbl_data.c
@@ -1,7 +1,7 @@
 /*	$Id$ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011, 2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011, 2015, 2017 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
@@ -144,6 +144,7 @@ tbl_cdata(struct tbl_node *tbl, int ln, 
 	}
 
 	dat->pos = TBL_DATA_DATA;
+	dat->block = 1;
 
 	if (dat->string != NULL) {
 		sz = strlen(p + pos) + strlen(dat->string) + 2;
Index: tbl_term.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/tbl_term.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -Ltbl_term.c -Ltbl_term.c -u -p -r1.45 -r1.46
--- tbl_term.c
+++ tbl_term.c
@@ -30,6 +30,7 @@
 
 static	size_t	term_tbl_len(size_t, void *);
 static	size_t	term_tbl_strlen(const char *, void *);
+static	size_t	term_tbl_sulen(const struct roffsu *, void *);
 static	void	tbl_char(struct termp *, char, size_t);
 static	void	tbl_data(struct termp *, const struct tbl_opts *,
 			const struct tbl_dat *,
@@ -44,16 +45,20 @@ static	void	tbl_word(struct termp *, con
 
 
 static size_t
-term_tbl_strlen(const char *p, void *arg)
+term_tbl_sulen(const struct roffsu *su, void *arg)
 {
+	return term_hspan((const struct termp *)arg, su) / 24;
+}
 
+static size_t
+term_tbl_strlen(const char *p, void *arg)
+{
 	return term_strlen((const struct termp *)arg, p);
 }
 
 static size_t
 term_tbl_len(size_t sz, void *arg)
 {
-
 	return term_len((const struct termp *)arg, sz);
 }
 
@@ -78,6 +83,7 @@ term_tbl(struct termp *tp, const struct 
 	if (tp->tbl.cols == NULL) {
 		tp->tbl.len = term_tbl_len;
 		tp->tbl.slen = term_tbl_strlen;
+		tp->tbl.sulen = term_tbl_sulen;
 		tp->tbl.arg = tp;
 
 		tblcalc(&tp->tbl, sp, tp->tcol->rmargin - tp->tcol->offset);
Index: mandoc.h
===================================================================
RCS file: /home/cvs/mdocml/mdocml/mandoc.h,v
retrieving revision 1.225
retrieving revision 1.226
diff -Lmandoc.h -Lmandoc.h -u -p -r1.225 -r1.226
--- mandoc.h
+++ mandoc.h
@@ -246,9 +246,10 @@ enum	tbl_cellt {
  */
 struct	tbl_cell {
 	struct tbl_cell	 *next;
+	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 */
-	enum tbl_cellt	  pos;
-	size_t		  spacing;
 	int		  col; /* column number, starting from 0 */
 	int		  flags;
 #define	TBL_CELL_TALIGN	 (1 << 0) /* t, T */
@@ -259,6 +260,7 @@ struct	tbl_cell {
 #define	TBL_CELL_UP	 (1 << 5) /* u, U */
 #define	TBL_CELL_WIGN	 (1 << 6) /* z, Z */
 #define	TBL_CELL_WMAX	 (1 << 7) /* x, X */
+	enum tbl_cellt	  pos;
 };
 
 /*
@@ -286,9 +288,10 @@ enum	tbl_datt {
  */
 struct	tbl_dat {
 	struct tbl_cell	 *layout; /* layout cell */
-	int		  spans; /* how many spans follow */
 	struct tbl_dat	 *next;
 	char		 *string; /* data (NULL if not TBL_DATA_DATA) */
+	int		  spans; /* how many spans follow */
+	int		  block; /* T{ text block T} */
 	enum tbl_datt	  pos;
 };
 
Index: tbl_layout.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/tbl_layout.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -Ltbl_layout.c -Ltbl_layout.c -u -p -r1.41 -r1.42
--- tbl_layout.c
+++ tbl_layout.c
@@ -1,7 +1,7 @@
 /*	$Id$ */
 /*
  * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2012, 2014, 2015 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2012, 2014, 2015, 2017 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
@@ -62,6 +62,7 @@ mods(struct tbl_node *tbl, struct tbl_ce
 		int ln, const char *p, int *pos)
 {
 	char		*endptr;
+	size_t		 sz;
 
 mod:
 	while (p[*pos] == ' ' || p[*pos] == '\t')
@@ -127,7 +128,22 @@ mod:
 	case 'u':
 		cp->flags |= TBL_CELL_UP;
 		goto mod;
-	case 'w':  /* XXX for now, ignore minimal column width */
+	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] == ')')
+				(*pos)++;
+		}
 		goto mod;
 	case 'x':
 		cp->flags |= TBL_CELL_WMAX;
Index: out.h
===================================================================
RCS file: /home/cvs/mdocml/mdocml/out.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -Lout.h -Lout.h -u -p -r1.28 -r1.29
--- out.h
+++ out.h
@@ -41,14 +41,16 @@ struct	roffsu {
 	double		  scale;
 };
 
+typedef	size_t	(*tbl_sulen)(const struct roffsu *, void *);
 typedef	size_t	(*tbl_strlen)(const char *, void *);
 typedef	size_t	(*tbl_len)(size_t, void *);
 
 struct	rofftbl {
+	tbl_sulen	 sulen; /* calculate scaling unit length */
 	tbl_strlen	 slen; /* calculate string length */
 	tbl_len		 len; /* produce width of empty space */
 	struct roffcol	*cols; /* master column specifiers */
-	void		*arg; /* passed to slen and len */
+	void		*arg; /* passed to sulen, slen, and len */
 };
 
 #define	SCALE_VS_INIT(p, v) \
Index: tbl.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/tbl.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -Ltbl.c -Ltbl.c -u -p -r1.40 -r1.41
--- tbl.c
+++ tbl.c
@@ -114,6 +114,7 @@ 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: out.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/out.c,v
retrieving revision 1.64
retrieving revision 1.65
diff -Lout.c -Lout.c -u -p -r1.64 -r1.65
--- out.c
+++ out.c
@@ -29,9 +29,10 @@
 #include "out.h"
 
 static	void	tblcalc_data(struct rofftbl *, struct roffcol *,
-			const struct tbl_opts *, const struct tbl_dat *);
+			const struct tbl_opts *, const struct tbl_dat *,
+			size_t);
 static	void	tblcalc_literal(struct rofftbl *, struct roffcol *,
-			const struct tbl_dat *);
+			const struct tbl_dat *, size_t);
 static	void	tblcalc_number(struct rofftbl *, struct roffcol *,
 			const struct tbl_opts *, const struct tbl_dat *);
 
@@ -106,6 +107,7 @@ void
 tblcalc(struct rofftbl *tbl, const struct tbl_span *sp,
 	size_t totalwidth)
 {
+	struct roffsu		 su;
 	const struct tbl_opts	*opts;
 	const struct tbl_dat	*dp;
 	struct roffcol		*col;
@@ -146,7 +148,16 @@ tblcalc(struct rofftbl *tbl, const struc
 			col->flags |= dp->layout->flags;
 			if (dp->layout->flags & TBL_CELL_WIGN)
 				continue;
-			tblcalc_data(tbl, col, opts, dp);
+			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;
+			tblcalc_data(tbl, col, opts, dp, dp->block ?
+			    totalwidth / (sp->opts->cols + 1) : 0);
 		}
 	}
 
@@ -234,7 +245,7 @@ tblcalc(struct rofftbl *tbl, const struc
 
 static void
 tblcalc_data(struct rofftbl *tbl, struct roffcol *col,
-		const struct tbl_opts *opts, const struct tbl_dat *dp)
+    const struct tbl_opts *opts, const struct tbl_dat *dp, size_t mw)
 {
 	size_t		 sz;
 
@@ -251,7 +262,7 @@ tblcalc_data(struct rofftbl *tbl, struct
 	case TBL_CELL_CENTRE:
 	case TBL_CELL_LEFT:
 	case TBL_CELL_RIGHT:
-		tblcalc_literal(tbl, col, dp);
+		tblcalc_literal(tbl, col, dp, mw);
 		break;
 	case TBL_CELL_NUMBER:
 		tblcalc_number(tbl, col, opts, dp);
@@ -265,16 +276,29 @@ tblcalc_data(struct rofftbl *tbl, struct
 
 static void
 tblcalc_literal(struct rofftbl *tbl, struct roffcol *col,
-		const struct tbl_dat *dp)
+    const struct tbl_dat *dp, size_t mw)
 {
-	size_t		 sz;
-	const char	*str;
-
-	str = dp->string ? dp->string : "";
-	sz = (*tbl->slen)(str, tbl->arg);
-
-	if (col->width < sz)
-		col->width = sz;
+	const char	*str;	/* Beginning of the first line. */
+	const char	*beg;	/* Beginning of the current line. */
+	char		*end;	/* End of the current line. */
+	size_t		 sz;	/* Length of the current line. */
+
+	if (dp->string == NULL || *dp->string == '\0')
+		return;
+	str = mw ? mandoc_strdup(dp->string) : dp->string;
+	for (beg = str; beg != NULL && *beg != '\0'; beg = end) {
+		end = mw ? strchr(beg, ' ') : NULL;
+		if (end != NULL) {
+			*end++ = '\0';
+			while (*end == ' ')
+				end++;
+		}
+		sz = (*tbl->slen)(beg, tbl->arg);
+		if (col->width < sz)
+			col->width = sz;
+	}
+	if (mw)
+		free((void *)str);
 }
 
 static void
Index: Makefile
===================================================================
RCS file: /home/cvs/mdocml/mdocml/regress/tbl/mod/Makefile,v
retrieving revision 1.2
retrieving revision 1.3
diff -Lregress/tbl/mod/Makefile -Lregress/tbl/mod/Makefile -u -p -r1.2 -r1.3
--- regress/tbl/mod/Makefile
+++ regress/tbl/mod/Makefile
@@ -1,6 +1,6 @@
 # $OpenBSD: Makefile,v 1.2 2015/02/10 11:02:19 schwarze Exp $
 
-REGRESS_TARGETS	 = badfont expand expand-toowide font misalign
+REGRESS_TARGETS	 = badfont expand expand-toowide font misalign width
 LINT_TARGETS	 = badfont font
 
 # groff-1.22.3 defects:
--- /dev/null
+++ regress/tbl/mod/width.in
@@ -0,0 +1,14 @@
+.TH TBL-MOD-WIDTH 1 "June 8, 2017" OpenBSD
+.SH NAME
+tbl-mod-width \- width modifier in table layout
+.SH DESCRIPTION
+normal text
+.TS
+box tab(:);
+lw2 | lw(2n) | lw(0.2i) | lw2 .
+a:abcd:T{
+a
+T}:T{
+.SM abcd
+T}
+.TE
--- /dev/null
+++ regress/tbl/mod/width.out_ascii
@@ -0,0 +1,16 @@
+TBL-MOD-WIDTH(1)            General Commands Manual           TBL-MOD-WIDTH(1)
+
+
+
+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
+
+       +---+------+----+------+
+       |a  | abcd | a  | abcd |
+       +---+------+----+------+
+
+
+OpenBSD                          June 8, 2017                 TBL-MOD-WIDTH(1)
--
 To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2017-06-08 18:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-08 18:11 mdocml: Implement w layout specifier (minimum column width) 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).