[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[groff] 01/03: Factor document-specific bloat out of spdf.tmac
From: |
Keith Marshall |
Subject: |
[groff] 01/03: Factor document-specific bloat out of spdf.tmac |
Date: |
Mon, 13 Sep 2021 17:29:50 -0400 (EDT) |
keithmarshall pushed a commit to branch master
in repository groff.
commit 2811e46d28b7a410a032298f11bd9d19c31e060c
Author: Keith Marshall <keith.d.marshall@ntlworld.com>
AuthorDate: Mon Sep 13 21:18:00 2021 +0100
Factor document-specific bloat out of spdf.tmac
* spdf.tmac: Reorganize; add many comments.
(XN): Retained, but reimplemented, to serve as...
(XH, XN): ...both of these; add callback hooks for...
(XH-INIT, XN-INIT, XH-UPDATE-TOC): ...these; provide no-op stubs;
factor out TOC collection code, delegating to XH-UPDATE-TOC.
(opt*XN-N, opt*XN-S, opt*XN-X): Rename internal macros to...
(de spdf:XH-N, de spdf:XH-S, de spdf:XH-X): ...these, respectively.
(AN, @AN, IE, IS, LU, NN, PXREF, SAME-PAGE, XM): Delete; we do not
require these; if users do, they should define their own.
(pdf@toc): Delete internal macro; fold body into...
(TC): ...this.
* pdfmark.ms (XH-UPDATE-TOC): Implement callback; it is based on...
(XN): ...original implementation of this, factored out of spdf.tmac,
but with significant simplification, to remove unnecessary code.
(XNVS1, XNVS2, XNVS3): Tighten vertical spacing.
---
contrib/pdfmark/pdfmark.ms | 94 ++++++++---
contrib/pdfmark/spdf.tmac | 396 ++++++++++++++++++++++++++++-----------------
2 files changed, 321 insertions(+), 169 deletions(-)
diff --git a/contrib/pdfmark/pdfmark.ms b/contrib/pdfmark/pdfmark.ms
index 2abe022..58dd74d 100644
--- a/contrib/pdfmark/pdfmark.ms
+++ b/contrib/pdfmark/pdfmark.ms
@@ -103,31 +103,87 @@ Publishing with GNU Troff
.ds = \f(CB\\$1\f(CR\\$4\f[CBI]\\$2\f(CR\\$3
.
.NH 1
-.\" When we use numbered section headings, we might like to automatically
-.\" insert a table of contents entry, using the text of the heading itself.
-.\" The "ms" macros don't provide any standard mechanism for doing this,
-.\" but "spdf.tmac" adds the "XN" macro, which will do it for us.
+.\" Conventionally, in "ms", NH precedes text which is to be set as a
+.\" numbered section heading, but it makes no provision for automatic
+.\" reference to that heading in a table of contents, or (in the case
+.\" of PDF document production) in a document outline. Both of these
+.\" limitations may be mitigated, by using the XN macro, (provided by
+.\" spdf.tmac), which sets its arguments, both as text to be included
+.\" in the section heading, as printed, and as an assocated document
+.\" outline reference; it will also make this same text available to
+.\" the user-specified callback macro, XH-UPDATE-TOC, whereby it may
+.\" be used, e.g. to construct a table of contents entry.
.\"
-.\" Here's a simple example of how we might use it. In this case, the word
-.\" "Introduction" will appear both in the body of the document, as the text
-.\" of the heading, and it will be added to the table of contents, which is
-.\" subsequently "printed" using the "TC" macro; in both locations, it will
-.\" be prefixed by the section number.
+.\" Within the table of contents, structural layout will be achieved,
+.\" under the direction of the following spacing control constants:
.\"
-.\" As an additional side effect, any use of "XN" will cause the table of
-.\" contents entry to be automatically reproduced, with the exception of its
-.\" page number reference, as a PDF document outline entry. Thus, the use
-.\" of "XN" to specify numbered section headings results in the automatic
-.\" creation of a numbered PDF document outline. This automatic creation
-.\" of the outline is completely transparent, and will occur regardless
-.\" of whether the "TC" macro is subsequently invoked, or not.
+.ds XNVS1 0.50v \" leading for top level
+.ds XNVS2 0.15v \" leading at nesting level increment
+.ds XNVS3 0.30v \" leading following nested group
.\"
+.\" Note that one TOC related callback hook is shared by both XH and
+.\" XN; its is called XH-UPDATE-TOC, regardless of whether called by
+.\" XH or by XN; when called by XN, it is invoked with arguments:
+.\"
+.\" .XH-UPDATE-TOC <outline-level> <section-number> <text> ...
+.\"
+.de XH-UPDATE-TOC
+.\" This implementation of XH-UPDATE-TOC utilizes the rudimentary ms
+.\" mechanism for formatting a table of contents, using XS and XE to
+.\" bracket individual entries.
+. XS
+. \" A local register, tc*hl, is used to track the outline level
+. \" of each TOC entry, as it is added; it is not defined, until
+. \" the first entry is recorded...
+. \"
+. if r tc*hl \{\
+. \" ...after which, we use it to establish indentation,
+. \" to reflect changes in outline level.
+. \"
+. ie \\$1>1 \{\
+. \" When at any outline level greater than one,
+. \" any level increment will be offset by XNVS2
+. \" units of vertical space...
+. \"
+. ie \\$1>\\n[tc*hl] .sp \\*[XNVS2]
+.
+. \" ...whereas any decrement will be offset by
+. \" XNVS3 units.
+. \"
+. el .if \\n[tc*hl]>\\$1 .sp \\*[XNVS3]
+. \}
+.
+. \" ...but every top-level entry, after the first, is
+. \" offset by XNVS1 units.
+. \"
+. el .sp \\*[XNVS1]
+. \}
+.
+. \" \$1 becomes the effective outline level for the current table
+. \" of contents entry, but we must ensure that it is one or more.
+. \"
+. ie \\$1 .nr tc*hl \\$1
+. el .nr tc*hl 1
+.
+. \" The current outline level determines the indentation at which
+. \" we place the section number reference...
+. \"
+. nop \h'\\n[tc*hl]-1m'\\$2\c
+.
+. \" ...after which we discard \$1 and \$2, allowing us to append
+. \" all remaining arguments, ensuring that there is at least 0.5n
+. \" of following space, before the first leader dot.
+. \"
+. shift 2
+. nop \h'1.5n'\\$*\h'0.5n'
+. XE
+..
.XN Introduction
.\"
-.\" If using an old s.tmac, without the SN-NO-DOT extension,
-.\" make sure we get SOMETHING in section number references.
+.\" If using an old s.tmac, without the SN-NO-DOT extension, ensure
+.\" that we get SOMETHING in section number references.
.\"
-.if !dSN-NO-DOT .als SN-NO-DOT SN
+.if !d SN-NO-DOT .als SN-NO-DOT SN
.LP
It might appear that it is a fairly simple matter to
produce documents in \*[Adobe]\~\(lqPortable\~Document\~Format\(rq,
diff --git a/contrib/pdfmark/spdf.tmac b/contrib/pdfmark/spdf.tmac
index d807faf..454802b 100644
--- a/contrib/pdfmark/spdf.tmac
+++ b/contrib/pdfmark/spdf.tmac
@@ -2,6 +2,9 @@
spdf.tmac
+Binding macros for use of "-m pdfmark" in conjunction with "-ms".
+
+
Copyright (C) 2004-2021 Free Software Foundation, Inc.
Written by Keith Marshall (keith.d.marshall@ntlworld.com)
@@ -21,56 +24,144 @@ You should have received a copy of the GNU General Public
License
along with this program. If not, see <http://www.gnu.org/licenses/>.
..
+.\" Bindings
+.\" ========
+.\"
+.\" Generic output mode control flag; pdfmark.tmac will bind this to
+.\" its own internal PDFOPMODE flag.
.\"
-.if !rOPMODE .nr OPMODE 1
+.if !r OPMODE .nr OPMODE 1
.\"
.mso s.tmac
.mso sanitize.tmac
.mso pdfmark.tmac
+.
+.\" Establish a handler to clean up output context, at end of document.
.\"
+.de pdf@exit em
+. if \\n[OPMODE] .pdfsync
+. pg@end-text
+.em pdf@exit
+.
+.
.\" Omitted Sections
.\" ================
.\"
.\" Define section markers, for special document sections,
.\" which are to be omitted from regular document processing.
.\"
+.\" .OMIT <name1> <name2>
+.\"
+.\" Defines a pair of macros, <name1> and <name2>, such that execution
+.\" of .<name1> marks the start of a block of troff input which should
+.\" be ignored; this block ends, on execution of .<name2>
+.\"
.de OMIT OMIT
-.de \\$1
-.omit@begin \\$1 \\$2
-..
-.de \\$2
-.omit@end \\$1 \\$2
-..
+. de \\$1
+. omit@begin \\$1 \\$2
+. .
+. de \\$2
+. omit@end \\$1 \\$2
+. .
+.\" Definition of the OMIT macro itself, ends when it is first used,
+.\" to identify an omitted section marker macro pair.
+.\"
.OMIT CS CE \" front cover text, processed independently
.OMIT MS ME \" menu definitions, for info documents only
+.
+.\" Actual omission is initiated by recording the name of the block
+.\" start macro, followed by injection of an "ig" request...
.\"
.de omit@begin
-.ds omit@section \\$1
-.ig \\$2
+. ds omit@section \\$1
+\. ig \\$2
..
+.\" ...and terminates with verification that the end macro matches
+.\" the start macro, and removal of the start macro record; (error
+.\" reporting uses the "@error" macro, from s.tmac).
+.\"
.de omit@end
-.if !'\\*[omit@section]'\\$1' .@error \\$2 without \\$1
-.rm omit@section
+. if !'\\*[omit@section]'\\$1' .@error \\$2 without \\$1
+. rm omit@section
..
-.de XM
+.\" .XR <dest-name> [<affixed> [<prefix>]]
.\"
-.pdfhref M -X \\$@
-..
-.de XR
+.\" A convenience shorthand macro, emulating the semantics of the "ms"
+.\" font change macros, when invoked with one, two, or three arguments;
+.\" it expands to the equivalent of:
+.\"
+.\" .pdfhref L -D <dest-name> [-A <affixed> [-P <prefix>]]
+.\"
+.\" to place a pdfhref reference link, to a named destination, within
+.\" the same document, using the reference text which is predefined in
+.\" the reference dictionary entry associated with the destination.
+.\"
+.de XR \" FIXME: suggest document-local implementation
.if \\n(.$ \{\
. if \\n[OPMODE] \{\
-. ds spdf!opts -D "\\$1"
-. if \\n(.$>1 .as spdf!opts " -A "\\$2"
-. if \\n(.$>2 .as spdf!opts " -P "\\$3"
-. pdfhref L \\*[spdf!opts]
-. rm spdf!opts
+. ds xr!argv -D "\\$1"
+. if \\n(.$>1 .as xr!argv " -A "\\$2"
+. if \\n(.$>2 .as xr!argv " -P "\\$3"
+. pdfhref L \\*[xr!argv]
+. rm xr!argv
. \}
. \}
..
+.
+.\" Document Outlines, and Section Headings
+.\" =======================================
+.\"
+.\" .XH [-N <name>] [-S] [-X] <outline-level> <heading-text> ...
+.\" .XN [-N <name>] [-S] [-X] <heading-text> ...
+.\"
+.\" Use after SH, and XN <n> respectively, to define text to be set
+.\" within the section heading, as a PDF document ouline entry, and
+.\" optionally, as a table of contents entry.
.\"
-.\" Document Outlines, Section Headings and Table of Contents
-.\" =========================================================
+.\" Options:
+.\" -N <name> Assigns <name> as a pdfhref destination,
+.\" and associates it with the heading.
.\"
+.\" -S Strip troff font-change escapes from the
+.\" text copied to the document outline.
+.\"
+.\" -X Force pdfhref destination assignment; if
+.\" -N <name> is unspecified, use first word
+.\" of <heading-text> as <name>.
+.\"
+.\" Arguments:
+.\" <outline-level> The nesting level of the heading, within
+.\" the document outline, and TOC. Required
+.\" for XH; inferred from NH <n>, for XN.
+.\"
+.\" <heading-text> Text (required) to appear within each of
+.\" the section heading, document outline,
+.\" and (optionally) TOC.
+.\"
+.\" Hooks:
+.\" XH-INIT User-defined macro, called on entry to XH;
+.\" used to specify initialization state which
+.\" may be needed after using SH; e.g. specify
+.\" a PDFHREF.INFO state without incorporation
+.\" of any "section" references.
+.\"
+.\" XN-INIT User-defined macro, called on entry to XN;
+.\" used to specify initialization state which
+.\" may be needed after using NH; e.g. specify
+.\" a PDFHREF.INFO state which may incorporate
+.\" "section" references.
+.\"
+.\" XH-UPDATE-TOC User-defined macro, called by both XH, and
+.\" XN; (there is no XN-UPDATE-TOC). Must be
+.\" defined, if a TOC entry is to be generated
+.\" by either XH, or XN; the format of such a
+.\" TOC entry is determined by the definition
+.\" of this macro.
+.\"
+.\" Both XH, and XN macros, share a common entry point.
+.\"
+.de XH als
+.als XN XH
.\" FIXME: within s.tmac, the heading level established by the most
.\" recent prior invocation of the NH macro is tracked by the "nh*hl"
.\" private register; perhaps s.tmac could expose this more publicly,
@@ -85,93 +176,130 @@ along with this program. If not, see
<http://www.gnu.org/licenses/>.
.\"
.ie r nh*hl .nr spdf:nh*hl \n[nh*hl]
.el .nr spdf:nh*hl 0
-.am @NH aln
+.am @NH
. nr spdf:nh*hl \\n[nh*hl]
+..
.aln .NH spdf:nh*hl
.
-.de XN
-.\" Use AFTER .NH n, to define the text of the numbered heading,
-.\" automatically generating a matching formatted TOC entry, and
-.\" a PDF document outline entry.
-.\"
-.\" String registers XNVS1, XNVS2 and XNVS3 establish additional leading,
-.\" prior to top level headings, preceding each level of indented subheading,
-.\" and following each nested level of subheading, respectively
-.\" (strings are used, rather than numeric registers, so that these
-.\" additional spacing parameters may be set relative to the current
-.\" document line spacing, as set by \n[VS]).
-.\"
-.rm spdf:refname
-.als spdf:bm.define spdf:bm.basic
-.while dopt*XN\\$1 \{\
-. opt*XN\\$1 \\$*
-. shift \\n[spdf:argc]
-. \}
-.rr spdf:argc
-.if '\\$1'--' .shift
-.if dspdf:refname .XM -N \\*[spdf:refname] -- \\$@
-.rm spdf:refname
-.spdf:bm.define spdf:bm.text "\\$*"
-.pdfhref O \\n[.NH] "\\*(SN \\*[spdf:bm.text]"
-.XS
-.if rtc*hl \{\
-. if !dXNVS1 .ds XNVS1 1.0v \" default leading for top level
-. if !dXNVS2 .ds XNVS2 0.3v \" default leading at nesting increment
-. if !dXNVS3 .ds XNVS3 0.6v \" default leading following nested group
-. if \\n[.NH]=1 \{\
-. sp \\*[XNVS1]
-. nr tc*hl-max 1
-. \}
-. ie \\n[.NH]<\\n[tc*hl] .if \\n[.NH]>1 .sp \\*[XNVS3]
-. el \{\
-. ie \\n[.NH]>\\n[tc*hl] .sp \\*[XNVS2]
-. el \{\
-. if !r tc*hl-max .nr tc*hl-max 1
-. ie \\n[tc*hl-max]>\\n[.NH] .sp \\*[XNVS3]
-. el .nr tc*hl-max \\n[.NH]
-. \}
+.\" The user is expected to furnish the XH-INIT, XH-UPDATE-TOC, and
+.\" XN-INIT handlers. (Note that the XH-UPDATE-TOC hook serves both
+.\" XH and XN; there is no separate XN-UPDATE-TOC). These stubs are
+.\" provided to avoid possible "undefined macro" warnings; each is
+.\" implemented as a no-op.
+.\"
+.de XH-INIT de
+.de XH-UPDATE-TOC de
+.de XN-INIT
+..
+.\" The common entry point for both XH, and XN, handles initialization,
+.\" and interpretation of any specified options, before handing over to
+.\" one of two distinct formatting helper macros, which are specific to
+.\" the XH, and XN implementations respectively.
+.\"
+.am XH \" and also XN
+. \\$0-INIT
+. rm spdf:refname
+. als spdf:bm.define spdf:bm.basic
+. while d spdf:XH\\$1 \{\
+. spdf:XH\\$1 \\$*
+. shift \\n[spdf:argc]
. \}
-. \}
-.nr tc*hl \\n[.NH]
-\h'\\n[.NH]-1m'\c
-\&\\*(SN\h'1n'\\$*
-.\".pdfhref L -D \\*[PDFBOOKMARK.NAME] -- \&\\*(SN\h'1n'\\$*
-.XE
-\&\\$*
+. rr spdf:argc
+. if '\\$1'--' .shift
+. spdf:\\$0.format \\$@
..
-.de opt*XN-N
-.ds spdf:refname \\$2
-.nr spdf:argc 2
+.\" Interpret the "-N <name>" option...
+.\"
+.de spdf:XH-N
+. ds spdf:refname \\$2
+. nr spdf:argc 2
..
-.de opt*XN-S
-.als spdf:bm.define sanitize
-.nr spdf:argc 1
+.\" ...the "-X" option, and...
+.\"
+.de spdf:XH-X
+. if !d spdf:refname .ds spdf:refname \\\\$1
+. nr spdf:argc 1
..
-.de opt*XN-X
-.if !dspdf:refname .ds spdf:refname \\\\$1
-.nr spdf:argc 1
+.\" ...the "-S" option.
+.\"
+.de spdf:XH-S
+. als spdf:bm.define sanitize
+. nr spdf:argc 1
..
+.\" By default, when the "-S" option is not specified, the text
+.\" incorporated into the PDF document outline will be a simple
+.\" verbatim copy of the arguments.
+.\"
.de spdf:bm.basic
-.shift
-.ds spdf:bm.text "\\$*\"
+. shift \" ignore \$1; it should always be "spdf:bm.text"
+. ds spdf:bm.text "\\$*\"
..
-.de LU
-.LP
-The content for this section is not yet available.
+.\" After initialization, and interpretation of options, the XH
+.\" and XN implementations diverge, into this helper macro, which
+.\" is specific to the XH implementation...
+.\"
+.de spdf:XH.format
+. XH-UPDATE-TOC \\$@
+. ds spdf:bm.argv \\$1
+. shift \" finalization doesn't want the outline level in \$1
+. spdf:XH.finalize \\$@
..
-.de AN
-.ie \\n(.$ .@AN \\$*
-.el .@AN Note
+.\" ...and this, which is specific to XN...
+.\"
+.de spdf:XN.format
+. ds spdf:bm.argv \\n[.NH] \\*[SN]
+. XH-UPDATE-TOC \\n[.NH] \\*[SN] \\$@
+. spdf:XH.finalize \\$@
..
-.de @AN
-.SH
-\\$*
-.LP
+.\" ...before ultimately converging back into this finalization
+.\" macro, which is once again common to both XH and XN.
+.\"
+.de spdf:XH.finalize
+. spdf:bm.define spdf:bm.text "\\$*"
+. if d spdf:refname .pdfhref M -X -N \\*[spdf:refname] -- \\$@
+. pdfhref O \\*[spdf:bm.argv] \\*[spdf:bm.text]
+. rm spdf:refname spdf:bm.argv spdf:bm.text
+. nop \\$*
..
+.
+.\" Cross-Reference Marshalling
+.\" ===========================
+.\"
+.\" s.tmac provides the "pg@bottom" macro, which has already
+.\" been installed as a page transition trap. To ensure proper
+.\" mapping of "pdfhref" links which overflow the bottom of any
+.\" page, we need to install the "pdfhref" page transition hook,
+.\" as an addendum to this macro.
+.
+.pdfhref I -PT pg@bottom
+.
+.
+.\" Phased Output Control
+.\" =====================
+.\"
+.\" Segregate output of table of contents, and document body text,
+.\" into two distinct output phases, to facilitate assembly of the
+.\" aggregate document in the correct order, particularly when the
+.\" TOC is generated at the end, by the default "ms" mechanism.
+.\"
.nr PDF-TOC-ONLY 1
.nr PDF-BODY-TEXT 2
+.\"
+.\" .OP [<output-phase>]
+.\"
+.\" If the user-specified PHASE numeric register has been defined,
+.\" and its value matches the <output-phase> argument value, (or if
+.\" no <output-phase> argument is specified), then set the OPMODE
+.\" control flag to one, and activate groff's "pen-down" mode.
+.\"
+.\" Otherwise, if <output-phase> is specified, but does NOT match
+.\" PHASE, set OPMODE to zero, and select "pen-up" mode.
+.\"
+.\" Alternatively, if PHASE has not been defined, unconditionally
+.\" set OPMODE to one, and leave groff's pen state unchanged.
+.\"
.de OP
-.ie rPHASE \{\
+.ie r PHASE \{\
. ie \\n(.$ \{\
. nr op:request 0
. while \\n(.$ \{\
@@ -187,67 +315,35 @@ The content for this section is not yet available.
. \}
.el .nr OPMODE 1
..
-.nr SAME-PAGE 0
-.de NN
-.if !\\n[SAME-PAGE] .bp
-.nr SAME-PAGE 0
-.NH \\$1
-.nn*setname \\$2
-.shift 2
-.XN -N \\*[nn*name] -- \\$@
-.rm nn*name
-..
-.de nn*setname
-.ds nn*name \\$1
-.shift
-.while \\n(.$ \{\
-. as nn*name -\\$1
-. shift
-. \}
-..
-.de PXREF
-.nn*setname \\$2
-.XR \\*[nn*name] )\\$1 (
-.rm nn*name
-..
-.de IS
-.RS
-.nr LL \\n(LL-\\n(PI
-..
-.de IE
-.RE
-.nr LL \\n(LL+\\n(PI
-..
-.\" Override the standard ms macro,
-.\" to ensure the document outline cache is flushed
-.\" BEFORE emitting the table of contents.
+.
+.\" Table of Contents Generation
+.\" ============================
+.\"
+.\" .TC [no]
+.\"
+.\" Replaces (and emulates) the TC macro, from s.tmac, to ensure
+.\" that the pdfmark document outline cache is flushed, before TOC
+.\" generation commences, that an outline reference is added for the
+.\" TOC itself, and that pdfroff TOC relocation mode is enabled, for
+.\" the TOC output phase of document production.
+.\"
.de TC
-.pdfsync O
-.P1
-.OP \n[PDF-TOC-ONLY]
-.pg@begin 1 i
-.if !\\n[PHASE] .tm pdfroff-option:set toc_relocation=enabled
-.if \\n[OPMODE] .pdf@toc
-.PX \\$1
-..
-.de pdf@toc
-.pdfhref O -T T 1 "\\*[TOC]"
-.pdfsync O
-..
-.de pdf@exit
-.if \\n[OPMODE] .pdfsync
-.pg@end-text
+. pdfsync O
+. P1
+. OP \n[PDF-TOC-ONLY]
+. pg@begin 1 i
+. if !\\n[PHASE] .tm pdfroff-option:set toc_relocation=enabled
+. if \\n[OPMODE] \{\
+. pdfhref O -T T 1 "\\*[TOC]"
+. pdfsync O
+. \}
+. PX \\$1
..
-.em pdf@exit
-.OP \n[PDF-BODY-TEXT]
.
-.\" groff "ms" provides the "pg@bottom" macro, which has already
-.\" been installed as a page transition trap. To ensure proper
-.\" mapping of "pdfhref" links which overflow the bottom of any
-.\" page, we need to install the "pdfhref" page transition hook,
-.\" as an addendum to this macro.
+.\" Initialize the default output state, for production of "body-text".
+.\"
+.OP \n[PDF-BODY-TEXT]
.
-.pdfhref I -PT pg@bottom
.\" Local Variables:
.\" mode: nroff
.\" End:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [groff] 01/03: Factor document-specific bloat out of spdf.tmac,
Keith Marshall <=