epic-ts
[kivitendo-erp.git] / SL / Template / Plugin / KiviLatex.pm
1 package SL::Template::Plugin::KiviLatex;
2
3 use strict;
4 use parent qw( Template::Plugin::Filter );
5
6 my $cached_instance;
7
8 sub new {
9   my $class = shift;
10
11   return $cached_instance ||= $class->SUPER::new(@_);
12 }
13
14 sub init {
15   my $self = shift;
16
17   $self->install_filter($self->{ _ARGS }->[0] || 'KiviLatex');
18
19   return $self;
20 }
21
22 sub filter {
23   my ($self, $text, $args) = @_;
24   return $::locale->quote_special_chars('Template/LaTeX', $text);
25 }
26
27 my %html_replace = (
28   '</p>'      => "\n\n",
29   '<ul>'      => "\\begin{itemize} ",
30   '</ul>'     => "\\end{itemize} ",
31   '<ol>'      => "\\begin{enumerate} ",
32   '</ol>'     => "\\end{enumerate} ",
33   '<li>'      => "\\item ",
34   '</li>'     => " ",
35   '<b>'       => "\\textbf{",
36   '</b>'      => "}",
37   '<strong>'  => "\\textbf{",
38   '</strong>' => "}",
39   '<i>'       => "\\textit{",
40   '</i>'      => "}",
41   '<em>'      => "\\textit{",
42   '</em>'     => "}",
43   '<u>'       => "\\uline{",
44   '</u>'      => "}",
45   '<s>'       => "\\sout{",
46   '</s>'      => "}",
47   '<sub>'     => "\\textsubscript{",
48   '</sub>'    => "}",
49   '<sup>'     => "\\textsuperscript{",
50   '</sup>'    => "}",
51   '<br/>'     => "\\newline ",
52   '<br>'      => "\\newline ",
53 );
54
55 sub filter_html {
56   my ($self, $text, $args) = @_;
57
58   $text =~ s{ \r+ }{}gx;
59   $text =~ s{ \n+ }{ }gx;
60   $text =~ s{ (?:\&nbsp;|\s)+ }{ }gx;
61   $text =~ s{ <ul>\s*</ul> | <ol>\s*</ol> }{}gx; # Remove lists without items. Can happen with copy & paste from e.g. LibreOffice.
62
63   my @parts = map {
64     if (substr($_, 0, 1) eq '<') {
65       s{ +}{}g;
66       $html_replace{$_} || '';
67
68     } else {
69       $::locale->quote_special_chars('Template/LaTeX', HTML::Entities::decode_entities($_));
70     }
71   } split(m{(<.*?>)}x, $text);
72
73   return join('', @parts);
74 }
75
76 sub required_packages_for_html {
77   my ($self) = @_;
78
79   return <<EOLATEX;
80 \\usepackage{ulem}
81 EOLATEX
82 }
83
84 return 'SL::Template::Plugin::KiviLatex';
85 __END__
86
87 =pod
88
89 =encoding utf8
90
91 =head1 NAME
92
93 SL::Template::Plugin::KiviLatex - Template::Toolkit plugin for
94 escaping text for use in LaTeX templates
95
96 =head1 SYNOPSIS
97
98 From within a LaTeX template. Activate both Template::Toolkit in
99 general and this plugin in particular; must be located before
100 C<\begin{document}>:
101
102   % config: use-template-toolkit=1
103   % config: tag-style=$( )$
104   $( USE KiviLatex )$
105
106 Later escape some text:
107
108   $( KiviLatex.format(longdescription) )$
109
110 =head1 FUNCTIONS
111
112 =over 4
113
114 =item C<filter $text>
115
116 Escapes characters in C<$text> with the appropriate LaTeX
117 constructs. Expects normal text without any markup (no HTML, no XML
118 etc). Returns the whole escaped text.
119
120 =item C<filter_html $html>
121
122 Converts HTML markup in C<$html> to the appropriate LaTeX
123 constructs. Only the following HTML elements are supported:
124
125 =over 2
126
127 =item * C<b>, C<strong> – bold text
128
129 =item * C<it>, C<em> – italic text
130
131 =item * C<ul> – underlined text
132
133 =item * C<s> – striked out text
134
135 =item * C<sub>, C<sup> – subscripted and superscripted text
136
137 =item * C<ul>, C<ol>, C<li> – unordered lists (converted to an itemized
138 list), ordered lists (converted to enumerated lists) and their list
139 items
140
141 =item * C<p>, C<br> – Paragraph markers and line breaks
142
143 =back
144
145 This function is tailored for working on the input of CKEditor, not on
146 arbitrary HTML content. It works nicely in tandem with the
147 Rose::DB::Object helper functions C<…_as_restricted_html> (see
148 L<SL::DB::Helper::AttrHTML/attr_html>).
149
150 Attributes are silently removed and ignored. All other markup and the
151 normal text are escaped the same as in L</filter>.
152
153 =item C<init>
154
155 =item C<new>
156
157 Initializes the plugin. Automatically called by Template::Toolkit when
158 the plugin is loaded.
159
160 =item C<required_packages_for_html>
161
162 Returns LaTeX code loading packages that are required for the
163 formatting done with L</filter_html>. This function must be called and
164 its output inserted before the C<\begin{document}> line if that
165 function is used within the document.
166
167 It is not required for normal text escaping with L</filter>.
168
169 =back
170
171 =head1 BUGS
172
173 Nothing here yet.
174
175 =head1 AUTHOR
176
177 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
178
179 =cut