+my %text_markup_replace = (
+ b => "BOLD",
+ i => "ITALIC",
+ s => "STRIKETHROUGH",
+ u => "UNDERLINE",
+ sup => "SUPER",
+ sub => "SUB",
+);
+
+sub _format_text {
+ my ($self, $content, %params) = @_;
+
+ $content = $::locale->quote_special_chars('Template/OpenDocument', $content);
+
+ # Allow some HTML markup to be converted into the output format's
+ # corresponding markup code, e.g. bold or italic.
+ foreach my $key (keys(%text_markup_replace)) {
+ my $value = $text_markup_replace{$key};
+ $content =~ s|\<${key}\>|<text:span text:style-name=\"TKIVITENDO${value}\">|gi; #"
+ $content =~ s|\</${key}\>|</text:span>|gi;
+ }
+
+ return $content;
+}
+
+my %html_replace = (
+ '</ul>' => '</text:list>',
+ '</ol>' => '</text:list>',
+ '</li>' => '</text:p></text:list-item>',
+ '<b>' => '<text:span text:style-name="TKIVITENDOBOLD">',
+ '</b>' => '</text:span>',
+ '<strong>' => '<text:span text:style-name="TKIVITENDOBOLD">',
+ '</strong>' => '</text:span>',
+ '<i>' => '<text:span text:style-name="TKIVITENDOITALIC">',
+ '</i>' => '</text:span>',
+ '<em>' => '<text:span text:style-name="TKIVITENDOITALIC">',
+ '</em>' => '</text:span>',
+ '<u>' => '<text:span text:style-name="TKIVITENDOUNDERLINE">',
+ '</u>' => '</text:span>',
+ '<s>' => '<text:span text:style-name="TKIVITENDOSTRIKETHROUGH">',
+ '</s>' => '</text:span>',
+ '<sub>' => '<text:span text:style-name="TKIVITENDOSUB">',
+ '</sub>' => '</text:span>',
+ '<sup>' => '<text:span text:style-name="TKIVITENDOSUPER">',
+ '</sup>' => '</text:span>',
+ '<br/>' => '<text:line-break/>',
+ '<br>' => '<text:line-break/>',
+);
+
+sub _format_html {
+ my ($self, $content, %params) = @_;
+
+ my $in_p = 0;
+ my $p_start_tag = qq|<text:p text:style-name="@{[ $self->{current_text_style} ]}">|;
+ 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{^<table};
+
+ if ($tag =~ m{^<text:p}) {
+ $in_p = 1;
+ $p_start_tag = $tag;
+ last;
+
+ } else {
+ $suffix = "${tag}${suffix}";
+ $tag =~ s{ .*>}{>};
+ $prefix .= '</' . substr($tag, 1);
+ }
+ }
+
+ $content =~ s{ ^<p> | </p>$ }{}gx if $in_p;
+ $content =~ s{ \r+ }{}gx;
+ $content =~ s{ \n+ }{ }gx;
+ $content =~ s{ (?:\ |\s)+ }{ }gx;
+
+ my $ul_start_tag = qq|<text:list xml:id="list@{[ int rand(9999999999999999) ]}" text:style-name="LKIVITENDOitemize@{[ $self->{current_text_style} ]}">|;
+ my $ol_start_tag = qq|<text:list xml:id="list@{[ int rand(9999999999999999) ]}" text:style-name="LKIVITENDOenumerate@{[ $self->{current_text_style} ]}">|;
+ my $ul_li_start_tag = qq|<text:list-item><text:p text:style-name="PKIVITENDOitemize@{[ $self->{current_text_style} ]}">|;
+ my $ol_li_start_tag = qq|<text:list-item><text:p text:style-name="PKIVITENDOenumerate@{[ $self->{current_text_style} ]}">|;
+
+ my @parts = map {
+ if (substr($_, 0, 1) eq '<') {
+ s{ +}{}g;
+ if ($_ eq '</p>') {
+ $in_p--;
+ $in_p == 0 ? '</text:p>' : '';
+
+ } elsif ($_ eq '<p>') {
+ $in_p++;
+ $in_p == 1 ? $p_start_tag : '';
+
+ } elsif ($_ eq '<ul>') {
+ $self->{used_list_styles}->{itemize}->{$self->{current_text_style}} = 1;
+ $html_replace{'<li>'} = $ul_li_start_tag;
+ $ul_start_tag;
+
+ } elsif ($_ eq '<ol>') {
+ $self->{used_list_styles}->{enumerate}->{$self->{current_text_style}} = 1;
+ $html_replace{'<li>'} = $ol_li_start_tag;
+ $ol_start_tag;
+
+ } else {
+ $html_replace{$_} || '';
+ }
+
+ } else {
+ $::locale->quote_special_chars('Template/OpenDocument', HTML::Entities::decode_entities($_));
+ }
+ } split(m{(<.*?>)}x, $content);
+
+ my $out = join('', $prefix, @parts, $suffix);
+
+ # $::lxdebug->dump(0, "prefix parts suffix", [ $prefix, join('', @parts), $suffix ]);
+
+ return $out;
+}
+
+my %formatters = (
+ html => \&_format_html,
+ text => \&_format_text,
+);
+