aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/roff.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2020-02-27 01:43:52 +0000
committerIngo Schwarze <schwarze@openbsd.org>2020-02-27 01:43:52 +0000
commit88750dda2da444fce307d20d33700d72e7c49c7f (patch)
tree140fdcb1a59ea5418ca8046a300e844dadd832d6 /roff.c
parent4e9a246966125ec03e481374634f3448a906235b (diff)
downloadmandoc-88750dda2da444fce307d20d33700d72e7c49c7f.tar.gz
mandoc-88750dda2da444fce307d20d33700d72e7c49c7f.tar.zst
mandoc-88750dda2da444fce307d20d33700d72e7c49c7f.zip
Introduce the concept of nodes that are semantically transparent:
they are skipped when looking for previous or following high-level macros. Examples include roff(7) .ft, .ll, and .ta, mdoc(7) .Sm and .Tg, and man(7) .DT and .PD. Use this concept for a variety of improved decisions in various validators and formatters. While here, * remove a few const qualifiers on struct arguments that caused trouble; * get rid of some more Yoda notation in the vicinity; * and apply some other stylistic improvements in the vicinity. I found this class of issues while considering .Tg patches from kn@.
Diffstat (limited to 'roff.c')
-rw-r--r--roff.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/roff.c b/roff.c
index 84f2b7cc..017f28f9 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.369 2020/01/19 18:02:00 schwarze Exp $ */
+/* $Id: roff.c,v 1.370 2020/02/27 01:43:52 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
@@ -1114,6 +1114,59 @@ roff_node_delete(struct roff_man *man, struct roff_node *n)
roff_node_free(n);
}
+int
+roff_node_transparent(struct roff_node *n)
+{
+ if (n == NULL)
+ return 0;
+ if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
+ return 1;
+ switch (n->tok) {
+ case ROFF_ft:
+ case ROFF_ll:
+ case ROFF_mc:
+ case ROFF_po:
+ case ROFF_ta:
+ case MDOC_Db:
+ case MDOC_Es:
+ case MDOC_Sm:
+ case MDOC_Tg:
+ case MAN_DT:
+ case MAN_UC:
+ case MAN_PD:
+ case MAN_AT:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+struct roff_node *
+roff_node_child(struct roff_node *n)
+{
+ for (n = n->child; roff_node_transparent(n); n = n->next)
+ continue;
+ return n;
+}
+
+struct roff_node *
+roff_node_prev(struct roff_node *n)
+{
+ do {
+ n = n->prev;
+ } while (roff_node_transparent(n));
+ return n;
+}
+
+struct roff_node *
+roff_node_next(struct roff_node *n)
+{
+ do {
+ n = n->next;
+ } while (roff_node_transparent(n));
+ return n;
+}
+
void
deroff(char **dest, const struct roff_node *n)
{