blib/lib/Text/Amuse/InlineElement.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 169 | 181 | 93.3 |
branch | 83 | 100 | 83.0 |
condition | 5 | 6 | 83.3 |
subroutine | 22 | 23 | 95.6 |
pod | 15 | 15 | 100.0 |
total | 294 | 325 | 90.4 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package Text::Amuse::InlineElement; | ||||||
2 | 43 | 43 | 242 | use strict; | |||
43 | 67 | ||||||
43 | 968 | ||||||
3 | 43 | 43 | 157 | use warnings; | |||
43 | 88 | ||||||
43 | 745 | ||||||
4 | 43 | 43 | 152 | use utf8; | |||
43 | 60 | ||||||
43 | 155 | ||||||
5 | 43 | 43 | 1048 | use Text::Amuse::Utils; | |||
43 | 66 | ||||||
43 | 86611 | ||||||
6 | |||||||
7 | =head1 NAME | ||||||
8 | |||||||
9 | Text::Amuse::InlineElement - Helper for Text::Amuse | ||||||
10 | |||||||
11 | =head1 METHODS | ||||||
12 | |||||||
13 | Everything here is pretty much internal only, underdocumented and | ||||||
14 | subject to change. | ||||||
15 | |||||||
16 | =head2 new(%args) | ||||||
17 | |||||||
18 | Constructor. Accepts the following named arguments (which are also | ||||||
19 | accessors) | ||||||
20 | |||||||
21 | =over 4 | ||||||
22 | |||||||
23 | =item type | ||||||
24 | |||||||
25 | The element type | ||||||
26 | |||||||
27 | =item string | ||||||
28 | |||||||
29 | The raw string | ||||||
30 | |||||||
31 | =item last_position | ||||||
32 | |||||||
33 | The offset of the last character in the parsed string | ||||||
34 | |||||||
35 | =item tag | ||||||
36 | |||||||
37 | The name of the tag | ||||||
38 | |||||||
39 | =item fmt | ||||||
40 | |||||||
41 | C |
||||||
42 | |||||||
43 | =cut | ||||||
44 | |||||||
45 | sub new { | ||||||
46 | 36801 | 36801 | 1 | 94277 | my ($class, %args) = @_; | ||
47 | 36801 | 89157 | my $self = { | ||||
48 | type => '', | ||||||
49 | string => '', | ||||||
50 | last_position => 0, | ||||||
51 | tag => '', | ||||||
52 | fmt => '', | ||||||
53 | lang => 'en', | ||||||
54 | }; | ||||||
55 | 36801 | 88380 | foreach my $k (keys %$self) { | ||||
56 | 220806 | 100 | 281739 | if (defined $args{$k}) { | |||
57 | 182846 | 197134 | $self->{$k} = $args{$k}; | ||||
58 | } | ||||||
59 | 220806 | 238262 | delete $args{$k}; | ||||
60 | } | ||||||
61 | 36801 | 50 | 55934 | die "Extra arguments passed :" . join(" ", %args) if %args; | |||
62 | 36801 | 50 | 50229 | die "Missing type for <$self->{string}>" unless $self->{type}; | |||
63 | 36801 | 50 | 66 | 76192 | unless ($self->{fmt} eq 'ltx' or $self->{fmt} eq 'html') { | ||
64 | 0 | 0 | die "Missing format $self->{fmt} for <$self->{string}>" | ||||
65 | } | ||||||
66 | 36801 | 188145 | bless $self, $class; | ||||
67 | } | ||||||
68 | |||||||
69 | sub type { | ||||||
70 | 395100 | 395100 | 1 | 425092 | my ($self, $type) = @_; | ||
71 | 395100 | 100 | 454424 | if ($type) { | |||
72 | 2744 | 3378 | $self->{type} = $type; | ||||
73 | } | ||||||
74 | 395100 | 708834 | return $self->{type}; | ||||
75 | } | ||||||
76 | |||||||
77 | sub last_position { | ||||||
78 | 4628 | 4628 | 1 | 7531 | shift->{last_position}; | ||
79 | } | ||||||
80 | |||||||
81 | sub string { | ||||||
82 | 73824 | 73824 | 1 | 153129 | shift->{string}; | ||
83 | } | ||||||
84 | |||||||
85 | =item lang | ||||||
86 | |||||||
87 | The language code. | ||||||
88 | |||||||
89 | =cut | ||||||
90 | |||||||
91 | sub lang { | ||||||
92 | 13993 | 13993 | 1 | 22370 | shift->{lang}; | ||
93 | } | ||||||
94 | |||||||
95 | =item append($element) | ||||||
96 | |||||||
97 | Append the provided string to the self's one and update the | ||||||
98 | last_position. | ||||||
99 | |||||||
100 | =cut | ||||||
101 | |||||||
102 | sub append { | ||||||
103 | 0 | 0 | 1 | 0 | my ($self, $element) = @_; | ||
104 | 0 | 0 | $self->{string} .= $element->string; | ||||
105 | 0 | 0 | $self->{last_position} = $element->last_position; | ||||
106 | } | ||||||
107 | |||||||
108 | sub tag { | ||||||
109 | 35215 | 100 | 35215 | 1 | 45972 | if (@_ > 1) { | |
110 | 64 | 89 | $_[0]{tag} = $_[1]; | ||||
111 | } | ||||||
112 | 35215 | 66133 | $_[0]{tag}; | ||||
113 | } | ||||||
114 | |||||||
115 | sub fmt { | ||||||
116 | 51734 | 51734 | 1 | 110001 | shift->{fmt}; | ||
117 | } | ||||||
118 | |||||||
119 | =item stringify | ||||||
120 | |||||||
121 | Main method to get the desired output from the element. | ||||||
122 | |||||||
123 | =cut | ||||||
124 | |||||||
125 | sub stringify { | ||||||
126 | 32208 | 32208 | 1 | 32857 | my $self = shift; | ||
127 | 32208 | 43419 | my $type = $self->type; | ||||
128 | 32208 | 41228 | my $string = $self->string; | ||||
129 | 32208 | 100 | 49331 | if ($type eq 'text') { | |||
130 | 25063 | 100 | 32756 | if ($self->is_latex) { | |||
50 | |||||||
131 | 11070 | 16149 | $string = $self->escape_tex($string); | ||||
132 | 11070 | 16915 | $string = $self->_ltx_replace_ldots($string); | ||||
133 | 11070 | 14806 | $string = $self->_ltx_replace_slash($string); | ||||
134 | 11070 | 39593 | return $string; | ||||
135 | } | ||||||
136 | elsif ($self->is_html) { | ||||||
137 | 13993 | 100 | 17626 | if ($self->lang eq 'fr') { | |||
138 | 41 | 69 | $string = $self->_html_french_punctuation($string); | ||||
139 | 41 | 68 | $string = $self->escape_all_html($string); | ||||
140 | 41 | 79 | $string =~ s/\x{a0}/ /g; # make them visible | ||||
141 | 41 | 80 | $string =~ s/\x{202f}/ /g; # ditto | ||||
142 | 41 | 174 | return $string; | ||||
143 | } | ||||||
144 | else { | ||||||
145 | 13952 | 19870 | return $self->escape_all_html($string); | ||||
146 | } | ||||||
147 | } | ||||||
148 | else { | ||||||
149 | 0 | 0 | die "Not reached"; | ||||
150 | } | ||||||
151 | } | ||||||
152 | 7145 | 100 | 11483 | if ($type eq 'safe') { | |||
153 | 1583 | 2766 | return $self->verbatim_string($string); | ||||
154 | } | ||||||
155 | 5562 | 100 | 8285 | if ($type eq 'ruby') { | |||
156 | 18 | 50 | 107 | if ($string =~ m/\A\s*(.+?)\s*\|\s*(.+?)\s*<\/ruby>\z/) { | |||
157 | 18 | 59 | my ($main, $ann) = ($1, $2); | ||||
158 | 18 | 42 | $main = $self->verbatim_string($main); | ||||
159 | 18 | 38 | $ann = $self->verbatim_string($ann); | ||||
160 | 18 | 100 | 32 | if ($self->is_latex) { | |||
50 | |||||||
161 | 9 | 57 | return sprintf("\\ruby{%s}{%s}", $main, $ann); | ||||
162 | } | ||||||
163 | elsif ($self->is_html) { | ||||||
164 | 9 | 66 | return sprintf(" |
||||
165 | } | ||||||
166 | } | ||||||
167 | } | ||||||
168 | 5544 | 100 | 100 | 19494 | if ($type eq 'verbatim') { | ||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
50 | |||||||
169 | 642 | 50 | 2532 | if ($string =~ /\A |
|||
170 | 642 | 1329 | $string = $1; | ||||
171 | 642 | 1076 | return $self->verbatim_string($string); | ||||
172 | } | ||||||
173 | else { | ||||||
174 | 0 | 0 | die "<$string> doesn't match verbatim!"; | ||||
175 | } | ||||||
176 | } | ||||||
177 | elsif ($type eq 'anchor') { | ||||||
178 | 812 | 927 | my $anchor = $string; | ||||
179 | 812 | 1474 | $anchor =~ s/[^A-Za-z0-9-]//g; | ||||
180 | 812 | 50 | 1596 | die "Bad anchor " . $string unless length($anchor); | |||
181 | 812 | 100 | 1249 | if ($self->is_latex) { | |||
50 | |||||||
182 | 371 | 923 | my $label = <<"TEX"; | ||||
183 | \\hyperdef{amuse}{$anchor}{}% | ||||||
184 | \\label{textamuse:$anchor}% | ||||||
185 | TEX | ||||||
186 | 371 | 1615 | return $label; | ||||
187 | } | ||||||
188 | elsif ($self->is_html) { | ||||||
189 | 441 | 2418 | return qq{<\/a>\n} | ||||
190 | } | ||||||
191 | else { | ||||||
192 | 0 | 0 | die "Not reached"; | ||||
193 | } | ||||||
194 | } | ||||||
195 | elsif ($type eq 'open' or $type eq 'close') { | ||||||
196 | 2526 | 100 | 3633 | if ($self->tag =~ m/\A\[([a-zA-Z-]+)\]\z/) { | |||
197 | 44 | 113 | my $iso = $1; | ||||
198 | 44 | 100 | 80 | if ($self->is_latex) { | |||
50 | |||||||
199 | 22 | 100 | 57 | if ($type eq 'open') { | |||
200 | 11 | 42 | my $lang = Text::Amuse::Utils::get_latex_lang($iso); | ||||
201 | 11 | 84 | return "\\foreignlanguage{$lang}{"; | ||||
202 | } | ||||||
203 | else { | ||||||
204 | 11 | 47 | return "}"; | ||||
205 | } | ||||||
206 | } | ||||||
207 | elsif ($self->is_html) { | ||||||
208 | 22 | 100 | 49 | if ($type eq 'open') { | |||
209 | 11 | 75 | return qq{}; | ||||
210 | } | ||||||
211 | else { | ||||||
212 | 11 | 45 | return ""; | ||||
213 | } | ||||||
214 | } | ||||||
215 | } | ||||||
216 | 2482 | 3823 | my $out = $self->_markup_table->{$self->tag}->{$type}->{$self->fmt}; | ||||
217 | 2482 | 50 | 16525 | die "Missing markup for $self->fmt $type $self->tag" unless $out; | |||
218 | 2482 | 8759 | return $out; | ||||
219 | } | ||||||
220 | elsif ($type eq 'nobreakspace') { | ||||||
221 | 90 | 100 | 199 | if ($self->is_latex) { | |||
50 | |||||||
222 | 45 | 174 | return '~'; | ||||
223 | } | ||||||
224 | elsif ($self->is_html) { | ||||||
225 | 45 | 172 | return ' ' | ||||
226 | } | ||||||
227 | } | ||||||
228 | elsif ($type eq 'noindent') { | ||||||
229 | 32 | 100 | 68 | if ($self->is_latex) { | |||
230 | 13 | 54 | return "\\noindent "; | ||||
231 | } | ||||||
232 | else { | ||||||
233 | 19 | 36 | my $leading = ''; | ||||
234 | 19 | 50 | 72 | if ($string =~ m/\A(\s+)/) { | |||
235 | 0 | 0 | $leading = $1; | ||||
236 | } | ||||||
237 | 19 | 101 | return "$leading "; |
||||
238 | } | ||||||
239 | } | ||||||
240 | elsif ($type eq 'br') { | ||||||
241 | 555 | 100 | 851 | if ($self->is_latex) { | |||
242 | 247 | 804 | return "\\forcelinebreak "; | ||||
243 | } | ||||||
244 | else { | ||||||
245 | 308 | 393 | my $leading = ''; | ||||
246 | 308 | 100 | 849 | if ($string =~ m/\A(\s+)/) { | |||
247 | 84 | 169 | $leading = $1; | ||||
248 | } | ||||||
249 | 308 | 1259 | return "$leading "; |
||||
250 | } | ||||||
251 | } | ||||||
252 | elsif ($type eq 'bigskip') { | ||||||
253 | 94 | 100 | 163 | if ($self->is_latex) { | |||
254 | 47 | 176 | return "\n\\bigskip"; | ||||
255 | } | ||||||
256 | else { | ||||||
257 | 47 | 67 | my $leading = ''; | ||||
258 | 47 | 100 | 142 | if ($string =~ m/\A(\s+)/) { | |||
259 | 1 | 4 | $leading = $1; | ||||
260 | } | ||||||
261 | 47 | 212 | return "$leading "; |
||||
262 | } | ||||||
263 | } | ||||||
264 | elsif ($type eq 'verbatim_code') { | ||||||
265 | # remove the prefixes | ||||||
266 | 793 | 100 | 5330 | warn qq{ is already verbatim! in "$string"\n} if $string =~ m{ |
|||
267 | 793 | 100 | 3618 | if ($string =~ /\A=(.+)=\z/s) { | |||
100 | |||||||
50 | |||||||
268 | 628 | 1398 | $string = $1; | ||||
269 | } | ||||||
270 | elsif ($string =~ /\A
|
||||||
271 | 56 | 163 | $string = $1; | ||||
272 | } | ||||||
273 | elsif ($string =~ /\A(.*)<\/code>\z/s) { |
||||||
274 | 109 | 253 | $string = $1; | ||||
275 | } | ||||||
276 | else { | ||||||
277 | 0 | 0 | die "$string doesn't match the pattern!"; |
||||
278 | } | ||||||
279 | 793 | 100 | 1648 | if (length $string) { | |||
280 | return $self->_markup_table->{code}->{open}->{$self->fmt} | ||||||
281 | . $self->verbatim_string($string) | ||||||
282 | 775 | 1618 | . $self->_markup_table->{code}->{close}->{$self->fmt}; | ||||
283 | } | ||||||
284 | else { | ||||||
285 | 18 | 78 | return ''; | ||||
286 | } | ||||||
287 | } | ||||||
288 | else { | ||||||
289 | 0 | 0 | die "Unrecognized type " . $type . " for " . $string; | ||||
290 | } | ||||||
291 | } | ||||||
292 | |||||||
293 | sub _markup_table { | ||||||
294 | return { | ||||||
295 | 4032 | 4032 | 80557 | 'rtl' => { | |||
296 | open => { | ||||||
297 | html => '', | ||||||
298 | ltx => "\\RL{", | ||||||
299 | }, | ||||||
300 | close => { | ||||||
301 | html => '', # LRM (U+200E LEFT-TO-RIGHT MARK) | ||||||
302 | ltx => '}', | ||||||
303 | }, | ||||||
304 | }, | ||||||
305 | 'ltr' => { | ||||||
306 | open => { | ||||||
307 | html => '', | ||||||
308 | ltx => "\\LR{", | ||||||
309 | }, | ||||||
310 | close => { | ||||||
311 | html => '', # RLM (U+200F RIGHT-TO-LEFT MARK) | ||||||
312 | ltx => '}', | ||||||
313 | }, | ||||||
314 | }, | ||||||
315 | 'em' => { | ||||||
316 | open => { | ||||||
317 | html => '', | ||||||
318 | ltx => "\\emph{" | ||||||
319 | }, | ||||||
320 | close => { | ||||||
321 | html => '', | ||||||
322 | ltx => '}', | ||||||
323 | } | ||||||
324 | }, | ||||||
325 | 'strong' => { | ||||||
326 | open => { | ||||||
327 | html => '', | ||||||
328 | ltx => "\\textbf{" | ||||||
329 | }, | ||||||
330 | close => { | ||||||
331 | html => '', | ||||||
332 | ltx => '}', | ||||||
333 | } | ||||||
334 | }, | ||||||
335 | 'code' => { | ||||||
336 | open => { | ||||||
337 | html => '', |
||||||
338 | ltx => "\\texttt{", | ||||||
339 | }, | ||||||
340 | close => { | ||||||
341 | html => '', | ||||||
342 | ltx => '}', | ||||||
343 | } | ||||||
344 | }, | ||||||
345 | 'strike' => { | ||||||
346 | open => { | ||||||
347 | html => ' |
||||||
348 | ltx => "\\sout{" | ||||||
349 | }, | ||||||
350 | close => { | ||||||
351 | html => '', | ||||||
352 | ltx => '}', | ||||||
353 | } | ||||||
354 | }, | ||||||
355 | 'del' => { | ||||||
356 | open => { | ||||||
357 | html => ' |
||||||
358 | ltx => "\\sout{" | ||||||
359 | }, | ||||||
360 | close => { | ||||||
361 | html => '', | ||||||
362 | ltx => '}', | ||||||
363 | } | ||||||
364 | }, | ||||||
365 | 'sup' => { | ||||||
366 | open => { | ||||||
367 | html => '', | ||||||
368 | ltx => "\\textsuperscript{" | ||||||
369 | }, | ||||||
370 | close => { | ||||||
371 | html => '', | ||||||
372 | ltx => '}', | ||||||
373 | } | ||||||
374 | }, | ||||||
375 | 'sub' => { | ||||||
376 | open => { | ||||||
377 | html => '', | ||||||
378 | ltx => "\\textsubscript{" | ||||||
379 | }, | ||||||
380 | close => { | ||||||
381 | html => '', | ||||||
382 | ltx => '}', | ||||||
383 | } | ||||||
384 | }, | ||||||
385 | sf => { | ||||||
386 | open => { | ||||||
387 | html => '', | ||||||
388 | ltx => "\\textsf{" | ||||||
389 | }, | ||||||
390 | close => { | ||||||
391 | html => '', | ||||||
392 | ltx => '}', | ||||||
393 | } | ||||||
394 | }, | ||||||
395 | sc => { | ||||||
396 | open => { | ||||||
397 | html => '', | ||||||
398 | ltx => "\\textsc{" | ||||||
399 | }, | ||||||
400 | close => { | ||||||
401 | html => '', | ||||||
402 | ltx => '}', | ||||||
403 | } | ||||||
404 | }, | ||||||
405 | }; | ||||||
406 | } | ||||||
407 | |||||||
408 | sub _ltx_replace_ldots { | ||||||
409 | 11070 | 11070 | 13670 | my ($self, $string) = @_; | |||
410 | 11070 | 12338 | my $ldots = "\\dots{}"; | ||||
411 | 11070 | 14104 | $string =~ s/\.{3,4}/$ldots/g ; | ||||
412 | 11070 | 15910 | $string =~ s/\x{2026}/$ldots/g; | ||||
413 | 11070 | 14866 | return $string; | ||||
414 | } | ||||||
415 | |||||||
416 | sub _ltx_replace_slash { | ||||||
417 | 11070 | 11070 | 14548 | my ($self, $string) = @_; | |||
418 | 11070 | 13944 | $string =~ s!/!\\Slash{}!g; | ||||
419 | 11070 | 13144 | return $string; | ||||
420 | } | ||||||
421 | |||||||
422 | # https://unicode.org/udhr/n/notes_fra.html | ||||||
423 | # espace fine insécable ; espace justifiante | ||||||
424 | # espace fine insécable ! espace justifiante | ||||||
425 | # espace fine insécable ? espace justifiante | ||||||
426 | |||||||
427 | # espace mots insécable : espace justifiante | ||||||
428 | # espace mots insécable » espace justifiante | ||||||
429 | |||||||
430 | # espace justifiante « espace mots insécable | ||||||
431 | |||||||
432 | # espace justifiante tiret espace justifiante | ||||||
433 | # pas de blanc , espace justifiante | ||||||
434 | # pas de blanc . espace justifiante | ||||||
435 | # espace justifiante ( pas de blanc | ||||||
436 | # espace justifiante [ pas de blanc | ||||||
437 | # pas de blanc ) espace justifiante | ||||||
438 | # pas de blanc ] espace justifiante | ||||||
439 | |||||||
440 | |||||||
441 | sub _html_french_punctuation { | ||||||
442 | 41 | 41 | 61 | my ($self, $string) = @_; | |||
443 | |||||||
444 | # try the # | ||||||
445 | |||||||
446 | # optional space, punct, and then either space or end of line | ||||||
447 | 41 | 95 | my $chars = qr{[\x{20}\x{a0}\x{202f}\(\)\[\]\.\,\:«»\;\!\?]}; | ||||
448 | 41 | 74 | my $ws = qr{[\x{20}\x{a0}\x{202f}]}; | ||||
449 | 41 | 419 | $string =~ s/$ws*([;!?])(?=$chars)/\x{202f}$1/gs; | ||||
450 | 41 | 255 | $string =~ s/$ws*([;!?])$/\x{202f}$1/gms; | ||||
451 | |||||||
452 | # ditto | ||||||
453 | 41 | 268 | $string =~ s/$ws*([:»])(?=$chars)/\x{a0}$1/gs; | ||||
454 | 41 | 217 | $string =~ s/$ws*([:»])$/\x{a0}$1/gms; | ||||
455 | |||||||
456 | 41 | 149 | $string =~ s/^«$ws*/«\x{a0}/gms; | ||||
457 | 41 | 191 | $string =~ s/(?<=$chars)«$ws*/«\x{a0}/gs; | ||||
458 | 41 | 122 | return $string; | ||||
459 | } | ||||||
460 | |||||||
461 | |||||||
462 | =item escape_all_html($string) | ||||||
463 | |||||||
464 | HTML escape | ||||||
465 | |||||||
466 | =cut | ||||||
467 | |||||||
468 | sub escape_all_html { | ||||||
469 | 15747 | 15747 | 1 | 19758 | my ($self, $string) = @_; | ||
470 | 15747 | 24841 | $string =~ s/&/&/g; | ||||
471 | 15747 | 18561 | $string =~ s/</g; | ||||
472 | 15747 | 18139 | $string =~ s/>/>/g; | ||||
473 | 15747 | 17193 | $string =~ s/"/"/g; | ||||
474 | 15747 | 17013 | $string =~ s/'/'/g; | ||||
475 | 15747 | 55513 | return $string; | ||||
476 | } | ||||||
477 | |||||||
478 | =item escape_tex | ||||||
479 | |||||||
480 | Escape the string for LaTeX output | ||||||
481 | |||||||
482 | =cut | ||||||
483 | |||||||
484 | sub escape_tex { | ||||||
485 | 12352 | 12352 | 1 | 15450 | my ($self, $string) = @_; | ||
486 | 12352 | 21256 | $string =~ s/\\/\\textbackslash{}/g; | ||||
487 | 12352 | 14494 | $string =~ s/#/\\#/g ; | ||||
488 | 12352 | 14070 | $string =~ s/\$/\\\$/g; | ||||
489 | 12352 | 15355 | $string =~ s/%/\\%/g; | ||||
490 | 12352 | 15177 | $string =~ s/&/\\&/g; | ||||
491 | 12352 | 14208 | $string =~ s/_/\\_/g ; | ||||
492 | 12352 | 14298 | $string =~ s/\{/\\{/g ; | ||||
493 | 12352 | 14160 | $string =~ s/\}/\\}/g ; | ||||
494 | 12352 | 13863 | $string =~ s/\\textbackslash\\\{\\\}/\\textbackslash{}/g; | ||||
495 | 12352 | 13774 | $string =~ s/~/\\textasciitilde{}/g ; | ||||
496 | 12352 | 13894 | $string =~ s/\^/\\^{}/g ; | ||||
497 | 12352 | 14136 | $string =~ s/\|/\\textbar{}/g; | ||||
498 | 12352 | 18567 | return $string; | ||||
499 | } | ||||||
500 | |||||||
501 | |||||||
502 | =item is_latex | ||||||
503 | |||||||
504 | Shortcut to check if the format is latex | ||||||
505 | |||||||
506 | =item is_html | ||||||
507 | |||||||
508 | Shortcut to check if the format is html | ||||||
509 | |||||||
510 | =cut | ||||||
511 | |||||||
512 | sub is_latex { | ||||||
513 | 29744 | 29744 | 1 | 39335 | shift->fmt eq 'ltx'; | ||
514 | } | ||||||
515 | |||||||
516 | sub is_html { | ||||||
517 | 16264 | 16264 | 1 | 20977 | shift->fmt eq 'html'; | ||
518 | } | ||||||
519 | |||||||
520 | =item unroll | ||||||
521 | |||||||
522 | Convert the close_inline open_inline symbols (= and *) into elements | ||||||
523 | an open/close type and the tag properly set. | ||||||
524 | |||||||
525 | =cut | ||||||
526 | |||||||
527 | sub unroll { | ||||||
528 | 1490 | 1490 | 1 | 1724 | my $self = shift; | ||
529 | 1490 | 1485 | my @new; | ||||
530 | 1490 | 4991 | my %map = ( | ||||
531 | '=' => [qw/code/], | ||||||
532 | '*' => [qw/em/], | ||||||
533 | '**' => [qw/strong/], | ||||||
534 | '***' => [qw/strong em/], | ||||||
535 | ); | ||||||
536 | 1490 | 100 | 2428 | if ($self->type eq 'open_inline') { | |||
50 | |||||||
537 | 752 | 1015 | push @new, map { +{ type => 'open', tag => $_ } } @{$map{$self->tag}}; | ||||
854 | 2222 | ||||||
752 | 1257 | ||||||
538 | } | ||||||
539 | elsif ($self->type eq 'close_inline') { | ||||||
540 | 738 | 1568 | push @new, map { +{ type => 'close', tag => $_ } } reverse @{$map{$self->tag}}; | ||||
840 | 1912 | ||||||
738 | 1235 | ||||||
541 | } | ||||||
542 | else { | ||||||
543 | 0 | 0 | die "unroll can be called only on close_inline/open_inline, not " . $self->type . " " . $self->string; | ||||
544 | } | ||||||
545 | 1490 | 2355 | return map { __PACKAGE__->new(%$_, string => '', fmt => $self->fmt) } @new; | ||||
1694 | 4242 | ||||||
546 | } | ||||||
547 | |||||||
548 | =item verbatim_string($string) | ||||||
549 | |||||||
550 | Escape the string according to the element format | ||||||
551 | |||||||
552 | =cut | ||||||
553 | |||||||
554 | sub verbatim_string { | ||||||
555 | 3036 | 3036 | 1 | 4571 | my ($self, $string) = @_; | ||
556 | 3036 | 100 | 4716 | if ($self->is_latex) { | |||
50 | |||||||
557 | 1282 | 1992 | return $self->escape_tex($string); | ||||
558 | } | ||||||
559 | elsif ($self->is_html) { | ||||||
560 | 1754 | 2770 | return $self->escape_all_html($string); | ||||
561 | } | ||||||
562 | else { | ||||||
563 | 0 | die "Not reached"; | |||||
564 | } | ||||||
565 | } | ||||||
566 | |||||||
567 | =back | ||||||
568 | |||||||
569 | =cut | ||||||
570 | |||||||
571 | 1; |