From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=T_SCC_BODY_TEXT_LINE, UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 17952 invoked from network); 31 May 2022 20:23:38 -0000 Received: from bsd.lv (HELO mandoc.bsd.lv) (66.111.2.12) by inbox.vuxu.org with ESMTPUTF8; 31 May 2022 20:23:38 -0000 Received: from fantadrom.bsd.lv (localhost [127.0.0.1]) by mandoc.bsd.lv (OpenSMTPD) with ESMTP id 3a35bb0c for ; Tue, 31 May 2022 15:23:36 -0500 (EST) Received: from localhost (mandoc.bsd.lv [local]) by mandoc.bsd.lv (OpenSMTPD) with ESMTPA id 23360ce7 for ; Tue, 31 May 2022 15:23:36 -0500 (EST) Date: Tue, 31 May 2022 15:23:36 -0500 (EST) X-Mailinglist: mandoc-source Reply-To: source@mandoc.bsd.lv MIME-Version: 1.0 From: schwarze@mandoc.bsd.lv To: source@mandoc.bsd.lv Subject: mandoc: Rudimentary implementation of the \A escape sequence, following X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: <33659725f5a63851@mandoc.bsd.lv> Log Message: ----------- Rudimentary implementation of the \A escape sequence, following groff semantics (test identifier for syntactical validity), not at all following the completely unrelated Heirloom semantics (define hyperlink target position). The main motivation for providing this implementation is to get \A into the parsing class ESCAPE_EXPAND that corresponds to groff parsing behaviour, which is quite similar to the \B escape sequence (test numerical expression for syntactical validity). This is likely to improve parsing of nested escape sequences in the future. Validation isn't perfect yet. In particular, this implementation rejects \A arguments containing some escape sequences that groff allows to slip through. But that is unlikely to cause trouble even in documents using \A for non-trivial purposes. Rejecting the nested escapes in question might even improve robustnest because the rejected names are unlikely to really be usable for practical purposes - no matter that groff dubiously considers them syntactically valid. Modified Files: -------------- mandoc: roff.c roff_escape.c roff.7 Revision Data ------------- Index: roff.7 =================================================================== RCS file: /home/cvs/mandoc/mandoc/roff.7,v retrieving revision 1.119 retrieving revision 1.120 diff -Lroff.7 -Lroff.7 -u -p -r1.119 -r1.120 --- roff.7 +++ roff.7 @@ -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 Index: roff.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/roff.c,v retrieving revision 1.390 retrieving revision 1.391 diff -Lroff.c -Lroff.c -u -p -r1.390 -r1.391 --- roff.c +++ roff.c @@ -1520,6 +1520,11 @@ roff_expand(struct roff *r, struct buf * *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 && Index: roff_escape.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/roff_escape.c,v retrieving revision 1.4 retrieving revision 1.5 diff -Lroff_escape.c -Lroff_escape.c -u -p -r1.4 -r1.5 --- roff_escape.c +++ roff_escape.c @@ -73,6 +73,7 @@ roff_escape(const char *buf, const int l 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 l /* 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 l /* 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 l 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; @@ -341,6 +352,10 @@ roff_escape(const char *buf, const int l if (resc == NULL && argl == 2 && buf[iarg] == '.' && buf[iarg + 1] == 'T') rval = ESCAPE_DEVICE; + break; + case 'A': + if (valid_A == 0) + iendarg = iarg; break; case 'O': switch (buf[iarg]) { -- To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv