File Coverage

blib/lib/Pod/PseudoPod/LaTeX.pm
Criterion Covered Total %
statement 235 338 69.5
branch 45 72 62.5
condition 9 20 45.0
subroutine 51 65 78.4
pod 1 41 2.4
total 341 536 63.6


line stmt bran cond sub pod time code
1             package Pod::PseudoPod::LaTeX;
2             $Pod::PseudoPod::LaTeX::VERSION = '1.20160626';
3 7     7   21418 use Pod::PseudoPod 0.16;
  7         162757  
  7         218  
4              
5 7     7   62 use base 'Pod::PseudoPod';
  7         12  
  7         686  
6 7     7   135 use 5.008006;
  7         19  
7              
8 7     7   24 use strict;
  7         41  
  7         117  
9 7     7   21 use warnings;
  7         8  
  7         2522  
10              
11              
12              
13             sub new
14             {
15 10     10 1 15239 my ( $class, %args ) = @_;
16 10         62 my $self = $class->SUPER::new(%args);
17              
18 10 100       418 $self->{keep_ligatures} = exists($args{keep_ligatures}) ? $args{keep_ligatures} : 0;
19 10 100       19 $self->{captions_below} = exists($args{captions_below}) ? $args{captions_below} : 0;
20 10 100       21 $self->{full} = exists($args{full}) ? $args{full} : 0;
21              
22             # These have their contents parsed
23 10         45 $self->accept_targets_as_text(
24             qw( sidebar blockquote programlisting screen figure table
25             PASM PIR PIR_FRAGMENT PASM_FRAGMENT PIR_FRAGMENT_INVALID )
26             );
27              
28             # These do not. Content is not touched.
29 10         356 $self->accept_target('latex');
30              
31 10   50     137 $self->{scratch} ||= '';
32 10         18 $self->{stack} = [];
33 10         21 $self->{labels} = { screen => 'Program output' };
34              
35 10         22 return $self;
36             }
37              
38             sub emit_environments
39             {
40 2     2 0 57 my ( $self, %env ) = @_;
41 2         6 for ( keys %env )
42             {
43 2         9 $self->{emit_environment}->{$_} = $env{$_};
44             }
45             }
46              
47             sub start_Document
48             {
49 8     8 0 2571 my $self = shift;
50 8 100       41 if ($self->{full}) {
51 1         3 $self->{scratch} .= "\\documentclass[12pt,a4paper]{book}\n"
52             . "\\usepackage{fancyvrb}\n"
53             . "\\usepackage{url}\n"
54             . "\\usepackage{titleref}\n"
55             . "\\usepackage[T1]{fontenc}\n"
56             . "\\usepackage{textcomp}\n"
57             . "\\begin{document}\n";
58             }
59             }
60              
61             sub end_Document
62             {
63 8     8 0 204 my $self = shift;
64 8 100       25 $self->{scratch} .= "\\end{document}\n" if $self->{full};
65 8         17 $self->emit();
66             }
67              
68             sub emit
69             {
70 465     465 0 315 my $self = shift;
71 465 100       728 return unless defined $self->{scratch};
72 458         315 print { $self->{output_fh} } delete $self->{scratch};
  458         1169  
73             }
74              
75             sub handle_text
76             {
77 745     745 0 25632 my ( $self, $text ) = @_;
78 745         927 $self->{scratch} .= $self->encode_text($text);
79             }
80              
81             sub encode_text
82             {
83 753     753 0 600 my ( $self, $text ) = @_;
84              
85 753         521 my $resolve = 1;
86 753         568 eval {
87 7     7   30 no warnings 'uninitialized';
  7         13  
  7         3352  
88 753 100 100     2415 if (exists($self->{curr_open}[-1][-1]{'~resolve'}) &&
89             $self->{curr_open}[-1][-1]{'~resolve'} == 0)
90             {
91 9         12 $resolve = 0;
92             }
93             };
94 753 100       1171 return $text unless $resolve;
95              
96 744 100       1058 return $self->encode_verbatim_text($text) if $self->{flags}{in_verbatim};
97 720 50       889 return $text if $self->{flags}{in_xref};
98 720 100       884 return $text if $self->{flags}{in_figure};
99              
100             # Escape LaTeX-specific characters
101 712         677 $text =~ s/\\/\\backslash/g; # backslashes are special
102 712         867 $text =~ s/([#\$&%_{}])/\\$1/g;
103 712         497 $text =~ s/(\^)/\\char94{}/g; # carets are special
104 712         761 $text =~ s/
105 712         441 $text =~ s/>/\\textgreater{}/g;
106              
107 712         518 $text =~ s/(\\backslash)/\$$1\$/g; # add unescaped dollars
108              
109             # use the right beginning quotes
110 712         631 $text =~ s/(^|\s)"/$1``/g;
111              
112             # and the right ending quotes
113 712         469 $text =~ s/"(\W|$)/''$1/g;
114              
115             # fix the ellipses
116 712         574 $text =~ s/\.{3}\s*/\\ldots /g;
117              
118             # fix the ligatures
119 712 50       1187 $text =~ s/f([fil])/f\\mbox{}$1/g unless $self->{keep_ligatures};
120              
121             # fix emdashes
122 712         515 $text =~ s/\s--\s/---/g;
123              
124             # fix tildes
125 712         481 $text =~ s/~/\$\\sim\$/g;
126              
127             # suggest hyphenation points for module names
128 712         487 $text =~ s/::/::\\-/g;
129              
130 712         1667 return $text;
131             }
132              
133             # in verbatim mode, some things still need escaping - otherwise markup
134             # wouldn't work when the codes_in_verbatim option is enabled.
135             sub encode_verbatim_text {
136 24     24 0 23 my ($self, $text) = @_;
137              
138 24         35 $text =~ s/([{}])/\\$1/g;
139 24         25 $text =~ s/\\(?![{}])/\\textbackslash{}/g;
140              
141 24         70 return $text;
142             }
143              
144             sub start_head0
145             {
146 8     8 0 865 my $self = shift;
147 8         20 $self->{scratch} .= '\\chapter{';
148             }
149              
150             sub end_head0
151             {
152 8     8 0 86 my $self = shift;
153 8         12 $self->{scratch} .= "}\n\n";
154 8         27 $self->emit();
155             }
156              
157             sub end_Para
158             {
159 224     224 0 1429 my $self = shift;
160 224         196 $self->{scratch} .= "\n\n";
161 224         274 $self->emit();
162             }
163              
164             BEGIN
165             {
166 7     7   51 for my $level ( 1 .. 5 )
167             {
168 35         65 my $prefix = '\\' . ( 'sub' x ( $level - 1 ) ) . 'section*{';
169             my $start_sub = sub {
170 32     32   4864 my $self = shift;
171 32         77 $self->{scratch} .= $prefix;
172 35         75 };
173              
174             my $end_sub = sub {
175 32     32   216 my $self = shift;
176 32         33 $self->{scratch} .= "}\n\n";
177 32         45 $self->emit();
178 35         89 };
179              
180 7     7   33 no strict 'refs';
  7         7  
  7         376  
181 35         24 *{ 'start_head' . $level } = $start_sub;
  35         94  
182 35         23 *{ 'end_head' . $level } = $end_sub;
  35         2649  
183             }
184             }
185              
186             sub start_E
187             {
188 48     48 0 437 my $self = shift;
189 48         37 push @{ $self->{stack} }, delete $self->{scratch};
  48         76  
190 48         74 $self->{scratch} = '';
191             }
192              
193             my %characters = (
194             acute => sub { qq|\\'| . shift },
195             grave => sub { qq|\\`| . shift },
196             uml => sub { qq|\\"| . shift },
197             cedilla => sub { '\c{c}' }, # ccedilla
198             opy => sub { '\copyright' }, # copy
199             dash => sub { '---' }, # mdash
200             lusmn => sub { '\ensuremath{\pm}' }, # plusmn
201             mp => sub { '\&' }, # amp
202             );
203              
204             sub end_E
205             {
206 48     48 0 278 my $self = shift;
207 48         35 my $clean_entity;
208              
209             # XXX - error checking here
210 48         43 my $entity = delete $self->{scratch};
211 48         99 $entity =~ /(\w)(\w+)/;
212              
213 48 50       89 if ( exists $characters{$2} )
    0          
214             {
215 48         79 $clean_entity = $characters{$2}->($1);
216             }
217             elsif ( $clean_entity = Pod::Escapes::e2char($entity) )
218             {
219             }
220             else
221             {
222 0         0 die "Unrecognized character '$entity'\n";
223             }
224              
225 48         38 $self->{scratch} = pop @{ $self->{stack} };
  48         61  
226 48         92 $self->{scratch} .= $clean_entity;
227             }
228              
229       40     sub _treat_Es { }
230              
231             sub start_X
232             {
233 48     48 0 581 my $self = shift;
234 48         39 push @{ $self->{stack} }, delete $self->{scratch};
  48         72  
235 48         83 $self->{scratch} = '';
236             }
237              
238             sub end_X
239             {
240 48     48 0 283 my $self = shift;
241 48         48 my $terms_text = delete $self->{scratch};
242 48         44 my @terms;
243 48         114 for my $t (split ',', $terms_text) {
244 56         193 $t =~ s/^\s+|\s+$//g;
245 56         67 $t =~ s/"/""/g;
246 56         153 $t =~ s/([!|@])/"$1/g;
247 56         85 push @terms, $t;
248             }
249             {
250 7     7   34 no warnings 'uninitialized';
  7         11  
  7         1148  
  48         65  
251 48         119 $self->{scratch} = pop(@{ $self->{stack} })
  48         192  
252             . '\\index{' . join('!', @terms) . '}';
253             }
254             }
255              
256             sub start_Z
257             {
258 0     0 0 0 my $self = shift;
259 0         0 push @{ $self->{stack} }, delete $self->{scratch};
  0         0  
260 0         0 $self->{scratch} = '';
261 0         0 $self->{flags}{in_xref}++;
262             }
263              
264             sub end_Z
265             {
266 0     0 0 0 my $self = shift;
267 0         0 my $clean_xref = delete $self->{scratch};
268              
269             # sanitize crossreference names
270 0         0 $clean_xref =~ s/[^\w:]/-/g;
271              
272             {
273 7     7   45 no warnings 'uninitialized';
  7         9  
  7         3934  
  0         0  
274 0         0 $self->{scratch} = pop( @{ $self->{stack} } )
  0         0  
275             . '\\label{' . $clean_xref . '}';
276             }
277 0         0 $self->{flags}{in_xref}--;
278             }
279              
280             sub start_A
281             {
282 0     0 0 0 my $self = shift;
283 0         0 push @{ $self->{stack} }, delete $self->{scratch};
  0         0  
284              
285 0         0 $self->{scratch} = '';
286 0         0 $self->{flags}{in_xref}++;
287             }
288              
289             sub end_A
290             {
291 0     0 0 0 my $self = shift;
292 0         0 my $clean_xref = delete $self->{scratch};
293              
294             # sanitize crossreference names
295 0         0 $clean_xref =~ s/[^\w:]/-/g;
296 0         0 $self->{scratch} = pop @{ $self->{stack} };
  0         0  
297              
298             # Figures have a different xref format
299 0 0       0 if ( $clean_xref =~ /^fig:/ )
    0          
300             {
301 0         0 $self->{scratch} .= 'Figure \\ref{' . $clean_xref . '} ';
302             }
303             # Tables have a different xref format
304             elsif ( $clean_xref =~ /^table:/ )
305             {
306 0         0 $self->{scratch} .= 'Table \\ref{' . $clean_xref . '} ';
307             }
308             else
309             {
310 0         0 $self->{scratch} .= '\\emph{\\titleref{' . $clean_xref . '}}';
311             }
312              
313 0         0 $self->{scratch} .= ' on page~'
314             . '\\pageref{' . $clean_xref . '}';
315              
316 0         0 $self->{flags}{in_xref}--;
317             }
318              
319             sub start_F
320             {
321 8     8 0 84 my $self = shift;
322              
323 8 50       22 if ( $self->{flags}{in_figure} )
324             {
325 0         0 push @{ $self->{stack} }, delete $self->{scratch};
  0         0  
326 0         0 $self->{scratch} = '';
327             }
328             else
329             {
330 8         20 $self->{scratch} .= '\\emph{';
331             }
332             }
333              
334             sub end_F
335             {
336 8     8 0 57 my $self = shift;
337              
338 8 50       21 if ( $self->{flags}{in_figure} )
339             {
340 0         0 my $raw_filename = delete $self->{scratch};
341 0         0 $self->{scratch} = pop @{ $self->{stack} };
  0         0  
342              
343             # extract bare image filename
344 0         0 $raw_filename =~ /(\w+)\.\w+$/;
345 0         0 $self->{scratch} .= "\n\\includegraphics{" . $1 . '}';
346             }
347             else
348             {
349 8         19 $self->{scratch} .= '}';
350             }
351             }
352              
353             sub start_for
354             {
355 33     33 0 2893 my ( $self, $flags ) = @_;
356              
357 33 100 33     262 if ($flags->{target} =~ /^latex$/i) { # support latex, LaTeX, et al
    100 66        
358 8         21 $self->{scratch} .= "\n\n";
359             } elsif (exists($flags->{'~really'}) &&
360             $flags->{'~really'} eq "=begin" &&
361             exists($self->{emit_environment}{$flags->{target}})) {
362 1         1 my $title = "";
363 1 50       5 $title = "{".$flags->{title}."}" if exists $flags->{title};
364             $self->{scratch} .= sprintf("\n\\begin{%s}%s\n",
365             $self->{emit_environment}{$flags->{target}},
366 1         7 $title);
367             }
368             }
369              
370             sub end_for
371             {
372 33     33 0 1662 my ( $self, $flags ) = @_;
373              
374 33 100       146 if ($flags->{target} =~ /^latex$/i) { # support latex, LaTeX, et al
    100          
375 8         13 $self->{scratch} .= "\n\n";
376 8         16 $self->emit;
377             } elsif (exists($self->{emit_environment}{$flags->{target}})) {
378             $self->{scratch} .= sprintf("\\end{%s}\n\n",
379 1         7 $self->{emit_environment}{$flags->{target}});
380 1         3 $self->emit;
381             }
382             }
383              
384             sub start_Verbatim
385             {
386 24     24 0 4160 my $self = shift;
387              
388 24         24 my $verb_options = "commandchars=\\\\\\{\\}";
389 24         23 eval {
390 7     7   31 no warnings 'uninitialized';
  7         41  
  7         6149  
391 24 100       79 if ($self->{curr_open}[-1][-1]{target} eq 'screen') {
392 8   33     33 my $label = $self->{curr_open}[-1][-1]{title} || $self->{labels}{screen};
393 8         17 $verb_options .= ",frame=single,label=$label";
394             }
395             };
396              
397 24         60 $self->{scratch} .= "\\vspace{-6pt}\n"
398             . "\\scriptsize\n"
399             . "\\begin{Verbatim}[$verb_options]\n";
400 24         47 $self->{flags}{in_verbatim}++;
401             }
402              
403             sub end_Verbatim
404             {
405 24     24 0 154 my $self = shift;
406              
407 24         32 $self->{scratch} .= "\n\\end{Verbatim}\n"
408             . "\\vspace{-6pt}\n";
409              
410             # $self->{scratch} .= "\\addtolength{\\parskip}{5pt}\n";
411 24         23 $self->{scratch} .= "\\normalsize\n";
412 24         33 $self->{flags}{in_verbatim}--;
413 24         34 $self->emit();
414             }
415              
416             sub end_screen
417             {
418 0     0 0 0 my $self = shift;
419 0         0 $self->{scratch} .= "\n\\end{Verbatim}\n"
420             . "\\vspace{-6pt}\n";
421              
422             # $self->{scratch} .= "\\addtolength{\\parskip}{5pt}\n";
423 0         0 $self->{scratch} .= "\\normalsize\n";
424 0         0 $self->{flags}{in_verbatim}--;
425 0         0 $self->emit();
426             }
427              
428             sub start_figure
429             {
430 8     8 0 1671 my ( $self, $flags ) = @_;
431              
432 8         17 $self->{scratch} .= "\\begin{figure}[!h]\n";
433              
434 8         15 $self->{_dangling_title} = undef; # just in case; Do not think it is worth a stack.
435 8 50       25 if ( $flags->{title} ) {
436 8 50       19 if ($self->{captions_below}) {
437 0         0 $self->{_dangling_title} = $flags->{title};
438             }
439             else {
440 8         21 my $title = $self->encode_text( $flags->{title} );
441 8         11 $title =~ s/^graphic\s*//;
442 8         29 $self->{scratch} .= "\\caption{" . $title . "}\n";
443             }
444             }
445              
446 8         12 $self->{scratch} .= "\\begin{center}\n";
447 8         25 $self->{flags}{in_figure}++;
448             }
449              
450             sub end_figure
451             {
452 8     8 0 781 my $self = shift;
453 8         18 $self->{scratch} .= "\\end{center}\n";
454              
455 8 0 33     24 if ($self->{captions_below} && $self->{_dangling_title})
456             {
457 0         0 my $title = $self->encode_text( $self->{_dangling_title} );
458 0         0 $title =~ s/^graphic\s*//;
459 0         0 $self->{scratch} .= "\\caption{" . $title . "}\n";
460 0         0 $self->{_dangling_title} = undef; # clear it
461             }
462              
463 8         12 $self->{scratch} .= "\\end{figure}\n";
464 8         14 $self->{flags}{in_figure}--;
465 8         15 $self->emit();
466             }
467              
468             sub start_table
469             {
470 0     0 0 0 my ( $self, $flags) = @_;
471              
472             # Open the table
473 0         0 $self->{scratch} .= "\\begin{table}[!h]\n";
474              
475 0         0 $self->{_dangling_title} = undef; # just in case; Do not think it is worth a stack.
476 0 0       0 if ( $flags->{title} )
477             {
478 0 0       0 if ($self->{captions_below}) {
479 0         0 $self->{_dangling_title} = $flags->{title};
480             }
481             else {
482 0         0 my $title = $self->encode_text( $flags->{title} );
483 0         0 $title =~ s/^graphic\s*//;
484 0         0 $self->{scratch} .= "\\caption{" . $title . "}\n";
485             }
486             }
487 0         0 $self->{scratch} .= "\\begin{center}\n";
488              
489 0         0 $self->{flags}{in_table}++;
490 0         0 delete $self->{table_rows};
491             }
492              
493             sub end_table
494             {
495 0     0 0 0 my $self = shift;
496              
497             # Format the table body
498 0         0 my $column_count = @{ $self->{table_rows}[0] };
  0         0  
499 0         0 my $format_spec = '|' . ( 'l|' x $column_count );
500              
501             # first row is gray
502 0         0 $self->{scratch} .= "\\begin{tabular}{$format_spec}\n"
503             . "\\hline\n"
504             . "\\rowcolor[gray]{.9}\n";
505              
506             # Format each row
507 0         0 my $row;
508 0         0 for $row ( @{ $self->{table_rows} } )
  0         0  
509             {
510 0         0 $self->{scratch} .= join( ' & ', @$row )
511             . "\\\\ \\hline\n";
512             }
513              
514             # Close the table
515 0         0 $self->{scratch} .= "\\end{tabular}\n"
516             . "\\end{center}\n";
517              
518              
519 0 0 0     0 if ($self->{captions_below} && $self->{_dangling_title})
520             {
521 0         0 my $title = $self->encode_text( $self->{_dangling_title} );
522 0         0 $title =~ s/^graphic\s*//;
523 0         0 $self->{scratch} .= "\\caption{" . $title . "}\n";
524 0         0 $self->{_dangling_title} = undef; # clear it
525             }
526              
527 0         0 $self->{scratch}.= "\\end{table}\n";
528              
529 0         0 $self->{flags}{in_table}--;
530 0         0 delete $self->{table_rows};
531              
532 0         0 $self->emit();
533             }
534              
535             sub start_headrow
536             {
537 0     0 0 0 my $self = shift;
538 0         0 $self->{in_headrow}++;
539             }
540              
541             sub start_bodyrows
542             {
543 0     0 0 0 my $self = shift;
544 0         0 $self->{in_headrow}--;
545             }
546              
547             sub start_row
548             {
549 0     0 0 0 my $self = shift;
550 0         0 delete $self->{table_current_row};
551             }
552              
553             sub end_row
554             {
555 0     0 0 0 my $self = shift;
556 0         0 push @{ $self->{table_rows} }, $self->{table_current_row};
  0         0  
557 0         0 delete $self->{table_current_row};
558             }
559              
560             sub start_cell
561             {
562 0     0 0 0 my $self = shift;
563 0         0 push @{ $self->{stack} }, delete $self->{scratch};
  0         0  
564 0         0 $self->{scratch} = '';
565             }
566              
567             sub end_cell
568             {
569 0     0 0 0 my $self = shift;
570 0         0 my $cell_contents = delete $self->{scratch};
571              
572 0 0       0 if ( $self->{in_headrow} )
573             {
574 0         0 $cell_contents = '\\textbf{\\textsf{' . $cell_contents . '}}';
575             }
576              
577 0         0 push @{ $self->{table_current_row} }, $cell_contents;
  0         0  
578 0         0 $self->{scratch} = pop @{ $self->{stack} };
  0         0  
579             }
580              
581             BEGIN
582             {
583 7     7   79 for my $listtype (
584             [qw( bullet itemize )], [qw( number enumerate )],
585             [qw( text description )], [qw( block description )],
586             )
587             {
588              
589             my $start_sub = sub {
590 40     40   4273 my $self = shift;
591 40         154 $self->{scratch} .= "\\vspace{-5pt}\n"
592             . "\n\\begin{$listtype->[1]}\n\n"
593             . "\\setlength{\\topsep}{0pt}\n"
594             . "\\setlength{\\itemsep}{0pt}\n";
595              
596             # $self->{scratch} .= "\\setlength{\\parskip}{0pt}\n";
597             # $self->{scratch} .= "\\setlength{\\parsep}{0pt}\n";
598 28         79 };
599              
600             my $end_sub = sub {
601 40     40   2715 my $self = shift;
602 40         93 $self->{scratch} .= "\\end{$listtype->[1]}\n\n"
603             . "\\vspace{-5pt}\n";
604 40         64 $self->emit();
605 28         62 };
606              
607 7     7   32 no strict 'refs';
  7         14  
  7         294  
608 28         24 *{ 'start_over_' . $listtype->[0] } = $start_sub;
  28         91  
609 28         24 *{ 'end_over_' . $listtype->[0] } = $end_sub;
  28         2440  
610             }
611             }
612              
613             sub start_item_bullet
614             {
615 24     24 0 4079 my $self = shift;
616 24         56 $self->{scratch} .= '\item ';
617             }
618              
619             sub start_item_number
620             {
621 0     0 0 0 my ( $self, $flags ) = @_;
622              
623             # $self->{scratch} .= "\\item[$flags->{number}] ";
624 0         0 $self->{scratch} .= "\\item "; # LaTeX will auto-number
625             }
626              
627             sub start_item_text
628             {
629 88     88 0 11829 my $self = shift;
630 88         162 $self->{scratch} .= '\item[] ';
631             }
632              
633             sub start_sidebar
634             {
635 8     8 0 873 my ( $self, $flags ) = @_;
636              
637 8         11 my $title;
638 8 50       22 $title = $self->encode_text( $flags->{title} ) if $flags->{title};
639              
640 8 100       25 if ( $self->{emit_environment}->{sidebar} )
641             {
642 1         5 $self->{scratch} .= "\\begin{" . $self->{emit_environment}->{sidebar} . "}";
643 1 50       4 $self->{scratch} .= "[$title]" if $title;
644 1         3 $self->{scratch} .= "\n";
645             }
646             else
647             {
648 7         13 $self->{scratch} .= "\\begin{figure}[!h]\n"
649             . "\\begin{center}\n"
650             . "\\framebox{\n"
651             . "\\begin{minipage}{3.5in}\n"
652             . "\\vspace{3pt}\n\n";
653              
654 7 50       32 if ( $title )
655             {
656 0         0 $self->{scratch} .= "\\begin{center}\n"
657             . "\\large{\\bfseries{" . $title . "}}\n"
658             . "\\end{center}\n\n";
659             }
660             }
661             }
662              
663             sub end_sidebar
664             {
665 8     8 0 624 my $self = shift;
666 8 100       22 if ( $self->{emit_environment}->{sidebar} )
667             {
668             $self->{scratch} .= "\\end{"
669 1         5 . $self->{emit_environment}->{sidebar} . "}\n\n";
670             }
671             else
672             {
673 7         22 $self->{scratch} .= "\\vspace{3pt}\n"
674             . "\\end{minipage}\n"
675             # end framebox
676             . "}\n"
677             . "\\end{center}\n"
678             . "\\end{figure}\n";
679             }
680             }
681              
682             BEGIN
683             {
684 7     7   15 for my $end (qw( bullet number text))
685             {
686             my $end_sub = sub {
687 112     112   656 my $self = shift;
688 112         102 $self->{scratch} .= "\n\n";
689 112         130 $self->emit();
690 21         60 };
691              
692 7     7   29 no strict 'refs';
  7         7  
  7         839  
693 21         17 *{ 'end_item_' . $end } = $end_sub;
  21         73  
694             }
695              
696 7         160 my %formats = (
697             B => [ '\\textbf', '' ],
698             C => [ '\\texttt', '' ],
699             I => [ '\\emph', '' ],
700             U => [ '\\url', '' ],
701             R => [ '\\emph', '' ],
702             L => [ '\\url', '' ],
703             N => [ '\\footnote', '' ],
704             G => [ '$^', '$' ],
705             H => [ '$_', '$' ],
706             );
707              
708 7         46 while ( my ( $code, $fixes ) = each %formats )
709             {
710             my $start_sub = sub {
711 80     80   697 my $self = shift;
712 80         167 $self->{scratch} .= $fixes->[0] . '{';
713 63         180 };
714              
715             my $end_sub = sub {
716 80     80   487 my $self = shift;
717 80         151 $self->{scratch} .= '}' . $fixes->[1];
718 63         108 };
719              
720 7     7   28 no strict 'refs';
  7         10  
  7         340  
721 63         50 *{ 'start_' . $code } = $start_sub;
  63         152  
722 63         39 *{ 'end_' . $code } = $end_sub;
  63         384  
723             }
724              
725             }
726              
727             1;
728             __END__