summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--man_html.c50
-rw-r--r--man_macro.c1
-rw-r--r--man_term.c27
-rw-r--r--man_validate.c31
-rw-r--r--mandoc.124
-rw-r--r--regress/man/MR/Makefile7
-rw-r--r--regress/man/MR/basic.in46
-rw-r--r--regress/man/MR/basic.out_ascii29
-rw-r--r--regress/man/MR/basic.out_lint5
-rw-r--r--regress/man/Makefile4
-rw-r--r--roff.c3
-rw-r--r--roff.h1
13 files changed, 215 insertions, 16 deletions
diff --git a/TODO b/TODO
index 46c766a9..af66e584 100644
--- a/TODO
+++ b/TODO
@@ -239,9 +239,6 @@ are mere guesses, and some may be wrong.
--- missing man features -----------------------------------------------
-- groff_man(7) .MR
- loc ** exist * algo * size * imp ***
-
- MANWIDTH
Markus Waldeck <waldeck at gmx dot de> 9 Jun 2015 05:49:56 +0200
Laura Morales <lauretas at mail dot com> 26 Apr 2018 08:15:55 +0200
diff --git a/man_html.c b/man_html.c
index 3e333e6a..46200a08 100644
--- a/man_html.c
+++ b/man_html.c
@@ -1,6 +1,6 @@
/* $Id$ */
/*
- * Copyright (c) 2013-2015,2017-2020,2022 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2013-15,2017-20,2022-23 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -53,6 +53,7 @@ static char list_continues(const struct roff_node *,
static int man_B_pre(MAN_ARGS);
static int man_IP_pre(MAN_ARGS);
static int man_I_pre(MAN_ARGS);
+static int man_MR_pre(MAN_ARGS);
static int man_OP_pre(MAN_ARGS);
static int man_PP_pre(MAN_ARGS);
static int man_RS_pre(MAN_ARGS);
@@ -106,6 +107,7 @@ static const struct man_html_act man_html_acts[MAN_MAX - MAN_TH] = {
{ NULL, NULL }, /* UE */
{ man_UR_pre, NULL }, /* MT */
{ NULL, NULL }, /* ME */
+ { man_MR_pre, NULL }, /* MR */
};
@@ -519,6 +521,52 @@ man_IP_pre(MAN_ARGS)
}
static int
+man_MR_pre(MAN_ARGS)
+{
+ struct tag *t;
+ const char *name, *section, *suffix;
+ char *label;
+
+ html_setfont(h, ESCAPE_FONTROMAN);
+ name = section = suffix = label = NULL;
+ if (n->child != NULL) {
+ name = n->child->string;
+ if (n->child->next != NULL) {
+ section = n->child->next->string;
+ mandoc_asprintf(&label,
+ "%s, section %s", name, section);
+ if (n->child->next->next != NULL)
+ suffix = n->child->next->next->string;
+ }
+ }
+
+ if (name != NULL && section != NULL && h->base_man1 != NULL)
+ t = print_otag(h, TAG_A, "chM?", "Xr",
+ name, section, "aria-label", label);
+ else
+ t = print_otag(h, TAG_A, "c?", "Xr", "aria-label", label);
+
+ free(label);
+ if (name != NULL) {
+ print_text(h, name);
+ h->flags |= HTML_NOSPACE;
+ }
+ print_text(h, "(");
+ h->flags |= HTML_NOSPACE;
+ if (section != NULL) {
+ print_text(h, section);
+ h->flags |= HTML_NOSPACE;
+ }
+ print_text(h, ")");
+ print_tagq(h, t);
+ if (suffix != NULL) {
+ h->flags |= HTML_NOSPACE;
+ print_text(h, suffix);
+ }
+ return 0;
+}
+
+static int
man_OP_pre(MAN_ARGS)
{
struct tag *tt;
diff --git a/man_macro.c b/man_macro.c
index 9840cff4..c2ea7d49 100644
--- a/man_macro.c
+++ b/man_macro.c
@@ -82,6 +82,7 @@ static const struct man_macro man_macros[MAN_MAX - MAN_TH] = {
{ blk_close, MAN_XSCOPE }, /* UE */
{ blk_exp, MAN_XSCOPE }, /* MT */
{ blk_close, MAN_XSCOPE }, /* ME */
+ { in_line_eoln, 0 }, /* MR */
};
diff --git a/man_term.c b/man_term.c
index a45a0ed2..4dac9ceb 100644
--- a/man_term.c
+++ b/man_term.c
@@ -1,6 +1,6 @@
/* $Id$ */
/*
- * Copyright (c) 2010-2015,2017-2020,2022 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010-15,2017-20,2022-23 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -74,6 +74,7 @@ static int pre_DT(DECL_ARGS);
static int pre_HP(DECL_ARGS);
static int pre_I(DECL_ARGS);
static int pre_IP(DECL_ARGS);
+static int pre_MR(DECL_ARGS);
static int pre_OP(DECL_ARGS);
static int pre_PD(DECL_ARGS);
static int pre_PP(DECL_ARGS);
@@ -134,6 +135,7 @@ static const struct man_term_act man_term_acts[MAN_MAX - MAN_TH] = {
{ NULL, NULL, 0 }, /* UE */
{ pre_UR, post_UR, 0 }, /* MT */
{ NULL, NULL, 0 }, /* ME */
+ { pre_MR, NULL, 0 }, /* MR */
};
static const struct man_term_act *man_term_act(enum roff_tok);
@@ -328,6 +330,29 @@ pre_B(DECL_ARGS)
}
static int
+pre_MR(DECL_ARGS)
+{
+ term_fontrepl(p, TERMFONT_NONE);
+ n = n->child;
+ if (n != NULL) {
+ term_word(p, n->string); /* name */
+ p->flags |= TERMP_NOSPACE;
+ }
+ term_word(p, "(");
+ p->flags |= TERMP_NOSPACE;
+ if (n != NULL && (n = n->next) != NULL) {
+ term_word(p, n->string); /* section */
+ p->flags |= TERMP_NOSPACE;
+ }
+ term_word(p, ")");
+ if (n != NULL && (n = n->next) != NULL) {
+ p->flags |= TERMP_NOSPACE;
+ term_word(p, n->string); /* suffix */
+ }
+ return 0;
+}
+
+static int
pre_OP(DECL_ARGS)
{
term_word(p, "[");
diff --git a/man_validate.c b/man_validate.c
index 722e4fdc..e3da8837 100644
--- a/man_validate.c
+++ b/man_validate.c
@@ -1,6 +1,6 @@
/* $Id$ */
/*
- * Copyright (c) 2010, 2012-2020 Ingo Schwarze <schwarze@openbsd.org>
+ * Copyright (c) 2010, 2012-2020, 2023 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -33,6 +33,7 @@
#include "mandoc_aux.h"
#include "mandoc.h"
+#include "mandoc_xr.h"
#include "roff.h"
#include "man.h"
#include "libmandoc.h"
@@ -54,6 +55,7 @@ static void post_AT(CHKARGS);
static void post_EE(CHKARGS);
static void post_EX(CHKARGS);
static void post_IP(CHKARGS);
+static void post_MR(CHKARGS);
static void post_OP(CHKARGS);
static void post_SH(CHKARGS);
static void post_TH(CHKARGS);
@@ -100,6 +102,7 @@ static const v_check man_valids[MAN_MAX - MAN_TH] = {
NULL, /* UE */
post_UR, /* MT */
NULL, /* ME */
+ post_MR, /* MR */
};
@@ -547,6 +550,32 @@ post_TH(CHKARGS)
}
static void
+post_MR(CHKARGS)
+{
+ struct roff_node *nch;
+
+ if ((nch = n->child) == NULL) {
+ mandoc_msg(MANDOCERR_NM_NONAME, n->line, n->pos, "MR");
+ return;
+ }
+ if (nch->next == NULL) {
+ mandoc_msg(MANDOCERR_XR_NOSEC,
+ n->line, n->pos, "MR %s", nch->string);
+ return;
+ }
+ if (mandoc_xr_add(nch->next->string, nch->string, nch->line, nch->pos))
+ mandoc_msg(MANDOCERR_XR_SELF, nch->line, nch->pos,
+ "MR %s %s", nch->string, nch->next->string);
+ if ((nch = nch->next->next) == NULL || nch->next == NULL)
+ return;
+
+ mandoc_msg(MANDOCERR_ARG_EXCESS, nch->next->line, nch->next->pos,
+ "MR ... %s", nch->next->string);
+ while (nch->next != NULL)
+ roff_node_delete(man, nch->next);
+}
+
+static void
post_UC(CHKARGS)
{
static const char * const bsd_versions[] = {
diff --git a/mandoc.1 b/mandoc.1
index 106db4b9..780183a2 100644
--- a/mandoc.1
+++ b/mandoc.1
@@ -1,6 +1,6 @@
.\" $Id$
.\"
-.\" Copyright (c) 2012, 2014-2022 Ingo Schwarze <schwarze@openbsd.org>
+.\" Copyright (c) 2012, 2014-2023 Ingo Schwarze <schwarze@openbsd.org>
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
@@ -1295,9 +1295,11 @@ The same standard section title occurs more than once.
A standard section header occurs in a section of the manual
where it normally isn't useful.
.It Sy "cross reference to self"
-.Pq mdoc
+.Pq mdoc , man
An
.Ic \&Xr
+or
+.Ic \&MR
macro refers to a name and section matching the section of the present
manual page and a name mentioned in an
.Ic \&Nm
@@ -1616,12 +1618,16 @@ macro is immediately followed by an
macro on the next input line.
Such an empty block does not produce any output.
.It Sy "missing section argument"
-.Pq mdoc
+.Pq mdoc , man
An
.Ic \&Xr
+or
+.Ic \&MR
macro lacks its second, section number argument.
-The first argument, i.e. the name, is printed, but without subsequent
-parentheses.
+The first argument, i.e. the name, is printed, but without a section number.
+In the case of
+.Ic \&Xr ,
+the parentheses are also omitted.
.It Sy "missing -std argument, adding it"
.Pq mdoc
An
@@ -2152,10 +2158,12 @@ request is neither a single ASCII character
nor a single character escape sequence.
All arguments are ignored and printing of a margin character is disabled.
.It Sy "missing manual name, using \(dq\(dq"
-.Pq mdoc
+.Pq mdoc , man
The first call to
.Ic \&Nm ,
-or any call in the NAME section, lacks the required argument.
+or any call in the NAME section, lacks the required argument, or
+.Ic \&MR
+is called without any argument.
.It Sy "uname(3) system call failed, using UNKNOWN"
.Pq mdoc
The
@@ -2283,6 +2291,8 @@ or a request of the
family with more than two arguments
.It
.Ic \&Dt
+or
+.Ic \&MR
with more than three arguments
.It
.Ic \&TH
diff --git a/regress/man/MR/Makefile b/regress/man/MR/Makefile
new file mode 100644
index 00000000..7ab2a9ee
--- /dev/null
+++ b/regress/man/MR/Makefile
@@ -0,0 +1,7 @@
+# $OpenBSD: Makefile,v 1.1 2023/10/24 20:30:49 schwarze Exp $
+
+# disable for now because groff changed the global indentation
+#REGRESS_TARGETS = basic
+LINT_TARGETS = basic
+
+.include <bsd.regress.mk>
diff --git a/regress/man/MR/basic.in b/regress/man/MR/basic.in
new file mode 100644
index 00000000..adb531a5
--- /dev/null
+++ b/regress/man/MR/basic.in
@@ -0,0 +1,46 @@
+.\" $OpenBSD: basic.in,v 1.1 2023/10/24 20:30:49 schwarze Exp $
+.TH MR-BASIC 1 "October 24, 2023" OpenBSD
+.SH NAME
+MR-basic \- manual page cross references
+.SH DESCRIPTION
+empty:
+.MR
+prints empty name and parentheses
+.PP
+single argument:
+.MR name
+prints empty parentheses
+.PP
+two arguments:
+.MR test 1
+normal use
+.PP
+three arguments:
+.MR test 1 suffix
+with suffix
+.PP
+four arguments:
+.MR test 1 suffix excess
+warning
+.PP
+five arguments:
+.MR test 1 suffix too many
+warning
+.PP
+after setting
+.ft B
+bold
+font:
+.MR test 1 suffix
+not bold
+.PP
+in bold next-line scope:
+.B
+.MR test 1 suffix
+not bold
+.TP 5n
+first tag
+first body
+.TP
+.MR test 1 tag
+test body
diff --git a/regress/man/MR/basic.out_ascii b/regress/man/MR/basic.out_ascii
new file mode 100644
index 00000000..d386ba0b
--- /dev/null
+++ b/regress/man/MR/basic.out_ascii
@@ -0,0 +1,29 @@
+MR-BASIC(1) General Commands Manual MR-BASIC(1)
+
+NNAAMMEE
+ MR-basic - manual page cross references
+
+DDEESSCCRRIIPPTTIIOONN
+ empty: () prints empty name and parentheses
+
+ single argument: name() prints empty parentheses
+
+ two arguments: test(1) normal use
+
+ three arguments: test(1)suffix with suffix
+
+ four arguments: test(1)suffix warning
+
+ five arguments: test(1)suffix warning
+
+ after setting bboolldd ffoonntt:: test(1)suffix not bold
+
+ in bold next-line scope: test(1)suffix not bold
+
+ first tag
+ first body
+
+ test(1)tag
+ test body
+
+OpenBSD October 24, 2023 MR-BASIC(1)
diff --git a/regress/man/MR/basic.out_lint b/regress/man/MR/basic.out_lint
new file mode 100644
index 00000000..d4803bcb
--- /dev/null
+++ b/regress/man/MR/basic.out_lint
@@ -0,0 +1,5 @@
+mandoc: basic.in:38:2: WARNING: line scope broken: MR breaks B
+mandoc: basic.in:7:2: ERROR: missing manual name, using "": MR
+mandoc: basic.in:11:2: WARNING: missing section argument: MR name
+mandoc: basic.in:23:19: ERROR: skipping excess arguments: MR ... excess
+mandoc: basic.in:27:19: ERROR: skipping excess arguments: MR ... too
diff --git a/regress/man/Makefile b/regress/man/Makefile
index 17a939b2..306411dc 100644
--- a/regress/man/Makefile
+++ b/regress/man/Makefile
@@ -1,6 +1,6 @@
-# $OpenBSD: Makefile,v 1.20 2022/04/27 17:04:15 schwarze Exp $
+# $OpenBSD: Makefile,v 1.21 2023/10/24 20:30:49 schwarze Exp $
-SUBDIR = AT B BI DT EX HP IP MT OP PD PP RS SH SS SY TH TP TS UC UR nf blank
+SUBDIR = AT B BI DT EX HP IP MR MT OP PD PP RS SH SS SY TH TP TS UC UR nf blank
.include "../Makefile.sub"
.include <bsd.subdir.mk>
diff --git a/roff.c b/roff.c
index 53f9df46..975aa471 100644
--- a/roff.c
+++ b/roff.c
@@ -367,7 +367,8 @@ const char *__roff_name[MAN_MAX + 1] = {
"PD", "AT", "in",
"SY", "YS", "OP",
"EX", "EE", "UR",
- "UE", "MT", "ME", NULL
+ "UE", "MT", "ME", "MR",
+ NULL
};
const char *const *roff_name = __roff_name;
diff --git a/roff.h b/roff.h
index b74d2280..4ebba2ec 100644
--- a/roff.h
+++ b/roff.h
@@ -476,6 +476,7 @@ enum roff_tok {
MAN_UE,
MAN_MT,
MAN_ME,
+ MAN_MR,
MAN_MAX /* End of man(7) macros. */
};