-/* $Id: html.c,v 1.261 2019/09/05 13:35:04 schwarze Exp $ */
+/* $Id: html.c,v 1.262 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
{"span", HTML_INPHRASE | HTML_TOPHRASE},
{"var", HTML_INPHRASE | HTML_TOPHRASE},
{"br", HTML_INPHRASE | HTML_NOSTACK | HTML_NLALL},
+ {"mark", HTML_INPHRASE | HTML_NOSTACK },
{"math", HTML_INPHRASE | HTML_NLALL | HTML_INDENT},
{"mrow", 0},
{"mi", 0},
-/* $Id: html.h,v 1.105 2019/09/01 15:12:19 schwarze Exp $ */
+/* $Id: html.h,v 1.106 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2017, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
TAG_SPAN,
TAG_VAR,
TAG_BR,
+ TAG_MARK,
TAG_MATH,
TAG_MROW,
TAG_MI,
-/* $Id: mandoc.h,v 1.265 2020/01/19 16:44:50 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.266 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2012-2020 Ingo Schwarze <schwarze@openbsd.org>
MANDOCERR_SHIFT, /* excessive shift: ..., but max is ... */
MANDOCERR_SO_PATH, /* NOT IMPLEMENTED: .so with absolute path or ".." */
MANDOCERR_SO_FAIL, /* .so request failed */
+ MANDOCERR_TG_SPC, /* skipping tag containing whitespace: tag */
MANDOCERR_ARG_SKIP, /* skipping all arguments: macro args */
MANDOCERR_ARG_EXCESS, /* skipping excess arguments: macro ... args */
MANDOCERR_DIVZERO, /* divide by zero */
-/* $Id: mandoc_msg.c,v 1.9 2020/01/19 16:44:50 schwarze Exp $ */
+/* $Id: mandoc_msg.c,v 1.10 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014-2020 Ingo Schwarze <schwarze@openbsd.org>
"excessive shift",
"NOT IMPLEMENTED: .so with absolute path or \"..\"",
".so request failed",
+ "skipping tag containing whitespace",
"skipping all arguments",
"skipping excess arguments",
"divide by zero",
-.\" $Id: mdoc.7,v 1.279 2019/07/15 19:20:30 schwarze Exp $
+.\" $Id: mdoc.7,v 1.280 2020/01/19 18:02:00 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
-.\" Copyright (c) 2010, 2011, 2013-2018 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2010, 2011, 2013-2020 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 15 2019 $
+.Dd $Mdocdate: January 19 2020 $
.Dt MDOC 7
.Os
.Sh NAME
.It Ic \&Ss Ta subsection header (one line)
.It Ic \&Sx Ta internal cross reference to a section or subsection
.It Ic \&Xr Ta cross reference to another manual page: Ar name section
+.It Ic \&Tg Ta tag the definition of a Ar term Pq <= 1 arguments
.It Ic \&Pp Ta start a text paragraph (no arguments)
.El
.Ss Displays and lists
.Ic \&Bl Fl column
lists; can only be used below
.Ic \&It .
+.It Ic \&Tg Op Ar term
+Announce that the next input line starts a definition of the
+.Ar term .
+This macro must appear alone on its own input line.
+The argument defaults to the first argument of the first macro
+on the next line.
+The argument may not contain whitespace characters, not even when it is quoted.
+This macro is a
+.Xr mandoc 1
+extension and is typically ignored by other formatters.
+.Pp
+When viewing terminal output with
+.Xr less 1 ,
+the interactive
+.Ic :t
+command can be used to go to the definition of the
+.Ar term
+as described for the
+.Ev MANPAGER
+variable in
+.Xr man 1 ;
+when producing HTML output, a fragment identifier
+.Pq Ic id No attribute
+is generated, to be used for deep linking to this place of the document.
+.Pp
+In most cases, adding a
+.Ic \&Tg
+macro would be redundant because
+.Xr mandoc 1
+is able to automatically tag most definitions.
+This macro is intended for cases where automatic tagging of a
+.Ar term
+is unsatisfactory, for example if a definition is not tagged
+automatically (false negative) or if places are tagged that do
+not define the
+.Ar term
+(false positives).
+When there is at least one
+.Ic \&Tg
+macro for a
+.Ar term ,
+no other places are automatically marked as definitions of that
+.Ar term .
.It Ic \&Tn Ar word ...
Supported only for compatibility, do not use this in new manuals.
Even though the macro name
.It Ic \&St Ta \&No Ta Yes Ta 1
.It Ic \&Sx Ta Yes Ta Yes Ta >0
.It Ic \&Sy Ta Yes Ta Yes Ta >0
+.It Ic \&Tg Ta \&No Ta \&No Ta <2
.It Ic \&Tn Ta Yes Ta Yes Ta >0
.It Ic \&Ud Ta \&No Ta \&No Ta 0
.It Ic \&Ux Ta Yes Ta Yes Ta n
-/* $Id: mdoc_html.c,v 1.332 2019/12/11 18:44:05 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.333 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2014-2019 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2014-2020 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
static int mdoc_st_pre(MDOC_ARGS);
static int mdoc_sx_pre(MDOC_ARGS);
static int mdoc_sy_pre(MDOC_ARGS);
+static int mdoc_tg_pre(MDOC_ARGS);
static int mdoc_va_pre(MDOC_ARGS);
static int mdoc_vt_pre(MDOC_ARGS);
static int mdoc_xr_pre(MDOC_ARGS);
{mdoc__x_pre, mdoc__x_post}, /* %Q */
{mdoc__x_pre, mdoc__x_post}, /* %U */
{NULL, NULL}, /* Ta */
+ {mdoc_tg_pre, NULL}, /* Tg */
};
return 0;
}
+static int
+mdoc_tg_pre(MDOC_ARGS)
+{
+ char *id;
+
+ if ((id = html_make_id(n, 1)) != NULL)
+ print_otag(h, TAG_MARK, "i", id);
+ return 0;
+}
+
static int
mdoc_ns_pre(MDOC_ARGS)
{
-/* $Id: mdoc_macro.c,v 1.233 2020/01/19 16:44:50 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.234 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2012-2019 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
{ in_line_eoln, MDOC_JOIN }, /* %Q */
{ in_line_eoln, 0 }, /* %U */
{ phrase_ta, MDOC_CALLABLE | MDOC_PARSED | MDOC_JOIN }, /* Ta */
+ { in_line_eoln, 0 }, /* Tg */
};
-/* $Id: mdoc_man.c,v 1.132 2019/01/04 03:17:36 schwarze Exp $ */
+/* $Id: mdoc_man.c,v 1.133 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2011-2019 Ingo Schwarze <schwarze@openbsd.org>
*
{ NULL, NULL, post_percent, NULL, NULL }, /* %Q */
{ NULL, NULL, post_percent, NULL, NULL }, /* %U */
{ NULL, NULL, NULL, NULL, NULL }, /* Ta */
+ { NULL, NULL, NULL, NULL, NULL }, /* Tg */
};
static const struct mdoc_man_act *mdoc_man_act(enum roff_tok);
-/* $Id: mdoc_markdown.c,v 1.31 2019/07/01 22:56:24 schwarze Exp $ */
+/* $Id: mdoc_markdown.c,v 1.32 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
*
{ NULL, NULL, md_post_pc, NULL, NULL }, /* %Q */
{ NULL, md_pre_Lk, md_post_pc, NULL, NULL }, /* %U */
{ NULL, NULL, NULL, NULL, NULL }, /* Ta */
+ { NULL, NULL, NULL, NULL, NULL }, /* Tg */
};
static const struct md_act *md_act(enum roff_tok);
-/* $Id: mdoc_state.c,v 1.15 2019/01/01 07:42:04 schwarze Exp $ */
+/* $Id: mdoc_state.c,v 1.16 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
*
NULL, /* %Q */
NULL, /* %U */
NULL, /* Ta */
+ NULL, /* Tg */
};
-/* $Id: mdoc_term.c,v 1.374 2019/06/27 12:20:18 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.375 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010, 2012-2019 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
*
* Permission to use, copy, modify, and distribute this software for any
static int termp_ss_pre(DECL_ARGS);
static int termp_sy_pre(DECL_ARGS);
static int termp_tag_pre(DECL_ARGS);
+static int termp_tg_pre(DECL_ARGS);
static int termp_under_pre(DECL_ARGS);
static int termp_vt_pre(DECL_ARGS);
static int termp_xr_pre(DECL_ARGS);
{ NULL, termp____post }, /* %Q */
{ NULL, termp____post }, /* %U */
{ NULL, NULL }, /* Ta */
+ { termp_tg_pre, NULL }, /* Tg */
};
static int fn_prio;
return 1;
}
+static int
+termp_tg_pre(DECL_ARGS)
+{
+ tag_put(n->child->string, -2, p->line);
+ return 0;
+}
+
static int
termp_abort_pre(DECL_ARGS)
{
-/* $Id: mdoc_validate.c,v 1.376 2020/01/19 16:44:50 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.377 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2020 Ingo Schwarze <schwarze@openbsd.org>
static void post_st(POST_ARGS);
static void post_std(POST_ARGS);
static void post_sx(POST_ARGS);
+static void post_tg(POST_ARGS);
static void post_useless(POST_ARGS);
static void post_xr(POST_ARGS);
static void post_xx(POST_ARGS);
NULL, /* %Q */
NULL, /* %U */
NULL, /* Ta */
+ post_tg, /* Tg */
};
#define RSORD_MAX 14 /* Number of `Rs' blocks. */
mdoc->last= n;
}
+static void
+post_tg(POST_ARGS)
+{
+ struct roff_node *n, *nch;
+ size_t len;
+
+ n = mdoc->last;
+ nch = n->child;
+ if (nch == NULL && n->next != NULL &&
+ n->next->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;
+ }
+ if (nch == NULL || *nch->string == '\0') {
+ mandoc_msg(MANDOCERR_MACRO_EMPTY, n->line, n->pos, "Tg");
+ 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);
+ if (nch->next != NULL) {
+ mandoc_msg(MANDOCERR_ARG_EXCESS, nch->next->line,
+ nch->next->pos, "Tg ... %s", nch->next->string);
+ while (nch->next != NULL)
+ roff_node_delete(mdoc, nch->next);
+ }
+ if (nch->string[len] != '\0')
+ roff_node_delete(mdoc, n);
+}
+
static void
post_obsolete(POST_ARGS)
{
while (nchild != NULL) {
nnext = nchild->next;
if (nchild->tok == MDOC_It ||
- (nchild->tok == MDOC_Sm &&
+ ((nchild->tok == MDOC_Sm || nchild->tok == MDOC_Tg) &&
nnext != NULL && nnext->tok == MDOC_It)) {
nchild = nnext;
continue;
-/* $Id: roff.c,v 1.368 2019/12/26 19:51:51 schwarze Exp $ */
+/* $Id: roff.c,v 1.369 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2010-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
"Lk", "Mt", "Brq", "Bro",
"Brc", "%C", "Es", "En",
"Dx", "%Q", "%U", "Ta",
- NULL,
+ "Tg", NULL,
"TH", "SH", "SS", "TP",
"TQ",
"LP", "PP", "P", "IP",
-/* $Id: roff.h,v 1.69 2019/03/04 13:01:57 schwarze Exp $ */
+/* $Id: roff.h,v 1.70 2020/01/19 18:02:00 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
- * Copyright (c) 2013-2015, 2017-2019 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
MDOC__Q,
MDOC__U,
MDOC_Ta,
+ MDOC_Tg,
MDOC_MAX,
MAN_TH,
MAN_SH,
-/* $Id: tag.c,v 1.25 2019/07/27 13:40:57 schwarze Exp $ */
+/* $Id: tag.c,v 1.26 2020/01/19 18:02:00 schwarze Exp $ */
/*
- * Copyright (c) 2015, 2016, 2018, 2019 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2015,2016,2018,2019,2020 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
/* A better entry is already present, ignore the new one. */
- if (entry->prio > 0 && entry->prio < prio)
+ if (entry->prio != -1 && entry->prio < prio)
return;
/* The existing entry is worse, clear it. */
- if (entry->prio < 1 || entry->prio > prio)
+ if (entry->prio == -1 || entry->prio == 0 ||
+ entry->prio > prio)
entry->nlines = 0;
}
empty = 1;
entry = ohash_first(&tag_data, &slot);
while (entry != NULL) {
- if (stream != NULL && entry->prio >= 0) {
+ if (stream != NULL && entry->prio != -1) {
for (i = 0; i < entry->nlines; i++) {
fprintf(stream, "%s %s %zu\n",
entry->s, tag_files.ofn, entry->lines[i]);