summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2015-01-21 20:33:25 +0000
committerIngo Schwarze <schwarze@openbsd.org>2015-01-21 20:33:25 +0000
commit1f42b16d7620434847b937d82a463bd7cbe63255 (patch)
tree4ee3ab1a6a2c6f5ee76f69a33d0b12a1aae40bf8
parent28c98469ed60b736b7c70dc094a9d94197a1568f (diff)
downloadmandoc-1f42b16d7620434847b937d82a463bd7cbe63255.tar.gz
Rudimentary implementation of the roff(7) \o escape sequence (overstrike).
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).
-rw-r--r--html.c9
-rw-r--r--mandoc.c10
-rw-r--r--mandoc.h3
-rw-r--r--mandoc_escape.311
-rw-r--r--roff.79
-rw-r--r--term.c27
6 files changed, 53 insertions, 16 deletions
diff --git a/html.c b/html.c
index 0560d14e..c72c3d48 100644
--- a/html.c
+++ b/html.c
@@ -1,7 +1,7 @@
/* $Id$ */
/*
* 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
@@ -307,6 +307,8 @@ html_strlen(const char *cp)
case ESCAPE_NUMBERED:
/* FALLTHROUGH */
case ESCAPE_SPECIAL:
+ /* FALLTHROUGH */
+ case ESCAPE_OVERSTRIKE:
if (skip)
skip = 0;
else
@@ -433,6 +435,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;
}
diff --git a/mandoc.c b/mandoc.c
index d0bf7f17..cd74f1a0 100644
--- a/mandoc.c
+++ b/mandoc.c
@@ -156,16 +156,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;
diff --git a/mandoc.h b/mandoc.h
index e46f3b38..18b496a4 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -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,
diff --git a/mandoc_escape.3 b/mandoc_escape.3
index 332b94fe..2fe2ccab 100644
--- a/mandoc_escape.3
+++ b/mandoc_escape.3
@@ -20,8 +20,6 @@
.Sh NAME
.Nm mandoc_escape
.Nd parse roff escape sequences
-.Sh LIBRARY
-.Lb libmandoc
.Sh SYNOPSIS
.In sys/types.h
.In mandoc.h
@@ -119,8 +117,8 @@ in turn contain other escape sequences,
for error detection internally by the
.Xr roff 7
parser part of the
-.Lb libmandoc ,
-see the file
+.Xr mandoc 3
+library, see the file
.Pa roff.c ,
.It
above all externally by the
@@ -256,6 +254,10 @@ Such ASCII character escape sequences can be rendered using the function
described in the
.Xr mchars_alloc 3
manual.
+.It Dv ESCAPE_OVERSTRIKE
+The escape sequence
+.Ic \eo
+followed by an argument delimited by an arbitrary character.
.It Dv ESCAPE_IGNORE
.Bl -bullet -width 2n
.It
@@ -288,7 +290,6 @@ The escape sequences
.Ic \eA ,
.Ic \eb ,
.Ic \eD ,
-.Ic \eo ,
.Ic \eR ,
.Ic \eX ,
and
diff --git a/roff.7 b/roff.7
index cef8d91c..804311ff 100644
--- a/roff.7
+++ b/roff.7
@@ -1948,10 +1948,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 .
diff --git a/term.c b/term.c
index 61fe0c3b..1887a6c4 100644
--- a/term.c
+++ b/term.c
@@ -1,7 +1,7 @@
/* $Id$ */
/*
* 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
@@ -495,6 +495,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;
}
@@ -716,6 +727,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;
}