line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Pod::LaTeX::Book; |
2
|
|
|
|
|
|
|
|
3
|
2
|
|
|
2
|
|
48982
|
use strict; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
81
|
|
4
|
2
|
|
|
2
|
|
11
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
67
|
|
5
|
|
|
|
|
|
|
|
6
|
2
|
|
|
2
|
|
53
|
use 5.008; |
|
2
|
|
|
|
|
14
|
|
|
2
|
|
|
|
|
83
|
|
7
|
|
|
|
|
|
|
|
8
|
2
|
|
|
2
|
|
10
|
use Carp; |
|
2
|
|
|
|
|
17
|
|
|
2
|
|
|
|
|
212
|
|
9
|
2
|
|
|
2
|
|
2074
|
use Config::Any; |
|
2
|
|
|
|
|
25505
|
|
|
2
|
|
|
|
|
75
|
|
10
|
2
|
|
|
2
|
|
2128
|
use Params::Validate qw(:all); |
|
2
|
|
|
|
|
22124
|
|
|
2
|
|
|
|
|
493
|
|
11
|
2
|
|
|
2
|
|
9309
|
use Data::Dumper; |
|
2
|
|
|
|
|
26742
|
|
|
2
|
|
|
|
|
416
|
|
12
|
2
|
|
|
2
|
|
1755
|
use Perl6::Slurp; |
|
2
|
|
|
|
|
3922
|
|
|
2
|
|
|
|
|
16
|
|
13
|
2
|
|
|
2
|
|
78
|
use Pod::Find; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
80
|
|
14
|
2
|
|
|
2
|
|
2256
|
use Pod::ParseUtils; # for Pod::Hyperlink |
|
2
|
|
|
|
|
7659
|
|
|
2
|
|
|
|
|
92
|
|
15
|
|
|
|
|
|
|
|
16
|
2
|
|
|
2
|
|
20
|
use base qw/ Pod::LaTeX /; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
4437
|
|
17
|
|
|
|
|
|
|
|
18
|
2
|
|
|
2
|
|
19747
|
use vars qw/ $VERSION /; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
9459
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
$VERSION = '0.0.1'; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=pod |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 NAME |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
Pod::LaTeX::Book - Compile POD pages into a LaTeX book. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
=head1 VERSION |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
This document describes Pod::LaTeX::Book version 0.0.1 |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=head1 SYNOPSIS |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
use Pod::LaTeX::Book; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
my $parser = Pod::LaTeX::Book->new ( ); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# configure |
44
|
|
|
|
|
|
|
$parser->configure( $cfgRef ); |
45
|
|
|
|
|
|
|
# or |
46
|
|
|
|
|
|
|
$parser->configure_from_file( 'config' ); |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
# output .tex file |
49
|
|
|
|
|
|
|
$parser->parse( 'out.tex' ); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
# script for producing a LaTeX book |
53
|
|
|
|
|
|
|
pod2book --conf=conf_file --out=tex_file |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head1 DESCRIPTION |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
This module aims to provide a mechanism to compile the POD |
58
|
|
|
|
|
|
|
documentation for a set of modules into a printable collection. LaTeX |
59
|
|
|
|
|
|
|
is used as an intermediate format from which both pdf and printed |
60
|
|
|
|
|
|
|
versions can be produced. |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
The modules builds on the functionality provided by Pod::LaTeX. For |
63
|
|
|
|
|
|
|
this purpose several methods from Pod::LaTeX are either overridden or |
64
|
|
|
|
|
|
|
extended. Perhaps most notably, this package uses the LaTeX packages |
65
|
|
|
|
|
|
|
C, C, and C to produce more attractive, |
66
|
|
|
|
|
|
|
extensively hyper-linked PDF. |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=head1 INTERFACE |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
The following routines provide the public interface. Note, that the |
72
|
|
|
|
|
|
|
methods from L, from which this module inherits, |
73
|
|
|
|
|
|
|
are also available. |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=begin __PRIVATE__ |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=head2 C |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
Initialise the object. This method is subclassed from C. |
81
|
|
|
|
|
|
|
The base class method is invoked. |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=end __PRIVATE__ |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=cut |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub initialize{ |
89
|
1
|
|
|
1
|
1
|
37
|
my $self = shift; |
90
|
|
|
|
|
|
|
|
91
|
1
|
|
|
|
|
12
|
$self->{_PodFiles} = [ ]; # for storing Pod's in the book |
92
|
1
|
|
|
|
|
4
|
$self->{_VerbatimParagraph} = ''; # for building listings |
93
|
1
|
|
|
|
|
2
|
$self->{_Codes} = [ ]; # for storing C<> interior sequences |
94
|
1
|
|
|
|
|
3
|
$self->{_Skipping} = 0; # for skipping sections |
95
|
1
|
|
|
|
|
2
|
$self->{_PastName} = 0; # for skipping sections |
96
|
1
|
|
|
|
|
1
|
$self->{_DoSkip} = 0; # for skipping sections |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# Run base initialize |
99
|
1
|
|
|
|
|
10
|
$self->SUPER::initialize; |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
=head2 C |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
Provide information about the documents to be combined and options for |
106
|
|
|
|
|
|
|
the output to be produced. This function should not be invoked |
107
|
|
|
|
|
|
|
directly; use L instead which calls this function. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
Basic validation of the configuration parameters is performed. |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=cut |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub configure{ |
114
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
115
|
0
|
|
|
|
|
0
|
my $config = shift; |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# validation and defaults |
118
|
|
|
|
|
|
|
# first check that the required sections exist ... |
119
|
0
|
|
|
|
|
0
|
my @temp = ( $config ); |
120
|
0
|
|
|
|
|
0
|
validate( @temp, |
121
|
|
|
|
|
|
|
{ |
122
|
|
|
|
|
|
|
DocOptions => { |
123
|
|
|
|
|
|
|
type => HASHREF, |
124
|
|
|
|
|
|
|
optional => 0 |
125
|
|
|
|
|
|
|
}, |
126
|
|
|
|
|
|
|
DocStructure => { |
127
|
|
|
|
|
|
|
type => ARRAYREF, |
128
|
|
|
|
|
|
|
optional => 0 |
129
|
|
|
|
|
|
|
}, |
130
|
|
|
|
|
|
|
} ); |
131
|
|
|
|
|
|
|
|
132
|
0
|
|
|
|
|
0
|
$self->{_DocOptions} = $config->{DocOptions}; |
133
|
0
|
|
|
|
|
0
|
$self->{_DocStructure} = $config->{DocStructure}; |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# ... then validate dcument options |
136
|
0
|
|
|
|
|
0
|
@temp = ( $self->{_DocOptions} ); |
137
|
0
|
|
|
|
|
0
|
%{$self->{_DocOptions}} = validate( @temp , |
|
0
|
|
|
|
|
0
|
|
138
|
|
|
|
|
|
|
{ |
139
|
|
|
|
|
|
|
Title => { # required, string |
140
|
|
|
|
|
|
|
type => SCALAR, |
141
|
|
|
|
|
|
|
optional => 0 |
142
|
|
|
|
|
|
|
}, |
143
|
|
|
|
|
|
|
Author => { # optional, string, default: '' |
144
|
|
|
|
|
|
|
type => SCALAR, |
145
|
|
|
|
|
|
|
default => '' |
146
|
|
|
|
|
|
|
}, |
147
|
|
|
|
|
|
|
Date => { # optional, string, default: latex sets date |
148
|
|
|
|
|
|
|
type => SCALAR, |
149
|
|
|
|
|
|
|
default => '\today' |
150
|
|
|
|
|
|
|
}, |
151
|
|
|
|
|
|
|
TexOut => { # optional, string, default: 'book.tex' |
152
|
|
|
|
|
|
|
type => SCALAR, |
153
|
|
|
|
|
|
|
default => 'book.tex' |
154
|
|
|
|
|
|
|
}, |
155
|
|
|
|
|
|
|
UserPreamble => { # optional, string, no default |
156
|
|
|
|
|
|
|
type => SCALAR, |
157
|
|
|
|
|
|
|
optional => 1 |
158
|
|
|
|
|
|
|
}, |
159
|
|
|
|
|
|
|
UserPostamble => { # optional, string, no default |
160
|
|
|
|
|
|
|
type => SCALAR, |
161
|
|
|
|
|
|
|
optional => 1 |
162
|
|
|
|
|
|
|
}, |
163
|
|
|
|
|
|
|
AddPreamble => { # optional, default FALSE |
164
|
|
|
|
|
|
|
type => SCALAR, |
165
|
|
|
|
|
|
|
default => 0 |
166
|
|
|
|
|
|
|
}, |
167
|
|
|
|
|
|
|
Head1Level => { # optional, default: 1 (\section) |
168
|
|
|
|
|
|
|
type => SCALAR, |
169
|
|
|
|
|
|
|
default => 1 |
170
|
|
|
|
|
|
|
}, |
171
|
|
|
|
|
|
|
LevelNoNum => { # optional, default: 4 (\paragraph) |
172
|
|
|
|
|
|
|
type => SCALAR, |
173
|
|
|
|
|
|
|
default => 4 |
174
|
|
|
|
|
|
|
}, |
175
|
|
|
|
|
|
|
ReplaceNAMEwithSection => { # optional, default TRUE |
176
|
|
|
|
|
|
|
type => SCALAR, |
177
|
|
|
|
|
|
|
default => 1 |
178
|
|
|
|
|
|
|
}, |
179
|
|
|
|
|
|
|
UniqueLabels => { # optional, default TRUE |
180
|
|
|
|
|
|
|
type => SCALAR, |
181
|
|
|
|
|
|
|
default => 1 |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
} ); |
184
|
|
|
|
|
|
|
#print "Options: ", Dumper( $self->{_DocOptions} ); |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
# Finally, validate the document structure |
187
|
0
|
|
|
|
|
0
|
my $DSRef = $self->{_DocStructure}; |
188
|
|
|
|
|
|
|
|
189
|
0
|
|
|
|
|
0
|
for ( @$DSRef ) { |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# section command can be used to break the document into parts |
192
|
0
|
0
|
|
|
|
0
|
if ( exists( $_->{Section} ) ) { |
|
|
0
|
|
|
|
|
|
193
|
0
|
|
|
|
|
0
|
@temp = ( $_->{Section} ); |
194
|
0
|
|
|
|
|
0
|
%{$_->{Section}} = validate( @temp, |
|
0
|
|
|
|
|
0
|
|
195
|
|
|
|
|
|
|
{ |
196
|
|
|
|
|
|
|
Title => { # required, string for section title |
197
|
|
|
|
|
|
|
type => SCALAR, |
198
|
|
|
|
|
|
|
optional => 0 |
199
|
|
|
|
|
|
|
}, |
200
|
|
|
|
|
|
|
Level => { # optional, string, default: part |
201
|
|
|
|
|
|
|
type => SCALAR, |
202
|
|
|
|
|
|
|
default => 'part' |
203
|
|
|
|
|
|
|
}, |
204
|
|
|
|
|
|
|
} ); |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
# input commands are used to insert pod or tex files |
208
|
|
|
|
|
|
|
elsif ( exists( $_->{Input} ) ) { |
209
|
0
|
|
|
|
|
0
|
@temp = ( $_->{Input} ); |
210
|
0
|
|
|
|
|
0
|
%{$_->{Input}} = validate( @temp, |
|
0
|
|
|
|
|
0
|
|
211
|
|
|
|
|
|
|
{ |
212
|
|
|
|
|
|
|
FileOrPod => { # required, string, tex file name or |
213
|
|
|
|
|
|
|
# POD document to include |
214
|
|
|
|
|
|
|
type => SCALAR, |
215
|
|
|
|
|
|
|
optional => 0 |
216
|
|
|
|
|
|
|
}, |
217
|
|
|
|
|
|
|
SkipUntil => { # optional, string, indicates section |
218
|
|
|
|
|
|
|
# title until which output is to be |
219
|
|
|
|
|
|
|
# supressed; title may be abbreviated. |
220
|
|
|
|
|
|
|
type => SCALAR, |
221
|
|
|
|
|
|
|
default => undef |
222
|
|
|
|
|
|
|
}, |
223
|
|
|
|
|
|
|
SkipFrom => { # optional, string, indicates section |
224
|
|
|
|
|
|
|
# title from which output is to be |
225
|
|
|
|
|
|
|
# supressed; title may be abbreviated. |
226
|
|
|
|
|
|
|
type => SCALAR, |
227
|
|
|
|
|
|
|
default => undef |
228
|
|
|
|
|
|
|
}, |
229
|
|
|
|
|
|
|
} ); |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# store pods for reference (don't worry about including tex files) |
232
|
0
|
|
|
|
|
0
|
push @{$self->{_PodFiles}}, $_->{Input}->{FileOrPod}; |
|
0
|
|
|
|
|
0
|
|
233
|
|
|
|
|
|
|
} |
234
|
|
|
|
|
|
|
else { |
235
|
0
|
|
|
|
|
0
|
confess "Invalid key: only Section and Input are allowed"; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
# print "Structure: ", Dumper( $self->{_DocStructure} ); |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
|
241
|
0
|
|
|
|
|
0
|
return $self; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
=head2 C |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
Read configuration information from a file. The file may be in any |
247
|
|
|
|
|
|
|
format supported by L. |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
The format of the file is as follows (in YAML): |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
--- |
252
|
|
|
|
|
|
|
DocOptions: |
253
|
|
|
|
|
|
|
Title: Your Book |
254
|
|
|
|
|
|
|
Author: Your Name |
255
|
|
|
|
|
|
|
Date: August 2, 2007 |
256
|
|
|
|
|
|
|
TexOut: mybook.tex |
257
|
|
|
|
|
|
|
UserPreamble: | |
258
|
|
|
|
|
|
|
\documentclass{book} |
259
|
|
|
|
|
|
|
UserPostamble: | |
260
|
|
|
|
|
|
|
\cleardoublepage |
261
|
|
|
|
|
|
|
\addcontentsline{toc}{chapter}{\numberline{}Index} |
262
|
|
|
|
|
|
|
\printindex |
263
|
|
|
|
|
|
|
\end{document} |
264
|
|
|
|
|
|
|
AddPreamble: 1 |
265
|
|
|
|
|
|
|
Head1Level: 0 |
266
|
|
|
|
|
|
|
LevelNoNum: 4 |
267
|
|
|
|
|
|
|
DocStructure: |
268
|
|
|
|
|
|
|
- Input: |
269
|
|
|
|
|
|
|
FileOrPod: frontmatter.tex |
270
|
|
|
|
|
|
|
- Section: |
271
|
|
|
|
|
|
|
Level: part |
272
|
|
|
|
|
|
|
Title: First Part |
273
|
|
|
|
|
|
|
- Input: |
274
|
|
|
|
|
|
|
FileOrPod: Catalyst::Manual::Tutorial |
275
|
|
|
|
|
|
|
SkipUntil: DESCRIPTION |
276
|
|
|
|
|
|
|
- Input: |
277
|
|
|
|
|
|
|
FileOrPod: Catalyst::Manual |
278
|
|
|
|
|
|
|
SkipFrom: THANKS |
279
|
|
|
|
|
|
|
- Section: |
280
|
|
|
|
|
|
|
Level: part |
281
|
|
|
|
|
|
|
Title: Appendix |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
Of the document options, only C is required. All others have |
284
|
|
|
|
|
|
|
sensitive defaults. The parameters C, C, and |
285
|
|
|
|
|
|
|
C are passed to L. |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
If the standard preamble is insufficient, it is recommended to set |
288
|
|
|
|
|
|
|
things up as above. Specify a minimal C, set |
289
|
|
|
|
|
|
|
C to a true value, and read the remainder of the preamble |
290
|
|
|
|
|
|
|
from the first input file (here, C). Note, that the |
291
|
|
|
|
|
|
|
preamble must include at least the following LaTeX packages. |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=over |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=item hyperref |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
=item listings |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=item fancyvrb |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
=back |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
The C specifies the sequence of documents to be |
304
|
|
|
|
|
|
|
included, it consists of a list of C |
305
|
|
|
|
|
|
|
directives. The C directives can be used to provide |
306
|
|
|
|
|
|
|
additional section commands (e.g., parts). The C directives |
307
|
|
|
|
|
|
|
specify the file name of a LaTeX document to be included or the name |
308
|
|
|
|
|
|
|
of a POD page. POD pages are parsed and translated to LaTeX. It is |
309
|
|
|
|
|
|
|
possible to skip leading sections in a POD via the C |
310
|
|
|
|
|
|
|
directive or trailing sections via the C directive. |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=cut |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
sub configure_from_file{ |
315
|
1
|
|
|
1
|
1
|
42
|
my $self = shift; |
316
|
1
|
|
|
|
|
2
|
my $file = shift; |
317
|
|
|
|
|
|
|
|
318
|
1
|
|
|
|
|
15
|
my $cfg = Config::Any->load_files({files => [ $file ], use_ext => 1 }); |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
# print 'Config:', Dumper( $cfg->[0] ); |
321
|
|
|
|
|
|
|
|
322
|
0
|
|
|
|
|
|
for (@$cfg) { |
323
|
0
|
|
|
|
|
|
my ($filename, $config) = each %$_; |
324
|
0
|
|
|
|
|
|
$self->configure($config); |
325
|
|
|
|
|
|
|
# warn "loaded config from file: $filename"; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
0
|
|
|
|
|
|
return $self; |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=pod |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=head2 C |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
Construct the latex document by converting each of the PODs from the |
336
|
|
|
|
|
|
|
configuration file. The bulk of the work is done by |
337
|
|
|
|
|
|
|
L. |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
=cut |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
sub parse { |
342
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
# open file for output |
345
|
0
|
|
|
|
|
|
my $fh_out; |
346
|
0
|
|
|
|
|
|
my $outfile = $self->{_DocOptions}->{TexOut}; |
347
|
|
|
|
|
|
|
|
348
|
0
|
0
|
|
|
|
|
open $fh_out, '>', $outfile or confess "Can't create $outfile: $!"; |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
# write preamble to output |
351
|
0
|
|
|
|
|
|
my $preamble = $self->make_preamble( ); |
352
|
0
|
|
|
|
|
|
print $fh_out $preamble; |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
# loop over elements of structure and produce output |
355
|
|
|
|
|
|
|
# uses direct output for non-pod material |
356
|
|
|
|
|
|
|
# Pod::LaTex::parse_from_file for pod |
357
|
0
|
|
|
|
|
|
foreach my $element ( @{$self->{_DocStructure}} ) { |
|
0
|
|
|
|
|
|
|
358
|
0
|
|
|
|
|
|
my $detailRef; |
359
|
|
|
|
|
|
|
|
360
|
0
|
0
|
|
|
|
|
if ( exists( $element->{Section} ) ) { |
361
|
0
|
|
|
|
|
|
$detailRef = $element->{Section}; |
362
|
|
|
|
|
|
|
|
363
|
0
|
0
|
|
|
|
|
if ( $detailRef->{Title} =~ /Appendix/ ) { |
364
|
0
|
|
|
|
|
|
print $fh_out "\n\n\\appendix\n\n"; |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
|
367
|
0
|
|
|
|
|
|
print $fh_out "\n\n\\" . $detailRef->{Level} . |
368
|
|
|
|
|
|
|
"\{$detailRef->{Title}\}\n\n" |
369
|
|
|
|
|
|
|
} |
370
|
|
|
|
|
|
|
|
371
|
0
|
0
|
|
|
|
|
if ( exists( $element->{Input} ) ) { |
372
|
0
|
|
|
|
|
|
$detailRef = $element->{Input}; |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
# is it a tex file? slurp in the file and dump it back out |
375
|
0
|
0
|
|
|
|
|
if ( $detailRef->{FileOrPod} =~ /.tex$/ ) { |
376
|
0
|
|
|
|
|
|
print $fh_out "\n\%\% File: $detailRef->{FileOrPod}\n\n"; |
377
|
|
|
|
|
|
|
|
378
|
0
|
|
|
|
|
|
my $texfile = slurp $detailRef->{FileOrPod}; |
379
|
0
|
|
|
|
|
|
print $fh_out $texfile; |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
else { # it's got to be a POD |
382
|
|
|
|
|
|
|
# reset configuration for Pod::LaTeX |
383
|
0
|
|
|
|
|
|
$self->AddPreamble( 0 ); # no individual preambles; |
384
|
0
|
|
|
|
|
|
$self->UserPreamble( '' ); |
385
|
0
|
|
|
|
|
|
$self->UserPostamble( '' ); |
386
|
0
|
|
|
|
|
|
$self->Head1Level( $self->{_DocOptions}->{Head1Level} ); |
387
|
0
|
|
|
|
|
|
$self->LevelNoNum( $self->{_DocOptions}->{LevelNoNum} ); |
388
|
0
|
|
|
|
|
|
$self->ReplaceNAMEwithSection($self->{_DocOptions}->{ReplaceNAMEwithSection} ); |
389
|
0
|
|
|
|
|
|
$self->UniqueLabels( $self->{_DocOptions}->{UniqueLabels} ); |
390
|
0
|
|
|
|
|
|
$self->Label(''); |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
# prepare for skipping |
393
|
0
|
0
|
|
|
|
|
$self->{_Skipping} = defined $detailRef->{SkipUntil} ? 1 :0; |
394
|
0
|
|
|
|
|
|
$self->{_PastName} = not $self->ReplaceNAMEwithSection(); |
395
|
0
|
|
0
|
|
|
|
$self->{_DoSkip} = $self->{_Skipping} && $self->{_PastName}; |
396
|
0
|
|
|
|
|
|
$self->{SkipUntil} = $detailRef->{SkipUntil}; |
397
|
0
|
|
|
|
|
|
$self->{SkipFrom} = $detailRef->{SkipUntil}; |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
# find file containing pod and parse |
400
|
0
|
|
|
|
|
|
my $location = Pod::Find::pod_where( { -inc => 1 }, |
401
|
|
|
|
|
|
|
$detailRef->{FileOrPod} ); |
402
|
0
|
0
|
|
|
|
|
unless( defined( $location) ) { |
403
|
0
|
|
|
|
|
|
confess "POD not found for $detailRef->{FileOrPod}"; |
404
|
|
|
|
|
|
|
} |
405
|
|
|
|
|
|
|
|
406
|
0
|
|
|
|
|
|
print $fh_out "\n\%\% POD: $detailRef->{FileOrPod}"; |
407
|
0
|
|
|
|
|
|
print $fh_out "\n\%\% File: $location\n\n"; |
408
|
|
|
|
|
|
|
|
409
|
0
|
|
|
|
|
|
$self->parse_from_file( $location, $fh_out ); |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
# output a pending verbatim paragraph (if needed) |
412
|
0
|
|
|
|
|
|
$self->output_verbatim(); |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
} |
415
|
|
|
|
|
|
|
} |
416
|
|
|
|
|
|
|
} |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
# write postamble |
419
|
0
|
|
|
|
|
|
my $postamble = $self->make_postamble( ); |
420
|
0
|
|
|
|
|
|
print $fh_out $postamble; |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
} |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
############################### Overridden subroutines #################### |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=pod |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
=head1 Overriden Subroutines |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
The following routines from L are overridden to modify or |
431
|
|
|
|
|
|
|
extend functionality. |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=cut |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
=pod |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
=head2 C |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
Overwrite the C in L to use the I |
440
|
|
|
|
|
|
|
environment rather than I. |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
The original package breaks listings up into chunks separated by empty |
443
|
|
|
|
|
|
|
lines, here we combine those. output does not happen until we're done |
444
|
|
|
|
|
|
|
with the entire block. See L. |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=cut |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
sub verbatim { |
449
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
450
|
0
|
|
|
|
|
|
my ($paragraph, $line_num, $parobj) = @_; |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
# return immediately if we're currently skipping output |
453
|
0
|
0
|
|
|
|
|
return if $self->{_DoSkip}; |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
# Expand paragraph unless in =begin block |
456
|
0
|
0
|
|
|
|
|
if ($self->{_dont_modify_any_para}) { |
457
|
|
|
|
|
|
|
# Just print as is |
458
|
0
|
|
|
|
|
|
$self->_output($paragraph); |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
} else { |
461
|
|
|
|
|
|
|
|
462
|
0
|
0
|
|
|
|
|
return if $paragraph =~ /^\s+$/; |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
# Clean trailing space |
465
|
0
|
|
|
|
|
|
$paragraph =~ s/\s+$//; |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
# Clean tabs. Routine taken from Tabs.pm |
468
|
|
|
|
|
|
|
# by David Muir Sharnoff muir@idiom.com, |
469
|
|
|
|
|
|
|
# slightly modified by hsmyers@sdragons.com 10/22/01 |
470
|
0
|
|
|
|
|
|
my @l = split("\n",$paragraph); |
471
|
0
|
|
|
|
|
|
foreach (@l) { |
472
|
0
|
|
|
|
|
|
1 while s/(^|\n)([^\t\n]*)(\t+)/ |
473
|
0
|
|
|
|
|
|
$1. $2 . (" " x |
474
|
|
|
|
|
|
|
(4 * length($3) |
475
|
|
|
|
|
|
|
- (length($2) % 4))) |
476
|
|
|
|
|
|
|
/sex; |
477
|
|
|
|
|
|
|
} |
478
|
0
|
|
|
|
|
|
$paragraph = join("\n",@l); |
479
|
|
|
|
|
|
|
# End of change. |
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
# append paragraph to pending verbatim block |
483
|
0
|
0
|
|
|
|
|
if ($self->{_VerbatimParagraph} eq '' ) { |
484
|
0
|
|
|
|
|
|
$self->{_VerbatimParagraph} = $paragraph; |
485
|
|
|
|
|
|
|
} |
486
|
|
|
|
|
|
|
else { |
487
|
0
|
|
|
|
|
|
$self->{_VerbatimParagraph} .= "\n\n" . $paragraph; |
488
|
|
|
|
|
|
|
} |
489
|
|
|
|
|
|
|
} |
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
=pod |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
=head2 C |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
Partially overwrite the functionality in Pod::LaTeX. Specifically, we |
497
|
|
|
|
|
|
|
replace processing of C-tags to use the C of C |
498
|
|
|
|
|
|
|
package. Also, proper hyperlinking is provided via the C |
499
|
|
|
|
|
|
|
package. |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
=cut |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
sub interior_sequence { |
504
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
505
|
|
|
|
|
|
|
|
506
|
0
|
|
|
|
|
|
my ($seq_command, $seq_argument, $pod_seq) = @_; |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
# override C-tags |
509
|
0
|
0
|
|
|
|
|
if ($seq_command eq 'C') { |
|
|
0
|
|
|
|
|
|
510
|
0
|
|
|
|
|
|
my $text = $seq_argument; |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
# often codes are just URL's, set those via \\texttt |
513
|
0
|
0
|
|
|
|
|
if ( $text =~ /(\w+):\/\/(\S+)/ ) { |
514
|
0
|
|
|
|
|
|
$text = $self->_replace_special_chars( $text ); |
515
|
|
|
|
|
|
|
#$text =~ s/(\w)(\/|\?|\.)(\w)/$1$2\\-$3/g; |
516
|
0
|
|
|
|
|
|
$text =~ s/(\/|\?|\.|=)(\w)/\\discretionary{$1}{$2}{$1$2}/g; |
517
|
|
|
|
|
|
|
|
518
|
0
|
|
|
|
|
|
return ' \texttt{'. $text . '} '; |
519
|
|
|
|
|
|
|
} |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
# A list of separators we're willing to use for e.g., \lstinline!time! |
522
|
0
|
|
|
|
|
|
my @separators = ( '!', '+','|', '=', '*', 'q', 'z', 'k', 'Q', 'Z'); |
523
|
|
|
|
|
|
|
|
524
|
0
|
|
|
|
|
|
my $separator; |
525
|
|
|
|
|
|
|
|
526
|
0
|
|
|
|
|
|
do { |
527
|
0
|
|
|
|
|
|
$separator = shift @separators; |
528
|
|
|
|
|
|
|
} while ( index( $text, $separator ) >= 0 ); |
529
|
|
|
|
|
|
|
|
530
|
0
|
0
|
|
|
|
|
unless (defined( $separator )) { |
531
|
0
|
|
|
|
|
|
confess "Can't find a suitable separator for $text."; |
532
|
|
|
|
|
|
|
}; |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
# we turn long-ish in-line codes into displayed versions |
535
|
0
|
0
|
0
|
|
|
|
if ( length( $text ) > 30 && $self->{_inTextBlock}) { |
536
|
0
|
|
|
|
|
|
return "\n" . |
537
|
|
|
|
|
|
|
'\begin{lstlisting}' . |
538
|
|
|
|
|
|
|
"\n$text\n" . '\end{lstlisting}' . "\n"; |
539
|
|
|
|
|
|
|
} |
540
|
|
|
|
|
|
|
else { |
541
|
0
|
|
|
|
|
|
return '\lstinline[breaklines=true]' . |
542
|
|
|
|
|
|
|
$separator . $text . $separator; |
543
|
|
|
|
|
|
|
} |
544
|
|
|
|
|
|
|
} |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
# override L-tags |
548
|
|
|
|
|
|
|
elsif ($seq_command eq 'L') { |
549
|
0
|
|
|
|
|
|
my $link = new Pod::Hyperlink($seq_argument); |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
# undef on failure |
552
|
0
|
0
|
|
|
|
|
unless (defined $link) { |
553
|
0
|
|
|
|
|
|
carp $@; |
554
|
0
|
|
|
|
|
|
return; |
555
|
|
|
|
|
|
|
} |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
# external links |
558
|
0
|
0
|
|
|
|
|
if ( $link->type() eq 'hyperlink' ) { |
|
|
0
|
|
|
|
|
|
559
|
0
|
|
|
|
|
|
my $target = $link->node(); |
560
|
|
|
|
|
|
|
# allow hyphenation in text |
561
|
0
|
|
|
|
|
|
(my $text = $link->text()) =~ |
562
|
|
|
|
|
|
|
s/(\/|\?|\.|=)(\w)/\\discretionary{$1}{$2}{$1$2}/g; |
563
|
0
|
|
|
|
|
|
return "\\href{$target}{$text}"; |
564
|
|
|
|
|
|
|
} |
565
|
|
|
|
|
|
|
elsif ( $link->page() eq '' ) { # link within this POD |
566
|
0
|
|
|
|
|
|
my $target = $self->_create_label( $link->node( ) ); |
567
|
0
|
|
|
|
|
|
my $text = $link->text(); |
568
|
|
|
|
|
|
|
|
569
|
0
|
|
|
|
|
|
return "\\hyperlink{$target}{$text}"; |
570
|
|
|
|
|
|
|
} |
571
|
|
|
|
|
|
|
else { # link to another POD page |
572
|
0
|
|
|
|
|
|
my $page = $link->page( ); |
573
|
|
|
|
|
|
|
|
574
|
0
|
|
|
|
|
|
my $foundPage = grep { $page eq $_ } @{$self->{_PodFiles}}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
|
576
|
0
|
0
|
|
|
|
|
if ( $foundPage > 0 ){ |
577
|
|
|
|
|
|
|
# case 1: link to a page in this collection of PODs |
578
|
0
|
|
|
|
|
|
my $OrigLabel = $self->Label; |
579
|
0
|
|
|
|
|
|
$self->Label( $page ); |
580
|
|
|
|
|
|
|
|
581
|
0
|
0
|
|
|
|
|
my $target = $link->node( ) |
582
|
|
|
|
|
|
|
? $self->_create_label( $link->node( ) ) |
583
|
|
|
|
|
|
|
: "_$page"; |
584
|
0
|
|
|
|
|
|
(my $text = $link->text()) =~ |
585
|
|
|
|
|
|
|
s/::(\w+)/\\discretionary{::}{$1}{::$1}/g; |
586
|
|
|
|
|
|
|
|
587
|
0
|
|
|
|
|
|
return "\\hyperlink{$target}{$text}"; |
588
|
|
|
|
|
|
|
|
589
|
0
|
|
|
|
|
|
$self->Label( $OrigLabel ) =~ |
590
|
|
|
|
|
|
|
s/::(\w+)/\\discretionary{::}{$1}{::$1}/g; |
591
|
|
|
|
|
|
|
} |
592
|
|
|
|
|
|
|
else { |
593
|
|
|
|
|
|
|
# case 2: link to a page NOT in this collection (link to CPAN) |
594
|
0
|
|
|
|
|
|
my $cpan_link = "http://search.cpan.org/search?query=" . |
595
|
|
|
|
|
|
|
$link->page(); |
596
|
0
|
|
|
|
|
|
(my $text = $link->text())=~ |
597
|
|
|
|
|
|
|
s/::(\w+)/\\discretionary{::}{$1}{::$1}/g; |
598
|
|
|
|
|
|
|
|
599
|
0
|
|
|
|
|
|
return "\\href{$cpan_link}{$text}"; |
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
} |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
# print "Link: $seq_argument ", Dumper( $link ); |
604
|
|
|
|
|
|
|
} |
605
|
|
|
|
|
|
|
else { |
606
|
|
|
|
|
|
|
# anything we didn't process is passed to Pod::LaTeX |
607
|
|
|
|
|
|
|
return |
608
|
0
|
|
|
|
|
|
$self->SUPER::interior_sequence( $seq_command, |
609
|
|
|
|
|
|
|
$seq_argument, $pod_seq ); |
610
|
|
|
|
|
|
|
} |
611
|
|
|
|
|
|
|
} |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
=pod |
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
=head2 C |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
Plain text paragraph. Modified to output any pending C output. |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
=cut |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
sub textblock { |
623
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
624
|
0
|
|
|
|
|
|
my ($paragraph, $line_num, $parobj) = @_; |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
# output a pending verbatim paragraph (if needed) |
627
|
0
|
|
|
|
|
|
$self->output_verbatim(); |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
# return immediately if we're currently skipping output |
630
|
0
|
0
|
|
|
|
|
return if $self->{_DoSkip}; |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
# mark the fact that we're in a text block |
633
|
0
|
|
|
|
|
|
$self->{_inTextBlock} = 1; |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
# invoke parent function |
636
|
0
|
|
|
|
|
|
$self->SUPER::textblock( $paragraph, $line_num, $parobj ); |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
# mark the fact that we're not in a text block |
639
|
0
|
|
|
|
|
|
$self->{_inTextBlock} = 0; |
640
|
|
|
|
|
|
|
} |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
=pod |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
=head2 C |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
Process basic pod commands. Modified to output any pending C output. |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
=cut |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
sub command { |
652
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
653
|
0
|
|
|
|
|
|
my ($command, $paragraph, $line_num, $parobj) = @_; |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
# output a pending verbatim paragraph (if needed) |
656
|
0
|
|
|
|
|
|
$self->output_verbatim(); |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
# update skipping behaviour |
659
|
0
|
0
|
|
|
|
|
if ( $self->{_DoSkip} ) { |
660
|
0
|
0
|
0
|
|
|
|
$self->{_DoSkip} = 0 |
661
|
|
|
|
|
|
|
if $paragraph =~ /$self->{SkipUntil}/ && $command =~ /head/i; |
662
|
|
|
|
|
|
|
} |
663
|
|
|
|
|
|
|
else { |
664
|
0
|
0
|
0
|
|
|
|
$self->{_DoSkip} = 1 |
|
|
|
0
|
|
|
|
|
665
|
|
|
|
|
|
|
if defined $self->{SkipFrom} && |
666
|
|
|
|
|
|
|
$paragraph =~ /$self->{SkipFrom}/ && |
667
|
|
|
|
|
|
|
$command =~ /head/i; |
668
|
|
|
|
|
|
|
} |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
# return immediately if we're currently skipping output |
671
|
0
|
0
|
|
|
|
|
return if $self->{_DoSkip}; |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
# invoke parent function |
674
|
0
|
|
|
|
|
|
$self->SUPER::command( $command, $paragraph, $line_num, $parobj ); |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
} |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
=pod |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
=begin __PRIVATE__ |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
=head2 C |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
Print a heading of the required level. |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
$parser->head($level, $paragraph, $parobj); |
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
The first argument is the pod heading level. The second argument |
689
|
|
|
|
|
|
|
is the contents of the heading. The 3rd argument is a Pod::Paragraph |
690
|
|
|
|
|
|
|
object so that the line number can be extracted. |
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
This is an extension of the function with the same name in |
693
|
|
|
|
|
|
|
L. Additonal functionality includes creating internal |
694
|
|
|
|
|
|
|
hyperlinks (using hyperref) and skipping of document sections. |
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
Also, the output produced for latex's section commands is changed so |
697
|
|
|
|
|
|
|
that labels and index entries are moved outside the section |
698
|
|
|
|
|
|
|
command. This is better because section titles are "moving" arguments |
699
|
|
|
|
|
|
|
and the included commands are "fragile". |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
=cut |
702
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
sub head { |
704
|
0
|
|
|
0
|
1
|
|
my $ self = shift; |
705
|
|
|
|
|
|
|
|
706
|
0
|
|
|
|
|
|
my $num = shift; |
707
|
0
|
|
|
|
|
|
my $paragraph = shift; |
708
|
0
|
|
|
|
|
|
my $parobj = shift; |
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
# If we replace 'head1 NAME' with a section |
711
|
|
|
|
|
|
|
# we return immediately if we get it |
712
|
0
|
0
|
0
|
|
|
|
if ($self->{_CURRENT_HEAD1} =~ /^NAME/i && |
713
|
|
|
|
|
|
|
$self->ReplaceNAMEwithSection()) { |
714
|
|
|
|
|
|
|
# mark the fact that we found just found 'head Name' |
715
|
0
|
|
|
|
|
|
$self->{_PastName} = -1; |
716
|
0
|
|
|
|
|
|
return; |
717
|
|
|
|
|
|
|
} |
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
# return immediately if we're currently skipping output |
720
|
0
|
0
|
|
|
|
|
return if $self->{_DoSkip}; |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
# Create a label |
723
|
0
|
|
|
|
|
|
my $label = $self->_create_label($paragraph); |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
# Create an index entry |
726
|
0
|
|
|
|
|
|
my $index = $self->_create_index($paragraph); |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
# Work out position in the above array taking into account |
729
|
|
|
|
|
|
|
# that =head1 is equivalent to $self->Head1Level |
730
|
|
|
|
|
|
|
|
731
|
0
|
|
|
|
|
|
my $level = $self->Head1Level() - 1 + $num; |
732
|
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
# Warn if heading to large |
734
|
0
|
|
|
|
|
|
my @LatexSections = (qw/ |
735
|
|
|
|
|
|
|
chapter |
736
|
|
|
|
|
|
|
section |
737
|
|
|
|
|
|
|
subsection |
738
|
|
|
|
|
|
|
subsubsection |
739
|
|
|
|
|
|
|
paragraph |
740
|
|
|
|
|
|
|
subparagraph |
741
|
|
|
|
|
|
|
/); |
742
|
|
|
|
|
|
|
|
743
|
0
|
0
|
|
|
|
|
if ($num > $#LatexSections) { |
744
|
0
|
|
|
|
|
|
my $line = $parobj->file_line; |
745
|
0
|
|
|
|
|
|
my $file = $self->input_file; |
746
|
0
|
|
|
|
|
|
warn "Heading level too large ($level) for LaTeX at line $line of file $file\n"; |
747
|
0
|
|
|
|
|
|
$level = $#LatexSections; |
748
|
|
|
|
|
|
|
} |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
# Check to see whether section should be unnumbered |
751
|
0
|
0
|
|
|
|
|
my $star = ($level >= $self->LevelNoNum ? '*' : ''); |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
# if there are latex commands inside the section text, we insert a |
754
|
|
|
|
|
|
|
# \protect statement before |
755
|
0
|
|
|
|
|
|
$paragraph =~ s/\\(\w+)/\\protect\\$1/g; |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
# allow hyphenation after :: |
758
|
0
|
0
|
|
|
|
|
$paragraph =~ s/::(\w+)/\\discretionary{::}{$1}{::$1}/g |
759
|
|
|
|
|
|
|
unless $paragraph =~ /\\protect/; |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
# Section |
762
|
0
|
|
|
|
|
|
$self->_output("\n\\" .$LatexSections[$level] .$star ."{$paragraph}\n"); |
763
|
0
|
|
|
|
|
|
$self->_output("\\label{".$label ."}\n"); |
764
|
0
|
0
|
|
|
|
|
$self->_output("\\index{".$index."}\n") unless $index =~ m/http:\/\//; |
765
|
|
|
|
|
|
|
# additional hypertarget for hyperref |
766
|
|
|
|
|
|
|
# my $label = $self->_create_label($paragraph); |
767
|
0
|
|
|
|
|
|
$self->_output("\\hypertarget{$label}{}\n\n"); |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
# check if we just set the 'Head = Name' information |
770
|
0
|
0
|
|
|
|
|
if ( $self->{_PastName} == -1 ) { |
771
|
0
|
|
|
|
|
|
$self->{_PastName} = 1; |
772
|
0
|
|
|
|
|
|
$self->{_DoSkip} = $self->{_Skipping}; |
773
|
|
|
|
|
|
|
} |
774
|
|
|
|
|
|
|
} |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
=pod |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
=head2 C<_replace_special_chars> |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
Subroutine to replace characters that are special in C |
781
|
|
|
|
|
|
|
with the escaped forms |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
$escaped = $parser->_replace_special_chars($paragraph); |
784
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
Need to call this routine before interior_sequences are munged but not |
786
|
|
|
|
|
|
|
if verbatim or C<>. It must be called before interpolation of interior |
787
|
|
|
|
|
|
|
sequences so that curly brackets and special latex characters inserted |
788
|
|
|
|
|
|
|
during interpolation are not themselves escaped. This means that < and |
789
|
|
|
|
|
|
|
> can not be modified here since the text still contains interior |
790
|
|
|
|
|
|
|
sequences. |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
Special characters and the C equivalents are: |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
} \} |
795
|
|
|
|
|
|
|
{ \{ |
796
|
|
|
|
|
|
|
_ \_ |
797
|
|
|
|
|
|
|
$ \$ |
798
|
|
|
|
|
|
|
% \% |
799
|
|
|
|
|
|
|
& \& |
800
|
|
|
|
|
|
|
\ $\backslash$ |
801
|
|
|
|
|
|
|
^ \^{} |
802
|
|
|
|
|
|
|
# \# |
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
Modified this routine to ignore C<> commands and leave ~ alone. |
805
|
|
|
|
|
|
|
|
806
|
|
|
|
|
|
|
=cut |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
sub _replace_special_chars { |
809
|
0
|
|
|
0
|
|
|
my $self = shift; |
810
|
0
|
|
|
|
|
|
my $paragraph = shift; |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
# Go through paragraph and extract all C<> sequences and replace |
813
|
|
|
|
|
|
|
# them with something innocuous: 'CqqPodBook', a string that's |
814
|
|
|
|
|
|
|
# unlikely to appear. They will be restored after interpolation by |
815
|
|
|
|
|
|
|
# _replace_special_chars_late. |
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
# make paragraph into a single line, in case C<> breaks across lines. |
818
|
0
|
|
|
|
|
|
$paragraph = join ' ', split /\s+/, $paragraph; |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
# Extract C<> sequences and save for later reinsertions, this is |
821
|
|
|
|
|
|
|
# tricky because pod also allows C<<>>, and so on. We simply rely on |
822
|
|
|
|
|
|
|
# L's C to help us find C<> interior |
823
|
|
|
|
|
|
|
# sequences. |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
|
826
|
0
|
|
|
|
|
|
my @Codes; |
827
|
|
|
|
|
|
|
|
828
|
0
|
0
|
|
|
|
|
if ( $paragraph =~ m/C(<(?:<+\s)?)/ ) { |
829
|
|
|
|
|
|
|
|
830
|
0
|
|
|
|
|
|
my $ptree = $self->parse_text( $paragraph ); |
831
|
|
|
|
|
|
|
|
832
|
0
|
|
|
|
|
|
$paragraph = $self->expandCparagraph( $ptree, \@Codes ); |
833
|
|
|
|
|
|
|
} |
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
# hide \~ (as it occurs in URLs) from replacement |
836
|
0
|
|
|
|
|
|
$paragraph =~ s/\/~/BACKSLASHTILDE/g; |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
# invoke function in parent |
839
|
0
|
|
|
|
|
|
$paragraph = $self->SUPER::_replace_special_chars( $paragraph ); |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
# store @Codes so that they can be re-inserted by _replace_special_chars_late |
842
|
0
|
|
|
|
|
|
$self->{_Codes} = \@Codes; |
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
# check for URL's that aren't marked with L<> or bare e-mail addresses |
845
|
|
|
|
|
|
|
#if ( $paragraph =~ /\w+:\/\/\S+/ && not $paragraph =~ /(?:<|\|)\w+:\/\/\S+/ ) { |
846
|
|
|
|
|
|
|
# $paragraph =~ s/(\w+:\/\/\S+)/ L<$1> /g; |
847
|
|
|
|
|
|
|
#} |
848
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
# $paragraph =~ s/[^<]\s*(\w+@\w+(\w|\.)+)\s*[^>]/ L /g; |
850
|
|
|
|
|
|
|
|
851
|
0
|
|
|
|
|
|
return $paragraph; |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
} |
854
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
=pod |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
=head2 C<_replace_special_chars_late> |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
Replace special characters that can not be replaced before interior |
860
|
|
|
|
|
|
|
sequence interpolation. See C<_replace_special_chars> for a routine |
861
|
|
|
|
|
|
|
to replace special characters prior to interpolation of interior |
862
|
|
|
|
|
|
|
sequences. |
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
Does the following transformation: |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
< $<$ |
867
|
|
|
|
|
|
|
> $>$ |
868
|
|
|
|
|
|
|
| $|$ |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
Modified this routine to reinsert C<> commands and then interpolate them. |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
=cut |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
sub _replace_special_chars_late { |
875
|
0
|
|
|
0
|
|
|
my $self = shift; |
876
|
0
|
|
|
|
|
|
my $paragraph = shift; |
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
# invoke function in parent |
879
|
0
|
|
|
|
|
|
$paragraph = $self->SUPER::_replace_special_chars_late( $paragraph ); |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
# Put C<> back in and interpolate |
882
|
0
|
0
|
|
|
|
|
if ( $paragraph =~ /CqqPodBook/ ) { |
883
|
0
|
|
|
|
|
|
my @Codes = @{$self->{_Codes}}; |
|
0
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
|
885
|
0
|
|
|
|
|
|
my $new_para = ''; |
886
|
0
|
|
|
|
|
|
my $segment; |
887
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
# put /~ back |
889
|
0
|
|
|
|
|
|
$paragraph =~ s/BACKSLASHTILDE/\/~/g; |
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
# split paragraph into segments separated by marker |
892
|
0
|
|
|
|
|
|
my @Segments = split 'CqqPodBook', $paragraph; |
893
|
0
|
|
|
|
|
|
foreach my $code ( @Codes ) { |
894
|
0
|
|
|
|
|
|
$segment = shift @Segments; |
895
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
# append original code where marker used to be |
897
|
0
|
0
|
|
|
|
|
$segment = '' unless defined $segment; |
898
|
0
|
|
|
|
|
|
$new_para .= $segment . $code; |
899
|
|
|
|
|
|
|
} |
900
|
|
|
|
|
|
|
# don't forget the final segment |
901
|
0
|
|
|
|
|
|
$segment = shift @Segments; |
902
|
0
|
0
|
|
|
|
|
$new_para .= $segment if defined( $segment ); |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
# now, the C<> tags must be interpolated |
905
|
0
|
|
|
|
|
|
$paragraph = $self->interpolate( $new_para, 1); |
906
|
|
|
|
|
|
|
} |
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
|
909
|
0
|
|
|
|
|
|
return $paragraph; |
910
|
|
|
|
|
|
|
} |
911
|
|
|
|
|
|
|
|
912
|
|
|
|
|
|
|
=pod |
913
|
|
|
|
|
|
|
|
914
|
|
|
|
|
|
|
=head2 C |
915
|
|
|
|
|
|
|
|
916
|
|
|
|
|
|
|
Augment the functionality of the function in the parent by setting a |
917
|
|
|
|
|
|
|
hypertarget if the item creates an index entry. |
918
|
|
|
|
|
|
|
|
919
|
|
|
|
|
|
|
$parser->add_item($paragraph, $line_num); |
920
|
|
|
|
|
|
|
|
921
|
|
|
|
|
|
|
=end __PRIVATE__ |
922
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
=cut |
924
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
sub add_item { |
926
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
927
|
0
|
|
|
|
|
|
my $paragraph = shift; |
928
|
0
|
|
|
|
|
|
my $line_num = shift; |
929
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
# return immediately if we're currently skipping output |
931
|
0
|
0
|
|
|
|
|
return if $self->{_DoSkip}; |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
# figure out the type of list (from Pod::LaTeX) |
934
|
0
|
|
|
|
|
|
$paragraph =~ s/\s+$//; |
935
|
0
|
|
|
|
|
|
$paragraph =~ s/^\s+//; |
936
|
|
|
|
|
|
|
|
937
|
0
|
|
|
|
|
|
my $type; |
938
|
0
|
0
|
|
|
|
|
if (substr($paragraph, 0,1) eq '*') { |
|
|
0
|
|
|
|
|
|
939
|
0
|
|
|
|
|
|
$type = 'itemize'; |
940
|
|
|
|
|
|
|
} elsif ($paragraph =~ /^\d/) { |
941
|
0
|
|
|
|
|
|
$type = 'enumerate'; |
942
|
|
|
|
|
|
|
} else { |
943
|
0
|
|
|
|
|
|
$type = 'description'; |
944
|
|
|
|
|
|
|
} |
945
|
|
|
|
|
|
|
|
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
# description texts cannot contain \lstinline or \Verb commands, |
948
|
|
|
|
|
|
|
# change to \textt |
949
|
0
|
0
|
|
|
|
|
if ($type eq 'description') { |
950
|
0
|
|
|
|
|
|
$paragraph =~ s/\\lstinline\[breaklines=true\](\S)/DqqPodBook/g; |
951
|
0
|
|
|
|
|
|
my $delim = $1; |
952
|
|
|
|
|
|
|
|
953
|
0
|
0
|
|
|
|
|
if ( defined $delim ) { |
954
|
0
|
|
|
|
|
|
my $pos = -1; |
955
|
0
|
|
|
|
|
|
while ( $paragraph =~ m/DqqPodBook(.+)$delim/g ) { |
956
|
0
|
|
|
|
|
|
my $contents = $1; |
957
|
0
|
|
|
|
|
|
my $pos = pos( $paragraph )-1; |
958
|
0
|
|
|
|
|
|
substr( $paragraph, $pos, 1 ) = 'PodBookDqq'; |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
# ensure $contents contains nothing objectionable to latex |
961
|
0
|
|
|
|
|
|
$contents = $self->_replace_special_chars( $contents ); |
962
|
0
|
|
|
|
|
|
$contents = $self->_replace_special_chars_late( $contents ); |
963
|
|
|
|
|
|
|
|
964
|
0
|
|
|
|
|
|
$paragraph =~ s/DqqPodBook(.+)PodBookDqq/\\texttt\{$contents\}/; |
965
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
} |
967
|
|
|
|
|
|
|
} |
968
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
} |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
# invoke function in parent |
973
|
0
|
|
|
|
|
|
$self->SUPER::add_item( $paragraph, $line_num ); |
974
|
|
|
|
|
|
|
|
975
|
|
|
|
|
|
|
# if $paragraph contains an \\index call, we also set a hypertarget. |
976
|
0
|
0
|
|
|
|
|
if ( $paragraph =~ /\\index\{(\S+)\}/ ) { |
977
|
0
|
|
|
|
|
|
( my $label = $1 ) =~ s/!/_/g; |
978
|
0
|
|
|
|
|
|
$self->_output("\\hypertarget{$label}{}"); |
979
|
|
|
|
|
|
|
} |
980
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
} |
982
|
|
|
|
|
|
|
|
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
############################### Private Subroutines ######################## |
985
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
=pod |
987
|
|
|
|
|
|
|
|
988
|
|
|
|
|
|
|
=begin __PRIVATE__ |
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
=head1 Private Subroutines that are exclusive to this package |
991
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
=cut |
993
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
=pod |
995
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
=head2 C |
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
Create a string for the document preamble; this normally starts with |
999
|
|
|
|
|
|
|
I<\documentclass{book}> and ends with I<\begin{document}>. |
1000
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
If C is C no output is produced. If |
1002
|
|
|
|
|
|
|
C is set, then the preamble is set from that. Otherwise, |
1003
|
|
|
|
|
|
|
a default preamble is produced. |
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
=cut |
1006
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
sub make_preamble{ |
1008
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
1009
|
|
|
|
|
|
|
|
1010
|
0
|
|
|
|
|
|
my $preamble = ''; |
1011
|
|
|
|
|
|
|
|
1012
|
0
|
0
|
|
|
|
|
if ( $self->{_DocOptions}->{AddPreamble} ) { |
1013
|
|
|
|
|
|
|
|
1014
|
0
|
0
|
|
|
|
|
if ( exists( $self->{_DocOptions}->{UserPreamble} ) ){ |
1015
|
0
|
|
|
|
|
|
$preamble = $self->{_DocOptions}->{UserPreamble}; |
1016
|
|
|
|
|
|
|
} |
1017
|
|
|
|
|
|
|
else { # default preamble |
1018
|
0
|
|
|
|
|
|
my $config = ''; |
1019
|
0
|
|
|
|
|
|
for (@{$self->{_DocStructure}}) { |
|
0
|
|
|
|
|
|
|
1020
|
0
|
|
|
|
|
|
my ($type, $detailRef) = each( %{$_} ); |
|
0
|
|
|
|
|
|
|
1021
|
0
|
|
|
|
|
|
$config .= "\n" . '%% ' . $type . ":"; |
1022
|
0
|
|
|
|
|
|
foreach my $field ( keys %$detailRef ) { |
1023
|
0
|
0
|
|
|
|
|
if ( defined( $detailRef->{$field} ) ) { |
1024
|
0
|
|
|
|
|
|
$config .= "\n" . '%% ' . $field . ": " . |
1025
|
|
|
|
|
|
|
$detailRef->{$field}; |
1026
|
|
|
|
|
|
|
} |
1027
|
|
|
|
|
|
|
} |
1028
|
|
|
|
|
|
|
} |
1029
|
|
|
|
|
|
|
|
1030
|
0
|
|
|
|
|
|
my $class = ref($self); |
1031
|
0
|
|
|
|
|
|
my $now = gmtime(time); |
1032
|
0
|
|
|
|
|
|
my $author = $self->{_DocOptions}->{Author}; |
1033
|
0
|
|
|
|
|
|
my $title = $self->{_DocOptions}->{Title}; |
1034
|
0
|
|
|
|
|
|
my $date = $self->{_DocOptions}->{Date}; |
1035
|
|
|
|
|
|
|
|
1036
|
0
|
|
|
|
|
|
$preamble = << "__END_PREAMBLE__" |
1037
|
|
|
|
|
|
|
\\documentclass[11pt]{book} |
1038
|
|
|
|
|
|
|
\\usepackage[T1]{fontenc} |
1039
|
|
|
|
|
|
|
\\usepackage{textcomp} |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
\\usepackage[pdftex, |
1042
|
|
|
|
|
|
|
pdftitle={$title}, |
1043
|
|
|
|
|
|
|
colorlinks, |
1044
|
|
|
|
|
|
|
breaklinks, |
1045
|
|
|
|
|
|
|
pdfauthor={$author}]{hyperref} |
1046
|
|
|
|
|
|
|
|
1047
|
|
|
|
|
|
|
\\usepackage[papersize={7.44in,9.68in},scale=0.8]{geometry} |
1048
|
|
|
|
|
|
|
|
1049
|
|
|
|
|
|
|
\\usepackage{listings} |
1050
|
|
|
|
|
|
|
\\newcommand{\\MyHookSign}{\\hbox{\\ensuremath\\hookleftarrow}} |
1051
|
|
|
|
|
|
|
% |
1052
|
|
|
|
|
|
|
%% Latex generated from configuration: $config |
1053
|
|
|
|
|
|
|
%% Using the perl module $class |
1054
|
|
|
|
|
|
|
%% Converted on $now |
1055
|
|
|
|
|
|
|
|
1056
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
\\usepackage{makeidx} |
1058
|
|
|
|
|
|
|
\\makeindex |
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
\\usepackage{fancyvrb} |
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
\% \\lstset{basicstyle={\\small\\ttfamily},numberbychapter=false,showstringspaces=false,\% |
1063
|
|
|
|
|
|
|
\% classoffset=0,\% |
1064
|
|
|
|
|
|
|
\% language=Perl,commentstyle={\\footnotesize\\ttfamily},keywordstyle={\\bfseries},identifierstyle={\\ttfamily},\% |
1065
|
|
|
|
|
|
|
\% classoffset=1,\% |
1066
|
|
|
|
|
|
|
\% language=SQL,commentstyle={\\footnotesize\\ttfamily},keywordstyle={\\bfseries},identifierstyle={\\ttfamily}} |
1067
|
|
|
|
|
|
|
|
1068
|
|
|
|
|
|
|
\\lstset{basicstyle={\\footnotesize\\ttfamily}, |
1069
|
|
|
|
|
|
|
breaklines=true,prebreak={\\space\\MyHookSign}} |
1070
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
\\begin{document} |
1072
|
|
|
|
|
|
|
\\pagestyle{empty} |
1073
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
\\title{$title} |
1075
|
|
|
|
|
|
|
\\author{$author} |
1076
|
|
|
|
|
|
|
\\date{$date} |
1077
|
|
|
|
|
|
|
|
1078
|
|
|
|
|
|
|
\\maketitle |
1079
|
|
|
|
|
|
|
|
1080
|
|
|
|
|
|
|
\\cleardoublepage |
1081
|
|
|
|
|
|
|
\\pagenumbering{roman} |
1082
|
|
|
|
|
|
|
\\pagestyle{headings} |
1083
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
\\addcontentsline{toc}{chapter}{\\numberline{}Contents} |
1085
|
|
|
|
|
|
|
\\tableofcontents |
1086
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
\\cleardoublepage |
1088
|
|
|
|
|
|
|
\\pagenumbering{arabic} |
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
__END_PREAMBLE__ |
1091
|
|
|
|
|
|
|
|
1092
|
|
|
|
|
|
|
} |
1093
|
|
|
|
|
|
|
} |
1094
|
|
|
|
|
|
|
|
1095
|
0
|
|
|
|
|
|
return $preamble; |
1096
|
|
|
|
|
|
|
} |
1097
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
=pod |
1101
|
|
|
|
|
|
|
|
1102
|
|
|
|
|
|
|
=head2 C |
1103
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
Create a string for the document postamble; this normally is just |
1105
|
|
|
|
|
|
|
I<\end{document}>. |
1106
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
If C is C no output is produced. If |
1108
|
|
|
|
|
|
|
C is set, then the postamble is set from that. Otherwise, |
1109
|
|
|
|
|
|
|
a default postamble is produced. |
1110
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
=cut |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
sub make_postamble{ |
1114
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
1115
|
|
|
|
|
|
|
|
1116
|
0
|
|
|
|
|
|
my $postamble = ''; |
1117
|
|
|
|
|
|
|
|
1118
|
0
|
0
|
|
|
|
|
if ( $self->{_DocOptions}->{AddPreamble} ) { |
1119
|
|
|
|
|
|
|
|
1120
|
0
|
0
|
|
|
|
|
if ( exists( $self->{_DocOptions}->{UserPostamble} ) ){ |
1121
|
0
|
|
|
|
|
|
$postamble = $self->{_DocOptions}->{UserPostamble}; |
1122
|
|
|
|
|
|
|
} |
1123
|
|
|
|
|
|
|
else { # default postamble |
1124
|
|
|
|
|
|
|
|
1125
|
0
|
|
|
|
|
|
$postamble = '\printindex' . "\n" . '\end{document}' . "\n"; |
1126
|
|
|
|
|
|
|
} |
1127
|
|
|
|
|
|
|
} |
1128
|
|
|
|
|
|
|
|
1129
|
0
|
|
|
|
|
|
return $postamble; |
1130
|
|
|
|
|
|
|
} |
1131
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
=pod |
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
=head2 C |
1135
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
Output a pending verbatim block. |
1137
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
=cut |
1139
|
|
|
|
|
|
|
|
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
sub output_verbatim{ |
1142
|
0
|
|
|
0
|
1
|
|
my $self =shift; |
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
# nothing to output? return. |
1145
|
0
|
0
|
|
|
|
|
if ( $self->{_VerbatimParagraph} eq '' ) { |
1146
|
0
|
|
|
|
|
|
return; |
1147
|
|
|
|
|
|
|
} |
1148
|
|
|
|
|
|
|
|
1149
|
0
|
|
|
|
|
|
my $paragraph = $self->{_VerbatimParagraph}; |
1150
|
|
|
|
|
|
|
|
1151
|
0
|
|
|
|
|
|
my $maxLen = 0; |
1152
|
0
|
|
|
|
|
|
my @lines = split /\n/, $paragraph; |
1153
|
0
|
|
|
|
|
|
for ( @lines ) { |
1154
|
0
|
|
|
|
|
|
my $len = length; |
1155
|
0
|
0
|
|
|
|
|
$maxLen = $len unless $len < $maxLen; |
1156
|
|
|
|
|
|
|
} |
1157
|
|
|
|
|
|
|
|
1158
|
|
|
|
|
|
|
# $self->_output("\n\nLength of line: $maxLen\n\n"); |
1159
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
|
1161
|
0
|
|
|
|
|
|
my $VerbatimOptions = 'fontfamily=courier,gobble=1,frame=lines'; |
1162
|
|
|
|
|
|
|
|
1163
|
0
|
0
|
|
|
|
|
if ( $maxLen > 95 ) { |
1164
|
0
|
|
|
|
|
|
$self->_output("\n" . '\begin{lstlisting}[frame=lines,gobble=1]' . |
1165
|
|
|
|
|
|
|
"\n$paragraph\n". |
1166
|
|
|
|
|
|
|
'\end{lstlisting}'."\n\n"); |
1167
|
|
|
|
|
|
|
} |
1168
|
|
|
|
|
|
|
else{ |
1169
|
0
|
0
|
|
|
|
|
if ( $maxLen > 83 ) { |
|
|
0
|
|
|
|
|
|
1170
|
0
|
|
|
|
|
|
$VerbatimOptions .= ',fontsize=\scriptsize'; |
1171
|
|
|
|
|
|
|
} |
1172
|
|
|
|
|
|
|
elsif ( $maxLen > 70 ) { |
1173
|
0
|
|
|
|
|
|
$VerbatimOptions .= ',fontsize=\footnotesize'; |
1174
|
|
|
|
|
|
|
} |
1175
|
|
|
|
|
|
|
else { |
1176
|
0
|
|
|
|
|
|
$VerbatimOptions .= ',fontsize=\small'; |
1177
|
|
|
|
|
|
|
} |
1178
|
|
|
|
|
|
|
|
1179
|
0
|
|
|
|
|
|
$self->_output("\n" . '\begin{Verbatim}[' . $VerbatimOptions . ']' . |
1180
|
|
|
|
|
|
|
"\n$paragraph\n". |
1181
|
|
|
|
|
|
|
'\end{Verbatim}'."\n\n"); |
1182
|
|
|
|
|
|
|
} |
1183
|
|
|
|
|
|
|
|
1184
|
|
|
|
|
|
|
# reset $self->{_VerbatimParagraph} |
1185
|
0
|
|
|
|
|
|
$self->{_VerbatimParagraph} = ''; |
1186
|
|
|
|
|
|
|
} |
1187
|
|
|
|
|
|
|
|
1188
|
|
|
|
|
|
|
=pod |
1189
|
|
|
|
|
|
|
|
1190
|
|
|
|
|
|
|
=head2 C |
1191
|
|
|
|
|
|
|
|
1192
|
|
|
|
|
|
|
Process a paragraph containing C<> tags to protect those tags from |
1193
|
|
|
|
|
|
|
interpolation. |
1194
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
=cut |
1196
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
sub expandCparagraph{ |
1198
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
1199
|
0
|
|
|
|
|
|
my $ptree = shift; |
1200
|
0
|
|
|
|
|
|
my $CodesRef = shift; |
1201
|
|
|
|
|
|
|
|
1202
|
0
|
|
|
|
|
|
my $CParagraph = ''; |
1203
|
|
|
|
|
|
|
|
1204
|
|
|
|
|
|
|
# traverse the parse tree in depth first order |
1205
|
0
|
|
|
|
|
|
foreach my $node ( @$ptree ) { |
1206
|
0
|
0
|
0
|
|
|
|
if ( ref $node && $node->isa( "Pod::InteriorSequence" ) ) { |
1207
|
|
|
|
|
|
|
# its an interior sequence, is it a C<> sequence? |
1208
|
0
|
0
|
|
|
|
|
if ( $node->{-name} eq 'C' ) { |
1209
|
0
|
|
|
|
|
|
my @CCodes = (); |
1210
|
0
|
|
|
|
|
|
my $text = |
1211
|
|
|
|
|
|
|
$self->expandCparagraph( $node->{-ptree}, \@CCodes); |
1212
|
0
|
0
|
|
|
|
|
if ( $#CCodes > -1 ) { |
1213
|
0
|
|
|
|
|
|
carp "Found nested C tags, expect the unexpected:\n $text"; |
1214
|
|
|
|
|
|
|
} |
1215
|
|
|
|
|
|
|
|
1216
|
|
|
|
|
|
|
# manually expand E and E inside C tags |
1217
|
0
|
|
|
|
|
|
$text =~ s/E/
|
1218
|
0
|
|
|
|
|
|
$text =~ s/E/>/g; |
1219
|
|
|
|
|
|
|
|
1220
|
|
|
|
|
|
|
# store code, making sure we have plenty of <'s |
1221
|
0
|
|
|
|
|
|
push @$CodesRef, 'C<<<< ' . $text . ' >>>>'; |
1222
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
# insert marker |
1224
|
0
|
|
|
|
|
|
$CParagraph .= 'CqqPodBook'; |
1225
|
|
|
|
|
|
|
} |
1226
|
|
|
|
|
|
|
else { |
1227
|
|
|
|
|
|
|
# not a C-sequence, just put it back together |
1228
|
0
|
|
|
|
|
|
$CParagraph .= $node->{-name} . |
1229
|
|
|
|
|
|
|
$node->{-ldelim} . |
1230
|
|
|
|
|
|
|
$self->expandCparagraph( $node->{-ptree}, $CodesRef ) . |
1231
|
|
|
|
|
|
|
$node->{-rdelim}; |
1232
|
|
|
|
|
|
|
} |
1233
|
|
|
|
|
|
|
} |
1234
|
|
|
|
|
|
|
else { |
1235
|
|
|
|
|
|
|
# $node is just a string |
1236
|
0
|
|
|
|
|
|
$CParagraph .= $node; |
1237
|
|
|
|
|
|
|
} |
1238
|
|
|
|
|
|
|
} |
1239
|
|
|
|
|
|
|
|
1240
|
0
|
|
|
|
|
|
return $CParagraph; |
1241
|
|
|
|
|
|
|
} |
1242
|
|
|
|
|
|
|
|
1243
|
|
|
|
|
|
|
1; # Magic true value required at end of module |
1244
|
|
|
|
|
|
|
__END__ |