summaryrefslogtreecommitdiff
path: root/contrib/pdfmark
diff options
context:
space:
mode:
authorkeithmarshall <keithmarshall>2006-03-31 22:07:02 +0000
committerkeithmarshall <keithmarshall>2006-03-31 22:07:02 +0000
commit36e4078567db41bca8fb258c561a1cb140d76509 (patch)
tree43b222cf5972d1f410ad95bc0a2173a19266aa1c /contrib/pdfmark
parent83ebc5cc1a68ff6ed5489d28a40cc30357253366 (diff)
downloadgroff-36e4078567db41bca8fb258c561a1cb140d76509.tar.gz
Split `pdfmark' output as required, to avoid excessively long
`ps:exec' intermediate output records. * pdfmark.tmac (pdfmark): Macro extended to deploy ... (pdf*pdfmark.limit): New macro; use it to define ... (PDFMARK.FOLDWIDTH, PDFMARK.FOLDWIDTH.MAX): New registers. (pdf*compose.first, pdf*compose.next, pdf*compose.literal): New macros; each will be aliased as required to ... (pdf*compose): ... this, to dynamically construct ... (pdf:composed.line, pdf:composed.literal): ... these new strings. (pdf:compose.test): New dynamically constructed string; use it to detect parenthesised literals in pdfmark content, so folding can be avoided within them, subject to honouring of `PDFMARK.FOLDWIDTH'. (pdf*length.increment): New macro; it triggers output folding when ... (pdf:length): ... this new register exceeds `PDFMARK.FOLDWIDTH.MAX'. (pdf*pdfmark.post.first, pdf*pdfmark.post.next): New macros; each will be aliased as required to ... (pdf*pdfmark.post): ... this, and invoked by ... (pdf*pdfmark.dispatch): ... this new macro; use it to define ... (pdf:composed): ... this dynamically constructed macro; use ... (pdf*end): ... this new macro to terminate it.
Diffstat (limited to 'contrib/pdfmark')
-rw-r--r--contrib/pdfmark/ChangeLog41
-rw-r--r--contrib/pdfmark/pdfmark.tmac377
2 files changed, 413 insertions, 5 deletions
diff --git a/contrib/pdfmark/ChangeLog b/contrib/pdfmark/ChangeLog
index 11b14a30..5a07e54c 100644
--- a/contrib/pdfmark/ChangeLog
+++ b/contrib/pdfmark/ChangeLog
@@ -1,3 +1,27 @@
+2006-03-31 Keith Marshall <keith.d.marshall@ntlworld.com>
+
+ Split `pdfmark' output as required, to avoid excessively long
+ `ps:exec' intermediate output records.
+
+ * pdfmark.tmac (pdfmark): Macro extended to deploy ...
+ (pdf*pdfmark.limit): New macro; use it to define ...
+ (PDFMARK.FOLDWIDTH, PDFMARK.FOLDWIDTH.MAX): New registers.
+ (pdf*compose.first, pdf*compose.next, pdf*compose.literal): New
+ macros; each will be aliased as required to ...
+ (pdf*compose): ... this, to dynamically construct ...
+ (pdf:composed.line, pdf:composed.literal): ... these new strings.
+ (pdf:compose.test): New dynamically constructed string; use it to
+ detect parenthesised literals in pdfmark content, so folding can be
+ avoided within them, subject to honouring of `PDFMARK.FOLDWIDTH'.
+ (pdf*length.increment): New macro; it triggers output folding when ...
+ (pdf:length): ... this new register exceeds `PDFMARK.FOLDWIDTH.MAX'.
+ (pdf*pdfmark.post.first, pdf*pdfmark.post.next): New macros; each will
+ be aliased as required to ...
+ (pdf*pdfmark.post): ... this, and invoked by ...
+ (pdf*pdfmark.dispatch): ... this new macro; use it to define ...
+ (pdf:composed): ... this dynamically constructed macro; use ...
+ (pdf*end): ... this new macro to terminate it.
+
2006-03-09 Keith Marshall <keith.d.marshall@ntlworld.com>
Incorporate portability recommendations by Ralf Wildenhues
@@ -22,11 +46,23 @@
retain them in `GROFF_TMPDIR=.'.
(CLEANADD): Include temporary files matching `pdf[0-9]*'.
+2006-03-08 Werner LEMBERG <wl@gnu.org>
+
+ * pdfmark.ms: Update URL for Adobe Reference Manual.
+
2006-02-26 Claudio Fontana <claudio@gnu.org>
* Makefile.sub: Add DESTDIR to install and uninstall targets
to support staged installations.
+2006-02-25 Werner LEMBERG <wl@gnu.org>
+
+ * pdfmark.ms: Correct typo; reported by Thomas Klausner.
+
+2006-02-24 Werner LEMBERG <wl@gnu.org>
+
+ * pdfmark.ms, pdfroff.sh: Replace legal/illegal with valid/invalid.
+
2005-06-22 Keith Marshall <keith.d.marshall@ntlworld.com>
pdfroff.sh portability enhancement.
@@ -57,6 +93,11 @@
* Makefile.sub (.ms.pdf): Use `--stylesheet', not `--style'.
+2005-05-26 Werner LEMBERG <wl@gnu.org>
+
+ * Makefile.sub, pdfmark.tmac, pdfroff.sh, spdf.tmac: Update postal
+ address for Free Software Foundation.
+
2005-05-17 Keith Marshall <keith.d.marshall@ntlworld.com>
Improve portability of `pdfroff' shell script.
diff --git a/contrib/pdfmark/pdfmark.tmac b/contrib/pdfmark/pdfmark.tmac
index 385185c4..c8d4d27d 100644
--- a/contrib/pdfmark/pdfmark.tmac
+++ b/contrib/pdfmark/pdfmark.tmac
@@ -3,7 +3,7 @@
pdfmark.tmac
-Copyright (C) 2004
+Copyright (C) 2004, 2005, 2006
Free Software Foundation, Inc.
Written by Keith Marshall (keith.d.marshall@ntlworld.com)
@@ -43,7 +43,7 @@ inspiration has come from discussion on the groff mailing list
.if d pdfmark .nx
.\"
.\" ======================================================================
-.\" Module PDFMARK: Insert Arbitrary PDFMARK Code in the PostScript Stream
+.\" Module PDFMARK: Insert Arbitrary PDFMARK Code in the Postscript Stream
.\" ======================================================================
.\"
.\" PDFMARK output may be disabled, by zeroing the PDFOPMODE register,
@@ -56,8 +56,31 @@ inspiration has come from discussion on the groff mailing list
.\"
.if !rPDFOPMODE .nr PDFOPMODE 1
.\"
+.\" PDFMARK output must be constrained to a maximum line length limit,
+.\" for strict compliance with the Postscript DSC. This limit is defined
+.\" in register "PDFMARK.FOLDWIDTH.MAX". This is user definable, up to a
+.\" ceiling value of 255, which is also its default value; this limit
+.\" is enforced for each PDFMARK, by macro "pdf*pdfmark.limit".
+.\"
+.de pdf*pdfmark.limit
+.\" ----------------------------------------------------------------
+.\" Usage:
+.\" .pdf*pdfmark.limit REGISTER-NAME DEFAULT-MAXIMUM-VALUE
+.\" ----------------------------------------------------------------
+.\"
+.\" If a register named REGISTER-NAME has not been defined, then
+.\" define it now, with default value = DEFAULT-MAXIMUM-VALUE.
+.\"
+.if !r\\$1 .nr \\$1 \\$2
+.\"
+.\" But when it has already been defined, ensure that its value does
+.\" not exceed DEFAULT-MAXIMUM-VALUE; if value does exceed this ceiling,
+.\" then redefine it, to enforce the limit.
+.\"
+.if (\\n[\\$1] > \\$2) .nr \\$1 \\$2
+..
.\" The "pdfmark" macro is responsible for emitting the appropriate
-.\" PostScript code.
+.\" Postscript code.
.\"
.de pdfmark
.\" ----------------------------------------------------------------
@@ -67,7 +90,351 @@ inspiration has come from discussion on the groff mailing list
.\" operator; DO NOT include them in the instruction text!
.\" ----------------------------------------------------------------
.\"
-.if \\n[PDFOPMODE] \X'ps:exec [\\$* pdfmark'\c
+.if \\n[PDFOPMODE] \{\
+.\"
+.\" Strict DSC compliance forbids emission of ps:exec lines which
+.\" exceed 255 characters in length. We will allow the user to specify
+.\" an alternative lesser limit ...
+.\"
+. pdf*pdfmark.limit PDFMARK.FOLDWIDTH.MAX 255
+.\"
+.\" ... and we will also support a second lesser limit, which will be
+.\" applied to literal text parenthetically embedded within the PDFMARK.
+.\"
+. pdf*pdfmark.limit PDFMARK.FOLDWIDTH \\n[PDFMARK.FOLDWIDTH.MAX]
+.\"
+.\" We will push out the entire PDFMARK in one chunk, provided it fits
+.\" within this limit.
+.\"
+. length pdf:length "[\\$* pdfmark\"
+. ie !(\\n[pdf:length] > \\n[PDFMARK.FOLDWIDTH]) \{\
+. \"
+. \" This PDFMARK is suitable for single chunk output ...
+. \"
+. nop \X'ps:exec [\\$* pdfmark'\c
+. \}
+. el \{\
+. \" ... but, when the limit would be violated, then we must
+. \" recompose the specified PDFMARK, spreading it over as many
+. \" continuation lines as are necessary.
+. \"
+. als pdf*compose pdf*compose.first
+. while \\n(.$ \{\
+. pdf*compose \\$1
+. shift
+. \}
+. \"
+. \" Complete the PDFMARK recomposition, by appending a
+. \" "pdfmark" operator, and push it out to the intermediate
+. \" output stream, (excluding its final line break).
+. \"
+. pdf*compose pdfmark
+. pdf*pdfmark.dispatch
+. chop pdf:composed
+. nop \Y[pdf:composed]\c
+. \"
+. \" And clean up when done.
+. \"
+. rm pdf*compose pdf*pdfmark.post
+. rm pdf:compose.test pdf:composed pdf:composed.literal
+. \}
+. rr pdf:length
+. \}
+..
+.\" When a PDFMARK exceeds the specified output record length limit,
+.\" then we decompose it, subsequently using the dynamically overloaded
+.\" macro, "pdf*compose", to reassemble it into as many continuation
+.\" records as it may require.
+.\"
+.\" Each call to "pdf*compose" uses macro "pdf*length.increment" to
+.\" keep track of the current output record length, so ensuring that
+.\" the active maximum length limit is not violated.
+.\"
+.de pdf*length.increment
+.\" ----------------------------------------------------------------
+.\" Usage:
+.\" .pdf*length.increment NEXT-ADDITION
+.\" ----------------------------------------------------------------
+.\"
+.ie d pdf:composed.line \
+. length pdf:length "\\*[pdf:composed.line] \\$*\"
+.el .length pdf:length "\\$*\"
+..
+.\" The first call to "pdf*compose" for each PDFMARK is directed
+.\" to "pdf*compose.first"; this initialises the local strings
+.\" and macros used to compose the eventual PDFMARK output.
+.\"
+.de pdf*compose.first
+.\" ----------------------------------------------------------------
+.\" Usage:
+.\" .als pdf*compose pdf*compose.first
+.\" . pdf*compose TOKEN
+.\" ----------------------------------------------------------------
+.\"
+.\" Ensure that the output record accumulator will be initialised
+.\" on posting of the first composed PDFMARK record.
+.\"
+.als pdf*pdfmark.post pdf*pdfmark.post.first
+.\"
+.\" The first token passed to "pdf*compose" should not be a
+.\" literal, but be prepared to handle one, just in case.
+.\"
+.ds pdf:compose.test \\$1
+.substring pdf:compose.test 0 0
+.ie '('\\*[pdf:compose.test]' \{\
+.\"
+.\" We found a literal, even though we didn't expect it;
+.\" if it's a single element literal, we can just handle it
+.\" as if it is a regular token anyway.
+.\"
+. ds pdf:compose.test "\\$\\n(.$\"
+. substring pdf:compose.test -1
+. if !')'\\*[pdf:compose.test]' \{\
+. \"
+. \" But when it is the first of a literal sequence,
+. \" then we need to set up "pdf*compose" to handle it.
+. \"
+. ds pdf:composed.literal "[\\$*\"
+. als pdf*compose pdf*compose.literal
+. \}
+. \}
+.el .ds pdf:compose.test )
+.if ')'\\*[pdf:compose.test]' \{\
+.\"
+.\" In the normal case, we start each new PDFMARK with a
+.\" regular token; save it as the first in the composed output
+.\" line sequence, and set up "pdf*compose" to collect
+.\" the rest of the sequence.
+.\"
+. ds pdf:composed.line "[\\$*\"
+. als pdf*compose pdf*compose.next
+. \}
+..
+.\" Subsequent calls to "pdf*compose", while collecting
+.\" regular tokens, are then directed to "pdf*compose.next".
+.\"
+.de pdf*compose.next
+.\" ----------------------------------------------------------------
+.\" Usage:
+.\" .als pdf*compose pdf*compose.next
+.\" . pdf*compose TOKEN
+.\" ----------------------------------------------------------------
+.\"
+.\" This first checks to ensure that the supplied token really is
+.\" a regular token, and not the first element in a literal.
+.\"
+.ds pdf:compose.test \\$1
+.substring pdf:compose.test 0 0
+.ie '('\\*[pdf:compose.test]' \{\
+.\"
+.\" The supplied token represents the first element of a literal,
+.\" but it may be a single element literal, which we simply handle
+.\" as a regular token anyway.
+.\"
+. ds pdf:compose.test "\\$\\n(.$\"
+. substring pdf:compose.test -1
+. if !')'\\*[pdf:compose.test]' \{\
+. \"
+. \" The supplied token is the first of a sequence of elements
+. \" which collectively define a literal, so start collecting a
+. \" composite literal token, and change the "pdf*compose"
+. \" state, to collect and append the remaining elements.
+. \"
+. ds pdf:composed.literal "\\$*\"
+. als pdf*compose pdf*compose.literal
+. \}
+. \}
+.el .ds pdf:compose.test )
+.if ')'\\*[pdf:compose.test]' \{\
+.\"
+.\" The supplied token IS a regular token; add it, but ensure that
+.\" the active maximum record length limit is honoured.
+.\"
+. pdf*length.increment "\\$*\"
+. ie (\\n[pdf:length] > \\n[PDFMARK.FOLDWIDTH.MAX]) \{\
+. \"
+. \" Adding this token would cause the current PDFMARK record, in
+. \" groff's intermediate output file, to overflow the active record
+. \" length limit, so post the current record and start another.
+. \"
+. pdf*pdfmark.dispatch
+. ds pdf:composed.line "\\$*\"
+. \}
+. el \{\
+. \"
+. \" This token will fit in the current PDFMARK record, without
+. \" violating the active length limit, so simply add it.
+. \"
+. ie d pdf:composed.line .as pdf:composed.line " \\$*\"
+. el .ds pdf:composed.line "\\$*\"
+. \}
+. \}
+..
+.\" While assembling a multiple token literal sequence into a single
+.\" literal token, successive calls to "pdf*compose" are directed
+.\" to "pdf*compose.literal".
+.\"
+.de pdf*compose.literal
+.\" ----------------------------------------------------------------
+.\" Usage:
+.\" .als pdf*compose pdf*compose.literal
+.\" . pdf*compose TOKEN
+.\" ----------------------------------------------------------------
+.\"
+.\" First, check to ensure that the current token can be appended to
+.\" the accumulated literal, without extending it beyond the maximum
+.\" allowed literal token length.
+.\"
+.length pdf:length "\\*[pdf:composed.literal] \\$*\"
+.ie (\\n[pdf:length] > \\n[PDFMARK.FOLDWIDTH]) \{\
+.\"
+.\" If it has grown too long, then it must be folded across two
+.\" physical PDFMARK output records, so check if we can accommodate
+.\" the portion collected so far within the current output record.
+.\"
+. pdf*length.increment "\\*[pdf:composed.literal]\"
+. if (\\n[pdf:length] > \\n[PDFMARK.FOLDWIDTH.MAX]) \{\
+. \"
+. \" The current output record CAN'T accommodate the currently
+. \" composed portion of the literal, so flush out the current
+. \" record, to make way for the accumulated literal.
+. \"
+. pdf*pdfmark.dispatch
+. \}
+. ie d pdf:composed.line \{\
+. \"
+. \" If we DIDN'T need to flush the current output record,
+. \" then we can simply append the accumulated literal to it...
+. \"
+. as pdf:composed.line " \\*[pdf:composed.literal]\"
+. \}
+. el \{\
+. \"
+. \" otherwise, when the current record has been flushed, or is
+. \" empty, then we promote the accumulated literal, to make it
+. \" the next output record...
+. \"
+. rn pdf:composed.literal pdf:composed.line
+. \}
+.\"
+.\" Now, to complete the fold, flush out any accumulated partial
+.\" output record, and continue accumulating the literal, starting
+.\" with the current token.
+.\"
+. pdf*pdfmark.dispatch
+. ds pdf:composed.literal "\\$*\"
+. \}
+.el \{\
+.\"
+.\" Alternatively, when we HAVEN'T identified a need to fold the
+.\" current output record, then we simply append the current token
+.\" to the accumulated literal token buffer string.
+.\"
+. as pdf:composed.literal " \\$*\"
+. \}
+.\"
+.\" Having ensured that we have sufficient space, in which to
+.\" append the current token to the currently accumulated literal,
+.\" we check its rightmost character, to see if is the closing
+.\" parenthesis, which completes the literal.
+.\"
+.ds pdf:compose.test \\$\\n(.$
+.substring pdf:compose.test -1
+.if ')'\\*[pdf:compose.test]' \{\
+.\"
+.\" The literal has been completely collected, so we may now append
+.\" it to the current output record, as a single literal token, but
+.\" subject to the constraint that it must not extend the output
+.\" record beyond the maximum permitted length.
+.\"
+. pdf*length.increment "\\*[pdf:composed.literal]\"
+. ie (\\n[pdf:length] > \\n[PDFMARK.FOLDWIDTH.MAX]) \{\
+. \"
+. \" So, when the literal cannot be accommodated within the maximum
+. \" length constraint, then we flush the current record, and start
+. \" a new one, with the literal token as its first entry.
+. \"
+. pdf*pdfmark.dispatch
+. rn pdf:composed.literal pdf:composed.line
+. \}
+. el \{\
+. \"
+. \" When the literal CAN be accommodated within the maximum length
+. \" constraint, then ...
+. \"
+. ie d pdf:composed.line \{\
+. \"
+. \" When an output record has already been instantiated, we
+. \" append the literal token to it, and discard the accumulator
+. \" string, which is no longer required.
+. \"
+. as pdf:composed.line " \\*[pdf:composed.literal]\"
+. rm pdf:composed.literal
+. \}
+. el \{\
+. \"
+. \" But when no output record yet exists, then we simply
+. \" reassign the accumulated literal token, to instantiate a
+. \" new output record.
+. \"
+. rn pdf:composed.literal pdf:composed.line
+. \}
+. \}
+.\"
+.\" Finally, since we have completed the accumulation of the literal,
+.\" we revert to the normal "pdf*compose" action, for collection of
+.\" the next token (if any).
+.\"
+. als pdf*compose pdf*compose.next
+. \}
+..
+.\" While composing a multiple record PDFMARK, each composed record
+.\" must be added to the collection, whenever the partially composed
+.\" output record has been filled; this is handled when necessary,
+.\" by calling the "pdf*pdfmark.dispatch" macro.
+.\"
+.de pdf*pdfmark.dispatch
+.\" ----------------------------------------------------------------
+.\" Usage:
+.\" .pdf*pdfmark.dispatch
+.\" ----------------------------------------------------------------
+.\"
+.if d pdf:composed.line \{\
+.\"
+.\" This is simply a wrapper around the overloaded "pdf*pdfmark.post"
+.\" macro, ensuring that an output record has actually been collected
+.\" before attempting to post it; it then cleans up after posting, to
+.\" ensure that each collected record is posted only once.
+.\"
+. pdf*pdfmark.post
+. rm pdf:composed.line
+. \}
+..
+.\" For each PDFMARK, the first call of "pdf*pdfmark.post" is directed
+.\" to the "pdf*pdfmark.post.first" macro; this initialises the state
+.\" of the "pdf:composed" macro, for assembly of a new PDFMARK.
+.\"
+.de pdf*pdfmark.post.first
+.de pdf:composed pdf*end
+ps:exec \\*[pdf:composed.line]
+.pdf*end
+.\"
+.\" Subsequent calls to "pdf*pdfmark.post" are redirected to the
+.\" alternative "pdf*pdfmark.post.next" macro, which simply appends
+.\" additional PDFMARK records to the "pdf:composed" macro.
+.\"
+.als pdf*pdfmark.post pdf*pdfmark.post.next
+..
+.de pdf*pdfmark.post.next
+.am pdf:composed pdf*end
+\\*[pdf:composed.line]
+.pdf*end
+..
+.\" "pdf*end" is a dummy macro. It is required to mark the end
+.\" of each individual fragment which is added to "pdf:composed";
+.\" other than this, it does nothing.
+.\"
+.de pdf*end
..
.\"
.\" Some supporting macros defer actual pdfmark output until an
@@ -216,7 +583,7 @@ inspiration has come from discussion on the groff mailing list
.ds pdf:bbox \\n[pdf:llx] u \\n[pdf:lly] u \\n[pdf:urx] u \\n[pdf:ury] u
.\"
.\" Getting line breaks into the text of a PDFNOTE is tricky -- we need
-.\" to get a "\n" into the PostScript stream, but three levels of "\" are
+.\" to get a "\n" into the Postscript stream, but three levels of "\" are
.\" swallowed, when we invoke "pdfnote". The following definition of "PDFLB",
.\" (for LineBreak), is rather ugly, but does allow us to use
.\"