From: Moritz Bunkus Date: Mon, 5 Oct 2015 10:52:40 +0000 (+0200) Subject: OpenDocument-Template: Umwandlung von HTML-Feldern gefixt X-Git-Tag: release-3.4.1~665 X-Git-Url: http://wagnertech.de/git?a=commitdiff_plain;h=a2be45a1fb3e4f1ad0a906699095985b42e05ed5;p=kivitendo-erp.git OpenDocument-Template: Umwandlung von HTML-Feldern gefixt OpenDocument hat gewisse Probleme mit Verschachtelung von gewissen Konstrukten, z.B. kein innerhalb von . Die HTML-Felder aber sind immer in ein

eingeschlossen. Bisheriger Ansatz war, davon auszugehen, dass der aktuell offene Tag im XML ein ist. Dafür wurde im HTML schlicht das erste

und das letzte

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 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 schließen und am Ende wieder öffnen. Potenzieller Fix für Redmine #83. --- diff --git a/SL/Template/OpenDocument.pm b/SL/Template/OpenDocument.pm index 5cf68ee38..704d5e7e0 100644 --- a/SL/Template/OpenDocument.pm +++ b/SL/Template/OpenDocument.pm @@ -70,30 +70,50 @@ my %html_replace = ( sub _format_html { my ($self, $content, %params) = @_; - $content =~ s{ ^

|

$ }{}gx; - $content =~ s{ \r+ }{}gx; - $content =~ s{ \n+ }{ }gx; - $content =~ s{ (?:\ |\s)+ }{ }gx; - - my $in_p = 1; - my $p_start_tag = qq||; - my $ul_start_tag = qq||; - my $ol_start_tag = qq||; - my $ul_li_start_tag = qq||; - my $ol_li_start_tag = qq||; + my $in_p = 0; + my $p_start_tag = qq||; + my $prefix = ''; + my $suffix = ''; + + my (@tags_to_open, @tags_to_close); + for (my $idx = scalar(@{ $self->{tag_stack} }) - 1; $idx >= 0; --$idx) { + my $tag = $self->{tag_stack}->[$idx]; + + next if $tag =~ m{/>$}; + last if $tag =~ m{^}{>}; + $prefix .= ' |

$ }{}gx if $in_p; + $content =~ s{ \r+ }{}gx; + $content =~ s{ \n+ }{ }gx; + $content =~ s{ (?:\ |\s)+ }{ }gx; + + my $ul_start_tag = qq||; + my $ol_start_tag = qq||; + my $ul_li_start_tag = qq||; + my $ol_li_start_tag = qq||; my @parts = map { if (substr($_, 0, 1) eq '<') { s{ +}{}g; if ($_ eq '

') { $in_p--; - '
'; + $in_p == 0 ? '
' : ''; } elsif ($_ eq '

') { - if (!$in_p) { - $in_p = 1; - $p_start_tag; - } + $in_p++; + $in_p == 1 ? $p_start_tag : ''; } elsif ($_ eq '

    ') { $self->{used_list_styles}->{itemize}->{$self->{current_text_style}} = 1; @@ -114,10 +134,9 @@ sub _format_html { } } split(m{(<.*?>)}x, $content); - my $out = join('', @parts); - $out .= $p_start_tag if !$in_p; + my $out = join('', $prefix, @parts, $suffix); - # $::lxdebug->message(0, "out $out"); + # $::lxdebug->dump(0, "prefix parts suffix", [ $prefix, join('', @parts), $suffix ]); return $out; } @@ -216,6 +235,8 @@ sub parse_block { $self->{current_text_style} = $1 if $tag =~ m|text:style-name\s*=\s*"([^"]+)"|; + push @{ $self->{tag_stack} }, $tag; + if ($tag =~ m|]*>)|; my $table_row = $1; @@ -261,6 +282,11 @@ sub parse_block { $new_contents .= $tag; } + if ($tag =~ m{^$}x) { + # $::lxdebug->message(0, "popping top tag is $tag top " . $self->{tag_stack}->[-1]); + pop @{ $self->{tag_stack} }; + } + } else { $contents =~ /^([^<]+)/; my $text = $1; @@ -358,6 +384,7 @@ sub parse { $::form->init_template->process(\$contents, $additional_params, \$new_contents) || die $::form->template->error; } else { + $self->{tag_stack} = []; $new_contents = $self->parse_block($contents); } if (!defined($new_contents)) {