* 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).