.\" $NetBSD: doc2html,v 1.71 2020/01/23 23:52:13 uwe Exp $
.\"
.\" Copyright (c) 1998, 1999, 2008 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Ross Harvey.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.ig
The first section of this package processes a large subset of the -mdoc macro
functions into HTML. All of the commonly used requests are implemented.
The second section implements -man (-man.old) macros. These are trivial
compared to -mdoc.
NOTES:
	The initial purpose of these macros is to support distrib/notes.
	It's very close, but not quite ready to do all of the man pages.
	See src/distrib/notes/Makefile.inc for important groff command
	examples. For HTML generation it is important to turn off overstrike
	modes with -P-b -P-u -P-o.
TODO:
	There are a few internal macros and other symbols that don't contain
	an embedded `-'.
	Need a tbl(1) command that generates html tables from tbl(1)
	input. (Partially written.) For now, we just switch into <pre>
	mode on .TS or .PS. Tbl input is very uncommon these days, anyway.
	(-mdoc has the .Bl -column list, which eliminates most requirements
	for tbl)
	We should probably end all the html pages with an upward
	pointing "contents" link, except right now there is nothing
	to point to.
	We need "intro" or "contents" pages for each man/man? (man/html?)
	section.
	WARNING! If you add a callable macro (or define an old one that
	was missing) it MUST have a doc2html@@ alias. (Scan for @@ to see.)
..
.
.if dError .Error - multiple inclusion of doc2html
.
.de TS
<pre>
..
.de TE
.	DEBUG .tm TE
</pre>
..
.de PS
<pre>
..
.de PE
.	DEBUG .tm PE
</pre>
..
.
.nr doc-stackp 0
.de doc-push
.	ds doc-stack-rq-\\n[doc-stackp] \\$1
.	nr doc-stack-ln-\\n[doc-stackp] \\n[.c]
.	nr doc-stackp +1
..
.
.de doc-pop
.	ie \\n[doc-stackp]<=0 .Error Extraneous \\$1 request
.	el .nr doc-stackp -1
.	ds doc-pop-tmp1 \\*[doc-stack-rq-\\n[doc-stackp]]
.	if !\\*[doc-pop-tmp1]\\$1 \{\
.		tm Need \\*[doc-pop-tmp1] before \\$1
.		Error See line \\n[doc-stack-ln-\\n[doc-stackp]]
.	\}
..
.
.de doc-rlookup
.	if !r\\$1 \{\
.		ie \\w\\V[\\$1] .nr \\$1 \\V[\\$1]
.		el .nr \\$1 \\$2
.	\}
..
.
.de doc-slookup
.	if !d\\$1 \{\
.		ie \\w\\V[\\$1] .ds \\$1 \\V[\\$1]
.		el .ds \\$1 \\$2
.	\}
..
.
.doc-rlookup DOC_DEBUG_MODE 0
.doc-rlookup DOC_XR 0
.doc-slookup DOC_MANROOT ..
.
.nr in-pre 0
.nr HTML 1
.pl 1i
.po 0
.in 0
.nf
.nh
.nr list-level 0
.de ce
.	ie \\$1 \{\
		<center>
.		nr center-on \\$1
.		it 1 doc-center-step
.	\}
.	el .	end-center
..
.nr center-on 0
.de end-center
.	it
.	if \\n[center-on] </center>
.	nr center-on 0
..
.
.de doc-center-step
<br>
.	nr center-on -1
.	ie \\n[center-on]<=0 .end-center
.	el .it 1 doc-center-step
..
.
.ds copy &copy;
.ds > &gt;
.ds < &lt;
.ds >= &gt;=
.ds <= &lt;=
.ds Lt &lt;
.ds Gt &gt;
.ds & &amp;
.ds Am &amp;
.ds _ &nbsp;
.ds q &quot;
.ds body-params bgcolor="#FFFFFF" text="#000000"
.ds document-title
.ds title-section
.ds dot-de .de
.ds dot-dot ..
.ds sepstring \~
.ds doc-punct-result
.ds doc-punct { . , : ; ( ) [ ] }
.ds close-mode
.ds open-mode
.ds doc-anchor
.\" default EOL after .An
.\" can be changed with .An -nosplit
.ds an-eol <br>
.ds Nm-save
.ds T " x
.ds tN <font\ size="-1">
.ds aa </font>
.ds Px \\*(tNPOSIX\\*(aa
.chop T
.nr doc-dosep 0
.nr r-lvl 0
.
.if !dMANROOT \{\
.	ds MANROOT \V[MANROOT]
.	if !\w\*[MANROOT] .ds MANROOT ..
.\}
.
.blm Pp
.
.
.de DEBUG
.if \\n[DOC_DEBUG_MODE] \\$*
..
.de Dd
.	as document-title " \\$*
..
.de Dt
.	as document-title " \\$*
..
.de Os
.	as document-title " \\$*
.	init-html
..
.\"----------------------------------------------------------------------
.\" troff requests we delete
.
.rm wh
.
.\" troff requests we translate
.
.rn br br-real
.rn sp sp-real
.rn fi fi-real
.rn nf nf-real
.
.de br
.	if \\n[in-pre]=0 <br>
..
.de sp-nice-try-ross
.	ie !\\n(.$ <br>
.	el .ie '\\$1'1' <br>
.	el \{\
.		if !\\n[in-pre] <pre>
.		nr sp-tmp \\$1v-1v
.		if \\n[sp-tmp]>0 .sp-real \\n[sp-tmp]u
.		if !\\n[in-pre] </pre>
.	\}
..
.\" Although the above probably works, the following is a lot simpler. It
.\" reduces the request to 1v, but why would you put more than one adjacent
.\" blank line in an html document anyway?
.de sp
.	ie \\n[center-on] <!-- -->
.	el <br><br>
..
.de end-preformat
.	DEBUG .tm end-preformat \\n[in-pre]
.	if \\n[in-pre] </pre>
.	nr in-pre 0
..
.de fi
.	DEBUG fi
.	end-preformat
..
.de nf
<br>
<pre>
.	nr in-pre 1
..
.\"
.\"----------------------------------------------------------------------
.\" Magic to open and close <body> and <html>
.\"
.de end-macro
.	if \\w\\n[.z] .ab ERROR, unclosed quotation from line \
\\n[quotation_line]
.	br-real	\" should be unnecessary...we have fill turned off
.	fl	\" more paranoia
</body>
</html>
.	br-real
.	fl
..
.em end-macro
.
.\" map groff -Tencoding argument to the charset name
.       ie '\*(.T'ascii'  .ds html-charset US-ASCII
.el \{ .ie '\*(.T'latin1' .ds html-charset ISO-8859-1
.el \{ .ie '\*(.T'utf8'   .ds html-charset UTF-8
.el    .ab unsupported encoding \*(.T
.\}\}
.
.de init-html
<html>
<head>
	<meta charset="\\*[html-charset]"/>
	<title>
.ie '\\*[title-section]'' \\*[document-title]\\$*
.el  \\*[title-section]
	</title>
	<style type="text/css">
	<!--
		body { margin-left:4%; }
		H1, H2, H3, H4, H5 {
			color: maroon; padding: 4pt; margin-left: -4%;
			border: solid; border-width: thin; width: 100%;
			background: rgb(204,204,255)
		}
	-->
	</style>
</head>
<body \\*[body-params]>
\\*[dot-de] init-html
\\*[dot-dot]
..
.de Lk
.	if \\n[.$]<1 .ab #\\n[.c]: Usage: .Lk href [ anchortext/punct ] ...
.	ds doc-href \\$1
.	ds doc-anchortext \\$1
.	shift
.	if \\n[.$] \{\
.		doc-checkpunct \\$1 \\*[doc-punct]
.		if !\\n[doc-ispunct] \{\
.			ds doc-anchortext \\$1
.			shift
.		\}
.	\}
.	ds doc-anchor <a href="\\*[doc-href]">\\*[doc-anchortext]</a>
.	while \\n[.$] \{\
.		doc-checkpunct \\$1 \\*[doc-punct]
.		if !\\n[doc-ispunct] .ab #\\n[.c]: .link ... '$1' -- Huh?
.		as doc-anchor \\$1
.		shift
.	\}
.	ds doc-tmp1 No
.	nr doc-tmp-2 \\w^G\\*[doc-anchortext]^G
.	nr doc-tmp-2 \\n[doc-tmp-2]/\\w'0'
.	if \\n[doc-tmp-2]>=30 .ds doc-tmp1 D1
.	\\*[doc-tmp1] \\*[doc-anchor]
..
.
.\".de mailto
.\"<a href="mailto:\\$1">\\$1</a>\\$2\\$3\\$4
.\"..
.
.de Ht
\\$*
..
.de Sh
.	end-preformat
.	init-html
	<h3 id="\\$*">
	\\$*
	</h3>
..
.de Ss
.	end-preformat
.	init-html
	<h4 id="\\$*">
	\\$*
	</h4>
..
.
.de Sx
.	end-preformat
.	ds doc-tmp-1 "\\$1
.	shift
.	while \\n[.$] \{\
.		doc-checkpunct \\$1 \\*[doc-punct]
.		ie !\\n[doc-ispunct] .as doc-tmp-1 " \\$1
.		el .break
.		shift
.	\}
<a href="#\\*[doc-tmp-1]">\\*[doc-tmp-1]</a>\\$1\\$2\\$3\\$4\\$5\\$6
..
.
.de Pp
.	end-preformat
	<p>
..
.
.nr doc-markbreak 0
.de doc-conditional-break
.	if \\n[.c]>(\\n[doc-markbreak]+1) <br>
.	nr doc-markbreak \\n[.c]
..
.
.de D1
.	end-preformat
.	doc-conditional-break
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.	No \\$@
<br>
..
.
.de Dl
.	end-preformat
.	doc-conditional-break
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.	Li \\$@
<br>
..
.
.de Bd
.	doc-push .Ed
.	end-preformat
.	nr Bd-literal 0
.	nr Bd-offset 0
.	ds get-file
.	while \\n(.$ \{\
.		if '\\$1'-literal' \{\
.			nr Bd-literal 1
.			shift
.			continue
.		\}
.		if '\\$1'-offset' \{\
.			shift
.			shift
.			nr Bd-offset 1
.			ds start-display <dl compact><dt><dd>
.			continue
.		\}
.		if '\\$1'-file' \{\
.			ds get-file so \\$2
.			shift
.			shift
.			continue
.		\}
.		shift
.	\}
.	if \\n[Bd-offset] <dl compact><dt><dd>
.	if \\n[Bd-literal] <code>
<pre>\\" HOW DO WE GET RID OF THIS NEWLINE??
.\\*[get-file]
..
.de Ed
.	DEBUG .tm Ed
</pre>
.	doc-pop .Ed
.	if \\n[Bd-literal] </code>
.	if \\n[Bd-offset] </dl>
..
.de Bl
.	doc-push .El
.	end-preformat
.	ds list-start UNKNOWN
.	nr bl-is-compact 0
.	while \\n(.$ \{\
.		if '\\$1'-width' \{\
.			shift
.			shift
.			continue
.		\}
.		if '\\$1'-column' \{\
.			ds list-start <center><table>
.			ds list-end </table></center>
.			ds list-tag-prefix <tr><td>
.			ds list-pp-prefix
.			shift
.			break
.		\}
.		if '\\$1'-bullet' \{\
.			ds list-start <ul>
.			ds list-end </ul>
.			ds list-tag-prefix <p>
.			ds list-pp-prefix <li>
.			shift
.			continue
.		\}
.		if '\\$1'-dash' \{\
.			ds list-start <dl>
.			ds list-end   </dl>
.			ds list-tag-prefix <p>
.			ds list-pp-prefix <dd>-
.			shift
.			continue
.		\}
.		if '\\$1'-enum' \{\
.			ds list-start <ol>
.			ds list-end   </ol>
.			ds list-tag-prefix <p>
.			ds list-pp-prefix <li>
.			shift
.			continue
.		\}
.		if '\\$1'-nested' \{\
.			\" this should suffice
.			shift
.			continue
.		\}
.		if '\\$1'-hyphen' \{\
.			ds list-start <dl>
.			ds list-end   </dl>
.			ds list-tag-prefix <p>
.			ds list-pp-prefix <dd>-
.			shift
.			continue
.		\}
.		if '\\$1'-item' \{\
.			ds list-start <dl>
.			ds list-end   </dl>
.			ds list-tag-prefix <p>
.			ds list-pp-prefix <dd>
.			shift
.			continue
.		\}
.		if '\\$1'-tag' \{\
.			ds list-start <dl compact>
.			ds list-end   </dl>
.			ds list-tag-prefix <p><dt>
.			ds list-pp-prefix <dd>
.			shift
.			continue
.		\}
.		if '\\$1'-diag' \{\
.			ds list-start <dl compact>
.			ds list-end   </dl>
.			ds list-tag-prefix <p><dt>
.			ds list-pp-prefix <dd>
.			shift
.			continue
.		\}
.		if '\\$1'-hang' \{\
.			ds list-start <dl compact>
.			ds list-end   </dl>
.			ds list-tag-prefix <p><dt>
.			ds list-pp-prefix <dd>
.			shift
.			continue
.		\}
.		if '\\$1'-ohang' \{\
.			ds list-start <dl>
.			ds list-end   </dl>
.			ds list-tag-prefix <p><dt>
.			ds list-pp-prefix <dd>
.			shift
.			continue
.		\}
.		if '\\$1'-offset' \{\
.			\" FIXME -- this isn't implemented
.			shift
.			shift
.			continue
.		\}
.		if '\\$1'-compact' \{\
.			nr bl-is-compact 1
.			shift
.			continue
.		\}
.		if '\\$1'-inset' \{\
.			ds list-start <dl>
.			ds list-end   </dl>
.			ds list-tag-prefix <p><dt>
.			ds list-pp-prefix <dd>
.			shift
.			continue
.		\}
.		ab Unknown .Bl list parameter \\$1 (#\\n(.c)
.		break
.	\}
.	if \\n[bl-is-compact] \{\
.		if '\\*[list-tag-prefix]'<p>' .ds list-tag-prefix
.		if '\\*[list-tag-prefix]'<p><dt>' .ds list-tag-prefix <dt>
.	\}
.	if '\\*[list-start]'UNKNOWN' .ab \
Unknown .Bl list type \\$1 (#\\n(.c)
.	push-list-level start end tag-prefix pp-prefix
\\*[list-start]
..
.de push-list-level
.	nr list-level +1
.	while \\n(.$ \{\
.		ds list-\\$1-\\n[list-level] \\*[list-\\$1]
.		shift
.	\}
..
.de pop-list-level
.	nr list-level -1
..
.de It-span
.	end-preformat
.	as doc-pcresult <tr><td colspan=9>
.	recurse \\$@
.	as doc-pcresult
.	pc-fin
..
.de It
.	end-preformat
.	as doc-pcresult \\*[list-tag-prefix-\\n[list-level]]
.	recurse \\$@
.	as doc-pcresult \\*[list-pp-prefix-\\n[list-level]]
.	pc-fin
..
.de El
.	doc-pop .El
\\*[list-end-\\n[list-level]]
.	pop-list-level
..
.de Lb  
.if !\\n(.$==1 .tm Usage: .Lb [library name]
.if "\\$1"libarm32" \&ARM32 Architecture Library (libarm32, -larm32)
.if "\\$1"libbluetooth" \&Bluetooth Library (libbluetooth, -lbluetooth)
.if "\\$1"libc" \&Standard C Library (libc, -lc)
.if "\\$1"libcdk" \&Curses Development Kit Library (libcdk, -lcdk)
.if "\\$1"libcompat" \&Compatibility Library (libcompat, -lcompat)
.if "\\$1"libcrypt" \&Crypt Library (libcrypt, -lcrypt)
.if "\\$1"libcurses" \&Curses Library (libcurses, -lcurses)
.if "\\$1"libedit" \&Command Line Editor Library (libedit, -ledit)
.if "\\$1"libevent" \&Event Notification Library (libevent, -levent)
.if "\\$1"libform" \&Curses Form Library (libform, -lform)
.if "\\$1"libi386" \&i386 Architecture Library (libi386, -li386)
.if "\\$1"libintl" \&Internationalized Message Handling Library (libintl, -lintl)
.if "\\$1"libipsec" \&IPsec Policy Control Library (libipsec, -lipsec)
.if "\\$1"libisns" \&Internet Storage Name Service Library (libisns, -lisns)
.if "\\$1"libkvm" \&Kernel Data Access Library (libkvm, -lkvm)
.if "\\$1"libm" \&Math Library (libm, -lm)
.if "\\$1"libm68k" \&m68k Architecture Library (libm68k, -lm68k)
.if "\\$1"libmagic" \&Magic Number Recognition Library (libmagic, -lmagic)
.if "\\$1"libmenu" \&Curses Menu Library (libmenu, -lmenu)
.if "\\$1"libossaudio" \&OSS Audio Emulation Library (libossaudio, -lossaudio)
.if "\\$1"libpanel" \&Curses Panel Library (libpanel, -lpanel)
.if "\\$1"libpcap" \&Packet Capture Library (libpcap, -lpcap)
.if "\\$1"libpci" \&PCI Bus Access Library (libpci, -lpci)
.if "\\$1"libpmc" \&Performance Counters Library (libpmc, -lpmc)
.if "\\$1"libposix" \&POSIX Compatibility Library (libposix, -lposix)
.if "\\$1"libpthread" \&POSIX Thread Library (libpthread, -lpthread)
.if "\\$1"libpthread_dbg" \&POSIX Debug Thread Library (libpthread_dbg, -lpthread_dbg)
.if "\\$1"libresolv" \&DNS Resolver Library (libresolv, -lresolv)
.if "\\$1"librt" \&POSIX Real-time Library (librt, -lrt)
.if "\\$1"libsaslc" \&Simple Authentication and Security Layer client library (libsaslc, -lsaslc)
.if "\\$1"libtermcap" \&Termcap Access Library (libtermcap, -ltermcap)
.if "\\$1"libusbhid" \&USB Human Interface Devices Library (libusbhid, -lusbhid)
.if "\\$1"libutil" \&System Utilities Library (libutil, -lutil)
.if "\\$1"libz" \&Compression Library (libz, -lz) 
.. 
.
.
.de doc-checkpunct
.	ds doc-cp-tmp1 \\$1
.	shift
.	nr doc-ispunct 0
.	while \\n[.$] \{\
.		if \\*[doc-cp-tmp1]\\$1 .nr doc-ispunct 1
.		shift
.	\}
..
.\"
.\" Parsed and Callable macros
.\"
.\" Internal structure: `recurse' and `mode-*-{on,off}'
.\"
.de recurse
.	nr r-lvl +1
.DEBUG .tm r \\n[r-lvl] __\\*[doc-pcresult]==\\$@__
.	while \\n(.$ \{\
.		doc-checkpunct \\$1 \\*[doc-punct]
.		if \\n[doc-ispunct] \{\
.			as doc-punct-result \\$1
.			shift
.			continue
.		\}
.		nr is-request \\A'\\$1'
.		if \\n[is-request] \{\
.			if ddoc2html@@\\$1 .nr is-request 1
.			if !ddoc2html@@\\$1 .nr is-request 0
.		\}
.		ie \\n[is-request] \{\
.			ds recurse-tmp1 \\$1
.			shift
.			\\*[recurse-tmp1] \\$@
.			break
.		\}
.		el \{\
.DEBUG .tm r \\n[r-lvl] __\\*[doc-pcresult]+\\$1==\\$@__
.			\" a random word, so output saved punctuation
.			\" (normally saved until level 0 mode closure )
.			if \\w\\*[doc-pcresult] \{\
.				as doc-pcresult \\*[close-mode]
.				as doc-pcresult \\*[doc-punct-result]
.				as doc-pcresult \\*[open-mode]
.				ds doc-punct-result
.			\}
.			if \\n[doc-dosep] .as doc-pcresult \\*[sepstring]
.			nr doc-dosep 1
.			as doc-pcresult \\$1
.			shift
.			continue
.		\}
.	\}
.	nr r-lvl -1
..
.
.de resetmode
.	ds open-mode
.	ds close-mode
..
.
.de make-mode
\\*[dot-de] mode-\\$1-on
.	DEBUG .tm mode-\\$1-on <\\\\$@>
.	rn close-mode xclose-mode
.	ds open-mode \\$2
.	ds close-mode \\$3
.	as doc-pcresult \\\\*[xclose-mode]\\$2
\\*[dot-dot]
\\*[dot-de] mode-\\$1-off
.	DEBUG .tm mode-\\$1-off <\\\\$@>
.	as doc-pcresult \\\\*[close-mode]
.	resetmode
\\*[dot-dot]
..
.de pc-fin
.	as doc-pcresult \\$1
.	if \\n[r-lvl]=0 \{\\*[doc-pcresult]\\*[doc-punct-result]
.		ds doc-punct-result
.		rm doc-pcresult
.		ds sepstring \~
.		nr doc-dosep 0
.	\}
..
.
.make-mode bold <b> </b>
.make-mode code <code> </code>
.make-mode em <em> </em>
.make-mode i <i> </i>
.make-mode caps <font\ size="-1"> </font>
.make-mode null \& \&
.make-mode function <code> </code>
.am mode-i-on
.	ds sepstring \~
..
.am mode-em-on
.	ds sepstring \~
..
.am mode-i-off
.	ds sepstring \~
..
.am mode-em-off
.	ds sepstring \~
..
.
.de doc-sep-append
.	if \\n[doc-dosep] .as doc-pcresult \~
.	as doc-pcresult \\$1
.	nr doc-dosep 0
..
.de No
.	as doc-pcresult \\*[close-mode]
.	resetmode
.	recurse \\$@
.	pc-fin
..
.de Fl
.DEBUG .tm .Fl \\$*
.	mode-bold-on
.	doc-sep-append \-
.	recurse \\$@
.	mode-bold-off
.	pc-fin
..
.de Cm
.DEBUG .tm .Cm \\$*
.	mode-bold-on
.	recurse \\$@
.	mode-bold-off
.	pc-fin
..
.de Op
.DEBUG .tm .Op \\$*
.	as doc-pcresult \&[
.	recurse \\$@
.	pc-fin \&]
..
.de Em
.DEBUG .tm .Em \\$*
.	mode-em-on
.	recurse \\$@
.	mode-em-off
.	pc-fin
..
.de Fx
.DEBUG .tm .Fx \\$*
.	as doc-pcresult FreeBSD
.	recurse \\$@
.	pc-fin
..
.de Nm
.	ds Nm-result \\*[Nm-save]
.	if \\n(.$ \{\
.		ie '\\$1'' .br-real
.		el \{\
.			ds Nm-result \\$1
.			if '\\*[Nm-save]'' .ds Nm-save \\$1
.			shift
.		\}
.	\}
.	mode-bold-on
.	as doc-pcresult \\*[Nm-result]
.	recurse \\$@
.	mode-bold-off
.	pc-fin
..
.de Nd
.DEBUG .tm .Nd \\$*
- \\$*
..
.de At
AT&T UNIX\\$*
..
.de An
.	if '\\$1'-nosplit' \{\
.		ds an-eol
.		shift
.	\}
.	recurse \\$@
.	as doc-pcresult \\*[an-eol]
.	pc-fin
..
.\".de Lk
.\".	as doc-pcresult <a href="\\$1">\\$1</a>
.\".	shift
.\".	recurse \\$@
.\".	pc-fin
.\"..
.de Mt
.	as doc-pcresult <a href="mailto:\\$1">\\$1</a>
.	shift
.	recurse \\$@
.	pc-fin
..
.de Ta
.	as doc-pcresult <td>
.	recurse \\$@
.	pc-fin
..
.de Bx
.	doc-checkpunct \\$1 \\*[doc-punct]
.	if !\\n[doc-ispunct] \{\
.		as doc-pcresult \\$1
.		shift
.	\}
.	as doc-pcresult BSD
.	recurse \\$@
.	pc-fin
..
.de Nx
.	as doc-pcresult NetBSD
.	recurse \\$@
.	pc-fin
..
.de Ox
.	as doc-pcresult OpenBSD
.	recurse \\$@
.	pc-fin
..
.de Ux
.	as doc-pcresult UNIX
.	recurse \\$@
.	pc-fin
..
.de Ql
.	as doc-pcresult `
.	recurse \\$@
.	pc-fin \&'
..
.de Pf
.	as doc-pcresult \\$1
.	shift
.	nr doc-dosep 0
.	recurse \\$@
.	pc-fin
..
.de Ns
.	nr doc-dosep 0
.	mode-null-on
.	recurse \\$@
.	mode-null-off
.	pc-fin
..
.
.de doc-start-quote 
.	if \\n[r-lvl]&\\n[doc-dosep] .as doc-pcresult \\*[sepstring]
.	as doc-pcresult \\$1
.	nr doc-dosep 0
..
.
.de safe-blm
..
.
.nr quote-level 0
.de doc-quote-open
.	nr quote-level +1
.	blm safe-blm
.	if \\n[r-lvl]&\\n[doc-dosep] .as doc-pcresult \\*[sepstring]
.	nr doc-dosep 0
.	ie \\n[quote-level]=1 \{\
.		ev quotation_ev
.		di quotation
.		br-real
.		nr quotation_line \\n[.c]
.	\}
.	el \{\
.		di
.		as quotation \\$1
.		da quotation
.	\}
..
.
.de general-close
.	nr quote-level -1
.	if \\w\\n[.z]=0 .Error no quotation is open
.	br-real
.	if \\n[quote-level]=0 \{\
.		di
.		ev
.		ev quotation_ev
.		br-real
.		da quotation
.		nf-real
.
.		di
.		ev
.		as doc-pcresult \\$1\\*[quotation]\\
.		blm Pp
.	\}
.
.
..
.
.de make-quoter
\\*[dot-de] \\$1o
.	doc-quote-open \\$2
.	recurse \\\\$@
.	pc-fin
\\*[dot-dot]
\\*[dot-de] \\$1c
.	DEBUG .tm CLOSE 1,\\\\$@,
.	general-close \\$2
.	DEBUG .tm CLOSE 2,\\\\$@,\\$3,
.	recurse \\\\$@ \\$3
.	pc-fin
\\*[dot-dot]
\\*[dot-de] \\$1q
.	doc-start-quote \\$2
.	recurse \\\\$@
.	pc-fin \\$3
\\*[dot-dot]
..
.
.\" generate Aq Ao Ac Bq Bo Bc Brq Bro Brc Dq Do Dc
.\"	Pq Po Pc Qq Qo Qc Sq So Sc Oo Oc
.make-quoter A &lt; &gt;
.make-quoter B \&[ ]
.make-quoter Br \&{ }
.make-quoter D \&`` ''
.make-quoter P \&( )
.make-quoter Q \&" "
.make-quoter S \&` '
.als Oo Bo
.als Oc Bc
.de Error
.	ab Line \\n[.c], Error: \\$*
..
.de Ft
.	as doc-pcresult <br><br>
.	mode-code-on
.	recurse \\$@
.	mode-code-off
.	pc-fin
..
.de Fn
.	mode-bold-on
.	as doc-pcresult "\\$1
.	shift
.	mode-bold-off
.	as doc-pcresult (
.	mode-function-on
.	ds sepstring , \" (need the space)
.	recurse \\$@
.	as doc-pcresult \\*[close-mode])
.	resetmode
.	pc-fin
..
.de Fo
.	mode-bold-on
.	as doc-pcresult "\\$1
.	shift
.	mode-bold-off
.	as doc-pcresult (
.	mode-code-on
.	recurse \\$@
.	mode-code-off
.	pc-fin
..
.de Fc
.	recurse \\$@
.	pc-fin )
..
.de Ar
.	mode-i-on
.	recurse \\$@
.	mode-i-off
.	pc-fin
..
.de Ic
.	mode-bold-on
.	recurse \\$@
.	mode-bold-off
.	pc-fin
..
.de Fa
.	mode-code-on
.	recurse \\$@
.	mode-code-off
.	pc-fin
..
.de Xr
.	nr have-sec 0
.	if \\$21 .nr have-sec 1
.	if \\$22 .nr have-sec 1
.	if \\$23 .nr have-sec 1
.	if \\$24 .nr have-sec 1
.	if \\$25 .nr have-sec 1
.	if \\$26 .nr have-sec 1
.	if \\$27 .nr have-sec 1
.	if \\$28 .nr have-sec 1
.	if \\$29 .nr have-sec 1
.	ie \\n[DOC_XR]:(\\n[have-sec]=0) \{\
.		mode-code-on
.		ie \\n[have-sec]=0 .as doc-pcresult \\$1
.		el .as doc-pcresult \\$1(\\$2)
.		mode-code-off
.	\}
.	el \{\
.		ds Xr-tmp \\$1
.		if \\*[Xr-tmp]index .ds Xr-tmp xindex
.		as doc-pcresult <a href="\\*[DOC_MANROOT]/html\\$2/\\$1.html">
.		ie \\w\\$2=0 .as doc-pcresult \\$1
.		el .as doc-pcresult \\$1(\\$2)
.		as doc-pcresult </a>
.	\}
.	shift
.	shift
.	recurse \\$@
.	pc-fin
..
.de Dv
.	mode-code-on
.	recurse \\$@
.	mode-code-off
.	pc-fin
..
.de Ic
.	mode-bold-on
.	recurse \\$@
.	mode-bold-off
.	pc-fin
..
.de Pa
.	mode-code-on
.	recurse \\$@
.	mode-code-off
.	pc-fin
..
.de Tn
.	mode-caps-on
.	recurse \\$@
.	mode-caps-off
.	pc-fin
..
.de Fd
.	as doc-pcresult <br>
.	mode-bold-on
.	recurse \\$@
.	mode-bold-off
.	pc-fin
..
.de Va
.	mode-i-on
.	recurse \\$@
.	mode-i-off
.	pc-fin
..
.de Li
.	mode-code-on
.	recurse \\$@
.	mode-code-off
.	pc-fin
..
.de Sy
.	mode-bold-on
.	recurse \\$@
.	mode-bold-off
.	pc-fin
..
.de Me
.	mode-bold-on
.	recurse \\$@
.	mode-bold-off
.	pc-fin
..
.de Ev
.	mode-code-on
.	recurse \\$@
.	mode-code-off
.	pc-fin
..
.de Cd
.	mode-bold-on
.	recurse \\$@
.	mode-bold-off
.	pc-fin
..
.ig
	I used to have a caps-code mode for Er. But <code> apparently
	already implies a small mode or maybe actually small caps mode.
..
.de Er
.	mode-code-on
.	recurse \\$@
.	mode-code-off
.	pc-fin
..
.de St
.	ie \\n(.$==0 \{\
.		tm The .St (expand standard name) macro requires >= 1 arg
.	\}
.	el \{\
.		ds std-tmp1 ERROR
.\" ANSI/ISO C
.		if "\\$1"-ansiC" \{\
.			ds std-tmp1 \&ANSI X3.159-1989
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``ANSI C89'')
.		\}
.		if "\\$1"-ansiC-89" \{\
.			ds std-tmp1 \&ANSI X3.159-1989
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``ANSI C89'')
.		\}
.		if "\\$1"-isoC" \{\
.			ds std-tmp1 \&ISO/IEC 9899:1990
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``ISO C90'')
.		\}
.		if "\\$1"-isoC-90" \{\
.			ds std-tmp1 \&ISO/IEC 9899:1990
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``ISO C90'')
.		\}
.		if "\\$1"-isoC-amd1" \{\
.			ds std-tmp1 \&ISO/IEC 9899/AMD1:1990
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``ISO C90'')
.		\}
.		if "\\$1"-isoC-tcor1" \{\
.			ds std-tmp1 \&ISO/IEC 9899/TCOR1:1990
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``ISO C90'')
.		\}
.		if "\\$1"-isoC-tcor2" \{\
.			ds std-tmp1 \&ISO/IEC 9899/TCOR2:1990
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``ISO C90'')
.		\}
.		if "\\$1"-isoC-99" \{\
.			ds std-tmp1 \&ISO/IEC 9899:1999
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``ISO C99'')
.		\}
.		if "\\$1"-isoC-2011" \{\
.			ds std-tmp1 \&ISO/IEC 9899:2011
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``ISO C11'')
.		\}
.\" POSIX Part 1: System API
.		if "\\$1"-p1003.1" \{\
.			ds std-tmp1 \&IEEE Std 1003.1
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-p1003.1-88" \{\
.			ds std-tmp1 \&IEEE Std 1003.1-1988
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-p1003.1-90" \{\
.			ds std-tmp1 \&ISO/IEC 9945-1:1990
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-iso9945-1-90" \{\
.			ds std-tmp1 \&ISO/IEC 9945-1:1990
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-p1003.1b-93" \{\
.			ds std-tmp1 \&IEEE Std 1003.1b-1993
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-p1003.1c-95" \{\
.			ds std-tmp1 \&IEEE Std 1003.1c-1995
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-p1003.1i-95" \{\
.			ds std-tmp1 \&IEEE Std 1003.1i-1995
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-p1003.1-96" \{\
.			ds std-tmp1 \&ISO/IEC 9945-1:1996
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-iso9945-1-96" \{\
.			ds std-tmp1 \&ISO/IEC 9945-1:1996
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-p1003.1g-2000" \{\
.			ds std-tmp1 \&IEEE Std 1003.1g-2000
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-p1003.1-2001" \{\
.			ds std-tmp1 \&IEEE Std 1003.1-2001
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-p1003.1-2004" \{\
.			ds std-tmp1 \&IEEE Std 1003.1-2004
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.		if "\\$1"-p1003.1-2008" \{\
.			ds std-tmp1 \&IEEE Std 1003.1-2008
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.1'')
.		\}
.\" POSIX Part 2: Shell and Utilities
.		if "\\$1"-p1003.2" \{\
.			ds std-tmp1 \&IEEE Std 1003.2
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.2'')
.		\}
.		if "\\$1"-p1003.2-92" \{\
.			ds std-tmp1 \&IEEE Std 1003.2-1992
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.2'')
.		\}
.		if "\\$1"-p1003.2a-92" \{\
.			ds std-tmp1 \&IEEE Std 1003.2a-1992
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.2'')
.		\}
.		if "\\$1"-iso9945-2-93" \{\
.			ds std-tmp1 \&ISO/IEC 9945-2:1993
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(Px.2'')
.		\}
.\" X/Open
.		if "\\$1"-susv2" \{\
.			ds std-tmp1 \&Version 2 of the Single UNIX Specification
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``SUSv2'')
.		\}
.		if "\\$1"-svid4" \{\
.			ds std-tmp1 \&System V Interface Definition,
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 \&Fourth Edition
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``SVID4'')
.		\}
.		if "\\$1"-xbd5" \{\
.			ds std-tmp1 X/Open System Interface Definitions Issue 5
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(tNXBD5\\*(aa'')
.		\}
.		if "\\$1"-xcu5" \{\
.			ds std-tmp1 X/Open Commands and Utilities Issue 5
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(tNXCU5\\*(aa'')
.		\}
.		if "\\$1"-xcurses4.2" \{\
.			ds std-tmp1 X/Open Curses, Issue 4, Version 2
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(tNXCURSES4.2\\*(aa'')
.		\}
.		if "\\$1"-xns5" \{\
.			ds std-tmp1 X/Open Networking Services Issue 5
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(tNXNS5\\*(aa'')
.		\}
.		if "\\$1"-xns5.2" \{\
.			ds std-tmp1 X/Open Networking Services Issue 5.2
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(tNXNS5.2\\*(aa'')
.		\}
.		if "\\$1"-xpg3" \{\
.			ds std-tmp1 X/Open Portability Guide Issue 3
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``XPG3'')
.		\}
.		if "\\$1"-xpg4" \{\
.			ds std-tmp1 X/Open Portability Guide Issue 4
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``XPG4'')
.		\}
.		if "\\$1"-xpg4.2" \{\
.			ds std-tmp1 X/Open Portability Guide Issue 4, Version 2
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``XPG4.2'')
.		\}
.		if "\\$1"-xsh5" \{\
.			ds std-tmp1 X/Open System Interfaces and Headers Issue 5
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``\\*(tNXSH5\\*(aa'')
.		\}
.\" Miscellaneous
.		if "\\$1"-ieee754" \{\
.			ds std-tmp1 \&IEEE Std 754-1985
.		\}
.		if "\\$1"-ieee1275-94" \{\
.			ds std-tmp1 \&IEEE Std 1275-1994
.			as std-tmp1 " \"exactly one space
.			as std-tmp1 (``Open Firmware'')
.		\}
.		if "\\$1"-iso8802-3" \{\
.			ds std-tmp1 \&ISO/IEC 8802-3:1989
.		\}
.		if "\\*[std-tmp1]"ERROR" .Error no such std: .St \\$*
.		shift
.		as doc-pcresult \~\\*[std-tmp1]\~
.		recurse \\$@
.		pc-fin
.	\}
..
.ig
	I've observed that <code> does decent things with caps, and it should
	be reminiscent of the old typewriter-style unix logos.
..
.de At
.   if \\n(.$==2 \{\
.	if "\\$1"32v" Version 32V <code>AT&T UNIX</code>\\$2
.	if "\\$1"V"  \<code>AT&T</code> System V <code>UNIX</code>\\$2
.	if "\\$1"V.1"  <code>AT&T</code> System V.1 <code>UNIX</code>\\$2
.	if "\\$1"V.2"  <code>AT&T</code> System V.2 <code>UNIX</code>\\$2
.	if "\\$1"V.3"  <code>AT&T</code> System V.3 <code>UNIX</code>\\$2
.	if "\\$1"V.4"  <code>AT&T</code> System V.4 <code>UNIX</code>\\$2
.	if "\\$1"v1"  Version 1 <code>AT&T UNIX</code>\\$2
.	if "\\$1"v5"  Version 5 <code>AT&T UNIX</code>\\$2
.	if "\\$1"v6"  Version 6 <code>AT&T UNIX</code>\\$2
.	if "\\$1"v7"  Version 7 <code>AT&T UNIX</code>\\$2
.   \}
.   if \\n(.$==1 \{\
.	if "\\$1"32v" Version 32V <code>AT&T UNIX</code>
.	if "\\$1"V"  <code>AT&T</code> System V <code>UNIX</code>
.	if "\\$1"V.1"  <code>AT&T</code> System V.1 <code>UNIX</code>
.	if "\\$1"V.2"  <code>AT&T</code> System V.2 <code>UNIX</code>
.	if "\\$1"V.3"  <code>AT&T</code> System V.3 <code>UNIX</code>
.	if "\\$1"V.4"  <code>AT&T</code> System V.4 <code>UNIX</code>
.	if "\\$1"v1"  Version 1 <code>AT&T UNIX</code>
.	if "\\$1"v5"  Version 5 <code>AT&T UNIX</code>
.	if "\\$1"v6"  Version 6 <code>AT&T UNIX</code>
.	if "\\$1"v7"  Version 7 <code>AT&T UNIX</code>
.   \}
.   if \\n(.$==0 \{\
.	if 1 <code>AT&T UNIX</code>
.   \}
..
.\"----------------------------------------------------------------------
.\"
.\" There must be a doc2html alias for all callable macros
.\"
.als doc2html@@Dd Dd
.als doc2html@@Dt Dt
.als doc2html@@Os Os
.als doc2html@@br br
.als doc2html@@sp sp
.als doc2html@@fi fi
.als doc2html@@nf nf
.als doc2html@@Sh Sh
.als doc2html@@Ss Ss
.als doc2html@@Pp Pp
.als doc2html@@D1 D1
.als doc2html@@Dl Dl
.als doc2html@@Bd Bd
.als doc2html@@Ed Ed
.als doc2html@@Bl Bl
.als doc2html@@It It
.als doc2html@@El El
.als doc2html@@Fl Fl
.als doc2html@@Cm Cm
.als doc2html@@Op Op
.als doc2html@@Em Em
.als doc2html@@Fx Fx
.als doc2html@@Ox Ox
.als doc2html@@Nm Nm
.als doc2html@@Nd Nd
.als doc2html@@At At
.als doc2html@@Bx Bx
.als doc2html@@Nx Nx
.als doc2html@@Ux Ux
.als doc2html@@Ql Ql
.als doc2html@@Pf Pf
.als doc2html@@Ns Ns
.als doc2html@@Ft Ft
.als doc2html@@Fn Fn
.als doc2html@@Fo Fo
.als doc2html@@Fc Fc
.als doc2html@@Ar Ar
.als doc2html@@Ic Ic
.als doc2html@@Fa Fa
.als doc2html@@Xr Xr
.als doc2html@@Dv Dv
.als doc2html@@Ic Ic
.als doc2html@@Pa Pa
.als doc2html@@Tn Tn
.als doc2html@@Fd Fd
.als doc2html@@Va Va
.als doc2html@@Li Li
.als doc2html@@Sy Sy
.als doc2html@@Me Me
.als doc2html@@Ev Ev
.als doc2html@@Cd Cd
.als doc2html@@St St
.als doc2html@@Er Er
.als doc2html@@Aq Aq
.als doc2html@@Ao Ao
.als doc2html@@Ac Ac
.als doc2html@@Bq Bq
.als doc2html@@Bo Bo
.als doc2html@@Bc Bc
.als doc2html@@Brq Brq
.als doc2html@@Bro Bro
.als doc2html@@Brc Brc
.als doc2html@@Dq Dq
.als doc2html@@Do Do
.als doc2html@@Dc Dc
.als doc2html@@Qq Qq
.als doc2html@@Qo Qo
.als doc2html@@Qc Qc
.als doc2html@@Pq Pq
.als doc2html@@Po Po
.als doc2html@@Pc Pc
.als doc2html@@Sq Sq
.als doc2html@@So So
.als doc2html@@Sc Sc
.als doc2html@@Oo Oo
.als doc2html@@Oc Oc
.als doc2html@@Ta Ta
.als doc2html@@Mt Mt
.als doc2html@@Lk Lk
.als doc2html@@No No
.als doc2html@@An An
.
.rn em doc-real-em
.de em
.	tm Hint: Should this have been .Em ...?
.	Error end-macro (.em) respecification is not allowed.
..
.
.ig
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
	THESE ARE THE -man (-man.old) MACRO FUNCTIONS
	Internal symbols relating to -man are prefixed with mo-
	The body-params string used with -mdoc2html is used here as well.
..
.de TH
.	init-html \\$@
.	nr mo-section \\$2
..
.de SH
.	end-preformat
.	mo-end-dl
<h3 id="\\$*"> \\$* </h3>
..
.de SS
.	end-preformat
.	mo-end-dl
<h4 id="\\$*"> \\$* </h4>
..
.de B
.	ie \\n(.$ <b>\&\\$*</b>
.	el \{\
.		if 1 <b>
.		it 1 mo-end-bold
.	\}
..
.de I
.	ie \\n(.$ <i>\&\\$*</i>
.	el \{\
.		if 1 <i>
.		it 1 mo-end-italic
.	\}
..
.de mo-end-bold
</b>
..
.de mo-end-italic
</i>
..
.de SM
<font size=-1>
.	it 1 mo-end-smallcaps
.	if \\n(.$ \&\\$*
..
.de mo-end-smallcaps
</font>
..
.de BI
.	mo-try-link \\$1 \\$2
.	if !\\n[mo-did-link] \{\
.		ds mo-bi-tmp1
.		while \\n(.$>=2 \{\
.			as mo-bi-tmp1 <b>\\$1</b><i>\\$2</i>
.			shift
.			shift
.		\}
.		as mo-bi-tmp1 \\$*
\&\\*[mo-bi-tmp1]
.	\}
..
.de BR
.	mo-try-link \\$1 \\$2
.	if !\\n[mo-did-link] \{\
.		ds mo-bi-tmp1
.		while \\n(.$>=2 \{\
.			as mo-bi-tmp1 <b>\\$1</b>\\$2
.			shift
.			shift
.		\}
.		as mo-bi-tmp1 \\$*
\&\\*[mo-bi-tmp1]
.	\}
..
.de IB
.	mo-try-link \\$1 \\$2
.	if !\\n[mo-did-link] \{\
.		ds mo-bi-tmp1
.		while \\n(.$>=2 \{\
.			as mo-bi-tmp1 <i>\\$1</i><b>\\$2</b>
.			shift
.			shift
.		\}
.		as mo-bi-tmp1 \\$*
\&\\*[mo-bi-tmp1]
.	\}
..
.de IR
.	mo-try-link \\$1 \\$2
.	if !\\n[mo-did-link] \{\
.		ds mo-bi-tmp1
.		while \\n(.$>=2 \{\
.			as mo-bi-tmp1 <i>\\$1</i>\\$2
.			shift
.			shift
.		\}
.		as mo-bi-tmp1 \\$*
\&\\*[mo-bi-tmp1]
.	\}
..
.de CT
\&&lt;<font size=-1>CTRL/</font>\\$*&gt;
..
.de DS
<code><pre>
..
.de DE
.	DEBUG .tm DE
</pre></code>
..
.als Ds DS
.als De DE
.als EX DS
.als EE DE
.de TP
.	mo-start-dl
<dt>
.	it 1 mo-dd
..
.de IP
.	mo-start-dl
<dt>
<b>\\$1</b>
.	it 1 mo-dd
..
.de mo-start-dl
.	end-preformat
.	if !\\n[mo-in-dl] <dl compact>
.	nr mo-in-dl 1
..
.de mo-dd
<dd>
..
.de mo-end-dl
.	if \\n[mo-in-dl] </dl>
.	nr mo-in-dl 0
..
.de P
.	end-preformat
.	mo-end-dl
<p>
..
.als PP P
.als LP P
.de mo-try-link
.	nr mo-did-link 0
.	if \\A'\\$2' \{\
.		if \\w'\\*[\\$2]' \{\
.			Xr \\$1 \\*[\\$2]
.			nr mo-did-link 1
.		\}
.	\}
..
.ds (1) 1
.ds (2) 2
.ds (3) 3
.ds (4) 4
.ds (5) 5
.ds (6) 6
.ds (7) 7
.ds (8) 8
.ds (9) 9
.ds (1), 1
.ds (2), 2
.ds (3), 3
.ds (4), 4
.ds (5), 5
.ds (6), 6
.ds (7), 7
.ds (8), 8
.ds (9), 9
.ds (1). 1
.ds (2). 2
.ds (3). 3
.ds (4). 4
.ds (5). 5
.ds (6). 6
.ds (7). 7
.ds (8). 8
.ds (9). 9
