source@mandoc.bsd.lv
 help / color / mirror / Atom feed
* mandoc: Rudimentary implementation of the roff(7) .char (output glyph
@ 2018-08-25 16:54 schwarze
  0 siblings, 0 replies; only message in thread
From: schwarze @ 2018-08-25 16:54 UTC (permalink / raw)
  To: source

Log Message:
-----------
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?

Modified Files:
--------------
    mandoc:
        mandoc.1
        mandoc.h
        read.c
        roff.7
        roff.c
    mandoc/regress/roff:
        Makefile

Added Files:
-----------
    mandoc/regress/roff/char:
        Makefile
        badarg.in
        badarg.out_ascii
        badarg.out_lint
        basic.in
        basic.out_ascii

Revision Data
-------------
Index: roff.7
===================================================================
RCS file: /home/cvs/mandoc/mandoc/roff.7,v
retrieving revision 1.104
retrieving revision 1.105
diff -Lroff.7 -Lroff.7 -u -p -r1.104 -r1.105
--- roff.7
+++ roff.7
@@ -507,9 +507,16 @@ This is a groff extension and currently 
 .It Ic \&ch Ar macroname Op Ar dist
 Change a trap location.
 Currently ignored.
-.It Ic \&char Ar glyphname Op Ar string
-Define a new glyph.
-Currently unsupported.
+.It Ic \&char Ar glyph Op Ar string
+Define or redefine the ASCII character or character escape sequence
+.Ar glyph
+to be rendered as
+.Ar string ,
+which can be empty.
+Only partially supported in
+.Xr mandoc 1 ;
+may interact incorrectly with
+.Ic \&tr .
 .It Ic \&chop Ar stringname
 Remove the last character from a macro, string, or diversion.
 Currently unsupported.
Index: roff.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/roff.c,v
retrieving revision 1.340
retrieving revision 1.341
diff -Lroff.c -Lroff.c -u -p -r1.340 -r1.341
--- roff.c
+++ roff.c
@@ -176,6 +176,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);
@@ -397,7 +398,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 */
@@ -3318,6 +3319,76 @@ roff_cc(ROFF_ARGS)
 		mandoc_vmsg(MANDOCERR_ARG_EXCESS, r->parse,
 		    ln, p - buf->buf, "cc ... %s", p);
 
+	return ROFF_IGN;
+}
+
+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;
 }
 
Index: mandoc.1
===================================================================
RCS file: /home/cvs/mandoc/mandoc/mandoc.1,v
retrieving revision 1.227
retrieving revision 1.228
diff -Lmandoc.1 -Lmandoc.1 -u -p -r1.227 -r1.228
--- mandoc.1
+++ mandoc.1
@@ -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
Index: mandoc.h
===================================================================
RCS file: /home/cvs/mandoc/mandoc/mandoc.h,v
retrieving revision 1.252
retrieving revision 1.253
diff -Lmandoc.h -Lmandoc.h -u -p -r1.252 -r1.253
--- mandoc.h
+++ mandoc.h
@@ -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 */
Index: read.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/read.c,v
retrieving revision 1.199
retrieving revision 1.200
diff -Lread.c -Lread.c -u -p -r1.199 -r1.200
--- read.c
+++ read.c
@@ -198,6 +198,7 @@ static	const char * const	mandocerrs[MAN
 	"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",
 
@@ -252,6 +253,7 @@ static	const char * const	mandocerrs[MAN
 	"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",
Index: Makefile
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/roff/Makefile,v
retrieving revision 1.7
retrieving revision 1.8
diff -Lregress/roff/Makefile -Lregress/roff/Makefile -u -p -r1.7 -r1.8
--- regress/roff/Makefile
+++ regress/roff/Makefile
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile,v 1.26 2018/08/24 22:56:37 schwarze Exp $
+# $OpenBSD: Makefile,v 1.27 2018/08/25 16:46:28 schwarze Exp $
 
 SUBDIR  = args cond esc scale string
-SUBDIR += br cc de ds ft ig it ll na nr po ps
+SUBDIR += br cc char de ds ft ig it ll na nr po ps
 SUBDIR += return rm rn shift sp ta ti tr while
 
 .include "../Makefile.sub"
--- /dev/null
+++ regress/roff/char/badarg.out_lint
@@ -0,0 +1,6 @@
+mandoc: badarg.in:6:6: ERROR: argument is not a character: char 
+mandoc: badarg.in:7:7: ERROR: argument is not a character: char \fR myval
+mandoc: badarg.in:8:7: WARNING: invalid escape sequence: \[myc]
+mandoc: badarg.in:8:7: ERROR: argument is not a character: char \[myc]x myval
+mandoc: badarg.in:9:7: ERROR: argument is not a character: char xy myval
+mandoc: badarg.in:10:7: WARNING: invalid escape sequence: \[myc]
--- /dev/null
+++ regress/roff/char/badarg.in
@@ -0,0 +1,10 @@
+.\" $OpenBSD: badarg.in,v 1.1 2018/08/25 16:43:52 schwarze Exp $
+.TH CHAR-BADARG 1 "August 25, 2018"
+.SH NAME
+char-badarg \(en char requests with invalid arguments
+.SH DESCRIPTION
+.char
+.char \fR myval
+.char \[myc]x myval
+.char xy myval
+myc: <\[myc]> x
--- /dev/null
+++ regress/roff/char/basic.out_ascii
@@ -0,0 +1,13 @@
+CHAR-BASIC(1)               General Commands Manual              CHAR-BASIC(1)
+
+
+
+N\bNA\bAM\bME\bE
+       char-basic - the char request
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+       initial text X\bX myval final teyt
+
+
+
+OpenBSD                         August 25, 2018                  CHAR-BASIC(1)
--- /dev/null
+++ regress/roff/char/Makefile
@@ -0,0 +1,6 @@
+# $OpenBSD: Makefile,v 1.1 2018/08/25 16:43:52 schwarze Exp $
+
+REGRESS_TARGETS	= basic badarg
+LINT_TARGETS	= badarg
+
+.include <bsd.regress.mk>
--- /dev/null
+++ regress/roff/char/basic.in
@@ -0,0 +1,11 @@
+.\" $OpenBSD: basic.in,v 1.1 2018/08/25 16:43:52 schwarze Exp $
+.TH CHAR-BASIC 1 "August 25, 2018"
+.SH NAME
+char-basic \(en the char request
+.SH DESCRIPTION
+initial text
+.char \[myc] myval
+.char x y
+.char \[boldX] \fBX
+\[boldX] \[myc]
+final text
--- /dev/null
+++ regress/roff/char/badarg.out_ascii
@@ -0,0 +1,13 @@
+CHAR-BADARG(1)              General Commands Manual             CHAR-BADARG(1)
+
+
+
+N\bNA\bAM\bME\bE
+       char-badarg - char requests with invalid arguments
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+       myc: <> x
+
+
+
+OpenBSD                         August 25, 2018                 CHAR-BADARG(1)
--
 To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv

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

only message in thread, other threads:[~2018-08-25 16:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-25 16:54 mandoc: Rudimentary implementation of the roff(7) .char (output glyph 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).