Revision 6744758d
Von Moritz Bunkus vor fast 18 Jahren hinzugefügt
- OpenDocument-Vorlagen: Konvertierung nach PDF: Der Xvfb wird nun nicht mehr nach jeder Konvertierung beendet sondern einmalig gestartet. Weitere Konvertierungen nutzen einen bereits laufenden Xvfb, was die Zeit zum Umwandeln um ca. 4s reduziert.
- OpenDocument-Vorlagen: Spezialvariablen first, last, odd und counter hinzugefuegt.
- OpenDocument-Vorlagen: "<%else%>" in "<%if%>" implementiert.
- foreach-Zeilenvariablen nach der Schleife wieder aus $form entfernen.
- HTML-Vorlagen: Unterstuetzung zur Konvertierung nach Postscript und PDF implementiert.
- OpenDocument-zu-PDF-Konvertierung: Funktionen eingebaut, um OpenOffice als Daemon zu starten, auf den ueber UNO zugegriffen wird. Dadurch verringern sich die Zeiten fuer die Konvertierung drastisch (sieben bis acht Sekunden, wenn OO fuer jedes zu konvertierende Dokument gestartet wird, und zwei bis drei Sekunden, wenn OO ueber UNO angesprochen wird). Erfordert allerdings ein installiertes Python.
- OpenOffice: Portnummer des OO-Daemons konfigurierbar gemacht.
- HTML- und LaTeX-Vorlagen: Bloecke verschachtelbar gemacht (analog zu den Parseraenderungen, die fuer OpenDocument vorgenommen wurden). Dabei Unterstuetzung fuer die <%include...%>-Anweisung entfernt.
- LaTeX/HTML-Vorlagen: Variablen koennen auch un-escaped ausgegeben werden, indem die Form <%variable NOESCAPE%> benutzt wird.
- OpenDocument-Vorlagen: Die styles.xml ebenfalls parsen, in ihr stehen die Kopf- und Fusszeilen.
- Backslashes in Variablen bei LaTeX-Vorlagen anstaendig escapen.
- Falsche Ersetzung von '&' in OpenDocument-XML-Dateien.
- Markup fuer Hoch- und Tiefstellen mit <sup>...</sup> und <sub>...</sub> bei HTML- und OpenDocument-Vorlagen.
- Markup-Tags bei Umwandlung in OpenDocument sowohl klein als auch gross geschrieben akzeptieren.
- In Vorlagen neben "<%ifnot...%>" auch "<%if not...%>" zulassen.
SL/Template.pm | ||
---|---|---|
87 | 87 |
my $form = $self->{"form"}; |
88 | 88 |
|
89 | 89 |
my %replace = |
90 |
('order' => [ |
|
90 |
('order' => [quotemeta("\\"), |
|
91 |
'<pagebreak>', |
|
91 | 92 |
'&', quotemeta("\n"), |
92 | 93 |
'"', '\$', '%', '_', '#', quotemeta('^'), |
93 | 94 |
'{', '}', '<', '>', '?', "\r" |
94 | 95 |
], |
96 |
quotemeta("\\") => '\\textbackslash ', |
|
97 |
'<pagebreak>' => '', |
|
95 | 98 |
'"' => "''", |
96 | 99 |
'&' => '\&', |
97 | 100 |
'\$' => '\$', |
... | ... | |
124 | 127 |
return $variable; |
125 | 128 |
} |
126 | 129 |
|
127 |
sub parse { |
|
128 |
my $self = $_[0]; |
|
129 |
local *OUT = $_[1]; |
|
130 |
my ($form, $myconfig) = ($self->{"form"}, $self->{"myconfig"}); |
|
130 |
sub substitute_vars { |
|
131 |
my ($self, $text, @indices) = @_; |
|
131 | 132 |
|
132 |
# Some variables used for page breaks |
|
133 |
my ($chars_per_line, $lines_on_first_page, $lines_on_second_page) = |
|
134 |
(0, 0, 0); |
|
135 |
my ($current_page, $current_line, $current_row) = (1, 1, 0); |
|
136 |
my ($pagebreak, $sum, $two_passes, $nodiscount_sum) = ("", 0, 0, 0); |
|
137 |
my ($par, $var); |
|
133 |
my $form = $self->{"form"}; |
|
138 | 134 |
|
139 |
# Do we have to run LaTeX two times? This is needed if
|
|
140 |
# the template contains page references.
|
|
141 |
$two_passes = 0;
|
|
135 |
while ($text =~ /<\%(.*?)\%>/) {
|
|
136 |
my ($var, @options) = split(/\s+/, $1);
|
|
137 |
my $value = $form->{$var};
|
|
142 | 138 |
|
143 |
if (!open(IN, "$form->{templates}/$form->{IN}")) { |
|
144 |
$self->{"error"} = "$!"; |
|
145 |
return 0; |
|
139 |
for (my $i = 0; $i < scalar(@indices); $i++) { |
|
140 |
last unless (ref($value) eq "ARRAY"); |
|
141 |
$value = $value->[$indices[$i]]; |
|
142 |
} |
|
143 |
$value = $self->format_string($value) unless (grep(/^NOESCAPE$/, @options)); |
|
144 |
substr($text, $-[0], $+[0] - $-[0]) = $value; |
|
146 | 145 |
} |
147 |
@_ = <IN>; |
|
148 |
close(IN); |
|
149 | 146 |
|
150 |
# first we generate a tmpfile |
|
151 |
# read file and replace <%variable%> |
|
152 |
while ($_ = shift) { |
|
153 |
$par = ""; |
|
154 |
$var = $_; |
|
147 |
return $text; |
|
148 |
} |
|
155 | 149 |
|
156 |
$two_passes = 1 if (/\\pageref/); |
|
150 |
sub parse_foreach { |
|
151 |
my ($self, $var, $text, $start_tag, $end_tag, @indices) = @_; |
|
157 | 152 |
|
158 |
# detect pagebreak block and its parameters |
|
159 |
if (/\s*<%pagebreak ([0-9]+) ([0-9]+) ([0-9]+)%>/) { |
|
160 |
$chars_per_line = $1; |
|
161 |
$lines_on_first_page = $2; |
|
162 |
$lines_on_second_page = $3; |
|
153 |
my ($form, $new_contents) = ($self->{"form"}, ""); |
|
163 | 154 |
|
164 |
while ($_ = shift) {
|
|
165 |
last if (/\s*<%end pagebreak%>/);
|
|
166 |
$pagebreak .= $_;
|
|
167 |
}
|
|
168 |
}
|
|
155 |
my $ary = $form->{$var};
|
|
156 |
for (my $i = 0; $i < scalar(@indices); $i++) {
|
|
157 |
last unless (ref($ary) eq "ARRAY");
|
|
158 |
$ary = $ary->[$indices[$i]];
|
|
159 |
} |
|
169 | 160 |
|
170 |
if (/\s*<%foreach /) { |
|
161 |
my $sum = 0; |
|
162 |
my $current_page = 1; |
|
163 |
my ($current_line, $corrent_row) = (0, 1); |
|
171 | 164 |
|
172 |
# this one we need for the count |
|
173 |
chomp $var; |
|
174 |
$var =~ s/\s*<%foreach (.+?)%>/$1/; |
|
175 |
while ($_ = shift) { |
|
176 |
last if (/\s*<%end /); |
|
165 |
for (my $i = 0; $i < scalar(@{$ary}); $i++) { |
|
166 |
$form->{"__first__"} = $i == 0; |
|
167 |
$form->{"__last__"} = ($i + 1) == scalar(@{$ary}); |
|
168 |
$form->{"__odd__"} = (($i + 1) % 2) == 1; |
|
169 |
$form->{"__counter__"} = $i + 1; |
|
170 |
|
|
171 |
if ((scalar(@{$form->{"description"}}) == scalar(@{$ary})) && |
|
172 |
$self->{"chars_per_line"}) { |
|
173 |
my $lines = |
|
174 |
int(length($form->{"description"}->[$i]) / $self->{"chars_per_line"}); |
|
175 |
my $lpp; |
|
176 |
|
|
177 |
$form->{"description"}->[$i] =~ s/(\\newline\s?)*$//; |
|
178 |
my $_description = $form->{"description"}->[$i]; |
|
179 |
while ($_description =~ /\\newline/) { |
|
180 |
$lines++; |
|
181 |
$_description =~ s/\\newline//; |
|
182 |
} |
|
183 |
$lines++; |
|
177 | 184 |
|
178 |
# store line in $par |
|
179 |
$par .= $_; |
|
185 |
if ($current_page == 1) { |
|
186 |
$lpp = $self->{"lines_on_first_page"}; |
|
187 |
} else { |
|
188 |
$lpp = $self->{"lines_on_second_page"}; |
|
180 | 189 |
} |
181 | 190 |
|
182 |
# Count the number of "lines" for our variable. Also find the forced pagebreak entries. |
|
183 |
my $num_entries = scalar(@{$form->{$var}}); |
|
184 |
my @forced_pagebreaks = (); |
|
185 |
for (my $i = 0; $i < scalar(@{$form->{$var}}); $i++) { |
|
186 |
if ($form->{$var}->[$i] =~ /<pagebreak>/) { |
|
187 |
push(@forced_pagebreaks, $i); |
|
188 |
} |
|
191 |
# Yes we need a manual page break -- or the user has forced one |
|
192 |
if ((($current_line + $lines) > $lpp) || |
|
193 |
($form->{"description"}->[$i] =~ /<pagebreak>/)) { |
|
194 |
my $pb = $self->{"pagebreak_block"}; |
|
195 |
|
|
196 |
# replace the special variables <%sumcarriedforward%> |
|
197 |
# and <%lastpage%> |
|
198 |
|
|
199 |
my $psum = $form->format_amount($myconfig, $sum, 2); |
|
200 |
$pb =~ s/<%sumcarriedforward%>/$psum/g; |
|
201 |
$pb =~ s/<%lastpage%>/$current_page/g; |
|
202 |
|
|
203 |
my $new_text = $self->parse_block($pb, (@indices, $i)); |
|
204 |
return undef unless (defined($new_text)); |
|
205 |
$new_contents .= $new_text; |
|
206 |
|
|
207 |
$current_page++; |
|
208 |
$current_line = 0; |
|
189 | 209 |
} |
210 |
$current_line += $lines; |
|
211 |
} |
|
212 |
if ($i < scalar(@{$form->{"linetotal"}})) { |
|
213 |
$sum += $form->parse_amount($myconfig, $form->{"linetotal"}->[$i]); |
|
214 |
} |
|
190 | 215 |
|
191 |
$current_line = 1; |
|
192 |
# display contents of $form->{number}[] array |
|
193 |
for ($i = 0; $i < $num_entries; $i++) { |
|
194 |
# Try to detect whether a manual page break is necessary |
|
195 |
# but only if there was a <%pagebreak ...%> block before |
|
196 |
|
|
197 |
if ($chars_per_line) { |
|
198 |
my $lines = |
|
199 |
int(length($form->{"description"}->[$i]) / $chars_per_line + 0.95); |
|
200 |
my $lpp; |
|
201 |
|
|
202 |
$form->{"description"}->[$i] =~ s/(\\newline\s?)*$//; |
|
203 |
my $_description = $form->{"description"}->[$i]; |
|
204 |
while ($_description =~ /\\newline/) { |
|
205 |
$lines++; |
|
206 |
$_description =~ s/\\newline//; |
|
207 |
} |
|
208 |
$lines++; |
|
216 |
my $new_text = $self->parse_block($text, (@indices, $i)); |
|
217 |
return undef unless (defined($new_text)); |
|
218 |
$new_contents .= $start_tag . $new_text . $end_tag; |
|
219 |
} |
|
220 |
map({ delete($form->{"__${_}__"}); } qw(first last odd counter)); |
|
209 | 221 |
|
210 |
if ($current_page == 1) { |
|
211 |
$lpp = $lines_on_first_page; |
|
212 |
} else { |
|
213 |
$lpp = $lines_on_second_page; |
|
214 |
} |
|
222 |
return $new_contents; |
|
223 |
} |
|
215 | 224 |
|
216 |
# Yes we need a manual page break -- or the user has forced one |
|
217 |
if ((($current_line + $lines) > $lpp) || |
|
218 |
grep(/^${current_row}$/, @forced_pagebreaks)) { |
|
219 |
my $pb = $pagebreak; |
|
225 |
sub find_end { |
|
226 |
my ($self, $text, $pos, $var, $not) = @_; |
|
220 | 227 |
|
221 |
# replace the special variables <%sumcarriedforward%>
|
|
222 |
# and <%lastpage%>
|
|
228 |
my $depth = 1;
|
|
229 |
$pos = 0 unless ($pos);
|
|
223 | 230 |
|
224 |
my $psum = $form->format_amount($myconfig, $sum, 2); |
|
225 |
my $nodiscount_psum = $form->format_amount($myconfig, $nodiscount_sum, 2); |
|
226 |
$pb =~ s/<%nodiscount_sumcarriedforward%>/$nodiscount_psum/g; |
|
227 |
$pb =~ s/<%sumcarriedforward%>/$psum/g; |
|
228 |
$pb =~ s/<%lastpage%>/$current_page/g; |
|
231 |
while ($pos < length($text)) { |
|
232 |
$pos++; |
|
229 | 233 |
|
230 |
# only "normal" variables are supported here |
|
231 |
# (no <%if, no <%foreach, no <%include) |
|
234 |
next if (substr($text, $pos - 1, 2) ne '<%'); |
|
232 | 235 |
|
233 |
while ($pb =~ /<%(.*?)%>/) { |
|
234 |
substr($pb, $-[0], $+[0] - $-[0]) = |
|
235 |
$self->format_string($form->{"$1"}->[$i]); |
|
236 |
} |
|
236 |
if ((substr($text, $pos + 1, 2) eq 'if') || (substr($text, $pos + 1, 3) eq 'for')) { |
|
237 |
$depth++; |
|
237 | 238 |
|
238 |
# page break block is ready to rock |
|
239 |
print(OUT $pb); |
|
240 |
$current_page++; |
|
241 |
$current_line = 1; |
|
242 |
} |
|
243 |
$current_line += $lines; |
|
244 |
$current_row++; |
|
245 |
} |
|
246 |
$sum += $form->parse_amount($myconfig, $form->{"linetotal"}->[$i]); |
|
247 |
$nodiscount_sum += $form->parse_amount($myconfig, $form->{"nodiscount_linetotal"}->[$i]); |
|
248 |
|
|
249 |
# don't parse par, we need it for each line |
|
250 |
$_ = $par; |
|
251 |
while (/<%(.*?)%>/) { |
|
252 |
substr($_, $-[0], $+[0] - $-[0]) = |
|
253 |
$self->format_string($form->{"$1"}->[$i]); |
|
254 |
} |
|
255 |
print OUT; |
|
239 |
} elsif ((substr($text, $pos + 1, 4) eq 'else') && (1 == $depth)) { |
|
240 |
if (!$var) { |
|
241 |
$self->{"error"} = '<%else%> outside of <%if%> / <%ifnot%>.'; |
|
242 |
return undef; |
|
243 |
} |
|
244 |
|
|
245 |
my $block = substr($text, 0, $pos - 1); |
|
246 |
substr($text, 0, $pos - 1) = ""; |
|
247 |
$text =~ s!^<\%[^\%]+\%>!!; |
|
248 |
$text = '<%if' . ($not ? " " : "not ") . $var . '%>' . $text; |
|
249 |
|
|
250 |
return ($block, $text); |
|
251 |
|
|
252 |
} elsif (substr($text, $pos + 1, 3) eq 'end') { |
|
253 |
$depth--; |
|
254 |
if ($depth == 0) { |
|
255 |
my $block = substr($text, 0, $pos - 1); |
|
256 |
substr($text, 0, $pos - 1) = ""; |
|
257 |
$text =~ s!^<\%[^\%]+\%>!!; |
|
258 |
|
|
259 |
return ($block, $text); |
|
256 | 260 |
} |
257 |
next; |
|
258 | 261 |
} |
262 |
} |
|
259 | 263 |
|
260 |
# if not comes before if!
|
|
261 |
if (/\s*<%if not /) {
|
|
264 |
return undef;
|
|
265 |
}
|
|
262 | 266 |
|
263 |
# check if it is not set and display |
|
264 |
chop; |
|
265 |
s/\s*<%if not (.+?)%>/$1/; |
|
267 |
sub parse_block { |
|
268 |
$main::lxdebug->enter_sub(); |
|
266 | 269 |
|
267 |
unless ($form->{$_}) { |
|
268 |
while ($_ = shift) { |
|
269 |
last if (/\s*<%end /); |
|
270 |
my ($self, $contents, @indices) = @_; |
|
270 | 271 |
|
271 |
# store line in $par |
|
272 |
$par .= $_; |
|
273 |
} |
|
272 |
my $new_contents = ""; |
|
274 | 273 |
|
275 |
$_ = $par; |
|
274 |
while ($contents ne "") { |
|
275 |
my $pos_if = index($contents, '<%if'); |
|
276 |
my $pos_foreach = index($contents, '<%foreach'); |
|
276 | 277 |
|
277 |
} else { |
|
278 |
while ($_ = shift) { |
|
279 |
last if (/\s*<%end /); |
|
280 |
} |
|
281 |
next; |
|
282 |
} |
|
278 |
if ((-1 == $pos_if) && (-1 == $pos_foreach)) { |
|
279 |
$new_contents .= $self->substitute_vars($contents, @indices); |
|
280 |
last; |
|
283 | 281 |
} |
284 | 282 |
|
285 |
if (/\s*<%if /) { |
|
283 |
if ((-1 == $pos_if) || ((-1 != $pos_foreach) && ($pos_if > $pos_foreach))) { |
|
284 |
$new_contents .= $self->substitute_vars(substr($contents, 0, $pos_foreach), @indices); |
|
285 |
substr($contents, 0, $pos_foreach) = ""; |
|
286 | 286 |
|
287 |
# check if it is set and display |
|
288 |
chop; |
|
289 |
s/\s*<%if (.+?)%>/$1/; |
|
287 |
if ($contents !~ m|^<\%foreach (.*?)\%>|) { |
|
288 |
$self->{"error"} = "Malformed <\%foreach\%>."; |
|
289 |
$main::lxdebug->leave_sub(); |
|
290 |
return undef; |
|
291 |
} |
|
290 | 292 |
|
291 |
if ($form->{$_}) { |
|
292 |
while ($_ = shift) { |
|
293 |
last if (/\s*<%end /); |
|
293 |
my $var = $1; |
|
294 | 294 |
|
295 |
# store line in $par |
|
296 |
$par .= $_; |
|
297 |
} |
|
295 |
substr($contents, 0, length($&)) = ""; |
|
298 | 296 |
|
299 |
$_ = $par; |
|
297 |
my $block; |
|
298 |
($block, $contents) = $self->find_end($contents); |
|
299 |
if (!$block) { |
|
300 |
$self->{"error"} = "Unclosed <\%foreach\%>." unless ($self->{"error"}); |
|
301 |
$main::lxdebug->leave_sub(); |
|
302 |
return undef; |
|
303 |
} |
|
300 | 304 |
|
301 |
} else { |
|
302 |
while ($_ = shift) { |
|
303 |
last if (/\s*<%end /); |
|
305 |
my $new_text = $self->parse_foreach($var, $block, "", "", @indices); |
|
306 |
if (!defined($new_text)) { |
|
307 |
$main::lxdebug->leave_sub(); |
|
308 |
return undef; |
|
309 |
} |
|
310 |
$new_contents .= $new_text; |
|
311 |
|
|
312 |
} else { |
|
313 |
$new_contents .= $self->substitute_vars(substr($contents, 0, $pos_if), @indices); |
|
314 |
substr($contents, 0, $pos_if) = ""; |
|
315 |
|
|
316 |
if ($contents !~ m|^<\%if\s*(not)?\s+(.*?)\%>|) { |
|
317 |
$self->{"error"} = "Malformed <\%if\%>."; |
|
318 |
$main::lxdebug->leave_sub(); |
|
319 |
return undef; |
|
320 |
} |
|
321 |
|
|
322 |
my ($not, $var) = ($1, $2); |
|
323 |
|
|
324 |
substr($contents, 0, length($&)) = ""; |
|
325 |
|
|
326 |
($block, $contents) = $self->find_end($contents, 0, $var, $not); |
|
327 |
if (!$block) { |
|
328 |
$self->{"error"} = "Unclosed <\%if${not}\%>." unless ($self->{"error"}); |
|
329 |
$main::lxdebug->leave_sub(); |
|
330 |
return undef; |
|
331 |
} |
|
332 |
|
|
333 |
my $value = $self->{"form"}->{$var}; |
|
334 |
for (my $i = 0; $i < scalar(@indices); $i++) { |
|
335 |
last unless (ref($value) eq "ARRAY"); |
|
336 |
$value = $value->[$indices[$i]]; |
|
337 |
} |
|
338 |
|
|
339 |
if (($not && !$value) || (!$not && $value)) { |
|
340 |
my $new_text = $self->parse_block($block, @indices); |
|
341 |
if (!defined($new_text)) { |
|
342 |
$main::lxdebug->leave_sub(); |
|
343 |
return undef; |
|
304 | 344 |
} |
305 |
next;
|
|
345 |
$new_contents .= $new_text;
|
|
306 | 346 |
} |
307 | 347 |
} |
348 |
} |
|
308 | 349 |
|
309 |
# check for <%include filename%> |
|
310 |
if (/\s*<%include /) { |
|
350 |
$main::lxdebug->leave_sub(); |
|
311 | 351 |
|
312 |
# get the filename |
|
313 |
chomp $var; |
|
314 |
$var =~ s/\s*<%include (.+?)%>/$1/; |
|
352 |
return $new_contents; |
|
353 |
} |
|
315 | 354 |
|
316 |
# mangle filename |
|
317 |
$var =~ s/(\/|\.\.)//g; |
|
355 |
sub parse { |
|
356 |
my $self = $_[0]; |
|
357 |
local *OUT = $_[1]; |
|
358 |
my $form = $self->{"form"}; |
|
318 | 359 |
|
319 |
# prevent the infinite loop! |
|
320 |
next if ($form->{"$var"}); |
|
360 |
# Do we have to run LaTeX two times? This is needed if |
|
361 |
# the template contains page references. |
|
362 |
my $two_passes = 0; |
|
321 | 363 |
|
322 |
open(INC, $form->{templates} . "/$var") |
|
323 |
or $form->error($self->cleanup . $form->{templates} . "/$var : $!"); |
|
324 |
unshift(@_, <INC>); |
|
325 |
close(INC); |
|
364 |
if (!open(IN, "$form->{templates}/$form->{IN}")) { |
|
365 |
$self->{"error"} = "$!"; |
|
366 |
return 0; |
|
367 |
} |
|
368 |
@_ = <IN>; |
|
369 |
close(IN); |
|
326 | 370 |
|
327 |
$form->{"$var"} = 1; |
|
371 |
my $contents = join("", @_); |
|
372 |
$two_passes = 1 if ($contents =~ /\\pageref/s); |
|
328 | 373 |
|
329 |
next; |
|
330 |
} |
|
374 |
# detect pagebreak block and its parameters |
|
375 |
if ($contents =~ /<%pagebreak\s+(\d+)\s+(\d+)\s+(\d+)\s*%>(.*?)<%end(\s*pagebreak)?%>/s) { |
|
376 |
$self->{"chars_per_line"} = $1; |
|
377 |
$self->{"lines_on_first_page"} = $2; |
|
378 |
$self->{"lines_on_second_page"} = $3; |
|
379 |
$self->{"pagebreak_block"} = $4; |
|
331 | 380 |
|
332 |
while (/<%(.*?)%>/) { |
|
333 |
substr($_, $-[0], $+[0] - $-[0]) = $self->format_string($form->{$1}); |
|
334 |
} |
|
335 |
print OUT; |
|
381 |
substr($contents, length($`), length($&)) = ""; |
|
336 | 382 |
} |
337 | 383 |
|
384 |
$self->{"forced_pagebreaks"} = []; |
|
385 |
|
|
386 |
my $new_contents = $self->parse_block($contents); |
|
387 |
if (!defined($new_contents)) { |
|
388 |
$main::lxdebug->leave_sub(); |
|
389 |
return 0; |
|
390 |
} |
|
391 |
|
|
392 |
print(OUT $new_contents); |
|
393 |
|
|
338 | 394 |
if ($form->{"format"} =~ /postscript/i) { |
339 | 395 |
return $self->convert_to_postscript($two_passes); |
340 | 396 |
} elsif ($form->{"format"} =~ /pdf/i) { |
... | ... | |
473 | 529 |
|
474 | 530 |
# Allow some HTML markup to be converted into the output format's |
475 | 531 |
# corresponding markup code, e.g. bold or italic. |
476 |
my @markup_replace = ('b', 'i', 's', 'u'); |
|
532 |
my @markup_replace = ('b', 'i', 's', 'u', 'sub', 'sup');
|
|
477 | 533 |
|
478 | 534 |
foreach my $key (@markup_replace) { |
479 | 535 |
$variable =~ s/\<(\/?)${key}\>/<$1${key}>/g; |
... | ... | |
483 | 539 |
} |
484 | 540 |
|
485 | 541 |
sub get_mime_type() { |
486 |
return "text/html"; |
|
542 |
my ($self) = @_; |
|
543 |
|
|
544 |
if ($self->{"form"}->{"format"} =~ /postscript/i) { |
|
545 |
return "application/postscript"; |
|
546 |
} elsif ($self->{"form"}->{"format"} =~ /pdf/i) { |
|
547 |
return "application/pdf"; |
|
548 |
} else { |
|
549 |
return "text/html"; |
|
550 |
} |
|
487 | 551 |
} |
488 | 552 |
|
489 | 553 |
sub uses_temp_file { |
490 |
return 0; |
|
554 |
my ($self) = @_; |
|
555 |
|
|
556 |
if ($self->{"form"}->{"format"} =~ /postscript/i) { |
|
557 |
return 1; |
|
558 |
} elsif ($self->{"form"}->{"format"} =~ /pdf/i) { |
|
559 |
return 1; |
|
560 |
} else { |
|
561 |
return 0; |
|
562 |
} |
|
563 |
} |
|
564 |
|
|
565 |
sub convert_to_postscript { |
|
566 |
my ($self) = @_; |
|
567 |
my ($form, $userspath) = ($self->{"form"}, $self->{"userspath"}); |
|
568 |
|
|
569 |
# Convert the HTML file to postscript |
|
570 |
|
|
571 |
if (!chdir("$userspath")) { |
|
572 |
$self->{"error"} = "chdir : $!"; |
|
573 |
$self->cleanup(); |
|
574 |
return 0; |
|
575 |
} |
|
576 |
|
|
577 |
$form->{"tmpfile"} =~ s/$userspath\///g; |
|
578 |
my $psfile = $form->{"tmpfile"}; |
|
579 |
$psfile =~ s/.html/.ps/; |
|
580 |
if ($psfile eq $form->{"tmpfile"}) { |
|
581 |
$psfile .= ".ps"; |
|
582 |
} |
|
583 |
|
|
584 |
system("html2ps -f html2ps-config < $form->{tmpfile} > $psfile"); |
|
585 |
if ($?) { |
|
586 |
$self->{"error"} = $form->cleanup(); |
|
587 |
$self->cleanup(); |
|
588 |
return 0; |
|
589 |
} |
|
590 |
|
|
591 |
$form->{"tmpfile"} = $psfile; |
|
592 |
|
|
593 |
$self->cleanup(); |
|
594 |
|
|
595 |
return 1; |
|
491 | 596 |
} |
492 | 597 |
|
598 |
sub convert_to_pdf { |
|
599 |
my ($self) = @_; |
|
600 |
my ($form, $userspath) = ($self->{"form"}, $self->{"userspath"}); |
|
601 |
|
|
602 |
# Convert the HTML file to PDF |
|
603 |
|
|
604 |
if (!chdir("$userspath")) { |
|
605 |
$self->{"error"} = "chdir : $!"; |
|
606 |
$self->cleanup(); |
|
607 |
return 0; |
|
608 |
} |
|
609 |
|
|
610 |
$form->{"tmpfile"} =~ s/$userspath\///g; |
|
611 |
my $pdffile = $form->{"tmpfile"}; |
|
612 |
$pdffile =~ s/.html/.pdf/; |
|
613 |
if ($pdffile eq $form->{"tmpfile"}) { |
|
614 |
$pdffile .= ".pdf"; |
|
615 |
} |
|
616 |
|
|
617 |
system("html2ps -f html2ps-config < $form->{tmpfile} | ps2pdf - $pdffile"); |
|
618 |
if ($?) { |
|
619 |
$self->{"error"} = $form->cleanup(); |
|
620 |
$self->cleanup(); |
|
621 |
return 0; |
|
622 |
} |
|
623 |
|
|
624 |
$form->{"tmpfile"} = $pdffile; |
|
625 |
|
|
626 |
$self->cleanup(); |
|
627 |
|
|
628 |
return 1; |
|
629 |
} |
|
493 | 630 |
|
494 | 631 |
|
495 | 632 |
#### |
... | ... | |
498 | 635 |
|
499 | 636 |
package OpenDocumentTemplate; |
500 | 637 |
|
638 |
use POSIX 'setsid'; |
|
501 | 639 |
use vars qw(@ISA); |
502 | 640 |
|
503 | 641 |
use Cwd; |
... | ... | |
560 | 698 |
} |
561 | 699 |
|
562 | 700 |
for (my $i = 0; $i < scalar(@{$ary}); $i++) { |
701 |
$form->{"__first__"} = $i == 0; |
|
702 |
$form->{"__last__"} = ($i + 1) == scalar(@{$ary}); |
|
703 |
$form->{"__odd__"} = (($i + 1) % 2) == 1; |
|
704 |
$form->{"__counter__"} = $i + 1; |
|
563 | 705 |
my $new_text = $self->parse_block($text, (@indices, $i)); |
564 | 706 |
return undef unless (defined($new_text)); |
565 | 707 |
$new_contents .= $start_tag . $new_text . $end_tag; |
566 | 708 |
} |
709 |
map({ delete($form->{"__${_}__"}); } qw(first last odd counter)); |
|
567 | 710 |
|
568 | 711 |
return $new_contents; |
569 | 712 |
} |
570 | 713 |
|
714 |
sub find_end { |
|
715 |
my ($self, $text, $pos, $var, $not) = @_; |
|
716 |
|
|
717 |
my $depth = 1; |
|
718 |
$pos = 0 unless ($pos); |
|
719 |
|
|
720 |
while ($pos < length($text)) { |
|
721 |
$pos++; |
|
722 |
|
|
723 |
next if (substr($text, $pos - 1, 5) ne '<%'); |
|
724 |
|
|
725 |
if ((substr($text, $pos + 4, 2) eq 'if') || (substr($text, $pos + 4, 3) eq 'for')) { |
|
726 |
$depth++; |
|
727 |
|
|
728 |
} elsif ((substr($text, $pos + 4, 4) eq 'else') && (1 == $depth)) { |
|
729 |
if (!$var) { |
|
730 |
$self->{"error"} = '<%else%> outside of <%if%> / <%ifnot%>.'; |
|
731 |
return undef; |
|
732 |
} |
|
733 |
|
|
734 |
my $block = substr($text, 0, $pos - 1); |
|
735 |
substr($text, 0, $pos - 1) = ""; |
|
736 |
$text =~ s!^\<\%[^\%]+\%\>!!; |
|
737 |
$text = '<%if' . ($not ? " " : "not ") . $var . '%>' . $text; |
|
738 |
|
|
739 |
return ($block, $text); |
|
740 |
|
|
741 |
} elsif (substr($text, $pos + 4, 3) eq 'end') { |
|
742 |
$depth--; |
|
743 |
if ($depth == 0) { |
|
744 |
my $block = substr($text, 0, $pos - 1); |
|
745 |
substr($text, 0, $pos - 1) = ""; |
|
746 |
$text =~ s!^\<\%[^\%]+\%\>!!; |
|
747 |
|
|
748 |
return ($block, $text); |
|
749 |
} |
|
750 |
} |
|
751 |
} |
|
752 |
|
|
753 |
return undef; |
|
754 |
} |
|
755 |
|
|
571 | 756 |
sub parse_block { |
572 | 757 |
$main::lxdebug->enter_sub(); |
573 | 758 |
|
... | ... | |
590 | 775 |
if ($table_row =~ m|\<\%foreachrow\s+(.*?)\%\>|) { |
591 | 776 |
my $var = $1; |
592 | 777 |
|
593 |
$table_row =~ s|\<\%foreachrow .*?\%\>||g; |
|
594 |
$table_row =~ s!\<\%end(for|foreach)?row\s+${var}\%\>!!g; |
|
778 |
substr($table_row, length($`), length($&)) = ""; |
|
779 |
|
|
780 |
my ($t1, $t2) = $self->find_end($table_row, length($`)); |
|
781 |
if (!$t1) { |
|
782 |
$self->{"error"} = "Unclosed <\%foreachrow\%>." unless ($self->{"error"}); |
|
783 |
$main::lxdebug->leave_sub(); |
|
784 |
return undef; |
|
785 |
} |
|
595 | 786 |
|
596 |
my $new_text = $self->parse_foreach($var, $table_row, $tag, $end_tag, @indices); |
|
597 |
return undef unless (defined($new_text)); |
|
787 |
my $new_text = $self->parse_foreach($var, $t1 . $t2, $tag, $end_tag, @indices); |
|
788 |
if (!defined($new_text)) { |
|
789 |
$main::lxdebug->leave_sub(); |
|
790 |
return undef; |
|
791 |
} |
|
598 | 792 |
$new_contents .= $new_text; |
599 | 793 |
|
600 | 794 |
} else { |
601 | 795 |
my $new_text = $self->parse_block($table_row, @indices); |
602 |
return undef unless (defined($new_text)); |
|
796 |
if (!defined($new_text)) { |
|
797 |
$main::lxdebug->leave_sub(); |
|
798 |
return undef; |
|
799 |
} |
|
603 | 800 |
$new_contents .= $tag . $new_text . $end_tag; |
604 | 801 |
} |
605 | 802 |
|
... | ... | |
634 | 831 |
|
635 | 832 |
substr($contents, 0, length($&)) = ""; |
636 | 833 |
|
637 |
if ($contents !~ m!\<\%end\s*?(for)?\s+${var}\%\>!) { |
|
638 |
$self->{"error"} = "Unclosed <\%foreach\%>."; |
|
834 |
my $block; |
|
835 |
($block, $contents) = $self->find_end($contents); |
|
836 |
if (!$block) { |
|
837 |
$self->{"error"} = "Unclosed <\%foreach\%>." unless ($self->{"error"}); |
|
639 | 838 |
$main::lxdebug->leave_sub(); |
640 | 839 |
return undef; |
641 | 840 |
} |
642 | 841 |
|
643 |
substr($contents, 0, length($`) + length($&)) = ""; |
|
644 |
my $new_text = $self->parse_foreach($var, $`, "", "", @indices); |
|
645 |
return undef unless (defined($new_text)); |
|
842 |
my $new_text = $self->parse_foreach($var, $block, "", "", @indices); |
|
843 |
if (!defined($new_text)) { |
|
844 |
$main::lxdebug->leave_sub(); |
|
845 |
return undef; |
|
846 |
} |
|
646 | 847 |
$new_contents .= $new_text; |
647 | 848 |
|
648 | 849 |
} else { |
649 | 850 |
$new_contents .= $self->substitute_vars(substr($contents, 0, $pos_if), @indices); |
650 | 851 |
substr($contents, 0, $pos_if) = ""; |
651 | 852 |
|
652 |
if ($contents !~ m|^\<\%if(not)?\s+(.*?)\%\>|) { |
|
853 |
if ($contents !~ m|^\<\%if\s*(not)?\s+(.*?)\%\>|) {
|
|
653 | 854 |
$self->{"error"} = "Malformed <\%if\%>."; |
654 | 855 |
$main::lxdebug->leave_sub(); |
655 | 856 |
return undef; |
... | ... | |
659 | 860 |
|
660 | 861 |
substr($contents, 0, length($&)) = ""; |
661 | 862 |
|
662 |
if ($contents !~ m!\<\%endif${not}\s+${var}\%\>!) { |
|
663 |
$self->{"error"} = "Unclosed <\%if${not}\%>."; |
|
863 |
($block, $contents) = $self->find_end($contents, 0, $var, $not); |
|
864 |
if (!$block) { |
|
865 |
$self->{"error"} = "Unclosed <\%if${not}\%>." unless ($self->{"error"}); |
|
664 | 866 |
$main::lxdebug->leave_sub(); |
665 | 867 |
return undef; |
666 | 868 |
} |
667 | 869 |
|
668 |
substr($contents, 0, length($`) + length($&)) = ""; |
|
669 |
|
|
670 | 870 |
my $value = $self->{"form"}->{$var}; |
671 | 871 |
for (my $i = 0; $i < scalar(@indices); $i++) { |
672 | 872 |
last unless (ref($value) eq "ARRAY"); |
... | ... | |
674 | 874 |
} |
675 | 875 |
|
676 | 876 |
if (($not && !$value) || (!$not && $value)) { |
677 |
my $new_text = $self->parse_block($`, @indices); |
|
678 |
return undef unless (defined($new_text)); |
|
877 |
my $new_text = $self->parse_block($block, @indices); |
|
878 |
if (!defined($new_text)) { |
|
879 |
$main::lxdebug->leave_sub(); |
|
880 |
return undef; |
|
881 |
} |
|
679 | 882 |
$new_contents .= $new_text; |
680 | 883 |
} |
681 | 884 |
} |
682 | 885 |
} |
683 | 886 |
} |
684 | 887 |
|
888 |
$main::lxdebug->leave_sub(); |
|
889 |
|
|
685 | 890 |
return $new_contents; |
686 | 891 |
} |
687 | 892 |
|
... | ... | |
694 | 899 |
|
695 | 900 |
close(OUT); |
696 | 901 |
|
902 |
my $file_name; |
|
903 |
if ($form->{"IN"} =~ m|^/|) { |
|
904 |
$file_name = $form->{"IN"}; |
|
905 |
} else { |
|
906 |
$file_name = $form->{"templates"} . "/" . $form->{"IN"}; |
|
907 |
} |
|
908 |
|
|
697 | 909 |
my $zip = Archive::Zip->new(); |
698 |
if (Archive::Zip::AZ_OK != $zip->read("$form->{templates}/$form->{IN}")) {
|
|
910 |
if (Archive::Zip::AZ_OK != $zip->read($file_name)) {
|
|
699 | 911 |
$self->{"error"} = "File not found/is not a OpenDocument file."; |
700 | 912 |
$main::lxdebug->leave_sub(); |
701 | 913 |
return 0; |
... | ... | |
720 | 932 |
</style:style> |
721 | 933 |
<style:style style:name="TLXO${rnd}STRIKETHROUGH" style:family="text"> |
722 | 934 |
<style:text-properties style:text-line-through-style="solid"/> |
723 |
</style:style>|; |
|
935 |
</style:style> |
|
936 |
<style:style style:name="TLXO${rnd}SUPER" style:family="text"> |
|
937 |
<style:text-properties style:text-position="super 58%"/> |
|
938 |
</style:style> |
|
939 |
<style:style style:name="TLXO${rnd}SUB" style:family="text"> |
|
940 |
<style:text-properties style:text-position="sub 58%"/> |
|
941 |
</style:style> |
|
942 |
|; |
|
724 | 943 |
|
725 | 944 |
$contents =~ s|</office:automatic-styles>|${new_styles}</office:automatic-styles>|; |
726 | 945 |
$contents =~ s|[\n\r]||gm; |
727 | 946 |
|
728 | 947 |
my $new_contents = $self->parse_block($contents); |
729 |
return 0 unless (defined($new_contents)); |
|
948 |
if (!defined($new_contents)) { |
|
949 |
$main::lxdebug->leave_sub(); |
|
950 |
return 0; |
|
951 |
} |
|
730 | 952 |
|
731 | 953 |
# $new_contents =~ s|>|>\n|g; |
732 | 954 |
|
733 | 955 |
$zip->contents("content.xml", $new_contents); |
956 |
|
|
957 |
my $styles = $zip->contents("styles.xml"); |
|
958 |
if ($contents) { |
|
959 |
my $new_styles = $self->parse_block($styles); |
|
960 |
if (!defined($new_contents)) { |
|
961 |
$main::lxdebug->leave_sub(); |
|
962 |
return 0; |
|
963 |
} |
|
964 |
$zip->contents("styles.xml", $new_styles); |
|
965 |
} |
|
966 |
|
|
734 | 967 |
$zip->writeToFileNamed($form->{"tmpfile"}, 1); |
735 | 968 |
|
736 | 969 |
my $res = 1; |
... | ... | |
742 | 975 |
return $res; |
743 | 976 |
} |
744 | 977 |
|
978 |
sub is_xvfb_running { |
|
979 |
$main::lxdebug->enter_sub(); |
|
980 |
|
|
981 |
my ($self) = @_; |
|
982 |
|
|
983 |
local *IN; |
|
984 |
my $dfname = $self->{"userspath"} . "/xvfb_display"; |
|
985 |
my $display; |
|
986 |
|
|
987 |
$main::lxdebug->message(LXDebug::DEBUG2, " Looking for $dfname\n"); |
|
988 |
if ((-f $dfname) && open(IN, $dfname)) { |
|
989 |
my $pid = <IN>; |
|
990 |
chomp($pid); |
|
991 |
$display = <IN>; |
|
992 |
chomp($display); |
|
993 |
my $xauthority = <IN>; |
|
994 |
chomp($xauthority); |
|
995 |
close(IN); |
|
996 |
|
|
997 |
$main::lxdebug->message(LXDebug::DEBUG2, " found with $pid and $display\n"); |
|
998 |
|
|
999 |
if ((! -d "/proc/$pid") || !open(IN, "/proc/$pid/cmdline")) { |
|
1000 |
$main::lxdebug->message(LXDebug::DEBUG2, " no/wrong process #1\n"); |
|
1001 |
unlink($dfname, $xauthority); |
|
1002 |
$main::lxdebug->leave_sub(); |
|
1003 |
return undef; |
|
1004 |
} |
|
1005 |
my $line = <IN>; |
|
1006 |
close(IN); |
|
1007 |
if ($line !~ /xvfb/i) { |
|
1008 |
$main::lxdebug->message(LXDebug::DEBUG2, " no/wrong process #2\n"); |
|
1009 |
unlink($dfname, $xauthority); |
|
1010 |
$main::lxdebug->leave_sub(); |
|
1011 |
return undef; |
|
1012 |
} |
|
1013 |
|
|
1014 |
$ENV{"XAUTHORITY"} = $xauthority; |
|
1015 |
$ENV{"DISPLAY"} = $display; |
|
1016 |
} else { |
|
1017 |
$main::lxdebug->message(LXDebug::DEBUG2, " not found\n"); |
|
1018 |
} |
|
1019 |
|
|
1020 |
$main::lxdebug->leave_sub(); |
|
1021 |
|
|
1022 |
return $display; |
|
1023 |
} |
|
1024 |
|
|
1025 |
sub spawn_xvfb { |
|
1026 |
$main::lxdebug->enter_sub(); |
|
1027 |
|
|
1028 |
my ($self) = @_; |
|
1029 |
|
|
1030 |
$main::lxdebug->message(LXDebug::DEBUG2, "spawn_xvfb()\n"); |
|
1031 |
|
|
1032 |
my $display = $self->is_xvfb_running(); |
|
1033 |
|
|
1034 |
if ($display) { |
|
1035 |
$main::lxdebug->leave_sub(); |
|
1036 |
return $display; |
|
1037 |
} |
|
1038 |
|
|
1039 |
$display = 99; |
|
1040 |
while ( -f "/tmp/.X${display}-lock") { |
|
1041 |
$display++; |
|
1042 |
} |
|
1043 |
$display = ":${display}"; |
|
1044 |
$main::lxdebug->message(LXDebug::DEBUG2, " display $display\n"); |
|
1045 |
|
|
1046 |
my $mcookie = `mcookie`; |
|
1047 |
die("Installation error: mcookie not found.") if ($? != 0); |
|
1048 |
chomp($mcookie); |
|
1049 |
|
|
1050 |
$main::lxdebug->message(LXDebug::DEBUG2, " mcookie $mcookie\n"); |
|
1051 |
|
|
1052 |
my $xauthority = "/tmp/.Xauthority-" . $$ . "-" . time() . "-" . int(rand(9999999)); |
|
1053 |
$ENV{"XAUTHORITY"} = $xauthority; |
|
1054 |
|
|
1055 |
$main::lxdebug->message(LXDebug::DEBUG2, " xauthority $xauthority\n"); |
|
1056 |
|
|
1057 |
system("xauth add \"${display}\" . \"${mcookie}\""); |
|
1058 |
if ($? != 0) { |
|
1059 |
$self->{"error"} = "Conversion to PDF failed because OpenOffice could not be started (xauth: $!)"; |
|
1060 |
$main::lxdebug->leave_sub(); |
|
1061 |
return undef; |
|
1062 |
} |
|
1063 |
|
|
1064 |
$main::lxdebug->message(LXDebug::DEBUG2, " about to fork()\n"); |
|
1065 |
|
|
1066 |
my $pid = fork(); |
|
1067 |
if (0 == $pid) { |
|
1068 |
$main::lxdebug->message(LXDebug::DEBUG2, " Child execing\n"); |
|
1069 |
exec($main::xvfb_bin, $display, "-screen", "0", "640x480x8", "-nolisten", "tcp"); |
|
1070 |
} |
|
1071 |
sleep(3); |
|
1072 |
$main::lxdebug->message(LXDebug::DEBUG2, " parent dont sleeping\n"); |
|
1073 |
|
|
1074 |
local *OUT; |
|
1075 |
my $dfname = $self->{"userspath"} . "/xvfb_display"; |
|
1076 |
if (!open(OUT, ">$dfname")) { |
|
1077 |
$self->{"error"} = "Conversion to PDF failed because OpenOffice could not be started ($dfname: $!)"; |
|
1078 |
unlink($xauthority); |
|
1079 |
kill($pid); |
|
1080 |
$main::lxdebug->leave_sub(); |
|
1081 |
return undef; |
|
1082 |
} |
|
1083 |
print(OUT "$pid\n$display\n$xauthority\n"); |
|
1084 |
close(OUT); |
|
1085 |
|
|
1086 |
$main::lxdebug->message(LXDebug::DEBUG2, " parent re-testing\n"); |
|
1087 |
|
|
1088 |
if (!$self->is_xvfb_running()) { |
|
1089 |
$self->{"error"} = "Conversion to PDF failed because OpenOffice could not be started."; |
|
1090 |
unlink($xauthority, $dfname); |
|
1091 |
kill($pid); |
|
1092 |
$main::lxdebug->leave_sub(); |
|
1093 |
return undef; |
|
1094 |
} |
|
1095 |
|
|
1096 |
$main::lxdebug->message(LXDebug::DEBUG2, " spawn OK\n"); |
|
1097 |
|
|
1098 |
$main::lxdebug->leave_sub(); |
|
1099 |
|
|
1100 |
return $display; |
|
1101 |
} |
|
1102 |
|
|
1103 |
sub is_openoffice_running { |
|
1104 |
$main::lxdebug->enter_sub(); |
|
1105 |
|
|
1106 |
system("./scripts/oo-uno-test-conn.py $main::openofficeorg_daemon_port " . |
|
1107 |
"> /dev/null 2> /dev/null"); |
|
1108 |
my $res = $? == 0; |
|
1109 |
$main::lxdebug->message(LXDebug::DEBUG2, " is_openoffice_running(): $?\n"); |
|
1110 |
|
|
1111 |
$main::lxdebug->leave_sub(); |
|
1112 |
|
|
1113 |
return $res; |
|
1114 |
} |
|
1115 |
|
|
1116 |
sub spawn_openoffice { |
|
1117 |
$main::lxdebug->enter_sub(); |
|
1118 |
|
|
1119 |
my ($self) = @_; |
|
1120 |
|
|
1121 |
$main::lxdebug->message(LXDebug::DEBUG2, "spawn_openoffice()\n"); |
|
1122 |
|
|
1123 |
my ($try, $spawned_oo, $res); |
|
1124 |
|
|
1125 |
$res = 0; |
|
1126 |
for ($try = 0; $try < 15; $try++) { |
|
1127 |
if ($self->is_openoffice_running()) { |
|
1128 |
$res = 1; |
|
1129 |
last; |
|
1130 |
} |
|
1131 |
|
|
1132 |
if (!$spawned_oo) { |
|
1133 |
my $pid = fork(); |
|
1134 |
if (0 == $pid) { |
|
1135 |
$main::lxdebug->message(LXDebug::DEBUG2, " Child daemonizing\n"); |
|
1136 |
chdir('/'); |
|
1137 |
open(STDIN, '/dev/null'); |
|
1138 |
open(STDOUT, '>/dev/null'); |
|
1139 |
my $new_pid = fork(); |
|
1140 |
exit if ($new_pid); |
|
1141 |
my $ssres = setsid(); |
|
1142 |
$main::lxdebug->message(LXDebug::DEBUG2, " Child execing\n"); |
|
1143 |
my @cmdline = ($main::openofficeorg_writer_bin, |
|
1144 |
"-minimized", "-norestore", "-nologo", "-nolockcheck", |
|
1145 |
"-headless", |
|
1146 |
"-accept=socket,host=localhost,port=" . |
|
1147 |
$main::openofficeorg_daemon_port . ";urp;"); |
|
1148 |
exec(@cmdline); |
|
1149 |
} |
|
1150 |
|
|
1151 |
$main::lxdebug->message(LXDebug::DEBUG2, " Parent after fork\n"); |
|
1152 |
$spawned_oo = 1; |
|
1153 |
sleep(3); |
|
1154 |
} |
|
1155 |
|
|
1156 |
sleep($try >= 5 ? 2 : 1); |
|
1157 |
} |
|
1158 |
|
|
1159 |
if (!$res) { |
|
1160 |
$self->{"error"} = "Conversion from OpenDocument to PDF failed because " . |
|
1161 |
"OpenOffice could not be started."; |
|
1162 |
} |
|
1163 |
|
|
1164 |
$main::lxdebug->leave_sub(); |
|
1165 |
|
|
1166 |
return $res; |
|
1167 |
} |
|
1168 |
|
|
745 | 1169 |
sub convert_to_pdf { |
1170 |
$main::lxdebug->enter_sub(); |
|
1171 |
|
|
746 | 1172 |
my ($self) = @_; |
747 | 1173 |
|
748 | 1174 |
my $form = $self->{"form"}; |
... | ... | |
759 | 1185 |
$ENV{'HOME'} = getcwd() . "/" . $self->{"userspath"}; |
760 | 1186 |
} |
761 | 1187 |
|
762 |
my @cmdline = ($main::xvfb_run_bin, $main::openofficeorg_writer_bin, |
|
763 |
"-minimized", "-norestore", "-nologo", "-nolockcheck", |
|
764 |
"-headless", |
|
765 |
"file:${filename}.odt", |
|
766 |
"macro://" . (split('/', $filename))[-1] . |
|
767 |
"/Standard.Conversion.ConvertSelfToPDF()"); |
|
1188 |
if (!$self->spawn_xvfb()) { |
|
1189 |
$main::lxdebug->leave_sub(); |
|
1190 |
return 0; |
|
1191 |
} |
|
1192 |
|
|
1193 |
my @cmdline; |
|
1194 |
if (!$main::openofficeorg_daemon) { |
|
1195 |
@cmdline = ($main::openofficeorg_writer_bin, |
|
1196 |
"-minimized", "-norestore", "-nologo", "-nolockcheck", |
|
1197 |
"-headless", |
|
1198 |
"file:${filename}.odt", |
|
1199 |
"macro://" . (split('/', $filename))[-1] . |
|
1200 |
"/Standard.Conversion.ConvertSelfToPDF()"); |
|
1201 |
} else { |
|
1202 |
if (!$self->spawn_openoffice()) { |
|
1203 |
$main::lxdebug->leave_sub(); |
|
1204 |
return 0; |
|
1205 |
} |
|
1206 |
|
|
1207 |
@cmdline = ("./scripts/oo-uno-convert-pdf.py", |
|
1208 |
$main::openofficeorg_daemon_port, |
|
1209 |
"${filename}.odt"); |
|
1210 |
} |
|
768 | 1211 |
|
769 | 1212 |
system(@cmdline); |
770 | 1213 |
|
... | ... | |
793 | 1236 |
my $iconv = $self->{"iconv"}; |
794 | 1237 |
|
795 | 1238 |
my %replace = |
796 |
('order' => ['<', '>', '"', "'", |
|
1239 |
('order' => ['&', '<', '>', '"', "'",
|
|
797 | 1240 |
'\x80', # Euro |
798 |
quotemeta("\n"), quotemeta("\r"), '&'],
|
|
1241 |
quotemeta("\n"), quotemeta("\r")], |
|
799 | 1242 |
'<' => '<', |
800 | 1243 |
'>' => '>', |
801 | 1244 |
'"' => '"', |
802 | 1245 |
"'" => ''', |
803 |
'&' => '"',
|
|
1246 |
'&' => '&',
|
|
804 | 1247 |
'\x80' => chr(0xa4), # Euro |
805 | 1248 |
quotemeta("\n") => '<text:line-break/>', |
806 | 1249 |
quotemeta("\r") => '', |
... | ... | |
812 | 1255 |
# corresponding markup code, e.g. bold or italic. |
813 | 1256 |
my $rnd = $self->{"rnd"}; |
814 | 1257 |
my %markup_replace = ("b" => "BOLD", "i" => "ITALIC", "s" => "STRIKETHROUGH", |
815 |
"u" => "UNDERLINE"); |
|
1258 |
"u" => "UNDERLINE", "sup" => "SUPER", "sub" => "SUB");
|
|
816 | 1259 |
|
817 | 1260 |
foreach my $key (keys(%markup_replace)) { |
818 | 1261 |
my $value = $markup_replace{$key}; |
819 |
$variable =~ s|\<${key}\>|<text:span text:style-name=\"TLXO${rnd}${value}\">|g; |
|
820 |
$variable =~ s|\</${key}\>|</text:span>|g; |
|
1262 |
$variable =~ s|\<${key}\>|<text:span text:style-name=\"TLXO${rnd}${value}\">|gi;
|
|
1263 |
$variable =~ s|\</${key}\>|</text:span>|gi;
|
|
821 | 1264 |
} |
822 | 1265 |
|
823 | 1266 |
return $iconv->convert($variable); |
Auch abrufbar als: Unified diff