Hello,

onf wrote on Sat, Feb 08, 2025 at 01:35:31AM +0100:
> On Fri Jan 24, 2025 at 7:51 PM CET, Ingo Schwarze wrote:

>> While parts of it may be a bit dusty and i might have to check whether
>> a few things could become even better by providing more stringent or
>> more relaxed advice as experience accumulated, this is still a good
>> resource for people having throughly digested mdoc(7) and taking the
>> extended documentation with minor grains of salt:
>>
>>   https://mandoc.bsd.lv/mdoc/
>>
>> In particular, do not miss the Appendix, which is actively maintained.

> Thank you for the pointers; the Appendix in particular is quite useful.
> However, there are some things which I haven't found in there.
> Perhaps they would make good additions.

Thank you for making suggestions.
The extended documentation certainly isn't perfect, it's more like a
collection of fragments.

The appendix is more than fragments and closer to completion,
but no doubt there are gaps in there that i would like to close,
and suggestions and questions help with that.

>  1. Escape sequences in the sense of inline commands, i.e. how to mark
>     up syntax like \f[font]? Does it fit under Cm?

The roff(7) language is a language using rather unusual syntax,
compared to other languages.  That makes applying good mdoc(7) style
to it relatively difficult; certainly more difficult than using mdoc(7)
for example for C or sh code.

That said, i don't like using .Cm for \f[font] because that's for fixed
strings that serve as arguments for commands or directives, and i see no
command or directive here that this could be an argument of.  For the "\f"
itself, the .Ic macro seems more appropriate because it serves the
function of a stand-alone command.  For the "font" argument in your
example, it depends whether you are displaying a literal font name (like
"BI") or a placeholder.  And then there is the question of how to mark
up the square brackets.  I prefer treating them as punctuation, i.e.
not marking them up at all.

So, consider this a good example - it's slightly modified text
pilfered from the roff(7) manual page in the mandoc package:

  The
  .Ic \ef Ns Bq Ar font
  escape sequence switches to the specified
  .Ar font.
  For example,
  .Ic \ef Ns Cm B
  switches to bold font,
  .Ic \ef Ns Cm P
  switches back to the previous font, and
  .Ic \ef Ns Cm ( BI
  switches to bold italic font.

Note the neat trick of putting the "(" as a separate argument *after*
the .Cm macro; it ends up out of, i.e. before the .Cm scope because
it's opening punctuation.  The following line is equivalent, but
arguably less clear because it does not stress the fact that "("
is punctuation as much:

  .Ic \ef Ns ( Cm BI

You see that documenting the roff(7) language *itself* using mdoc(7)
quickly becomes tricky - admittedly not quite as difficult as it
would be with man(7), which requires either \c or font escapes:

  The
  .B \ef\c
  .RI [ font ]
  escape sequence switches to the specified

or:

  The \fB\ef\fR[\fIfont\fR]
  escape sequence switches to the specified

Even for this appendix, marking up roff(7) syntax is arguably a somewhat
niche topic.  Then again, while the mdoc(7) manual page aims for
conciseness, this appendix does not.  The appendix aims for
completeness instead, so i added an entry for "escape sequence"
to the appendix.  I'm also appending the committed patch below
for easy reference.

>  2. stdin, stdout, stderr without the /dev/; do those fit under Pa?
>     Practice among mdoc documents seems inconsistent.[1]

If you are talking about the FILE pointers declared in <stdio.h>,
no, absolutely not .Pa.

What to use instead is tricky.  Technically, these are the names of
gloval variables, so .Va would not be completely wrong.  However, their
function is more like constants than like variables - compare to a typical
read-only only variable like ".Va errno".  Considering their function,
using .Dv makes most sense: they are used just like ".Dv STDOUT_FILENO"
from <unistd.h>, only with different API functions, so using the same
macro makes sense to me.

So i would maybe say something like:

  To redirect standard error output to a file, one can pass
  .Dv stderr
  as the third argument to
  .Xr freopen 3 ,
  but some might argue that first opening the file with
  .Xr open 2 ,
  then passing the resulting file descriptor and the constant
  .Dv STDOUT_FILENO
  to
  .Xr dup2 2
  also gets the job done.

The constant symbols stdin, stdout, and stderr seem exessively
specific to explicitly mention them in the appendix, so i'm not
sure what to do about that.

If you are talking about the devices, use ".Xr stdout 4".
If you are talking about the device files, use ".Pa /dev/stdout".
Given that "stdout" can be three different things (device, file,
or variable), do not use bare "stdout" as a relative path name,
or you will inevitably confuse at least some readers, so i
believe ".Pa stdout" is almost always bad markup.

If you want to talk about the general concepts (and not about any
specific syntax element), use the plain English words "standard
input", "standard output", and "standard error output" rather than
the cryptic abbreviations stdin, stdout, and stderr.

>  3. Displaying " as a literal character. Sq is suggested for displaying
>     single characters, but it seems to be a poor match for ". I am
>     currently using Sy.

  The
  .Xr ascii 7
  double quote character
  .Pq Sq \&"

does not look that bad to me and is certainly rigorous.
Then again, if you want to use

  .Pq Sy \&"

for that specific case, i wouldn't get upset about that, either.
Does that need mentioning in the appendix?  Not so sure, that
sounds excessively specific, too.

> By the way, the entry for emphasis says 'stess' instead of 'stress'.

Fixed by the patch below.

> Also, http://manpages.bsd.lv/mdoc.html says:
>   To display output, you must invoke nroff as nroff -mandoc file.
>   The mandoc flag indicates that input is in mdoc.
> 
> That's wrong on several levels, but since this is meant to be a tutorial
> and some level of simplification is necessary, s/man/m/g seems like the
> easiest way to make it acceptable.

Now we are getting into murky territory.  Kristaps wrote
the manpages.bsd.lv website without my involvement and it has been
unmaintained for a very long time.  Even if i had the time to maintain
that site, me doing that would not be ideal because part of the value
of that site is that it is written in a style very different from my
own, so there is a chance some people may like it who hate my style
of technical writing, and if i would work too much on it, i might
end up ruining the unique style and supplanting it with my own.

One person volunteered maintaining manpages.bsd.lv in the past,
but did so little work on it that i would still call the site
unmaintained.

All the same, i fixed the particular bug you reported, as follows:

  The mandoc flag indicates that input is in either mdoc or man format.

That is accurate and concise and does not seem to break the style.
Your s/man/m/ proposal doesn't seem incorrect either, but if people
use nroff(1), i'd recommend to keep the habit of using -mandoc
because it works for both languages, and when formatting, you
rarely care about the source format, but mishaps easily occur
if your are overly specific with -mdoc or -man.

> [1] Querying mdoc manuals installed on my machine:
>       bsdtar(1): stdout without markup

That wouldn't be ideal, but the tar(1) manual in OpenBSD does not
contain the string "std" at all, so i cannot fix anything there.
It appears the OpenBSD manual follows my recommendation to use
the unabbreviated English words, which feels appropriate in section 1
in particular.

>       bsdunzip(1): Va stderr, stdout without markup

That's the third-party project https://www.libarchive.org/ .
Some BSD developers appear to be involved, more from FreeBSD
than OpenBSD, so reporting should go upstream.

>       sndioctl(1): Em stdout

Fixed, OpenBSD sndioctl.1 rev. 1.17:

 If no commands are specified, all valid controls are displayed on
-.Em stdout .
+standard output.

>       ssh-agent(1): Dv stdout

Even though .Dv would be technically OK from the markup perspective,
this should not contain the string "stdout" in the first place.
Fixed in OpenBSD ssh-agent.1 rev. 1.82:

-Generate C-shell commands on
-.Dv stdout .
+Generate C-shell commands on standard output.

-Generate Bourne shell commands on
-.Dv stdout .
+Generate Bourne shell commands on standard output.

>       sshd_config(5): Xr stdout 4, Xr stderr 4

That's actually correct since it is specifically talking about
the devices and linking to the device documentation is useful.

So this resulted in changes to four files in four different projects
(mandoc.bsd.lv, manpages.bsd.lv, OpenBSD snd* stuff, and OpenSSH).
Possibly one of the most internally diverse bug reports ever.  :-D

Tanks again,
  Ingo


Index: appendix/markup.mdoc
===================================================================
RCS file: /home/cvs/mdocml/www/mdoc/appendix/markup.mdoc,v
diff -u -r1.4 markup.mdoc
--- appendix/markup.mdoc        5 Mar 2019 10:57:45 -0000       1.4
+++ appendix/markup.mdoc        9 Feb 2025 17:20:11 -0000
@@ -403,7 +403,7 @@
 .Ic \&Dx
 .It email address:
 .Ic \&Mt
-.It emphasis (contrastive stess in the linguistic sense):
+.It emphasis (contrastive stress in the linguistic sense):
 .Ic \&Em
 .It enclosure:
 .Bl -bullet -compact
@@ -428,6 +428,29 @@
 .Xr eqn 7
 .It error number (errno) constant:
 .Ic \&Er
+.It Xo
+escape sequence (e.g. in the
+.Xr roff 7
+language):
+.Xc
+.Bl -bullet -compact
+.It
+escape sequence name:
+.Ic \&Ic
+.It
+escape sequence punctuation (parenthesis or brackets): no markup or
+.Ic \&Bq
+.It
+escape sequence argument keyword:
+.Ic \&Cm
+.It
+escape sequence argument placeholder:
+.Ic \&Ar
+.It
+examples:
+.Dq .Ic \eef \&Ns \&Bq \&Ar fontname ,
+.Dq .Ic \eef \&Ns \&Cm \&( \&BI
+.El
 .It escaping:
 .Bl -bullet -compact
 .It

Reply via email to