summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-06-01 19:05:37 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-06-01 19:05:37 +0000
commit70410dfcfd38b668debf911095b28861d93134f1 (patch)
tree33d8c726de9e8afae8308bd07e389623156bfed1
parent8aa141e07f78054e526f8f85ec8f12e47a40fbb9 (diff)
downloadmandoc-70410dfcfd38b668debf911095b28861d93134f1.tar.gz
Minimal implementation of the \h (horizontal motion) escape sequence.
Good enough to cope with the average DocBook insanity.
-rw-r--r--mandoc.c2
-rw-r--r--mandoc.h1
-rw-r--r--mdoc_term.c3
-rw-r--r--regress/roff/esc/h.in4
-rw-r--r--roff.77
-rw-r--r--term.c22
6 files changed, 32 insertions, 7 deletions
diff --git a/mandoc.c b/mandoc.c
index 4bfe4c36..03c25e0d 100644
--- a/mandoc.c
+++ b/mandoc.c
@@ -175,7 +175,7 @@ mandoc_escape(const char **end, const char **start, int *sz)
++*end;
return ESCAPE_ERROR;
}
- gly = ESCAPE_IGNORE;
+ gly = (*start)[-1] == 'h' ? ESCAPE_HORIZ : ESCAPE_IGNORE;
term = **start;
*start = ++*end;
break;
diff --git a/mandoc.h b/mandoc.h
index 37baee40..51290770 100644
--- a/mandoc.h
+++ b/mandoc.h
@@ -411,6 +411,7 @@ enum mandoc_esc {
ESCAPE_NUMBERED, /* a numbered glyph */
ESCAPE_UNICODE, /* a unicode codepoint */
ESCAPE_NOSPACE, /* suppress space if the last on a line */
+ ESCAPE_HORIZ, /* horizontal movement */
ESCAPE_SKIPCHAR, /* skip the next character */
ESCAPE_OVERSTRIKE /* overstrike all chars in the argument */
};
diff --git a/mdoc_term.c b/mdoc_term.c
index 585b507a..751f3702 100644
--- a/mdoc_term.c
+++ b/mdoc_term.c
@@ -407,7 +407,8 @@ print_mdoc_node(DECL_ARGS)
if (NODE_EOS & n->flags)
p->flags |= TERMP_SENTENCE;
- p->offset = offset;
+ if (n->type != ROFFT_TEXT)
+ p->offset = offset;
p->rmargin = rmargin;
}
diff --git a/regress/roff/esc/h.in b/regress/roff/esc/h.in
index 31fbb4e2..4bc1953e 100644
--- a/regress/roff/esc/h.in
+++ b/regress/roff/esc/h.in
@@ -7,11 +7,11 @@
.Sh DESCRIPTION
simple: >\h'0'<
.br
-escape only: >\h'\w'\&''<
+escape only: >\h'\w'\&'M'<
.br
escape at the end: >\h'0+\w'\&''<
.br
-escape at the beginning: >\h'\w'\&'+0'<
+escape at the beginning: >\h'\w'\&'M+0'<
.br
escape in the middle: >\h'0+\w'\&'+0'<
.br
diff --git a/roff.7 b/roff.7
index 6dc1c1de..464ee2ad 100644
--- a/roff.7
+++ b/roff.7
@@ -1925,9 +1925,10 @@ and
.Ss \eH\(aq Ns Oo +|- Oc Ns Ar number Ns \(aq
Set the height of the current font; ignored by
.Xr mandoc 1 .
-.Ss \eh\(aq Ns Ar number Ns \(aq
-Horizontal motion; ignored by
-.Xr mandoc 1 .
+.Ss \eh\(aq Ns Ar width Ns \(aq
+Horizontal motion relative to the current position.
+The default scaling unit is
+.Cm m .
.Ss \ek[ Ns Ar name ]
Mark horizontal input place in register; ignored by
.Xr mandoc 1 .
diff --git a/term.c b/term.c
index e52ba40c..2c8aa7c6 100644
--- a/term.c
+++ b/term.c
@@ -400,6 +400,7 @@ term_fontpop(struct termp *p)
void
term_word(struct termp *p, const char *word)
{
+ struct roffsu su;
const char nbrsp[2] = { ASCII_NBRSP, 0 };
const char *seq, *cp;
int sz, uc;
@@ -488,6 +489,27 @@ term_word(struct termp *p, const char *word)
else if (*word == '\0')
p->flags |= (TERMP_NOSPACE | TERMP_NONEWLINE);
continue;
+ case ESCAPE_HORIZ:
+ if (a2roffsu(seq, &su, SCALE_EM) == 0)
+ continue;
+ uc = term_hspan(p, &su) / 24;
+ if (uc > 0)
+ while (uc-- > 0)
+ bufferc(p, ASCII_NBRSP);
+ else if (p->col > (size_t)(-uc))
+ p->col += uc;
+ else {
+ uc += p->col;
+ p->col = 0;
+ if (p->offset > (size_t)(-uc)) {
+ p->ti += uc;
+ p->offset += uc;
+ } else {
+ p->ti -= p->offset;
+ p->offset = 0;
+ }
+ }
+ continue;
case ESCAPE_SKIPCHAR:
p->flags |= TERMP_BACKAFTER;
continue;