aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--roff.721
-rw-r--r--roff.c7
-rw-r--r--roff_escape.c21
3 files changed, 42 insertions, 7 deletions
diff --git a/roff.7 b/roff.7
index cafa5287..2d58efd6 100644
--- a/roff.7
+++ b/roff.7
@@ -1,4 +1,4 @@
-.\" $Id: roff.7,v 1.119 2022/05/31 18:09:57 schwarze Exp $
+.\" $Id: roff.7,v 1.120 2022/05/31 20:23:05 schwarze Exp $
.\"
.\" Copyright (c) 2010-2019, 2022 Ingo Schwarze <schwarze@openbsd.org>
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -2021,8 +2021,23 @@ End conditional input; see
Paddable non-breaking space character.
.It Ic \e0
Digit width space character.
-.It Ic \eA\(aq Ns Ar string Ns Ic \(aq
-Anchor definition; ignored by
+.It Ic \eA\(aq Ns Ar name Ns Ic \(aq
+Interpolate
+.Sq 1
+if
+.Ar name
+is a syntactically valid identifier that can be used
+as a name for a macro or user-defined string, or
+.Sq 0
+otherwise.
+This is a thoroughly non-portable groff extension.
+Heirloom troff uses the same escape sequence with the same syntax
+for a completely different purpose,
+defining a hyperlink target position, also called an
+.Dq anchor ,
+with the given
+.Ar name .
+The Heirloom semantics is not supported by
.Xr mandoc 1 .
.It Ic \ea
Leader character; ignored by
diff --git a/roff.c b/roff.c
index 0c36e08e..83701f7d 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.390 2022/05/31 18:09:57 schwarze Exp $ */
+/* $Id: roff.c,v 1.391 2022/05/31 20:23:05 schwarze Exp $ */
/*
* Copyright (c) 2010-2015, 2017-2022 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -1520,6 +1520,11 @@ roff_expand(struct roff *r, struct buf *buf, int ln, int pos, char ec)
*dst++ = '"';
}
continue;
+ case 'A':
+ ubuf[0] = iendarg > iarg ? '1' : '0';
+ ubuf[1] = '\0';
+ res = ubuf;
+ break;
case 'B':
npos = 0;
ubuf[0] = iendarg > iarg && iend > iendarg &&
diff --git a/roff_escape.c b/roff_escape.c
index 3c38ced7..20e5267a 100644
--- a/roff_escape.c
+++ b/roff_escape.c
@@ -73,6 +73,7 @@ roff_escape(const char *buf, const int ln, const int aesc,
int maxl; /* expected length of the argument */
int argl; /* actual length of the argument */
int c, i; /* for \[char...] parsing */
+ int valid_A; /* for \A parsing */
enum mandoc_esc rval; /* return value */
enum mandocerr err; /* diagnostic code */
char esc_name;
@@ -181,12 +182,12 @@ roff_escape(const char *buf, const int ln, const int aesc,
/* Quoted arguments */
+ case 'A':
case 'B':
case 'w':
rval = ESCAPE_EXPAND;
term = '\b';
break;
- case 'A':
case 'D':
case 'H':
case 'L':
@@ -301,6 +302,7 @@ roff_escape(const char *buf, const int ln, const int aesc,
/* Advance to the end of the argument. */
+ valid_A = 1;
iendarg = iarg;
while (maxl > 0) {
if (buf[iendarg] == '\0') {
@@ -319,11 +321,20 @@ roff_escape(const char *buf, const int ln, const int aesc,
break;
}
if (buf[iendarg] == buf[iesc]) {
- if (roff_escape(buf, ln, iendarg,
- &sesc, &sarg, &sendarg, &send) == ESCAPE_EXPAND)
+ switch (roff_escape(buf, ln, iendarg,
+ &sesc, &sarg, &sendarg, &send)) {
+ case ESCAPE_EXPAND:
goto out_sub;
+ case ESCAPE_UNDEF:
+ break;
+ default:
+ valid_A = 0;
+ break;
+ }
iendarg = iend = send;
} else {
+ if (buf[iendarg] == ' ' || buf[iendarg] == '\t')
+ valid_A = 0;
if (maxl != INT_MAX)
maxl--;
iend = ++iendarg;
@@ -342,6 +353,10 @@ roff_escape(const char *buf, const int ln, const int aesc,
buf[iarg] == '.' && buf[iarg + 1] == 'T')
rval = ESCAPE_DEVICE;
break;
+ case 'A':
+ if (valid_A == 0)
+ iendarg = iarg;
+ break;
case 'O':
switch (buf[iarg]) {
case '0':