diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2018-08-25 16:43:53 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2018-08-25 16:43:53 +0000 |
commit | 9386514a18738cd55c2f7e145f89528e04ffb6bc (patch) | |
tree | 5ed98afceb73329cede728a7808bd701702fe9f0 /usr.bin | |
parent | d2a91c10c1a90277c03f97a4bc9b82807d159e9c (diff) |
Rudimentary implementation of the roff(7) .char (output glyph
definition) request, used for example by groff_hdtbl(7).
This simplistic implementation may interact incorrectly
with the .tr (input character translation) request.
But come on, you are not only using .char *and* .tr, but you do so
with respect to the same character in the same manual page?
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/mandoc/mandoc.1 | 17 | ||||
-rw-r--r-- | usr.bin/mandoc/mandoc.h | 4 | ||||
-rw-r--r-- | usr.bin/mandoc/read.c | 4 | ||||
-rw-r--r-- | usr.bin/mandoc/roff.c | 75 |
4 files changed, 94 insertions, 6 deletions
diff --git a/usr.bin/mandoc/mandoc.1 b/usr.bin/mandoc/mandoc.1 index cc55b3ceac0..aa19c49d634 100644 --- a/usr.bin/mandoc/mandoc.1 +++ b/usr.bin/mandoc/mandoc.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: mandoc.1,v 1.151 2018/08/23 14:16:12 schwarze Exp $ +.\" $OpenBSD: mandoc.1,v 1.152 2018/08/25 16:43:52 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2012, 2014-2018 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: August 23 2018 $ +.Dd $Mdocdate: August 25 2018 $ .Dt MANDOC 1 .Os .Sh NAME @@ -1606,6 +1606,12 @@ or .Cm off . The invalid argument is moved out of the macro, which leaves the macro empty, causing it to toggle the spacing mode. +.It Sy "argument contains two font escapes" +.Pq roff +The second argument of a +.Ic char +request contains more than one font escape sequence. +A wrong font may remain active after using the character. .It Sy "unknown font, skipping request" .Pq man , tbl A @@ -1959,6 +1965,13 @@ macro fails to specify the list type. The argument of a .Ic \&ce request is not a number. +.It Sy "argument is not a character" +.Pq roff +The first argument of a +.Ic char +request is neither a single ASCII character +nor a single character escape sequence. +The request is ignored including all its arguments. .It Sy "missing manual name, using \(dq\(dq" .Pq mdoc The first call to diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h index 6b39fc056ee..4a46bd89d13 100644 --- a/usr.bin/mandoc/mandoc.h +++ b/usr.bin/mandoc/mandoc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mandoc.h,v 1.194 2018/08/24 22:56:37 schwarze Exp $ */ +/* $OpenBSD: mandoc.h,v 1.195 2018/08/25 16:43:52 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> @@ -158,6 +158,7 @@ enum mandocerr { MANDOCERR_LB_BAD, /* unknown library name: Lb ... */ MANDOCERR_RS_BAD, /* invalid content in Rs block: macro */ MANDOCERR_SM_BAD, /* invalid Boolean argument: macro arg */ + MANDOCERR_CHAR_FONT, /* argument contains two font escapes */ MANDOCERR_FT_BAD, /* unknown font, skipping request: ft font */ MANDOCERR_TR_ODD, /* odd number of characters in request: tr char */ @@ -212,6 +213,7 @@ enum mandocerr { 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_CHAR_ARG, /* argument is not a character: char ... */ 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/usr.bin/mandoc/read.c b/usr.bin/mandoc/read.c index 2ab9dae312e..e6c81ed3516 100644 --- a/usr.bin/mandoc/read.c +++ b/usr.bin/mandoc/read.c @@ -1,4 +1,4 @@ -/* $OpenBSD: read.c,v 1.171 2018/08/24 22:56:37 schwarze Exp $ */ +/* $OpenBSD: read.c,v 1.172 2018/08/25 16:43:52 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> @@ -196,6 +196,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "unknown library name", "invalid content in Rs block", "invalid Boolean argument", + "argument contains two font escapes", "unknown font, skipping request", "odd number of characters in request", @@ -250,6 +251,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "skipping display without arguments", "missing list type, using -item", "argument is not numeric, using 1", + "argument is not a character", "missing manual name, using \"\"", "uname(3) system call failed, using UNKNOWN", "unknown standard specifier", diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index 57ff4a137db..d6fc50bb27f 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roff.c,v 1.212 2018/08/24 22:56:37 schwarze Exp $ */ +/* $OpenBSD: roff.c,v 1.213 2018/08/25 16:43:52 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> @@ -174,6 +174,7 @@ static int roff_br(ROFF_ARGS); static int roff_cblock(ROFF_ARGS); static int roff_cc(ROFF_ARGS); static int roff_ccond(struct roff *, int, int); +static int roff_char(ROFF_ARGS); static int roff_cond(ROFF_ARGS); static int roff_cond_text(ROFF_ARGS); static int roff_cond_sub(ROFF_ARGS); @@ -395,7 +396,7 @@ static struct roffmac roffs[TOKEN_NONE] = { { roff_insec, NULL, NULL, 0 }, /* cf */ { roff_line_ignore, NULL, NULL, 0 }, /* cflags */ { roff_line_ignore, NULL, NULL, 0 }, /* ch */ - { roff_unsupp, NULL, NULL, 0 }, /* char */ + { roff_char, NULL, NULL, 0 }, /* char */ { roff_unsupp, NULL, NULL, 0 }, /* chop */ { roff_line_ignore, NULL, NULL, 0 }, /* class */ { roff_insec, NULL, NULL, 0 }, /* close */ @@ -3320,6 +3321,76 @@ roff_cc(ROFF_ARGS) } static int +roff_char(ROFF_ARGS) +{ + const char *p, *kp, *vp; + size_t ksz, vsz; + int font; + + /* Parse the character to be replaced. */ + + kp = buf->buf + pos; + p = kp + 1; + if (*kp == '\0' || (*kp == '\\' && + mandoc_escape(&p, NULL, NULL) != ESCAPE_SPECIAL) || + (*p != ' ' && *p != '\0')) { + mandoc_vmsg(MANDOCERR_CHAR_ARG, r->parse, + ln, pos, "char %s", kp); + return ROFF_IGN; + } + ksz = p - kp; + while (*p == ' ') + p++; + + /* + * If the replacement string contains a font escape sequence, + * we have to restore the font at the end. + */ + + vp = p; + vsz = strlen(p); + font = 0; + while (*p != '\0') { + if (*p++ != '\\') + continue; + switch (mandoc_escape(&p, NULL, NULL)) { + case ESCAPE_FONT: + case ESCAPE_FONTROMAN: + case ESCAPE_FONTITALIC: + case ESCAPE_FONTBOLD: + case ESCAPE_FONTBI: + case ESCAPE_FONTPREV: + font++; + break; + default: + break; + } + } + if (font > 1) + mandoc_msg(MANDOCERR_CHAR_FONT, r->parse, + ln, vp - buf->buf, vp); + + /* + * Approximate the effect of .char using the .tr tables. + * XXX In groff, .char and .tr interact differently. + */ + + if (ksz == 1) { + if (r->xtab == NULL) + r->xtab = mandoc_calloc(128, sizeof(*r->xtab)); + assert((unsigned int)*kp < 128); + free(r->xtab[(int)*kp].p); + r->xtab[(int)*kp].sz = mandoc_asprintf(&r->xtab[(int)*kp].p, + "%s%s", vp, font ? "\fP" : ""); + } else { + roff_setstrn(&r->xmbtab, kp, ksz, vp, vsz, 0); + if (font) + roff_setstrn(&r->xmbtab, kp, ksz, "\\fP", 3, 1); + } + return ROFF_IGN; +} + +static int roff_ec(ROFF_ARGS) { const char *p; |