File Coverage

blib/lib/Pod/InDesign/TaggedText.pm
Criterion Covered Total %
statement 104 149 69.8
branch 12 26 46.1
condition 4 15 26.6
subroutine 39 61 63.9
pod 10 51 19.6
total 169 302 55.9


line stmt bran cond sub pod time code
1             # $Id$
2             package Pod::InDesign::TaggedText;
3 5     5   25087 use strict;
  5         13  
  5         210  
4 5     5   33 use base 'Pod::PseudoPod';
  5         12  
  5         4985  
5              
6 5     5   242153 use warnings;
  5         16  
  5         249  
7 5     5   27 no warnings;
  5         9  
  5         240  
8              
9 5     5   6256 use subs qw();
  5         165  
  5         135  
10 5     5   29 use vars qw($VERSION);
  5         12  
  5         12435  
11              
12             $VERSION = '0.11';
13              
14             =head1 NAME
15              
16             Pod::InDesign::TaggedText - Turn Pod into Tagged Text
17              
18             =head1 SYNOPSIS
19              
20             use Pod::InDesign::TaggedText;
21              
22             =head1 DESCRIPTION
23              
24             ***THIS IS ALPHA SOFTWARE. MAJOR PARTS WILL CHANGE***
25              
26             =head2 The style information
27              
28             This module takes care of most of the tagged text stuff for you, but you'll
29             want to insert your own style names. The module gets these by calling
30             methods to get the style names. You probably want to create an InDesign
31             document and export it to tagged text to see what you need.
32              
33             Override these in a subclass.
34              
35             =cut
36              
37             =over 4
38              
39             =item document_header
40              
41             This is the start of the document that defines all of the styles. You'll need
42             to override this. You can take this directly from
43              
44             =cut
45              
46             sub document_header
47             {
48 4     4 1 17 <<'HTML';
49            
50             >
51             >
52             HTML
53             }
54              
55             =item head1_style, head2_style, head3_style, head4_style
56              
57             The paragraph styles to use with each heading level. By default these are
58             C, and so on.
59              
60             =cut
61              
62 4     4 1 26 sub head1_style { 'Head1Style' }
63 0     0 1 0 sub head2_style { 'Head2Style' }
64 0     0 1 0 sub head3_style { 'Head3Style' }
65 0     0 1 0 sub head4_style { 'Head4Style' }
66              
67             =item normal_paragraph_style
68              
69             The paragraph style for normal Pod paragraphs. You don't have to use this
70             for all normal paragraphs, but you'll have to override and extend more things
71             to get everything just how you like. You'll need to override C to
72             get more variety.
73              
74             =cut
75              
76 6     6 0 63 sub normal_para_style { 'NormalParagraphStyle' }
77              
78             =item normal_paragraph_style
79              
80             Like C, but for verbatim sections. To get more fancy
81             handling, you'll need to override C and C.
82              
83             =cut
84              
85 2     2 0 6 sub code_para_style { 'CodeParagraphStyle' }
86              
87             =item inline_code_style
88              
89             The character style that goes with C<< CE> >>.
90              
91             =cut
92              
93 1     1 1 4 sub inline_code_style { 'CodeCharacterStyle' }
94              
95             =item inline_url_style
96              
97             The character style that goes with C<< UEE >>.
98              
99             =cut
100              
101 0     0 1 0 sub inline_url_style { 'URLCharacterStyle' }
102              
103             =item inline_italic_style
104              
105             The character style that goes with C<< IE> >>.
106              
107             =cut
108              
109 1     1 1 5 sub inline_italic_style { 'ItalicCharacterStyle' }
110              
111             =item inline_bold_style
112              
113             The character style that goes with C<< BE> >>.
114              
115             =cut
116              
117 1     1 1 5 sub inline_bold_style { 'BoldCharacterStyle' }
118              
119             =back
120              
121             =head2 The Pod::Simple mechanics
122              
123             Everything else is the same stuff from C.
124              
125             =cut
126              
127 4     4 1 6292 sub new { $_[0]->SUPER::new() }
128              
129             sub emit
130             {
131 16     16 0 26 print {$_[0]->{'output_fh'}} $_[0]->{'scratch'};
  16         86  
132 16         192 $_[0]->{'scratch'} = '';
133 16         45 return;
134             }
135              
136             sub get_pad
137             {
138             # flow elements first
139 18 50   18 0 70 if( $_[0]{module_flag} ) { 'module_text' }
  0 50       0  
140 0         0 elsif( $_[0]{url_flag} ) { 'url_text' }
141             # then block elements
142             # finally the default
143 18         37 else { 'scratch' }
144             }
145              
146             sub start_Document
147             {
148 4     4 0 21315 $_[0]->{'scratch'} .= $_[0]->document_header; $_[0]->emit;
  4         18  
149             }
150              
151 4     4 0 337 sub end_Document { 1 }
152              
153 4     4 0 1022 sub start_head1 { $_[0]{'scratch'} = 'head1_style . '>'; }
154 4     4 0 72 sub end_head1 { $_[0]{'scratch'} .= "\n"; $_[0]->end_non_code_text }
  4         19  
155              
156 0     0 0 0 sub start_head2 { $_[0]{'scratch'} = 'head2_style . '>'; }
157 0     0 0 0 sub end_head2 { $_[0]{'scratch'} .= "\n"; $_[0]->end_non_code_text }
  0         0  
158              
159 0     0 0 0 sub start_head3 { $_[0]{'scratch'} = 'head3_style . '>'; }
160 0     0 0 0 sub end_head3 { $_[0]{'scratch'} .= "\n"; $_[0]->end_non_code_text }
  0         0  
161              
162 0     0 0 0 sub start_head4 { $_[0]{'scratch'} = 'head4_style . '>'; }
163 0     0 0 0 sub end_head4 { $_[0]{'scratch'} .= "\n"; $_[0]->end_non_code_text }
  0         0  
164              
165             sub end_non_code_text
166             {
167 10     10 0 15 my $self = shift;
168            
169 10         27 $self->make_curly_quotes;
170            
171             #$self->{'scratch'} .= "\n";
172 10         30 $self->emit
173             }
174            
175             sub start_Para
176             {
177 6     6 0 1325 my $self = shift;
178            
179 6         26 $self->{'scratch'} = 'normal_para_style . '>';
180            
181 6         55 $self->{'in_para'} = 1;
182             }
183              
184              
185             sub end_Para
186             {
187 6     6 0 69 my $self = shift;
188            
189 6         14 $self->{'scratch'} .= "\n";
190              
191 6         16 $self->end_non_code_text;
192              
193 6         17 $self->{'in_para'} = 0;
194             }
195              
196 0     0 0 0 sub start_figure { }
197              
198 0     0 0 0 sub end_figure { }
199              
200 2     2 0 47 sub start_Verbatim { $_[0]{'in_verbatim'} = 1; }
201              
202             sub end_Verbatim
203             {
204 2     2 0 35 my @lines = split m/^/m, $_[0]{'scratch'};
205            
206 2         4 my $first = shift @lines;
207 2         4 my $last = shift @lines;
208            
209 2         10 $_[0]{'scratch'} =~ s/\n+\z/\n/;
210            
211 2         9 my $style = $_[0]->code_para_style;
212            
213 2         24 $_[0]{'scratch'} =~ s/^//gm;
214              
215 2         6 $_[0]{'scratch'} .= "\n";
216              
217 2         6 $_[0]->emit();
218              
219 2         7 $_[0]{'in_verbatim'} = 0;
220             }
221              
222 1     1 0 20 sub start_B { $_[0]{'scratch'} .= "inline_bold_style . ">" }
223 1     1 0 12 sub end_B { $_[0]{'scratch'} .= "" }
224              
225 1     1 0 20 sub start_C { $_[0]{'scratch'} .= "inline_code_style . ">" }
226 1     1 0 16 sub end_C { $_[0]{'scratch'} .= "" }
227              
228 0     0 0 0 sub start_E { $_[0]{'in_E'} = 1 }
229 0     0 0 0 sub end_E { $_[0]{'in_E'} = 0 }
230              
231 0     0 0 0 sub start_F { }
232 0     0 0 0 sub end_F { }
233              
234 1     1 0 22 sub start_I { $_[0]{'scratch'} .= "inline_italic_style . ">" }
235 1     1 0 13 sub end_I { $_[0]{'scratch'} .= "" }
236              
237             sub start_M
238             {
239 0     0 0 0 $_[0]{'module_flag'} = 1;
240 0         0 $_[0]{'module_text'} = '';
241 0         0 $_[0]->start_C;
242             }
243              
244             sub end_M
245             {
246 0     0 0 0 $_[0]->end_C;
247 0         0 $_[0]{'module_flag'} = 0;
248             }
249              
250 0     0 0 0 sub start_N { }
251 0     0 0 0 sub end_N { }
252              
253 0     0 0 0 sub start_U { $_[0]->start_I }
254 0     0 0 0 sub end_U { $_[0]->end_I }
255              
256             sub handle_text
257             {
258 18     18 0 249 my( $self, $text ) = @_;
259            
260 18         41 my $pad = $self->get_pad;
261            
262 18         47 $self->escape_text( \$text );
263            
264 18         64 $self->{$pad} .= $text;
265             }
266              
267             sub escape_text
268             {
269 18     18 0 28 my( $self, $text_ref ) = @_;
270            
271             # escape escape chars. This is escpaing them for InDesign
272             # so don't worry about double escaping for other levels. Don't
273             # worry about InDesign in the pod.
274 18         36 $$text_ref =~ s/\\/\\\\/gx;
275              
276             # escape < and >, unless it looks like <0xABCD>, in
277             # which case it's a wide character annotated as its
278             # hex value.
279 18         34 $$text_ref =~ s/ < (?! 0x[0-9a-f]{4} > ) /\\
280 18         31 $$text_ref =~ s/(? /\\>/gx;
281            
282 18         26 return 1;
283             }
284              
285             sub make_curly_quotes
286             {
287 10     10 0 13 my( $self ) = @_;
288            
289 10         23 my $text = $self->{scratch};
290            
291 10         4313 require Tie::Cycle;
292            
293 10         4377 tie my $cycle, 'Tie::Cycle', [ qw( <0x201C> <0x201D> ) ];
294              
295 10         353 1 while $text =~ s/"/$cycle/;
296            
297             # escape escape chars. This is escpaing them for InDesign
298             # so don't worry about double escaping for other levels. Don't
299             # worry about InDesign in the pod.
300 10         86 $text =~ s/'/<0x2019>/g;
301            
302 10         24 $self->{'scratch'} = $text;
303            
304 10         67 return 1;
305             }
306            
307             BEGIN {
308 5     5   1808 require Pod::Simple::BlackBox;
309              
310             package Pod::Simple::BlackBox;
311              
312             sub _ponder_Verbatim {
313 2     2   592 my ($self,$para) = @_;
314 2         4 DEBUG and print " giving verbatim treatment...\n";
315              
316 2         6 $para->[1]{'xml:space'} = 'preserve';
317 2         11 foreach my $line ( @$para[ 2 .. $#$para ] )
318             {
319 6         22 $line =~ s/^\t//gm;
320 6         13 $line =~ s/^(\t+)/" " x ( 4 * length($1) )/e
  0         0  
321             }
322            
323             # Now the VerbatimFormatted hoodoo...
324 2 50 33     29 if( $self->{'accept_codes'} and
    50          
325             $self->{'accept_codes'}{'VerbatimFormatted'}
326             ) {
327 0   0     0 while(@$para > 3 and $para->[-1] !~ m/\S/) { pop @$para }
  0         0  
328             # Kill any number of terminal newlines
329 0         0 $self->_verbatim_format($para);
330             } elsif ($self->{'codes_in_verbatim'}) {
331 0         0 push @$para,
332 0         0 @{$self->_make_treelet(
333             join("\n", splice(@$para, 2)),
334             $para->[1]{'start_line'}, $para->[1]{'xml:space'}
335             )};
336 0         0 $para->[-1] =~ s/\n+$//s; # Kill any number of terminal newlines
337             } else {
338 2 50       23 push @$para, join "\n", splice(@$para, 2) if @$para > 3;
339 2         13 $para->[-1] =~ s/\n+$//s; # Kill any number of terminal newlines
340             }
341 2         7 return;
342             }
343              
344             }
345              
346 5     5   162 BEGIN {
347              
348             # override _treat_Es so I can localize e2char
349             sub _treat_Es
350             {
351 2     2   1274 my $self = shift;
352              
353 2         14 require Pod::Escapes;
354 2         29 local *Pod::Escapes::e2char = *e2char_tagged_text;
355              
356 2         22 $self->SUPER::_treat_Es( @_ );
357             }
358              
359             sub e2char_tagged_text
360             {
361             package Pod::Escapes;
362            
363 5     5 0 198 my $in = shift;
364 5 50 33     29 return unless defined $in and length $in;
365            
366 5 50       20 if( $in =~ m/^(0[0-7]*)$/ ) { $in = oct $in; }
  0 50       0  
367 0         0 elsif( $in =~ m/^0?x([0-9a-fA-F]+)$/ ) { $in = hex $1; }
368              
369 5 50       14 if( $NOT_ASCII )
370             {
371 0 0       0 unless( $in =~ m/^\d+$/ )
372             {
373 0         0 $in = $Name2character{$in};
374 0 0       0 return unless defined $in;
375 0         0 $in = ord $in;
376             }
377              
378 0   0     0 return $Code2USASCII{$in}
379             || $Latin1Code_to_fallback{$in}
380             || $FAR_CHAR;
381             }
382            
383 5 100 66     27 if( defined $Name2character_number{$in} and $Name2character_number{$in} < 127 )
    50          
384             {
385 4         15 return chr( $Name2character_number{$in} );
386             }
387             elsif( defined $Name2character_number{$in} )
388             {
389             # this need to be fixed width because I want to look for
390             # it in a negative lookbehind
391 1         11 return sprintf '<0x%04x>', $Name2character_number{$in};
392             }
393             else
394             {
395 0           return '???';
396             }
397            
398             }
399             }
400              
401             =head1 TO DO
402              
403             =over 4
404              
405             =item * beef up entity handling in EE>. I had to override some stuff from Pod::Escapes
406              
407             =back
408              
409             =head1 SEE ALSO
410              
411             L, L
412              
413             =head1 SOURCE AVAILABILITY
414              
415             This source is part of a SourceForge project which always has the
416             latest sources in CVS, as well as all of the previous releases.
417              
418             http://sourceforge.net/projects/brian-d-foy/
419              
420             If, for some reason, I disappear from the world, one of the other
421             members of the project can shepherd this module appropriately.
422              
423             =head1 AUTHOR
424              
425             brian d foy, C<< >>
426              
427             =head1 COPYRIGHT AND LICENSE
428              
429             Copyright (c) 2007, brian d foy, All Rights Reserved.
430              
431             You may redistribute this under the same terms as Perl itself.
432              
433             =cut
434              
435             1;