aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-06-06 15:01:04 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-06-06 15:01:04 +0000
commit1ab4ebe5662ad82d7ab745fdb9c8124e07630673 (patch)
tree4624a848d37ebcc20c00eb4fbebd33ed81c3b593
parent4a4657f9f40ea60d08ecfb7c12fc46e29440ff58 (diff)
downloadmandoc-1ab4ebe5662ad82d7ab745fdb9c8124e07630673.tar.gz
mandoc-1ab4ebe5662ad82d7ab745fdb9c8124e07630673.tar.zst
mandoc-1ab4ebe5662ad82d7ab745fdb9c8124e07630673.zip
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.
-rw-r--r--mandoc.19
-rw-r--r--mandoc.h3
-rw-r--r--mdoc_man.c6
-rw-r--r--read.c3
-rw-r--r--roff.c71
-rw-r--r--roff.h4
-rw-r--r--roff_html.c23
-rw-r--r--roff_term.c41
-rw-r--r--roff_validate.c3
9 files changed, 142 insertions, 21 deletions
diff --git a/mandoc.1 b/mandoc.1
index a323ecc0..783ac2b9 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -1,4 +1,4 @@
-.\" $Id: mandoc.1,v 1.193 2017/06/03 12:17:25 schwarze Exp $
+.\" $Id: mandoc.1,v 1.194 2017/06/06 15:01:04 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 3 2017 $
+.Dd $Mdocdate: June 6 2017 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -1716,6 +1716,11 @@ whatever mode was active before the block.
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
diff --git a/mandoc.h b/mandoc.h
index 93a8a285..fc8418ae 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc.h,v 1.222 2017/06/03 15:55:24 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.223 2017/06/06 15:01:04 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -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 */
diff --git a/mdoc_man.c b/mdoc_man.c
index afee4466..5e628345 100644
--- a/mdoc_man.c
+++ b/mdoc_man.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_man.c,v 1.117 2017/06/04 22:44:15 schwarze Exp $ */
+/* $Id: mdoc_man.c,v 1.118 2017/06/06 15:01:04 schwarze Exp $ */
/*
* Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -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
diff --git a/read.c b/read.c
index efc840bf..e302658f 100644
--- a/read.c
+++ b/read.c
@@ -1,4 +1,4 @@
-/* $Id: read.c,v 1.170 2017/06/04 00:13:15 schwarze Exp $ */
+/* $Id: read.c,v 1.171 2017/06/06 15:01:04 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -227,6 +227,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"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",
diff --git a/roff.c b/roff.c
index ae77e781..f9de12c0 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.304 2017/06/04 22:44:15 schwarze Exp $ */
+/* $Id: roff.c,v 1.305 2017/06/06 15:01:04 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -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_ARGS);
#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_name;
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[PREDEFS_MAX] = {
#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, int ln, int pos)
* 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, int *offs)
} 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, struct buf *buf, int *offs)
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, struct buf *buf, int *offs)
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;
}
diff --git a/roff.h b/roff.h
index d0951046..fbfd593c 100644
--- a/roff.h
+++ b/roff.h
@@ -1,4 +1,4 @@
-/* $Id: roff.h,v 1.49 2017/06/04 22:44:15 schwarze Exp $ */
+/* $Id: roff.h,v 1.50 2017/06/06 15:01:04 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -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,
diff --git a/roff_html.c b/roff_html.c
index 00a100ad..abb2ddf9 100644
--- a/roff_html.c
+++ b/roff_html.c
@@ -1,4 +1,4 @@
-/* $Id: roff_html.c,v 1.6 2017/06/04 22:44:15 schwarze Exp $ */
+/* $Id: roff_html.c,v 1.7 2017/06/06 15:01:04 schwarze Exp $ */
/*
* Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -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 struct roff_node *n)
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
diff --git a/roff_term.c b/roff_term.c
index a4d48812..eaade486 100644
--- a/roff_term.c
+++ b/roff_term.c
@@ -1,4 +1,4 @@
-/* $Id: roff_term.c,v 1.7 2017/06/04 22:44:15 schwarze Exp $ */
+/* $Id: roff_term.c,v 1.8 2017/06/06 15:01:04 schwarze Exp $ */
/*
* Copyright (c) 2010, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -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_ARGS);
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 */
@@ -65,6 +67,43 @@ roff_term_pre_br(ROFF_TERM_ARGS)
}
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
roff_term_pre_ft(ROFF_TERM_ARGS)
{
switch (*n->child->string) {
diff --git a/roff_validate.c b/roff_validate.c
index 6ffc7eed..feadfb40 100644
--- a/roff_validate.c
+++ b/roff_validate.c
@@ -1,4 +1,4 @@
-/* $Id: roff_validate.c,v 1.6 2017/06/04 22:44:15 schwarze Exp $ */
+/* $Id: roff_validate.c,v 1.7 2017/06/06 15:01:04 schwarze Exp $ */
/*
* Copyright (c) 2010, 2017 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -32,6 +32,7 @@ static void roff_valid_ft(ROFF_VALID_ARGS);
static const roff_valid_fp roff_valids[ROFF_MAX] = {
NULL, /* br */
+ NULL, /* ce */
roff_valid_ft, /* ft */
NULL, /* ll */
NULL, /* mc */