Merge branch 'b-3.6.1' of ../kivitendo-erp_20220811
[kivitendo-erp.git] / SL / Template / LaTeX.pm
index 8b4c4e8..293db2e 100644 (file)
@@ -83,6 +83,8 @@ sub _format_html {
   $content =~ s{ (?:\ |\s)+ }{ }gx;
   $content =~ s{ (?:\ |\s)+$ }{}gx;
   $content =~ s{ (?: <br/?> )+$ }{}gx;
+  $content =~ s{ <ul>\s*</ul> | <ol>\s*</ol> }{}igx;
+  $content =~ s{ (?: <p>\s*</p>\s* )+ \Z }{}imgx;
 
   my @parts = grep { $_ } map {
     if (substr($_, 0, 1) eq '<') {
@@ -394,12 +396,16 @@ sub _embed_file_directive {
   my ($self, $file) = @_;
 
   # { source      => $xmlfile,
-  #   name        => 'ZUGFeRD-invoice.xml',
-  #   description => $::locale->text('ZUGFeRD invoice'), }
+  #   name        => 'factur-x.xml',
+  #   description => $::locale->text('Factur-X/ZUGFeRD invoice'), }
 
   my $file_name  =  blessed($file->{source}) && $file->{source}->can('filename') ? $file->{source}->filename : "" . $file->{source}->filename;
   my $embed_name =  $file->{name} // $file_name;
   $embed_name    =~ s{.*/}{};
+
+  my $embed_name_ascii = $::locale->quote_special_chars('filenames', $embed_name);
+  $embed_name_ascii    =~ s{[^a-z0-9!@#$%^&*(){}[\],.+'"=_-]+}{}gi;
+
   my @options;
 
   my $add_opt = sub {
@@ -408,10 +414,11 @@ sub _embed_file_directive {
     push @options, sprintf('%s={%s}', $name, $value); # TODO: escaping
   };
 
- $add_opt->('ucfilespec',     $embed_name);
- $add_opt->('desc',           $file->{description});
- $add_opt->('afrelationship', $file->{relationship});
- $add_opt->('mimetype',       $file->{mime_type});
+  $add_opt->('filespec',       $embed_name_ascii);
+  $add_opt->('ucfilespec',     $embed_name);
+  $add_opt->('desc',           $file->{description});
+  $add_opt->('afrelationship', $file->{relationship});
+  $add_opt->('mimetype',       $file->{mime_type});
 
   return sprintf('\embedfile[%s]{%s}', join(',', @options), $file_name);
 }
@@ -420,7 +427,7 @@ sub _force_mandatory_packages {
   my ($self, @lines) = @_;
   my @new_lines;
 
-  my (%used_packages, $at_beginning_of_document);
+  my %used_packages;
   my @required_packages = qw(textcomp ulem);
   push @required_packages, 'embedfile' if $self->{pdf_a};
 
@@ -428,38 +435,30 @@ sub _force_mandatory_packages {
     if ($line =~ m/\\usepackage[^\{]*{(.*?)}/) {
       $used_packages{$1} = 1;
 
-    } elsif (($line =~ m/\\documentclass/) && $self->{pdf_a}) {
-      my $version = $self->{pdf_a}->{version}   // '3a';
-      my $meta    = $self->{pdf_a}->{meta_data} // {};
-
-      push @new_lines, (
-        "\\RequirePackage{filecontents}\n",
-        "\\begin{filecontents*}{\\jobname.xmpdata}\n",
-        ($meta->{title}    ? sprintf("\\Title{%s}\n",    $meta->{title})    : ""),
-        ($meta->{author}   ? sprintf("\\Author{%s}\n",   $meta->{author})   : ""),
-        ($meta->{language} ? sprintf("\\Language{%s}\n", $meta->{language}) : ""),
-        "\\end{filecontents*}\n",
-        $line,
-        "\\usepackage[a-${version},mathxmp]{pdfx}[2018/12/22]\n",
-        "\\usepackage[genericmode]{tagpdf}\n",
-        "\\tagpdfsetup{activate-all}\n",
-        "\\hypersetup{pdfstartview=}\n",
-      );
-
-      next;
-
     } elsif ($line =~ m/\\begin\{document\}/) {
-      $at_beginning_of_document = 1;
+      if ($self->{pdf_a} && $self->{pdf_a}->{xmp}) {
+        my $version       = $self->{pdf_a}->{version}   // '3a';
+        my $xmp_file_name = $self->{userspath} . "/pdfa.xmp";
+        my $out           = IO::File->new($xmp_file_name, ">:encoding(utf-8)") || croak "Error creating ${xmp_file_name}: $!";
+        $out->print(Encode::encode('utf-8', $self->{pdf_a}->{xmp}));
+        $out->close;
+
+        push @new_lines, (
+          "\\usepackage[a-${version},mathxmp]{pdfx}[2018/12/22]\n",
+          "\\usepackage[genericmode]{tagpdf}\n",
+          "\\tagpdfsetup{activate-all}\n",
+          "\\hypersetup{pdfstartview=}\n",
+        );
+      }
+
       push @new_lines, map { "\\usepackage{$_}\n" } grep { !$used_packages{$_} } @required_packages;
+      push @new_lines, $line;
+      push @new_lines, map { $self->_embed_file_directive($_) } @{ $self->{pdf_attachments} // [] };
+
+      next;
     }
 
     push @new_lines, $line;
-
-    if ($at_beginning_of_document) {
-      $at_beginning_of_document = 0;
-
-      push @new_lines, map { $self->_embed_file_directive($_) } @{ $self->{pdf_attachments} // [] };
-    }
   }
 
   return @new_lines;