From: schwarze Date: Wed, 14 Jun 2017 01:31:19 +0000 (+0000) Subject: implement the roff(7) \p (break output line) escape sequence X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=6167ec38c25c524dfc7cd0fa734962d15add0402;p=openbsd implement the roff(7) \p (break output line) escape sequence --- diff --git a/regress/usr.bin/mandoc/roff/esc/Makefile b/regress/usr.bin/mandoc/roff/esc/Makefile index f0860368510..6d81161491b 100644 --- a/regress/usr.bin/mandoc/roff/esc/Makefile +++ b/regress/usr.bin/mandoc/roff/esc/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.11 2015/04/29 18:32:57 schwarze Exp $ +# $OpenBSD: Makefile,v 1.12 2017/06/14 01:31:19 schwarze Exp $ -REGRESS_TARGETS = one two multi B c c_man e f h o w z ignore +REGRESS_TARGETS = one two multi B c c_man e f h o p w z ignore LINT_TARGETS = B h w ignore .include diff --git a/regress/usr.bin/mandoc/roff/esc/p.in b/regress/usr.bin/mandoc/roff/esc/p.in new file mode 100644 index 00000000000..b94ab13adfe --- /dev/null +++ b/regress/usr.bin/mandoc/roff/esc/p.in @@ -0,0 +1,15 @@ +.Dd June 14, 2017 +.Dt ESC-P 1 +.Os OpenBSD +.Sh NAME +.Nm esc-p +.Nd line break escape sequence +.Sh DESCRIPTION +no blank: line one\pline two +.Pp +blank after esc: line one\p line two +.Pp +blank before esc: line one \pline two +.Pp +at eol: line one\p +line two diff --git a/regress/usr.bin/mandoc/roff/esc/p.out_ascii b/regress/usr.bin/mandoc/roff/esc/p.out_ascii new file mode 100644 index 00000000000..488e2c613aa --- /dev/null +++ b/regress/usr.bin/mandoc/roff/esc/p.out_ascii @@ -0,0 +1,19 @@ +ESC-P(1) General Commands Manual ESC-P(1) + +NNAAMMEE + eesscc--pp - line break escape sequence + +DDEESSCCRRIIPPTTIIOONN + no blank: line oneline + two + + blank after esc: line one + line two + + blank before esc: line one line + two + + at eol: line one + line two + +OpenBSD June 14, 2017 OpenBSD diff --git a/share/man/man7/roff.7 b/share/man/man7/roff.7 index 9f152c092cd..b689e4816d4 100644 --- a/share/man/man7/roff.7 +++ b/share/man/man7/roff.7 @@ -1,4 +1,4 @@ -.\" $OpenBSD: roff.7,v 1.67 2017/06/10 16:32:08 schwarze Exp $ +.\" $OpenBSD: roff.7,v 1.68 2017/06/14 01:31:19 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons .\" Copyright (c) 2010,2011,2013-2015,2017 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 10 2017 $ +.Dd $Mdocdate: June 14 2017 $ .Dt ROFF 7 .Os .Sh NAME @@ -1989,6 +1989,8 @@ Overstrike, writing all the characters contained in the to the same output position. In terminal and HTML output modes, only the last one of the characters is visible. +.Ss \ep +Break the output line at the end of the current word. .Ss \eR\(aq Ns Ar name Oo +|- Oc Ns Ar number Ns \(aq Set number register; ignored by .Xr mandoc 1 . diff --git a/usr.bin/mandoc/html.c b/usr.bin/mandoc/html.c index f25c21da748..58576242ace 100644 --- a/usr.bin/mandoc/html.c +++ b/usr.bin/mandoc/html.c @@ -1,4 +1,4 @@ -/* $OpenBSD: html.c,v 1.83 2017/06/08 12:54:40 schwarze Exp $ */ +/* $OpenBSD: html.c,v 1.84 2017/06/14 01:31:19 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2011-2015, 2017 Ingo Schwarze @@ -343,16 +343,18 @@ static int print_encode(struct html *h, const char *p, const char *pend, int norecurse) { char numbuf[16]; - size_t sz; - int c, len, nospace; + struct tag *t; const char *seq; + size_t sz; + int c, len, breakline, nospace; enum mandoc_esc esc; - static const char rejs[9] = { '\\', '<', '>', '&', '"', + static const char rejs[10] = { ' ', '\\', '<', '>', '&', '"', ASCII_NBRSP, ASCII_HYPH, ASCII_BREAK, '\0' }; if (pend == NULL) pend = strchr(p, '\0'); + breakline = 0; nospace = 0; while (p < pend) { @@ -363,14 +365,28 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse) } for (sz = strcspn(p, rejs); sz-- && p < pend; p++) - if (*p == ' ') - print_endword(h); - else - print_byte(h, *p); + print_byte(h, *p); + + if (breakline && + (p >= pend || *p == ' ' || *p == ASCII_NBRSP)) { + t = print_otag(h, TAG_DIV, ""); + print_text(h, "\\~"); + print_tagq(h, t); + breakline = 0; + while (p < pend && (*p == ' ' || *p == ASCII_NBRSP)) + p++; + continue; + } if (p >= pend) break; + if (*p == ' ') { + print_endword(h); + p++; + continue; + } + if (print_escape(h, *p++)) continue; @@ -415,6 +431,9 @@ print_encode(struct html *h, const char *p, const char *pend, int norecurse) if (c <= 0) continue; break; + case ESCAPE_BREAK: + breakline = 1; + continue; case ESCAPE_NOSPACE: if ('\0' == *p) nospace = 1; diff --git a/usr.bin/mandoc/mandoc.c b/usr.bin/mandoc/mandoc.c index 8000e4ad664..3aff3c5b77f 100644 --- a/usr.bin/mandoc/mandoc.c +++ b/usr.bin/mandoc/mandoc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mandoc.c,v 1.69 2017/06/11 19:36:31 schwarze Exp $ */ +/* $OpenBSD: mandoc.c,v 1.70 2017/06/14 01:31:19 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2011-2015, 2017 Ingo Schwarze @@ -94,6 +94,8 @@ mandoc_escape(const char **end, const char **start, int *sz) case ',': case '/': return ESCAPE_IGNORE; + case 'p': + return ESCAPE_BREAK; /* * The \z escape is supposed to output the following diff --git a/usr.bin/mandoc/mandoc.h b/usr.bin/mandoc/mandoc.h index 6f14e23ec31..ed4d1d7fc17 100644 --- a/usr.bin/mandoc/mandoc.h +++ b/usr.bin/mandoc/mandoc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mandoc.h,v 1.171 2017/06/11 19:36:31 schwarze Exp $ */ +/* $OpenBSD: mandoc.h,v 1.172 2017/06/14 01:31:19 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons * Copyright (c) 2010-2017 Ingo Schwarze @@ -423,6 +423,7 @@ enum mandoc_esc { ESCAPE_FONTPREV, /* previous font mode */ ESCAPE_NUMBERED, /* a numbered glyph */ ESCAPE_UNICODE, /* a unicode codepoint */ + ESCAPE_BREAK, /* break the output line */ ESCAPE_NOSPACE, /* suppress space if the last on a line */ ESCAPE_HORIZ, /* horizontal movement */ ESCAPE_HLINE, /* horizontal line drawing */ diff --git a/usr.bin/mandoc/mdoc_markdown.c b/usr.bin/mandoc/mdoc_markdown.c index 19d564a2dbd..1a8a70ada5d 100644 --- a/usr.bin/mandoc/mdoc_markdown.c +++ b/usr.bin/mandoc/mdoc_markdown.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mdoc_markdown.c,v 1.22 2017/05/30 16:31:25 schwarze Exp $ */ +/* $OpenBSD: mdoc_markdown.c,v 1.23 2017/06/14 01:31:19 schwarze Exp $ */ /* * Copyright (c) 2017 Ingo Schwarze * @@ -493,7 +493,7 @@ md_word(const char *s) { const char *seq, *prevfont, *currfont, *nextfont; char c; - int bs, sz, uc; + int bs, sz, uc, breakline; /* No spacing before closing delimiters. */ if (s[0] != '\0' && s[1] == '\0' && @@ -510,6 +510,7 @@ md_word(const char *s) if ((s[0] == '(' || s[0] == '[') && s[1] == '\0') outflags &= ~MD_spc; + breakline = 0; prevfont = currfont = ""; while ((c = *s++) != '\0') { bs = 0; @@ -595,6 +596,9 @@ md_word(const char *s) case ESCAPE_FONTPREV: nextfont = prevfont; break; + case ESCAPE_BREAK: + breakline = 1; + break; case ESCAPE_NOSPACE: case ESCAPE_SKIPCHAR: case ESCAPE_OVERSTRIKE: @@ -642,6 +646,13 @@ md_word(const char *s) if (bs) putchar('\\'); md_char(c); + if (breakline && + (*s == '\0' || *s == ' ' || *s == ASCII_NBRSP)) { + printf(" \n"); + breakline = 0; + while (*s == ' ' || *s == ASCII_NBRSP) + s++; + } } if (*currfont != '\0') { outflags &= ~MD_spc; diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c index 07b7f57a2e5..e6aebdc379a 100644 --- a/usr.bin/mandoc/term.c +++ b/usr.bin/mandoc/term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: term.c,v 1.129 2017/06/12 18:55:42 schwarze Exp $ */ +/* $OpenBSD: term.c,v 1.130 2017/06/14 01:31:19 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2017 Ingo Schwarze @@ -114,6 +114,7 @@ term_flushln(struct termp *p) size_t jhy; /* last hyph before overflow w/r/t j */ size_t maxvis; /* output position of visible boundary */ int ntab; /* number of tabs to prepend */ + int breakline; /* after this word */ vbl = (p->flags & TERMP_NOPAD) || p->tcol->offset < p->viscol ? 0 : p->tcol->offset - p->viscol; @@ -153,7 +154,13 @@ term_flushln(struct termp *p) */ jhy = 0; + breakline = 0; for (j = p->tcol->col; j < p->tcol->lastcol; j++) { + if (p->tcol->buf[j] == '\n') { + if ((p->flags & TERMP_BRIND) == 0) + breakline = 1; + continue; + } if (p->tcol->buf[j] == ' ' || p->tcol->buf[j] == '\t') break; @@ -219,6 +226,8 @@ term_flushln(struct termp *p) for ( ; p->tcol->col < p->tcol->lastcol; p->tcol->col++) { if (vend > bp && jhy > 0 && p->tcol->col > jhy) break; + if (p->tcol->buf[p->tcol->col] == '\n') + continue; if (p->tcol->buf[p->tcol->col] == '\t') break; if (p->tcol->buf[p->tcol->col] == ' ') { @@ -258,6 +267,26 @@ term_flushln(struct termp *p) p->tcol->buf[p->tcol->col]); } vis = vend; + + if (breakline == 0) + continue; + + /* Explicitly requested output line break. */ + + if (p->flags & TERMP_MULTICOL) + return; + + endline(p); + breakline = 0; + vis = vend = 0; + + /* Re-establish indentation. */ + + vbl = p->tcol->offset; + maxvis = p->tcol->rmargin > vbl ? + p->tcol->rmargin - vbl : 0; + bp = !(p->flags & TERMP_NOBREAK) ? maxvis : + p->maxrmargin > vbl ? p->maxrmargin - vbl : 0; } /* @@ -485,6 +514,9 @@ term_word(struct termp *p, const char *word) case ESCAPE_FONTPREV: term_fontlast(p); continue; + case ESCAPE_BREAK: + bufferc(p, '\n'); + continue; case ESCAPE_NOSPACE: if (p->flags & TERMP_BACKAFTER) p->flags &= ~TERMP_BACKAFTER;