Rudimentary implementation of the roff(7) \o escape sequence (overstrike).
authorschwarze <schwarze@openbsd.org>
Wed, 21 Jan 2015 20:20:49 +0000 (20:20 +0000)
committerschwarze <schwarze@openbsd.org>
Wed, 21 Jan 2015 20:20:49 +0000 (20:20 +0000)
This is of some relevance because the pod2man(1) preamble abuses it
for the icelandic letter Thorn, instead of simply using \(TP and \(Tp.
Missing feature found by sthen@ in DateTime::Locale::is_IS(3p).

regress/usr.bin/mandoc/roff/esc/Makefile
regress/usr.bin/mandoc/roff/esc/o.in [new file with mode: 0644]
regress/usr.bin/mandoc/roff/esc/o.out_ascii [new file with mode: 0644]
share/man/man7/roff.7
usr.bin/mandoc/html.c
usr.bin/mandoc/mandoc.c
usr.bin/mandoc/mandoc.h
usr.bin/mandoc/term.c

index 92db491..ab2b01a 100644 (file)
@@ -1,6 +1,6 @@
-# $OpenBSD: Makefile,v 1.9 2015/01/01 18:10:09 schwarze Exp $
+# $OpenBSD: Makefile,v 1.10 2015/01/21 20:20:49 schwarze Exp $
 
-REGRESS_TARGETS = one two multi B c c_man e f h w z ignore
+REGRESS_TARGETS = one two multi B c c_man e f h w z ignore
 LINT_TARGETS   = B h w ignore
 
 # Postprocessing to remove "character backspace" sequences
diff --git a/regress/usr.bin/mandoc/roff/esc/o.in b/regress/usr.bin/mandoc/roff/esc/o.in
new file mode 100644 (file)
index 0000000..2976a9d
--- /dev/null
@@ -0,0 +1,18 @@
+.Dd January 21, 2015
+.Dt ESC-O 1
+.Os OpenBSD
+.Sh NAME
+.Nm esc-o
+.Nd the roff escape o sequence: overstrike
+.Sh DESCRIPTION
+empty: x\o''x
+.br
+one character: x\o'|'x
+.br
+wide/narrow: x\o'O|'x
+.br
+narrow/wide: x\o'|O'x
+.br
+wide/narrow/narrow: x\o'O-|'x
+.br
+narrow/narrow/wide: x\o'|-O'x
diff --git a/regress/usr.bin/mandoc/roff/esc/o.out_ascii b/regress/usr.bin/mandoc/roff/esc/o.out_ascii
new file mode 100644 (file)
index 0000000..39dc1b1
--- /dev/null
@@ -0,0 +1,14 @@
+ESC-O(1)                    General Commands Manual                   ESC-O(1)
+
+N\bNA\bAM\bME\bE
+     e\bes\bsc\bc-\b-o\bo - the roff escape o sequence: overstrike
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+     empty: xx
+     one character: x|x
+     wide/narrow: xO\b|x
+     narrow/wide: x|\bOx
+     wide/narrow/narrow: xO\b-\b|x
+     narrow/narrow/wide: x|\b-\bOx
+
+OpenBSD                        January 21, 2015                        OpenBSD
index 3930005..f6399c6 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: roff.7,v 1.43 2015/01/20 22:34:15 jmc Exp $
+.\"    $OpenBSD: roff.7,v 1.44 2015/01/21 20:20:49 schwarze Exp $
 .\"
 .\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
 .\" Copyright (c) 2010, 2011, 2013, 2014 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: January 20 2015 $
+.Dd $Mdocdate: January 21 2015 $
 .Dt ROFF 7
 .Os
 .Sh NAME
@@ -1946,10 +1946,11 @@ For short names, there are variants
 and
 .No \en( Ns Ar cc .
 .Ss \eo\(aq Ns Ar string Ns \(aq
-Overstrike
-.Ar string ;
-ignored by
-.Xr mandoc 1 .
+Overstrike, that is, write all the characters contained in the
+.Ar string
+to the same output position.
+In terminal and HTML output modes,
+only the last one of the characters is visible.
 .Ss \eR\(aq Ns Ar name Oo +|- Oc Ns Ar number Ns \(aq
 Set number register; ignored by
 .Xr mandoc 1 .
index 69f907f..44933c3 100644 (file)
@@ -1,7 +1,7 @@
-/*     $OpenBSD: html.c,v 1.54 2014/12/20 00:19:54 schwarze Exp $ */
+/*     $OpenBSD: html.c,v 1.55 2015/01/21 20:20:49 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -305,6 +305,8 @@ html_strlen(const char *cp)
                case ESCAPE_NUMBERED:
                        /* FALLTHROUGH */
                case ESCAPE_SPECIAL:
+                       /* FALLTHROUGH */
+               case ESCAPE_OVERSTRIKE:
                        if (skip)
                                skip = 0;
                        else
@@ -431,6 +433,11 @@ print_encode(struct html *h, const char *p, int norecurse)
                        if ('\0' == *p)
                                nospace = 1;
                        continue;
+               case ESCAPE_OVERSTRIKE:
+                       if (len == 0)
+                               continue;
+                       c = seq[len - 1];
+                       break;
                default:
                        continue;
                }
index 362edb9..14fd071 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mandoc.c,v 1.58 2015/01/01 18:10:09 schwarze Exp $ */
+/*     $OpenBSD: mandoc.c,v 1.59 2015/01/21 20:20:49 schwarze Exp $ */
 /*
  * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -154,16 +154,18 @@ mandoc_escape(const char **end, const char **start, int *sz)
                /* FALLTHROUGH */
        case 'D':
                /* FALLTHROUGH */
-       case 'o':
-               /* FALLTHROUGH */
        case 'R':
                /* FALLTHROUGH */
        case 'X':
                /* FALLTHROUGH */
        case 'Z':
-               if ('\0' == **start)
-                       return(ESCAPE_ERROR);
                gly = ESCAPE_IGNORE;
+               /* FALLTHROUGH */
+       case 'o':
+               if (**start == '\0')
+                       return(ESCAPE_ERROR);
+               if (gly == ESCAPE_ERROR)
+                       gly = ESCAPE_OVERSTRIKE;
                term = **start;
                *start = ++*end;
                break;
index 713bafd..fb255d0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mandoc.h,v 1.125 2015/01/20 21:12:46 schwarze Exp $ */
+/*     $OpenBSD: mandoc.h,v 1.126 2015/01/21 20:20:49 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
@@ -399,7 +399,8 @@ enum        mandoc_esc {
        ESCAPE_NUMBERED, /* a numbered glyph */
        ESCAPE_UNICODE, /* a unicode codepoint */
        ESCAPE_NOSPACE, /* suppress space if the last on a line */
-       ESCAPE_SKIPCHAR /* skip the next character */
+       ESCAPE_SKIPCHAR, /* skip the next character */
+       ESCAPE_OVERSTRIKE /* overstrike all chars in the argument */
 };
 
 typedef        void    (*mandocmsg)(enum mandocerr, enum mandoclevel,
index ee24746..74401b3 100644 (file)
@@ -1,7 +1,7 @@
-/*     $OpenBSD: term.c,v 1.102 2014/12/24 23:31:59 schwarze Exp $ */
+/*     $OpenBSD: term.c,v 1.103 2015/01/21 20:20:49 schwarze Exp $ */
 /*
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2015 Ingo Schwarze <schwarze@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -493,6 +493,17 @@ term_word(struct termp *p, const char *word)
                case ESCAPE_SKIPCHAR:
                        p->flags |= TERMP_SKIPCHAR;
                        continue;
+               case ESCAPE_OVERSTRIKE:
+                       cp = seq + sz;
+                       while (seq < cp) {
+                               if (*seq == '\\') {
+                                       mandoc_escape(&seq, NULL, NULL);
+                                       continue;
+                               }
+                               encode1(p, *seq++);
+                               if (seq < cp)
+                                       encode(p, "\b", 1);
+                       }
                default:
                        continue;
                }
@@ -714,6 +725,20 @@ term_strlen(const struct termp *p, const char *cp)
                        case ESCAPE_SKIPCHAR:
                                skip = 1;
                                continue;
+                       case ESCAPE_OVERSTRIKE:
+                               rsz = 0;
+                               rhs = seq + ssz;
+                               while (seq < rhs) {
+                                       if (*seq == '\\') {
+                                               mandoc_escape(&seq, NULL, NULL);
+                                               continue;
+                                       }
+                                       i = (*p->width)(p, *seq++);
+                                       if (rsz < i)
+                                               rsz = i;
+                               }
+                               sz += rsz;
+                               continue;
                        default:
                                continue;
                        }