Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision a2be45a1

Von Moritz Bunkus vor mehr als 9 Jahren hinzugefügt

  • ID a2be45a1fb3e4f1ad0a906699095985b42e05ed5
  • Vorgänger 31347b09
  • Nachfolger 38666007

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.

Unterschiede anzeigen:

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{ (?:\&nbsp;|\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{ (?:\&nbsp;|\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