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 | 285 | use strict; | |||
43 | 67 | ||||||
43 | 1107 | ||||||
3 | 43 | 43 | 192 | use warnings; | |||
43 | 69 | ||||||
43 | 882 | ||||||
4 | 43 | 43 | 269 | use utf8; | |||
43 | 89 | ||||||
43 | 208 | ||||||
5 | 43 | 43 | 1253 | use Text::Amuse::Utils; | |||
43 | 66 | ||||||
43 | 100009 | ||||||
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 | 36429 | 36429 | 1 | 111282 | my ($class, %args) = @_; | ||
47 | 36429 | 103293 | my $self = { | ||||
48 | type => '', | ||||||
49 | string => '', | ||||||
50 | last_position => 0, | ||||||
51 | tag => '', | ||||||
52 | fmt => '', | ||||||
53 | lang => 'en', | ||||||
54 | }; | ||||||
55 | 36429 | 104406 | foreach my $k (keys %$self) { | ||||
56 | 218574 | 100 | 314477 | if (defined $args{$k}) { | |||
57 | 180952 | 227003 | $self->{$k} = $args{$k}; | ||||
58 | } | ||||||
59 | 218574 | 268885 | delete $args{$k}; | ||||
60 | } | ||||||
61 | 36429 | 50 | 62088 | die "Extra arguments passed :" . join(" ", %args) if %args; | |||
62 | 36429 | 50 | 58415 | die "Missing type for <$self->{string}>" unless $self->{type}; | |||
63 | 36429 | 50 | 66 | 90582 | unless ($self->{fmt} eq 'ltx' or $self->{fmt} eq 'html') { | ||
64 | 0 | 0 | die "Missing format $self->{fmt} for <$self->{string}>" | ||||
65 | } | ||||||
66 | 36429 | 217492 | bless $self, $class; | ||||
67 | } | ||||||
68 | |||||||
69 | sub type { | ||||||
70 | 390516 | 390516 | 1 | 485427 | my ($self, $type) = @_; | ||
71 | 390516 | 100 | 506626 | if ($type) { | |||
72 | 2718 | 4050 | $self->{type} = $type; | ||||
73 | } | ||||||
74 | 390516 | 809467 | return $self->{type}; | ||||
75 | } | ||||||
76 | |||||||
77 | sub last_position { | ||||||
78 | 4554 | 4554 | 1 | 9033 | shift->{last_position}; | ||
79 | } | ||||||
80 | |||||||
81 | sub string { | ||||||
82 | 73029 | 73029 | 1 | 175194 | shift->{string}; | ||
83 | } | ||||||
84 | |||||||
85 | =item lang | ||||||
86 | |||||||
87 | The language code. | ||||||
88 | |||||||
89 | =cut | ||||||
90 | |||||||
91 | sub lang { | ||||||
92 | 13859 | 13859 | 1 | 25782 | 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 | 35155 | 100 | 35155 | 1 | 52365 | if (@_ > 1) { | |
110 | 64 | 141 | $_[0]{tag} = $_[1]; | ||||
111 | } | ||||||
112 | 35155 | 75858 | $_[0]{tag}; | ||||
113 | } | ||||||
114 | |||||||
115 | sub fmt { | ||||||
116 | 51193 | 51193 | 1 | 125745 | 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 | 31850 | 31850 | 1 | 42079 | my $self = shift; | ||
127 | 31850 | 43060 | my $type = $self->type; | ||||
128 | 31850 | 50022 | my $string = $self->string; | ||||
129 | 31850 | 100 | 53657 | if ($type eq 'text') { | |||
130 | 24795 | 100 | 38688 | if ($self->is_latex) { | |||
50 | |||||||
131 | 10936 | 18880 | $string = $self->escape_tex($string); | ||||
132 | 10936 | 19694 | $string = $self->_ltx_replace_ldots($string); | ||||
133 | 10936 | 18468 | $string = $self->_ltx_replace_slash($string); | ||||
134 | 10936 | 46972 | return $string; | ||||
135 | } | ||||||
136 | elsif ($self->is_html) { | ||||||
137 | 13859 | 100 | 20449 | if ($self->lang eq 'fr') { | |||
138 | 41 | 73 | $string = $self->_html_french_punctuation($string); | ||||
139 | 41 | 76 | $string = $self->escape_all_html($string); | ||||
140 | 41 | 94 | $string =~ s/\x{a0}/ /g; # make them visible | ||||
141 | 41 | 82 | $string =~ s/\x{202f}/ /g; # ditto | ||||
142 | 41 | 201 | return $string; | ||||
143 | } | ||||||
144 | else { | ||||||
145 | 13818 | 23184 | return $self->escape_all_html($string); | ||||
146 | } | ||||||
147 | } | ||||||
148 | else { | ||||||
149 | 0 | 0 | die "Not reached"; | ||||
150 | } | ||||||
151 | } | ||||||
152 | 7055 | 100 | 12502 | if ($type eq 'safe') { | |||
153 | 1617 | 3418 | return $self->verbatim_string($string); | ||||
154 | } | ||||||
155 | 5438 | 100 | 9812 | if ($type eq 'ruby') { | |||
156 | 18 | 50 | 107 | if ($string =~ m/\A\s*(.+?)\s*\|\s*(.+?)\s*<\/ruby>\z/) { | |||
157 | 18 | 54 | my ($main, $ann) = ($1, $2); | ||||
158 | 18 | 34 | $main = $self->verbatim_string($main); | ||||
159 | 18 | 35 | $ann = $self->verbatim_string($ann); | ||||
160 | 18 | 100 | 33 | if ($self->is_latex) { | |||
50 | |||||||
161 | 9 | 65 | return sprintf("\\ruby{%s}{%s}", $main, $ann); | ||||
162 | } | ||||||
163 | elsif ($self->is_html) { | ||||||
164 | 9 | 68 | return sprintf(" |
||||
165 | } | ||||||
166 | } | ||||||
167 | } | ||||||
168 | 5420 | 100 | 100 | 24408 | if ($type eq 'verbatim') { | ||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
100 | |||||||
50 | |||||||
169 | 548 | 50 | 2455 | if ($string =~ /\A |
|||
170 | 548 | 1265 | $string = $1; | ||||
171 | 548 | 1086 | 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 | 1173 | my $anchor = $string; | ||||
179 | 812 | 1777 | $anchor =~ s/[^A-Za-z0-9-]//g; | ||||
180 | 812 | 50 | 1863 | die "Bad anchor " . $string unless length($anchor); | |||
181 | 812 | 100 | 1460 | if ($self->is_latex) { | |||
50 | |||||||
182 | 371 | 1167 | my $label = <<"TEX"; | ||||
183 | \\hyperdef{amuse}{$anchor}{}% | ||||||
184 | \\label{textamuse:$anchor}% | ||||||
185 | TEX | ||||||
186 | 371 | 2298 | return $label; | ||||
187 | } | ||||||
188 | elsif ($self->is_html) { | ||||||
189 | 441 | 2749 | 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 | 2522 | 100 | 3977 | if ($self->tag =~ m/\A\[([a-zA-Z-]+)\]\z/) { | |||
197 | 44 | 119 | my $iso = $1; | ||||
198 | 44 | 100 | 90 | if ($self->is_latex) { | |||
50 | |||||||
199 | 22 | 100 | 55 | if ($type eq 'open') { | |||
200 | 11 | 43 | my $lang = Text::Amuse::Utils::get_latex_lang($iso); | ||||
201 | 11 | 92 | return "\\foreignlanguage{$lang}{"; | ||||
202 | } | ||||||
203 | else { | ||||||
204 | 11 | 49 | return "}"; | ||||
205 | } | ||||||
206 | } | ||||||
207 | elsif ($self->is_html) { | ||||||
208 | 22 | 100 | 55 | if ($type eq 'open') { | |||
209 | 11 | 139 | return qq{}; | ||||
210 | } | ||||||
211 | else { | ||||||
212 | 11 | 52 | return ""; | ||||
213 | } | ||||||
214 | } | ||||||
215 | } | ||||||
216 | 2478 | 4704 | my $out = $self->_markup_table->{$self->tag}->{$type}->{$self->fmt}; | ||||
217 | 2478 | 50 | 18855 | die "Missing markup for $self->fmt $type $self->tag" unless $out; | |||
218 | 2478 | 10009 | return $out; | ||||
219 | } | ||||||
220 | elsif ($type eq 'nobreakspace') { | ||||||
221 | 90 | 100 | 198 | if ($self->is_latex) { | |||
50 | |||||||
222 | 45 | 178 | return '~'; | ||||
223 | } | ||||||
224 | elsif ($self->is_html) { | ||||||
225 | 45 | 187 | return ' ' | ||||
226 | } | ||||||
227 | } | ||||||
228 | elsif ($type eq 'noindent') { | ||||||
229 | 32 | 100 | 72 | if ($self->is_latex) { | |||
230 | 13 | 58 | return "\\noindent "; | ||||
231 | } | ||||||
232 | else { | ||||||
233 | 19 | 41 | my $leading = ''; | ||||
234 | 19 | 50 | 75 | if ($string =~ m/\A(\s+)/) { | |||
235 | 0 | 0 | $leading = $1; | ||||
236 | } | ||||||
237 | 19 | 103 | return "$leading "; |
||||
238 | } | ||||||
239 | } | ||||||
240 | elsif ($type eq 'br') { | ||||||
241 | 541 | 100 | 1012 | if ($self->is_latex) { | |||
242 | 240 | 925 | return "\\forcelinebreak "; | ||||
243 | } | ||||||
244 | else { | ||||||
245 | 301 | 478 | my $leading = ''; | ||||
246 | 301 | 100 | 932 | if ($string =~ m/\A(\s+)/) { | |||
247 | 83 | 181 | $leading = $1; | ||||
248 | } | ||||||
249 | 301 | 1348 | return "$leading "; |
||||
250 | } | ||||||
251 | } | ||||||
252 | elsif ($type eq 'bigskip') { | ||||||
253 | 88 | 100 | 196 | if ($self->is_latex) { | |||
254 | 44 | 205 | return "\n\\bigskip"; | ||||
255 | } | ||||||
256 | else { | ||||||
257 | 44 | 83 | my $leading = ''; | ||||
258 | 44 | 100 | 212 | if ($string =~ m/\A(\s+)/) { | |||
259 | 1 | 4 | $leading = $1; | ||||
260 | } | ||||||
261 | 44 | 238 | return "$leading "; |
||||
262 | } | ||||||
263 | } | ||||||
264 | elsif ($type eq 'verbatim_code') { | ||||||
265 | # remove the prefixes | ||||||
266 | 787 | 100 | 7286 | warn qq{ is already verbatim! in "$string"\n} if $string =~ m{ |
|||
267 | 787 | 100 | 4672 | if ($string =~ /\A=(.+)=\z/s) { | |||
100 | |||||||
50 | |||||||
268 | 628 | 1791 | $string = $1; | ||||
269 | } | ||||||
270 | elsif ($string =~ /\A
|
||||||
271 | 50 | 197 | $string = $1; | ||||
272 | } | ||||||
273 | elsif ($string =~ /\A(.*)<\/code>\z/s) { |
||||||
274 | 109 | 298 | $string = $1; | ||||
275 | } | ||||||
276 | else { | ||||||
277 | 0 | 0 | die "$string doesn't match the pattern!"; |
||||
278 | } | ||||||
279 | 787 | 100 | 2027 | if (length $string) { | |||
280 | return $self->_markup_table->{code}->{open}->{$self->fmt} | ||||||
281 | . $self->verbatim_string($string) | ||||||
282 | 769 | 1666 | . $self->_markup_table->{code}->{close}->{$self->fmt}; | ||||
283 | } | ||||||
284 | else { | ||||||
285 | 18 | 75 | return ''; | ||||
286 | } | ||||||
287 | } | ||||||
288 | else { | ||||||
289 | 0 | 0 | die "Unrecognized type " . $type . " for " . $string; | ||||
290 | } | ||||||
291 | } | ||||||
292 | |||||||
293 | sub _markup_table { | ||||||
294 | return { | ||||||
295 | 4016 | 4016 | 97625 | '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 | 10936 | 10936 | 15638 | my ($self, $string) = @_; | |||
410 | 10936 | 14193 | my $ldots = "\\dots{}"; | ||||
411 | 10936 | 16994 | $string =~ s/\.{3,4}/$ldots/g ; | ||||
412 | 10936 | 18426 | $string =~ s/\x{2026}/$ldots/g; | ||||
413 | 10936 | 17490 | return $string; | ||||
414 | } | ||||||
415 | |||||||
416 | sub _ltx_replace_slash { | ||||||
417 | 10936 | 10936 | 15635 | my ($self, $string) = @_; | |||
418 | 10936 | 15708 | $string =~ s!/!\\Slash{}!g; | ||||
419 | 10936 | 16072 | 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 | 63 | my ($self, $string) = @_; | |||
443 | |||||||
444 | # try the # | ||||||
445 | |||||||
446 | # optional space, punct, and then either space or end of line | ||||||
447 | 41 | 112 | my $chars = qr{[\x{20}\x{a0}\x{202f}\(\)\[\]\.\,\:«»\;\!\?]}; | ||||
448 | 41 | 79 | my $ws = qr{[\x{20}\x{a0}\x{202f}]}; | ||||
449 | 41 | 450 | $string =~ s/$ws*([;!?])(?=$chars)/\x{202f}$1/gs; | ||||
450 | 41 | 265 | $string =~ s/$ws*([;!?])$/\x{202f}$1/gms; | ||||
451 | |||||||
452 | # ditto | ||||||
453 | 41 | 291 | $string =~ s/$ws*([:»])(?=$chars)/\x{a0}$1/gs; | ||||
454 | 41 | 229 | $string =~ s/$ws*([:»])$/\x{a0}$1/gms; | ||||
455 | |||||||
456 | 41 | 164 | $string =~ s/^«$ws*/«\x{a0}/gms; | ||||
457 | 41 | 204 | $string =~ s/(?<=$chars)«$ws*/«\x{a0}/gs; | ||||
458 | 41 | 139 | 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 | 15580 | 15580 | 1 | 23356 | my ($self, $string) = @_; | ||
470 | 15580 | 29157 | $string =~ s/&/&/g; | ||||
471 | 15580 | 21053 | $string =~ s/</g; | ||||
472 | 15580 | 21045 | $string =~ s/>/>/g; | ||||
473 | 15580 | 20251 | $string =~ s/"/"/g; | ||||
474 | 15580 | 20450 | $string =~ s/'/'/g; | ||||
475 | 15580 | 64431 | 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 | 12185 | 12185 | 1 | 17792 | my ($self, $string) = @_; | ||
486 | 12185 | 23835 | $string =~ s/\\/\\textbackslash{}/g; | ||||
487 | 12185 | 17285 | $string =~ s/#/\\#/g ; | ||||
488 | 12185 | 15570 | $string =~ s/\$/\\\$/g; | ||||
489 | 12185 | 16299 | $string =~ s/%/\\%/g; | ||||
490 | 12185 | 15336 | $string =~ s/&/\\&/g; | ||||
491 | 12185 | 15259 | $string =~ s/_/\\_/g ; | ||||
492 | 12185 | 15929 | $string =~ s/\{/\\{/g ; | ||||
493 | 12185 | 15947 | $string =~ s/\}/\\}/g ; | ||||
494 | 12185 | 15781 | $string =~ s/\\textbackslash\\\{\\\}/\\textbackslash{}/g; | ||||
495 | 12185 | 15407 | $string =~ s/~/\\textasciitilde{}/g ; | ||||
496 | 12185 | 15151 | $string =~ s/\^/\\^{}/g ; | ||||
497 | 12185 | 16121 | $string =~ s/\|/\\textbar{}/g; | ||||
498 | 12185 | 21438 | 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 | 29390 | 29390 | 1 | 45323 | shift->fmt eq 'ltx'; | ||
514 | } | ||||||
515 | |||||||
516 | sub is_html { | ||||||
517 | 16097 | 16097 | 1 | 23458 | 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 | 1486 | 1486 | 1 | 2085 | my $self = shift; | ||
529 | 1486 | 1893 | my @new; | ||||
530 | 1486 | 5829 | my %map = ( | ||||
531 | '=' => [qw/code/], | ||||||
532 | '*' => [qw/em/], | ||||||
533 | '**' => [qw/strong/], | ||||||
534 | '***' => [qw/strong em/], | ||||||
535 | ); | ||||||
536 | 1486 | 100 | 2552 | if ($self->type eq 'open_inline') { | |||
50 | |||||||
537 | 750 | 1305 | push @new, map { +{ type => 'open', tag => $_ } } @{$map{$self->tag}}; | ||||
852 | 2658 | ||||||
750 | 1300 | ||||||
538 | } | ||||||
539 | elsif ($self->type eq 'close_inline') { | ||||||
540 | 736 | 1139 | push @new, map { +{ type => 'close', tag => $_ } } reverse @{$map{$self->tag}}; | ||||
838 | 2244 | ||||||
736 | 1354 | ||||||
541 | } | ||||||
542 | else { | ||||||
543 | 0 | 0 | die "unroll can be called only on close_inline/open_inline, not " . $self->type . " " . $self->string; | ||||
544 | } | ||||||
545 | 1486 | 2523 | return map { __PACKAGE__->new(%$_, string => '', fmt => $self->fmt) } @new; | ||||
1690 | 4983 | ||||||
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 | 2970 | 2970 | 1 | 5501 | my ($self, $string) = @_; | ||
556 | 2970 | 100 | 5090 | if ($self->is_latex) { | |||
50 | |||||||
557 | 1249 | 2641 | return $self->escape_tex($string); | ||||
558 | } | ||||||
559 | elsif ($self->is_html) { | ||||||
560 | 1721 | 3268 | 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; |