diff options
Diffstat (limited to 'contrib/mandoc/term_ascii.c')
-rw-r--r-- | contrib/mandoc/term_ascii.c | 91 |
1 files changed, 51 insertions, 40 deletions
diff --git a/contrib/mandoc/term_ascii.c b/contrib/mandoc/term_ascii.c index 3942dc757953..990833c8a021 100644 --- a/contrib/mandoc/term_ascii.c +++ b/contrib/mandoc/term_ascii.c @@ -1,7 +1,7 @@ -/* $Id: term_ascii.c,v 1.69 2023/11/13 19:13:01 schwarze Exp $ */ +/* $Id: term_ascii.c,v 1.71 2025/07/16 14:33:08 schwarze Exp $ */ /* + * Copyright (c) 2014,2015,2017-2020,2025 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014,2015,2017,2018,2020 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 @@ -43,7 +43,7 @@ static struct termp *ascii_init(enum termenc, const struct manoutput *); static int ascii_hspan(const struct termp *, const struct roffsu *); -static size_t ascii_width(const struct termp *, int); +static size_t ascii_getwidth(const struct termp *, int); static void ascii_advance(struct termp *, size_t); static void ascii_begin(struct termp *); static void ascii_end(struct termp *); @@ -55,7 +55,7 @@ static void ascii_setwidth(struct termp *, int, int); static void locale_advance(struct termp *, size_t); static void locale_endline(struct termp *); static void locale_letter(struct termp *, int); -static size_t locale_width(const struct termp *, int); +static size_t locale_getwidth(const struct termp *, int); #endif @@ -73,7 +73,6 @@ ascii_init(enum termenc enc, const struct manoutput *outopts) p->line = 1; p->defindent = 5; - p->defrmargin = p->lastrmargin = 78; p->fontq = mandoc_reallocarray(NULL, (p->fontsz = 8), sizeof(*p->fontq)); p->fontq[0] = p->fontl = TERMFONT_NONE; @@ -82,13 +81,12 @@ ascii_init(enum termenc enc, const struct manoutput *outopts) p->end = ascii_end; p->hspan = ascii_hspan; p->type = TERMTYPE_CHAR; - p->enc = TERMENC_ASCII; p->advance = ascii_advance; p->endline = ascii_endline; p->letter = ascii_letter; p->setwidth = ascii_setwidth; - p->width = ascii_width; + p->getwidth = ascii_getwidth; #if HAVE_WCHAR if (enc != TERMENC_ASCII) { @@ -118,17 +116,15 @@ ascii_init(enum termenc enc, const struct manoutput *outopts) p->advance = locale_advance; p->endline = locale_endline; p->letter = locale_letter; - p->width = locale_width; + p->getwidth = locale_getwidth; } } #endif + p->defrmargin = term_len(p, outopts->width ? outopts->width : 78); + p->lastrmargin = p->defrmargin; - if (outopts->mdoc) - p->mdocstyle = 1; if (outopts->indent) p->defindent = outopts->indent; - if (outopts->width) - p->defrmargin = outopts->width; if (outopts->synopsisonly) p->synopsisonly = 1; @@ -140,29 +136,24 @@ ascii_init(enum termenc enc, const struct manoutput *outopts) void * ascii_alloc(const struct manoutput *outopts) { - return ascii_init(TERMENC_ASCII, outopts); } void * utf8_alloc(const struct manoutput *outopts) { - return ascii_init(TERMENC_UTF8, outopts); } void * locale_alloc(const struct manoutput *outopts) { - return ascii_init(TERMENC_LOCALE, outopts); } static void ascii_setwidth(struct termp *p, int iop, int width) { - - width /= 24; p->tcol->rmargin = p->defrmargin; if (iop > 0) p->defrmargin += width; @@ -172,8 +163,8 @@ ascii_setwidth(struct termp *p, int iop, int width) p->defrmargin -= width; else p->defrmargin = 0; - if (p->defrmargin > 1000) - p->defrmargin = 1000; + if (p->defrmargin > term_len(p, 1000)) + p->defrmargin = term_len(p, 1000); p->lastrmargin = p->tcol->rmargin; p->tcol->rmargin = p->maxrmargin = p->defrmargin; } @@ -182,67 +173,76 @@ void terminal_sepline(void *arg) { struct termp *p; - size_t i; + size_t i; /* Printed width in basic units. */ + size_t sz; /* Width of a dash in basic units. */ p = (struct termp *)arg; (*p->endline)(p); - for (i = 0; i < p->defrmargin; i++) + sz = (*p->getwidth)(p, '-'); + for (i = 0; i < p->defrmargin; i += sz) (*p->letter)(p, '-'); (*p->endline)(p); (*p->endline)(p); } static size_t -ascii_width(const struct termp *p, int c) +ascii_getwidth(const struct termp *p, int c) { - return c != ASCII_BREAK && c != ASCII_NBRZW && c != ASCII_TABREF; + switch (c) { + case ASCII_BREAK: + case ASCII_NBRZW: + case ASCII_TABREF: + return 0; + default: + return 24; + } } void ascii_free(void *arg) { - term_free((struct termp *)arg); } static void ascii_letter(struct termp *p, int c) { - putchar(c); } static void ascii_begin(struct termp *p) { - (*p->headf)(p, p->argf); } static void ascii_end(struct termp *p) { - (*p->footf)(p, p->argf); } static void ascii_endline(struct termp *p) { - p->line++; if ((int)p->tcol->offset > p->ti) p->tcol->offset -= p->ti; else p->tcol->offset = 0; p->ti = 0; + p->minbl = 0; + p->viscol = 0; putchar('\n'); } static void ascii_advance(struct termp *p, size_t len) { - size_t i; + size_t dst; /* Destination column in basic units. */ + size_t sz; /* Width of a space in basic units. */ + + sz = (*p->getwidth)(p, ' '); /* * XXX We used to have "assert(len < UINT16_MAX)" here. @@ -250,10 +250,14 @@ ascii_advance(struct termp *p, size_t len) * can trigger that by merely providing large input. * For now, simply truncate. */ - if (len > 256) - len = 256; - for (i = 0; i < len; i++) + if (len > 256 * sz) + len = 256 * sz; + + dst = p->viscol + len; + while (p->viscol + sz / 2 < dst) { putchar(' '); + p->viscol += sz; + } } static int @@ -372,7 +376,7 @@ ascii_uc2str(int uc) #if HAVE_WCHAR static size_t -locale_width(const struct termp *p, int c) +locale_getwidth(const struct termp *p, int c) { int rc; @@ -381,13 +385,16 @@ locale_width(const struct termp *p, int c) rc = wcwidth(c); if (rc < 0) rc = 0; - return rc; + return rc * 24; } static void locale_advance(struct termp *p, size_t len) { - size_t i; + size_t dst; /* Destination column in basic units. */ + size_t sz; /* Width of a space in basic units. */ + + sz = (*p->getwidth)(p, ' '); /* * XXX We used to have "assert(len < UINT16_MAX)" here. @@ -395,29 +402,33 @@ locale_advance(struct termp *p, size_t len) * can trigger that by merely providing large input. * For now, simply truncate. */ - if (len > 256) - len = 256; - for (i = 0; i < len; i++) + if (len > 256 * sz) + len = 256 * sz; + + dst = p->viscol + len; + while (p->viscol + sz / 2 < dst) { putwchar(L' '); + p->viscol += sz; + } } static void locale_endline(struct termp *p) { - p->line++; if ((int)p->tcol->offset > p->ti) p->tcol->offset -= p->ti; else p->tcol->offset = 0; p->ti = 0; + p->minbl = 0; + p->viscol = 0; putwchar(L'\n'); } static void locale_letter(struct termp *p, int c) { - putwchar(c); } #endif |