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.20190729';
3 7     7   73862 use Pod::PseudoPod 0.16;
  7         231417  
  7         244  
4              
5 7     7   71 use base 'Pod::PseudoPod';
  7         14  
  7         849  
6 7     7   113 use 5.008006;
  7         24  
7              
8 7     7   39 use strict;
  7         16  
  7         136  
9 7     7   31 use warnings;
  7         15  
  7         3477  
10              
11              
12              
13             sub new
14             {
15 10     10 1 24672 my ( $class, %args ) = @_;
16 10         60 my $self = $class->SUPER::new(%args);
17              
18 10 100       475 $self->{keep_ligatures} = exists($args{keep_ligatures}) ? $args{keep_ligatures} : 0;
19 10 100       29 $self->{captions_below} = exists($args{captions_below}) ? $args{captions_below} : 0;
20 10 100       26 $self->{full} = exists($args{full}) ? $args{full} : 0;
21              
22             # These have their contents parsed
23 10         53 $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         572 $self->accept_target('latex');
30              
31 10   50     199 $self->{scratch} ||= '';
32 10         69 $self->{stack} = [];
33 10         26 $self->{labels} = { screen => 'Program output' };
34              
35 10         60 return $self;
36             }
37              
38             sub emit_environments
39             {
40 2     2 0 48 my ( $self, %env ) = @_;
41 2         9 for ( keys %env )
42             {
43 2         9 $self->{emit_environment}->{$_} = $env{$_};
44             }
45             }
46              
47             sub start_Document
48             {
49 8     8 0 3867 my $self = shift;
50 8 100       37 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 420 my $self = shift;
64 8 100       34 $self->{scratch} .= "\\end{document}\n" if $self->{full};
65 8         33 $self->emit();
66             }
67              
68             sub emit
69             {
70 465     465 0 666 my $self = shift;
71 465 100       1027 return unless defined $self->{scratch};
72 458         701 print { $self->{output_fh} } delete $self->{scratch};
  458         1738  
73             }
74              
75             sub handle_text
76             {
77 745     745 0 47429 my ( $self, $text ) = @_;
78 745         1577 $self->{scratch} .= $self->encode_text($text);
79             }
80              
81             sub encode_text
82             {
83 753     753 0 1260 my ( $self, $text ) = @_;
84              
85 753         1071 my $resolve = 1;
86 753         1069 eval {
87 7     7   55 no warnings 'uninitialized';
  7         22  
  7         5195  
88 753 100 100     3431 if (exists($self->{curr_open}[-1][-1]{'~resolve'}) &&
89             $self->{curr_open}[-1][-1]{'~resolve'} == 0)
90             {
91 9         19 $resolve = 0;
92             }
93             };
94 753 100       1812 return $text unless $resolve;
95              
96 744 100       1517 return $self->encode_verbatim_text($text) if $self->{flags}{in_verbatim};
97 720 50       1329 return $text if $self->{flags}{in_xref};
98 720 100       1372 return $text if $self->{flags}{in_figure};
99              
100             # Escape LaTeX-specific characters
101 712         1375 $text =~ s/\\/\\backslash/g; # backslashes are special
102 712         1570 $text =~ s/([#\$&%_{}])/\\$1/g;
103 712         1187 $text =~ s/(\^)/\\char94{}/g; # carets are special
104 712         1055 $text =~ s/
105 712         1011 $text =~ s/>/\\textgreater{}/g;
106              
107 712         1042 $text =~ s/(\\backslash)/\$$1\$/g; # add unescaped dollars
108              
109             # use the right beginning quotes
110 712         1150 $text =~ s/(^|\s)"/$1``/g;
111              
112             # and the right ending quotes
113 712         1097 $text =~ s/"(\W|$)/''$1/g;
114              
115             # fix the ellipses
116 712         1060 $text =~ s/\.{3}\s*/\\ldots /g;
117              
118             # fix the ligatures
119 712 50       1730 $text =~ s/f([fil])/f\\mbox{}$1/g unless $self->{keep_ligatures};
120              
121             # fix emdashes
122 712         1086 $text =~ s/\s--\s/---/g;
123              
124             # fix tildes
125 712         1024 $text =~ s/~/\$\\sim\$/g;
126              
127             # suggest hyphenation points for module names
128 712         1029 $text =~ s/::/::\\-/g;
129              
130 712         2414 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 49 my ($self, $text) = @_;
137              
138 24         67 $text =~ s/([{}])/\\$1/g;
139 24         51 $text =~ s/\\(?![{}])/\\textbackslash{}/g;
140              
141 24         102 return $text;
142             }
143              
144             sub start_head0
145             {
146 8     8 0 1223 my $self = shift;
147 8         35 $self->{scratch} .= '\\chapter{';
148             }
149              
150             sub end_head0
151             {
152 8     8 0 140 my $self = shift;
153 8         19 $self->{scratch} .= "}\n\n";
154 8         21 $self->emit();
155             }
156              
157             sub end_Para
158             {
159 224     224 0 2540 my $self = shift;
160 224         394 $self->{scratch} .= "\n\n";
161 224         427 $self->emit();
162             }
163              
164             BEGIN
165             {
166 7     7   42 for my $level ( 1 .. 5 )
167             {
168 35         123 my $prefix = '\\' . ( 'sub' x ( $level - 1 ) ) . 'section*{';
169             my $start_sub = sub {
170 32     32   8455 my $self = shift;
171 32         99 $self->{scratch} .= $prefix;
172 35         161 };
173              
174             my $end_sub = sub {
175 32     32   411 my $self = shift;
176 32         63 $self->{scratch} .= "}\n\n";
177 32         73 $self->emit();
178 35         108 };
179              
180 7     7   57 no strict 'refs';
  7         13  
  7         424  
181 35         57 *{ 'start_head' . $level } = $start_sub;
  35         153  
182 35         63 *{ 'end_head' . $level } = $end_sub;
  35         4023  
183             }
184             }
185              
186             sub start_E
187             {
188 48     48 0 927 my $self = shift;
189 48         67 push @{ $self->{stack} }, delete $self->{scratch};
  48         119  
190 48         135 $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 523 my $self = shift;
207 48         86 my $clean_entity;
208              
209             # XXX - error checking here
210 48         85 my $entity = delete $self->{scratch};
211 48         162 $entity =~ /(\w)(\w+)/;
212              
213 48 50       152 if ( exists $characters{$2} )
    0          
214             {
215 48         113 $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         81 $self->{scratch} = pop @{ $self->{stack} };
  48         124  
226 48         134 $self->{scratch} .= $clean_entity;
227             }
228              
229       40     sub _treat_Es { }
230              
231             sub start_X
232             {
233 48     48 0 1149 my $self = shift;
234 48         74 push @{ $self->{stack} }, delete $self->{scratch};
  48         125  
235 48         157 $self->{scratch} = '';
236             }
237              
238             sub end_X
239             {
240 48     48 0 559 my $self = shift;
241 48         119 my $terms_text = delete $self->{scratch};
242 48         81 my @terms;
243 48         139 for my $t (split ',', $terms_text) {
244 56         301 $t =~ s/^\s+|\s+$//g;
245 56         115 $t =~ s/"/""/g;
246 56         179 $t =~ s/([!|@])/"$1/g;
247 56         139 push @terms, $t;
248             }
249             {
250 7     7   62 no warnings 'uninitialized';
  7         25  
  7         1664  
  48         82  
251 48         91 $self->{scratch} = pop(@{ $self->{stack} })
  48         242  
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   56 no warnings 'uninitialized';
  7         16  
  7         5561  
  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 152 my $self = shift;
322              
323 8 50       29 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 87 my $self = shift;
337              
338 8 50       26 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         34 $self->{scratch} .= '}';
350             }
351             }
352              
353             sub start_for
354             {
355 33     33 0 5431 my ( $self, $flags ) = @_;
356              
357 33 100 33     288 if ($flags->{target} =~ /^latex$/i) { # support latex, LaTeX, et al
    100 66        
358 8         36 $self->{scratch} .= "\n\n";
359             } elsif (exists($flags->{'~really'}) &&
360             $flags->{'~really'} eq "=begin" &&
361             exists($self->{emit_environment}{$flags->{target}})) {
362 1         4 my $title = "";
363 1 50       6 $title = "{".$flags->{title}."}" if exists $flags->{title};
364             $self->{scratch} .= sprintf("\n\\begin{%s}%s\n",
365             $self->{emit_environment}{$flags->{target}},
366 1         9 $title);
367             }
368             }
369              
370             sub end_for
371             {
372 33     33 0 2999 my ( $self, $flags ) = @_;
373              
374 33 100       188 if ($flags->{target} =~ /^latex$/i) { # support latex, LaTeX, et al
    100          
375 8         20 $self->{scratch} .= "\n\n";
376 8         25 $self->emit;
377             } elsif (exists($self->{emit_environment}{$flags->{target}})) {
378             $self->{scratch} .= sprintf("\\end{%s}\n\n",
379 1         5 $self->{emit_environment}{$flags->{target}});
380 1         3 $self->emit;
381             }
382             }
383              
384             sub start_Verbatim
385             {
386 24     24 0 7393 my $self = shift;
387              
388 24         48 my $verb_options = "commandchars=\\\\\\{\\}";
389 24         43 eval {
390 7     7   84 no warnings 'uninitialized';
  7         30  
  7         9493  
391 24 100       105 if ($self->{curr_open}[-1][-1]{target} eq 'screen') {
392 8   33     71 my $label = $self->{curr_open}[-1][-1]{title} || $self->{labels}{screen};
393 8         29 $verb_options .= ",frame=single,label=$label";
394             }
395             };
396              
397 24         86 $self->{scratch} .= "\\vspace{-6pt}\n"
398             . "\\scriptsize\n"
399             . "\\begin{Verbatim}[$verb_options]\n";
400 24         66 $self->{flags}{in_verbatim}++;
401             }
402              
403             sub end_Verbatim
404             {
405 24     24 0 303 my $self = shift;
406              
407 24         75 $self->{scratch} .= "\n\\end{Verbatim}\n"
408             . "\\vspace{-6pt}\n";
409              
410             # $self->{scratch} .= "\\addtolength{\\parskip}{5pt}\n";
411 24         56 $self->{scratch} .= "\\normalsize\n";
412 24         36 $self->{flags}{in_verbatim}--;
413 24         54 $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 3184 my ( $self, $flags ) = @_;
431              
432 8         25 $self->{scratch} .= "\\begin{figure}[!h]\n";
433              
434 8         22 $self->{_dangling_title} = undef; # just in case; Do not think it is worth a stack.
435 8 50       30 if ( $flags->{title} ) {
436 8 50       30 if ($self->{captions_below}) {
437 0         0 $self->{_dangling_title} = $flags->{title};
438             }
439             else {
440 8         24 my $title = $self->encode_text( $flags->{title} );
441 8         20 $title =~ s/^graphic\s*//;
442 8         51 $self->{scratch} .= "\\caption{" . $title . "}\n";
443             }
444             }
445              
446 8         24 $self->{scratch} .= "\\begin{center}\n";
447 8         24 $self->{flags}{in_figure}++;
448             }
449              
450             sub end_figure
451             {
452 8     8 0 1463 my $self = shift;
453 8         25 $self->{scratch} .= "\\end{center}\n";
454              
455 8 0 33     30 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         42 $self->{scratch} .= "\\end{figure}\n";
464 8         31 $self->{flags}{in_figure}--;
465 8         41 $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   43 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   8316 my $self = shift;
591 40         194 $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         147 };
599              
600             my $end_sub = sub {
601 40     40   4854 my $self = shift;
602 40         139 $self->{scratch} .= "\\end{$listtype->[1]}\n\n"
603             . "\\vspace{-5pt}\n";
604 40         86 $self->emit();
605 28         96 };
606              
607 7     7   68 no strict 'refs';
  7         19  
  7         464  
608 28         42 *{ 'start_over_' . $listtype->[0] } = $start_sub;
  28         130  
609 28         51 *{ 'end_over_' . $listtype->[0] } = $end_sub;
  28         3407  
610             }
611             }
612              
613             sub start_item_bullet
614             {
615 24     24 0 7539 my $self = shift;
616 24         72 $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 22506 my $self = shift;
630 88         245 $self->{scratch} .= '\item[] ';
631             }
632              
633             sub start_sidebar
634             {
635 8     8 0 1561 my ( $self, $flags ) = @_;
636              
637 8         155 my $title;
638 8 50       37 $title = $self->encode_text( $flags->{title} ) if $flags->{title};
639              
640 8 100       30 if ( $self->{emit_environment}->{sidebar} )
641             {
642 1         3 $self->{scratch} .= "\\begin{" . $self->{emit_environment}->{sidebar} . "}";
643 1 50       5 $self->{scratch} .= "[$title]" if $title;
644 1         4 $self->{scratch} .= "\n";
645             }
646             else
647             {
648 7         23 $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       31 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 1083 my $self = shift;
666 8 100       34 if ( $self->{emit_environment}->{sidebar} )
667             {
668             $self->{scratch} .= "\\end{"
669 1         9 . $self->{emit_environment}->{sidebar} . "}\n\n";
670             }
671             else
672             {
673 7         26 $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   37 for my $end (qw( bullet number text))
685             {
686             my $end_sub = sub {
687 112     112   1227 my $self = shift;
688 112         196 $self->{scratch} .= "\n\n";
689 112         216 $self->emit();
690 21         72 };
691              
692 7     7   63 no strict 'refs';
  7         36  
  7         1224  
693 21         40 *{ 'end_item_' . $end } = $end_sub;
  21         117  
694             }
695              
696 7         139 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         73 while ( my ( $code, $fixes ) = each %formats )
709             {
710             my $start_sub = sub {
711 80     80   1414 my $self = shift;
712 80         268 $self->{scratch} .= $fixes->[0] . '{';
713 63         232 };
714              
715             my $end_sub = sub {
716 80     80   862 my $self = shift;
717 80         186 $self->{scratch} .= '}' . $fixes->[1];
718 63         245 };
719              
720 7     7   61 no strict 'refs';
  7         13  
  7         484  
721 63         112 *{ 'start_' . $code } = $start_sub;
  63         228  
722 63         105 *{ 'end_' . $code } = $end_sub;
  63         591  
723             }
724              
725             }
726              
727             1;
728             __END__