summaryrefslogtreecommitdiff
path: root/usr.bin/mandoc
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@cvs.openbsd.org>2012-05-28 13:00:52 +0000
committerIngo Schwarze <schwarze@cvs.openbsd.org>2012-05-28 13:00:52 +0000
commit08973cb4d1227bb54783bdeab50035c9a6bfbec0 (patch)
tree29302e4a7dce3f5a46a365d627f6e4d95bf18e20 /usr.bin/mandoc
parent83c0700d2695f59ff8403c43a705f01176ecab53 (diff)
Implement the roff \z escape sequence, intended to output the next
character without advancing the cursor position; implement it to simply skip the next character, as it will usually be overwritten. With this change, the pod2man(1) preamble user-defined string \*:, intended to render as a diaeresis or umlaut diacritic above the preceding character, is rendered in a slightly less ugly way, though still not correctly. It was rendered as "z.." and is now rendered as ".". Given that the definition of \*: uses elaborate manual \h positioning, there is little chance for mandoc(1) to ever render it correctly, but at least we can refrain from printing out a spurious "z", and we can make the \z do something semi-reasonable for easier cases.
Diffstat (limited to 'usr.bin/mandoc')
-rw-r--r--usr.bin/mandoc/html.c83
-rw-r--r--usr.bin/mandoc/html.h3
-rw-r--r--usr.bin/mandoc/mandoc.c14
-rw-r--r--usr.bin/mandoc/mandoc.h5
-rw-r--r--usr.bin/mandoc/term.c68
-rw-r--r--usr.bin/mandoc/term.h3
6 files changed, 131 insertions, 45 deletions
diff --git a/usr.bin/mandoc/html.c b/usr.bin/mandoc/html.c
index 80f6acc6956..41e9814955f 100644
--- a/usr.bin/mandoc/html.c
+++ b/usr.bin/mandoc/html.c
@@ -1,7 +1,7 @@
-/* $Id: html.c,v 1.29 2011/10/09 17:59:56 schwarze Exp $ */
+/* $Id: html.c,v 1.30 2012/05/28 13:00:51 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011, 2012 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
@@ -258,8 +258,8 @@ print_metaf(struct html *h, enum mandoc_esc deco)
int
html_strlen(const char *cp)
{
- int ssz, sz;
- const char *seq, *p;
+ size_t rsz;
+ int skip, sz;
/*
* Account for escaped sequences within string length
@@ -270,10 +270,21 @@ html_strlen(const char *cp)
*/
sz = 0;
- while (NULL != (p = strchr(cp, '\\'))) {
- sz += (int)(p - cp);
- ++cp;
- switch (mandoc_escape(&cp, &seq, &ssz)) {
+ skip = 0;
+ while (1) {
+ rsz = strcspn(cp, "\\");
+ if (rsz) {
+ cp += rsz;
+ if (skip) {
+ skip = 0;
+ rsz--;
+ }
+ sz += rsz;
+ }
+ if ('\0' == *cp)
+ break;
+ cp++;
+ switch (mandoc_escape(&cp, NULL, NULL)) {
case (ESCAPE_ERROR):
return(sz);
case (ESCAPE_UNICODE):
@@ -281,15 +292,19 @@ html_strlen(const char *cp)
case (ESCAPE_NUMBERED):
/* FALLTHROUGH */
case (ESCAPE_SPECIAL):
- sz++;
+ if (skip)
+ skip = 0;
+ else
+ sz++;
+ break;
+ case (ESCAPE_SKIPCHAR):
+ skip = 1;
break;
default:
break;
}
}
-
- assert(sz >= 0);
- return(sz + strlen(cp));
+ return(sz);
}
static int
@@ -304,6 +319,12 @@ print_encode(struct html *h, const char *p, int norecurse)
nospace = 0;
while ('\0' != *p) {
+ if (HTML_SKIPCHAR & h->flags && '\\' != *p) {
+ h->flags &= ~HTML_SKIPCHAR;
+ p++;
+ continue;
+ }
+
sz = strcspn(p, rejs);
fwrite(p, 1, sz, stdout);
@@ -334,6 +355,31 @@ print_encode(struct html *h, const char *p, int norecurse)
break;
switch (esc) {
+ case (ESCAPE_FONT):
+ /* FALLTHROUGH */
+ case (ESCAPE_FONTPREV):
+ /* FALLTHROUGH */
+ case (ESCAPE_FONTBOLD):
+ /* FALLTHROUGH */
+ case (ESCAPE_FONTITALIC):
+ /* FALLTHROUGH */
+ case (ESCAPE_FONTROMAN):
+ if (0 == norecurse)
+ print_metaf(h, esc);
+ continue;
+ case (ESCAPE_SKIPCHAR):
+ h->flags |= HTML_SKIPCHAR;
+ continue;
+ default:
+ break;
+ }
+
+ if (h->flags & HTML_SKIPCHAR) {
+ h->flags &= ~HTML_SKIPCHAR;
+ continue;
+ }
+
+ switch (esc) {
case (ESCAPE_UNICODE):
/* Skip passed "u" header. */
c = mchars_num2uc(seq + 1, len - 1);
@@ -352,19 +398,6 @@ print_encode(struct html *h, const char *p, int norecurse)
else if (-1 == c && 1 == len)
putchar((int)*seq);
break;
- case (ESCAPE_FONT):
- /* FALLTHROUGH */
- case (ESCAPE_FONTPREV):
- /* FALLTHROUGH */
- case (ESCAPE_FONTBOLD):
- /* FALLTHROUGH */
- case (ESCAPE_FONTITALIC):
- /* FALLTHROUGH */
- case (ESCAPE_FONTROMAN):
- if (norecurse)
- break;
- print_metaf(h, esc);
- break;
case (ESCAPE_NOSPACE):
if ('\0' == *p)
nospace = 1;
diff --git a/usr.bin/mandoc/html.h b/usr.bin/mandoc/html.h
index bcc6d6f7c39..d3a4307c4c7 100644
--- a/usr.bin/mandoc/html.h
+++ b/usr.bin/mandoc/html.h
@@ -1,4 +1,4 @@
-/* $Id: html.h,v 1.18 2011/10/09 17:59:56 schwarze Exp $ */
+/* $Id: html.h,v 1.19 2012/05/28 13:00:51 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -117,6 +117,7 @@ struct html {
#define HTML_PREKEEP (1 << 3)
#define HTML_NONOSPACE (1 << 4) /* never add spaces */
#define HTML_LITERAL (1 << 5) /* literal (e.g., <PRE>) context */
+#define HTML_SKIPCHAR (1 << 6) /* skip the next character */
struct tagq tags; /* stack of open tags */
struct rofftbl tbl; /* current table */
struct tag *tblt; /* current open table scope */
diff --git a/usr.bin/mandoc/mandoc.c b/usr.bin/mandoc/mandoc.c
index 842cea4b3b2..2b21522948c 100644
--- a/usr.bin/mandoc/mandoc.c
+++ b/usr.bin/mandoc/mandoc.c
@@ -1,7 +1,7 @@
-/* $Id: mandoc.c,v 1.31 2011/11/17 11:58:11 schwarze Exp $ */
+/* $Id: mandoc.c,v 1.32 2012/05/28 13:00:51 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2011, 2012 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
@@ -139,6 +139,16 @@ mandoc_escape(const char **end, const char **start, int *sz)
break;
/*
+ * The \z escape is supposed to output the following
+ * character without advancing the cursor position.
+ * Since we are mostly dealing with terminal mode,
+ * let us just skip the next character.
+ */
+ case ('z'):
+ (*end)++;
+ return(ESCAPE_SKIPCHAR);
+
+ /*
* Handle all triggers matching \X(xy, \Xx, and \X[xxxx], where
* 'X' is the trigger. These have opaque sub-strings.
*/
diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h
index a66bb0d74ad..e91f2e7bf2e 100644
--- a/usr.bin/mandoc/mandoc.h
+++ b/usr.bin/mandoc/mandoc.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc.h,v 1.45 2012/05/26 20:03:34 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.46 2012/05/28 13:00:51 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -379,7 +379,8 @@ enum mandoc_esc {
ESCAPE_FONTPREV, /* previous font mode */
ESCAPE_NUMBERED, /* a numbered glyph */
ESCAPE_UNICODE, /* a unicode codepoint */
- ESCAPE_NOSPACE /* suppress space if the last on a line */
+ ESCAPE_NOSPACE, /* suppress space if the last on a line */
+ ESCAPE_SKIPCHAR /* skip the next character */
};
typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel,
diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c
index acbe2c802ef..a30c2440d39 100644
--- a/usr.bin/mandoc/term.c
+++ b/usr.bin/mandoc/term.c
@@ -1,4 +1,4 @@
-/* $Id: term.c,v 1.63 2012/05/27 01:01:24 schwarze Exp $ */
+/* $Id: term.c,v 1.64 2012/05/28 13:00:51 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
@@ -29,6 +29,7 @@
#include "term.h"
#include "main.h"
+static size_t cond_width(const struct termp *, int, int *);
static void adjbuf(struct termp *p, int);
static void bufferc(struct termp *, char);
static void encode(struct termp *, const char *, size_t);
@@ -415,12 +416,17 @@ term_word(struct termp *p, const char *word)
p->flags &= ~(TERMP_SENTENCE | TERMP_IGNDELIM);
while ('\0' != *word) {
- if ((ssz = strcspn(word, "\\")) > 0)
+ if ('\\' != *word) {
+ if (TERMP_SKIPCHAR & p->flags) {
+ p->flags &= ~TERMP_SKIPCHAR;
+ word++;
+ continue;
+ }
+ ssz = strcspn(word, "\\");
encode(p, word, ssz);
-
- word += (int)ssz;
- if ('\\' != *word)
+ word += (int)ssz;
continue;
+ }
word++;
esc = mandoc_escape(&word, &seq, &sz);
@@ -476,9 +482,14 @@ term_word(struct termp *p, const char *word)
term_fontlast(p);
break;
case (ESCAPE_NOSPACE):
- if ('\0' == *word)
+ if (TERMP_SKIPCHAR & p->flags)
+ p->flags &= ~TERMP_SKIPCHAR;
+ else if ('\0' == *word)
p->flags |= TERMP_NOSPACE;
break;
+ case (ESCAPE_SKIPCHAR):
+ p->flags |= TERMP_SKIPCHAR;
+ break;
default:
break;
}
@@ -518,6 +529,11 @@ encode1(struct termp *p, int c)
{
enum termfont f;
+ if (TERMP_SKIPCHAR & p->flags) {
+ p->flags &= ~TERMP_SKIPCHAR;
+ return;
+ }
+
if (p->col + 4 >= p->maxcols)
adjbuf(p, p->col + 4);
@@ -541,6 +557,11 @@ encode(struct termp *p, const char *word, size_t sz)
enum termfont f;
int i, len;
+ if (TERMP_SKIPCHAR & p->flags) {
+ p->flags &= ~TERMP_SKIPCHAR;
+ return;
+ }
+
/* LINTED */
len = sz;
@@ -589,12 +610,22 @@ term_len(const struct termp *p, size_t sz)
return((*p->width)(p, ' ') * sz);
}
+static size_t
+cond_width(const struct termp *p, int c, int *skip)
+{
+
+ if (*skip) {
+ (*skip) = 0;
+ return(0);
+ } else
+ return((*p->width)(p, c));
+}
size_t
term_strlen(const struct termp *p, const char *cp)
{
size_t sz, rsz, i;
- int ssz, c;
+ int ssz, skip, c;
const char *seq, *rhs;
enum mandoc_esc esc;
static const char rej[] = { '\\', ASCII_HYPH, ASCII_NBRSP, '\0' };
@@ -606,10 +637,11 @@ term_strlen(const struct termp *p, const char *cp)
*/
sz = 0;
+ skip = 0;
while ('\0' != *cp) {
rsz = strcspn(cp, rej);
for (i = 0; i < rsz; i++)
- sz += (*p->width)(p, *cp++);
+ sz += cond_width(p, *cp++, &skip);
c = 0;
switch (*cp) {
@@ -626,14 +658,14 @@ term_strlen(const struct termp *p, const char *cp)
(seq + 1, ssz - 1);
if ('\0' == c)
break;
- sz += (*p->width)(p, c);
+ sz += cond_width(p, c, &skip);
continue;
case (ESCAPE_SPECIAL):
c = mchars_spec2cp
(p->symtab, seq, ssz);
if (c <= 0)
break;
- sz += (*p->width)(p, c);
+ sz += cond_width(p, c, &skip);
continue;
default:
break;
@@ -643,12 +675,12 @@ term_strlen(const struct termp *p, const char *cp)
switch (esc) {
case (ESCAPE_UNICODE):
- sz += (*p->width)(p, '?');
+ sz += cond_width(p, '?', &skip);
break;
case (ESCAPE_NUMBERED):
c = mchars_num2char(seq, ssz);
if ('\0' != c)
- sz += (*p->width)(p, c);
+ sz += cond_width(p, c, &skip);
break;
case (ESCAPE_SPECIAL):
rhs = mchars_spec2str
@@ -660,6 +692,9 @@ term_strlen(const struct termp *p, const char *cp)
rhs = seq;
rsz = ssz;
break;
+ case (ESCAPE_SKIPCHAR):
+ skip = 1;
+ break;
default:
break;
}
@@ -667,15 +702,20 @@ term_strlen(const struct termp *p, const char *cp)
if (NULL == rhs)
break;
+ if (skip) {
+ skip = 0;
+ break;
+ }
+
for (i = 0; i < rsz; i++)
sz += (*p->width)(p, *rhs++);
break;
case (ASCII_NBRSP):
- sz += (*p->width)(p, ' ');
+ sz += cond_width(p, ' ', &skip);
cp++;
break;
case (ASCII_HYPH):
- sz += (*p->width)(p, '-');
+ sz += cond_width(p, '-', &skip);
cp++;
break;
default:
diff --git a/usr.bin/mandoc/term.h b/usr.bin/mandoc/term.h
index 92a74e535a8..7317725e56f 100644
--- a/usr.bin/mandoc/term.h
+++ b/usr.bin/mandoc/term.h
@@ -1,4 +1,4 @@
-/* $Id: term.h,v 1.35 2012/05/27 01:01:24 schwarze Exp $ */
+/* $Id: term.h,v 1.36 2012/05/28 13:00:51 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -78,6 +78,7 @@ struct termp {
#define TERMP_ANPREC (1 << 13) /* See termp_an_pre(). */
#define TERMP_KEEP (1 << 14) /* Keep words together. */
#define TERMP_PREKEEP (1 << 15) /* ...starting with the next one. */
+#define TERMP_SKIPCHAR (1 << 16) /* Skip the next character. */
int *buf; /* Output buffer. */
enum termenc enc; /* Type of encoding. */
struct mchars *symtab; /* Encoded-symbol table. */