Revision a2be45a1
Von Moritz Bunkus vor mehr als 9 Jahren hinzugefügt
SL/Template/OpenDocument.pm | ||
---|---|---|
70 | 70 |
sub _format_html { |
71 | 71 |
my ($self, $content, %params) = @_; |
72 | 72 |
|
73 |
$content =~ s{ ^<p> | </p>$ }{}gx; |
|
74 |
$content =~ s{ \r+ }{}gx; |
|
75 |
$content =~ s{ \n+ }{ }gx; |
|
76 |
$content =~ s{ (?:\ |\s)+ }{ }gx; |
|
77 |
|
|
78 |
my $in_p = 1; |
|
79 |
my $p_start_tag = qq|<text:p text:style-name="@{[ $self->{current_text_style} ]}">|; |
|
80 |
my $ul_start_tag = qq|<text:list xml:id="list@{[ int rand(9999999999999999) ]}" text:style-name="LKIVITENDOitemize@{[ $self->{current_text_style} ]}">|; |
|
81 |
my $ol_start_tag = qq|<text:list xml:id="list@{[ int rand(9999999999999999) ]}" text:style-name="LKIVITENDOenumerate@{[ $self->{current_text_style} ]}">|; |
|
82 |
my $ul_li_start_tag = qq|<text:list-item><text:p text:style-name="PKIVITENDOitemize@{[ $self->{current_text_style} ]}">|; |
|
83 |
my $ol_li_start_tag = qq|<text:list-item><text:p text:style-name="PKIVITENDOenumerate@{[ $self->{current_text_style} ]}">|; |
|
73 |
my $in_p = 0; |
|
74 |
my $p_start_tag = qq|<text:p text:style-name="@{[ $self->{current_text_style} ]}">|; |
|
75 |
my $prefix = ''; |
|
76 |
my $suffix = ''; |
|
77 |
|
|
78 |
my (@tags_to_open, @tags_to_close); |
|
79 |
for (my $idx = scalar(@{ $self->{tag_stack} }) - 1; $idx >= 0; --$idx) { |
|
80 |
my $tag = $self->{tag_stack}->[$idx]; |
|
81 |
|
|
82 |
next if $tag =~ m{/>$}; |
|
83 |
last if $tag =~ m{^<table}; |
|
84 |
|
|
85 |
if ($tag =~ m{^<text:p}) { |
|
86 |
$in_p = 1; |
|
87 |
$p_start_tag = $tag; |
|
88 |
last; |
|
89 |
|
|
90 |
} else { |
|
91 |
$suffix = "${tag}${suffix}"; |
|
92 |
$tag =~ s{ .*>}{>}; |
|
93 |
$prefix .= '</' . substr($tag, 1); |
|
94 |
} |
|
95 |
} |
|
96 |
|
|
97 |
$content =~ s{ ^<p> | </p>$ }{}gx if $in_p; |
|
98 |
$content =~ s{ \r+ }{}gx; |
|
99 |
$content =~ s{ \n+ }{ }gx; |
|
100 |
$content =~ s{ (?:\ |\s)+ }{ }gx; |
|
101 |
|
|
102 |
my $ul_start_tag = qq|<text:list xml:id="list@{[ int rand(9999999999999999) ]}" text:style-name="LKIVITENDOitemize@{[ $self->{current_text_style} ]}">|; |
|
103 |
my $ol_start_tag = qq|<text:list xml:id="list@{[ int rand(9999999999999999) ]}" text:style-name="LKIVITENDOenumerate@{[ $self->{current_text_style} ]}">|; |
|
104 |
my $ul_li_start_tag = qq|<text:list-item><text:p text:style-name="PKIVITENDOitemize@{[ $self->{current_text_style} ]}">|; |
|
105 |
my $ol_li_start_tag = qq|<text:list-item><text:p text:style-name="PKIVITENDOenumerate@{[ $self->{current_text_style} ]}">|; |
|
84 | 106 |
|
85 | 107 |
my @parts = map { |
86 | 108 |
if (substr($_, 0, 1) eq '<') { |
87 | 109 |
s{ +}{}g; |
88 | 110 |
if ($_ eq '</p>') { |
89 | 111 |
$in_p--; |
90 |
'</text:p>';
|
|
112 |
$in_p == 0 ? '</text:p>' : '';
|
|
91 | 113 |
|
92 | 114 |
} elsif ($_ eq '<p>') { |
93 |
if (!$in_p) { |
|
94 |
$in_p = 1; |
|
95 |
$p_start_tag; |
|
96 |
} |
|
115 |
$in_p++; |
|
116 |
$in_p == 1 ? $p_start_tag : ''; |
|
97 | 117 |
|
98 | 118 |
} elsif ($_ eq '<ul>') { |
99 | 119 |
$self->{used_list_styles}->{itemize}->{$self->{current_text_style}} = 1; |
... | ... | |
114 | 134 |
} |
115 | 135 |
} split(m{(<.*?>)}x, $content); |
116 | 136 |
|
117 |
my $out = join('', @parts); |
|
118 |
$out .= $p_start_tag if !$in_p; |
|
137 |
my $out = join('', $prefix, @parts, $suffix); |
|
119 | 138 |
|
120 |
# $::lxdebug->message(0, "out $out");
|
|
139 |
# $::lxdebug->dump(0, "prefix parts suffix", [ $prefix, join('', @parts), $suffix ]);
|
|
121 | 140 |
|
122 | 141 |
return $out; |
123 | 142 |
} |
... | ... | |
216 | 235 |
|
217 | 236 |
$self->{current_text_style} = $1 if $tag =~ m|text:style-name\s*=\s*"([^"]+)"|; |
218 | 237 |
|
238 |
push @{ $self->{tag_stack} }, $tag; |
|
239 |
|
|
219 | 240 |
if ($tag =~ m|<table:table-row|) { |
220 | 241 |
$contents =~ m|^(.*?)(</table:table-row[^>]*>)|; |
221 | 242 |
my $table_row = $1; |
... | ... | |
261 | 282 |
$new_contents .= $tag; |
262 | 283 |
} |
263 | 284 |
|
285 |
if ($tag =~ m{^</ | />$}x) { |
|
286 |
# $::lxdebug->message(0, "popping top tag is $tag top " . $self->{tag_stack}->[-1]); |
|
287 |
pop @{ $self->{tag_stack} }; |
|
288 |
} |
|
289 |
|
|
264 | 290 |
} else { |
265 | 291 |
$contents =~ /^([^<]+)/; |
266 | 292 |
my $text = $1; |
... | ... | |
358 | 384 |
|
359 | 385 |
$::form->init_template->process(\$contents, $additional_params, \$new_contents) || die $::form->template->error; |
360 | 386 |
} else { |
387 |
$self->{tag_stack} = []; |
|
361 | 388 |
$new_contents = $self->parse_block($contents); |
362 | 389 |
} |
363 | 390 |
if (!defined($new_contents)) { |
Auch abrufbar als: Unified diff
OpenDocument-Template: Umwandlung von HTML-Feldern gefixt
OpenDocument hat gewisse Probleme mit Verschachtelung von gewissen
Konstrukten, z.B. kein <text:p> innerhalb von <text:p><text:span>. Die
HTML-Felder aber sind immer in ein <p>…</p> eingeschlossen.
Bisheriger Ansatz war, davon auszugehen, dass der aktuell offene Tag im
XML ein <text:p> ist. Dafür wurde im HTML schlicht das erste <p> und das
letzte </p> entfernt. Das funktioniert, wenn das HTML-Feld der einzige
Inhalt in z.B. einer Tabellenzelle ist, z.B. eine Zelle, in der nur
<%longdescription%> steht.
Es geht aber in die Hose, wenn der innerste offene Tag eben nicht
<text:p> ist, was sehr schnell passiert, z.B. wenn man Konstrukte wie
<%description%><%if longdescription%><%longdescription%><%end%>
nutzt.
Lösung ist, die aktuell offenen Tags in einem Stack zu verfolgen. Das
HTML-Formatieren kann dann alle offenen Tags bis zum letzten <text:p>
schließen und am Ende wieder öffnen.
Potenzieller Fix für Redmine #83.