summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2010-05-08 08:36:44 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2010-05-08 08:36:44 +0000
commitd0924326c0c8e754370d5d2d2142366c3a75ae70 (patch)
treef6e7eb3799bf9f4b01e6f4c70cbf361a3640630c
parentc10df4f63596660b1a585dd712a0778b88ec5874 (diff)
downloadmandoc-d0924326c0c8e754370d5d2d2142366c3a75ae70.tar.gz
Strip trailing, unescaped whitespace from free-form, non-literal lines (like groff).
-rw-r--r--man.711
-rw-r--r--man.c20
-rw-r--r--mdoc.718
-rw-r--r--mdoc.c20
4 files changed, 45 insertions, 24 deletions
diff --git a/man.7 b/man.7
index 5a3b22dc..a9733a11 100644
--- a/man.7
+++ b/man.7
@@ -126,10 +126,13 @@ and
.Sq \ef
attributes are forgotten when entering or exiting a macro block.
.Ss Whitespace
-Unless specifically escaped, consecutive blocks of whitespace are pruned
-from input. These are later re-added, if applicable, by a front-end
-utility such as
-.Xr mandoc 1 .
+In free-form lines, whitespace is preserved within a line; un-escaped
+trailing spaces are stripped from input (unless in a literal context).
+Blank free-form lines, which may include spaces, are permitted and
+rendered as an empty line.
+.Pp
+In macro lines, whitespace delimits arguments and is discarded. If
+arguments are quoted, whitespace within the quotes is retained.
.Ss Dates
The
.Sx \&TH
diff --git a/man.c b/man.c
index 828698d7..28c72df6 100644
--- a/man.c
+++ b/man.c
@@ -395,16 +395,30 @@ man_ptext(struct man *m, int line, char *buf)
goto descope;
}
- /* Warn if the last un-escaped character is whitespace. */
+ /*
+ * Warn if the last un-escaped character is whitespace. Then
+ * strip away the remaining spaces (tabs stay!).
+ */
i = (int)strlen(buf);
assert(i);
- if (' ' == buf[i - 1] || '\t' == buf[i - 1])
- if (1 == i || ('\\' != buf[i - 2]))
+ if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
+ assert(i > 1);
+ if ('\\' != buf[i - 2])
if ( ! man_pwarn(m, line, i - 1, WTSPACE))
return(0);
+ for (--i; i && ' ' == buf[i]; i--)
+ /* Spin back to non-space. */ ;
+
+ /* Jump ahead of escaped whitespace. */
+ assert(i);
+ i += '\\' == buf[i] ? 2 : 1;
+
+ buf[i] = '\0';
+ }
+
if ( ! man_word_alloc(m, line, 0, buf))
return(0);
diff --git a/mdoc.7 b/mdoc.7
index 1b807efa..d9c6b757 100644
--- a/mdoc.7
+++ b/mdoc.7
@@ -181,23 +181,13 @@ and
.Sq \e*(Ba
.Pq vertical bar .
.Ss Whitespace
-In non-literal free-form lines, consecutive blocks of whitespace are
-pruned from input and added later in the output filter, if applicable:
-.Bd -literal -offset indent
-These spaces are pruned from input.
-\&.Bd \-literal
-These are not.
-\&.Ed
-.Ed
+In free-form lines, whitespace is preserved within a line; un-escaped
+trailing spaces are stripped from input (unless in a literal context).
+Blank free-form lines, which may include spaces, are only permitted
+within literal contexts.
.Pp
In macro lines, whitespace delimits arguments and is discarded. If
arguments are quoted, whitespace within the quotes is retained.
-.Pp
-Blank lines are only permitted within literal contexts, as are lines
-containing only whitespace. Tab characters are only acceptable when
-delimiting
-.Sq \&Bl \-column
-or when in a literal context.
.Ss Quotation
Macro arguments may be quoted with a double-quote to group
space-delimited terms or to retain blocks of whitespace. A quoted
diff --git a/mdoc.c b/mdoc.c
index 9bb391a2..1a6d23f8 100644
--- a/mdoc.c
+++ b/mdoc.c
@@ -665,16 +665,30 @@ mdoc_ptext(struct mdoc *m, int line, char *buf)
return(1);
}
- /* Warn if the last un-escaped character is whitespace. */
+ /*
+ * Warn if the last un-escaped character is whitespace. Then
+ * strip away the remaining spaces (tabs stay!).
+ */
i = (int)strlen(buf);
assert(i);
- if (' ' == buf[i - 1] || '\t' == buf[i - 1])
- if (1 == i || ('\\' != buf[i - 2]))
+ if (' ' == buf[i - 1] || '\t' == buf[i - 1]) {
+ assert(i > 1);
+ if ('\\' != buf[i - 2])
if ( ! mdoc_pwarn(m, line, i - 1, ETAILWS))
return(0);
+ for (--i; i && ' ' == buf[i]; i--)
+ /* Spin back to non-space. */ ;
+
+ /* Jump ahead of escaped whitespace. */
+ assert(i);
+ i += '\\' == buf[i] ? 2 : 1;
+
+ buf[i] = '\0';
+ }
+
/* Allocate the whole word. */
return(mdoc_word_alloc(m, line, 0, buf));