Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision fc2fbbca

Von Moritz Bunkus vor mehr als 10 Jahren hinzugefügt

  • ID fc2fbbca36f5ac516fdae260e9322fc3d357497c
  • Vorgänger 3b32e1dd
  • Nachfolger a4c6c83d

SL::Template::OpenDocument: Unterstützung für HTML-codierte Felder

Unterschiede anzeigen:

SL/Template/OpenDocument.pm
4 4

  
5 5
use Archive::Zip;
6 6
use Encode;
7
use HTML::Entities;
7 8
use POSIX 'setsid';
8 9

  
9 10
use SL::Iconv;
11
use SL::Template::OpenDocument::Styles;
10 12

  
11 13
use Cwd;
12 14
# use File::Copy;
......
16 18

  
17 19
use strict;
18 20

  
21
my %text_markup_replace = (
22
  b   => "BOLD",
23
  i   => "ITALIC",
24
  s   => "STRIKETHROUGH",
25
  u   => "UNDERLINE",
26
  sup => "SUPER",
27
  sub => "SUB",
28
);
29

  
30
sub _format_text {
31
  my ($self, $content, %params) = @_;
32

  
33
  $content = $::locale->quote_special_chars('Template/OpenDocument', $content);
34

  
35
  # Allow some HTML markup to be converted into the output format's
36
  # corresponding markup code, e.g. bold or italic.
37
  foreach my $key (keys(%text_markup_replace)) {
38
    my $value = $text_markup_replace{$key};
39
    $content =~ s|\&lt;${key}\&gt;|<text:span text:style-name=\"TKIVITENDO${value}\">|gi; #"
40
    $content =~ s|\&lt;/${key}\&gt;|</text:span>|gi;
41
  }
42

  
43
  return $content;
44
}
45

  
46
my %html_replace = (
47
  '</ul>'     => '</text:list>',
48
  '</ol>'     => '</text:list>',
49
  '</li>'     => '</text:p></text:list-item>',
50
  '<b>'       => '<text:span text:style-name="TKIVITENDOBOLD">',
51
  '</b>'      => '</text:span>',
52
  '<strong>'  => '<text:span text:style-name="TKIVITENDOBOLD">',
53
  '</strong>' => '</text:span>',
54
  '<i>'       => '<text:span text:style-name="TKIVITENDOITALIC">',
55
  '</i>'      => '</text:span>',
56
  '<em>'      => '<text:span text:style-name="TKIVITENDOITALIC">',
57
  '</em>'     => '</text:span>',
58
  '<u>'       => '<text:span text:style-name="TKIVITENDOUNDERLINE">',
59
  '</u>'      => '</text:span>',
60
  '<s>'       => '<text:span text:style-name="TKIVITENDOSTRIKETHROUGH">',
61
  '</s>'      => '</text:span>',
62
  '<sub>'     => '<text:span text:style-name="TKIVITENDOSUB">',
63
  '</sub>'    => '</text:span>',
64
  '<sup>'     => '<text:span text:style-name="TKIVITENDOSUPER">',
65
  '</sup>'    => '</text:span>',
66
  '<br/>'     => '<text:line-break/>',
67
  '<br>'      => '<text:line-break/>',
68
);
69

  
70
sub _format_html {
71
  my ($self, $content, %params) = @_;
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} ]}">|;
84

  
85
  my @parts = map {
86
    if (substr($_, 0, 1) eq '<') {
87
      s{ +}{}g;
88
      if ($_ eq '</p>') {
89
        $in_p--;
90
        '</text:p>';
91

  
92
      } elsif ($_ eq '<p>') {
93
        if (!$in_p) {
94
          $in_p = 1;
95
          $p_start_tag;
96
        }
97

  
98
      } elsif ($_ eq '<ul>') {
99
        $self->{used_list_styles}->{itemize}->{$self->{current_text_style}}   = 1;
100
        $html_replace{'<li>'}                                                 = $ul_li_start_tag;
101
        $ul_start_tag;
102

  
103
      } elsif ($_ eq '<ol>') {
104
        $self->{used_list_styles}->{enumerate}->{$self->{current_text_style}} = 1;
105
        $html_replace{'<li>'}                                                 = $ol_li_start_tag;
106
        $ol_start_tag;
107

  
108
      } else {
109
        $html_replace{$_} || '';
110
      }
111

  
112
    } else {
113
      $::locale->quote_special_chars('Template/OpenDocument', HTML::Entities::decode_entities($_));
114
    }
115
  } split(m{(<.*?>)}x, $content);
116

  
117
  my $out  = join('', @parts);
118
  $out    .= $p_start_tag if !$in_p;
119

  
120
  # $::lxdebug->message(0, "out $out");
121

  
122
  return $out;
123
}
124

  
125
my %formatters = (
126
  html => \&_format_html,
127
  text => \&_format_text,
128
);
129

  
19 130
sub new {
20 131
  my $type = shift;
21 132

  
22 133
  my $self = $type->SUPER::new(@_);
23 134

  
24
  $self->{"rnd"}   = int(rand(1000000));
25

  
26 135
  $self->set_tag_style('&lt;%', '%&gt;');
27 136
  $self->{quot_re} = '&quot;';
28 137

  
......
105 214
      my $tag = $&;
106 215
      substr($contents, 0, length($&)) = "";
107 216

  
217
      $self->{current_text_style} = $1 if $tag =~ m|text:style-name\s*=\s*"([^"]+)"|;
218

  
108 219
      if ($tag =~ m|<table:table-row|) {
109 220
        $contents =~ m|^(.*?)(</table:table-row[^>]*>)|;
110 221
        my $table_row = $1;
......
235 346
    return 0;
236 347
  }
237 348

  
238
  my $rnd = $self->{"rnd"};
239
  my $new_styles = qq|<style:style style:name="TLXO${rnd}BOLD" style:family="text">
240
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
241
</style:style>
242
<style:style style:name="TLXO${rnd}ITALIC" style:family="text">
243
<style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic"/>
244
</style:style>
245
<style:style style:name="TLXO${rnd}UNDERLINE" style:family="text">
246
<style:text-properties style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color"/>
247
</style:style>
248
<style:style style:name="TLXO${rnd}STRIKETHROUGH" style:family="text">
249
<style:text-properties style:text-line-through-style="solid"/>
250
</style:style>
251
<style:style style:name="TLXO${rnd}SUPER" style:family="text">
252
<style:text-properties style:text-position="super 58%"/>
253
</style:style>
254
<style:style style:name="TLXO${rnd}SUB" style:family="text">
255
<style:text-properties style:text-position="sub 58%"/>
256
</style:style>
257
|;
258

  
259
  $contents =~ s|</office:automatic-styles>|${new_styles}</office:automatic-styles>|;
260
  $contents =~ s|[\n\r]||gm;
349
  $self->{current_text_style} =  '';
350
  $self->{used_list_styles}   =  {
351
    itemize                   => {},
352
    enumerate                 => {},
353
  };
261 354

  
262 355
  my $new_contents;
263 356
  if ($self->{use_template_toolkit}) {
......
272 365
    return 0;
273 366
  }
274 367

  
368
  my $new_styles = SL::Template::OpenDocument::Styles->get_style('text_basic');
369

  
370
  foreach my $type (qw(itemize enumerate)) {
371
    foreach my $parent (sort { $a cmp $b } keys %{ $self->{used_list_styles}->{$type} }) {
372
      $new_styles .= SL::Template::OpenDocument::Styles->get_style('text_list_item', TYPE => $type, PARENT => $parent)
373
                   .  SL::Template::OpenDocument::Styles->get_style("list_${type}",  TYPE => $type, PARENT => $parent);
374
    }
375
  }
376

  
377
  # $::lxdebug->dump(0, "new_Styles", $new_styles);
378

  
379
  $new_contents =~ s|</office:automatic-styles>|${new_styles}</office:automatic-styles>|;
380
  $new_contents =~ s|[\n\r]||gm;
381

  
275 382
#   $new_contents =~ s|>|>\n|g;
276 383

  
277 384
  $zip->contents("content.xml", Encode::encode('utf-8-strict', $new_contents));
......
572 679
}
573 680

  
574 681
sub format_string {
575
  my ($self, $variable) = @_;
576
  my $form = $self->{"form"};
682
  my ($self, $content, $variable) = @_;
577 683

  
578
  $variable = $main::locale->quote_special_chars('Template/OpenDocument', $variable);
579

  
580
  # Allow some HTML markup to be converted into the output format's
581
  # corresponding markup code, e.g. bold or italic.
582
  my $rnd = $self->{"rnd"};
583
  my %markup_replace = ("b" => "BOLD", "i" => "ITALIC", "s" => "STRIKETHROUGH",
584
                        "u" => "UNDERLINE", "sup" => "SUPER", "sub" => "SUB");
585

  
586
  foreach my $key (keys(%markup_replace)) {
587
    my $value = $markup_replace{$key};
588
    $variable =~ s|\&lt;${key}\&gt;|<text:span text:style-name=\"TLXO${rnd}${value}\">|gi; #"
589
    $variable =~ s|\&lt;/${key}\&gt;|</text:span>|gi;
590
  }
684
  my $formatter =
685
       $formatters{ $self->{variable_content_types}->{$variable} }
686
    // $formatters{ $self->{default_content_type} }
687
    // $formatters{ text };
591 688

  
592
  return $variable;
689
  return $formatter->($self, $content, variable => $variable);
593 690
}
594 691

  
595 692
sub get_mime_type() {
SL/Template/OpenDocument/Styles.pm
1
package SL::Template::OpenDocument::Styles;
2

  
3
use strict;
4
use utf8;
5

  
6
use Carp;
7

  
8
my %styles = (
9
  text_basic => qq|
10
    <style:style style:name="TKIVITENDOBOLD" style:family="text">
11
      <style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
12
    </style:style>
13
    <style:style style:name="TKIVITENDOITALIC" style:family="text">
14
      <style:text-properties fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic"/>
15
    </style:style>
16
    <style:style style:name="TKIVITENDOUNDERLINE" style:family="text">
17
      <style:text-properties style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color"/>
18
    </style:style>
19
    <style:style style:name="TKIVITENDOSTRIKETHROUGH" style:family="text">
20
      <style:text-properties style:text-line-through-style="solid"/>
21
    </style:style>
22
    <style:style style:name="TKIVITENDOSUPER" style:family="text">
23
      <style:text-properties style:text-position="super 58%"/>
24
    </style:style>
25
    <style:style style:name="TKIVITENDOSUB" style:family="text">
26
      <style:text-properties style:text-position="sub 58%"/>
27
    </style:style>
28
    <style:style style:name="TKIVITENDOBULLETS" style:family="text">
29
      <style:text-properties style:font-name="OpenSymbol" fo:font-family="OpenSymbol" style:font-charset="x-symbol" style:font-name-asian="OpenSymbol" style:font-family-asian="OpenSymbol" style:font-charset-asian="x-symbol" style:font-name-complex="OpenSymbol" style:font-family-complex="OpenSymbol" style:font-charset-complex="x-symbol"/>
30
    </style:style>
31
    <style:style style:name="TKIVITENDONUMBERING" style:family="text"/>
32
|,
33

  
34
  text_list_item => qq|
35
    <style:style style:name="PKIVITENDO__TYPE____PARENT__" style:family="paragraph" style:parent-style-name="__PARENT__" style:list-style-name="LKIVITENDO__TYPE____PARENT__">
36
      <style:text-properties officeooo:rsid="002df67b" officeooo:paragraph-rsid="002df67b"/>
37
    </style:style>
38
|,
39

  
40
  list_itemize => qq|
41
    <text:list-style style:name="LKIVITENDO__TYPE____PARENT__">
42
      <text:list-level-style-bullet text:level="1" text:style-name="TKIVITENDOBULLETS" text:bullet-char="•">
43
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
44
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.80cm" fo:text-indent="-0.435cm" fo:margin-left="0.80cm"/>
45
        </style:list-level-properties>
46
      </text:list-level-style-bullet>
47
      <text:list-level-style-bullet text:level="2" text:style-name="TKIVITENDOBULLETS" text:bullet-char="◦">
48
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
49
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.2cm" fo:text-indent="-0.435cm" fo:margin-left="1.2cm"/>
50
        </style:list-level-properties>
51
      </text:list-level-style-bullet>
52
      <text:list-level-style-bullet text:level="3" text:style-name="TKIVITENDOBULLETS" text:bullet-char="▪">
53
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
54
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.6cm" fo:text-indent="-0.435cm" fo:margin-left="1.6cm"/>
55
        </style:list-level-properties>
56
      </text:list-level-style-bullet>
57
      <text:list-level-style-bullet text:level="4" text:style-name="TKIVITENDOBULLETS" text:bullet-char="•">
58
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
59
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0cm" fo:text-indent="-0.435cm" fo:margin-left="2.0cm"/>
60
        </style:list-level-properties>
61
      </text:list-level-style-bullet>
62
      <text:list-level-style-bullet text:level="5" text:style-name="TKIVITENDOBULLETS" text:bullet-char="◦">
63
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
64
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.4cm" fo:text-indent="-0.435cm" fo:margin-left="2.4cm"/>
65
        </style:list-level-properties>
66
      </text:list-level-style-bullet>
67
      <text:list-level-style-bullet text:level="6" text:style-name="TKIVITENDOBULLETS" text:bullet-char="▪">
68
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
69
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.80cm" fo:text-indent="-0.435cm" fo:margin-left="2.80cm"/>
70
        </style:list-level-properties>
71
      </text:list-level-style-bullet>
72
      <text:list-level-style-bullet text:level="7" text:style-name="TKIVITENDOBULLETS" text:bullet-char="•">
73
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
74
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.20cm" fo:text-indent="-0.435cm" fo:margin-left="3.20cm"/>
75
        </style:list-level-properties>
76
      </text:list-level-style-bullet>
77
      <text:list-level-style-bullet text:level="8" text:style-name="TKIVITENDOBULLETS" text:bullet-char="◦">
78
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
79
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.60cm" fo:text-indent="-0.435cm" fo:margin-left="3.60cm"/>
80
        </style:list-level-properties>
81
      </text:list-level-style-bullet>
82
      <text:list-level-style-bullet text:level="9" text:style-name="TKIVITENDOBULLETS" text:bullet-char="▪">
83
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
84
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.00cm" fo:text-indent="-0.435cm" fo:margin-left="4.00cm"/>
85
        </style:list-level-properties>
86
      </text:list-level-style-bullet>
87
      <text:list-level-style-bullet text:level="10" text:style-name="TKIVITENDOBULLETS" text:bullet-char="•">
88
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
89
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.40cm" fo:text-indent="-0.435cm" fo:margin-left="4.40cm"/>
90
        </style:list-level-properties>
91
      </text:list-level-style-bullet>
92
    </text:list-style>|,
93

  
94
  list_enumerate => qq|
95
    <text:list-style style:name="LKIVITENDO__TYPE____PARENT__">
96
      <text:list-level-style-number text:level="1" text:style-name="TKIVITENDONUMBERING" style:num-suffix="." style:num-format="1">
97
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
98
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="0.80cm" fo:text-indent="-0.435cm" fo:margin-left="0.80cm"/>
99
        </style:list-level-properties>
100
      </text:list-level-style-number>
101
      <text:list-level-style-number text:level="2" text:style-name="TKIVITENDONUMBERING" style:num-suffix="." style:num-format="1">
102
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
103
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.2cm" fo:text-indent="-0.435cm" fo:margin-left="1.2cm"/>
104
        </style:list-level-properties>
105
      </text:list-level-style-number>
106
      <text:list-level-style-number text:level="3" text:style-name="TKIVITENDONUMBERING" style:num-suffix="." style:num-format="1">
107
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
108
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="1.6cm" fo:text-indent="-0.435cm" fo:margin-left="1.6cm"/>
109
        </style:list-level-properties>
110
      </text:list-level-style-number>
111
      <text:list-level-style-number text:level="4" text:style-name="TKIVITENDONUMBERING" style:num-suffix="." style:num-format="1">
112
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
113
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.0cm" fo:text-indent="-0.435cm" fo:margin-left="2.0cm"/>
114
        </style:list-level-properties>
115
      </text:list-level-style-number>
116
      <text:list-level-style-number text:level="5" text:style-name="TKIVITENDONUMBERING" style:num-suffix="." style:num-format="1">
117
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
118
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.4cm" fo:text-indent="-0.435cm" fo:margin-left="2.4cm"/>
119
        </style:list-level-properties>
120
      </text:list-level-style-number>
121
      <text:list-level-style-number text:level="6" text:style-name="TKIVITENDONUMBERING" style:num-suffix="." style:num-format="1">
122
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
123
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="2.80cm" fo:text-indent="-0.435cm" fo:margin-left="2.80cm"/>
124
        </style:list-level-properties>
125
      </text:list-level-style-number>
126
      <text:list-level-style-number text:level="7" text:style-name="TKIVITENDONUMBERING" style:num-suffix="." style:num-format="1">
127
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
128
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.20cm" fo:text-indent="-0.435cm" fo:margin-left="3.20cm"/>
129
        </style:list-level-properties>
130
      </text:list-level-style-number>
131
      <text:list-level-style-number text:level="8" text:style-name="TKIVITENDONUMBERING" style:num-suffix="." style:num-format="1">
132
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
133
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="3.60cm" fo:text-indent="-0.435cm" fo:margin-left="3.60cm"/>
134
        </style:list-level-properties>
135
      </text:list-level-style-number>
136
      <text:list-level-style-number text:level="9" text:style-name="TKIVITENDONUMBERING" style:num-suffix="." style:num-format="1">
137
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
138
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.00cm" fo:text-indent="-0.435cm" fo:margin-left="4.00cm"/>
139
        </style:list-level-properties>
140
      </text:list-level-style-number>
141
      <text:list-level-style-number text:level="10" text:style-name="TKIVITENDONUMBERING" style:num-suffix="." style:num-format="1">
142
        <style:list-level-properties text:list-level-position-and-space-mode="label-alignment">
143
          <style:list-level-label-alignment text:label-followed-by="listtab" text:list-tab-stop-position="4.40cm" fo:text-indent="-0.435cm" fo:margin-left="4.40cm"/>
144
        </style:list-level-properties>
145
      </text:list-level-style-number>
146
    </text:list-style>|,
147
);
148

  
149
sub get_style {
150
  my ($class, $style_name, %replacements) = @_;
151

  
152
  my $copy = "". $styles{$style_name} || croak("Unknown style $style_name");
153

  
154
  $copy =~ s{^ +}{}gm;
155
  $copy =~ s{[\r\n]+}{}gm;
156
  $copy =~ s{__${_}__}{ $replacements{$_} }ge for keys %replacements;
157

  
158
  return $copy;
159
}
160

  
161
1;

Auch abrufbar als: Unified diff