2 # ------------------------------------------------------------------------------
4 # Copyright (C) 2004, Free Software Foundation, Inc.
5 # Written by Keith Marshall (keith.d.marshall@ntlworld.com)
7 # This file is part of groff.
9 # groff is free software; you can redistribute it and/or modify it under
10 # the terms of the GNU General Public License as published by the Free
11 # Software Foundation; either version 2, or (at your option) any later
14 # groff is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 # You should have received a copy of the GNU General Public License along
20 # with groff; see the file COPYING. If not, write to the Free Software
21 # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 # ------------------------------------------------------------------------------
27 # We use GhostScript as our PDF writer -- here's how we will run it
30 PDFWRITE
= $(GS
) $(GSFLAGS
) -dQUIET
-dNOPAUSE
-dBATCH
-sDEVICE
=pdfwrite
32 # When generating Tables of Contents, we may need to split the document
33 # into separate TOC and BODY components, so that we can rearrange these
34 # into the correct order, when we assemble the final PDF document.
36 # To achieve this split, we run two groff passes, with different "phase"
37 # indices in each of the passes.
42 # In order to choose a groff macro package, to format the document, we need
43 # a value for TMACTYPE to be set on the command line. This should name ONE
44 # of groff's principal macro packages, e.g. ms, mm, or me.
48 # When TMACTYPE has been appropriately set up, then we may establish the
49 # proper settings for groff, to format the document. Notice that we do not
50 # specify the principal macro package name directly, but rather, we use a
51 # wrapper macro package, which adds the appropriate PDF extensions to the
52 # base set; the name of this wrapper package matches its corresponding base
53 # package name, with "pdf" appended, e.g. for the ms macros, implemented in
54 # "s.tmac", and selected by setting "TMACTYPE=ms", the corresponding wrapper
55 # is "spdf.tmac", and the "-ms" option to groff is replaced by "-mspdf",
56 # ( which is actually constructed as "-$(TMACTYPE)pdf" ).
58 GROFF_SETUP
= -Tps
$(GROFF_FLAGS
) -M.
-$(TMACTYPE
)pdf
$(GROFF_LAYOUT
)
60 # We also need to communicate the selected paper size to groff, by setting
61 # flags to pass it BOTH to troff, and to the postprocessor, grops.
63 GROFF_LAYOUT
= -dpaper
=$(PAPERSIZE
) -P-p
$(PAPERSIZE
)
65 # The final output file SHOULD be named with a ".pdf" suffix, but
66 # we allow the user to specify the target name without the ".pdf" suffix,
67 # and automically append it, silently, when required.
74 # When the TMACTYPE definition has not been supplied, we may deduce it,
75 # assuming the input file is named with the macro package name as a suffix,
76 # for an input file named to match "%.ms", select the ms macro package ...
78 %: %.ms
; @
$(REMAKE
) TMACTYPE
=ms
$@
79 %.ref
: %.ms
; @
$(REMAKE
) TMACTYPE
=ms
$@
80 %.map
: %.ms
; @
$(REMAKE
) TMACTYPE
=ms
$@
81 %.pdf
: %.ms
; @
$(REMAKE
) TMACTYPE
=ms
$@
83 # Similarly, for the mm, me and mom packages, with input file names matching
84 # "%.mm", "%.me" and "%.mom" respectively ...
86 %: %.mm
; @
$(REMAKE
) TMACTYPE
=mm
$@
87 %.ref
: %.mm
; @
$(REMAKE
) TMACTYPE
=mm
$@
88 %.map
: %.mm
; @
$(REMAKE
) TMACTYPE
=mm
$@
89 %.pdf
: %.mm
; @
$(REMAKE
) TMACTYPE
=mm
$@
91 %: %.me
; @
$(REMAKE
) TMACTYPE
=me
$@
92 %.ref
: %.me
; @
$(REMAKE
) TMACTYPE
=me
$@
93 %.map
: %.me
; @
$(REMAKE
) TMACTYPE
=me
$@
94 %.pdf
: %.me
; @
$(REMAKE
) TMACTYPE
=me
$@
96 %: %.mom
; @
$(REMAKE
) TMACTYPE
=mom
$@
97 %.ref
: %.mom
; @
$(REMAKE
) TMACTYPE
=mom
$@
98 %.map
: %.mom
; @
$(REMAKE
) TMACTYPE
=mom
$@
99 %.pdf
: %.mom
; @
$(REMAKE
) TMACTYPE
=mom
$@
101 # FIXME: each of the above four rule sets requires an appropriate package of
102 # binding macros, to add the PDF extensions to the corresponding base package;
103 # until someone provides "mpdf.tmac", "epdf.tmac" and "ompdf.tmac", only the
104 # TMACTYPE=ms option will actually work!
108 # Define an awk script to extract cross reference data from the groff stderr
109 # stream, and format as a cross reference definitions file, of type "%.ref",
110 # to be merged with the groff input stream, in a later formatting pass
112 XREF_MARKER
= /^gropdf-info
:href
/
113 XREF_FORMAT
= { $$1 = ".ds"; $$2 = "pdf:href(" $$2 ").info"; print }
114 XREF_SCRIPT
= $(XREF_MARKER
) $(XREF_FORMAT
)
116 # Define the awk command, which uses the above script to create a cross
117 # reference filter, and specify the groff flags to be applied when piping
118 # the groff stderr stream through this filter.
120 XREF_FILTER
= awk
'$(XREF_SCRIPT)'
121 XREF_FLAGS
= $(GROFF_SETUP
) -Z
2>&1 1>/dev
/null
123 # To kick start the cross referencing process, we create an intermediate
124 # file, of type "%.xrf", initialised with the "first pass" cross reference
125 # definitions file content.
127 %.xrf
: %.
$(TMACTYPE
)
128 groff
$(XREF_FLAGS
) $^ |
$(XREF_FILTER
) > $@
130 # The final cross reference definitions file is created by recurrently
131 # processing the original groff input stream, including the definitions
132 # from the preceding pass, (starting with the "%.xrf" file from above),
133 # until two consecutive passes create identical output, capturing the
134 # final cross reference definitions in the "%.ref" file.
136 REMAKE
= $(MAKE
) --no-print-directory
138 %.ref
: %.xrf
%.
$(TMACTYPE
)
139 groff
$(XREF_FLAGS
) $^ |
$(XREF_FILTER
) > $@
140 diff
$< $@
1>/dev
/null
2>&1 || mv
-f
$@
$<
141 test -f
$@ ||
$(REMAKE
) $@
143 # Define a second awk script, which will be used to reprocess the fully
144 # cross referenced groff input stream, adding "hot-spot" mapping information
145 # to the cross reference definitions.
147 XMAP_MARKER
= /^grohtml-info
/
148 XMAP_PREFIX
= BEGIN
{ mapref
= 0 }
149 #MAP_FORMAT = ".ds pdf:href.map-%d %d %d %d\n"
150 #MAP_FORMAT = ".ds pdf:href.map-%d %d %d %d %d %d\n"
151 #MAP_APPEND = { printf $(XMAP_FORMAT), ++mapref, $$2, $$3, $$6, $$7, $$4 }
152 #MAP_APPEND = { printf $(XMAP_FORMAT), ++mapref, $$2, $$3, $$4 }
153 #MAP_SCRIPT = $(XMAP_PREFIX) $(XMAP_MARKER) $(XMAP_APPEND)
154 XMAP_FORMAT
= { print ".ds pdf:href.map-" ++mapref
, $$2, $$3, $$4 }
155 XMAP_SCRIPT
= $(XMAP_PREFIX
) $(XMAP_MARKER
) $(XMAP_FORMAT
)
157 # The awk command, which invokes this script as the final cross reference
158 # mapping filter, must also reproduce the output of the earlier filter,
159 # used to create the "%.ref" file.
161 XMAP_FILTER
= awk
'$(XMAP_SCRIPT) $(XREF_SCRIPT)'
163 # The "hot-spot" mapping data is merged with the original "%.ref" cross
164 # reference definitions, with the final cross reference mapping definitions
165 # being captured in a "%.map" file.
167 %.map
: %.ref
%.
$(TMACTYPE
)
168 groff
$(XREF_FLAGS
) $^ |
$(XMAP_FILTER
) > $@
170 # Assuming a cover page title block is defined in the groff document source,
171 # with its content bracketed by ".CS" .. ".CE" macro pairs, we can use sed
174 SET_TITLE
= sed
-n
'/^\.CS/,/^\.CE/p'
176 # The extracted title block may then be merged into a standard cover page
177 # layout template, and processed by groff, to generate a cover page.
179 %-fp.ps
: %.
$(TMACTYPE
)
180 $(SET_TITLE
) $< | groff
$(GROFF_SETUP
) cover.
$(TMACTYPE
) - > $@
182 # Define the "phase" codes, passed to groff, for separating tables of
183 # contents and body text into distinct document parts.
185 TOC_ONLY
= -rPHASE
=$(PDF_TOC_ONLY
)
186 BODY_ONLY
= -rPHASE
=$(PDF_BODY_TEXT
)
188 # Identify the document parts to be assembled, by examining the "PARTSLIST"
189 # file, if any, specified on the command line as "PARTSLIST=filename".
195 # When we are assembling a multipart document, each individual part may
196 # include redundant blank pages, inherited from a groff processing phase
197 # for an alternative part, reprocessed in its own phase, with "pen up".
198 # The following sed script will discard such pages.
202 -e
' /%%EndPageSetup/b finish' \
210 -e
' /^%%Page:.*0 *Cg *EP/d'
212 # Define the "multipart" rules for each of the Table of Contents, and
213 # the "Body Text" document parts.
215 %-toc.ps
: %.map
%.
$(TMACTYPE
)
216 groff
$(GROFF_SETUP
) $(TOC_ONLY
) $^ |
$(KILL_BLANK_PAGES
) > $@
218 %-body.ps
: %.map
%.
$(TMACTYPE
)
219 groff
$(GROFF_SETUP
) $(BODY_ONLY
) $^ |
$(KILL_BLANK_PAGES
) > $@
221 # The "PARTSLIST" file tells us which parts to assemble, by defining a
222 # prototype list, in the "PARTNAMES" variable.
226 # When "PARTNAMES" has been defined, then we may proceed to assemble the
227 # specified document parts.
230 $(PDFWRITE
) -sOutputFile
=$@
$^
234 # ... but when, "PARTNAMES" is not yet specified, then we must examine the
235 # groff input file, to deduce which parts are required ..
237 INCLUDE_TOC
= egrep
"^[.']"'[ ]*TC( .*)*[
]*$$'
239 %-parts.txt
: %.
$(TMACTYPE
)
240 echo
"PARTNAMES =" > $@
241 test -z
"`$(SET_TITLE) $<`" || echo
"%-fp.ps" >> $@
242 test -z
"`$(INCLUDE_TOC) $<`" || echo
"%-toc.ps" >> $@
243 echo
"%-body.ps" >> $@
245 # ... assembling the identified "PARTNAMES" in to a "PARTSLIST" file ...
247 %-parts.mk
: %-parts.txt
248 echo
`tr '\012\014' '\040\040' < $<` > $@
250 # ... which we then reprocess, to generate the output document.
253 $(REMAKE
) PARTSLIST
=$< $@
257 # ------------------------------------------------------------------------------
258 # pdfmake: end of file