From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from localhost (mandoc.bsd.lv [local]) by mandoc.bsd.lv (OpenSMTPD) with ESMTPA id 2649595a for ; Fri, 13 Mar 2020 10:33:21 -0500 (EST) Date: Fri, 13 Mar 2020 10:33:21 -0500 (EST) X-Mailinglist: mandoc-source Reply-To: source@mandoc.bsd.lv MIME-Version: 1.0 From: schwarze@mandoc.bsd.lv To: source@mandoc.bsd.lv Subject: mandoc: Split tagging into a validation part including prioritization in X-Mailer: activitymail 1.26, http://search.cpan.org/dist/activitymail/ Content-Type: text/plain; charset=utf-8 Message-ID: <11ff0e2fd20e8825@mandoc.bsd.lv> Log Message: ----------- Split tagging into a validation part including prioritization in tag.{h,c} and {mdoc,man}_validate.c and into a formatting part including command line argument checking in term_tag.{h,c}, html.c, and {mdoc|man}_{term|html}.c. Immediate functional benefits include: * Improved prioritization of automatic tags for .Em and .Sy. * Avoiding bogus automatic tags when .Em, .Fn, or .Sy are explicitly tagged. * Explicit tagging of .Er and .Fl now works in HTML output. * Automatic tagging of .IP and .TP now works in HTML output. But mainly, this patch provides clean earth to build further improvements on. Technical changes: * Main program: Write a tag file for ASCII and UTF-8 output only. * All formatters: There is no more need to delay writing the tags. * mdoc(7)+man(7) formatters: No more need for elaborate syntax tree inspection. * HTML formatter: If available, use the "string" attribute as the tag. * HTML formatter: New function to write permalinks, to reduce code duplication. Style cleanup in the vicinity while here: * mdoc(7) terminal formatter: To set up bold font for children, defer to termp_bold_pre() rather than calling term_fontpush() manually. * mdoc(7) terminal formatter: Garbage collect some duplicate functions. * mdoc(7) HTML formatter: Unify handling, delete redundant functions. * Where possible, use switch statements rather than if cascades. * Get rid of some more Yoda notation. The necessity for such changes was first discussed with kn@, but i didn't bother him with a request to review the resulting -673/+782 line patch. Modified Files: -------------- mandoc: Makefile Makefile.depend html.c html.h main.c man_html.c man_term.c man_validate.c mandoc_headers.3 mandoc_html.3 mdoc_html.c mdoc_term.c mdoc_validate.c read.c tag.c tag.h tree.c mandoc/regress: regress.pl regress.pl.1 mandoc/regress/man/IP: Makefile empty.in empty.out_ascii empty.out_lint literal.out_html mandoc/regress/man/TP: Makefile literal.out_html vert.out_html mandoc/regress/mdoc: Makefile mandoc/regress/mdoc/Cm: Makefile mandoc/regress/mdoc/Dv: Makefile mandoc/regress/mdoc/Em: Makefile mandoc/regress/mdoc/Er: Makefile mandoc/regress/mdoc/Ev: Makefile mandoc/regress/mdoc/Fl: Makefile mandoc/regress/mdoc/Fo: Makefile mandoc/regress/mdoc/Ic: Makefile mandoc/regress/mdoc/Li: Makefile mandoc/regress/mdoc/Ms: Makefile mandoc/regress/mdoc/No: Makefile punct.out_lint mandoc/regress/mdoc/Sy: Makefile Added Files: ----------- mandoc: term_tag.c term_tag.h mandoc/regress: copyless mandoc/regress/man/IP: empty.out_html empty.out_tag tag.in tag.out_ascii tag.out_html tag.out_tag mandoc/regress/man/TP: tag.in tag.out_ascii tag.out_html tag.out_tag mandoc/regress/mdoc/Cm: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Dv: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Em: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Er: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Ev: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Fl: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Fo: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Ic: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Li: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Ms: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/No: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Sy: tag.in tag.out_ascii tag.out_html tag.out_markdown tag.out_tag mandoc/regress/mdoc/Tg: Makefile warn.in warn.out_ascii warn.out_html warn.out_lint warn.out_markdown warn.out_tag Revision Data ------------- Index: tag.h =================================================================== RCS file: /home/cvs/mandoc/mandoc/tag.h,v retrieving revision 1.10 retrieving revision 1.11 diff -Ltag.h -Ltag.h -u -p -r1.10 -r1.11 --- tag.h +++ tag.h @@ -1,4 +1,4 @@ -/* $Id$ */ +/* $Id$ */ /* * Copyright (c) 2015, 2018, 2019, 2020 Ingo Schwarze * @@ -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); Index: mandoc_html.3 =================================================================== RCS file: /home/cvs/mandoc/mandoc/mandoc_html.3,v retrieving revision 1.19 retrieving revision 1.20 diff -Lmandoc_html.3 -Lmandoc_html.3 -u -p -r1.19 -r1.20 --- mandoc_html.3 +++ 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 Index: html.h =================================================================== RCS file: /home/cvs/mandoc/mandoc/html.h,v retrieving revision 1.106 retrieving revision 1.107 diff -Lhtml.h -Lhtml.h -u -p -r1.106 -r1.107 --- html.h +++ html.h @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* + * Copyright (c) 2017, 2018, 2019, 2020 Ingo Schwarze * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons - * Copyright (c) 2017, 2018, 2019 Ingo Schwarze * * 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 *, 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 *); Index: tag.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/tag.c,v retrieving revision 1.27 retrieving revision 1.28 diff -Ltag.c -Ltag.c -u -p -r1.27 -r1.28 --- tag.c +++ tag.c @@ -1,4 +1,4 @@ -/* $Id$ */ +/* $Id$ */ /* * Copyright (c) 2015,2016,2018,2019,2020 Ingo Schwarze * @@ -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 #include -#include #include -#include #include -#include -#include #include #include -#include #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 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 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; } Index: mdoc_html.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/mdoc_html.c,v retrieving revision 1.335 retrieving revision 1.336 diff -Lmdoc_html.c -Lmdoc_html.c -u -p -r1.335 -r1.336 --- mdoc_html.c +++ mdoc_html.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2014-2020 Ingo Schwarze + * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * * 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_h {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_h {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 *me 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; } Index: tree.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/tree.c,v retrieving revision 1.86 retrieving revision 1.87 diff -Ltree.c -Ltree.c -u -p -r1.86 -r1.87 --- tree.c +++ tree.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons * Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze + * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons * * 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 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'); Index: read.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/read.c,v retrieving revision 1.214 retrieving revision 1.215 diff -Lread.c -Lread.c -u -p -r1.214 -r1.215 --- read.c +++ read.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2019 Ingo Schwarze + * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2012 Joerg Sonnenberger * * 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 } 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); Index: main.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/main.c,v retrieving revision 1.344 retrieving revision 1.345 diff -Lmain.c -Lmain.c -u -p -r1.344 -r1.345 --- main.c +++ main.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2012, 2014-2020 Ingo Schwarze + * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010 Joerg Sonnenberger * * 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, struc } 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, struc 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. */ Index: man_validate.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/man_validate.c,v retrieving revision 1.150 retrieving revision 1.151 diff -Lman_validate.c -Lman_validate.c -u -p -r1.150 -r1.151 --- man_validate.c +++ man_validate.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2012-2020 Ingo Schwarze + * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * * 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) __att 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 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, @@ -346,6 +413,37 @@ post_IP(CHKARGS) default: break; } +} + +/* + * 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 Index: mandoc_headers.3 =================================================================== RCS file: /home/cvs/mandoc/mandoc/mandoc_headers.3,v retrieving revision 1.32 retrieving revision 1.33 diff -Lmandoc_headers.3 -Lmandoc_headers.3 -u -p -r1.32 -r1.33 --- mandoc_headers.3 +++ mandoc_headers.3 @@ -1,6 +1,6 @@ .\" $Id$ .\" -.\" Copyright (c) 2014-2019 Ingo Schwarze +.\" Copyright (c) 2014-2020 Ingo Schwarze .\" .\" 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 f .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 prototype 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 Index: man_term.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/man_term.c,v retrieving revision 1.234 retrieving revision 1.235 diff -Lman_term.c -Lman_term.c -u -p -r1.234 -r1.235 --- man_term.c +++ man_term.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze + * Copyright (c) 2008-2012 Kristaps Dzonsons * * 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: /* @@ -1158,61 +1148,4 @@ print_man_head(struct termp *p, const st term_vspace(p); } 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; - } - } } Index: Makefile.depend =================================================================== RCS file: /home/cvs/mandoc/mandoc/Makefile.depend,v retrieving revision 1.45 retrieving revision 1.46 diff -LMakefile.depend -LMakefile.depend -u -p -r1.45 -r1.46 --- Makefile.depend +++ Makefile.depend @@ -33,12 +33,12 @@ eqn_html.o: eqn_html.c config.h mandoc.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 mand 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_ 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 Index: mdoc_term.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/mdoc_term.c,v retrieving revision 1.378 retrieving revision 1.379 diff -Lmdoc_term.c -Lmdoc_term.c -u -p -r1.378 -r1.379 --- mdoc_term.c +++ mdoc_term.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2012-2020 Ingo Schwarze + * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2013 Franco Fichtner * * 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_t { 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_t { 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_t { 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_t { 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 ro 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 rof 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,103 +1908,43 @@ 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; } Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/Makefile,v retrieving revision 1.530 retrieving revision 1.531 diff -LMakefile -LMakefile -u -p -r1.530 -r1.531 --- Makefile +++ Makefile @@ -1,7 +1,7 @@ # $Id$ # +# Copyright (c) 2011, 2013-2020 Ingo Schwarze # Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons -# Copyright (c) 2011, 2013-2019 Ingo Schwarze # # 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: @@ -516,6 +518,9 @@ libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_ 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) Index: html.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/html.c,v retrieving revision 1.263 retrieving revision 1.264 diff -Lhtml.c -Lhtml.c -u -p -r1.263 -r1.264 --- html.c +++ html.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2011-2015, 2017-2020 Ingo Schwarze + * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * * 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_ 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 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, 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 @@ -734,6 +765,33 @@ print_otag(struct html *h, enum htmltag h->noindent++; 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 --- /dev/null +++ term_tag.c @@ -0,0 +1,206 @@ +/* $Id: term_tag.c,v 1.1 2020/03/13 15:32:29 schwarze Exp $ */ +/* + * Copyright (c) 2015,2016,2018,2019,2020 Ingo Schwarze + * + * 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 + +#include +#include +#include +#include +#include +#include +#include + +#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); +} Index: mdoc_validate.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/mdoc_validate.c,v retrieving revision 1.379 retrieving revision 1.380 diff -Lmdoc_validate.c -Lmdoc_validate.c -u -p -r1.379 -r1.380 --- mdoc_validate.c +++ mdoc_validate.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2020 Ingo Schwarze + * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010 Joerg Sonnenberger * * 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 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 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 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__ 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 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; --- /dev/null +++ term_tag.h @@ -0,0 +1,35 @@ +/* $Id: term_tag.h,v 1.1 2020/03/13 15:32:29 schwarze Exp $ */ +/* + * Copyright (c) 2015, 2018, 2019, 2020 Ingo Schwarze + * + * 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); Index: man_html.c =================================================================== RCS file: /home/cvs/mandoc/mandoc/man_html.c,v retrieving revision 1.176 retrieving revision 1.177 diff -Lman_html.c -Lman_html.c -u -p -r1.176 -r1.177 --- man_html.c +++ man_html.c @@ -1,7 +1,7 @@ -/* $Id$ */ +/* $Id$ */ /* - * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze + * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * * 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) --- /dev/null +++ regress/mdoc/Sy/tag.out_tag @@ -0,0 +1,5 @@ +one 9 +two 9 +three 12 +four 13 +explicit 13 --- /dev/null +++ regress/mdoc/Sy/tag.out_html @@ -0,0 +1,10 @@ +
+
| +
+
text
+
+
text
+
+ + one + --- /dev/null +++ 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 --- /dev/null +++ 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 --- /dev/null +++ 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: March 13 2020 $ +.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 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Sy/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -Lregress/mdoc/Sy/Makefile -Lregress/mdoc/Sy/Makefile -u -p -r1.3 -r1.4 --- regress/mdoc/Sy/Makefile +++ 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 Index: regress.pl.1 =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/regress.pl.1,v retrieving revision 1.4 retrieving revision 1.5 diff -Lregress/regress.pl.1 -Lregress/regress.pl.1 -u -p -r1.4 -r1.5 --- regress/regress.pl.1 +++ regress/regress.pl.1 @@ -1,6 +1,6 @@ .\" $Id$ .\" -.\" Copyright (c) 2017 Ingo Schwarze +.\" Copyright (c) 2017, 2019, 2020 Ingo Schwarze .\" .\" 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 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 Index: regress.pl =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/regress.pl,v retrieving revision 1.13 retrieving revision 1.14 diff -Lregress/regress.pl -Lregress/regress.pl -u -p -r1.13 -r1.14 --- regress/regress.pl +++ regress/regress.pl @@ -2,7 +2,7 @@ # # $Id$ # -# Copyright (c) 2017 Ingo Schwarze +# Copyright (c) 2017, 2018, 2019, 2020 Ingo Schwarze # # 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 ma 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 ma 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; --- /dev/null +++ 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 --- /dev/null +++ regress/man/IP/tag.out_tag @@ -0,0 +1,2 @@ +strong 13 +weak 15 --- /dev/null +++ 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 --- /dev/null +++ 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) Index: empty.in =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/man/IP/empty.in,v retrieving revision 1.2 retrieving revision 1.3 diff -Lregress/man/IP/empty.in -Lregress/man/IP/empty.in -u -p -r1.2 -r1.3 --- regress/man/IP/empty.in +++ 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 --- /dev/null +++ regress/man/IP/empty.out_html @@ -0,0 +1,18 @@ +
+
+
indented text
+
+

Empty IP is deleted:

+
+
+
+
+
indented text
+
+

Empty IP is deleted, RS does not cause additional spacing:

+
+
+
+
indented text
+
+
--- /dev/null +++ regress/man/IP/empty.out_tag @@ -0,0 +1,3 @@ +tag1 15 +tag2 17 +tag 21 Index: literal.out_html =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/man/IP/literal.out_html,v retrieving revision 1.4 retrieving revision 1.5 diff -Lregress/man/IP/literal.out_html -Lregress/man/IP/literal.out_html -u -p -r1.4 -r1.5 --- regress/man/IP/literal.out_html +++ regress/man/IP/literal.out_html @@ -1,5 +1,5 @@
-
tag
+
indented regular text

new regular paragraph

@@ -8,7 +8,7 @@ literal text
-
tag
+
 indented
@@ -32,7 +32,7 @@ literal
 text
 
-
tag
+
 indented
@@ -48,7 +48,7 @@ text
   out of indented paragraph
 

regular text

-
tag
+
indented regular text
 indented
Index: Makefile
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/man/IP/Makefile,v
retrieving revision 1.3
retrieving revision 1.4
diff -Lregress/man/IP/Makefile -Lregress/man/IP/Makefile -u -p -r1.3 -r1.4
--- regress/man/IP/Makefile
+++ 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 
--- /dev/null
+++ regress/man/IP/tag.out_html
@@ -0,0 +1,10 @@
+
+
strong
+
text
+
+
text
+
+
text
+
strong
+
text
+
Index: empty.out_lint =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/man/IP/empty.out_lint,v retrieving revision 1.4 retrieving revision 1.5 diff -Lregress/man/IP/empty.out_lint -Lregress/man/IP/empty.out_lint -u -p -r1.4 -r1.5 --- regress/man/IP/empty.out_lint +++ 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 Index: empty.out_ascii =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/man/IP/empty.out_ascii,v retrieving revision 1.1 retrieving revision 1.2 diff -Lregress/man/IP/empty.out_ascii -Lregress/man/IP/empty.out_ascii -u -p -r1.1 -r1.2 --- regress/man/IP/empty.out_ascii +++ 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 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/man/TP/Makefile,v retrieving revision 1.5 retrieving revision 1.6 diff -Lregress/man/TP/Makefile -Lregress/man/TP/Makefile -u -p -r1.5 -r1.6 --- regress/man/TP/Makefile +++ 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. --- /dev/null +++ regress/man/TP/tag.out_tag @@ -0,0 +1,3 @@ +plain 13 +strong 19 +weak 21 --- /dev/null +++ regress/man/TP/tag.out_html @@ -0,0 +1,16 @@ +
+
plain
+
text
+
+
text
+
plain
+
text
+
strong
+
text
+
+
text
+
+
text
+
strong
+
text
+
--- /dev/null +++ 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) Index: literal.out_html =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/man/TP/literal.out_html,v retrieving revision 1.2 retrieving revision 1.3 diff -Lregress/man/TP/literal.out_html -Lregress/man/TP/literal.out_html -u -p -r1.2 -r1.3 --- regress/man/TP/literal.out_html +++ regress/man/TP/literal.out_html @@ -1,5 +1,5 @@
-
tag
+
regular indented text

regular paragraph

@@ -8,7 +8,7 @@ literal text
-
tag
+
 indented
--- /dev/null
+++ 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
Index: vert.out_html
===================================================================
RCS file: /home/cvs/mandoc/mandoc/regress/man/TP/vert.out_html,v
retrieving revision 1.1
retrieving revision 1.2
diff -Lregress/man/TP/vert.out_html -Lregress/man/TP/vert.out_html -u -p -r1.1 -r1.2
--- regress/man/TP/vert.out_html
+++ regress/man/TP/vert.out_html
@@ -2,8 +2,8 @@
 

-
tag
+
text
-
tag
+
text
Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -Lregress/mdoc/Makefile -Lregress/mdoc/Makefile -u -p -r1.1 -r1.2 --- regress/mdoc/Makefile +++ 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 --- /dev/null +++ regress/mdoc/Cm/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 --- /dev/null +++ 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 --- /dev/null +++ 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 --- /dev/null +++ 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: March 13 2020 $ +.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 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Cm/Makefile,v retrieving revision 1.4 retrieving revision 1.5 diff -Lregress/mdoc/Cm/Makefile -Lregress/mdoc/Cm/Makefile -u -p -r1.4 -r1.5 --- regress/mdoc/Cm/Makefile +++ 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 --- /dev/null +++ regress/mdoc/Cm/tag.out_html @@ -0,0 +1,9 @@ +
+
+ | +
+
text
+
+
text
+
+ --- /dev/null +++ regress/mdoc/Dv/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 --- /dev/null +++ regress/mdoc/Dv/tag.out_html @@ -0,0 +1,9 @@ +
+
+ | +
+
text
+
+
text
+
+ --- /dev/null +++ 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 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Dv/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -Lregress/mdoc/Dv/Makefile -Lregress/mdoc/Dv/Makefile -u -p -r1.3 -r1.4 --- regress/mdoc/Dv/Makefile +++ 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 --- /dev/null +++ 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: March 13 2020 $ +.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 --- /dev/null +++ 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 --- /dev/null +++ regress/mdoc/Em/tag.out_html @@ -0,0 +1,10 @@ +
+
| +
+
text
+
+
text
+
+ + one + --- /dev/null +++ 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 --- /dev/null +++ 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: March 13 2020 $ +.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 --- /dev/null +++ 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 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Em/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -Lregress/mdoc/Em/Makefile -Lregress/mdoc/Em/Makefile -u -p -r1.3 -r1.4 --- regress/mdoc/Em/Makefile +++ 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 --- /dev/null +++ regress/mdoc/Em/tag.out_tag @@ -0,0 +1,5 @@ +one 9 +two 9 +three 12 +four 13 +explicit 13 --- /dev/null +++ regress/mdoc/Er/tag.out_html @@ -0,0 +1,12 @@ +
+
one
+
text
+
+ +
+
+

+
+
[]
+
text
+
Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Er/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -Lregress/mdoc/Er/Makefile -Lregress/mdoc/Er/Makefile -u -p -r1.3 -r1.4 --- regress/mdoc/Er/Makefile +++ 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 --- /dev/null +++ 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 --- /dev/null +++ regress/mdoc/Er/tag.out_tag @@ -0,0 +1,2 @@ +two 10 +ENOENT 13 --- /dev/null +++ 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: March 13 2020 $ +.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 --- /dev/null +++ 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 --- /dev/null +++ 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: March 13 2020 $ +.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 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Ev/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -Lregress/mdoc/Ev/Makefile -Lregress/mdoc/Ev/Makefile -u -p -r1.3 -r1.4 --- regress/mdoc/Ev/Makefile +++ 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 --- /dev/null +++ regress/mdoc/Ev/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 --- /dev/null +++ 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 --- /dev/null +++ regress/mdoc/Ev/tag.out_html @@ -0,0 +1,9 @@ +
+
+ | +
+
text
+
+
text
+
+ --- /dev/null +++ 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 --- /dev/null +++ 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 --- /dev/null +++ regress/mdoc/Fl/tag.out_tag @@ -0,0 +1,4 @@ +a 9 +b 9 +c 12 +d 13 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Fl/Makefile,v retrieving revision 1.6 retrieving revision 1.7 diff -Lregress/mdoc/Fl/Makefile -Lregress/mdoc/Fl/Makefile -u -p -r1.6 -r1.7 --- regress/mdoc/Fl/Makefile +++ 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 --- /dev/null +++ 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: March 13 2020 $ +.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 --- /dev/null +++ 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 --- /dev/null +++ regress/mdoc/Fl/tag.out_html @@ -0,0 +1,8 @@ +
+
| +
+
text
+
+
text
+
+ --- /dev/null +++ regress/mdoc/Fo/tag.out_html @@ -0,0 +1,9 @@ +

automatic: + () + and second()

+

() + and first()

+

explicit: + () + and + (void);

--- /dev/null +++ regress/mdoc/Fo/tag.out_tag @@ -0,0 +1,4 @@ +first 9 +second 11 +e3 13 +e4 13 --- /dev/null +++ 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: March 13 2020 $ +.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 --- /dev/null +++ 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 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Fo/Makefile,v retrieving revision 1.5 retrieving revision 1.6 diff -Lregress/mdoc/Fo/Makefile -Lregress/mdoc/Fo/Makefile -u -p -r1.5 -r1.6 --- regress/mdoc/Fo/Makefile +++ 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 --- /dev/null +++ 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 --- /dev/null +++ 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: March 13 2020 $ +.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 --- /dev/null +++ regress/mdoc/Ic/tag.out_html @@ -0,0 +1,9 @@ +
+
+ | +
+
text
+
+
text
+
+ --- /dev/null +++ regress/mdoc/Ic/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Ic/Makefile,v retrieving revision 1.4 retrieving revision 1.5 diff -Lregress/mdoc/Ic/Makefile -Lregress/mdoc/Ic/Makefile -u -p -r1.4 -r1.5 --- regress/mdoc/Ic/Makefile +++ 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 --- /dev/null +++ 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 --- /dev/null +++ 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 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Li/Makefile,v retrieving revision 1.4 retrieving revision 1.5 diff -Lregress/mdoc/Li/Makefile -Lregress/mdoc/Li/Makefile -u -p -r1.4 -r1.5 --- regress/mdoc/Li/Makefile +++ 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 --- /dev/null +++ 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 --- /dev/null +++ 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 --- /dev/null +++ regress/mdoc/Li/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 --- /dev/null +++ regress/mdoc/Li/tag.out_html @@ -0,0 +1,9 @@ +
+
+ | +
+
text
+
+
text
+
+ --- /dev/null +++ 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: March 13 2020 $ +.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 --- /dev/null +++ regress/mdoc/Ms/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/Ms/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -Lregress/mdoc/Ms/Makefile -Lregress/mdoc/Ms/Makefile -u -p -r1.3 -r1.4 --- regress/mdoc/Ms/Makefile +++ 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 --- /dev/null +++ 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 --- /dev/null +++ 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: March 13 2020 $ +.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 --- /dev/null +++ regress/mdoc/Ms/tag.out_html @@ -0,0 +1,9 @@ +
+
+ | +
+
text
+
+
text
+
+ --- /dev/null +++ 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 --- /dev/null +++ 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 Index: punct.out_lint =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/No/punct.out_lint,v retrieving revision 1.8 retrieving revision 1.9 diff -Lregress/mdoc/No/punct.out_lint -Lregress/mdoc/No/punct.out_lint -u -p -r1.8 -r1.9 --- regress/mdoc/No/punct.out_lint +++ regress/mdoc/No/punct.out_lint @@ -23,3 +23,4 @@ mandoc: punct.in:72:7: WARNING: skipping 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. --- /dev/null +++ regress/mdoc/No/tag.out_html @@ -0,0 +1,9 @@ +
+
+ | +
+
text
+
+
text
+
+ --- /dev/null +++ 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 --- /dev/null +++ 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: March 13 2020 $ +.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 --- /dev/null +++ regress/mdoc/No/tag.out_tag @@ -0,0 +1,4 @@ +one 9 +two 9 +three 12 +four 13 Index: Makefile =================================================================== RCS file: /home/cvs/mandoc/mandoc/regress/mdoc/No/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -Lregress/mdoc/No/Makefile -Lregress/mdoc/No/Makefile -u -p -r1.3 -r1.4 --- regress/mdoc/No/Makefile +++ 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 --- /dev/null +++ regress/mdoc/Tg/warn.out_html @@ -0,0 +1,11 @@ +

initial text + + too many badstart badend whitespace

+
+

+

subtext

+
+
+
+

+

example text

--- /dev/null +++ regress/mdoc/Tg/warn.out_tag @@ -0,0 +1,5 @@ +start 9 +macro 9 +sub 9 +double 11 +examples 14 --- /dev/null +++ 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 --- /dev/null +++ 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 --- /dev/null +++ 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 --- /dev/null +++ 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 --- /dev/null +++ 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: March 13 2020 $ +.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 -- To unsubscribe send an email to source+unsubscribe@mandoc.bsd.lv