From d21f0a146ce9ce0249c46751cdb849738768e38c Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 22 Nov 2020 22:19:22 +0000 Subject: hyperxmp (22nov20) git-svn-id: svn://tug.org/texlive/trunk@56984 c570f23f-e606-0410-a88d-b1316a301751 --- .../source/texk/texlive/linked_scripts/Makefile.am | 1 + .../source/texk/texlive/linked_scripts/Makefile.in | 189 +++++++++--------- .../hyperxmp/hyperxmp-add-bytecount.pl | 219 +++++++++++++++++++++ .../source/texk/texlive/linked_scripts/scripts.lst | 95 +-------- Master/bin/aarch64-linux/hyperxmp-add-bytecount | 1 + Master/bin/amd64-freebsd/hyperxmp-add-bytecount | 1 + Master/bin/amd64-netbsd/hyperxmp-add-bytecount | 1 + Master/bin/armhf-linux/hyperxmp-add-bytecount | 1 + Master/bin/i386-cygwin/hyperxmp-add-bytecount | 1 + Master/bin/i386-freebsd/hyperxmp-add-bytecount | 1 + Master/bin/i386-linux/hyperxmp-add-bytecount | 1 + Master/bin/i386-netbsd/hyperxmp-add-bytecount | 1 + Master/bin/i386-solaris/hyperxmp-add-bytecount | 1 + Master/bin/win32/hyperxmp-add-bytecount.exe | Bin 0 -> 1536 bytes Master/bin/x86_64-cygwin/hyperxmp-add-bytecount | 1 + Master/bin/x86_64-darwin/hyperxmp-add-bytecount | 1 + .../bin/x86_64-darwinlegacy/hyperxmp-add-bytecount | 1 + Master/bin/x86_64-linux/hyperxmp-add-bytecount | 1 + Master/bin/x86_64-linuxmusl/hyperxmp-add-bytecount | 1 + Master/bin/x86_64-solaris/hyperxmp-add-bytecount | 1 + Master/texmf-dist/doc/latex/hyperxmp/README | 10 +- Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf | Bin 1549965 -> 1555235 bytes .../doc/man/man1/hyperxmp-add-bytecount.1 | 36 ++++ .../scripts/hyperxmp/hyperxmp-add-bytecount.pl | 219 +++++++++++++++++++++ .../texmf-dist/source/latex/hyperxmp/hyperxmp.dtx | 216 +++++++++++++++----- Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty | 32 ++- Master/tlpkg/libexec/ctan2tds | 1 + Master/tlpkg/tlpsrc/hyperxmp.tlpsrc | 2 + 28 files changed, 788 insertions(+), 247 deletions(-) create mode 100755 Build/source/texk/texlive/linked_scripts/hyperxmp/hyperxmp-add-bytecount.pl create mode 120000 Master/bin/aarch64-linux/hyperxmp-add-bytecount create mode 120000 Master/bin/amd64-freebsd/hyperxmp-add-bytecount create mode 120000 Master/bin/amd64-netbsd/hyperxmp-add-bytecount create mode 120000 Master/bin/armhf-linux/hyperxmp-add-bytecount create mode 120000 Master/bin/i386-cygwin/hyperxmp-add-bytecount create mode 120000 Master/bin/i386-freebsd/hyperxmp-add-bytecount create mode 120000 Master/bin/i386-linux/hyperxmp-add-bytecount create mode 120000 Master/bin/i386-netbsd/hyperxmp-add-bytecount create mode 120000 Master/bin/i386-solaris/hyperxmp-add-bytecount create mode 100755 Master/bin/win32/hyperxmp-add-bytecount.exe create mode 120000 Master/bin/x86_64-cygwin/hyperxmp-add-bytecount create mode 120000 Master/bin/x86_64-darwin/hyperxmp-add-bytecount create mode 120000 Master/bin/x86_64-darwinlegacy/hyperxmp-add-bytecount create mode 120000 Master/bin/x86_64-linux/hyperxmp-add-bytecount create mode 120000 Master/bin/x86_64-linuxmusl/hyperxmp-add-bytecount create mode 120000 Master/bin/x86_64-solaris/hyperxmp-add-bytecount create mode 100644 Master/texmf-dist/doc/man/man1/hyperxmp-add-bytecount.1 create mode 100755 Master/texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.am b/Build/source/texk/texlive/linked_scripts/Makefile.am index 195c309d3f8..685291e13bb 100644 --- a/Build/source/texk/texlive/linked_scripts/Makefile.am +++ b/Build/source/texk/texlive/linked_scripts/Makefile.am @@ -142,6 +142,7 @@ texmf_other_scripts = \ getmap/getmapdl.lua \ glossaries/makeglossaries \ glossaries/makeglossaries-lite.lua \ + hyperxmp/hyperxmp-add-bytecount.pl jfmutil/jfmutil.pl \ ketcindy/ketcindy.pl \ kotex-utils/jamo-normalize.pl \ diff --git a/Build/source/texk/texlive/linked_scripts/Makefile.in b/Build/source/texk/texlive/linked_scripts/Makefile.in index ee6a86741a9..bc21ac22d23 100644 --- a/Build/source/texk/texlive/linked_scripts/Makefile.in +++ b/Build/source/texk/texlive/linked_scripts/Makefile.in @@ -355,100 +355,7 @@ texmf_other_scripts = \ getmap/getmapdl.lua \ glossaries/makeglossaries \ glossaries/makeglossaries-lite.lua \ - jfmutil/jfmutil.pl \ - ketcindy/ketcindy.pl \ - kotex-utils/jamo-normalize.pl \ - kotex-utils/komkindex.pl \ - kotex-utils/ttf2kotexfont.pl \ - l3build/l3build.lua \ - latex-git-log/latex-git-log \ - latex-papersize/latex-papersize.py \ - latex2man/latex2man \ - latex2nemeth/latex2nemeth \ - latexdiff/latexdiff-vc.pl \ - latexdiff/latexdiff.pl \ - latexdiff/latexrevise.pl \ - latexindent/latexindent.pl \ - latexmk/latexmk.pl \ - latexpand/latexpand \ - light-latex-make/llmk.lua \ - lilyglyphs/lily-glyph-commands.py \ - lilyglyphs/lily-image-commands.py \ - lilyglyphs/lily-rebuild-pdfs.py \ - ltximg/ltximg.pl \ - luaotfload/luaotfload-tool.lua \ - lwarp/lwarpmk.lua \ - m-tx/m-tx.lua \ - makedtx/makedtx.pl \ - make4ht/make4ht \ - match_parens/match_parens \ - mathspic/mathspic.pl \ - mf2pt1/mf2pt1.pl \ - mkgrkindex/mkgrkindex \ - mkjobtexmf/mkjobtexmf.pl \ - mkpic/mkpic \ - multibibliography/multibibliography.pl \ - musixtex/musixflx.lua \ - musixtex/musixtex.lua \ - pax/pdfannotextractor.pl \ - pdfcrop/pdfcrop.pl \ - pdflatexpicscale/pdflatexpicscale.pl \ - pedigree-perl/pedigree.pl \ - perltex/perltex.pl \ - petri-nets/pn2pdf \ - pfarrei/a5toa4.tlu \ - pfarrei/pfarrei.tlu \ - pkfix-helper/pkfix-helper \ - pkfix/pkfix.pl \ - pmxchords/pmxchords.lua \ - pst2pdf/pst2pdf.pl \ - ptex-fontmaps/kanji-config-updmap-sys.sh \ - ptex-fontmaps/kanji-config-updmap-user.sh \ - ptex-fontmaps/kanji-config-updmap.pl \ - ptex-fontmaps/kanji-fontmap-creator.pl \ - ptex2pdf/ptex2pdf.lua \ - purifyeps/purifyeps \ - pygmentex/pygmentex.py \ - pythontex/depythontex.py \ - pythontex/pythontex.py \ - rubik/rubikrotation.pl \ - spix/spix.py \ - splitindex/splitindex.pl \ - srcredact/srcredact.pl \ - sty2dtx/sty2dtx.pl \ - svn-multi/svn-multi.pl \ - tex4ebook/tex4ebook \ - texcount/texcount.pl \ - texdef/texdef.pl \ - texdiff/texdiff \ - texdirflatten/texdirflatten \ - texdoc/texdoc.tlu \ - texfot/texfot.pl \ - texlive/fmtutil-sys.sh \ - texlive/fmtutil-user.sh \ - texlive/fmtutil.pl \ - texlive/mktexlsr \ - texlive/mktexmf \ - texlive/mktexpk \ - texlive/mktextfm \ - texlive/rungs.tlu \ - texlive/tlmgr.pl \ - texlive/updmap-sys.sh \ - texlive/updmap-user.sh \ - texlive/updmap.pl \ - texlive-extra/e2pall.pl \ - texliveonfly/texliveonfly.py \ - texloganalyser/texloganalyser \ - texplate/texplate.sh \ - thumbpdf/thumbpdf.pl \ - tlcockpit/tlcockpit.sh \ - tlshell/tlshell.tcl \ - ulqda/ulqda.pl \ - urlbst/urlbst \ - vpe/vpe.pl \ - webquiz/webquiz.py \ - xindex/xindex.lua \ - yplan/yplan + hyperxmp/hyperxmp-add-bytecount.pl texmf_context_scripts = \ context/stubs/unix/context \ @@ -732,6 +639,100 @@ scripts-list: Makefile installdirs-local: $(MKDIR_P) $(DESTDIR)$(bindir) + jfmutil/jfmutil.pl \ + ketcindy/ketcindy.pl \ + kotex-utils/jamo-normalize.pl \ + kotex-utils/komkindex.pl \ + kotex-utils/ttf2kotexfont.pl \ + l3build/l3build.lua \ + latex-git-log/latex-git-log \ + latex-papersize/latex-papersize.py \ + latex2man/latex2man \ + latex2nemeth/latex2nemeth \ + latexdiff/latexdiff-vc.pl \ + latexdiff/latexdiff.pl \ + latexdiff/latexrevise.pl \ + latexindent/latexindent.pl \ + latexmk/latexmk.pl \ + latexpand/latexpand \ + light-latex-make/llmk.lua \ + lilyglyphs/lily-glyph-commands.py \ + lilyglyphs/lily-image-commands.py \ + lilyglyphs/lily-rebuild-pdfs.py \ + ltximg/ltximg.pl \ + luaotfload/luaotfload-tool.lua \ + lwarp/lwarpmk.lua \ + m-tx/m-tx.lua \ + makedtx/makedtx.pl \ + make4ht/make4ht \ + match_parens/match_parens \ + mathspic/mathspic.pl \ + mf2pt1/mf2pt1.pl \ + mkgrkindex/mkgrkindex \ + mkjobtexmf/mkjobtexmf.pl \ + mkpic/mkpic \ + multibibliography/multibibliography.pl \ + musixtex/musixflx.lua \ + musixtex/musixtex.lua \ + pax/pdfannotextractor.pl \ + pdfcrop/pdfcrop.pl \ + pdflatexpicscale/pdflatexpicscale.pl \ + pedigree-perl/pedigree.pl \ + perltex/perltex.pl \ + petri-nets/pn2pdf \ + pfarrei/a5toa4.tlu \ + pfarrei/pfarrei.tlu \ + pkfix-helper/pkfix-helper \ + pkfix/pkfix.pl \ + pmxchords/pmxchords.lua \ + pst2pdf/pst2pdf.pl \ + ptex-fontmaps/kanji-config-updmap-sys.sh \ + ptex-fontmaps/kanji-config-updmap-user.sh \ + ptex-fontmaps/kanji-config-updmap.pl \ + ptex-fontmaps/kanji-fontmap-creator.pl \ + ptex2pdf/ptex2pdf.lua \ + purifyeps/purifyeps \ + pygmentex/pygmentex.py \ + pythontex/depythontex.py \ + pythontex/pythontex.py \ + rubik/rubikrotation.pl \ + spix/spix.py \ + splitindex/splitindex.pl \ + srcredact/srcredact.pl \ + sty2dtx/sty2dtx.pl \ + svn-multi/svn-multi.pl \ + tex4ebook/tex4ebook \ + texcount/texcount.pl \ + texdef/texdef.pl \ + texdiff/texdiff \ + texdirflatten/texdirflatten \ + texdoc/texdoc.tlu \ + texfot/texfot.pl \ + texlive/fmtutil-sys.sh \ + texlive/fmtutil-user.sh \ + texlive/fmtutil.pl \ + texlive/mktexlsr \ + texlive/mktexmf \ + texlive/mktexpk \ + texlive/mktextfm \ + texlive/rungs.tlu \ + texlive/tlmgr.pl \ + texlive/updmap-sys.sh \ + texlive/updmap-user.sh \ + texlive/updmap.pl \ + texlive-extra/e2pall.pl \ + texliveonfly/texliveonfly.py \ + texloganalyser/texloganalyser \ + texplate/texplate.sh \ + thumbpdf/thumbpdf.pl \ + tlcockpit/tlcockpit.sh \ + tlshell/tlshell.tcl \ + ulqda/ulqda.pl \ + urlbst/urlbst \ + vpe/vpe.pl \ + webquiz/webquiz.py \ + xindex/xindex.lua \ + yplan/yplan install-data-hook: installdirs-local @WIN32_TRUE@ @for s in $(texmf_other_scripts); do \ @WIN32_TRUE@ t=`basename $$s | sed 's,\.[^/]*$$,,' | tr '[A-Z]' '[a-z]'`; \ diff --git a/Build/source/texk/texlive/linked_scripts/hyperxmp/hyperxmp-add-bytecount.pl b/Build/source/texk/texlive/linked_scripts/hyperxmp/hyperxmp-add-bytecount.pl new file mode 100755 index 00000000000..8d965a63f5f --- /dev/null +++ b/Build/source/texk/texlive/linked_scripts/hyperxmp/hyperxmp-add-bytecount.pl @@ -0,0 +1,219 @@ +#!/usr/bin/env perl +use warnings; + +############################################################# +############################################################# + +######################################################################## +# hyperxmp-add-bytecount # +# Adds/updates byteCount specification in XMP packet in pdf file(s) # +# made by hyperxmp, with byteCount = file size. # +# Copyright (C) 2020 John Collins # +# and Scott Pakin, # +# # +# This program may be distributed and/or modified under the conditions # +# of the LaTeX Project Public License, either version 1.3c of this # +# license or (at your option) any later version. # +# # +# The latest version of this license is in: # +# # +# http://www.latex-project.org/lppl.txt # +# # +# and version 1.3c or later is part of all distributions of LaTeX # +# version 2008/05/04 or later. # +######################################################################## + +$name = 'hyperref-add-bytecount'; +$version = '1.1-2020-11-20'; +$maintainer + = 'John Collins, jcc8@psu.edu; Scott Pakin, scott+hyxmp@pakin.org'; + +my $exit_code = 0; + +if ( (! @ARGV) || ($ARGV[0] =~ /^(-|--)(h|help)$/) ) { + print "$name $version.\n", + "Usage: $name [options] pdf_filename(s)\n", + " Adds/updates byteCount specification in XMP packet in pdf file(s) from\n", + " hyperxmp, with byteCount = file size.\n", + " No change if there's no XMP packet of the form produced by hyperxmp.\n", + "Options:\n", + " -help or -h Output usage information.\n", + " -version or -v Output version information.\n", + "Bug reports to:\n $maintainer.\n"; + exit; +} elsif ( $ARGV[0] =~ /^(-|--)(v|version)$/ ) { + print "$name $version.\n", + "Bug reports to:\n $maintainer.\n"; + exit; +} + +foreach (@ARGV) { + if ( ! fix_pdf($_) ) { $exit_code = 1; } +} + +exit $exit_code; + +#====================================================== + +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 = ''; + local $decl_bC = 'byteCount'; + local $pre_bC = ''; + local $post_bC = ''; + local $pC = ''; + local $rd_end = ''; + local $xmp_end = ''; + + 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 ( ) { + # 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 ( ) { + push @xmp, $_; + if ( /^\s*\Q$xmp_end\E/ ) { + $xmp_end_found = 1; + # Get amount of padding; + while () { + 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; + } +} + +#====================================================== diff --git a/Build/source/texk/texlive/linked_scripts/scripts.lst b/Build/source/texk/texlive/linked_scripts/scripts.lst index 9d9308af690..f0ea334e3db 100644 --- a/Build/source/texk/texlive/linked_scripts/scripts.lst +++ b/Build/source/texk/texlive/linked_scripts/scripts.lst @@ -84,100 +84,7 @@ fragmaster/fragmaster.pl getmap/getmapdl.lua glossaries/makeglossaries glossaries/makeglossaries-lite.lua -jfmutil/jfmutil.pl -ketcindy/ketcindy.pl -kotex-utils/jamo-normalize.pl -kotex-utils/komkindex.pl -kotex-utils/ttf2kotexfont.pl -l3build/l3build.lua -latex-git-log/latex-git-log -latex-papersize/latex-papersize.py -latex2man/latex2man -latex2nemeth/latex2nemeth -latexdiff/latexdiff-vc.pl -latexdiff/latexdiff.pl -latexdiff/latexrevise.pl -latexindent/latexindent.pl -latexmk/latexmk.pl -latexpand/latexpand -light-latex-make/llmk.lua -lilyglyphs/lily-glyph-commands.py -lilyglyphs/lily-image-commands.py -lilyglyphs/lily-rebuild-pdfs.py -ltximg/ltximg.pl -luaotfload/luaotfload-tool.lua -lwarp/lwarpmk.lua -m-tx/m-tx.lua -makedtx/makedtx.pl -make4ht/make4ht -match_parens/match_parens -mathspic/mathspic.pl -mf2pt1/mf2pt1.pl -mkgrkindex/mkgrkindex -mkjobtexmf/mkjobtexmf.pl -mkpic/mkpic -multibibliography/multibibliography.pl -musixtex/musixflx.lua -musixtex/musixtex.lua -pax/pdfannotextractor.pl -pdfcrop/pdfcrop.pl -pdflatexpicscale/pdflatexpicscale.pl -pedigree-perl/pedigree.pl -perltex/perltex.pl -petri-nets/pn2pdf -pfarrei/a5toa4.tlu -pfarrei/pfarrei.tlu -pkfix-helper/pkfix-helper -pkfix/pkfix.pl -pmxchords/pmxchords.lua -pst2pdf/pst2pdf.pl -ptex-fontmaps/kanji-config-updmap-sys.sh -ptex-fontmaps/kanji-config-updmap-user.sh -ptex-fontmaps/kanji-config-updmap.pl -ptex-fontmaps/kanji-fontmap-creator.pl -ptex2pdf/ptex2pdf.lua -purifyeps/purifyeps -pygmentex/pygmentex.py -pythontex/depythontex.py -pythontex/pythontex.py -rubik/rubikrotation.pl -spix/spix.py -splitindex/splitindex.pl -srcredact/srcredact.pl -sty2dtx/sty2dtx.pl -svn-multi/svn-multi.pl -tex4ebook/tex4ebook -texcount/texcount.pl -texdef/texdef.pl -texdiff/texdiff -texdirflatten/texdirflatten -texdoc/texdoc.tlu -texfot/texfot.pl -texlive/fmtutil-sys.sh -texlive/fmtutil-user.sh -texlive/fmtutil.pl -texlive/mktexlsr -texlive/mktexmf -texlive/mktexpk -texlive/mktextfm -texlive/rungs.tlu -texlive/tlmgr.pl -texlive/updmap-sys.sh -texlive/updmap-user.sh -texlive/updmap.pl -texlive-extra/e2pall.pl -texliveonfly/texliveonfly.py -texloganalyser/texloganalyser -texplate/texplate.sh -thumbpdf/thumbpdf.pl -tlcockpit/tlcockpit.sh -tlshell/tlshell.tcl -ulqda/ulqda.pl -urlbst/urlbst -vpe/vpe.pl -webquiz/webquiz.py -xindex/xindex.lua -yplan/yplan +hyperxmp/hyperxmp-add-bytecount.pl context/stubs/unix/context context/stubs/unix/contextjit context/stubs/unix/luatools diff --git a/Master/bin/aarch64-linux/hyperxmp-add-bytecount b/Master/bin/aarch64-linux/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/aarch64-linux/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/amd64-freebsd/hyperxmp-add-bytecount b/Master/bin/amd64-freebsd/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/amd64-freebsd/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/amd64-netbsd/hyperxmp-add-bytecount b/Master/bin/amd64-netbsd/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/amd64-netbsd/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/armhf-linux/hyperxmp-add-bytecount b/Master/bin/armhf-linux/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/armhf-linux/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/i386-cygwin/hyperxmp-add-bytecount b/Master/bin/i386-cygwin/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/i386-cygwin/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/i386-freebsd/hyperxmp-add-bytecount b/Master/bin/i386-freebsd/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/i386-freebsd/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/i386-linux/hyperxmp-add-bytecount b/Master/bin/i386-linux/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/i386-linux/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/i386-netbsd/hyperxmp-add-bytecount b/Master/bin/i386-netbsd/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/i386-netbsd/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/i386-solaris/hyperxmp-add-bytecount b/Master/bin/i386-solaris/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/i386-solaris/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/win32/hyperxmp-add-bytecount.exe b/Master/bin/win32/hyperxmp-add-bytecount.exe new file mode 100755 index 00000000000..5777d90a17a Binary files /dev/null and b/Master/bin/win32/hyperxmp-add-bytecount.exe differ diff --git a/Master/bin/x86_64-cygwin/hyperxmp-add-bytecount b/Master/bin/x86_64-cygwin/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/x86_64-cygwin/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/x86_64-darwin/hyperxmp-add-bytecount b/Master/bin/x86_64-darwin/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/x86_64-darwin/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/x86_64-darwinlegacy/hyperxmp-add-bytecount b/Master/bin/x86_64-darwinlegacy/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/x86_64-darwinlegacy/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/x86_64-linux/hyperxmp-add-bytecount b/Master/bin/x86_64-linux/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/x86_64-linux/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/x86_64-linuxmusl/hyperxmp-add-bytecount b/Master/bin/x86_64-linuxmusl/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/x86_64-linuxmusl/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/bin/x86_64-solaris/hyperxmp-add-bytecount b/Master/bin/x86_64-solaris/hyperxmp-add-bytecount new file mode 120000 index 00000000000..74e1150d5b3 --- /dev/null +++ b/Master/bin/x86_64-solaris/hyperxmp-add-bytecount @@ -0,0 +1 @@ +../../texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl \ No newline at end of file diff --git a/Master/texmf-dist/doc/latex/hyperxmp/README b/Master/texmf-dist/doc/latex/hyperxmp/README index 4fb504485d0..93a2733315d 100644 --- a/Master/texmf-dist/doc/latex/hyperxmp/README +++ b/Master/texmf-dist/doc/latex/hyperxmp/README @@ -36,13 +36,13 @@ installing packages. Building hyperxmp.pdf is a little more involved: - pdflatex hyperxmp.dtx - pdflatex hyperxmp.dtx + lualatex hyperxmp.dtx + lualatex hyperxmp.dtx makeindex -s gind-hyxmp.ist hyperxmp.idx -o hyperxmp.ind makeindex -s gglo-hyxmp.ist hyperxmp.glo -o hyperxmp.gls - pdflatex hyperxmp.dtx - pdflatex hyperxmp.dtx - + lualatex hyperxmp.dtx + lualatex hyperxmp.dtx + perl add_byteCount.pl hyperxmp.pdf Copyright and license ===================== diff --git a/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf b/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf index d62a5dc5553..f11adaee15a 100644 Binary files a/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf and b/Master/texmf-dist/doc/latex/hyperxmp/hyperxmp.pdf differ diff --git a/Master/texmf-dist/doc/man/man1/hyperxmp-add-bytecount.1 b/Master/texmf-dist/doc/man/man1/hyperxmp-add-bytecount.1 new file mode 100644 index 00000000000..e1aa4c8b908 --- /dev/null +++ b/Master/texmf-dist/doc/man/man1/hyperxmp-add-bytecount.1 @@ -0,0 +1,36 @@ +.TH HYPERXMP-ADD-BYTECOUNT 1 "22 November 2020" "v1.1" +.SH NAME +hyperxmp-add-bytecount \- adds/updates byteCount specification in XMP +packet in PDF file. +.SH SYNOPSIS +.B hyperxmp-add-bytecount +.RI [ options ] +.IR filename.pdf ... +.SH DESCRIPTION +\fBhyperxmp-add-bytecount\fP adds/updates the \fCbyteCount\fP +specification in the XMP packet in a PDF file(s), with \fCbyteCount\fP += file size. The XMP packet needs to be of, or compatible with, the +format produced from a document that uses +.UR https://ctan.org/pkg/hyperxmp +the +.ie t L\h'-0.36'\v'-0.15'\s-2A\s+2\v'0.15'\h'-0.15'T\h'-0.1667'\v'0.2'E\v'-0.2'\h'-0.125'X +.el LaTeX +hyperxmp package +.UE . +.PP +If no XMP packet of a compatible form is found in the PDF file, no +change is made to the file. +.SH OPTIONS +.IP \fB-help\fP +Write usage summary and exit. +.IP \fB-version\fP +Output version information and exit. +.SH BUGS +Email bug reports to +.MT jcc8@psu.edu +John Collins +.ME +and/or +.MT scott+hyxmp@pakin.org +Scott Pakin +.ME . diff --git a/Master/texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl b/Master/texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl new file mode 100755 index 00000000000..8d965a63f5f --- /dev/null +++ b/Master/texmf-dist/scripts/hyperxmp/hyperxmp-add-bytecount.pl @@ -0,0 +1,219 @@ +#!/usr/bin/env perl +use warnings; + +############################################################# +############################################################# + +######################################################################## +# hyperxmp-add-bytecount # +# Adds/updates byteCount specification in XMP packet in pdf file(s) # +# made by hyperxmp, with byteCount = file size. # +# Copyright (C) 2020 John Collins # +# and Scott Pakin, # +# # +# This program may be distributed and/or modified under the conditions # +# of the LaTeX Project Public License, either version 1.3c of this # +# license or (at your option) any later version. # +# # +# The latest version of this license is in: # +# # +# http://www.latex-project.org/lppl.txt # +# # +# and version 1.3c or later is part of all distributions of LaTeX # +# version 2008/05/04 or later. # +######################################################################## + +$name = 'hyperref-add-bytecount'; +$version = '1.1-2020-11-20'; +$maintainer + = 'John Collins, jcc8@psu.edu; Scott Pakin, scott+hyxmp@pakin.org'; + +my $exit_code = 0; + +if ( (! @ARGV) || ($ARGV[0] =~ /^(-|--)(h|help)$/) ) { + print "$name $version.\n", + "Usage: $name [options] pdf_filename(s)\n", + " Adds/updates byteCount specification in XMP packet in pdf file(s) from\n", + " hyperxmp, with byteCount = file size.\n", + " No change if there's no XMP packet of the form produced by hyperxmp.\n", + "Options:\n", + " -help or -h Output usage information.\n", + " -version or -v Output version information.\n", + "Bug reports to:\n $maintainer.\n"; + exit; +} elsif ( $ARGV[0] =~ /^(-|--)(v|version)$/ ) { + print "$name $version.\n", + "Bug reports to:\n $maintainer.\n"; + exit; +} + +foreach (@ARGV) { + if ( ! fix_pdf($_) ) { $exit_code = 1; } +} + +exit $exit_code; + +#====================================================== + +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 = ''; + local $decl_bC = 'byteCount'; + local $pre_bC = ''; + local $post_bC = ''; + local $pC = ''; + local $rd_end = ''; + local $xmp_end = ''; + + 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 ( ) { + # 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 ( ) { + push @xmp, $_; + if ( /^\s*\Q$xmp_end\E/ ) { + $xmp_end_found = 1; + # Get amount of padding; + while () { + 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; + } +} + +#====================================================== diff --git a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx index a6dd612e77e..4fad6b29d0a 100644 --- a/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx +++ b/Master/texmf-dist/source/latex/hyperxmp/hyperxmp.dtx @@ -22,7 +22,7 @@ %\NeedsTeXFormat{LaTeX2e}[1999/12/01] %\ProvidesPackage{hyperxmp} %<*package> - [2020/11/01 v5.7 Store hyperref metadata in XMP format] + [2020/11/22 v5.9 Store hyperref metadata in XMP format] % % %<*driver> @@ -116,7 +116,7 @@ % % \fi % -% \CheckSum{2826} +% \CheckSum{2836} % % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z @@ -305,7 +305,7 @@ % \texorpdfstring{Dvips\SortIndex{dvips}{\texttt{dvips}}}{Dvips}^^A % } % \DeclareRobustCommand{\progname}[1]{^^A -% \texttt{#1}\SortIndex{#1}{\texttt{#1}}^^A +% \mbox{\texttt{#1}}\SortIndex{#1}{\texttt{#1}}^^A % } % \DeclareRobustCommand{\Lua}{^^A % Lua\index{Lua}^^A @@ -1489,68 +1489,88 @@ % property that indicates the \acro{PDF} file size in bytes. % \pkgname{hyperxmp} computes this value automatically when the document % is built using \LuaLaTeX\ but not when using any other \TeX\ engine. -% (Note that \pkgname{hyperxmp} uses the file size from the +% Note that \pkgname{hyperxmp} uses the file size from the % \emph{previous} run of \LuaLaTeX\ because the new \acro{PDF} file is -% not yet complete.) -% -% The \progname{latexmk} build tool can be configured to automatically -% append a line of the form ``|\hypersetup{pdfbytes=|\meta{number}|}|'' -% to the generated |.aux| file. The subsequent build of the document -% will read the |.aux| file at the end of the preamble and set -% \optname{pdfbytes} accordingly. The Perl code shown in -% Figure~\ref{fig:latexmkrc}, derived from code posted by Nelson Posse -% Lago and John Collins on -% \url{https://github.com/borisveytsman/acmart/issues/413}, can be -% included in a \progname{latexmk} configuration file to set -% \optname{pdfbytes} automatically whenever \progname{latexmk} builds a -% \pkgname{hyperxmp}-based document using -% \pdfLaTeX\ (\progname{latexmk}'s |--pdf| option). The code can be -% adapted, \textit{mutatis mutandis}, to work with \XeLaTeX\ builds -% (\progname{latexmk}'s |--pdfxe| or |--xelatex| option). +% not yet complete. Consequently, one extra compilation is needed for +% the byte count to converge relative to the the number of compilations +% that would otherwise be required. +% +% Starting with \pkgname{hyperxmp}~v5.9, the \pkgname{hyperxmp} +% distribution includes a Perl\index{Perl} script called +% \progname{hyperxmp-add-bytecount} that edits a \acro{PDF} file in +% place, adding or replacing the \xmpprop{prism:byteCount} property with +% one that specifies the final file size.\footnote{The script was in +% fact introduced with \progname{hyperxmp}~v5.8 and was then called +% \texttt{add\_byteCount}.} Run the script as +% ``\progname{hyperxmp-add-bytecount} \meta{filename.pdf}''. +% +% The \progname{latexmk} build tool can be configured to run +% \progname{hyperxmp-add-bytecount} automatically every time a \acro{PDF} file +% is generated. Simply add the code shown in Figure~\ref{fig:latexmkrc} +% to your \progname{latexmk} configuration file. See +% \href{http://mirrors.ctan.org/support/latexmk/latexmk.pdf}{the +% \progname{latexmk} manual} for information on configuration-file +% naming on different operating systems and explanations of the hook +% functions used in Figure~\ref{fig:latexmkrc}. +% +% \changes{v5.8}{2020/11/18}{Distribute an +% \protect\progname{add\_byteCount} script and document some sample +% \protect\progname{latexmk} configuration code that invokes it. +% Thanks to John Collins for providing both of those} +% \changes{v5.9}{2020/11/22}{At Karl Berry's request, rename +% \protect\progname{add\_byteCount} to the less generic-sounding +% \protect\progname{hyperxmp-add-bytecount}} % % \iffalse %<*listings> % \fi -\begin{figure} +\newsavebox{\latexmkrcbox} +\begin{lrbox}{\latexmkrcbox} \begin{lstlisting}[ language=perl, columns=fullflexible, + linewidth=19pc, frame=single, basicstyle=\footnotesize, - showstringspaces=false + showstringspaces=false, + upquote=true, + literate={-}{-}{1} ] -$pdflatex = 'internal mylatex %O %S'; - -sub mylatex { - my @args = @_; - $retval = system 'pdflatex', @args; - get_pdf_size(); - return $retval; +foreach my $cmd ( "latex", "lualatex", "pdflatex", "xelatex", + "dvipdf", "xdvipdfmx", "ps2pdf" ) { + ${$cmd} = "internal mycmd ${$cmd}"; } -sub get_pdf_size { - my $size = (stat($out_dir1 . $root_filename . ".pdf"))[7]; - open(AUX, '>>', $aux_dir1 . $root_filename . ".aux") - || die "Can't open file " . $aux_dir1 . $root_filename . ".aux: $!"; - if (defined($size)) { - print AUX "\\\@ifpackageloaded{hyperxmp}{\\hypersetup{pdfbytes=$size}}{}\n"; +sub mycmd { + my $retval = system @_; + if ( $$Pdest =~ /\.pdf$/ ) { + system 'hyperxmp-add-bytecount', $$Pdest; } - close(AUX); + return $retval; } \end{lstlisting} - \caption{Code to include in a \progname{latexmk} configuration file - to automate the assignment of \pkgname{hyperxmp}'s - \optname{pdfbytes} option when building with \pdfLaTeX} - \label{fig:latexmkrc} -\end{figure} +\end{lrbox} % \iffalse % % \fi % -% See \href{http://mirrors.ctan.org/support/latexmk/latexmk.pdf}{the -% \progname{latexmk} manual} for information on configuration-file -% naming on different operating systems and explanations of the hooks -% used in the Figure~\ref{fig:latexmkrc} code. +% \begin{figure} +% \centering +% \usebox{\latexmkrcbox} +% \caption{ \progname{latexmk} configuration-file code for +% automatically invoking \progname{hyperxmp-add-bytecount} every time a +% \acro{PDF} file is generated} +% \label{fig:latexmkrc} +% \end{figure} +% +% Even though \pkgname{hyperxmp} can compute the byte count +% automatically when run from \LuaLaTeX, users of \progname{latexmk} +% need to use configuration-file code like that shown in +% Figure~\ref{fig:latexmkrc}. Otherwise, \progname{latexmk} would +% compile the document one time too few for the byte count to +% converge. It is recommended that those who use both \progname{latexmk} +% and \pkgname{hyperxmp} configure \progname{latexmk} to be +% \pkgname{hyperxmp}-aware. % % % \StopEventually{^^A @@ -3194,13 +3214,111 @@ sub get_pdf_size { % Derek Dreyer, and the other contributors to % \protect\href{https://github.com/borisveytsman/acmart/issues/413}{\protect\pkgname{acmart} issue \#413}, % ``Latexmk goes into an infinite loop even on sample files from ACM''} +% \changes{v5.8}{2020/11/05}{Take +% \protect\mbox{\protect\texttt{-\kern0pt-output-directory}} into +% consideration when querying the output file size. Thanks to John +% Collins for pointing out that the user can change the output +% directory} % \begin{macrocode} \ifLuaTeX - \edef\hyxmp@prev@pdf@size{% - \luadirect{% -local nbytes = lfs.attributes("\hyxmp@jobname.pdf", "size") +% \end{macrocode} +% Now that we know we're running \LuaLaTeX\ we define a Lua function, +% |get_pdf_size|, that takes the base name of the output file and +% returns the number of bytes in the corresponding \acro{PDF} file. One +% difficulty is that, at the time of this writing, \LuaTeX\ lacks a +% mechanism for querying the full name of the output file. Our +% workaround is a tad kludgy but seems to work. We walk the list of +% command-line arguments for +% \mbox{``|-\kern0pt-output-directory=|\meta{dir}''}. (We in fact +% accept either one or two initial dashes and abbreviations as terse as +% \mbox{``|-output-d|''}.) Then, we concatenate the output directory +% (or ``|.|'' if unspecified), a path separator, the given base name of +% the job, and a ``|.pdf|'' extension. Alas, different operating +% systems use different path separators so we have to query the +% operating-system type to select an appropriate separator: ``|\|'' on +% Windows/\acro{DOS} and ``|/|'' on everything else. +% +% |get_pdf_size| is called regardless of whether we're producing +% \acro{PDF} or \acro{DVI} output. We assume that even if the user +% specified |--output-format=dvi|, the user's intention is eventually to +% convert the document to \acro{PDF}. +% \begin{macrocode} + \begin{luacode*} +function get_pdf_size (bname) +% \end{macrocode} +% Search the list of command-line arguments for the output directory. +% \begin{macrocode} + local odir = "" + for _, opt in ipairs(arg) do + local m = string.match(opt, "%-output%-d.-=(.*)") + if m then + odir = m + end + end +% \end{macrocode} +% Set the path separator to either ``|/|'' or ``|\|'', depending on the +% operating system. +% \begin{macrocode} + local sep = "/" + if os.type == "windows" or os.type == "msdos" then + sep = "\\\\" + end +% \end{macrocode} +% Concatenate the output directory, path separator, base name, and +% \texttt{.pdf} extension. Do not insert a path separator if either +% (1)~no output directory was specified, (2)~the output directory +% already ends with the path separator, or (3)~the output directory ends +% in a colon (and is therefore a relative directory) on +% Windows/\acro{DOS}. As a few examples, +% +% \bigskip +% \noindent +% \begingroup +% \let\bs=\textbackslash +% \begin{tabular}{@{\quad\textbullet~}l@{~+~}l@{~+~}l@{~+~``\texttt{.pdf}''~=~}l@{}} +% ``'' & ``\texttt{/}'' & ``\texttt{myfile}'' +% & ``\texttt{myfile.pdf}'' \\ +% ``\texttt{/docs}'' & ``\texttt{/}'' & ``\texttt{myfile}'' +% & ``\texttt{/docs/myfile.pdf}'' \\ +% ``\texttt{/docs/}'' & ``\texttt{/}'' & ``\texttt{myfile}'' +% & ``\texttt{/docs/myfile.pdf}'' \\ +% ``\texttt{C:\bs docs}'' & ``\texttt{\bs}'' & ``\texttt{myfile}'' +% & ``\texttt{C:\bs docs\bs myfile.pdf}'' \\ +% ``\texttt{C:\bs docs\bs}'' & ``\texttt{\bs}'' & ``\texttt{myfile}'' +% & ``\texttt{C:\bs docs\bs myfile.pdf}'' \\ +% ``\texttt{C:\bs}'' & ``\texttt{\bs}'' & ``\texttt{myfile}'' +% & ``\texttt{C:\bs myfile.pdf}'' \\ +% ``\texttt{C:}'' & ``\texttt{\bs}'' & ``\texttt{myfile}'' +% & ``\texttt{C:myfile.pdf}'' \\ +% \end{tabular} +% \endgroup +% \bigskip +% \begin{macrocode} + local dlast = string.sub(odir, -1) + if odir == "" or dlast == sep or (dlast == ":" and sep == "\\\\") then + sep = "" + end + local fname = odir .. sep .. bname .. ".pdf" +% \end{macrocode} +% Query the file size and return it. +% \begin{macrocode} + local nbytes = lfs.attributes(fname, "size") + return nbytes +end + \end{luacode*} +% \end{macrocode} +% Now that we've defined |get_pdf_size| we invoke it, passing it +% \cs{hyxmp@jobname} as the base name of the job. (Recall that +% \cs{hyxmp@jobname} is the same as \cs{jobname} but with any +% surrounding double quotes removed.) We store |get_pdf_size|'s +% output---which will be empty if the \acro{PDF} file doesn't yet +% exist---in \cs{hyxmp@prev@pdf@size}. +% \begin{macrocode} + \xdef\hyxmp@prev@pdf@size{% + \luadirect{ +nbytes = get_pdf_size("\hyxmp@jobname") if nbytes then - tex.write(nbytes) + tex.write(nbytes) end }% }% diff --git a/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty b/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty index 46cc9c97564..0c4ca2de09d 100644 --- a/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty +++ b/Master/texmf-dist/tex/latex/hyperxmp/hyperxmp.sty @@ -22,7 +22,7 @@ %% \NeedsTeXFormat{LaTeX2e}[1999/12/01] \ProvidesPackage{hyperxmp} - [2020/11/01 v5.7 Store hyperref metadata in XMP format] + [2020/11/22 v5.9 Store hyperref metadata in XMP format] \edef\hyxmp@dq@code{\the\catcode`\"} \catcode`\"=12 \@ifundefined{AtEndDocument}{% @@ -505,11 +505,33 @@ \RequirePackage{totpages} \fi \ifLuaTeX - \edef\hyxmp@prev@pdf@size{% - \luadirect{% -local nbytes = lfs.attributes("\hyxmp@jobname.pdf", "size") + \begin{luacode*} +function get_pdf_size (bname) + local odir = "" + for _, opt in ipairs(arg) do + local m = string.match(opt, "%-output%-d.-=(.*)") + if m then + odir = m + end + end + local sep = "/" + if os.type == "windows" or os.type == "msdos" then + sep = "\\\\" + end + local dlast = string.sub(odir, -1) + if odir == "" or dlast == sep or (dlast == ":" and sep == "\\\\") then + sep = "" + end + local fname = odir .. sep .. bname .. ".pdf" + local nbytes = lfs.attributes(fname, "size") + return nbytes +end + \end{luacode*} + \xdef\hyxmp@prev@pdf@size{% + \luadirect{ +nbytes = get_pdf_size("\hyxmp@jobname") if nbytes then - tex.write(nbytes) + tex.write(nbytes) end }% }% diff --git a/Master/tlpkg/libexec/ctan2tds b/Master/tlpkg/libexec/ctan2tds index ac479294cd5..24d0118c2b4 100755 --- a/Master/tlpkg/libexec/ctan2tds +++ b/Master/tlpkg/libexec/ctan2tds @@ -3284,6 +3284,7 @@ $standardttf = '\.ttf|\.TTC'; 'getmap' => 'getmapdl.lua', 'git-latexdiff' => 'git-latexdiff$', 'glossaries' => 'makeglossaries$|makeglossaries-lite\.lua', + 'hyperxmp' => '\.pl', 'installfont' => 'installfont-tl', 'jfmutil' => '\.pl', 'ketcindy' => 'ketcindy\.pl', diff --git a/Master/tlpkg/tlpsrc/hyperxmp.tlpsrc b/Master/tlpkg/tlpsrc/hyperxmp.tlpsrc index e69de29bb2d..49e3dc3eee4 100644 --- a/Master/tlpkg/tlpsrc/hyperxmp.tlpsrc +++ b/Master/tlpkg/tlpsrc/hyperxmp.tlpsrc @@ -0,0 +1,2 @@ +binpattern f bin/${ARCH}/hyperxmp-add-bytecount +docpattern +f texmf-dist/doc/man/man1/hyperxmp-add-bytecount.* -- cgit v1.2.3