.ig
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)
This file is part of groff.
groff is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or
(at your option) any later version.
groff is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
..
.\" Bindings
.\" ========
.\"
.\" Generic output mode control flag; pdfmark.tmac will bind this to
.\" its own internal PDFOPMODE flag.
.\"
.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
.\"
.\" Defines a pair of macros, and , such that execution
.\" of . marks the start of a block of troff input which should
.\" be ignored; this block ends, on execution of .
.\"
.de OMIT OMIT
. 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
..
.\" ...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
..
.
.\" Document Outlines, and Section Headings
.\" =======================================
.\"
.\" .XH [-N ] [-S] [-X] ...
.\" .XN [-N ] [-S] [-X] ...
.\"
.\" Use after SH, and XN 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.
.\"
.\" Options:
.\" -N Assigns 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 is unspecified, use first word
.\" of as .
.\"
.\" Arguments:
.\" The nesting level of the heading, within
.\" the document outline, and TOC. Required
.\" for XH; inferred from NH , for XN.
.\"
.\" 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.
.\"
.\" Our replacements for both XH, and XN macros share a common entry
.\" point; we map both to their respective replacement hooks, so that
.\" we may continue to take advantage of setup logic in s.tmac. When
.\" these are eventually invoked, they will have been renamed so that
.\" they replace XH, and XH respectively.
.\"
.de XH-REPLACEMENT als
.als XN-REPLACEMENT XH-REPLACEMENT
.\" 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,
.\" as by this ostensibly read-only alias, since we need it to keep
.\" PDF document outlines in synchronization with NH level...
.\"
.\" .aln .NH nh*hl
.\"
.\" ...but maybe a local "belt and braces" approach is better anyway,
.\" to insulate "nh*hl" from possible abuse of our ".NH" register, by
.\" any users who may be determined to shoot themselves in the foot!
.\"
.ie r nh*hl .nr spdf:nh*hl \n[nh*hl]
.el .nr spdf:nh*hl 0
.am @NH
. nr spdf:nh*hl \\n[nh*hl]
..
.aln .NH spdf:nh*hl
.
.\" 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-REPLACEMENT \" thus serving as implementation for both XH and XN
.\"
.\" 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). A suitable stub
.\" for each is provided by s.tmac; we have no need to replace them.
.\"
. \\$0-INIT
. rm spdf:refname
. als spdf:bm.define spdf:bm.basic
. while d spdf:XH\\$1 \{\
. spdf:XH\\$1 \\$*
. shift \\n[spdf:argc]
. \}
. rr spdf:argc
. if '\\$1'--' .shift
. spdf:\\$0.format \\$@
..
.\" Interpret the "-N " option...
.\"
.de spdf:XH-N
. ds spdf:refname \\$2
. nr spdf:argc 2
..
.\" ...the "-X" option, and...
.\"
.de spdf:XH-X
. if !d spdf: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 \" ignore \$1; it should always be "spdf:bm.text"
. ds spdf:bm.text "\\$*\"
..
.\" 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 \\$@
..
.\" ...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 \\$@
..
.\" ...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 []
.\"
.\" If the user-specified PHASE numeric register has been defined,
.\" and its value matches the argument value, (or if
.\" no argument is specified), then set the OPMODE
.\" control flag to one, and activate groff's "pen-down" mode.
.\"
.\" Otherwise, if 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 r PHASE \{\
. ie \\n(.$ \{\
. nr op:request 0
. while \\n(.$ \{\
. if \\$1=\\n[PHASE] .nr op:request 1
. shift
. \}
. \}
. el .nr op:request 1
. if !\\n[op:request]=\\n[OPMODE] \{\
. nr OPMODE \\n[op:request]
. nop \O[\\n[OPMODE]]\c
. \}
. \}
.el .nr OPMODE 1
..
.
.\" 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] \{\
. pdfhref O -T T 1 "\\*[TOC]"
. pdfsync O
. \}
. PX \\$1
..
.
.\" Initialize the default output state, for production of "body-text".
.\"
.OP \n[PDF-BODY-TEXT]
.
.\" Local Variables:
.\" mode: nroff
.\" End:
.\" vim: filetype=groff:
.\" spdf.tmac: end of file