source@mandoc.bsd.lv
 help / color / mirror / Atom feed
From: schwarze@mandoc.bsd.lv
To: source@mandoc.bsd.lv
Subject: mandoc: When starting a new input line, even when continuing the same
Date: Tue, 16 Aug 2022 12:46:25 -0500 (EST)	[thread overview]
Message-ID: <336a35bc2fff3d39@mandoc.bsd.lv> (raw)

Log Message:
-----------
When starting a new input line, even when continuing the same output
line, use the current output position as the reference position 
for tabs on that input line.  This brings mandoc in line with the 
behaviour of GNU, Heirloom, and Plan 9 roff.

Modified Files:
--------------
    mandoc:
        man_term.c
        mdoc_term.c
        term.c
        term.h
        term_ascii.c

Revision Data
-------------
Index: term.h
===================================================================
RCS file: /home/cvs/mandoc/mandoc/term.h,v
retrieving revision 1.133
retrieving revision 1.134
diff -Lterm.h -Lterm.h -u -p -r1.133 -r1.134
--- term.h
+++ term.h
@@ -1,7 +1,7 @@
 /* $Id$ */
 /*
+ * Copyright (c) 2011-2015,2017,2019,2022 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2011-2015, 2017, 2019 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
@@ -150,6 +150,7 @@ size_t		  term_len(const struct termp *,
 
 void		  term_tab_set(const struct termp *, const char *);
 void		  term_tab_iset(size_t);
+void		  term_tab_ref(struct termp *);
 size_t		  term_tab_next(size_t);
 void		  term_tab_free(void);
 
Index: term.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/term.c,v
retrieving revision 1.289
retrieving revision 1.290
diff -Lterm.c -Lterm.c -u -p -r1.289 -r1.290
--- term.c
+++ term.c
@@ -157,7 +157,11 @@ term_flushln(struct termp *p)
 		/* Finally, print the field content. */
 
 		term_field(p, vbl, nbr);
-		p->tcol->taboff += vbr + (*p->width)(p, ' ');
+		if (vbr < vtarget)
+			p->tcol->taboff += vbr;
+		else
+			p->tcol->taboff += vtarget;
+		p->tcol->taboff += (*p->width)(p, ' ');
 
 		/*
 		 * If there is no text left in the field, exit the loop.
@@ -177,7 +181,9 @@ term_flushln(struct termp *p)
 					vbr += (*p->width)(p, ' ');
 				continue;
 			case '\n':
+			case ASCII_NBRZW:
 			case ASCII_BREAK:
+			case ASCII_TABREF:
 				continue;
 			default:
 				break;
@@ -258,9 +264,11 @@ term_fill(struct termp *p, size_t *nbr, 
 	size_t	 vn;        /* Visual position of the next character. */
 	int	 breakline; /* Break at the end of this word. */
 	int	 graph;     /* Last character was non-blank. */
+	int	 taboff;    /* Temporary offset for literal tabs. */
 
 	*nbr = *vbr = vis = 0;
 	breakline = graph = 0;
+	taboff = p->tcol->taboff;
 	for (ic = p->tcol->col; ic < p->tcol->lastcol; ic++) {
 		switch (p->tcol->buf[ic]) {
 		case '\b':  /* Escape \o (overstrike) or backspace markup. */
@@ -306,12 +314,19 @@ term_fill(struct termp *p, size_t *nbr, 
 			*vbr = vis;
 			continue;
 
+		case ASCII_TABREF:
+			taboff = -vis - (*p->width)(p, ' ');
+			continue;
+
 		default:
 			switch (p->tcol->buf[ic]) {
 			case '\t':
-				vis += p->tcol->taboff;
+				if (taboff < 0 && (size_t)-taboff > vis)
+					vis = 0;
+				else
+					vis += taboff;
 				vis = term_tab_next(vis);
-				vis -= p->tcol->taboff;
+				vis -= taboff;
 				break;
 			case ASCII_NBRZW:  /* Non-breakable zero-width. */
 				break;
@@ -354,8 +369,10 @@ term_field(struct termp *p, size_t vbl, 
 	size_t	 vis;	/* Visual position of the current character. */
 	size_t	 vt;	/* Visual position including tab offset. */
 	size_t	 dv;	/* Visual width of the current character. */
+	int	 taboff; /* Temporary offset for literal tabs. */
 
 	vis = 0;
+	taboff = p->tcol->taboff;
 	for (ic = p->tcol->col; ic < nbr; ic++) {
 
 		/*
@@ -368,11 +385,17 @@ term_field(struct termp *p, size_t vbl, 
 		case ASCII_BREAK:
 		case ASCII_NBRZW:
 			continue;
+		case ASCII_TABREF:
+			taboff = -vis - (*p->width)(p, ' ');
+			continue;
 		case '\t':
 		case ' ':
 		case ASCII_NBRSP:
 			if (p->tcol->buf[ic] == '\t') {
-				vt = p->tcol->taboff + vis;
+				if (taboff < 0 && (size_t)-taboff > vis)
+					vt = 0;
+				else
+					vt = vis + taboff;
 				dv = term_tab_next(vt) - vt;
 			} else
 				dv = (*p->width)(p, ' ');
@@ -437,10 +460,10 @@ endline(struct termp *p)
 void
 term_newln(struct termp *p)
 {
-	p->tcol->taboff = 0;
 	p->flags |= TERMP_NOSPACE;
 	if (p->tcol->lastcol || p->viscol)
 		term_flushln(p);
+	p->tcol->taboff = 0;
 }
 
 /*
@@ -801,6 +824,14 @@ bufferc(struct termp *p, char c)
 		p->tcol->lastcol = p->col;
 }
 
+void
+term_tab_ref(struct termp *p)
+{
+	if (p->tcol->lastcol && p->tcol->lastcol <= p->col &&
+	    (p->flags & TERMP_NOBUF) == 0)
+		bufferc(p, ASCII_TABREF);
+}
+
 /*
  * See encode().
  * Do this for a single (probably unicode) value.
@@ -946,7 +977,7 @@ term_strlen(const struct termp *p, const
 	const char	*seq, *rhs;
 	enum mandoc_esc	 esc;
 	static const char rej[] = { '\\', ASCII_NBRSP, ASCII_NBRZW,
-		ASCII_BREAK, ASCII_HYPH, '\0' };
+		ASCII_BREAK, ASCII_HYPH, ASCII_TABREF, '\0' };
 
 	/*
 	 * Account for escaped sequences within string length
Index: mdoc_term.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/mdoc_term.c,v
retrieving revision 1.380
retrieving revision 1.381
diff -Lmdoc_term.c -Lmdoc_term.c -u -p -r1.380 -r1.381
--- mdoc_term.c
+++ mdoc_term.c
@@ -1,6 +1,6 @@
 /* $Id$ */
 /*
- * Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012-2020, 2022 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
  *
@@ -320,8 +320,11 @@ print_mdoc_node(DECL_ARGS)
 		    (p->flags & TERMP_NONEWLINE) == 0)
 			term_newln(p);
 		p->flags |= TERMP_BRNEVER;
-	} else
+	} else {
+		if (n->flags & NODE_LINE)
+			term_tab_ref(p);
 		p->flags &= ~TERMP_BRNEVER;
+	}
 
 	if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
 		return;
Index: man_term.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/man_term.c,v
retrieving revision 1.239
retrieving revision 1.240
diff -Lman_term.c -Lman_term.c -u -p -r1.239 -r1.240
--- man_term.c
+++ man_term.c
@@ -910,8 +910,11 @@ print_man_node(DECL_ARGS)
 		    (p->flags & TERMP_NONEWLINE) == 0)
 			term_newln(p);
 		p->flags |= TERMP_BRNEVER;
-	} else
+	} else {
+		if (n->flags & NODE_LINE)
+			term_tab_ref(p);
 		p->flags &= ~TERMP_BRNEVER;
+	}
 
 	if (n->flags & NODE_ID)
 		term_tag_write(n, p->line);
Index: term_ascii.c
===================================================================
RCS file: /home/cvs/mandoc/mandoc/term_ascii.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -Lterm_ascii.c -Lterm_ascii.c -u -p -r1.67 -r1.68
--- term_ascii.c
+++ term_ascii.c
@@ -196,7 +196,7 @@ terminal_sepline(void *arg)
 static size_t
 ascii_width(const struct termp *p, int c)
 {
-	return c != ASCII_BREAK && c != ASCII_NBRZW;
+	return c != ASCII_BREAK && c != ASCII_NBRZW && c != ASCII_TABREF;
 }
 
 void
--
 To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv


                 reply	other threads:[~2022-08-16 17:46 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=336a35bc2fff3d39@mandoc.bsd.lv \
    --to=schwarze@mandoc.bsd.lv \
    --cc=source@mandoc.bsd.lv \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).