1*544c191cSchristos /* Id: mdoc_state.c,v 1.15 2019/01/01 07:42:04 schwarze Exp */
29ff1f2acSchristos /*
3c9bcef03Schristos * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
49ff1f2acSchristos *
59ff1f2acSchristos * Permission to use, copy, modify, and distribute this software for any
69ff1f2acSchristos * purpose with or without fee is hereby granted, provided that the above
79ff1f2acSchristos * copyright notice and this permission notice appear in all copies.
89ff1f2acSchristos *
99ff1f2acSchristos * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
109ff1f2acSchristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
119ff1f2acSchristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
129ff1f2acSchristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
139ff1f2acSchristos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
149ff1f2acSchristos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
159ff1f2acSchristos * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
169ff1f2acSchristos */
179ff1f2acSchristos #include <sys/types.h>
189ff1f2acSchristos
19c9bcef03Schristos #include <assert.h>
20*544c191cSchristos #include <stdio.h>
219ff1f2acSchristos #include <stdlib.h>
229ff1f2acSchristos #include <string.h>
239ff1f2acSchristos
249ff1f2acSchristos #include "mandoc.h"
259ff1f2acSchristos #include "roff.h"
269ff1f2acSchristos #include "mdoc.h"
279ff1f2acSchristos #include "libmandoc.h"
28*544c191cSchristos #include "roff_int.h"
299ff1f2acSchristos #include "libmdoc.h"
309ff1f2acSchristos
319ff1f2acSchristos #define STATE_ARGS struct roff_man *mdoc, struct roff_node *n
329ff1f2acSchristos
339ff1f2acSchristos typedef void (*state_handler)(STATE_ARGS);
349ff1f2acSchristos
359ff1f2acSchristos static void state_bl(STATE_ARGS);
369ff1f2acSchristos static void state_sh(STATE_ARGS);
379ff1f2acSchristos static void state_sm(STATE_ARGS);
389ff1f2acSchristos
39*544c191cSchristos static const state_handler state_handlers[MDOC_MAX - MDOC_Dd] = {
409ff1f2acSchristos NULL, /* Dd */
419ff1f2acSchristos NULL, /* Dt */
429ff1f2acSchristos NULL, /* Os */
439ff1f2acSchristos state_sh, /* Sh */
449ff1f2acSchristos NULL, /* Ss */
459ff1f2acSchristos NULL, /* Pp */
469ff1f2acSchristos NULL, /* D1 */
47*544c191cSchristos NULL, /* Dl */
48*544c191cSchristos NULL, /* Bd */
499ff1f2acSchristos NULL, /* Ed */
509ff1f2acSchristos state_bl, /* Bl */
519ff1f2acSchristos NULL, /* El */
529ff1f2acSchristos NULL, /* It */
539ff1f2acSchristos NULL, /* Ad */
549ff1f2acSchristos NULL, /* An */
55c9bcef03Schristos NULL, /* Ap */
569ff1f2acSchristos NULL, /* Ar */
579ff1f2acSchristos NULL, /* Cd */
589ff1f2acSchristos NULL, /* Cm */
599ff1f2acSchristos NULL, /* Dv */
609ff1f2acSchristos NULL, /* Er */
619ff1f2acSchristos NULL, /* Ev */
629ff1f2acSchristos NULL, /* Ex */
639ff1f2acSchristos NULL, /* Fa */
649ff1f2acSchristos NULL, /* Fd */
659ff1f2acSchristos NULL, /* Fl */
669ff1f2acSchristos NULL, /* Fn */
679ff1f2acSchristos NULL, /* Ft */
689ff1f2acSchristos NULL, /* Ic */
699ff1f2acSchristos NULL, /* In */
709ff1f2acSchristos NULL, /* Li */
719ff1f2acSchristos NULL, /* Nd */
729ff1f2acSchristos NULL, /* Nm */
739ff1f2acSchristos NULL, /* Op */
749ff1f2acSchristos NULL, /* Ot */
759ff1f2acSchristos NULL, /* Pa */
769ff1f2acSchristos NULL, /* Rv */
779ff1f2acSchristos NULL, /* St */
789ff1f2acSchristos NULL, /* Va */
799ff1f2acSchristos NULL, /* Vt */
809ff1f2acSchristos NULL, /* Xr */
819ff1f2acSchristos NULL, /* %A */
829ff1f2acSchristos NULL, /* %B */
839ff1f2acSchristos NULL, /* %D */
849ff1f2acSchristos NULL, /* %I */
859ff1f2acSchristos NULL, /* %J */
869ff1f2acSchristos NULL, /* %N */
879ff1f2acSchristos NULL, /* %O */
889ff1f2acSchristos NULL, /* %P */
899ff1f2acSchristos NULL, /* %R */
909ff1f2acSchristos NULL, /* %T */
919ff1f2acSchristos NULL, /* %V */
929ff1f2acSchristos NULL, /* Ac */
939ff1f2acSchristos NULL, /* Ao */
949ff1f2acSchristos NULL, /* Aq */
959ff1f2acSchristos NULL, /* At */
969ff1f2acSchristos NULL, /* Bc */
979ff1f2acSchristos NULL, /* Bf */
989ff1f2acSchristos NULL, /* Bo */
999ff1f2acSchristos NULL, /* Bq */
1009ff1f2acSchristos NULL, /* Bsx */
1019ff1f2acSchristos NULL, /* Bx */
1029ff1f2acSchristos NULL, /* Db */
1039ff1f2acSchristos NULL, /* Dc */
1049ff1f2acSchristos NULL, /* Do */
1059ff1f2acSchristos NULL, /* Dq */
1069ff1f2acSchristos NULL, /* Ec */
1079ff1f2acSchristos NULL, /* Ef */
1089ff1f2acSchristos NULL, /* Em */
1099ff1f2acSchristos NULL, /* Eo */
1109ff1f2acSchristos NULL, /* Fx */
1119ff1f2acSchristos NULL, /* Ms */
1129ff1f2acSchristos NULL, /* No */
1139ff1f2acSchristos NULL, /* Ns */
1149ff1f2acSchristos NULL, /* Nx */
1159ff1f2acSchristos NULL, /* Ox */
1169ff1f2acSchristos NULL, /* Pc */
1179ff1f2acSchristos NULL, /* Pf */
1189ff1f2acSchristos NULL, /* Po */
1199ff1f2acSchristos NULL, /* Pq */
1209ff1f2acSchristos NULL, /* Qc */
1219ff1f2acSchristos NULL, /* Ql */
1229ff1f2acSchristos NULL, /* Qo */
1239ff1f2acSchristos NULL, /* Qq */
1249ff1f2acSchristos NULL, /* Re */
1259ff1f2acSchristos NULL, /* Rs */
1269ff1f2acSchristos NULL, /* Sc */
1279ff1f2acSchristos NULL, /* So */
1289ff1f2acSchristos NULL, /* Sq */
1299ff1f2acSchristos state_sm, /* Sm */
1309ff1f2acSchristos NULL, /* Sx */
1319ff1f2acSchristos NULL, /* Sy */
1329ff1f2acSchristos NULL, /* Tn */
1339ff1f2acSchristos NULL, /* Ux */
1349ff1f2acSchristos NULL, /* Xc */
1359ff1f2acSchristos NULL, /* Xo */
1369ff1f2acSchristos NULL, /* Fo */
1379ff1f2acSchristos NULL, /* Fc */
1389ff1f2acSchristos NULL, /* Oo */
1399ff1f2acSchristos NULL, /* Oc */
1409ff1f2acSchristos NULL, /* Bk */
1419ff1f2acSchristos NULL, /* Ek */
1429ff1f2acSchristos NULL, /* Bt */
1439ff1f2acSchristos NULL, /* Hf */
1449ff1f2acSchristos NULL, /* Fr */
1459ff1f2acSchristos NULL, /* Ud */
1469ff1f2acSchristos NULL, /* Lb */
1479ff1f2acSchristos NULL, /* Lp */
1489ff1f2acSchristos NULL, /* Lk */
1499ff1f2acSchristos NULL, /* Mt */
1509ff1f2acSchristos NULL, /* Brq */
1519ff1f2acSchristos NULL, /* Bro */
1529ff1f2acSchristos NULL, /* Brc */
1539ff1f2acSchristos NULL, /* %C */
1549ff1f2acSchristos NULL, /* Es */
1559ff1f2acSchristos NULL, /* En */
1569ff1f2acSchristos NULL, /* Dx */
1579ff1f2acSchristos NULL, /* %Q */
1589ff1f2acSchristos NULL, /* %U */
1599ff1f2acSchristos NULL, /* Ta */
1609ff1f2acSchristos };
1619ff1f2acSchristos
1629ff1f2acSchristos
1639ff1f2acSchristos void
mdoc_state(struct roff_man * mdoc,struct roff_node * n)1649ff1f2acSchristos mdoc_state(struct roff_man *mdoc, struct roff_node *n)
1659ff1f2acSchristos {
1669ff1f2acSchristos state_handler handler;
1679ff1f2acSchristos
168c9bcef03Schristos if (n->tok == TOKEN_NONE || n->tok < ROFF_MAX)
1699ff1f2acSchristos return;
1709ff1f2acSchristos
171c9bcef03Schristos assert(n->tok >= MDOC_Dd && n->tok < MDOC_MAX);
172*544c191cSchristos if ((mdoc_macro(n->tok)->flags & MDOC_PROLOGUE) == 0)
1739ff1f2acSchristos mdoc->flags |= MDOC_PBODY;
1749ff1f2acSchristos
175*544c191cSchristos handler = state_handlers[n->tok - MDOC_Dd];
1769ff1f2acSchristos if (*handler)
1779ff1f2acSchristos (*handler)(mdoc, n);
1789ff1f2acSchristos }
1799ff1f2acSchristos
1809ff1f2acSchristos static void
state_bl(STATE_ARGS)1819ff1f2acSchristos state_bl(STATE_ARGS)
1829ff1f2acSchristos {
183c9bcef03Schristos struct mdoc_arg *args;
184c9bcef03Schristos size_t i;
1859ff1f2acSchristos
1869ff1f2acSchristos if (n->type != ROFFT_HEAD || n->parent->args == NULL)
1879ff1f2acSchristos return;
1889ff1f2acSchristos
189c9bcef03Schristos args = n->parent->args;
190c9bcef03Schristos for (i = 0; i < args->argc; i++) {
191c9bcef03Schristos switch(args->argv[i].arg) {
1929ff1f2acSchristos case MDOC_Diag:
1939ff1f2acSchristos n->norm->Bl.type = LIST_diag;
194c9bcef03Schristos return;
1959ff1f2acSchristos case MDOC_Column:
1969ff1f2acSchristos n->norm->Bl.type = LIST_column;
197c9bcef03Schristos return;
1989ff1f2acSchristos default:
1999ff1f2acSchristos break;
2009ff1f2acSchristos }
2019ff1f2acSchristos }
202c9bcef03Schristos }
2039ff1f2acSchristos
2049ff1f2acSchristos static void
state_sh(STATE_ARGS)2059ff1f2acSchristos state_sh(STATE_ARGS)
2069ff1f2acSchristos {
2079ff1f2acSchristos struct roff_node *nch;
2089ff1f2acSchristos char *secname;
2099ff1f2acSchristos
2109ff1f2acSchristos if (n->type != ROFFT_HEAD)
2119ff1f2acSchristos return;
2129ff1f2acSchristos
2139508192eSchristos if ( ! (n->flags & NODE_VALID)) {
2149ff1f2acSchristos secname = NULL;
2159ff1f2acSchristos deroff(&secname, n);
2169ff1f2acSchristos
2179ff1f2acSchristos /*
2189ff1f2acSchristos * Set the section attribute for the BLOCK, HEAD,
2199ff1f2acSchristos * and HEAD children; the latter can only be TEXT
2209ff1f2acSchristos * nodes, so no recursion is needed. For other
2219ff1f2acSchristos * nodes, including the .Sh BODY, this is done
2229ff1f2acSchristos * when allocating the node data structures, but
2239ff1f2acSchristos * for .Sh BLOCK and HEAD, the section is still
2249ff1f2acSchristos * unknown at that time.
2259ff1f2acSchristos */
2269ff1f2acSchristos
2279ff1f2acSchristos n->sec = n->parent->sec = secname == NULL ?
2289ff1f2acSchristos SEC_CUSTOM : mdoc_a2sec(secname);
2299ff1f2acSchristos for (nch = n->child; nch != NULL; nch = nch->next)
2309ff1f2acSchristos nch->sec = n->sec;
2319ff1f2acSchristos free(secname);
2329ff1f2acSchristos }
2339ff1f2acSchristos
2349ff1f2acSchristos if ((mdoc->lastsec = n->sec) == SEC_SYNOPSIS) {
2359ff1f2acSchristos roff_setreg(mdoc->roff, "nS", 1, '=');
2369ff1f2acSchristos mdoc->flags |= MDOC_SYNOPSIS;
2379ff1f2acSchristos } else {
2389ff1f2acSchristos roff_setreg(mdoc->roff, "nS", 0, '=');
2399ff1f2acSchristos mdoc->flags &= ~MDOC_SYNOPSIS;
2409ff1f2acSchristos }
2419ff1f2acSchristos }
2429ff1f2acSchristos
2439ff1f2acSchristos static void
state_sm(STATE_ARGS)2449ff1f2acSchristos state_sm(STATE_ARGS)
2459ff1f2acSchristos {
2469ff1f2acSchristos
2479ff1f2acSchristos if (n->child == NULL)
2489ff1f2acSchristos mdoc->flags ^= MDOC_SMOFF;
2499ff1f2acSchristos else if ( ! strcmp(n->child->string, "on"))
2509ff1f2acSchristos mdoc->flags &= ~MDOC_SMOFF;
2519ff1f2acSchristos else if ( ! strcmp(n->child->string, "off"))
2529ff1f2acSchristos mdoc->flags |= MDOC_SMOFF;
2539ff1f2acSchristos }
254