diff options
121 files changed, 2339 insertions, 909 deletions
@@ -1,7 +1,7 @@ # $Id$ # +# Copyright (c) 2011, 2013-2020 Ingo Schwarze <schwarze@openbsd.org> # Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> -# Copyright (c) 2011, 2013-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 @@ -134,6 +134,7 @@ SRCS = arch.c \ term_ascii.c \ term_ps.c \ term_tab.c \ + term_tag.c \ tree.c DISTFILES = INSTALL \ @@ -209,6 +210,7 @@ DISTFILES = INSTALL \ tbl_int.h \ tbl_parse.h \ term.h \ + term_tag.h \ $(SRCS) \ $(TESTSRCS) @@ -245,7 +247,8 @@ LIBMANDOC_OBJS = $(LIBMAN_OBJS) \ mandoc_xr.o \ msec.o \ preconv.o \ - read.o + read.o \ + tag.o COMPAT_OBJS = compat_err.o \ compat_fts.o \ @@ -280,6 +283,7 @@ MANDOC_TERM_OBJS = eqn_term.o \ term_ascii.o \ term_ps.o \ term_tab.o \ + term_tag.o \ tbl_term.o DBM_OBJS = dbm.o \ @@ -302,7 +306,6 @@ MAIN_OBJS = $(MANDOC_HTML_OBJS) \ mdoc_man.o \ mdoc_markdown.o \ out.o \ - tag.o \ tree.o CGI_OBJS = $(MANDOC_HTML_OBJS) \ @@ -313,8 +316,7 @@ CGI_OBJS = $(MANDOC_HTML_OBJS) \ MANDOCD_OBJS = $(MANDOC_HTML_OBJS) \ $(MANDOC_TERM_OBJS) \ mandocd.o \ - out.o \ - tag.o + out.o DEMANDOC_OBJS = demandoc.o @@ -393,7 +395,7 @@ distclean: clean clean: rm -f libmandoc.a $(LIBMANDOC_OBJS) $(COMPAT_OBJS) - rm -f mandoc $(MAIN_OBJS) + rm -f mandoc man $(MAIN_OBJS) rm -f man.cgi $(CGI_OBJS) rm -f mandocd catman catman.o $(MANDOCD_OBJS) rm -f demandoc $(DEMANDOC_OBJS) @@ -501,7 +503,7 @@ uninstall: rm -f $(DESTDIR)$(INCLUDEDIR)/tbl.h [ ! -e $(DESTDIR)$(INCLUDEDIR) ] || rmdir $(DESTDIR)$(INCLUDEDIR) -regress: all +regress: all man cd regress && ./regress.pl regress-clean: @@ -517,6 +519,9 @@ libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS) mandoc: $(MAIN_OBJS) libmandoc.a $(CC) -o $@ $(LDFLAGS) $(MAIN_OBJS) libmandoc.a $(LDADD) +man: mandoc + $(LN) mandoc man + man.cgi: $(CGI_OBJS) libmandoc.a $(CC) $(STATIC) -o $@ $(LDFLAGS) $(CGI_OBJS) libmandoc.a $(LDADD) diff --git a/Makefile.depend b/Makefile.depend index 3540aeda..eb8606d5 100644 --- a/Makefile.depend +++ b/Makefile.depend @@ -33,12 +33,12 @@ eqn_html.o: eqn_html.c config.h mandoc.h roff.h eqn.h out.h html.h eqn_term.o: eqn_term.c config.h eqn.h out.h term.h html.o: html.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h out.h html.h manconf.h main.h lib.o: lib.c config.h roff.h libmdoc.h lib.in -main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h mandoc_parse.h tag.h main.h manconf.h mansearch.h +main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h mandoc_parse.h term_tag.h main.h manconf.h mansearch.h man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h man_html.o: man_html.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h html.h main.h man_macro.o: man_macro.c config.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h -man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h tag.h main.h -man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h +man_term.o: man_term.c config.h mandoc_aux.h mandoc.h roff.h man.h out.h term.h term_tag.h main.h +man_validate.o: man_validate.c config.h mandoc_aux.h mandoc.h roff.h tag.h man.h libmandoc.h roff_int.h libman.h mandoc.o: mandoc.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h roff_int.h mandoc_aux.o: mandoc_aux.c config.h mandoc.h mandoc_aux.h mandoc_msg.o: mandoc_msg.c config.h mandoc.h @@ -55,19 +55,19 @@ mdoc_macro.o: mdoc_macro.c config.h mandoc.h roff.h mdoc.h libmandoc.h roff_int. mdoc_man.o: mdoc_man.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h out.h main.h mdoc_markdown.o: mdoc_markdown.c mandoc_aux.h mandoc.h roff.h mdoc.h main.h mdoc_state.o: mdoc_state.c mandoc.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h -mdoc_term.o: mdoc_term.c config.h mandoc_aux.h roff.h mdoc.h out.h term.h tag.h main.h -mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h libmandoc.h roff_int.h libmdoc.h +mdoc_term.o: mdoc_term.c config.h mandoc_aux.h roff.h mdoc.h out.h term.h term_tag.h main.h +mdoc_validate.o: mdoc_validate.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h tag.h mdoc.h libmandoc.h roff_int.h libmdoc.h msec.o: msec.c config.h mandoc.h libmandoc.h msec.in out.o: out.c config.h mandoc_aux.h tbl.h out.h preconv.o: preconv.c config.h mandoc.h roff.h mandoc_parse.h libmandoc.h -read.o: read.c config.h mandoc_aux.h mandoc.h roff.h mdoc.h man.h mandoc_parse.h libmandoc.h roff_int.h +read.o: read.c config.h mandoc_aux.h mandoc.h roff.h tag.h mdoc.h man.h mandoc_parse.h libmandoc.h roff_int.h roff.o: roff.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h mandoc_parse.h libmandoc.h roff_int.h tbl_parse.h eqn_parse.h predefs.in roff_html.o: roff_html.c mandoc.h roff.h out.h html.h roff_term.o: roff_term.c mandoc.h roff.h out.h term.h roff_validate.o: roff_validate.c mandoc.h roff.h libmandoc.h roff_int.h soelim.o: soelim.c config.h compat_stringlist.h st.o: st.c config.h mandoc.h roff.h libmdoc.h -tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h tag.h +tag.o: tag.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h roff.h tag.h tbl.o: tbl.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_parse.h tbl_int.h tbl_data.o: tbl_data.c config.h mandoc_aux.h mandoc.h tbl.h libmandoc.h tbl_int.h tbl_html.o: tbl_html.c config.h mandoc.h roff.h tbl.h out.h html.h @@ -78,4 +78,5 @@ term.o: term.c config.h mandoc.h mandoc_aux.h out.h term.h main.h term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h manconf.h main.h term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h manconf.h main.h term_tab.o: term_tab.c mandoc_aux.h out.h term.h +term_tag.o: term_tag.c config.h mandoc.h roff.h tag.h term_tag.h tree.o: tree.c config.h mandoc.h roff.h mdoc.h man.h tbl.h eqn.h main.h @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,6 +14,9 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Common functions for mandoc(1) HTML formatters. + * For use by individual formatters and by the main program. */ #include "config.h" @@ -321,6 +324,18 @@ html_fillmode(struct html *h, enum roff_tok want) return had; } +/* + * Allocate a string to be used for the "id=" attribute of an HTML + * element and/or as a segment identifier for a URI in an <a> element. + * The function may fail and return NULL if the node lacks text data + * to create the attribute from. + * If the "unique" argument is 0, the caller is responsible for + * free(3)ing the returned string after using it. + * If the "unique" argument is non-zero, the "id_unique" ohash table + * is used for de-duplication and owns the returned string, so the + * caller must not free(3) it. In this case, it will be freed + * automatically by html_reset() or html_free(). + */ char * html_make_id(const struct roff_node *n, int unique) { @@ -329,14 +344,30 @@ html_make_id(const struct roff_node *n, int unique) unsigned int slot; int suffix; - for (nch = n->child; nch != NULL; nch = nch->next) - if (nch->type != ROFFT_TEXT) - return NULL; - - buf = NULL; - deroff(&buf, n); - if (buf == NULL) - return NULL; + if (n->string != NULL) + buf = mandoc_strdup(n->string); + else { + switch (n->tok) { + case MDOC_Sh: + case MDOC_Ss: + case MDOC_Sx: + case MAN_SH: + case MAN_SS: + for (nch = n->child; nch != NULL; nch = nch->next) + if (nch->type != ROFFT_TEXT) + return NULL; + buf = NULL; + deroff(&buf, n); + if (buf == NULL) + return NULL; + break; + default: + if (n->child->type != ROFFT_TEXT) + return NULL; + buf = mandoc_strdup(n->child->string); + break; + } + } /* * In ID attributes, only use ASCII characters that are @@ -736,6 +767,33 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) return t; } +/* + * Print an element with an optional "id=" attribute. + * If there is an "id=" attribute, also add a permalink: + * outside if it's a phrasing element, or inside otherwise. + */ +struct tag * +print_otag_id(struct html *h, enum htmltag elemtype, const char *cattr, + struct roff_node *n) +{ + struct tag *ret, *t; + const char *id; + + ret = NULL; + id = NULL; + if (n->flags & NODE_ID) + id = html_make_id(n, 1); + if (id != NULL && htmltags[elemtype].flags & HTML_INPHRASE) + ret = print_otag(h, TAG_A, "chR", "permalink", id); + t = print_otag(h, elemtype, "ci", cattr, id); + if (ret == NULL) { + ret = t; + if (id != NULL) + print_otag(h, TAG_A, "chR", "permalink", id); + } + return ret; +} + static void print_ctag(struct html *h, struct tag *tag) { @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* + * Copyright (c) 2017, 2018, 2019, 2020 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2017, 2018, 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 @@ -14,6 +14,9 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Internal interfaces for mandoc(1) HTML formatters. + * For use by the individual HTML formatters only. */ enum htmltag { @@ -120,6 +123,8 @@ void print_gen_comment(struct html *, struct roff_node *); void print_gen_decls(struct html *); void print_gen_head(struct html *); struct tag *print_otag(struct html *, enum htmltag, const char *, ...); +struct tag *print_otag_id(struct html *, enum htmltag, const char *, + struct roff_node *); void print_tagq(struct html *, const struct tag *); void print_stagq(struct html *, const struct tag *); void print_text(struct html *, const char *); @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2012, 2014-2020 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -15,6 +15,8 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Main program for mandoc(1), man(1), apropos(1), whatis(1), and help(1). */ #include "config.h" @@ -52,7 +54,7 @@ #include "mdoc.h" #include "man.h" #include "mandoc_parse.h" -#include "tag.h" +#include "term_tag.h" #include "main.h" #include "manconf.h" #include "mansearch.h" @@ -598,7 +600,6 @@ main(int argc, char *argv[]) * readable: Maybe it won't be needed after all. */ startdir = open(".", O_RDONLY | O_DIRECTORY); - for (i = 0; i < ressz; i++) { process_onefile(mp, res + i, startdir, &outst, &conf); if (outst.wstop && mandoc_msg_getrc() != MANDOCLEVEL_OK) @@ -608,7 +609,6 @@ main(int argc, char *argv[]) (void)fchdir(startdir); close(startdir); } - if (outst.outdata != NULL) { switch (outst.outtype) { case OUTT_HTML: @@ -617,6 +617,7 @@ main(int argc, char *argv[]) case OUTT_UTF8: case OUTT_LOCALE: case OUTT_ASCII: + term_tag_finish(); ascii_free(outst.outdata); break; case OUTT_PDF: @@ -638,9 +639,8 @@ out: if (outst.tag_files != NULL) { fclose(stdout); - tag_write(); run_pager(outst.tag_files); - tag_unlink(); + term_tag_unlink(); } else if (outst.had_output && outst.outtype != OUTT_LINT) mandoc_msg_summary(); @@ -831,15 +831,16 @@ process_onefile(struct mparse *mp, struct manpage *resp, int startdir, } else fd = STDIN_FILENO; - if (outst->use_pager) { - outst->use_pager = 0; - outst->tag_files = tag_init(conf->output.tag); - } - - if (outst->had_output && outst->outtype <= OUTT_UTF8) { - if (outst->outdata == NULL) - outdata_alloc(outst, &conf->output); - terminal_sepline(outst->outdata); + if (outst->outtype <= OUTT_UTF8) { + if (outst->use_pager) { + outst->use_pager = 0; + outst->tag_files = term_tag_init(conf->output.tag); + } + if (outst->had_output) { + if (outst->outdata == NULL) + outdata_alloc(outst, &conf->output); + terminal_sepline(outst->outdata); + } } if (resp->form == FORM_SRC) @@ -853,7 +854,7 @@ process_onefile(struct mparse *mp, struct manpage *resp, int startdir, if (outst->tag_files != NULL) { mandoc_msg(MANDOCERR_WRITE, 0, 0, "%s: %s", outst->tag_files->ofn, strerror(errno)); - tag_unlink(); + term_tag_unlink(); outst->tag_files = NULL; } else mandoc_msg(MANDOCERR_WRITE, 0, 0, "%s", @@ -1278,7 +1279,7 @@ spawn_pager(struct tag_files *tag_files) _exit(mandoc_msg_getrc()); } close(tag_files->ofd); - assert(tag_files->tfd == -1); + assert(tag_files->tfs == NULL); /* Do not start the pager before controlling the terminal. */ @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,6 +14,8 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * HTML formatter for man(7) used by mandoc(1). */ #include "config.h" @@ -310,7 +312,6 @@ static int man_SH_pre(MAN_ARGS) { const char *class; - char *id; enum htmltag tag; if (n->tok == MAN_SH) { @@ -326,10 +327,8 @@ man_SH_pre(MAN_ARGS) print_otag(h, TAG_SECTION, "c", class); break; case ROFFT_HEAD: - id = html_make_id(n, 1); - print_otag(h, tag, "ci", class, id); - if (id != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); + n->flags |= NODE_ID; + print_otag_id(h, tag, class, n); break; case ROFFT_BODY: break; @@ -489,7 +488,7 @@ man_IP_pre(MAN_ARGS) case ROFFT_HEAD: if (body_elem == TAG_LI) return 0; - print_otag(h, TAG_DT, ""); + print_otag_id(h, TAG_DT, NULL, n); break; case ROFFT_BODY: print_otag(h, body_elem, ""); @@ -497,7 +496,6 @@ man_IP_pre(MAN_ARGS) default: abort(); } - switch(n->tok) { case MAN_IP: /* Only print the first header element. */ if (n->child != NULL) @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,6 +14,9 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Plain text formatter for man(7), used by mandoc(1) + * for ASCII, UTF-8, PostScript, and PDF output. */ #include "config.h" @@ -32,7 +35,7 @@ #include "man.h" #include "out.h" #include "term.h" -#include "tag.h" +#include "term_tag.h" #include "main.h" #define MAXMARGINS 64 /* maximum number of indented scopes */ @@ -94,8 +97,6 @@ static void post_SY(DECL_ARGS); static void post_TP(DECL_ARGS); static void post_UR(DECL_ARGS); -static void tag_man(struct termp *, struct roff_node *); - static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = { { NULL, NULL, 0 }, /* TH */ { pre_SH, post_SH, 0 }, /* SH */ @@ -539,10 +540,8 @@ pre_IP(DECL_ARGS) case ROFFT_HEAD: p->tcol->offset = mt->offset; p->tcol->rmargin = mt->offset + len; - if (n->child != NULL) { + if (n->child != NULL) print_man_node(p, mt, n->child, meta); - tag_man(p, n->child); - } return 0; case ROFFT_BODY: p->tcol->offset = mt->offset + len; @@ -622,18 +621,6 @@ pre_TP(DECL_ARGS) while (nn != NULL && (nn->flags & NODE_LINE) == 0) nn = nn->next; - if (nn == NULL) - return 0; - - if (nn->type == ROFFT_TEXT) - tag_man(p, nn); - else if (nn->child != NULL && - nn->child->type == ROFFT_TEXT && - (nn->tok == MAN_B || nn->tok == MAN_BI || - nn->tok == MAN_BR || nn->tok == MAN_I || - nn->tok == MAN_IB || nn->tok == MAN_IR)) - tag_man(p, nn->child); - while (nn != NULL) { print_man_node(p, mt, nn, meta); nn = nn->next; @@ -913,6 +900,9 @@ print_man_node(DECL_ARGS) const struct man_term_act *act; int c; + if (n->flags & NODE_ID) + term_tag_write(n, p->line); + switch (n->type) { case ROFFT_TEXT: /* @@ -1159,60 +1149,3 @@ print_man_head(struct termp *p, const struct roff_meta *meta) } free(title); } - -/* - * Skip leading whitespace, dashes, backslashes, and font escapes, - * then create a tag if the first following byte is a letter. - * Priority is high unless whitespace is present. - */ -static void -tag_man(struct termp *p, struct roff_node *n) -{ - const char *cp, *arg; - int prio, sz; - - assert(n->type == ROFFT_TEXT); - cp = n->string; - prio = TAG_STRONG; - for (;;) { - switch (*cp) { - case ' ': - case '\t': - prio = TAG_WEAK; - /* FALLTHROUGH */ - case '-': - cp++; - break; - case '\\': - cp++; - switch (mandoc_escape(&cp, &arg, &sz)) { - case ESCAPE_FONT: - case ESCAPE_FONTROMAN: - case ESCAPE_FONTITALIC: - case ESCAPE_FONTBOLD: - case ESCAPE_FONTPREV: - case ESCAPE_FONTBI: - break; - case ESCAPE_SPECIAL: - if (sz != 1) - return; - switch (*arg) { - case '&': - case '-': - case 'e': - break; - default: - return; - } - break; - default: - return; - } - break; - default: - if (isalpha((unsigned char)*cp)) - tag_put(cp, prio, p->line); - return; - } - } -} diff --git a/man_validate.c b/man_validate.c index 1d3078a7..4e10fb55 100644 --- a/man_validate.c +++ b/man_validate.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,6 +14,8 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Validation module for man(7) syntax trees used by mandoc(1). */ #include "config.h" @@ -32,6 +34,7 @@ #include "mandoc_aux.h" #include "mandoc.h" #include "roff.h" +#include "tag.h" #include "man.h" #include "libmandoc.h" #include "roff_int.h" @@ -45,6 +48,7 @@ static void check_abort(CHKARGS) __attribute__((__noreturn__)); static void check_par(CHKARGS); static void check_part(CHKARGS); static void check_root(CHKARGS); +static void check_tag(struct roff_node *, struct roff_node *); static void check_text(CHKARGS); static void post_AT(CHKARGS); @@ -54,6 +58,7 @@ static void post_IP(CHKARGS); static void post_OP(CHKARGS); static void post_SH(CHKARGS); static void post_TH(CHKARGS); +static void post_TP(CHKARGS); static void post_UC(CHKARGS); static void post_UR(CHKARGS); static void post_in(CHKARGS); @@ -62,8 +67,8 @@ static const v_check man_valids[MAN_MAX - MAN_TH] = { post_TH, /* TH */ post_SH, /* SH */ post_SH, /* SS */ - NULL, /* TP */ - NULL, /* TQ */ + post_TP, /* TP */ + post_TP, /* TQ */ check_abort,/* LP */ check_par, /* PP */ check_abort,/* P */ @@ -201,6 +206,66 @@ check_abort(CHKARGS) abort(); } +/* + * Skip leading whitespace, dashes, backslashes, and font escapes, + * then create a tag if the first following byte is a letter. + * Priority is high unless whitespace is present. + */ +static void +check_tag(struct roff_node *n, struct roff_node *nt) +{ + const char *cp, *arg; + int prio, sz; + + if (nt == NULL || nt->type != ROFFT_TEXT) + return; + + cp = nt->string; + prio = TAG_STRONG; + for (;;) { + switch (*cp) { + case ' ': + case '\t': + prio = TAG_WEAK; + /* FALLTHROUGH */ + case '-': + cp++; + break; + case '\\': + cp++; + switch (mandoc_escape(&cp, &arg, &sz)) { + case ESCAPE_FONT: + case ESCAPE_FONTBOLD: + case ESCAPE_FONTITALIC: + case ESCAPE_FONTBI: + case ESCAPE_FONTROMAN: + case ESCAPE_FONTCW: + case ESCAPE_FONTPREV: + case ESCAPE_IGNORE: + break; + case ESCAPE_SPECIAL: + if (sz != 1) + return; + switch (*arg) { + case '-': + case 'e': + break; + default: + return; + } + break; + default: + return; + } + break; + default: + if (isalpha((unsigned char)*cp)) + tag_put(cp, prio, n); + return; + } + } +} + static void check_text(CHKARGS) { @@ -332,12 +397,14 @@ check_par(CHKARGS) static void post_IP(CHKARGS) { - switch (n->type) { case ROFFT_BLOCK: if (n->head->child == NULL && n->body->child == NULL) roff_node_delete(man, n); break; + case ROFFT_HEAD: + check_tag(n, n->child); + break; case ROFFT_BODY: if (n->parent->head->child == NULL && n->child == NULL) mandoc_msg(MANDOCERR_PAR_SKIP, n->line, n->pos, @@ -348,6 +415,37 @@ post_IP(CHKARGS) } } +/* + * The first next-line element in the head is the tag. + * If that's a font macro, use its first child instead. + */ +static void +post_TP(CHKARGS) +{ + struct roff_node *nt; + + if (n->type != ROFFT_HEAD || (nt = n->child) == NULL) + return; + + while ((nt->flags & NODE_LINE) == 0) + if ((nt = nt->next) == NULL) + return; + + switch (nt->tok) { + case MAN_B: + case MAN_BI: + case MAN_BR: + case MAN_I: + case MAN_IB: + case MAN_IR: + nt = nt->child; + break; + default: + break; + } + check_tag(n, nt); +} + static void post_TH(CHKARGS) { diff --git a/mandoc_headers.3 b/mandoc_headers.3 index 9e2c1752..f55d491d 100644 --- a/mandoc_headers.3 +++ b/mandoc_headers.3 @@ -1,6 +1,6 @@ .\" $Id$ .\" -.\" Copyright (c) 2014-2019 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2014-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 @@ -232,6 +232,30 @@ and the functions .Fn mandoc_xr_get , and .Fn mandoc_xr_free . +.It Qq Pa tag.h +Internal interfaces to tag syntax tree nodes, +for use by validation modules only. +.Pp +Requires +.In limits.h +for +.Dv INT_MAX . +.Pp +Provides the functions +.Fn tag_alloc , +.Fn tag_put , +.Fn tag_check , +and +.Fn tag_free +and some +.Dv TAG_* +constants. +.Pp +Uses the type +.Vt struct roff_node +from +.Qq Pa roff.h +as an opaque type for function prototypes. .El .Pp The following two require @@ -587,6 +611,33 @@ When this header is included, the same file should not include .Qq Pa html.h or .Qq Pa mansearch.h . +.It Qq Pa tag_term.h +Requires +.In sys/types.h +for +.Vt size_t +and +.In stdio.h +for +.Vt FILE . +.Pp +Provides an interface to generate +.Xr ctags 1 +files for the +.Ic :t +functionality mentioned in +.Xr man 1 . +.Pp +Uses the type +.Vt struct roff_node +from +.Qq Pa roff.h +as an opaque type for function prototypes. +.Pp +When this header is included, the same file should not include +.Qq Pa html.h +or +.Qq Pa mansearch.h . .It Qq Pa html.h Requires .In sys/types.h @@ -629,25 +680,10 @@ from as opaque types for function prototypes. .Pp When this header is included, the same file should not include -.Qq Pa term.h +.Qq Pa term.h , +.Qq Pa tab_term.h , or .Qq Pa mansearch.h . -.It Qq Pa tag.h -Requires -.In sys/types.h -for -.Vt size_t -and -.In limits.h -for -.Dv INT_MAX . -.Pp -Provides an interface to generate -.Xr ctags 1 -files for the -.Ic :t -functionality mentioned in -.Xr man 1 . .It Qq Pa main.h Provides the top level steering functions for all formatters. .Pp @@ -700,6 +736,7 @@ as an opaque type for function prototypes. When this header is included, the same file should not include .Qq Pa out.h , .Qq Pa term.h , +.Qq Pa tab_term.h , or .Qq Pa html.h . .El diff --git a/mandoc_html.3 b/mandoc_html.3 index 5b84769b..4ab03e21 100644 --- a/mandoc_html.3 +++ b/mandoc_html.3 @@ -53,10 +53,14 @@ .Ft char * .Fo html_make_id .Fa "const struct roff_node *n" +.Fa "int unique" .Fc -.Ft int -.Fo html_strlen -.Fa "const char *cp" +.Ft struct tag * +.Fo print_otag_id +.Fa "struct html *h" +.Fa "enum htmltag tag" +.Fa "const char *cattr" +.Fa "struct roff_node *n" .Fc .Sh DESCRIPTION The mandoc HTML formatter is not a formal library. @@ -257,23 +261,77 @@ functions. .Pp The function .Fn html_make_id -takes a node containing one or more text children -and returns a newly allocated string containing the concatenation -of the child strings, with blanks replaced by underscores. -If the node +allocates a string to be used for the +.Cm id +attribute of an HTML element and/or as a segment identifier for a URI in an +.Aq Ic A +element. +If .Fa n -contains any non-text child node, -.Fn html_make_id -returns +contains a +.Fa string +attribute, it is used; otherwise, child nodes are used. +If +.Fa n +is an +.Ic \&Sh , +.Ic \&Ss , +.Ic \&Sx , +.Ic SH , +or +.Ic SS +node, the resulting string is the concatenation of the child strings; +for other node types, only the first child is used. +Bytes not permitted in URI-fragment strings are replaced by underscores. +If any of the children to be used is not a text node, +no string is generated and .Dv NULL -instead. -The caller is responsible for freeing the returned string. +is returned instead. +If the +.Fa unique +argument is non-zero, deduplication is performed by appending an +underscore and a decimal integer, if necessary. .Pp The function -.Fn html_strlen -counts the number of characters in -.Fa cp . -It is used as a crude estimate of the width needed to display a string. +.Fn print_otag_id +opens a +.Fa tag +element of class +.Fa cattr +for the node +.Fa n . +If the flag +.Dv NODE_ID +is set in +.Fa n , +it attempts to generate an +.Cm id +attribute with +.Fn html_make_id . +If an +.Cm id +attribute is written, +.Fn print_otag_id +also adds an +.Aq Ic A +element of class +.Qq permalink : +outside if +.Fa n +generates a phrasing element, or inside otherwise. +This function is a wrapper around +.Fn html_make_id +and +.Fn print_otag , +fixing the +.Fa unique +argument to 1 and the +.Fa fmt +arguments to +.Qq chR +and +.Qq ci , +respectively. .Pp The functions .Fn print_eqn , @@ -281,6 +339,49 @@ The functions and .Fn print_tblclose are not yet documented. +.Sh RETURN VALUES +The functions +.Fn print_otag +and +.Fn print_otag_id +return a pointer to a new element on the stack of HTML elements. +When +.Fn print_otag_id +opens two elements, a pointer to the outer one is returned. +The memory pointed to is owned by the library and is automatically +.Xr free 3 Ns d +when +.Fn print_tagq +is called on it or when +.Fn print_stagq +is called on a parent element. +.Pp +The function +.Fn html_make_id +returns a newly allocated string or +.Dv NULL +if +.Fa n +lacks text data to create the attribute from. +If the +.Fa unique +argument is 0, the caller is responsible for +.Xr free 3 Ns ing +the returned string after using it. +If the +.Fa unique +argument is non-zero, the +.Va id_unique +ohash table is used for de-duplication and owns the returned string. +In this case, it will be freed automatically by +.Fn html_reset +or +.Fn html_free . +.Pp +In case of +.Xr malloc 3 +failure, these functions do not return but call +.Xr err 3 . .Sh FILES .Bl -tag -width mandoc_aux.c -compact .It Pa main.h diff --git a/mdoc_html.c b/mdoc_html.c index 5f3973ef..946af309 100644 --- a/mdoc_html.c +++ b/mdoc_html.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014-2020 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,6 +14,8 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * HTML formatter for mdoc(7) used by mandoc(1). */ #include "config.h" @@ -47,7 +49,6 @@ struct mdoc_html_act { void (*post)(MDOC_ARGS); }; -static char *cond_id(const struct roff_node *); static void print_mdoc_head(const struct roff_meta *, struct html *); static void print_mdoc_node(MDOC_ARGS); @@ -72,9 +73,8 @@ static void mdoc_bk_post(MDOC_ARGS); static int mdoc_bk_pre(MDOC_ARGS); static int mdoc_bl_pre(MDOC_ARGS); static int mdoc_cd_pre(MDOC_ARGS); -static int mdoc_cm_pre(MDOC_ARGS); +static int mdoc_code_pre(MDOC_ARGS); static int mdoc_d1_pre(MDOC_ARGS); -static int mdoc_dv_pre(MDOC_ARGS); static int mdoc_fa_pre(MDOC_ARGS); static int mdoc_fd_pre(MDOC_ARGS); static int mdoc_fl_pre(MDOC_ARGS); @@ -83,20 +83,15 @@ static int mdoc_ft_pre(MDOC_ARGS); static int mdoc_em_pre(MDOC_ARGS); static void mdoc_eo_post(MDOC_ARGS); static int mdoc_eo_pre(MDOC_ARGS); -static int mdoc_er_pre(MDOC_ARGS); -static int mdoc_ev_pre(MDOC_ARGS); static int mdoc_ex_pre(MDOC_ARGS); static void mdoc_fo_post(MDOC_ARGS); static int mdoc_fo_pre(MDOC_ARGS); -static int mdoc_ic_pre(MDOC_ARGS); static int mdoc_igndelim_pre(MDOC_ARGS); static int mdoc_in_pre(MDOC_ARGS); static int mdoc_it_pre(MDOC_ARGS); static int mdoc_lb_pre(MDOC_ARGS); -static int mdoc_li_pre(MDOC_ARGS); static int mdoc_lk_pre(MDOC_ARGS); static int mdoc_mt_pre(MDOC_ARGS); -static int mdoc_ms_pre(MDOC_ARGS); static int mdoc_nd_pre(MDOC_ARGS); static int mdoc_nm_pre(MDOC_ARGS); static int mdoc_no_pre(MDOC_ARGS); @@ -139,19 +134,19 @@ static const struct mdoc_html_act mdoc_html_acts[MDOC_MAX - MDOC_Dd] = { {mdoc_ap_pre, NULL}, /* Ap */ {mdoc_ar_pre, NULL}, /* Ar */ {mdoc_cd_pre, NULL}, /* Cd */ - {mdoc_cm_pre, NULL}, /* Cm */ - {mdoc_dv_pre, NULL}, /* Dv */ - {mdoc_er_pre, NULL}, /* Er */ - {mdoc_ev_pre, NULL}, /* Ev */ + {mdoc_code_pre, NULL}, /* Cm */ + {mdoc_code_pre, NULL}, /* Dv */ + {mdoc_code_pre, NULL}, /* Er */ + {mdoc_code_pre, NULL}, /* Ev */ {mdoc_ex_pre, NULL}, /* Ex */ {mdoc_fa_pre, NULL}, /* Fa */ {mdoc_fd_pre, NULL}, /* Fd */ {mdoc_fl_pre, NULL}, /* Fl */ {mdoc_fn_pre, NULL}, /* Fn */ {mdoc_ft_pre, NULL}, /* Ft */ - {mdoc_ic_pre, NULL}, /* Ic */ + {mdoc_code_pre, NULL}, /* Ic */ {mdoc_in_pre, NULL}, /* In */ - {mdoc_li_pre, NULL}, /* Li */ + {mdoc_code_pre, NULL}, /* Li */ {mdoc_nd_pre, NULL}, /* Nd */ {mdoc_nm_pre, NULL}, /* Nm */ {mdoc_quote_pre, mdoc_quote_post}, /* Op */ @@ -192,7 +187,7 @@ static const struct mdoc_html_act mdoc_html_acts[MDOC_MAX - MDOC_Dd] = { {mdoc_em_pre, NULL}, /* Em */ {mdoc_eo_pre, mdoc_eo_post}, /* Eo */ {mdoc_xx_pre, NULL}, /* Fx */ - {mdoc_ms_pre, NULL}, /* Ms */ + {mdoc_no_pre, NULL}, /* Ms */ {mdoc_no_pre, NULL}, /* No */ {mdoc_ns_pre, NULL}, /* Ns */ {mdoc_xx_pre, NULL}, /* Nx */ @@ -507,20 +502,11 @@ mdoc_root_pre(const struct roff_meta *meta, struct html *h) return 1; } -static char * -cond_id(const struct roff_node *n) +static int +mdoc_code_pre(MDOC_ARGS) { - if (n->child != NULL && - n->child->type == ROFFT_TEXT && - (n->prev == NULL || - (n->prev->type == ROFFT_TEXT && - strcmp(n->prev->string, "|") == 0)) && - (n->parent->tok == MDOC_It || - (n->parent->tok == MDOC_Xo && - n->parent->parent->prev == NULL && - n->parent->parent->parent->tok == MDOC_It))) - return html_make_id(n, 1); - return NULL; + print_otag_id(h, TAG_CODE, roff_name[n->tok], n); + return 1; } static int @@ -583,10 +569,8 @@ mdoc_sh_pre(MDOC_ARGS) print_otag(h, TAG_SECTION, "c", "Sh"); break; case ROFFT_HEAD: - id = html_make_id(n, 1); - print_otag(h, TAG_H1, "ci", "Sh", id); - if (id != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); + n->flags |= NODE_ID; + print_otag_id(h, TAG_H1, "Sh", n); break; case ROFFT_BODY: if (n->sec == SEC_AUTHORS) @@ -601,25 +585,20 @@ mdoc_sh_pre(MDOC_ARGS) static int mdoc_ss_pre(MDOC_ARGS) { - char *id; - switch (n->type) { case ROFFT_BLOCK: html_close_paragraph(h); print_otag(h, TAG_SECTION, "c", "Ss"); - return 1; + break; case ROFFT_HEAD: + n->flags |= NODE_ID; + print_otag_id(h, TAG_H2, "Ss", n); break; case ROFFT_BODY: - return 1; + break; default: abort(); } - - id = html_make_id(n, 1); - print_otag(h, TAG_H2, "ci", "Ss", id); - if (id != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); return 1; } @@ -627,12 +606,8 @@ static int mdoc_fl_pre(MDOC_ARGS) { struct roff_node *nn; - char *id; - - if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); - print_otag(h, TAG_CODE, "ci", "Fl", id); + print_otag_id(h, TAG_CODE, "Fl", n); print_text(h, "\\-"); if (n->child != NULL || ((nn = roff_node_next(n)) != NULL && @@ -644,17 +619,6 @@ mdoc_fl_pre(MDOC_ARGS) } static int -mdoc_cm_pre(MDOC_ARGS) -{ - char *id; - - if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); - print_otag(h, TAG_CODE, "ci", "Cm", id); - return 1; -} - -static int mdoc_nd_pre(MDOC_ARGS) { switch (n->type) { @@ -926,7 +890,7 @@ mdoc_st_pre(MDOC_ARGS) static int mdoc_em_pre(MDOC_ARGS) { - print_otag(h, TAG_I, "c", "Em"); + print_otag_id(h, TAG_I, "Em", n); return 1; } @@ -1052,45 +1016,6 @@ mdoc_cd_pre(MDOC_ARGS) } static int -mdoc_dv_pre(MDOC_ARGS) -{ - char *id; - - if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); - print_otag(h, TAG_CODE, "ci", "Dv", id); - return 1; -} - -static int -mdoc_ev_pre(MDOC_ARGS) -{ - char *id; - - if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); - print_otag(h, TAG_CODE, "ci", "Ev", id); - return 1; -} - -static int -mdoc_er_pre(MDOC_ARGS) -{ - char *id; - - id = n->sec == SEC_ERRORS && - (n->parent->tok == MDOC_It || - (n->parent->tok == MDOC_Bq && - n->parent->parent->parent->tok == MDOC_It)) ? - html_make_id(n, 1) : NULL; - - if (id != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); - print_otag(h, TAG_CODE, "ci", "Er", id); - return 1; -} - -static int mdoc_fa_pre(MDOC_ARGS) { const struct roff_node *nn; @@ -1222,7 +1147,7 @@ mdoc_fn_pre(MDOC_ARGS) print_tagq(h, t); } - t = print_otag(h, TAG_CODE, "c", "Fn"); + t = print_otag_id(h, TAG_CODE, "Fn", n); if (sp) print_text(h, sp); @@ -1341,14 +1266,12 @@ mdoc_mt_pre(MDOC_ARGS) for (n = n->child; n; n = n->next) { assert(n->type == ROFFT_TEXT); - mandoc_asprintf(&cp, "mailto:%s", n->string); t = print_otag(h, TAG_A, "ch", "Mt", cp); print_text(h, n->string); print_tagq(h, t); free(cp); } - return 0; } @@ -1357,30 +1280,30 @@ mdoc_fo_pre(MDOC_ARGS) { struct tag *t; - if (n->type == ROFFT_BODY) { + switch (n->type) { + case ROFFT_BLOCK: + synopsis_pre(h, n); + return 1; + case ROFFT_HEAD: + if (n->child != NULL) { + t = print_otag_id(h, TAG_CODE, "Fn", n); + print_text(h, n->child->string); + print_tagq(h, t); + } + return 0; + case ROFFT_BODY: h->flags |= HTML_NOSPACE; print_text(h, "("); h->flags |= HTML_NOSPACE; return 1; - } else if (n->type == ROFFT_BLOCK) { - synopsis_pre(h, n); - return 1; + default: + abort(); } - - if (n->child == NULL) - return 0; - - assert(n->child->string); - t = print_otag(h, TAG_CODE, "c", "Fn"); - print_text(h, n->child->string); - print_tagq(h, t); - return 0; } static void mdoc_fo_post(MDOC_ARGS) { - if (n->type != ROFFT_BODY) return; h->flags |= HTML_NOSPACE; @@ -1430,22 +1353,10 @@ mdoc_in_pre(MDOC_ARGS) assert(n->type == ROFFT_TEXT); print_text(h, n->string); } - return 0; } static int -mdoc_ic_pre(MDOC_ARGS) -{ - char *id; - - if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); - print_otag(h, TAG_CODE, "ci", "Ic", id); - return 1; -} - -static int mdoc_va_pre(MDOC_ARGS) { print_otag(h, TAG_VAR, "c", "Va"); @@ -1455,7 +1366,6 @@ mdoc_va_pre(MDOC_ARGS) static int mdoc_ap_pre(MDOC_ARGS) { - h->flags |= HTML_NOSPACE; print_text(h, "\\(aq"); h->flags |= HTML_NOSPACE; @@ -1494,20 +1404,8 @@ mdoc_bf_pre(MDOC_ARGS) } static int -mdoc_ms_pre(MDOC_ARGS) -{ - char *id; - - if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); - print_otag(h, TAG_SPAN, "ci", "Ms", id); - return 1; -} - -static int mdoc_igndelim_pre(MDOC_ARGS) { - h->flags |= HTML_IGNDELIM; return 1; } @@ -1515,7 +1413,6 @@ mdoc_igndelim_pre(MDOC_ARGS) static void mdoc_pf_post(MDOC_ARGS) { - if ( ! (n->next == NULL || n->next->flags & NODE_LINE)) h->flags |= HTML_NOSPACE; } @@ -1544,29 +1441,14 @@ mdoc_rs_pre(MDOC_ARGS) static int mdoc_no_pre(MDOC_ARGS) { - char *id; - - if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); - print_otag(h, TAG_SPAN, "ci", "No", id); - return 1; -} - -static int -mdoc_li_pre(MDOC_ARGS) -{ - char *id; - - if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "permalink", id); - print_otag(h, TAG_CODE, "ci", "Li", id); + print_otag_id(h, TAG_SPAN, roff_name[n->tok], n); return 1; } static int mdoc_sy_pre(MDOC_ARGS) { - print_otag(h, TAG_B, "c", "Sy"); + print_otag_id(h, TAG_B, "Sy", n); return 1; } diff --git a/mdoc_term.c b/mdoc_term.c index 35e05809..f7e59cca 100644 --- a/mdoc_term.c +++ b/mdoc_term.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de> * * Permission to use, copy, modify, and distribute this software for any @@ -15,6 +15,9 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Plain text formatter for mdoc(7), used by mandoc(1) + * for ASCII, UTF-8, PostScript, and PDF output. */ #include "config.h" @@ -33,7 +36,7 @@ #include "mdoc.h" #include "out.h" #include "term.h" -#include "tag.h" +#include "term_tag.h" #include "main.h" struct termpair { @@ -89,11 +92,8 @@ static int termp_bf_pre(DECL_ARGS); static int termp_bk_pre(DECL_ARGS); static int termp_bl_pre(DECL_ARGS); static int termp_bold_pre(DECL_ARGS); -static int termp_cd_pre(DECL_ARGS); static int termp_d1_pre(DECL_ARGS); static int termp_eo_pre(DECL_ARGS); -static int termp_em_pre(DECL_ARGS); -static int termp_er_pre(DECL_ARGS); static int termp_ex_pre(DECL_ARGS); static int termp_fa_pre(DECL_ARGS); static int termp_fd_pre(DECL_ARGS); @@ -115,8 +115,6 @@ static int termp_skip_pre(DECL_ARGS); static int termp_sm_pre(DECL_ARGS); static int termp_pp_pre(DECL_ARGS); static int termp_ss_pre(DECL_ARGS); -static int termp_sy_pre(DECL_ARGS); -static int termp_tag_pre(DECL_ARGS); static int termp_under_pre(DECL_ARGS); static int termp_vt_pre(DECL_ARGS); static int termp_xr_pre(DECL_ARGS); @@ -140,11 +138,11 @@ static const struct mdoc_term_act mdoc_term_acts[MDOC_MAX - MDOC_Dd] = { { termp_an_pre, NULL }, /* An */ { termp_ap_pre, NULL }, /* Ap */ { termp_under_pre, NULL }, /* Ar */ - { termp_cd_pre, NULL }, /* Cd */ + { termp_fd_pre, NULL }, /* Cd */ { termp_bold_pre, NULL }, /* Cm */ { termp_li_pre, NULL }, /* Dv */ - { termp_er_pre, NULL }, /* Er */ - { termp_tag_pre, NULL }, /* Ev */ + { NULL, NULL }, /* Er */ + { NULL, NULL }, /* Ev */ { termp_ex_pre, NULL }, /* Ex */ { termp_fa_pre, NULL }, /* Fa */ { termp_fd_pre, termp_fd_post }, /* Fd */ @@ -191,7 +189,7 @@ static const struct mdoc_term_act mdoc_term_acts[MDOC_MAX - MDOC_Dd] = { { termp_quote_pre, termp_quote_post }, /* Dq */ { NULL, NULL }, /* Ec */ /* FIXME: no space */ { NULL, NULL }, /* Ef */ - { termp_em_pre, NULL }, /* Em */ + { termp_under_pre, NULL }, /* Em */ { termp_eo_pre, termp_eo_post }, /* Eo */ { termp_xx_pre, termp_xx_post }, /* Fx */ { termp_bold_pre, NULL }, /* Ms */ @@ -214,7 +212,7 @@ static const struct mdoc_term_act mdoc_term_acts[MDOC_MAX - MDOC_Dd] = { { termp_quote_pre, termp_quote_post }, /* Sq */ { termp_sm_pre, NULL }, /* Sm */ { termp_under_pre, NULL }, /* Sx */ - { termp_sy_pre, NULL }, /* Sy */ + { termp_bold_pre, NULL }, /* Sy */ { NULL, NULL }, /* Tn */ { termp_xx_pre, termp_xx_post }, /* Ux */ { NULL, NULL }, /* Xc */ @@ -246,8 +244,6 @@ static const struct mdoc_term_act mdoc_term_acts[MDOC_MAX - MDOC_Dd] = { { termp_skip_pre, NULL }, /* Tg */ }; -static int fn_prio = TAG_STRONG; - void terminal_mdoc(void *arg, const struct roff_meta *mdoc) @@ -300,7 +296,6 @@ terminal_mdoc(void *arg, const struct roff_meta *mdoc) static void print_mdoc_nodelist(DECL_ARGS) { - while (n != NULL) { print_mdoc_node(p, pair, meta, n); n = n->next; @@ -341,8 +336,7 @@ print_mdoc_node(DECL_ARGS) npair.ppair = pair; if (n->flags & NODE_ID) - tag_put(n->string == NULL ? n->child->string : n->string, - TAG_MANUAL, p->line); + term_tag_write(n, p->line); /* * Keeps only work until the end of a line. If a keep was @@ -1008,24 +1002,30 @@ termp_nm_pre(DECL_ARGS) p->flags |= TERMP_HANG; } } - - term_fontpush(p, TERMFONT_BOLD); - return 1; + return termp_bold_pre(p, pair, meta, n); } static void termp_nm_post(DECL_ARGS) { - - if (n->type == ROFFT_BLOCK) { + switch (n->type) { + case ROFFT_BLOCK: p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP); - } else if (n->type == ROFFT_HEAD && - NULL != n->next && NULL != n->next->child) { + break; + case ROFFT_HEAD: + if (n->next == NULL || n->next->child == NULL) + break; term_flushln(p); p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG); p->trailspace = 0; - } else if (n->type == ROFFT_BODY && n->child != NULL) - term_flushln(p); + break; + case ROFFT_BODY: + if (n->child != NULL) + term_flushln(p); + break; + default: + break; + } } static int @@ -1033,7 +1033,6 @@ termp_fl_pre(DECL_ARGS) { struct roff_node *nn; - termp_tag_pre(p, pair, meta, n); term_fontpush(p, TERMFONT_BOLD); term_word(p, "\\-"); @@ -1219,24 +1218,22 @@ synopsis_pre(struct termp *p, struct roff_node *n) static int termp_vt_pre(DECL_ARGS) { - - if (n->type == ROFFT_ELEM) { - synopsis_pre(p, n); - return termp_under_pre(p, pair, meta, n); - } else if (n->type == ROFFT_BLOCK) { + switch (n->type) { + case ROFFT_ELEM: + return termp_ft_pre(p, pair, meta, n); + case ROFFT_BLOCK: synopsis_pre(p, n); return 1; - } else if (n->type == ROFFT_HEAD) + case ROFFT_HEAD: return 0; - - return termp_under_pre(p, pair, meta, n); + default: + return termp_under_pre(p, pair, meta, n); + } } static int termp_bold_pre(DECL_ARGS) { - - termp_tag_pre(p, pair, meta, n); term_fontpush(p, TERMFONT_BOLD); return 1; } @@ -1244,7 +1241,6 @@ termp_bold_pre(DECL_ARGS) static int termp_fd_pre(DECL_ARGS) { - synopsis_pre(p, n); return termp_bold_pre(p, pair, meta, n); } @@ -1252,7 +1248,6 @@ termp_fd_pre(DECL_ARGS) static void termp_fd_post(DECL_ARGS) { - term_newln(p); } @@ -1273,23 +1268,14 @@ termp_sh_pre(DECL_ARGS) term_vspace(p); break; case ROFFT_HEAD: - term_fontpush(p, TERMFONT_BOLD); - break; + return termp_bold_pre(p, pair, meta, n); case ROFFT_BODY: p->tcol->offset = term_len(p, p->defindent); term_tab_set(p, NULL); term_tab_set(p, "T"); term_tab_set(p, ".5i"); - switch (n->sec) { - case SEC_DESCRIPTION: - fn_prio = TAG_STRONG; - break; - case SEC_AUTHORS: + if (n->sec == SEC_AUTHORS) p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT); - break; - default: - break; - } break; default: break; @@ -1300,7 +1286,6 @@ termp_sh_pre(DECL_ARGS) static void termp_sh_post(DECL_ARGS) { - switch (n->type) { case ROFFT_HEAD: term_newln(p); @@ -1317,15 +1302,13 @@ termp_sh_post(DECL_ARGS) static void termp_lb_post(DECL_ARGS) { - - if (SEC_LIBRARY == n->sec && NODE_LINE & n->flags) + if (n->sec == SEC_LIBRARY && n->flags & NODE_LINE) term_newln(p); } static int termp_d1_pre(DECL_ARGS) { - if (n->type != ROFFT_BLOCK) return 1; term_newln(p); @@ -1339,11 +1322,8 @@ termp_d1_pre(DECL_ARGS) static int termp_ft_pre(DECL_ARGS) { - - /* NB: NODE_LINE does not effect this! */ synopsis_pre(p, n); - term_fontpush(p, TERMFONT_UNDER); - return 1; + return termp_under_pre(p, pair, meta, n); } static int @@ -1352,11 +1332,9 @@ termp_fn_pre(DECL_ARGS) size_t rmargin = 0; int pretty; - pretty = NODE_SYNPRETTY & n->flags; - synopsis_pre(p, n); - - if (NULL == (n = n->child)) + pretty = n->flags & NODE_SYNPRETTY; + if ((n = n->child) == NULL) return 0; if (pretty) { @@ -1370,9 +1348,6 @@ termp_fn_pre(DECL_ARGS) term_word(p, n->string); term_fontpop(p); - if (n->sec == SEC_DESCRIPTION || n->sec == SEC_CUSTOM) - tag_put(n->string, fn_prio++, p->line); - if (pretty) { term_flushln(p); p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG); @@ -1407,7 +1382,6 @@ termp_fn_pre(DECL_ARGS) term_word(p, ";"); term_flushln(p); } - return 0; } @@ -1416,10 +1390,9 @@ termp_fa_pre(DECL_ARGS) { const struct roff_node *nn; - if (n->parent->tok != MDOC_Fo) { - term_fontpush(p, TERMFONT_UNDER); - return 1; - } + if (n->parent->tok != MDOC_Fo) + return termp_under_pre(p, pair, meta, n); + for (nn = n->child; nn != NULL; nn = nn->next) { term_fontpush(p, TERMFONT_UNDER); p->flags |= TERMP_NBRWORD; @@ -1530,9 +1503,8 @@ termp_ss_pre(DECL_ARGS) term_vspace(p); break; case ROFFT_HEAD: - term_fontpush(p, TERMFONT_BOLD); p->tcol->offset = term_len(p, (p->defindent+1)/2); - break; + return termp_bold_pre(p, pair, meta, n); case ROFFT_BODY: p->tcol->offset = term_len(p, p->defindent); term_tab_set(p, NULL); @@ -1553,21 +1525,10 @@ termp_ss_post(DECL_ARGS) } static int -termp_cd_pre(DECL_ARGS) -{ - - synopsis_pre(p, n); - term_fontpush(p, TERMFONT_BOLD); - return 1; -} - -static int termp_in_pre(DECL_ARGS) { - synopsis_pre(p, n); - - if (NODE_SYNPRETTY & n->flags && NODE_LINE & n->flags) { + if (n->flags & NODE_SYNPRETTY && n->flags & NODE_LINE) { term_fontpush(p, TERMFONT_BOLD); term_word(p, "#include"); term_word(p, "<"); @@ -1575,7 +1536,6 @@ termp_in_pre(DECL_ARGS) term_word(p, "<"); term_fontpush(p, TERMFONT_UNDER); } - p->flags |= TERMP_NOSPACE; return 1; } @@ -1583,21 +1543,17 @@ termp_in_pre(DECL_ARGS) static void termp_in_post(DECL_ARGS) { - - if (NODE_SYNPRETTY & n->flags) + if (n->flags & NODE_SYNPRETTY) term_fontpush(p, TERMFONT_BOLD); - p->flags |= TERMP_NOSPACE; term_word(p, ">"); - - if (NODE_SYNPRETTY & n->flags) + if (n->flags & NODE_SYNPRETTY) term_fontpop(p); } static int termp_pp_pre(DECL_ARGS) { - fn_prio = TAG_STRONG; term_vspace(p); return 0; } @@ -1605,14 +1561,12 @@ termp_pp_pre(DECL_ARGS) static int termp_skip_pre(DECL_ARGS) { - return 0; } static int termp_quote_pre(DECL_ARGS) { - if (n->type != ROFFT_BODY && n->type != ROFFT_ELEM) return 1; @@ -1769,17 +1723,15 @@ termp_eo_post(DECL_ARGS) static int termp_fo_pre(DECL_ARGS) { - size_t rmargin = 0; - int pretty; - - pretty = NODE_SYNPRETTY & n->flags; + size_t rmargin; - if (n->type == ROFFT_BLOCK) { + switch (n->type) { + case ROFFT_BLOCK: synopsis_pre(p, n); return 1; - } else if (n->type == ROFFT_BODY) { - if (pretty) { - rmargin = p->tcol->rmargin; + case ROFFT_BODY: + rmargin = p->tcol->rmargin; + if (n->flags & NODE_SYNPRETTY) { p->tcol->rmargin = p->tcol->offset + term_len(p, 4); p->flags |= TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG; @@ -1787,7 +1739,7 @@ termp_fo_pre(DECL_ARGS) p->flags |= TERMP_NOSPACE; term_word(p, "("); p->flags |= TERMP_NOSPACE; - if (pretty) { + if (n->flags & NODE_SYNPRETTY) { term_flushln(p); p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND | TERMP_HANG); @@ -1796,30 +1748,21 @@ termp_fo_pre(DECL_ARGS) p->tcol->rmargin = rmargin; } return 1; + default: + return termp_bold_pre(p, pair, meta, n); } - - if (NULL == n->child) - return 0; - - /* XXX: we drop non-initial arguments as per groff. */ - - assert(n->child->string); - term_fontpush(p, TERMFONT_BOLD); - term_word(p, n->child->string); - return 0; } static void termp_fo_post(DECL_ARGS) { - if (n->type != ROFFT_BODY) return; p->flags |= TERMP_NOSPACE; term_word(p, ")"); - if (NODE_SYNPRETTY & n->flags) { + if (n->flags & NODE_SYNPRETTY) { p->flags |= TERMP_NOSPACE; term_word(p, ";"); term_flushln(p); @@ -1829,29 +1772,30 @@ termp_fo_post(DECL_ARGS) static int termp_bf_pre(DECL_ARGS) { - - if (n->type == ROFFT_HEAD) + switch (n->type) { + case ROFFT_HEAD: return 0; - else if (n->type != ROFFT_BODY) + case ROFFT_BODY: + break; + default: return 1; - - if (FONT_Em == n->norm->Bf.font) - term_fontpush(p, TERMFONT_UNDER); - else if (FONT_Sy == n->norm->Bf.font) - term_fontpush(p, TERMFONT_BOLD); - else - term_fontpush(p, TERMFONT_NONE); - - return 1; + } + switch (n->norm->Bf.font) { + case FONT_Em: + return termp_under_pre(p, pair, meta, n); + case FONT_Sy: + return termp_bold_pre(p, pair, meta, n); + default: + return termp_li_pre(p, pair, meta, n); + } } static int termp_sm_pre(DECL_ARGS) { - - if (NULL == n->child) + if (n->child == NULL) p->flags ^= TERMP_NONOSPACE; - else if (0 == strcmp("on", n->child->string)) + else if (strcmp(n->child->string, "on") == 0) p->flags &= ~TERMP_NONOSPACE; else p->flags |= TERMP_NONOSPACE; @@ -1865,7 +1809,6 @@ termp_sm_pre(DECL_ARGS) static int termp_ap_pre(DECL_ARGS) { - p->flags |= TERMP_NOSPACE; term_word(p, "'"); p->flags |= TERMP_NOSPACE; @@ -1904,8 +1847,6 @@ termp____post(DECL_ARGS) static int termp_li_pre(DECL_ARGS) { - - termp_tag_pre(p, pair, meta, n); term_fontpush(p, TERMFONT_NONE); return 1; } @@ -1955,7 +1896,6 @@ termp_lk_pre(DECL_ARGS) static int termp_bk_pre(DECL_ARGS) { - switch (n->type) { case ROFFT_BLOCK: break; @@ -1968,107 +1908,47 @@ termp_bk_pre(DECL_ARGS) default: abort(); } - return 1; } static void termp_bk_post(DECL_ARGS) { - if (n->type == ROFFT_BODY) p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP); } +/* + * If we are in an `Rs' and there is a journal present, + * then quote us instead of underlining us (for disambiguation). + */ static void termp__t_post(DECL_ARGS) { - - /* - * If we're in an `Rs' and there's a journal present, then quote - * us instead of underlining us (for disambiguation). - */ - if (n->parent && MDOC_Rs == n->parent->tok && + if (n->parent != NULL && n->parent->tok == MDOC_Rs && n->parent->norm->Rs.quote_T) termp_quote_post(p, pair, meta, n); - termp____post(p, pair, meta, n); } static int termp__t_pre(DECL_ARGS) { - - /* - * If we're in an `Rs' and there's a journal present, then quote - * us instead of underlining us (for disambiguation). - */ - if (n->parent && MDOC_Rs == n->parent->tok && + if (n->parent != NULL && n->parent->tok == MDOC_Rs && n->parent->norm->Rs.quote_T) return termp_quote_pre(p, pair, meta, n); - - term_fontpush(p, TERMFONT_UNDER); - return 1; + else + return termp_under_pre(p, pair, meta, n); } static int termp_under_pre(DECL_ARGS) { - - term_fontpush(p, TERMFONT_UNDER); - return 1; -} - -static int -termp_em_pre(DECL_ARGS) -{ - if (n->child != NULL && - n->child->type == ROFFT_TEXT) - tag_put(n->child->string, TAG_FALLBACK, p->line); term_fontpush(p, TERMFONT_UNDER); return 1; } static int -termp_sy_pre(DECL_ARGS) -{ - if (n->child != NULL && - n->child->type == ROFFT_TEXT) - tag_put(n->child->string, TAG_FALLBACK, p->line); - term_fontpush(p, TERMFONT_BOLD); - return 1; -} - -static int -termp_er_pre(DECL_ARGS) -{ - - if (n->sec == SEC_ERRORS && - (n->parent->tok == MDOC_It || - (n->parent->tok == MDOC_Bq && - n->parent->parent->parent->tok == MDOC_It))) - tag_put(n->child->string, TAG_STRONG, p->line); - return 1; -} - -static int -termp_tag_pre(DECL_ARGS) -{ - - if (n->child != NULL && - n->child->type == ROFFT_TEXT && - (n->prev == NULL || - (n->prev->type == ROFFT_TEXT && - strcmp(n->prev->string, "|") == 0)) && - (n->parent->tok == MDOC_It || - (n->parent->tok == MDOC_Xo && - n->parent->parent->prev == NULL && - n->parent->parent->parent->tok == MDOC_It))) - tag_put(n->child->string, TAG_STRONG, p->line); - return 1; -} - -static int termp_abort_pre(DECL_ARGS) { abort(); diff --git a/mdoc_validate.c b/mdoc_validate.c index c8e261f9..7bcb841d 100644 --- a/mdoc_validate.c +++ b/mdoc_validate.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2020 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -15,6 +15,8 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Validation module for mdoc(7) syntax trees used by mandoc(1). */ #include "config.h" @@ -35,6 +37,7 @@ #include "mandoc.h" #include "mandoc_xr.h" #include "roff.h" +#include "tag.h" #include "mdoc.h" #include "libmandoc.h" #include "roff_int.h" @@ -82,7 +85,9 @@ static void post_dd(POST_ARGS); static void post_delim(POST_ARGS); static void post_delim_nb(POST_ARGS); static void post_dt(POST_ARGS); +static void post_em(POST_ARGS); static void post_en(POST_ARGS); +static void post_er(POST_ARGS); static void post_es(POST_ARGS); static void post_eoln(POST_ARGS); static void post_ex(POST_ARGS); @@ -113,6 +118,7 @@ static void post_sm(POST_ARGS); static void post_st(POST_ARGS); static void post_std(POST_ARGS); static void post_sx(POST_ARGS); +static void post_tag(POST_ARGS); static void post_tg(POST_ARGS); static void post_useless(POST_ARGS); static void post_xr(POST_ARGS); @@ -137,19 +143,19 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = { NULL, /* Ap */ post_defaults, /* Ar */ NULL, /* Cd */ - post_delim_nb, /* Cm */ - post_delim_nb, /* Dv */ - post_delim_nb, /* Er */ - post_delim_nb, /* Ev */ + post_tag, /* Cm */ + post_tag, /* Dv */ + post_er, /* Er */ + post_tag, /* Ev */ post_ex, /* Ex */ post_fa, /* Fa */ NULL, /* Fd */ - post_delim_nb, /* Fl */ + post_tag, /* Fl */ post_fn, /* Fn */ post_delim_nb, /* Ft */ - post_delim_nb, /* Ic */ + post_tag, /* Ic */ post_delim_nb, /* In */ - post_defaults, /* Li */ + post_tag, /* Li */ post_nd, /* Nd */ post_nm, /* Nm */ post_delim_nb, /* Op */ @@ -187,11 +193,11 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = { NULL, /* Dq */ NULL, /* Ec */ NULL, /* Ef */ - post_delim_nb, /* Em */ + post_em, /* Em */ NULL, /* Eo */ post_xx, /* Fx */ - post_delim_nb, /* Ms */ - NULL, /* No */ + post_tag, /* Ms */ + post_tag, /* No */ post_ns, /* Ns */ post_xx, /* Nx */ post_xx, /* Ox */ @@ -210,7 +216,7 @@ static const v_post mdoc_valids[MDOC_MAX - MDOC_Dd] = { post_delim_nb, /* Sq */ post_sm, /* Sm */ post_sx, /* Sx */ - post_delim_nb, /* Sy */ + post_em, /* Sy */ post_useless, /* Tn */ post_xx, /* Ux */ NULL, /* Xc */ @@ -287,6 +293,8 @@ static const char * const secnames[SEC__MAX] = { NULL }; +static int fn_prio = TAG_STRONG; + /* Validate the subtree rooted at mdoc->last. */ void @@ -1094,8 +1102,11 @@ post_st(POST_ARGS) static void post_tg(POST_ARGS) { - struct roff_node *n, *nch, *nn; - size_t len; + struct roff_node *n; /* The .Tg node. */ + struct roff_node *nch; /* The first child of the .Tg node. */ + struct roff_node *nn; /* The next node after the .Tg node. */ + struct roff_node *nt; /* The TEXT node containing the tag. */ + size_t len; /* The number of bytes in the tag. */ /* Find the next node. */ n = mdoc->last; @@ -1106,30 +1117,26 @@ post_tg(POST_ARGS) } } - /* Add the default argument, if needed. */ - nch = n->child; - if (nch == NULL && nn != NULL && nn->child->type == ROFFT_TEXT) { - mdoc->next = ROFF_NEXT_CHILD; - roff_word_alloc(mdoc, n->line, n->pos, n->next->child->string); - nch = mdoc->last; - nch->flags |= NODE_NOSRC; - mdoc->last = n; - } + /* Find the tag. */ + nt = nch = n->child; + if (nch == NULL && nn != NULL && nn->child != NULL && + nn->child->type == ROFFT_TEXT) + nt = nn->child; - /* Validate the first argument. */ - if (nch == NULL || *nch->string == '\0') + /* Validate the tag. */ + if (nt == NULL || *nt->string == '\0') mandoc_msg(MANDOCERR_MACRO_EMPTY, n->line, n->pos, "Tg"); - if (nch == NULL) { + if (nt == NULL) { roff_node_delete(mdoc, n); return; } - len = strcspn(nch->string, " \t"); - if (nch->string[len] != '\0') - mandoc_msg(MANDOCERR_TG_SPC, nch->line, nch->pos + len + 1, - "Tg %s", nch->string); + len = strcspn(nt->string, " \t\\"); + if (nt->string[len] != '\0') + mandoc_msg(MANDOCERR_TG_SPC, nt->line, + nt->pos + len, "Tg %s", nt->string); /* Keep only the first argument. */ - if (nch->next != NULL) { + if (nch != NULL && nch->next != NULL) { mandoc_msg(MANDOCERR_ARG_EXCESS, nch->next->line, nch->next->pos, "Tg ... %s", nch->next->string); while (nch->next != NULL) @@ -1137,32 +1144,44 @@ post_tg(POST_ARGS) } /* Drop the macro if the first argument is invalid. */ - if (len == 0 || nch->string[len] != '\0') { + if (len == 0 || nt->string[len] != '\0') { roff_node_delete(mdoc, n); return; } - /* By default, write a <mark> element. */ - n->flags |= NODE_ID; + /* By default, tag the .Tg node itself. */ if (nn == NULL) - return; + nn = n; /* Explicit tagging of specific macros. */ switch (nn->tok) { case MDOC_Sh: case MDOC_Ss: - if (nn->head->flags & NODE_ID || nn->head->child == NULL) + case MDOC_Fo: + nn = nn->head; + /* FALLTHROUGH */ + case MDOC_Cm: + case MDOC_Dv: + case MDOC_Em: + case MDOC_Er: + case MDOC_Ev: + case MDOC_Fl: + case MDOC_Fn: + case MDOC_Ic: + case MDOC_Li: + case MDOC_Ms: + case MDOC_No: + case MDOC_Sy: + if (nn->child != NULL && (nn->flags & NODE_ID) == 0) break; - n->flags |= NODE_NOPRT; - nn->head->flags |= NODE_ID | NODE_HREF; - assert(nn->head->string == NULL); - nn->head->string = mandoc_strdup(nch->string); - break; + /* FALLTHROUGH */ default: + nn = n; break; } - if (n->flags & NODE_NOPRT) - n->flags &= ~NODE_ID; + tag_put(nt->string, TAG_MANUAL, nn); + if (nn != n) + n->flags |= NODE_NOPRT; } static void @@ -1257,28 +1276,32 @@ post_bf(POST_ARGS) static void post_fname(POST_ARGS) { - const struct roff_node *n; + struct roff_node *n, *nch; const char *cp; size_t pos; - n = mdoc->last->child; - cp = n->string; + n = mdoc->last; + nch = n->child; + cp = nch->string; if (*cp == '(') { if (cp[strlen(cp + 1)] == ')') return; pos = 0; } else { pos = strcspn(cp, "()"); - if (cp[pos] == '\0') + if (cp[pos] == '\0') { + if (n->sec == SEC_DESCRIPTION || + n->sec == SEC_CUSTOM) + tag_put(NULL, fn_prio++, n); return; + } } - mandoc_msg(MANDOCERR_FN_PAREN, n->line, n->pos + pos, "%s", cp); + mandoc_msg(MANDOCERR_FN_PAREN, nch->line, nch->pos + pos, "%s", cp); } static void post_fn(POST_ARGS) { - post_fname(mdoc); post_fa(mdoc); } @@ -1442,38 +1465,29 @@ post_display(POST_ARGS) static void post_defaults(POST_ARGS) { - struct roff_node *nn; + struct roff_node *n; - if (mdoc->last->child != NULL) { + n = mdoc->last; + if (n->child != NULL) { post_delim_nb(mdoc); return; } - - /* - * The `Ar' defaults to "file ..." if no value is provided as an - * argument; the `Mt' and `Pa' macros use "~"; the `Li' just - * gets an empty string. - */ - - nn = mdoc->last; - switch (nn->tok) { + mdoc->next = ROFF_NEXT_CHILD; + switch (n->tok) { case MDOC_Ar: - mdoc->next = ROFF_NEXT_CHILD; - roff_word_alloc(mdoc, nn->line, nn->pos, "file"); - mdoc->last->flags |= NODE_NOSRC; - roff_word_alloc(mdoc, nn->line, nn->pos, "..."); + roff_word_alloc(mdoc, n->line, n->pos, "file"); mdoc->last->flags |= NODE_NOSRC; + roff_word_alloc(mdoc, n->line, n->pos, "..."); break; case MDOC_Pa: case MDOC_Mt: - mdoc->next = ROFF_NEXT_CHILD; - roff_word_alloc(mdoc, nn->line, nn->pos, "~"); - mdoc->last->flags |= NODE_NOSRC; + roff_word_alloc(mdoc, n->line, n->pos, "~"); break; default: abort(); } - mdoc->last = nn; + mdoc->last->flags |= NODE_NOSRC; + mdoc->last = n; } static void @@ -1527,18 +1541,54 @@ post_an(POST_ARGS) } static void -post_en(POST_ARGS) +post_em(POST_ARGS) { + post_tag(mdoc); + tag_put(NULL, TAG_FALLBACK, mdoc->last); +} +static void +post_en(POST_ARGS) +{ post_obsolete(mdoc); if (mdoc->last->type == ROFFT_BLOCK) mdoc->last->norm->Es = mdoc->last_es; } static void -post_es(POST_ARGS) +post_er(POST_ARGS) +{ + struct roff_node *n; + + n = mdoc->last; + if (n->sec == SEC_ERRORS && + (n->parent->tok == MDOC_It || + (n->parent->tok == MDOC_Bq && + n->parent->parent->parent->tok == MDOC_It))) + tag_put(NULL, TAG_STRONG, n); + post_delim_nb(mdoc); +} + +static void +post_tag(POST_ARGS) { + struct roff_node *n; + + n = mdoc->last; + if ((n->prev == NULL || + (n->prev->type == ROFFT_TEXT && + strcmp(n->prev->string, "|") == 0)) && + (n->parent->tok == MDOC_It || + (n->parent->tok == MDOC_Xo && + n->parent->parent->prev == NULL && + n->parent->parent->parent->tok == MDOC_It))) + tag_put(NULL, TAG_STRONG, n); + post_delim_nb(mdoc); +} +static void +post_es(POST_ARGS) +{ post_obsolete(mdoc); mdoc->last_es = mdoc->last; } @@ -1635,8 +1685,8 @@ post_it(POST_ARGS) if ((nch = nit->head->child) != NULL) mandoc_msg(MANDOCERR_ARG_SKIP, nit->line, nit->pos, "It %s", - nch->string == NULL ? roff_name[nch->tok] : - nch->string); + nch->type == ROFFT_TEXT ? nch->string : + roff_name[nch->tok]); break; case LIST_column: cols = (int)nbl->norm->Bl.ncols; @@ -2152,7 +2202,6 @@ post_sx(POST_ARGS) static void post_sh(POST_ARGS) { - post_ignpar(mdoc); switch (mdoc->last->type) { @@ -2384,6 +2433,8 @@ post_sh_head(POST_ARGS) roff_setreg(mdoc->roff, "nS", 0, '='); mdoc->flags &= ~MDOC_SYNOPSIS; } + if (sec == SEC_DESCRIPTION) + fn_prio = TAG_STRONG; /* Mark our last section. */ @@ -2555,6 +2606,7 @@ post_par(POST_ARGS) { struct roff_node *np; + fn_prio = TAG_STRONG; post_prevpar(mdoc); np = mdoc->last; @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2019 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -15,6 +15,12 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Top-level functions of the mandoc(3) parser: + * Parser and input encoding selection, decompression, + * handling of input bytes, characters, lines, and files, + * handling of roff(7) loops and file inclusion, + * and steering of the various parsers. */ #include "config.h" @@ -36,6 +42,7 @@ #include "mandoc_aux.h" #include "mandoc.h" #include "roff.h" +#include "tag.h" #include "mdoc.h" #include "man.h" #include "mandoc_parse.h" @@ -664,6 +671,7 @@ mparse_alloc(int options, enum mandoc_os os_e, const char *os_s) } curp->man->meta.first->tok = TOKEN_NONE; curp->man->meta.os_e = os_e; + tag_alloc(); return curp; } @@ -680,6 +688,7 @@ mparse_reset(struct mparse *curp) void mparse_free(struct mparse *curp) { + tag_free(); roffhash_free(curp->man->mdocmac); roffhash_free(curp->man->manmac); roff_man_free(curp->man); diff --git a/regress/copyless b/regress/copyless new file mode 100755 index 00000000..a00c0009 --- /dev/null +++ b/regress/copyless @@ -0,0 +1,14 @@ +#!/bin/sh +set -e +umask 022 +if [ "$#" -ne 4 ]; then + echo "$0 $*: $# args instead of 4" 1>&2 + exit 1 +fi +if [ "$2" != "-T" ]; then + echo "$0 $*: second arg is not -T" 1>&2 + exit 1 +fi +cut -d ' ' -f 1,3 "$3" > "$1.mandoc_tag" +cp "$4" "$1.mandoc_ascii" +exit 0 diff --git a/regress/man/IP/Makefile b/regress/man/IP/Makefile index 70094e5f..8d607c62 100644 --- a/regress/man/IP/Makefile +++ b/regress/man/IP/Makefile @@ -1,8 +1,9 @@ -# $OpenBSD: Makefile,v 1.10 2020/02/27 01:25:58 schwarze Exp $ +# $OpenBSD: Makefile,v 1.11 2020/03/13 00:31:05 schwarze Exp $ -REGRESS_TARGETS = bullet empty literal longhead manyargs spacing vert width +REGRESS_TARGETS = bullet empty literal longhead manyargs spacing tag vert width +TAG_TARGETS = empty tag UTF8_TARGETS = bullet LINT_TARGETS = empty -HTML_TARGETS = bullet literal +HTML_TARGETS = bullet empty literal tag .include <bsd.regress.mk> diff --git a/regress/man/IP/empty.in b/regress/man/IP/empty.in index 21c42983..bb814870 100644 --- a/regress/man/IP/empty.in +++ b/regress/man/IP/empty.in @@ -1,8 +1,9 @@ -.\" $OpenBSD: empty.in,v 1.2 2017/07/04 14:53:23 schwarze Exp $ +.\" $OpenBSD: empty.in,v 1.3 2020/03/13 00:31:05 schwarze Exp $ .TH IP-EMPTY 1 "July 17, 2012" .SH NAME IP-empty \- empty indented paragraphs .SH DESCRIPTION +BEGINTEST regular text .IP @@ -25,3 +26,4 @@ text .RE regular text +ENDTEST diff --git a/regress/man/IP/empty.out_ascii b/regress/man/IP/empty.out_ascii index 24ab17fa..b17190ab 100644 --- a/regress/man/IP/empty.out_ascii +++ b/regress/man/IP/empty.out_ascii @@ -6,7 +6,7 @@ NNAAMMEE IP-empty - empty indented paragraphs DDEESSCCRRIIPPTTIIOONN - regular text + BEGINTEST regular text indented text @@ -19,7 +19,7 @@ DDEESSCCRRIIPPTTIIOONN Empty IP is deleted, RS does not cause additional spacing: tag indented text - regular text + regular text ENDTEST diff --git a/regress/man/IP/empty.out_html b/regress/man/IP/empty.out_html new file mode 100644 index 00000000..f2498dba --- /dev/null +++ b/regress/man/IP/empty.out_html @@ -0,0 +1,18 @@ +<dl class="Bl-tag"> + <dt></dt> + <dd>indented text</dd> +</dl> +<p class="Pp">Empty IP is deleted:</p> +<dl class="Bl-tag"> + <dt id="tag1"><a class="permalink" href="#tag1">tag1</a></dt> + <dd></dd> + <dt id="tag2"><a class="permalink" href="#tag2">tag2</a></dt> + <dd>indented text</dd> +</dl> +<p class="Pp">Empty IP is deleted, RS does not cause additional spacing:</p> +<div class="Bd-indent"> +<dl class="Bl-tag"> + <dt id="tag"><a class="permalink" href="#tag">tag</a></dt> + <dd>indented text</dd> +</dl> +</div> diff --git a/regress/man/IP/empty.out_lint b/regress/man/IP/empty.out_lint index 6c666c88..3514b94f 100644 --- a/regress/man/IP/empty.out_lint +++ b/regress/man/IP/empty.out_lint @@ -1,2 +1,2 @@ -mandoc: empty.in:13:2: WARNING: skipping paragraph macro: IP empty -mandoc: empty.in:20:2: WARNING: skipping paragraph macro: IP empty +mandoc: empty.in:14:2: WARNING: skipping paragraph macro: IP empty +mandoc: empty.in:21:2: WARNING: skipping paragraph macro: IP empty diff --git a/regress/man/IP/empty.out_tag b/regress/man/IP/empty.out_tag new file mode 100644 index 00000000..f35f1120 --- /dev/null +++ b/regress/man/IP/empty.out_tag @@ -0,0 +1,3 @@ +tag1 15 +tag2 17 +tag 21 diff --git a/regress/man/IP/literal.out_html b/regress/man/IP/literal.out_html index b61fc843..3b9cc429 100644 --- a/regress/man/IP/literal.out_html +++ b/regress/man/IP/literal.out_html @@ -1,5 +1,5 @@ <dl class="Bl-tag"> - <dt>tag</dt> + <dt id="tag"><a class="permalink" href="#tag">tag</a></dt> <dd>indented regular text</dd> </dl> <p class="Pp">new regular paragraph</p> @@ -8,7 +8,7 @@ literal text </pre> <dl class="Bl-tag"> - <dt>tag</dt> + <dt id="tag_2"><a class="permalink" href="#tag_2">tag</a></dt> <dd> <pre> indented @@ -32,7 +32,7 @@ literal text </pre> <dl class="Bl-tag"> - <dt>tag</dt> + <dt id="tag_3"><a class="permalink" href="#tag_3">tag</a></dt> <dd> <pre> indented @@ -48,7 +48,7 @@ text out of indented paragraph</a></h2> <p class="Pp">regular text</p> <dl class="Bl-tag"> - <dt>tag</dt> + <dt id="tag_4"><a class="permalink" href="#tag_4">tag</a></dt> <dd>indented regular text <pre> indented diff --git a/regress/man/IP/tag.in b/regress/man/IP/tag.in new file mode 100644 index 00000000..038fa969 --- /dev/null +++ b/regress/man/IP/tag.in @@ -0,0 +1,18 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:05 schwarze Exp $ +.TH IP-TAG 1 "March 10, 2020" +.SH NAME +IP-tag \- automatic tagging of indented blocks +.SH DESCRIPTION +BEGINTEST +initial +text +.IP " strong" 10n +text +.IP "-strong" +text +.IP "\&\fI \-weak\fP" +text +.IP " strong" +text +.PP +ENDTEST diff --git a/regress/man/IP/tag.out_ascii b/regress/man/IP/tag.out_ascii new file mode 100644 index 00000000..afd4f587 --- /dev/null +++ b/regress/man/IP/tag.out_ascii @@ -0,0 +1,23 @@ +IP-TAG(1) General Commands Manual IP-TAG(1) + + + +NNAAMMEE + IP-tag - automatic tagging of indented blocks + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST initial text + + strong text + + -strong text + + _-_w_e_a_k text + + strong text + + ENDTEST + + + +OpenBSD March 10, 2020 IP-TAG(1) diff --git a/regress/man/IP/tag.out_html b/regress/man/IP/tag.out_html new file mode 100644 index 00000000..4d25b12b --- /dev/null +++ b/regress/man/IP/tag.out_html @@ -0,0 +1,10 @@ +<dl class="Bl-tag"> + <dt> strong</dt> + <dd>text</dd> + <dt id="strong"><a class="permalink" href="#strong">-strong</a></dt> + <dd>text</dd> + <dt id="weak"><a class="permalink" href="#weak"><i> -weak</i></a></dt> + <dd>text</dd> + <dt> strong</dt> + <dd>text</dd> +</dl> diff --git a/regress/man/IP/tag.out_tag b/regress/man/IP/tag.out_tag new file mode 100644 index 00000000..5be038db --- /dev/null +++ b/regress/man/IP/tag.out_tag @@ -0,0 +1,2 @@ +strong 13 +weak 15 diff --git a/regress/man/TP/Makefile b/regress/man/TP/Makefile index ca2475b0..9dd2fde7 100644 --- a/regress/man/TP/Makefile +++ b/regress/man/TP/Makefile @@ -1,9 +1,10 @@ -# $OpenBSD: Makefile,v 1.16 2020/02/27 01:25:58 schwarze Exp $ +# $OpenBSD: Makefile,v 1.17 2020/03/13 00:31:05 schwarze Exp $ REGRESS_TARGETS = badarg broken double eof fill indent literal longhead -REGRESS_TARGETS += macrotag manyargs sameline spacing vert width +REGRESS_TARGETS += macrotag manyargs sameline spacing tag vert width +TAG_TARGETS = tag LINT_TARGETS = broken double eof -HTML_TARGETS = literal vert +HTML_TARGETS = literal tag vert # groff-1.22.3 defects: # - If .TP precedes .RE, the latter does not properly reset indentation. diff --git a/regress/man/TP/literal.out_html b/regress/man/TP/literal.out_html index 7f5b1c1f..8b818ed8 100644 --- a/regress/man/TP/literal.out_html +++ b/regress/man/TP/literal.out_html @@ -1,5 +1,5 @@ <dl class="Bl-tag"> - <dt>tag</dt> + <dt id="tag"><a class="permalink" href="#tag">tag</a></dt> <dd>regular indented text</dd> </dl> <p class="Pp">regular paragraph</p> @@ -8,7 +8,7 @@ literal text </pre> <dl class="Bl-tag"> - <dt>tag</dt> + <dt id="tag_2"><a class="permalink" href="#tag_2">tag</a></dt> <dd> <pre> indented diff --git a/regress/man/TP/tag.in b/regress/man/TP/tag.in new file mode 100644 index 00000000..34d1e151 --- /dev/null +++ b/regress/man/TP/tag.in @@ -0,0 +1,31 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:05 schwarze Exp $ +.TH IP-TAG 1 "March 10, 2020" +.SH NAME +IP-tag \- automatic tagging of indented blocks +.SH DESCRIPTION +BEGINTEST +initial +text +.TP 10n +.I " plain" +text +.TP +plain +text +.TP +.I "plain " +text +.TP +\& strong +text +.TP +.B -strong +text +.TP +\&\fI \-weak\fP +text +.TP +.B "strong " +text +.PP +ENDTEST diff --git a/regress/man/TP/tag.out_ascii b/regress/man/TP/tag.out_ascii new file mode 100644 index 00000000..4da2efa0 --- /dev/null +++ b/regress/man/TP/tag.out_ascii @@ -0,0 +1,29 @@ +IP-TAG(1) General Commands Manual IP-TAG(1) + + + +NNAAMMEE + IP-tag - automatic tagging of indented blocks + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST initial text + + _p_l_a_i_n text + + plain text + + _p_l_a_i_n text + + strong text + + --ssttrroonngg text + + _-_w_e_a_k text + + ssttrroonngg text + + ENDTEST + + + +OpenBSD March 10, 2020 IP-TAG(1) diff --git a/regress/man/TP/tag.out_html b/regress/man/TP/tag.out_html new file mode 100644 index 00000000..3fbbe41d --- /dev/null +++ b/regress/man/TP/tag.out_html @@ -0,0 +1,16 @@ +<dl class="Bl-tag"> + <dt><i> plain</i></dt> + <dd>text</dd> + <dt id="plain"><a class="permalink" href="#plain">plain</a></dt> + <dd>text</dd> + <dt><i>plain </i></dt> + <dd>text</dd> + <dt> strong</dt> + <dd>text</dd> + <dt id="strong"><a class="permalink" href="#strong"><b>-strong</b></a></dt> + <dd>text</dd> + <dt id="weak"><a class="permalink" href="#weak"><i> -weak</i></a></dt> + <dd>text</dd> + <dt><b>strong </b></dt> + <dd>text</dd> +</dl> diff --git a/regress/man/TP/tag.out_tag b/regress/man/TP/tag.out_tag new file mode 100644 index 00000000..88f6cff8 --- /dev/null +++ b/regress/man/TP/tag.out_tag @@ -0,0 +1,3 @@ +plain 13 +strong 19 +weak 21 diff --git a/regress/man/TP/vert.out_html b/regress/man/TP/vert.out_html index 7301819f..1124ed33 100644 --- a/regress/man/TP/vert.out_html +++ b/regress/man/TP/vert.out_html @@ -2,8 +2,8 @@ <section class="Sh"> <h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1> <dl class="Bl-tag"> - <dt>tag</dt> + <dt id="tag"><a class="permalink" href="#tag">tag</a></dt> <dd>text</dd> - <dt>tag</dt> + <dt id="tag_2"><a class="permalink" href="#tag_2">tag</a></dt> <dd>text</dd> </dl> diff --git a/regress/mdoc/Cm/Makefile b/regress/mdoc/Cm/Makefile index 4b7066ec..7bc3fc20 100644 --- a/regress/mdoc/Cm/Makefile +++ b/regress/mdoc/Cm/Makefile @@ -1,6 +1,8 @@ -# $OpenBSD: Makefile,v 1.3 2014/07/02 20:18:42 schwarze Exp $ +# $OpenBSD: Makefile,v 1.7 2020/03/13 00:31:05 schwarze Exp $ -REGRESS_TARGETS = basic font noarg punct +REGRESS_TARGETS = basic font noarg punct tag +TAG_TARGETS = tag LINT_TARGETS = noarg +HTML_TARGETS = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/Cm/tag.in b/regress/mdoc/Cm/tag.in new file mode 100644 index 00000000..2fe7d1e3 --- /dev/null +++ b/regress/mdoc/Cm/tag.in @@ -0,0 +1,21 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:05 schwarze Exp $ +.Dd $Mdocdate$ +.Dt CM-TAG 1 +.Os +.Sh NAME +.Nm Cm-tag +.Nd tagging of command modifier macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It Cm one | two +text +.It Xo +.Cm three +.Xc +text +.El +.Tg +.Cm four +.Pp +ENDTEST diff --git a/regress/mdoc/Cm/tag.out_ascii b/regress/mdoc/Cm/tag.out_ascii new file mode 100644 index 00000000..071408c7 --- /dev/null +++ b/regress/mdoc/Cm/tag.out_ascii @@ -0,0 +1,17 @@ +CM-TAG(1) General Commands Manual CM-TAG(1) + +NNAAMMEE + CCmm--ttaagg - tagging of command modifier macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + oonnee | ttwwoo + text + + tthhrreeee text + ffoouurr + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Cm/tag.out_html b/regress/mdoc/Cm/tag.out_html new file mode 100644 index 00000000..a140fe3e --- /dev/null +++ b/regress/mdoc/Cm/tag.out_html @@ -0,0 +1,9 @@ +<dl class="Bl-tag"> + <dt><a class="permalink" href="#one"><code class="Cm" id="one">one</code></a> + | + <a class="permalink" href="#two"><code class="Cm" id="two">two</code></a></dt> + <dd>text</dd> + <dt><a class="permalink" href="#three"><code class="Cm" id="three">three</code></a></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#four"><code class="Cm" id="four">four</code></a> diff --git a/regress/mdoc/Cm/tag.out_markdown b/regress/mdoc/Cm/tag.out_markdown new file mode 100644 index 00000000..893a8fe5 --- /dev/null +++ b/regress/mdoc/Cm/tag.out_markdown @@ -0,0 +1,23 @@ +CM-TAG(1) - General Commands Manual + +# NAME + +**Cm-tag** - tagging of command modifier macros + +# DESCRIPTION + +BEGINTEST + +**one** | **two** + +> text + +**three** + +> text + +**four** + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Cm/tag.out_tag b/regress/mdoc/Cm/tag.out_tag new file mode 100644 index 00000000..94f0cfb2 --- /dev/null +++ b/regress/mdoc/Cm/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 diff --git a/regress/mdoc/Dv/Makefile b/regress/mdoc/Dv/Makefile index cfe3ad0b..979e1826 100644 --- a/regress/mdoc/Dv/Makefile +++ b/regress/mdoc/Dv/Makefile @@ -1,6 +1,8 @@ -# $OpenBSD: Makefile,v 1.2 2014/07/02 20:18:42 schwarze Exp $ +# $OpenBSD: Makefile,v 1.5 2020/03/13 00:31:05 schwarze Exp $ -REGRESS_TARGETS = font noarg +REGRESS_TARGETS = font noarg tag +TAG_TARGETS = tag LINT_TARGETS = noarg +HTML_TARGETS = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/Dv/tag.in b/regress/mdoc/Dv/tag.in new file mode 100644 index 00000000..60d2716b --- /dev/null +++ b/regress/mdoc/Dv/tag.in @@ -0,0 +1,21 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:05 schwarze Exp $ +.Dd $Mdocdate$ +.Dt DV-TAG 1 +.Os +.Sh NAME +.Nm Dv-tag +.Nd tagging of defined variable macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It Dv one | two +text +.It Xo +.Dv three +.Xc +text +.El +.Tg +.Dv four +.Pp +ENDTEST diff --git a/regress/mdoc/Dv/tag.out_ascii b/regress/mdoc/Dv/tag.out_ascii new file mode 100644 index 00000000..119e3509 --- /dev/null +++ b/regress/mdoc/Dv/tag.out_ascii @@ -0,0 +1,17 @@ +DV-TAG(1) General Commands Manual DV-TAG(1) + +NNAAMMEE + DDvv--ttaagg - tagging of defined variable macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + one | two + text + + three text + four + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Dv/tag.out_html b/regress/mdoc/Dv/tag.out_html new file mode 100644 index 00000000..cee78340 --- /dev/null +++ b/regress/mdoc/Dv/tag.out_html @@ -0,0 +1,9 @@ +<dl class="Bl-tag"> + <dt><a class="permalink" href="#one"><code class="Dv" id="one">one</code></a> + | + <a class="permalink" href="#two"><code class="Dv" id="two">two</code></a></dt> + <dd>text</dd> + <dt><a class="permalink" href="#three"><code class="Dv" id="three">three</code></a></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#four"><code class="Dv" id="four">four</code></a> diff --git a/regress/mdoc/Dv/tag.out_markdown b/regress/mdoc/Dv/tag.out_markdown new file mode 100644 index 00000000..29b454bb --- /dev/null +++ b/regress/mdoc/Dv/tag.out_markdown @@ -0,0 +1,23 @@ +DV-TAG(1) - General Commands Manual + +# NAME + +**Dv-tag** - tagging of defined variable macros + +# DESCRIPTION + +BEGINTEST + +`one` | `two` + +> text + +`three` + +> text + +`four` + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Dv/tag.out_tag b/regress/mdoc/Dv/tag.out_tag new file mode 100644 index 00000000..94f0cfb2 --- /dev/null +++ b/regress/mdoc/Dv/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 diff --git a/regress/mdoc/Em/Makefile b/regress/mdoc/Em/Makefile index 13de4337..2b500444 100644 --- a/regress/mdoc/Em/Makefile +++ b/regress/mdoc/Em/Makefile @@ -1,6 +1,8 @@ -# $OpenBSD: Makefile,v 1.3 2014/11/17 06:44:35 schwarze Exp $ +# $OpenBSD: Makefile,v 1.6 2020/03/13 00:31:05 schwarze Exp $ -REGRESS_TARGETS = font noarg punct +REGRESS_TARGETS = font noarg punct tag +TAG_TARGETS = tag LINT_TARGETS = noarg punct +HTML_TARGETS = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/Em/tag.in b/regress/mdoc/Em/tag.in new file mode 100644 index 00000000..9d309835 --- /dev/null +++ b/regress/mdoc/Em/tag.in @@ -0,0 +1,23 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:05 schwarze Exp $ +.Dd $Mdocdate$ +.Dt EM-TAG 1 +.Os +.Sh NAME +.Nm Em-tag +.Nd tagging of emphasis macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It Em one | two +text +.It Xo +.Em three +.Xc +text +.El +.Em four +.Em one +.Tg explicit +.Em five +.Pp +ENDTEST diff --git a/regress/mdoc/Em/tag.out_ascii b/regress/mdoc/Em/tag.out_ascii new file mode 100644 index 00000000..74f8212b --- /dev/null +++ b/regress/mdoc/Em/tag.out_ascii @@ -0,0 +1,17 @@ +EM-TAG(1) General Commands Manual EM-TAG(1) + +NNAAMMEE + EEmm--ttaagg - tagging of emphasis macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + _o_n_e | _t_w_o + text + + _t_h_r_e_e text + _f_o_u_r _o_n_e _f_i_v_e + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Em/tag.out_html b/regress/mdoc/Em/tag.out_html new file mode 100644 index 00000000..4046673f --- /dev/null +++ b/regress/mdoc/Em/tag.out_html @@ -0,0 +1,10 @@ +<dl class="Bl-tag"> + <dt><a class="permalink" href="#one"><i class="Em" id="one">one</i></a> | + <a class="permalink" href="#two"><i class="Em" id="two">two</i></a></dt> + <dd>text</dd> + <dt><a class="permalink" href="#three"><i class="Em" id="three">three</i></a></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#four"><i class="Em" id="four">four</i></a> + <i class="Em">one</i> + <a class="permalink" href="#explicit"><i class="Em" id="explicit">five</i></a> diff --git a/regress/mdoc/Em/tag.out_markdown b/regress/mdoc/Em/tag.out_markdown new file mode 100644 index 00000000..4c107159 --- /dev/null +++ b/regress/mdoc/Em/tag.out_markdown @@ -0,0 +1,25 @@ +EM-TAG(1) - General Commands Manual + +# NAME + +**Em-tag** - tagging of emphasis macros + +# DESCRIPTION + +BEGINTEST + +*one* | *two* + +> text + +*three* + +> text + +*four* +*one* +*five* + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Em/tag.out_tag b/regress/mdoc/Em/tag.out_tag new file mode 100644 index 00000000..c2fbaf59 --- /dev/null +++ b/regress/mdoc/Em/tag.out_tag @@ -0,0 +1,5 @@ +one 9 +two 9 +three 12 +four 13 +explicit 13 diff --git a/regress/mdoc/Er/Makefile b/regress/mdoc/Er/Makefile index 1be2a84a..55f6cc76 100644 --- a/regress/mdoc/Er/Makefile +++ b/regress/mdoc/Er/Makefile @@ -1,6 +1,8 @@ -# $OpenBSD: Makefile,v 1.4 2014/07/02 20:18:42 schwarze Exp $ +# $OpenBSD: Makefile,v 1.7 2020/03/13 00:31:05 schwarze Exp $ -REGRESS_TARGETS = noarg font +REGRESS_TARGETS = noarg font tag +TAG_TARGETS = tag LINT_TARGETS = noarg +HTML_TARGETS = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/Er/tag.in b/regress/mdoc/Er/tag.in new file mode 100644 index 00000000..bad7a88b --- /dev/null +++ b/regress/mdoc/Er/tag.in @@ -0,0 +1,21 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:05 schwarze Exp $ +.Dd $Mdocdate$ +.Dt ER-TAG 1 +.Os +.Sh NAME +.Nm Er-tag +.Nd tagging of error number macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It Er one +text +.El +.Tg +.Er two +.Sh ERRORS +.Bl -tag -width Er +.It Bq Er ENOENT +text +.El +ENDTEST diff --git a/regress/mdoc/Er/tag.out_ascii b/regress/mdoc/Er/tag.out_ascii new file mode 100644 index 00000000..62dbf9ca --- /dev/null +++ b/regress/mdoc/Er/tag.out_ascii @@ -0,0 +1,16 @@ +ER-TAG(1) General Commands Manual ER-TAG(1) + +NNAAMMEE + EErr--ttaagg - tagging of error number macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + one text + two + +EERRRROORRSS + [ENOENT] text + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Er/tag.out_html b/regress/mdoc/Er/tag.out_html new file mode 100644 index 00000000..a2c2978f --- /dev/null +++ b/regress/mdoc/Er/tag.out_html @@ -0,0 +1,12 @@ +<dl class="Bl-tag"> + <dt><code class="Er">one</code></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#two"><code class="Er" id="two">two</code></a> +</section> +<section class="Sh"> +<h1 class="Sh" id="ERRORS"><a class="permalink" href="#ERRORS">ERRORS</a></h1> +<dl class="Bl-tag"> + <dt>[<a class="permalink" href="#ENOENT"><code class="Er" id="ENOENT">ENOENT</code></a>]</dt> + <dd>text</dd> +</dl> diff --git a/regress/mdoc/Er/tag.out_markdown b/regress/mdoc/Er/tag.out_markdown new file mode 100644 index 00000000..d11eb4b9 --- /dev/null +++ b/regress/mdoc/Er/tag.out_markdown @@ -0,0 +1,25 @@ +ER-TAG(1) - General Commands Manual + +# NAME + +**Er-tag** - tagging of error number macros + +# DESCRIPTION + +BEGINTEST + +`one` + +> text + +`two` + +# ERRORS + +\[`ENOENT`] + +> text + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Er/tag.out_tag b/regress/mdoc/Er/tag.out_tag new file mode 100644 index 00000000..b00a6718 --- /dev/null +++ b/regress/mdoc/Er/tag.out_tag @@ -0,0 +1,2 @@ +two 10 +ENOENT 13 diff --git a/regress/mdoc/Ev/Makefile b/regress/mdoc/Ev/Makefile index cfe3ad0b..979e1826 100644 --- a/regress/mdoc/Ev/Makefile +++ b/regress/mdoc/Ev/Makefile @@ -1,6 +1,8 @@ -# $OpenBSD: Makefile,v 1.2 2014/07/02 20:18:42 schwarze Exp $ +# $OpenBSD: Makefile,v 1.5 2020/03/13 00:31:05 schwarze Exp $ -REGRESS_TARGETS = font noarg +REGRESS_TARGETS = font noarg tag +TAG_TARGETS = tag LINT_TARGETS = noarg +HTML_TARGETS = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/Ev/tag.in b/regress/mdoc/Ev/tag.in new file mode 100644 index 00000000..014b0fbc --- /dev/null +++ b/regress/mdoc/Ev/tag.in @@ -0,0 +1,21 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:05 schwarze Exp $ +.Dd $Mdocdate$ +.Dt EV-TAG 1 +.Os +.Sh NAME +.Nm Ev-tag +.Nd tagging of environment variable macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It Ev one | two +text +.It Xo +.Ev three +.Xc +text +.El +.Tg +.Ev four +.Pp +ENDTEST diff --git a/regress/mdoc/Ev/tag.out_ascii b/regress/mdoc/Ev/tag.out_ascii new file mode 100644 index 00000000..5569d1c8 --- /dev/null +++ b/regress/mdoc/Ev/tag.out_ascii @@ -0,0 +1,17 @@ +EV-TAG(1) General Commands Manual EV-TAG(1) + +NNAAMMEE + EEvv--ttaagg - tagging of environment variable macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + one | two + text + + three text + four + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Ev/tag.out_html b/regress/mdoc/Ev/tag.out_html new file mode 100644 index 00000000..1e1c92b9 --- /dev/null +++ b/regress/mdoc/Ev/tag.out_html @@ -0,0 +1,9 @@ +<dl class="Bl-tag"> + <dt><a class="permalink" href="#one"><code class="Ev" id="one">one</code></a> + | + <a class="permalink" href="#two"><code class="Ev" id="two">two</code></a></dt> + <dd>text</dd> + <dt><a class="permalink" href="#three"><code class="Ev" id="three">three</code></a></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#four"><code class="Ev" id="four">four</code></a> diff --git a/regress/mdoc/Ev/tag.out_markdown b/regress/mdoc/Ev/tag.out_markdown new file mode 100644 index 00000000..f9a6712b --- /dev/null +++ b/regress/mdoc/Ev/tag.out_markdown @@ -0,0 +1,23 @@ +EV-TAG(1) - General Commands Manual + +# NAME + +**Ev-tag** - tagging of environment variable macros + +# DESCRIPTION + +BEGINTEST + +`one` | `two` + +> text + +`three` + +> text + +`four` + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Ev/tag.out_tag b/regress/mdoc/Ev/tag.out_tag new file mode 100644 index 00000000..94f0cfb2 --- /dev/null +++ b/regress/mdoc/Ev/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 diff --git a/regress/mdoc/Fl/Makefile b/regress/mdoc/Fl/Makefile index e4e4a6bc..c061adef 100644 --- a/regress/mdoc/Fl/Makefile +++ b/regress/mdoc/Fl/Makefile @@ -1,6 +1,9 @@ -# $OpenBSD: Makefile,v 1.13 2020/02/27 01:25:58 schwarze Exp $ +# $OpenBSD: Makefile,v 1.14 2020/03/13 00:31:06 schwarze Exp $ -REGRESS_TARGETS = font multiarg noarg parsed punct spacing +REGRESS_TARGETS = font multiarg noarg parsed punct spacing tag +TAG_TARGETS = tag LINT_TARGETS = punct +HTML_TARGETS = tag +SKIP_TMAN = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/Fl/tag.in b/regress/mdoc/Fl/tag.in new file mode 100644 index 00000000..a4d3c135 --- /dev/null +++ b/regress/mdoc/Fl/tag.in @@ -0,0 +1,21 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:06 schwarze Exp $ +.Dd $Mdocdate$ +.Dt FL-TAG 1 +.Os +.Sh NAME +.Nm Fl-tag +.Nd tagging of command line option macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It Fl a | b +text +.It Xo +.Fl c +.Xc +text +.El +.Tg +.Fl d +.Pp +ENDTEST diff --git a/regress/mdoc/Fl/tag.out_ascii b/regress/mdoc/Fl/tag.out_ascii new file mode 100644 index 00000000..4fcf803c --- /dev/null +++ b/regress/mdoc/Fl/tag.out_ascii @@ -0,0 +1,17 @@ +FL-TAG(1) General Commands Manual FL-TAG(1) + +NNAAMMEE + FFll--ttaagg - tagging of command line option macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + --aa | --bb + text + + --cc text + --dd + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Fl/tag.out_html b/regress/mdoc/Fl/tag.out_html new file mode 100644 index 00000000..f67a30c0 --- /dev/null +++ b/regress/mdoc/Fl/tag.out_html @@ -0,0 +1,8 @@ +<dl class="Bl-tag"> + <dt><a class="permalink" href="#a"><code class="Fl" id="a">-a</code></a> | + <a class="permalink" href="#b"><code class="Fl" id="b">-b</code></a></dt> + <dd>text</dd> + <dt><a class="permalink" href="#c"><code class="Fl" id="c">-c</code></a></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#d"><code class="Fl" id="d">-d</code></a> diff --git a/regress/mdoc/Fl/tag.out_markdown b/regress/mdoc/Fl/tag.out_markdown new file mode 100644 index 00000000..1e7c6f14 --- /dev/null +++ b/regress/mdoc/Fl/tag.out_markdown @@ -0,0 +1,23 @@ +FL-TAG(1) - General Commands Manual + +# NAME + +**Fl-tag** - tagging of command line option macros + +# DESCRIPTION + +BEGINTEST + +**-a** | **-b** + +> text + +**-c** + +> text + +**-d** + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Fl/tag.out_tag b/regress/mdoc/Fl/tag.out_tag new file mode 100644 index 00000000..89a94151 --- /dev/null +++ b/regress/mdoc/Fl/tag.out_tag @@ -0,0 +1,4 @@ +a 9 +b 9 +c 12 +d 13 diff --git a/regress/mdoc/Fo/Makefile b/regress/mdoc/Fo/Makefile index 7770e9a1..ce25ddf3 100644 --- a/regress/mdoc/Fo/Makefile +++ b/regress/mdoc/Fo/Makefile @@ -1,8 +1,10 @@ -# $OpenBSD: Makefile,v 1.17 2020/02/27 01:25:58 schwarze Exp $ +# $OpenBSD: Makefile,v 1.18 2020/03/13 00:31:06 schwarze Exp $ REGRESS_TARGETS = basic break eos font noarg nohead -REGRESS_TARGETS += obsolete punct section transp warn +REGRESS_TARGETS += obsolete punct section tag transp warn +TAG_TARGETS = tag LINT_TARGETS = noarg nohead obsolete punct warn +HTML_TARGETS = tag # groff-1.22.3 defects: # - .Fo without an argument prints unbalanced parentheses diff --git a/regress/mdoc/Fo/tag.in b/regress/mdoc/Fo/tag.in new file mode 100644 index 00000000..727fdaf1 --- /dev/null +++ b/regress/mdoc/Fo/tag.in @@ -0,0 +1,29 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:06 schwarze Exp $ +.Dd $Mdocdate$ +.Dt FO-TAG 1 +.Os +.Sh NAME +.Nm Fo-tag +.Nd tagging of function name macros +.Sh DESCRIPTION +BEGINTEST +.Pp +automatic: +.Fn first +and +.Fn second +.Pp +.Fn second +and +.Fn first +.Pp +explicit: +.Tg e3 +.Fn third +and +.Tg e4 +.Fo fourth +.Fa void +.Fc +.Pp +ENDTEST diff --git a/regress/mdoc/Fo/tag.out_ascii b/regress/mdoc/Fo/tag.out_ascii new file mode 100644 index 00000000..505c0b7a --- /dev/null +++ b/regress/mdoc/Fo/tag.out_ascii @@ -0,0 +1,17 @@ +FO-TAG(1) General Commands Manual FO-TAG(1) + +NNAAMMEE + FFoo--ttaagg - tagging of function name macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + automatic: ffiirrsstt() and sseeccoonndd() + + sseeccoonndd() and ffiirrsstt() + + explicit: tthhiirrdd() and ffoouurrtthh(_v_o_i_d) + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Fo/tag.out_html b/regress/mdoc/Fo/tag.out_html new file mode 100644 index 00000000..b3508614 --- /dev/null +++ b/regress/mdoc/Fo/tag.out_html @@ -0,0 +1,9 @@ +<p class="Pp">automatic: + <a class="permalink" href="#first"><code class="Fn" id="first">first</code></a>() + and <code class="Fn">second</code>()</p> +<p class="Pp"><a class="permalink" href="#second"><code class="Fn" id="second">second</code></a>() + and <code class="Fn">first</code>()</p> +<p class="Pp">explicit: + <a class="permalink" href="#e3"><code class="Fn" id="e3">third</code></a>() + and + <a class="permalink" href="#e4"><code class="Fn" id="e4">fourth</code></a>(<var class="Fa">void</var>);</p> diff --git a/regress/mdoc/Fo/tag.out_markdown b/regress/mdoc/Fo/tag.out_markdown new file mode 100644 index 00000000..273a00d4 --- /dev/null +++ b/regress/mdoc/Fo/tag.out_markdown @@ -0,0 +1,27 @@ +FO-TAG(1) - General Commands Manual + +# NAME + +**Fo-tag** - tagging of function name macros + +# DESCRIPTION + +BEGINTEST + +automatic: +**first**() +and +**second**() + +**second**() +and +**first**() + +explicit: +**third**() +and +**fourth**(*void*) + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Fo/tag.out_tag b/regress/mdoc/Fo/tag.out_tag new file mode 100644 index 00000000..2387023c --- /dev/null +++ b/regress/mdoc/Fo/tag.out_tag @@ -0,0 +1,4 @@ +first 9 +second 11 +e3 13 +e4 13 diff --git a/regress/mdoc/Ic/Makefile b/regress/mdoc/Ic/Makefile index 33faa380..4a06ee20 100644 --- a/regress/mdoc/Ic/Makefile +++ b/regress/mdoc/Ic/Makefile @@ -1,6 +1,8 @@ -# $OpenBSD: Makefile,v 1.4 2014/07/02 20:18:42 schwarze Exp $ +# $OpenBSD: Makefile,v 1.8 2020/03/13 00:31:06 schwarze Exp $ -REGRESS_TARGETS = font noarg punct +REGRESS_TARGETS = font noarg punct tag +TAG_TARGETS = tag LINT_TARGETS = noarg +HTML_TARGETS = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/Ic/tag.in b/regress/mdoc/Ic/tag.in new file mode 100644 index 00000000..fb7b441e --- /dev/null +++ b/regress/mdoc/Ic/tag.in @@ -0,0 +1,21 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:06 schwarze Exp $ +.Dd $Mdocdate$ +.Dt IC-TAG 1 +.Os +.Sh NAME +.Nm Ic-tag +.Nd tagging of internal command macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It Ic one | two +text +.It Xo +.Ic three +.Xc +text +.El +.Tg +.Ic four +.Pp +ENDTEST diff --git a/regress/mdoc/Ic/tag.out_ascii b/regress/mdoc/Ic/tag.out_ascii new file mode 100644 index 00000000..513b2638 --- /dev/null +++ b/regress/mdoc/Ic/tag.out_ascii @@ -0,0 +1,17 @@ +IC-TAG(1) General Commands Manual IC-TAG(1) + +NNAAMMEE + IIcc--ttaagg - tagging of internal command macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + oonnee | ttwwoo + text + + tthhrreeee text + ffoouurr + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Ic/tag.out_html b/regress/mdoc/Ic/tag.out_html new file mode 100644 index 00000000..ad3cc1ef --- /dev/null +++ b/regress/mdoc/Ic/tag.out_html @@ -0,0 +1,9 @@ +<dl class="Bl-tag"> + <dt><a class="permalink" href="#one"><code class="Ic" id="one">one</code></a> + | + <a class="permalink" href="#two"><code class="Ic" id="two">two</code></a></dt> + <dd>text</dd> + <dt><a class="permalink" href="#three"><code class="Ic" id="three">three</code></a></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#four"><code class="Ic" id="four">four</code></a> diff --git a/regress/mdoc/Ic/tag.out_markdown b/regress/mdoc/Ic/tag.out_markdown new file mode 100644 index 00000000..c0f13879 --- /dev/null +++ b/regress/mdoc/Ic/tag.out_markdown @@ -0,0 +1,23 @@ +IC-TAG(1) - General Commands Manual + +# NAME + +**Ic-tag** - tagging of internal command macros + +# DESCRIPTION + +BEGINTEST + +**one** | **two** + +> text + +**three** + +> text + +**four** + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Ic/tag.out_tag b/regress/mdoc/Ic/tag.out_tag new file mode 100644 index 00000000..94f0cfb2 --- /dev/null +++ b/regress/mdoc/Ic/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 diff --git a/regress/mdoc/Li/Makefile b/regress/mdoc/Li/Makefile index 7b2a3313..44dcf01c 100644 --- a/regress/mdoc/Li/Makefile +++ b/regress/mdoc/Li/Makefile @@ -1,6 +1,8 @@ -# $OpenBSD: Makefile,v 1.7 2018/12/21 16:58:49 schwarze Exp $ +# $OpenBSD: Makefile,v 1.8 2020/03/13 00:31:06 schwarze Exp $ -REGRESS_TARGETS = arg punct font +REGRESS_TARGETS = arg punct font tag +TAG_TARGETS = tag LINT_TARGETS = punct +HTML_TARGETS = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/Li/tag.in b/regress/mdoc/Li/tag.in new file mode 100644 index 00000000..add672ad --- /dev/null +++ b/regress/mdoc/Li/tag.in @@ -0,0 +1,21 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:06 schwarze Exp $ +.Dd $Mdocdate$ +.Dt LI-TAG 1 +.Os +.Sh NAME +.Nm Li-tag +.Nd tagging of literal font macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It Li one | two +text +.It Xo +.Li three +.Xc +text +.El +.Tg +.Li four +.Pp +ENDTEST diff --git a/regress/mdoc/Li/tag.out_ascii b/regress/mdoc/Li/tag.out_ascii new file mode 100644 index 00000000..e1afda6e --- /dev/null +++ b/regress/mdoc/Li/tag.out_ascii @@ -0,0 +1,17 @@ +LI-TAG(1) General Commands Manual LI-TAG(1) + +NNAAMMEE + LLii--ttaagg - tagging of literal font macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + one | two + text + + three text + four + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Li/tag.out_html b/regress/mdoc/Li/tag.out_html new file mode 100644 index 00000000..3730caa6 --- /dev/null +++ b/regress/mdoc/Li/tag.out_html @@ -0,0 +1,9 @@ +<dl class="Bl-tag"> + <dt><a class="permalink" href="#one"><code class="Li" id="one">one</code></a> + | + <a class="permalink" href="#two"><code class="Li" id="two">two</code></a></dt> + <dd>text</dd> + <dt><a class="permalink" href="#three"><code class="Li" id="three">three</code></a></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#four"><code class="Li" id="four">four</code></a> diff --git a/regress/mdoc/Li/tag.out_markdown b/regress/mdoc/Li/tag.out_markdown new file mode 100644 index 00000000..6467e16d --- /dev/null +++ b/regress/mdoc/Li/tag.out_markdown @@ -0,0 +1,23 @@ +LI-TAG(1) - General Commands Manual + +# NAME + +**Li-tag** - tagging of literal font macros + +# DESCRIPTION + +BEGINTEST + +`one` | `two` + +> text + +`three` + +> text + +`four` + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Li/tag.out_tag b/regress/mdoc/Li/tag.out_tag new file mode 100644 index 00000000..94f0cfb2 --- /dev/null +++ b/regress/mdoc/Li/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 diff --git a/regress/mdoc/Makefile b/regress/mdoc/Makefile index 86bdcb7a..83bd7fb7 100644 --- a/regress/mdoc/Makefile +++ b/regress/mdoc/Makefile @@ -1,9 +1,9 @@ -# $OpenBSD: Makefile,v 1.32 2017/01/11 17:39:45 schwarze Exp $ +# $OpenBSD: Makefile,v 1.33 2020/03/13 00:31:05 schwarze Exp $ SUBDIR = Ad An Ap Aq Ar At Bd Bf Bk Bl Brq Bx Cd Cm SUBDIR += D1 Db Dd Dl Dq Dt Dv Em Eo Er Ev Ex Fd Fl Fo Ft Ic In Lb Li Lk SUBDIR += Ms Mt Nd Nm No Ns Oo Op Os Ox Pa Pf Pp Qq Rs Rv -SUBDIR += Sh Sm Sq St Sx Sy Tn Ud Ux Va Vt Xr blank break +SUBDIR += Sh Sm Sq St Sx Sy Tg Tn Ud Ux Va Vt Xr blank break .include "../Makefile.sub" .include <bsd.subdir.mk> diff --git a/regress/mdoc/Ms/Makefile b/regress/mdoc/Ms/Makefile index 1be2a84a..618edd3f 100644 --- a/regress/mdoc/Ms/Makefile +++ b/regress/mdoc/Ms/Makefile @@ -1,6 +1,8 @@ -# $OpenBSD: Makefile,v 1.4 2014/07/02 20:18:42 schwarze Exp $ +# $OpenBSD: Makefile,v 1.8 2020/03/13 00:58:48 schwarze Exp $ -REGRESS_TARGETS = noarg font +REGRESS_TARGETS = noarg font tag +TAG_TARGETS = tag LINT_TARGETS = noarg +HTML_TARGETS = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/Ms/tag.in b/regress/mdoc/Ms/tag.in new file mode 100644 index 00000000..e3465073 --- /dev/null +++ b/regress/mdoc/Ms/tag.in @@ -0,0 +1,21 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:06 schwarze Exp $ +.Dd $Mdocdate$ +.Dt MS-TAG 1 +.Os +.Sh NAME +.Nm Ms-tag +.Nd tagging of mathematical symbol macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It Ms one | two +text +.It Xo +.Ms three +.Xc +text +.El +.Tg +.Ms four +.Pp +ENDTEST diff --git a/regress/mdoc/Ms/tag.out_ascii b/regress/mdoc/Ms/tag.out_ascii new file mode 100644 index 00000000..2d06f4bf --- /dev/null +++ b/regress/mdoc/Ms/tag.out_ascii @@ -0,0 +1,17 @@ +MS-TAG(1) General Commands Manual MS-TAG(1) + +NNAAMMEE + MMss--ttaagg - tagging of mathematical symbol macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + oonnee | ttwwoo + text + + tthhrreeee text + ffoouurr + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Ms/tag.out_html b/regress/mdoc/Ms/tag.out_html new file mode 100644 index 00000000..0f24b2ac --- /dev/null +++ b/regress/mdoc/Ms/tag.out_html @@ -0,0 +1,9 @@ +<dl class="Bl-tag"> + <dt><a class="permalink" href="#one"><span class="Ms" id="one">one</span></a> + | + <a class="permalink" href="#two"><span class="Ms" id="two">two</span></a></dt> + <dd>text</dd> + <dt><a class="permalink" href="#three"><span class="Ms" id="three">three</span></a></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#four"><span class="Ms" id="four">four</span></a> diff --git a/regress/mdoc/Ms/tag.out_markdown b/regress/mdoc/Ms/tag.out_markdown new file mode 100644 index 00000000..055c3860 --- /dev/null +++ b/regress/mdoc/Ms/tag.out_markdown @@ -0,0 +1,23 @@ +MS-TAG(1) - General Commands Manual + +# NAME + +**Ms-tag** - tagging of mathematical symbol macros + +# DESCRIPTION + +BEGINTEST + +**one** | **two** + +> text + +**three** + +> text + +**four** + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Ms/tag.out_tag b/regress/mdoc/Ms/tag.out_tag new file mode 100644 index 00000000..94f0cfb2 --- /dev/null +++ b/regress/mdoc/Ms/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 diff --git a/regress/mdoc/No/Makefile b/regress/mdoc/No/Makefile index 3110bf2b..35aa4e1e 100644 --- a/regress/mdoc/No/Makefile +++ b/regress/mdoc/No/Makefile @@ -1,6 +1,8 @@ -# $OpenBSD: Makefile,v 1.4 2014/11/17 06:44:35 schwarze Exp $ +# $OpenBSD: Makefile,v 1.7 2020/03/13 00:31:06 schwarze Exp $ -REGRESS_TARGETS = punct spacing +REGRESS_TARGETS = punct spacing tag +TAG_TARGETS = tag LINT_TARGETS = punct +HTML_TARGETS = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/No/punct.out_lint b/regress/mdoc/No/punct.out_lint index e046da6a..6a65c3b4 100644 --- a/regress/mdoc/No/punct.out_lint +++ b/regress/mdoc/No/punct.out_lint @@ -23,3 +23,4 @@ mandoc: punct.in:72:7: WARNING: skipping empty macro: No mandoc: punct.in:75:7: WARNING: skipping empty macro: No mandoc: punct.in:76:7: WARNING: skipping empty macro: No mandoc: punct.in:84:2: WARNING: skipping empty macro: No +mandoc: punct.in:87:6: STYLE: no blank before trailing delimiter: No a. diff --git a/regress/mdoc/No/tag.in b/regress/mdoc/No/tag.in new file mode 100644 index 00000000..700d79da --- /dev/null +++ b/regress/mdoc/No/tag.in @@ -0,0 +1,21 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:06 schwarze Exp $ +.Dd $Mdocdate$ +.Dt NO-TAG 1 +.Os +.Sh NAME +.Nm No-tag +.Nd tagging of normal font macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It No one | two +text +.It Xo +.No three +.Xc +text +.El +.Tg +.No four +.Pp +ENDTEST diff --git a/regress/mdoc/No/tag.out_ascii b/regress/mdoc/No/tag.out_ascii new file mode 100644 index 00000000..44481b02 --- /dev/null +++ b/regress/mdoc/No/tag.out_ascii @@ -0,0 +1,17 @@ +NO-TAG(1) General Commands Manual NO-TAG(1) + +NNAAMMEE + NNoo--ttaagg - tagging of normal font macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + one | two + text + + three text + four + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/No/tag.out_html b/regress/mdoc/No/tag.out_html new file mode 100644 index 00000000..32696917 --- /dev/null +++ b/regress/mdoc/No/tag.out_html @@ -0,0 +1,9 @@ +<dl class="Bl-tag"> + <dt><a class="permalink" href="#one"><span class="No" id="one">one</span></a> + | + <a class="permalink" href="#two"><span class="No" id="two">two</span></a></dt> + <dd>text</dd> + <dt><a class="permalink" href="#three"><span class="No" id="three">three</span></a></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#four"><span class="No" id="four">four</span></a> diff --git a/regress/mdoc/No/tag.out_markdown b/regress/mdoc/No/tag.out_markdown new file mode 100644 index 00000000..1590c010 --- /dev/null +++ b/regress/mdoc/No/tag.out_markdown @@ -0,0 +1,23 @@ +NO-TAG(1) - General Commands Manual + +# NAME + +**No-tag** - tagging of normal font macros + +# DESCRIPTION + +BEGINTEST + +one | two + +> text + +three + +> text + +four + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/No/tag.out_tag b/regress/mdoc/No/tag.out_tag new file mode 100644 index 00000000..94f0cfb2 --- /dev/null +++ b/regress/mdoc/No/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 diff --git a/regress/mdoc/Sy/Makefile b/regress/mdoc/Sy/Makefile index 36c1859b..752d1382 100644 --- a/regress/mdoc/Sy/Makefile +++ b/regress/mdoc/Sy/Makefile @@ -1,6 +1,8 @@ -# $OpenBSD: Makefile,v 1.5 2014/11/17 06:44:35 schwarze Exp $ +# $OpenBSD: Makefile,v 1.8 2020/03/13 00:31:06 schwarze Exp $ -REGRESS_TARGETS = noarg font punct +REGRESS_TARGETS = noarg font punct tag +TAG_TARGETS = tag LINT_TARGETS = noarg punct +HTML_TARGETS = tag .include <bsd.regress.mk> diff --git a/regress/mdoc/Sy/tag.in b/regress/mdoc/Sy/tag.in new file mode 100644 index 00000000..b2719093 --- /dev/null +++ b/regress/mdoc/Sy/tag.in @@ -0,0 +1,23 @@ +.\" $OpenBSD: tag.in,v 1.1 2020/03/13 00:31:06 schwarze Exp $ +.Dd $Mdocdate$ +.Dt SY-TAG 1 +.Os +.Sh NAME +.Nm Sy-tag +.Nd tagging of symbolic font macros +.Sh DESCRIPTION +BEGINTEST +.Bl -tag -width Ds +.It Sy one | two +text +.It Xo +.Sy three +.Xc +text +.El +.Sy four +.Sy one +.Tg explicit +.Sy five +.Pp +ENDTEST diff --git a/regress/mdoc/Sy/tag.out_ascii b/regress/mdoc/Sy/tag.out_ascii new file mode 100644 index 00000000..3b89cb41 --- /dev/null +++ b/regress/mdoc/Sy/tag.out_ascii @@ -0,0 +1,17 @@ +SY-TAG(1) General Commands Manual SY-TAG(1) + +NNAAMMEE + SSyy--ttaagg - tagging of symbolic font macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + oonnee | ttwwoo + text + + tthhrreeee text + ffoouurr oonnee ffiivvee + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Sy/tag.out_html b/regress/mdoc/Sy/tag.out_html new file mode 100644 index 00000000..69276a18 --- /dev/null +++ b/regress/mdoc/Sy/tag.out_html @@ -0,0 +1,10 @@ +<dl class="Bl-tag"> + <dt><a class="permalink" href="#one"><b class="Sy" id="one">one</b></a> | + <a class="permalink" href="#two"><b class="Sy" id="two">two</b></a></dt> + <dd>text</dd> + <dt><a class="permalink" href="#three"><b class="Sy" id="three">three</b></a></dt> + <dd>text</dd> +</dl> +<a class="permalink" href="#four"><b class="Sy" id="four">four</b></a> + <b class="Sy">one</b> + <a class="permalink" href="#explicit"><b class="Sy" id="explicit">five</b></a> diff --git a/regress/mdoc/Sy/tag.out_markdown b/regress/mdoc/Sy/tag.out_markdown new file mode 100644 index 00000000..5382a5e2 --- /dev/null +++ b/regress/mdoc/Sy/tag.out_markdown @@ -0,0 +1,25 @@ +SY-TAG(1) - General Commands Manual + +# NAME + +**Sy-tag** - tagging of symbolic font macros + +# DESCRIPTION + +BEGINTEST + +**one** | **two** + +> text + +**three** + +> text + +**four** +**one** +**five** + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Sy/tag.out_tag b/regress/mdoc/Sy/tag.out_tag new file mode 100644 index 00000000..c2fbaf59 --- /dev/null +++ b/regress/mdoc/Sy/tag.out_tag @@ -0,0 +1,5 @@ +one 9 +two 9 +three 12 +four 13 +explicit 13 diff --git a/regress/mdoc/Tg/Makefile b/regress/mdoc/Tg/Makefile new file mode 100644 index 00000000..7f538766 --- /dev/null +++ b/regress/mdoc/Tg/Makefile @@ -0,0 +1,8 @@ +# $OpenBSD: Makefile,v 1.1 2020/03/13 00:31:06 schwarze Exp $ + +REGRESS_TARGETS = warn +TAG_TARGETS = warn +LINT_TARGETS = warn +HTML_TARGETS = warn + +.include <bsd.regress.mk> diff --git a/regress/mdoc/Tg/warn.in b/regress/mdoc/Tg/warn.in new file mode 100644 index 00000000..af40f012 --- /dev/null +++ b/regress/mdoc/Tg/warn.in @@ -0,0 +1,34 @@ +.\" $OpenBSD: warn.in,v 1.1 2020/03/13 00:31:06 schwarze Exp $ +.Dd $Mdocdate$ +.Dt TG-WARN 1 +.Os +.Sh NAME +.Nm Tg-warn +.Nd warnings about tagging macros +.Sh DESCRIPTION +BEGINTEST +.Pp +.Tg start +initial +text +.Tg +.Ic macro +.Tg "" ignored arguments +too many +.Tg \&badstart +badstart +.Tg badend\& +badend +.Tg "white space" +whitespace +.Tg sub +.Tg double +.Ss Subsection +subtext +.Tg examples +.Sh EXAMPLES +example +text +.Pp +ENDTEST +.Tg diff --git a/regress/mdoc/Tg/warn.out_ascii b/regress/mdoc/Tg/warn.out_ascii new file mode 100644 index 00000000..8dee9aed --- /dev/null +++ b/regress/mdoc/Tg/warn.out_ascii @@ -0,0 +1,19 @@ +TG-WARN(1) General Commands Manual TG-WARN(1) + +NNAAMMEE + TTgg--wwaarrnn - warnings about tagging macros + +DDEESSCCRRIIPPTTIIOONN + BEGINTEST + + initial text mmaaccrroo too many badstart badend whitespace + + SSuubbsseeccttiioonn + subtext + +EEXXAAMMPPLLEESS + example text + + ENDTEST + +OpenBSD March 13, 2020 OpenBSD diff --git a/regress/mdoc/Tg/warn.out_html b/regress/mdoc/Tg/warn.out_html new file mode 100644 index 00000000..b4d3cf74 --- /dev/null +++ b/regress/mdoc/Tg/warn.out_html @@ -0,0 +1,11 @@ +<p class="Pp"><mark id="start"></mark>initial text + <a class="permalink" href="#macro"><code class="Ic" id="macro">macro</code></a> + too many badstart badend whitespace <mark id="sub"></mark></p> +<section class="Ss"> +<h2 class="Ss" id="double"><a class="permalink" href="#double">Subsection</a></h2> +<p class="Pp">subtext</p> +</section> +</section> +<section class="Sh"> +<h1 class="Sh" id="examples"><a class="permalink" href="#examples">EXAMPLES</a></h1> +<p class="Pp">example text</p> diff --git a/regress/mdoc/Tg/warn.out_lint b/regress/mdoc/Tg/warn.out_lint new file mode 100644 index 00000000..39c1f541 --- /dev/null +++ b/regress/mdoc/Tg/warn.out_lint @@ -0,0 +1,6 @@ +mandoc: warn.in:16:2: WARNING: skipping empty macro: Tg +mandoc: warn.in:16:8: ERROR: skipping excess arguments: Tg ... ignored +mandoc: warn.in:18:5: ERROR: skipping tag containing whitespace: Tg \&badstart +mandoc: warn.in:20:11: ERROR: skipping tag containing whitespace: Tg badend\& +mandoc: warn.in:22:10: ERROR: skipping tag containing whitespace: Tg white space +mandoc: warn.in:34:2: WARNING: skipping empty macro: Tg diff --git a/regress/mdoc/Tg/warn.out_markdown b/regress/mdoc/Tg/warn.out_markdown new file mode 100644 index 00000000..87204424 --- /dev/null +++ b/regress/mdoc/Tg/warn.out_markdown @@ -0,0 +1,30 @@ +TG-WARN(1) - General Commands Manual + +# NAME + +**Tg-warn** - warnings about tagging macros + +# DESCRIPTION + +BEGINTEST + +initial +text +**macro** +too many +badstart +badend +whitespace + +## Subsection + +subtext + +# EXAMPLES + +example +text + +ENDTEST + +OpenBSD - March 13, 2020 diff --git a/regress/mdoc/Tg/warn.out_tag b/regress/mdoc/Tg/warn.out_tag new file mode 100644 index 00000000..e1fc141c --- /dev/null +++ b/regress/mdoc/Tg/warn.out_tag @@ -0,0 +1,5 @@ +start 9 +macro 9 +sub 9 +double 11 +examples 14 diff --git a/regress/regress.pl b/regress/regress.pl index 01e46b3e..cb402875 100755 --- a/regress/regress.pl +++ b/regress/regress.pl @@ -2,7 +2,7 @@ # # $Id$ # -# Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> +# Copyright (c) 2017, 2018, 2019, 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 @@ -120,16 +120,17 @@ sub fail ($$) { my $onlytest = shift // ''; for (@ARGV) { - /^(all|ascii|utf8|man|html|markdown|lint|clean|verbose)$/ + /^(all|ascii|tag|man|utf8|html|markdown|lint|clean|verbose)$/ or usage "$_: invalid modifier"; $targets{$_} = 1; } $targets{all} = 1 - unless $targets{ascii} || $targets{utf8} || $targets{man} || - $targets{html} || $targets{markdown} || + unless $targets{ascii} || $targets{tag} || $targets{man} || + $targets{utf8} || $targets{html} || $targets{markdown} || $targets{lint} || $targets{clean}; -$targets{ascii} = $targets{utf8} = $targets{man} = $targets{html} = - $targets{markdown} = $targets{lint} = 1 if $targets{all}; +$targets{ascii} = $targets{tag} = $targets{man} = $targets{utf8} = + $targets{html} = $targets{markdown} = $targets{lint} = 1 + if $targets{all}; # --- parse Makefiles -------------------------------------------------- @@ -157,7 +158,7 @@ sub parse_makefile ($%) { } my (@regress_tests, @utf8_tests, @lint_tests, @html_tests); -my (%skip_ascii, %skip_man, %skip_markdown); +my (%tag_tests, %skip_ascii, %skip_man, %skip_markdown); foreach my $module (qw(roff char mdoc man tbl eqn)) { my %modvars; parse_makefile "$module/Makefile", \%modvars; @@ -168,36 +169,41 @@ foreach my $module (qw(roff char mdoc man tbl eqn)) { delete $subvars{GOPTS}; delete $subvars{SKIP_GROFF}; delete $subvars{SKIP_GROFF_ASCII}; - my @mandoc = ('../mandoc', split ' ', $subvars{MOPTS}); + my @mopts = split ' ', $subvars{MOPTS}; delete $subvars{MOPTS}; my @regress_testnames; + if (defined $subvars{TAG_TARGETS}) { + $tag_tests{"$module/$subdir/$_"} = 1 + for split ' ', $subvars{TAG_TARGETS}; + delete $subvars{TAG_TARGETS}; + } if (defined $subvars{REGRESS_TARGETS}) { push @regress_testnames, split ' ', $subvars{REGRESS_TARGETS}; push @regress_tests, { NAME => "$module/$subdir/$_", - MANDOC => \@mandoc, + MOPTS => \@mopts, } foreach @regress_testnames; delete $subvars{REGRESS_TARGETS}; } if (defined $subvars{UTF8_TARGETS}) { push @utf8_tests, { NAME => "$module/$subdir/$_", - MANDOC => \@mandoc, + MOPTS => \@mopts, } foreach split ' ', $subvars{UTF8_TARGETS}; delete $subvars{UTF8_TARGETS}; } if (defined $subvars{HTML_TARGETS}) { push @html_tests, { NAME => "$module/$subdir/$_", - MANDOC => \@mandoc, + MOPTS => \@mopts, } foreach split ' ', $subvars{HTML_TARGETS}; delete $subvars{HTML_TARGETS}; } if (defined $subvars{LINT_TARGETS}) { push @lint_tests, { NAME => "$module/$subdir/$_", - MANDOC => \@mandoc, + MOPTS => \@mopts, } foreach split ' ', $subvars{LINT_TARGETS}; delete $subvars{LINT_TARGETS}; } @@ -243,22 +249,44 @@ foreach my $module (qw(roff char mdoc man tbl eqn)) { my $count_total = 0; my $count_ascii = 0; +my $count_tag = 0; my $count_man = 0; my $count_rm = 0; -if ($targets{ascii} || $targets{man}) { - print "Running ascii and man tests "; +if ($targets{ascii} || $targets{tag} || $targets{man}) { + print "Running ascii, tag, and man tests "; print "...\n" if $targets{verbose}; } for my $test (@regress_tests) { my $i = "$test->{NAME}.in"; my $o = "$test->{NAME}.mandoc_ascii"; my $w = "$test->{NAME}.out_ascii"; - if ($targets{ascii} && !$skip_ascii{$test->{NAME}} && + my $to = "$test->{NAME}.mandoc_tag"; + my $tw = "$test->{NAME}.out_tag"; + my $diff_ascii; + if ($targets{tag} && $tag_tests{$test->{NAME}} && $test->{NAME} =~ /^$onlytest/) { - $count_ascii++; + $count_tag++; $count_total++; - sysout $o, @{$test->{MANDOC}}, qw(-I os=OpenBSD -T ascii), $i + local $ENV{MANPAGER} = "./copyless $test->{NAME}"; + my @cmd = (qw(../man -l), @{$test->{MOPTS}}, + qw(-I os=OpenBSD -T ascii), $i); + print "@cmd\n" if $targets{verbose}; + system @cmd + and fail $test->{NAME}, 'tag:man'; + system @diff, $tw, $to + and fail $test->{NAME}, 'tag:diff'; + print "." unless $targets{verbose}; + $diff_ascii = $targets{ascii}; + } elsif ($targets{ascii} && !$skip_ascii{$test->{NAME}} && + $test->{NAME} =~ /^$onlytest/) { + sysout $o, '../mandoc', @{$test->{MOPTS}}, + qw(-I os=OpenBSD -T ascii), $i and fail $test->{NAME}, 'ascii:mandoc'; + $diff_ascii = 1; + } + if ($diff_ascii) { + $count_ascii++; + $count_total++; system @diff, $w, $o and fail $test->{NAME}, 'ascii:diff'; print "." unless $targets{verbose}; @@ -269,9 +297,10 @@ for my $test (@regress_tests) { $test->{NAME} =~ /^$onlytest/) { $count_man++; $count_total++; - sysout $m, @{$test->{MANDOC}}, qw(-I os=OpenBSD -T man), $i + sysout $m, '../mandoc', @{$test->{MOPTS}}, + qw(-I os=OpenBSD -T man), $i and fail $test->{NAME}, 'man:man'; - sysout $mo, @{$test->{MANDOC}}, + sysout $mo, '../mandoc', @{$test->{MOPTS}}, qw(-man -I os=OpenBSD -T ascii -O mdoc), $m and fail $test->{NAME}, 'man:mandoc'; system @diff, $w, $mo @@ -279,13 +308,13 @@ for my $test (@regress_tests) { print "." unless $targets{verbose}; } if ($targets{clean}) { - print "rm $o $m $mo\n" if $targets{verbose}; - $count_rm += unlink $o, $m, $mo; + print "rm $o $to $m $mo\n" if $targets{verbose}; + $count_rm += unlink $o, $to, $m, $mo; } } -if ($targets{ascii} || $targets{man}) { - print "Number of ascii and man tests:" if $targets{verbose}; - print " $count_ascii + $count_man tests run.\n"; +if ($targets{ascii} || $targets{tag} || $targets{man}) { + print "Number of ascii, tag, and man tests:" if $targets{verbose}; + print " $count_ascii + $count_tag + $count_man tests run.\n"; } my $count_utf8 = 0; @@ -300,7 +329,8 @@ for my $test (@utf8_tests) { if ($targets{utf8} && $test->{NAME} =~ /^$onlytest/o) { $count_utf8++; $count_total++; - sysout $o, @{$test->{MANDOC}}, qw(-I os=OpenBSD -T utf8), $i + sysout $o, '../mandoc', @{$test->{MOPTS}}, + qw(-I os=OpenBSD -T utf8), $i and fail $test->{NAME}, 'utf8:mandoc'; system @diff, $w, $o and fail $test->{NAME}, 'utf8:diff'; @@ -328,7 +358,8 @@ for my $test (@html_tests) { if ($targets{html} && $test->{NAME} =~ /^$onlytest/) { $count_html++; $count_total++; - syshtml $o, @{$test->{MANDOC}}, qw(-T html), $i + syshtml $o, '../mandoc', @{$test->{MOPTS}}, + qw(-T html), $i and fail $test->{NAME}, 'html:mandoc'; system @diff, $w, $o and fail $test->{NAME}, 'html:diff'; @@ -357,7 +388,7 @@ for my $test (@regress_tests) { $test->{NAME} =~ /^$onlytest/) { $count_markdown++; $count_total++; - sysout $o, @{$test->{MANDOC}}, + sysout $o, '../mandoc', @{$test->{MOPTS}}, qw(-I os=OpenBSD -T markdown), $i and fail $test->{NAME}, 'markdown:mandoc'; system @diff, $w, $o @@ -386,7 +417,7 @@ for my $test (@lint_tests) { if ($targets{lint} && $test->{NAME} =~ /^$onlytest/) { $count_lint++; $count_total++; - syslint $o, @{$test->{MANDOC}}, + syslint $o, '../mandoc', @{$test->{MOPTS}}, qw(-I os=OpenBSD -T lint -W all), $i and fail $test->{NAME}, 'lint:mandoc'; system @diff, $w, $o @@ -418,6 +449,7 @@ if ($count_total == 1) { } elsif ($count_total) { print "All $count_total tests OK:"; print " $count_ascii ascii" if $count_ascii; + print " $count_tag tag" if $count_tag; print " $count_man man" if $count_man; print " $count_utf8 utf8" if $count_utf8; print " $count_html html" if $count_html; diff --git a/regress/regress.pl.1 b/regress/regress.pl.1 index 3777ec49..66d5369b 100644 --- a/regress/regress.pl.1 +++ b/regress/regress.pl.1 @@ -1,6 +1,6 @@ .\" $Id$ .\" -.\" Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2017, 2019, 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 @@ -78,6 +78,8 @@ output mode. Run subtests for .Fl T Cm markdown output mode. +.It Cm tag +Run subtests for automatic and manual tagging. .It Cm utf8 Run subtests for .Fl T Cm utf8 @@ -146,15 +148,6 @@ subdirectory of the regression suite is not included. It uses a Makefile structure that differs vastly from the rest of the suite. .Sh BUGS -On Oracle Solaris 11, -.Xr diff 1 -does not support the -.Fl a -option. -Delete that option from the following line in this script: -.Pp -.Dl my @diff = qw(diff -au); -.Pp The C library function .Xr wcwidth 3 is known to be buggy on Solaris, which may cause failures in the @@ -1,4 +1,4 @@ -/* $Id$ */ +/* $Id$ */ /* * Copyright (c) 2015,2016,2018,2019,2020 Ingo Schwarze <schwarze@openbsd.org> * @@ -13,134 +13,67 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Functions to tag syntax tree nodes. + * For internal use by mandoc(1) validation modules only. */ #include "config.h" #include <sys/types.h> #include <assert.h> -#include <errno.h> #include <limits.h> -#include <signal.h> #include <stddef.h> -#include <stdint.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #include "mandoc_aux.h" #include "mandoc_ohash.h" -#include "mandoc.h" +#include "roff.h" #include "tag.h" struct tag_entry { - size_t *lines; - size_t maxlines; - size_t nlines; + struct roff_node **nodes; + size_t maxnodes; + size_t nnodes; int prio; char s[]; }; -static void tag_signal(int) __attribute__((__noreturn__)); - static struct ohash tag_data; -static struct tag_files tag_files; /* - * Prepare for using a pager. - * Not all pagers are capable of using a tag file, - * but for simplicity, create it anyway. + * Set up the ohash table to collect nodes + * where various marked-up terms are documented. */ -struct tag_files * -tag_init(char *tagname) +void +tag_alloc(void) { - struct sigaction sa; - int ofd; - - ofd = -1; - tag_files.tfd = -1; - tag_files.tcpgid = -1; - tag_files.tagname = tagname; - - /* Clean up when dying from a signal. */ - - memset(&sa, 0, sizeof(sa)); - sigfillset(&sa.sa_mask); - sa.sa_handler = tag_signal; - sigaction(SIGHUP, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - sigaction(SIGTERM, &sa, NULL); - - /* - * POSIX requires that a process calling tcsetpgrp(3) - * from the background gets a SIGTTOU signal. - * In that case, do not stop. - */ - - sa.sa_handler = SIG_IGN; - sigaction(SIGTTOU, &sa, NULL); - - /* Save the original standard output for use by the pager. */ - - if ((tag_files.ofd = dup(STDOUT_FILENO)) == -1) { - mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno)); - goto fail; - } + mandoc_ohash_init(&tag_data, 4, offsetof(struct tag_entry, s)); +} - /* Create both temporary output files. */ +void +tag_free(void) +{ + struct tag_entry *entry; + unsigned int slot; - (void)strlcpy(tag_files.ofn, "/tmp/man.XXXXXXXXXX", - sizeof(tag_files.ofn)); - (void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX", - sizeof(tag_files.tfn)); - if ((ofd = mkstemp(tag_files.ofn)) == -1) { - mandoc_msg(MANDOCERR_MKSTEMP, 0, 0, - "%s: %s", tag_files.ofn, strerror(errno)); - goto fail; - } - if ((tag_files.tfd = mkstemp(tag_files.tfn)) == -1) { - mandoc_msg(MANDOCERR_MKSTEMP, 0, 0, - "%s: %s", tag_files.tfn, strerror(errno)); - goto fail; - } - if (dup2(ofd, STDOUT_FILENO) == -1) { - mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno)); - goto fail; + entry = ohash_first(&tag_data, &slot); + while (entry != NULL) { + free(entry->nodes); + free(entry); + entry = ohash_next(&tag_data, &slot); } - close(ofd); - - /* - * Set up the ohash table to collect output line numbers - * where various marked-up terms are documented. - */ - - mandoc_ohash_init(&tag_data, 4, offsetof(struct tag_entry, s)); - return &tag_files; - -fail: - tag_unlink(); - if (ofd != -1) - close(ofd); - if (tag_files.ofd != -1) - close(tag_files.ofd); - if (tag_files.tfd != -1) - close(tag_files.tfd); - *tag_files.ofn = '\0'; - *tag_files.tfn = '\0'; - tag_files.ofd = -1; - tag_files.tfd = -1; - tag_files.tagname = NULL; - return NULL; + ohash_delete(&tag_data); } /* - * Set the line number where a term is defined, + * Set a node where a term is defined, * unless it is already defined at a lower priority. */ void -tag_put(const char *s, int prio, size_t line) +tag_put(const char *s, int prio, struct roff_node *n) { struct tag_entry *entry; const char *se; @@ -148,11 +81,14 @@ tag_put(const char *s, int prio, size_t line) unsigned int slot; assert(prio <= TAG_FALLBACK); - if (tag_files.tfd <= 0) - return; - if (s[0] == '\\' && (s[1] == '&' || s[1] == 'e')) - s += 2; + if (s == NULL) { + if (n->child == NULL || n->child->type != ROFFT_TEXT) + return; + s = n->child->string; + if (s[0] == '\\' && (s[1] == '&' || s[1] == 'e')) + s += 2; + } /* * Skip whitespace and escapes and whatever follows, @@ -170,131 +106,67 @@ tag_put(const char *s, int prio, size_t line) slot = ohash_qlookupi(&tag_data, s, &se); entry = ohash_find(&tag_data, slot); - if (entry == NULL) { - - /* Build a new entry. */ + /* Build a new entry. */ + if (entry == NULL) { entry = mandoc_malloc(sizeof(*entry) + len + 1); memcpy(entry->s, s, len); entry->s[len] = '\0'; - entry->lines = NULL; - entry->maxlines = entry->nlines = 0; + entry->nodes = NULL; + entry->maxnodes = entry->nnodes = 0; ohash_insert(&tag_data, slot, entry); + } - } else { - - /* - * Lower priority numbers take precedence, - * but TAG_FALLBACK is special. - * A tag with priority TAG_FALLBACK is only used - * if the tag occurs exactly once. - */ + /* + * Lower priority numbers take precedence. + * If a better entry is already present, ignore the new one. + */ - if (prio == TAG_FALLBACK) { - if (entry->prio == TAG_FALLBACK) - entry->prio = TAG_DELETE; + else if (entry->prio < prio) return; - } - /* A better entry is already present, ignore the new one. */ - - if (entry->prio < prio) - return; + /* + * If the existing entry is worse, clear it. + * In addition, a tag with priority TAG_FALLBACK + * is only used if the tag occurs exactly once. + */ - /* The existing entry is worse, clear it. */ + else if (entry->prio > prio || prio == TAG_FALLBACK) { + while (entry->nnodes > 0) + entry->nodes[--entry->nnodes]->flags &= ~NODE_ID; - if (entry->prio > prio) - entry->nlines = 0; + if (prio == TAG_FALLBACK) { + entry->prio = TAG_DELETE; + return; + } } - /* Remember the new line. */ + /* Remember the new node. */ - if (entry->maxlines == entry->nlines) { - entry->maxlines += 4; - entry->lines = mandoc_reallocarray(entry->lines, - entry->maxlines, sizeof(*entry->lines)); + if (entry->maxnodes == entry->nnodes) { + entry->maxnodes += 4; + entry->nodes = mandoc_reallocarray(entry->nodes, + entry->maxnodes, sizeof(*entry->nodes)); } - entry->lines[entry->nlines++] = line; + entry->nodes[entry->nnodes++] = n; entry->prio = prio; -} - -/* - * Write out the tags file using the previously collected - * information and clear the ohash table while going along. - */ -void -tag_write(void) -{ - FILE *stream; - struct tag_entry *entry; - size_t i; - unsigned int slot; - int empty; - - if (tag_files.tfd <= 0) - return; - if (tag_files.tagname != NULL && ohash_find(&tag_data, - ohash_qlookup(&tag_data, tag_files.tagname)) == NULL) { - mandoc_msg(MANDOCERR_TAG, 0, 0, "%s", tag_files.tagname); - tag_files.tagname = NULL; - } - if ((stream = fdopen(tag_files.tfd, "w")) == NULL) - mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno)); - empty = 1; - entry = ohash_first(&tag_data, &slot); - while (entry != NULL) { - if (stream != NULL && entry->prio < TAG_DELETE) { - for (i = 0; i < entry->nlines; i++) { - fprintf(stream, "%s %s %zu\n", - entry->s, tag_files.ofn, entry->lines[i]); - empty = 0; - } - } - free(entry->lines); - free(entry); - entry = ohash_next(&tag_data, &slot); - } - ohash_delete(&tag_data); - if (stream != NULL) - fclose(stream); - else - close(tag_files.tfd); - tag_files.tfd = -1; - if (empty) { - unlink(tag_files.tfn); - *tag_files.tfn = '\0'; + n->flags |= NODE_ID; + if (n->child == NULL || n->child->string != s || *se != '\0') { + assert(n->string == NULL); + n->string = mandoc_strndup(s, len); } } -void -tag_unlink(void) +enum tag_result +tag_check(const char *test_tag) { - pid_t tc_pgid; + unsigned int slot; - if (tag_files.tcpgid != -1) { - tc_pgid = tcgetpgrp(tag_files.ofd); - if (tc_pgid == tag_files.pager_pid || - tc_pgid == getpgid(0) || - getpgid(tc_pgid) == -1) - (void)tcsetpgrp(tag_files.ofd, tag_files.tcpgid); - } - if (*tag_files.ofn != '\0') - unlink(tag_files.ofn); - if (*tag_files.tfn != '\0') - unlink(tag_files.tfn); -} - -static void -tag_signal(int signum) -{ - struct sigaction sa; - - tag_unlink(); - memset(&sa, 0, sizeof(sa)); - sigemptyset(&sa.sa_mask); - sa.sa_handler = SIG_DFL; - sigaction(signum, &sa, NULL); - kill(getpid(), signum); - /* NOTREACHED */ - _exit(1); + if (ohash_first(&tag_data, &slot) == NULL) + return TAG_EMPTY; + else if (test_tag != NULL && ohash_find(&tag_data, + ohash_qlookup(&tag_data, test_tag)) == NULL) + return TAG_MISS; + else + return TAG_OK; } @@ -1,4 +1,4 @@ -/* $Id$ */ +/* $Id$ */ /* * Copyright (c) 2015, 2018, 2019, 2020 Ingo Schwarze <schwarze@openbsd.org> * @@ -13,6 +13,9 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Internal interfaces to tag syntax tree nodes. + * For use by mandoc(1) validation modules only. */ /* @@ -25,19 +28,17 @@ #define TAG_FALLBACK (INT_MAX - 1) /* Tag only used if unique. */ #define TAG_DELETE (INT_MAX) /* Tag not used at all. */ - -struct tag_files { - char ofn[20]; - char tfn[20]; - char *tagname; - int ofd; - int tfd; - pid_t tcpgid; - pid_t pager_pid; +/* + * Return values of tag_check(). + */ +enum tag_result { + TAG_OK, /* Argument exists as a tag. */ + TAG_MISS, /* Argument not found. */ + TAG_EMPTY /* No tag exists at all. */ }; -struct tag_files *tag_init(char *); -void tag_put(const char *, int, size_t); -void tag_write(void); -void tag_unlink(void); +void tag_alloc(void); +void tag_put(const char *, int, struct roff_node *); +enum tag_result tag_check(const char *); +void tag_free(void); diff --git a/term_tag.c b/term_tag.c new file mode 100644 index 00000000..6f34143d --- /dev/null +++ b/term_tag.c @@ -0,0 +1,206 @@ +/* $Id$ */ +/* + * Copyright (c) 2015,2016,2018,2019,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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Functions to write a ctags(1) file. + * For use by the mandoc(1) ASCII and UTF-8 formatters only. + */ +#include "config.h" + +#include <sys/types.h> + +#include <errno.h> +#include <signal.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "mandoc.h" +#include "roff.h" +#include "tag.h" +#include "term_tag.h" + +static void tag_signal(int) __attribute__((__noreturn__)); + +static struct tag_files tag_files; + + +/* + * Prepare for using a pager. + * Not all pagers are capable of using a tag file, + * but for simplicity, create it anyway. + */ +struct tag_files * +term_tag_init(char *tagname) +{ + struct sigaction sa; + int ofd; /* In /tmp/, dup(2)ed to stdout. */ + int tfd; + + ofd = tfd = -1; + tag_files.tfs = NULL; + tag_files.tcpgid = -1; + tag_files.tagname = tagname; + + /* Clean up when dying from a signal. */ + + memset(&sa, 0, sizeof(sa)); + sigfillset(&sa.sa_mask); + sa.sa_handler = tag_signal; + sigaction(SIGHUP, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + + /* + * POSIX requires that a process calling tcsetpgrp(3) + * from the background gets a SIGTTOU signal. + * In that case, do not stop. + */ + + sa.sa_handler = SIG_IGN; + sigaction(SIGTTOU, &sa, NULL); + + /* Save the original standard output for use by the pager. */ + + if ((tag_files.ofd = dup(STDOUT_FILENO)) == -1) { + mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno)); + goto fail; + } + + /* Create both temporary output files. */ + + (void)strlcpy(tag_files.ofn, "/tmp/man.XXXXXXXXXX", + sizeof(tag_files.ofn)); + (void)strlcpy(tag_files.tfn, "/tmp/man.XXXXXXXXXX", + sizeof(tag_files.tfn)); + if ((ofd = mkstemp(tag_files.ofn)) == -1) { + mandoc_msg(MANDOCERR_MKSTEMP, 0, 0, + "%s: %s", tag_files.ofn, strerror(errno)); + goto fail; + } + if ((tfd = mkstemp(tag_files.tfn)) == -1) { + mandoc_msg(MANDOCERR_MKSTEMP, 0, 0, + "%s: %s", tag_files.tfn, strerror(errno)); + goto fail; + } + if ((tag_files.tfs = fdopen(tfd, "w")) == NULL) { + mandoc_msg(MANDOCERR_FDOPEN, 0, 0, "%s", strerror(errno)); + goto fail; + } + tfd = -1; + if (dup2(ofd, STDOUT_FILENO) == -1) { + mandoc_msg(MANDOCERR_DUP, 0, 0, "%s", strerror(errno)); + goto fail; + } + close(ofd); + return &tag_files; + +fail: + term_tag_unlink(); + if (ofd != -1) + close(ofd); + if (tfd != -1) + close(tfd); + if (tag_files.ofd != -1) { + close(tag_files.ofd); + tag_files.ofd = -1; + } + tag_files.tagname = NULL; + return NULL; +} + +void +term_tag_write(struct roff_node *n, size_t line) +{ + const char *cp; + int len; + + if (tag_files.tfs == NULL) + return; + if (n->string == NULL) + n = n->child; + cp = n->string; + if (cp[0] == '\\' && (cp[1] == '&' || cp[1] == 'e')) + cp += 2; + len = strcspn(cp, " \t\\"); + fprintf(tag_files.tfs, "%.*s %s %zu\n", + len, cp, tag_files.ofn, line); +} + +void +term_tag_finish(void) +{ + if (tag_files.tfs == NULL) + return; + fclose(tag_files.tfs); + tag_files.tfs = NULL; + switch (tag_check(tag_files.tagname)) { + case TAG_EMPTY: + unlink(tag_files.tfn); + *tag_files.tfn = '\0'; + /* FALLTHROUGH */ + case TAG_MISS: + if (tag_files.tagname == NULL) + break; + mandoc_msg(MANDOCERR_TAG, 0, 0, "%s", tag_files.tagname); + tag_files.tagname = NULL; + break; + case TAG_OK: + break; + } +} + +void +term_tag_unlink(void) +{ + pid_t tc_pgid; + + if (tag_files.tcpgid != -1) { + tc_pgid = tcgetpgrp(tag_files.ofd); + if (tc_pgid == tag_files.pager_pid || + tc_pgid == getpgid(0) || + getpgid(tc_pgid) == -1) + (void)tcsetpgrp(tag_files.ofd, tag_files.tcpgid); + } + if (*tag_files.ofn != '\0') { + unlink(tag_files.ofn); + *tag_files.ofn = '\0'; + } + if (*tag_files.tfn != '\0') { + unlink(tag_files.tfn); + *tag_files.tfn = '\0'; + } + if (tag_files.tfs != NULL) { + fclose(tag_files.tfs); + tag_files.tfs = NULL; + } +} + +static void +tag_signal(int signum) +{ + struct sigaction sa; + + term_tag_unlink(); + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_DFL; + sigaction(signum, &sa, NULL); + kill(getpid(), signum); + /* NOTREACHED */ + _exit(1); +} diff --git a/term_tag.h b/term_tag.h new file mode 100644 index 00000000..88a82115 --- /dev/null +++ b/term_tag.h @@ -0,0 +1,35 @@ +/* $Id$ */ +/* + * Copyright (c) 2015, 2018, 2019, 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Internal interfaces to write a ctags(1) file. + * For use by the mandoc(1) ASCII and UTF-8 formatters only. + */ + +struct tag_files { + char ofn[20]; /* Output file name. */ + char tfn[20]; /* Tag file name. */ + char *tagname; /* Target specified with -O. */ + FILE *tfs; /* Tag file object. */ + int ofd; /* Original output file descriptor. */ + pid_t tcpgid; /* Process group controlling the terminal. */ + pid_t pager_pid; /* Process ID of the pager. */ +}; + + +struct tag_files *term_tag_init(char *); +void term_tag_write(struct roff_node *, size_t); +void term_tag_finish(void); +void term_tag_unlink(void); @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,6 +14,9 @@ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Formatting module to let mandoc(1) show + * a human readable representation of the syntax tree. */ #include "config.h" @@ -305,6 +308,11 @@ print_man(const struct roff_node *n, int indent) putchar(')'); if (n->flags & NODE_EOS) putchar('.'); + if (n->flags & NODE_ID) { + printf(" ID"); + if (n->string != NULL) + printf("=%s", n->string); + } if (n->flags & NODE_NOFILL) printf(" NOFILL"); putchar('\n'); |