summaryrefslogtreecommitdiff
path: root/support/latexmk/example_rcfiles
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-04-17 03:00:41 +0000
committerNorbert Preining <norbert@preining.info>2021-04-17 03:00:41 +0000
commit8ca7af6e140fdaee415715e4a537d8f1a9305198 (patch)
tree7ca5f98e34ec0c9e917f70c3577a3a3b0cff176f /support/latexmk/example_rcfiles
parent487e248ea8406af82362ed0cf749198b48b38183 (diff)
CTAN sync 202104170300
Diffstat (limited to 'support/latexmk/example_rcfiles')
-rw-r--r--support/latexmk/example_rcfiles/chapterbib-latexmkrc21
-rw-r--r--support/latexmk/example_rcfiles/hyperxmp-latexmkrc200
2 files changed, 211 insertions, 10 deletions
diff --git a/support/latexmk/example_rcfiles/chapterbib-latexmkrc b/support/latexmk/example_rcfiles/chapterbib-latexmkrc
index 403cbd6ef5..e5c2cb6250 100644
--- a/support/latexmk/example_rcfiles/chapterbib-latexmkrc
+++ b/support/latexmk/example_rcfiles/chapterbib-latexmkrc
@@ -15,32 +15,33 @@ $bibtex = 'bibtex %O %S';
$bibtex_save = $bibtex;
$bibtex = 'internal bibtex_fix %R %D %S';
-# MUST NOT use bibtex_fudge (i.e., change of directory before running bibtex).
-# That's not needed in post-2019 versions of bibtex, and messes up
-# things with chapterbib. So turn it off:
-$bibtex_fudge = 0;
-
$clean_ext .= " %R-mod.blg %R-mod.aux %R-mod.bbl";
sub bibtex_fix {
my ($root, $dest, $source) = @_;
- local ($base_tex, $path, $ext) = fileparse( $source, '\.[^\.]*' );
+ local ($base_bare, $path, $ext) = fileparse( $source, '\.[^\.]*' );
+ if ($path eq './') { $path = ''; }
+ local $base = $path.$base_bare;
my $ret = 0;
- if ( $base_tex eq $root ) {
+ if ( $base_bare eq $root ) {
print "--- Will run bibtex on modified '$root.aux' file\n";
- my $aux_mod_base = $path.$base_tex."-mod";
+ my $aux_mod_base = $base."-mod";
local $out_fh = new FileHandle "> $aux_mod_base$ext";
if (!$out_fh) { die "Cannot write to '$aux_mod_base$ext'\n"; }
local $level = 0;
fix_aux( $source );
close $out_fh;
- $ret = Run_subst( $bibtex_save, 2, undef, "$aux_mod_base.aux", undef, $aux_mod_base );
+ # Override source, dest, and basenames, since they are to have the path given
+ # in the arguments to this subroutine, instead of the path given in the
+ # corresponding names in the rule. Latexmk may change directory before
+ # calling this subroutine, and adjusts the arguments accordingly:
+ $ret = Run_subst( $bibtex_save, 2, undef, "$aux_mod_base$ext", "$aux_mod_base.bbl", $aux_mod_base );
foreach ( 'bbl', 'blg' ) {
copy "$aux_mod_base.$_", "$path$root.$_";
}
}
else {
- $ret = Run_subst( $bibtex_save );
+ $ret = Run_subst( $bibtex_save, 2, undef, $source, $dest, $base );
}
return $ret;
}
diff --git a/support/latexmk/example_rcfiles/hyperxmp-latexmkrc b/support/latexmk/example_rcfiles/hyperxmp-latexmkrc
new file mode 100644
index 0000000000..e0a80a7f40
--- /dev/null
+++ b/support/latexmk/example_rcfiles/hyperxmp-latexmkrc
@@ -0,0 +1,200 @@
+# Configuration of latexmk so that it works with the hyperxmp package.
+# Hyperxmp puts document xmp metadata in the pdf file, and one of the
+# fields in that metadata is byteCount, which is the size of the pdf file.
+# This configuration ensures that the byteCount is present and correctly
+# equals the pdf file's size.
+#
+# Method of operation:
+# For any command that might produce a pdf file, prepend "internal mycmd3 "
+# to the previously configured command, so that a subroutine mycmd3 is
+# called. It runs the expected command and then does post-processing if
+# the output file is a pdf file.
+
+foreach my $cmd ( "latex", "lualatex", "pdflatex", "xelatex",
+ "dvipdf", "xdvipdfmx", "ps2pdf" ) {
+ ${$cmd} = "internal mycmd ${$cmd}";
+}
+
+#======================================================
+
+sub mycmd {
+ # Run command, and do extra processing of output file, if it is a pdf
+ # file.
+ # This subroutine is run in a rule context, so that $rule is the name of
+ # the rule and $$Pdest is the destination file name.
+
+ # Identification string for messages:
+ local $name = "$My_name.mycmd";
+
+ my $retval = system @_;
+
+ if ( $$Pdest =~ /\.pdf$/ ) {
+ fix_pdf( $$Pdest );
+ }
+ return $retval;
+}
+
+#======================================================
+
+sub fix_pdf {
+ # Change/insert byteCount field with correct file length, while preserving
+ # the file size and the length of the stream containing xmp metadata.
+ # Return 1 on success, else 0.
+
+ local $pdf_name = shift;
+ local $tmp_name = "$pdf_name.new.pdf";
+ local $pdf_size = (stat($pdf_name))[7];
+ warn "Inserting/correcting byteCount field in '$pdf_name' ...\n";
+
+ # Strings surrounding (and identifying) the byteCount field, and other
+ # parts of the xmp packet:
+ local $xmp_start = '<x:xmpmeta xmlns:x="adobe:ns:meta/">';
+ local $decl_bC = '<pdfaProperty:name>byteCount</pdfaProperty:name>';
+ local $pre_bC = '<prism:byteCount>';
+ local $post_bC = '</prism:byteCount>';
+ local $pC = '<prism:pageCount>';
+ local $rd_end = '</rdf:Description>';
+ local $xmp_end = '</x:xmpmeta>';
+
+ local *PDF;
+ local *TMP;
+
+ if (! open PDF, "<", $pdf_name ) {
+ warn " Cannot read '$pdf_name'\n";
+ return 0;
+ }
+ if ( ! open TMP, ">", $tmp_name ) {
+ warn " Cannot write temporary file '$tmp_name'\n";
+ close PDF;
+ return 0;
+ }
+ local $status = 0; # 0 = no XMP packet, 1 = success, >= errors
+ while ( <PDF> ) {
+ # Only examine first XMP packet:
+ if ( ($status == 0) && /^\s*\Q$xmp_start\E/ ) {
+ local @xmp = $_;
+ local $len_padding = 0;
+ local $xmp_after_line = '';
+ &xmp_get_mod;
+ print TMP @xmp;
+ # Insert correct padding to leave file size unchanged:
+ while ( $len_padding > 0 ) {
+ my $len_line = 64;
+ if ( $len_line > $len_padding ) { $len_line = $len_padding; }
+ $len_padding -= $len_line;
+ print TMP (' ' x ($len_line - 1) ), "\n";
+ }
+ print TMP $xmp_after_line;
+ $xmp_after_line = '';
+ }
+ else {
+ print TMP "$_";
+ }
+ }
+ close PDF;
+ close TMP;
+
+ if ($status == 0) {
+ warn " Could not insert/modify byteCount, since no XMP packet was found.\n";
+ warn " So '$pdf_name' is unchanged,\n",
+ " and I will delete temporary file '$tmp_name'.\n";
+ unlink $tmp_name;
+ } elsif ($status == 1) {
+ rename $tmp_name, $pdf_name
+ or die " Cannot move temporary file '$tmp_name' to '$pdf_name'.\n",
+ " Error is '$!'\n";
+ } else {
+ warn " Could not insert correct byteCount. See above for reason.\n";
+ warn " So '$pdf_name' is unchanged,\n",
+ " and I will delete temporary file '$tmp_name'.\n";
+ unlink $tmp_name;
+ }
+ return ($status == 1);
+}
+
+#======================================================
+
+sub xmp_get_mod {
+ # Get xmp packet, given that @xmp contains its first line.
+ # Get amount of trailing padding, and line after that.
+ # If possible, insert a byteCount field:
+ # Either replace existing specification, if it exists,
+ # or insert one in expected place for hyperxmp, if the XMP packet
+ # matches what hyperxmp would produce.
+ # Return xmp packet in @xmp, amount of padding needed in $len_padding,
+ # line after that in $xmp_after_line, and error code in $error.
+ # Set $status appropriately: 1 for success; >=1 for failure.
+
+ $len_padding = 0;
+ $xmp_after_line = '';
+
+ my $bC_index = -1;
+ my $xmp_end_found = 0;
+ my $decl_bC_found = 0;
+ while ( <PDF> ) {
+ push @xmp, $_;
+ if ( /^\s*\Q$xmp_end\E/ ) {
+ $xmp_end_found = 1;
+ # Get amount of padding;
+ while (<PDF>) {
+ if ( /^\s*$/ ) {
+ $len_padding += length($_);
+ } else {
+ $xmp_after_line = $_;
+ last;
+ }
+ }
+ last;
+ }
+ elsif ( $bC_index >= 0 ){
+ next;
+ }
+ # Rest of conditions only apply if no place yet found for byteCount
+ # specification.
+ elsif ( /^(\s*)\Q$pre_bC\E.*?\Q$post_bC\E\s*$/ ) {
+ $bC_index = $#xmp;
+ }
+ elsif ( /^\s*\Q$decl_bC\E/ ) {
+ $decl_bC_found = 1;
+ }
+ elsif ( /^(\s*)\Q$rd_end\E/ ){
+ # End of rdf:Description block.
+ # So having previous declaration of byteCount is irrelevant.
+ $decl_bC_found = 0;
+ }
+ elsif ( $decl_bC_found && /^(\s*)\Q$pC\E/ ){
+ $bC_index = $#xmp;
+ pop @xmp;
+ push @xmp, '', $_;
+ }
+
+ } # End reading of XMP
+
+ if ($bC_index < 0) {
+ if ( ! $xmp_end_found ) {
+ warn " End of XMP packet not found.\n";
+ $status = 2;
+ }
+ elsif ( ! $decl_bC_found ) {
+ warn " XMP packet not in appropriate hyperxmp-compatible format.\n";
+ $status = 3;
+ }
+ return;
+ }
+ my $new_line = ' ' . $pre_bC . $pdf_size . $post_bC . "\n";
+ my $old_line = $xmp[$bC_index];
+ my $delta_len = length($new_line) - length($old_line);
+ if ($delta_len > $len_padding) {
+ warn " Cannot get padding correct for '$pdf_name'.\n",
+ " Length change of bC line = $delta_len; ",
+ " Padding bytes available = $len_padding.\n";
+ $status = 4;
+ return;
+ } else {
+ $len_padding -= $delta_len;
+ $xmp[$bC_index] = $new_line;
+ $status = 1;
+ }
+}
+
+#======================================================