source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mdocml: Minimal implementation of the roff(7) .ce request (center a
@ 2017-06-06 15:01 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2017-06-06 15:01 UTC (permalink / raw)
  To: source

Log Message:
-----------
Minimal implementation of the roff(7) .ce request (center a number
of input lines without filling).
Contrary to groff, high-level macros abort .ce mode for now.

Modified Files:
--------------
    mdocml:
        mandoc.1
        mandoc.h
        mdoc_man.c
        read.c
        roff.c
        roff.h
        roff_html.c
        roff_term.c
        roff_validate.c

Revision Data
-------------
Index: read.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/read.c,v
retrieving revision 1.170
retrieving revision 1.171
diff -Lread.c -Lread.c -u -p -r1.170 -r1.171
--- read.c
+++ read.c
@@ -227,6 +227,7 @@ static	const char * const	mandocerrs[MAN
 	"NOT IMPLEMENTED: Bd -file",
 	"skipping display without arguments",
 	"missing list type, using -item",
+	"argument is not numeric, using 1",
 	"missing manual name, using \"\"",
 	"uname(3) system call failed, using UNKNOWN",
 	"unknown standard specifier",
Index: roff_html.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/roff_html.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -Lroff_html.c -Lroff_html.c -u -p -r1.6 -r1.7
--- roff_html.c
+++ roff_html.c
@@ -29,10 +29,12 @@
 typedef	void	(*roff_html_pre_fp)(ROFF_HTML_ARGS);
 
 static	void	  roff_html_pre_br(ROFF_HTML_ARGS);
+static	void	  roff_html_pre_ce(ROFF_HTML_ARGS);
 static	void	  roff_html_pre_sp(ROFF_HTML_ARGS);
 
 static	const roff_html_pre_fp roff_html_pre_acts[ROFF_MAX] = {
 	roff_html_pre_br,  /* br */
+	roff_html_pre_ce,  /* ce */
 	NULL,  /* ft */
 	NULL,  /* ll */
 	NULL,  /* mc */
@@ -53,8 +55,25 @@ roff_html_pre(struct html *h, const stru
 static void
 roff_html_pre_br(ROFF_HTML_ARGS)
 {
-	print_otag(h, TAG_DIV, "");
+	struct tag	*t;
+
+	t = print_otag(h, TAG_DIV, "");
 	print_text(h, "\\~");  /* So the div isn't empty. */
+	print_tagq(h, t);
+}
+
+static void
+roff_html_pre_ce(ROFF_HTML_ARGS)
+{
+	for (n = n->child->next; n != NULL; n = n->next) {
+		if (n->type == ROFFT_TEXT) {
+			if (n->flags & NODE_LINE)
+				roff_html_pre_br(h, n);
+			print_text(h, n->string);
+		} else
+			roff_html_pre(h, n);
+	}
+	roff_html_pre_br(h, n);
 }
 
 static void
Index: roff.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/roff.c,v
retrieving revision 1.304
retrieving revision 1.305
diff -Lroff.c -Lroff.c -u -p -r1.304 -r1.305
--- roff.c
+++ roff.c
@@ -189,7 +189,8 @@ static	enum rofferr	 roff_nr(ROFF_ARGS);
 static	enum rofferr	 roff_onearg(ROFF_ARGS);
 static	enum roff_tok	 roff_parse(struct roff *, char *, int *,
 				int, int);
-static	enum rofferr	 roff_parsetext(struct buf *, int, int *);
+static	enum rofferr	 roff_parsetext(struct roff *, struct buf *,
+				int, int *);
 static	enum rofferr	 roff_res(struct roff *, struct buf *, int, int);
 static	enum rofferr	 roff_rm(ROFF_ARGS);
 static	enum rofferr	 roff_rr(ROFF_ARGS);
@@ -215,15 +216,16 @@ static	enum rofferr	 roff_userdef(ROFF_A
 #define	ROFFNUM_WHITE	(1 << 1)  /* Skip whitespace in roff_evalnum(). */
 
 const char *__roff_name[MAN_MAX + 1] = {
-	"br",		"ft",		"ll",		"mc",
-	"sp",		"ta",		"ti",		NULL,
+	"br",		"ce",		"ft",		"ll",
+	"mc",		"sp",		"ta",		"ti",
+	NULL,
 	"ab",		"ad",		"af",		"aln",
 	"als",		"am",		"am1",		"ami",
 	"ami1",		"as",		"as1",		"asciify",
 	"backtrace",	"bd",		"bleedat",	"blm",
         "box",		"boxa",		"bp",		"BP",
 	"break",	"breakchar",	"brnl",		"brp",
-	"brpnl",	"c2",		"cc",		"ce",
+	"brpnl",	"c2",		"cc",
 	"cf",		"cflags",	"ch",		"char",
 	"chop",		"class",	"close",	"CL",
 	"color",	"composite",	"continue",	"cp",
@@ -323,6 +325,7 @@ const	char *const *roff_name = __roff_na
 
 static	struct roffmac	 roffs[TOKEN_NONE] = {
 	{ roff_br, NULL, NULL, 0 },  /* br */
+	{ roff_onearg, NULL, NULL, 0 },  /* ce */
 	{ roff_onearg, NULL, NULL, 0 },  /* ft */
 	{ roff_onearg, NULL, NULL, 0 },  /* ll */
 	{ roff_onearg, NULL, NULL, 0 },  /* mc */
@@ -357,7 +360,6 @@ static	struct roffmac	 roffs[TOKEN_NONE]
 	{ roff_line_ignore, NULL, NULL, 0 },  /* brpnl */
 	{ roff_unsupp, NULL, NULL, 0 },  /* c2 */
 	{ roff_cc, NULL, NULL, 0 },  /* cc */
-	{ roff_line_ignore, NULL, NULL, 0 },  /* ce */
 	{ roff_insec, NULL, NULL, 0 },  /* cf */
 	{ roff_line_ignore, NULL, NULL, 0 },  /* cflags */
 	{ roff_line_ignore, NULL, NULL, 0 },  /* ch */
@@ -604,6 +606,8 @@ static	const struct predef predefs[PREDE
 #include "predefs.in"
 };
 
+static	int	 roffce_lines;	/* number of input lines to center */
+static	struct roff_node *roffce_node;  /* active request */
 static	int	 roffit_lines;  /* number of lines to delay */
 static	char	*roffit_macro;  /* nil-terminated macro line */
 
@@ -1387,7 +1391,7 @@ roff_res(struct roff *r, struct buf *buf
  * Process text streams.
  */
 static enum rofferr
-roff_parsetext(struct buf *buf, int pos, int *offs)
+roff_parsetext(struct roff *r, struct buf *buf, int pos, int *offs)
 {
 	size_t		 sz;
 	const char	*start;
@@ -1409,6 +1413,16 @@ roff_parsetext(struct buf *buf, int pos,
 	} else if (roffit_lines > 1)
 		--roffit_lines;
 
+	if (roffce_node != NULL && buf->buf[pos] != '\0') {
+		if (roffce_lines < 1) {
+			r->man->last = roffce_node;
+			r->man->next = ROFF_NEXT_SIBLING;
+			roffce_lines = 0;
+			roffce_node = NULL;
+		} else
+			roffce_lines--;
+	}
+
 	/* Convert all breakable hyphens into ASCII_HYPH. */
 
 	start = p = buf->buf + pos;
@@ -1494,7 +1508,7 @@ roff_parseln(struct roff *r, int ln, str
 	if (r->tbl != NULL && ( ! ctl || buf->buf[pos] == '\0'))
 		return tbl_read(r->tbl, ln, buf->buf, ppos);
 	if ( ! ctl)
-		return roff_parsetext(buf, pos, offs);
+		return roff_parsetext(r, buf, pos, offs);
 
 	/* Skip empty request lines. */
 
@@ -1535,6 +1549,16 @@ roff_parseln(struct roff *r, int ln, str
 		return tbl_read(r->tbl, ln, buf->buf, pos);
 	}
 
+	/* For now, let high level macros abort .ce mode. */
+
+	if (ctl && roffce_node != NULL &&
+	    (t == TOKEN_NONE || t == ROFF_EQ || t == ROFF_TS)) {
+		r->man->last = roffce_node;
+		r->man->next = ROFF_NEXT_SIBLING;
+		roffce_lines = 0;
+		roffce_node = NULL;
+	}
+
 	/*
 	 * This is neither a roff request nor a user-defined macro.
 	 * Let the standard macro set parsers handle it.
@@ -2836,11 +2860,17 @@ roff_onearg(ROFF_ARGS)
 {
 	struct roff_node	*n;
 	char			*cp;
+	int			 npos;
 
 	if (r->man->flags & (MAN_BLINE | MAN_ELINE) &&
 	    (tok == ROFF_sp || tok == ROFF_ti))
 		man_breakscope(r->man, tok);
 
+	if (tok == ROFF_ce && roffce_node != NULL) {
+		r->man->last = roffce_node;
+		r->man->next = ROFF_NEXT_SIBLING;
+	}
+
 	roff_elem_alloc(r->man, ln, ppos, tok);
 	n = r->man->last;
 
@@ -2857,8 +2887,29 @@ roff_onearg(ROFF_ARGS)
 		roff_word_alloc(r->man, ln, pos, buf->buf + pos);
 	}
 
-	n->flags |= NODE_LINE | NODE_VALID | NODE_ENDED;
-	r->man->last = n;
+	if (tok == ROFF_ce) {
+		if (r->man->last->tok == ROFF_ce) {
+			roff_word_alloc(r->man, ln, pos, "1");
+			r->man->last->flags |= NODE_NOSRC;
+		}
+		npos = 0;
+		if (roff_evalnum(r, ln, r->man->last->string, &npos,
+		    &roffce_lines, 0) == 0) {
+			mandoc_vmsg(MANDOCERR_CE_NONUM,
+			    r->parse, ln, pos, "ce %s", buf->buf + pos);
+			roffce_lines = 1;
+		}
+		if (roffce_lines < 1) {
+			r->man->last = r->man->last->parent;
+			roffce_node = NULL;
+			roffce_lines = 0;
+		} else
+			roffce_node = r->man->last->parent;
+	} else {
+		n->flags |= NODE_VALID | NODE_ENDED;
+		r->man->last = n;
+	}
+	n->flags |= NODE_LINE;
 	r->man->next = ROFF_NEXT_SIBLING;
 	return ROFF_IGN;
 }
Index: roff.h
===================================================================
RCS file: /home/cvs/mdocml/mdocml/roff.h,v
retrieving revision 1.49
retrieving revision 1.50
diff -Lroff.h -Lroff.h -u -p -r1.49 -r1.50
--- roff.h
+++ roff.h
@@ -67,6 +67,7 @@ enum	roff_type {
 
 enum	roff_tok {
 	ROFF_br = 0,
+	ROFF_ce,
 	ROFF_ft,
 	ROFF_ll,
 	ROFF_mc,
@@ -101,7 +102,6 @@ enum	roff_tok {
 	ROFF_brpnl,
 	ROFF_c2,
 	ROFF_cc,
-	ROFF_ce,
 	ROFF_cf,
 	ROFF_cflags,
 	ROFF_ch,
Index: roff_validate.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/roff_validate.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -Lroff_validate.c -Lroff_validate.c -u -p -r1.6 -r1.7
--- roff_validate.c
+++ roff_validate.c
@@ -32,6 +32,7 @@ static	void	  roff_valid_ft(ROFF_VALID_A
 
 static	const roff_valid_fp roff_valids[ROFF_MAX] = {
 	NULL,  /* br */
+	NULL,  /* ce */
 	roff_valid_ft,  /* ft */
 	NULL,  /* ll */
 	NULL,  /* mc */
Index: mdoc_man.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/mdoc_man.c,v
retrieving revision 1.117
retrieving revision 1.118
diff -Lmdoc_man.c -Lmdoc_man.c -u -p -r1.117 -r1.118
--- mdoc_man.c
+++ mdoc_man.c
@@ -126,6 +126,7 @@ static	void	  print_node(DECL_ARGS);
 
 static	const void_fp roff_manacts[ROFF_MAX] = {
 	pre_br,
+	pre_onearg,
 	pre_ft,
 	pre_onearg,
 	pre_onearg,
@@ -1582,6 +1583,9 @@ pre_onearg(DECL_ARGS)
 	if (n->child != NULL)
 		print_word(n->child->string);
 	outflags |= MMAN_nl;
+	if (n->tok == ROFF_ce)
+		for (n = n->child->next; n != NULL; n = n->next)
+			print_node(meta, n);
 }
 
 static int
Index: mandoc.1
===================================================================
RCS file: /home/cvs/mdocml/mdocml/mandoc.1,v
retrieving revision 1.193
retrieving revision 1.194
diff -Lmandoc.1 -Lmandoc.1 -u -p -r1.193 -r1.194
--- mandoc.1
+++ mandoc.1
@@ -1716,6 +1716,11 @@ whatever mode was active before the bloc
 A
 .Ic \&Bl
 macro fails to specify the list type.
+.It Sy "argument is not numeric, using 1"
+.Pq roff
+The argument of a
+.Ic \&ce
+request is not a number.
 .It Sy "missing manual name, using \(dq\(dq"
 .Pq mdoc
 The first call to
Index: roff_term.c
===================================================================
RCS file: /home/cvs/mdocml/mdocml/roff_term.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -Lroff_term.c -Lroff_term.c -u -p -r1.7 -r1.8
--- roff_term.c
+++ roff_term.c
@@ -28,6 +28,7 @@
 typedef	void	(*roff_term_pre_fp)(ROFF_TERM_ARGS);
 
 static	void	  roff_term_pre_br(ROFF_TERM_ARGS);
+static	void	  roff_term_pre_ce(ROFF_TERM_ARGS);
 static	void	  roff_term_pre_ft(ROFF_TERM_ARGS);
 static	void	  roff_term_pre_ll(ROFF_TERM_ARGS);
 static	void	  roff_term_pre_mc(ROFF_TERM_ARGS);
@@ -37,6 +38,7 @@ static	void	  roff_term_pre_ti(ROFF_TERM
 
 static	const roff_term_pre_fp roff_term_pre_acts[ROFF_MAX] = {
 	roff_term_pre_br,  /* br */
+	roff_term_pre_ce,  /* ce */
 	roff_term_pre_ft,  /* ft */
 	roff_term_pre_ll,  /* ll */
 	roff_term_pre_mc,  /* mc */
@@ -62,6 +64,43 @@ roff_term_pre_br(ROFF_TERM_ARGS)
 		p->rmargin = p->maxrmargin;
 		p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
 	}
+}
+
+static void
+roff_term_pre_ce(ROFF_TERM_ARGS)
+{
+	const struct roff_node	*nch;
+	size_t			 len, lm;
+
+	roff_term_pre_br(p, n);
+	lm = p->offset;
+	n = n->child->next;
+	while (n != NULL) {
+		nch = n;
+		len = 0;
+		do {
+			if (n->type == ROFFT_TEXT) {
+				if (len)
+					len++;
+				len += term_strlen(p, nch->string);
+			}
+			nch = nch->next;
+		} while (nch != NULL && (n->type != ROFFT_TEXT ||
+		    (n->flags & NODE_LINE) == 0));
+		p->offset = len >= p->rmargin ? 0 :
+		    lm + len >= p->rmargin ? p->rmargin - len :
+		    (lm + p->rmargin - len) / 2;
+		while (n != nch) {
+			if (n->type == ROFFT_TEXT)
+				term_word(p, n->string);
+			else
+				roff_term_pre(p, n);
+			n = n->next;
+		}
+		p->flags |= TERMP_NOSPACE;
+		term_flushln(p);
+	}
+	p->offset = lm;
 }
 
 static void
Index: mandoc.h
===================================================================
RCS file: /home/cvs/mdocml/mdocml/mandoc.h,v
retrieving revision 1.222
retrieving revision 1.223
diff -Lmandoc.h -Lmandoc.h -u -p -r1.222 -r1.223
--- mandoc.h
+++ mandoc.h
@@ -185,6 +185,7 @@ enum	mandocerr {
 	MANDOCERR_BD_FILE, /* NOT IMPLEMENTED: Bd -file */
 	MANDOCERR_BD_NOARG, /* skipping display without arguments: Bd */
 	MANDOCERR_BL_NOTYPE, /* missing list type, using -item: Bl */
+	MANDOCERR_CE_NONUM, /* argument is not numeric, using 1: ce ... */
 	MANDOCERR_NM_NONAME, /* missing manual name, using "": Nm */
 	MANDOCERR_OS_UNAME, /* uname(3) system call failed, using UNKNOWN */
 	MANDOCERR_ST_BAD, /* unknown standard specifier: St standard */
--
 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-06 15:01 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-06 15:01 mdocml: Minimal implementation of the roff(7) .ce request (center a 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).