From c8cdc23dd605e08382028d103f06d34563196973 Mon Sep 17 00:00:00 2001 From: Kristaps Dz Date: Wed, 25 Dec 2024 11:57:31 -0800 Subject: [PATCH] Make --template escaperoff() escape initial delim. Make escaperoff() escape its roff delimiters whether they appear after a newline OR at the start of the string. This is more in line with how the transform would be used in practice. --- man/lowdown-diff.1 | 2 ++ man/lowdown.1 | 2 ++ nroff_escape.c | 14 +++++++++----- regress/template/escaperoff.html | 3 +++ regress/template/escaperoff.md | 6 ++++++ regress/template/escaperoff.xml | 2 ++ template.c | 2 +- 7 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 regress/template/escaperoff.html create mode 100644 regress/template/escaperoff.md create mode 100644 regress/template/escaperoff.xml diff --git a/man/lowdown-diff.1 b/man/lowdown-diff.1 index a04b7ab..caf1d4a 100644 --- a/man/lowdown-diff.1 +++ b/man/lowdown-diff.1 @@ -959,6 +959,8 @@ body content. Escape list items for roff .Pq Fl t Ns Ar ms , Fl t Ns Ar man , either for multiple lines or compressed to a single line. +.Cm escaperoff +also escapes initial roff delimiters and those after newlines. .It Cm join Join a list into a singleton list using two spaces as a join delimiter. .It Cm lowercase diff --git a/man/lowdown.1 b/man/lowdown.1 index 5e5a0f3..2debc3a 100644 --- a/man/lowdown.1 +++ b/man/lowdown.1 @@ -952,6 +952,8 @@ body content. Escape list items for roff .Pq Fl t Ns Ar ms , Fl t Ns Ar man , either for multiple lines or compressed to a single line. +.Cm escaperoff +also escapes initial roff delimiters and those after newlines. .It Cm join Join a list into a singleton list using two spaces as a join delimiter. .It Cm lowercase diff --git a/nroff_escape.c b/nroff_escape.c index 50e34b1..c5d7454 100644 --- a/nroff_escape.c +++ b/nroff_escape.c @@ -34,7 +34,10 @@ /* * Escape unsafe text into roff output such that no roff features are * invoked by the text (macros, escapes, etc.). - * If "oneline" is non-zero, newlines are replaced with spaces. + * If "oneline" is >0, newlines are replaced with spaces; if =0, + * newlines are retained and roff delimiters after the newline are + * escaped; if <0, like =0 except that the first character if a + * delimiter is also escaped. * If "literal", doesn't strip leading space. * Return zero on failure, non-zero on success. */ @@ -81,7 +84,7 @@ lowdown_nroff_esc(struct lowdown_buf *ob, const char *data, size_t size, return 0; break; case '\n': - if (!hbuf_putc(ob, oneline ? ' ' : '\n')) + if (!hbuf_putc(ob, oneline > 0 ? ' ' : '\n')) return 0; if (literal) break; @@ -99,9 +102,10 @@ lowdown_nroff_esc(struct lowdown_buf *ob, const char *data, size_t size, break; case '\'': case '.': - if (!oneline && - ob->size > 0 && - ob->data[ob->size - 1] == '\n' && + if (((oneline < 0 && i == 0) || + (oneline <= 0 && + ob->size > 0 && + ob->data[ob->size - 1] == '\n')) && !HBUF_PUTSL(ob, "\\&")) return 0; /* FALLTHROUGH */ diff --git a/regress/template/escaperoff.html b/regress/template/escaperoff.html new file mode 100644 index 0000000..d8da307 --- /dev/null +++ b/regress/template/escaperoff.html @@ -0,0 +1,3 @@ +\&.HT \e(ac \ee bc +\&.HT foo +.AT hello \eethere .HT multiline diff --git a/regress/template/escaperoff.md b/regress/template/escaperoff.md new file mode 100644 index 0000000..ba05f08 --- /dev/null +++ b/regress/template/escaperoff.md @@ -0,0 +1,6 @@ +title: .HT \(ac \e bc +.HT foo +author: .AT hello \ethere + .HT multiline + +asdf diff --git a/regress/template/escaperoff.xml b/regress/template/escaperoff.xml new file mode 100644 index 0000000..a33a6b7 --- /dev/null +++ b/regress/template/escaperoff.xml @@ -0,0 +1,2 @@ +$title.escaperoff()$ +$author.escaperoffline()$ diff --git a/template.c b/template.c index 77785ed..b4a4121 100644 --- a/template.c +++ b/template.c @@ -840,7 +840,7 @@ op_eval_function(struct op_out *out, const char *expr, size_t exprsz, else if (exprsz == 11 && strncasecmp(expr, "escapelatex", 11) == 0) nq = op_eval_function_escape_latex(out, input); else if (exprsz == 10 && strncasecmp(expr, "escaperoff", 10) == 0) - nq = op_eval_function_escape_roff(out, input, 0); + nq = op_eval_function_escape_roff(out, input, -1); else if (exprsz == 14 && strncasecmp(expr, "escaperoffline", 14) == 0) nq = op_eval_function_escape_roff(out, input, 1); else {