texlive[52913] Master: pdftexcmds split from oberdiek (24nov19)

commits+karl at tug.org commits+karl at tug.org
Sun Nov 24 22:44:23 CET 2019


Revision: 52913
          http://tug.org/svn/texlive?view=revision&revision=52913
Author:   karl
Date:     2019-11-24 22:44:23 +0100 (Sun, 24 Nov 2019)
Log Message:
-----------
pdftexcmds split from oberdiek (24nov19)

Modified Paths:
--------------
    trunk/Master/tlpkg/bin/tlpkg-ctan-check
    trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/latex/pdftexcmds/
    trunk/Master/texmf-dist/doc/latex/pdftexcmds/README.md
    trunk/Master/texmf-dist/doc/latex/pdftexcmds/pdftexcmds.pdf
    trunk/Master/texmf-dist/scripts/pdftexcmds/
    trunk/Master/texmf-dist/scripts/pdftexcmds/pdftexcmds.lua
    trunk/Master/texmf-dist/source/latex/pdftexcmds/
    trunk/Master/texmf-dist/source/latex/pdftexcmds/pdftexcmds.dtx
    trunk/Master/texmf-dist/tex/latex/pdftexcmds/
    trunk/Master/texmf-dist/tex/latex/pdftexcmds/pdftexcmds.sty
    trunk/Master/tlpkg/tlpsrc/pdftexcmds.tlpsrc

Added: trunk/Master/texmf-dist/doc/latex/pdftexcmds/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/pdftexcmds/README.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/pdftexcmds/README.md	2019-11-24 21:44:23 UTC (rev 52913)
@@ -0,0 +1,11 @@
+# pdftexcmds
+pdftexcmds package for LaTeX
+
+
+
+
+
+    doc/latex/pdftexcmds/pdftexcmds.pdf
+    scripts/pdftexcmds/pdftexcmds.lua
+    source/latex/pdftexcmds/pdftexcmds.dtx
+    tex/generic/pdftexcmds/pdftexcmds.sty


Property changes on: trunk/Master/texmf-dist/doc/latex/pdftexcmds/README.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/pdftexcmds/pdftexcmds.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/pdftexcmds/pdftexcmds.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/pdftexcmds/pdftexcmds.pdf	2019-11-24 21:38:59 UTC (rev 52912)
+++ trunk/Master/texmf-dist/doc/latex/pdftexcmds/pdftexcmds.pdf	2019-11-24 21:44:23 UTC (rev 52913)

Property changes on: trunk/Master/texmf-dist/doc/latex/pdftexcmds/pdftexcmds.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/scripts/pdftexcmds/pdftexcmds.lua
===================================================================
--- trunk/Master/texmf-dist/scripts/pdftexcmds/pdftexcmds.lua	                        (rev 0)
+++ trunk/Master/texmf-dist/scripts/pdftexcmds/pdftexcmds.lua	2019-11-24 21:44:23 UTC (rev 52913)
@@ -0,0 +1,376 @@
+-- 
+--  This is file `pdftexcmds.lua',
+--  generated with the docstrip utility.
+-- 
+--  The original source files were:
+-- 
+--  pdftexcmds.dtx  (with options: `lua')
+--  
+--  This is a generated file.
+--  
+--  Project: pdftexcmds
+--  Version: 2019/11/24 v0.31
+--  
+--  Copyright (C)
+--     2007, 2009-2011  Heiko Oberdiek
+--     2016-2019        Oberdiek Package Support Group
+--  
+--  This work 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. This version of this license is in
+--     https://www.latex-project.org/lppl/lppl-1-3c.txt
+--  and the latest version of this license is in
+--     https://www.latex-project.org/lppl.txt
+--  and version 1.3 or later is part of all distributions of
+--  LaTeX version 2005/12/01 or later.
+--  
+--  This work has the LPPL maintenance status "maintained".
+--  
+--  The Current Maintainers of this work are
+--  Heiko Oberdiek and the Oberdiek Package Support Group
+--  https://github.com/ho-tex/pdftexcmds/issues
+--  
+--  
+--  The Base Interpreter refers to any `TeX-Format',
+--  because some files are installed in TDS:tex/generic//.
+--  
+--  This work consists of the main source file pdftexcmds.dtx
+--  and the derived files
+--     pdftexcmds.sty, pdftexcmds.pdf, pdftexcmds.ins, pdftexcmds.drv,
+--     pdftexcmds.lua.
+--  
+oberdiek = oberdiek or {}
+local pdftexcmds = oberdiek.pdftexcmds or {}
+oberdiek.pdftexcmds = pdftexcmds
+local systemexitstatus
+function pdftexcmds.getversion()
+  tex.write("2019/11/24 v0.31")
+end
+function pdftexcmds.strcmp(A, B)
+  if A == B then
+    tex.write("0")
+  elseif A < B then
+    tex.write("-1")
+  else
+    tex.write("1")
+  end
+end
+local function utf8_to_byte(str)
+  local i = 0
+  local n = string.len(str)
+  local t = {}
+  while i < n do
+    i = i + 1
+    local a = string.byte(str, i)
+    if a < 128 then
+      table.insert(t, string.char(a))
+    else
+      if a >= 192 and i < n then
+        i = i + 1
+        local b = string.byte(str, i)
+        if b < 128 or b >= 192 then
+          i = i - 1
+        elseif a == 194 then
+          table.insert(t, string.char(b))
+        elseif a == 195 then
+          table.insert(t, string.char(b + 64))
+        end
+      end
+    end
+  end
+  return table.concat(t)
+end
+function pdftexcmds.escapehex(str, mode)
+  if mode == "byte" then
+    str = utf8_to_byte(str)
+  end
+  tex.write((string.gsub(str, ".",
+    function (ch)
+      return string.format("%02X", string.byte(ch))
+    end
+  )))
+end
+function pdftexcmds.unescapehex(str, mode, patch)
+  local a = 0
+  local first = true
+  local result = {}
+  for i = 1, string.len(str), 1 do
+    local ch = string.byte(str, i)
+    if ch >= 48 and ch <= 57 then
+      ch = ch - 48
+    elseif ch >= 65 and ch <= 70 then
+      ch = ch - 55
+    elseif ch >= 97 and ch <= 102 then
+      ch = ch - 87
+    else
+      ch = nil
+    end
+    if ch then
+      if first then
+        a = ch * 16
+        first = false
+      else
+        table.insert(result, a + ch)
+        first = true
+      end
+    end
+  end
+  if not first then
+    table.insert(result, a)
+  end
+  if patch == 1 then
+    local temp = {}
+    for i, a in ipairs(result) do
+      if a == 0 then
+        table.insert(temp, 1)
+        table.insert(temp, 1)
+      else
+        if a == 1 then
+          table.insert(temp, 1)
+          table.insert(temp, 2)
+        else
+          table.insert(temp, a)
+        end
+      end
+    end
+    result = temp
+  end
+  if mode == "byte" then
+    local utf8 = {}
+    for i, a in ipairs(result) do
+      if a < 128 then
+        table.insert(utf8, a)
+      else
+        if a < 192 then
+          table.insert(utf8, 194)
+          a = a - 128
+        else
+          table.insert(utf8, 195)
+          a = a - 192
+        end
+        table.insert(utf8, a + 128)
+      end
+    end
+    result = utf8
+  end
+  local unpack = _G["unpack"] or table.unpack
+  tex.settoks(pdftexcmds.toks, string.char(unpack(result)))
+end
+function pdftexcmds.escapestring(str, mode)
+  if mode == "byte" then
+    str = utf8_to_byte(str)
+  end
+  tex.write((string.gsub(str, ".",
+    function (ch)
+      local b = string.byte(ch)
+      if b < 33 or b > 126 then
+        return string.format("\\%.3o", b)
+      end
+      if b == 40 or b == 41 or b == 92 then
+        return "\\" .. ch
+      end
+      return nil
+    end
+  )))
+end
+function pdftexcmds.escapename(str, mode)
+  if mode == "byte" then
+    str = utf8_to_byte(str)
+  end
+  tex.write((string.gsub(str, ".",
+    function (ch)
+      local b = string.byte(ch)
+      if b == 0 then
+        return ""
+      end
+      if b <= 32 or b >= 127
+          or b == 35 or b == 37 or b == 40 or b == 41
+          or b == 47 or b == 60 or b == 62 or b == 91
+          or b == 93 or b == 123 or b == 125 then
+        return string.format("#%.2X", b)
+      else
+        return nil
+      end
+    end
+  )))
+end
+function pdftexcmds.filesize(filename)
+  local foundfile = kpse.find_file(filename, "tex", true)
+  if foundfile then
+    local size = lfs.attributes(foundfile, "size")
+    if size then
+      tex.write(size)
+    end
+  end
+end
+function pdftexcmds.filemoddate(filename)
+  local foundfile = kpse.find_file(filename, "tex", true)
+  if foundfile then
+    local date = lfs.attributes(foundfile, "modification")
+    if date then
+      local d = os.date("*t", date)
+      if d.sec >= 60 then
+        d.sec = 59
+      end
+      local u = os.date("!*t", date)
+      local off = 60 * (d.hour - u.hour) + d.min - u.min
+      if d.year ~= u.year then
+        if d.year > u.year then
+          off = off + 1440
+        else
+          off = off - 1440
+        end
+      elseif d.yday ~= u.yday then
+        if d.yday > u.yday then
+          off = off + 1440
+        else
+          off = off - 1440
+        end
+      end
+      local timezone
+      if off == 0 then
+        timezone = "Z"
+      else
+        local hours = math.floor(off / 60)
+        local mins = math.abs(off - hours * 60)
+        timezone = string.format("%+03d'%02d'", hours, mins)
+      end
+      tex.write(string.format("D:%04d%02d%02d%02d%02d%02d%s",
+          d.year, d.month, d.day, d.hour, d.min, d.sec, timezone))
+    end
+  end
+end
+function pdftexcmds.filedump(offset, length, filename)
+  length = tonumber(length)
+  if length and length > 0 then
+    local foundfile = kpse.find_file(filename, "tex", true)
+    if foundfile then
+      offset = tonumber(offset)
+      if not offset then
+        offset = 0
+      end
+      local filehandle = io.open(foundfile, "rb")
+      if filehandle then
+        if offset > 0 then
+          filehandle:seek("set", offset)
+        end
+        local dump = filehandle:read(length)
+        pdftexcmds.escapehex(dump)
+        filehandle:close()
+      end
+    end
+  end
+end
+function pdftexcmds.mdfivesum(str, mode)
+  if mode == "byte" then
+    str = utf8_to_byte(str)
+  end
+  pdftexcmds.escapehex(md5.sum(str))
+end
+function pdftexcmds.filemdfivesum(filename)
+  local foundfile = kpse.find_file(filename, "tex", true)
+  if foundfile then
+    local filehandle = io.open(foundfile, "rb")
+    if filehandle then
+      local contents = filehandle:read("*a")
+      pdftexcmds.escapehex(md5.sum(contents))
+      filehandle:close()
+    end
+  end
+end
+local basetime = 0
+function pdftexcmds.resettimer()
+  basetime = os.clock()
+end
+function pdftexcmds.elapsedtime()
+  local val = (os.clock() - basetime) * 65536 + .5
+  if val > 2147483647 then
+    val = 2147483647
+  end
+  tex.write(string.format("%d", val))
+end
+function pdftexcmds.shellescape()
+  if os.execute then
+    if status
+        and status.luatex_version
+        and status.luatex_version >= 68 then
+      tex.write(os.execute())
+    else
+      local result = os.execute()
+      if result == 0 then
+        tex.write("0")
+      else
+        if result == nil then
+          tex.write("0")
+        else
+          tex.write("1")
+        end
+      end
+    end
+  else
+    tex.write("0")
+  end
+end
+function pdftexcmds.system(cmdline)
+  systemexitstatus = nil
+  texio.write_nl("log", "system(" .. cmdline .. ") ")
+  if os.execute then
+    texio.write("log", "executed.")
+    systemexitstatus = os.execute(cmdline)
+  else
+    texio.write("log", "disabled.")
+  end
+end
+function pdftexcmds.lastsystemstatus()
+  local result = tonumber(systemexitstatus)
+  if result then
+    local x = math.floor(result / 256)
+    tex.write(result - 256 * math.floor(result / 256))
+  end
+end
+function pdftexcmds.lastsystemexit()
+  local result = tonumber(systemexitstatus)
+  if result then
+    tex.write(math.floor(result / 256))
+  end
+end
+function pdftexcmds.pipe(cmdline, patch)
+  local result
+  systemexitstatus = nil
+  texio.write_nl("log", "pipe(" .. cmdline ..") ")
+  if io.popen then
+    texio.write("log", "executed.")
+    local handle = io.popen(cmdline, "r")
+    if handle then
+      result = handle:read("*a")
+      handle:close()
+    end
+  else
+    texio.write("log", "disabled.")
+  end
+  if result then
+    if patch == 1 then
+      local temp = {}
+      for i, a in ipairs(result) do
+        if a == 0 then
+          table.insert(temp, 1)
+          table.insert(temp, 1)
+        else
+          if a == 1 then
+            table.insert(temp, 1)
+            table.insert(temp, 2)
+          else
+            table.insert(temp, a)
+          end
+        end
+      end
+      result = temp
+    end
+    tex.settoks(pdftexcmds.toks, result)
+  else
+    tex.settoks(pdftexcmds.toks, "")
+  end
+end
+-- 
+--  End of File `pdftexcmds.lua'.


Property changes on: trunk/Master/texmf-dist/scripts/pdftexcmds/pdftexcmds.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/pdftexcmds/pdftexcmds.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/pdftexcmds/pdftexcmds.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/pdftexcmds/pdftexcmds.dtx	2019-11-24 21:44:23 UTC (rev 52913)
@@ -0,0 +1,2662 @@
+% \iffalse meta-comment
+%
+% File: pdftexcmds.dtx
+% Version: 2019/11/24 v0.31
+% Info: Utility functions of pdfTeX for LuaTeX
+%
+% Copyright (C)
+% 2007, 2009-2011  Heiko Oberdiek
+% 2016-2019        Oberdiek Package Support Group
+%
+% This work 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. This version of this license is in
+%    https://www.latex-project.org/lppl/lppl-1-3c.txt
+% and the latest version of this license is in
+%    https://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of
+% LaTeX version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status "maintained".
+%
+% The Current Maintainers of this work are
+% Heiko Oberdiek and the Oberdiek Package Support Group
+% https://github.com/ho-tex/pdftexcmds/issues
+%
+% The Base Interpreter refers to any `TeX-Format',
+% because some files are installed in TDS:tex/generic//.
+%
+% This work consists of the main source file pdftexcmds.dtx
+% and the derived files
+%    pdftexcmds.sty, pdftexcmds.pdf, pdftexcmds.ins, pdftexcmds.drv,
+%    pdftexcmds.bib, pdftexcmds-test1.tex, pdftexcmds-test2.tex,
+%    pdftexcmds-test-shell.tex, pdftexcmds-test-escape.tex,
+%    pdftexcmds.lua.
+%
+% Distribution:
+%    CTAN:macros/latex/contrib/pdftexcmds/pdftexcmds.dtx
+%    CTAN:macros/latex/contrib/pdftexcmds/pdftexcmds.pdf
+%
+% Unpacking:
+%    (a) If pdftexcmds.ins is present:
+%           tex pdftexcmds.ins
+%    (b) Without pdftexcmds.ins:
+%           tex pdftexcmds.dtx
+%    (c) If you insist on using LaTeX
+%           latex \let\install=y\input{pdftexcmds.dtx}
+%        (quote the arguments according to the demands of your shell)
+%
+% Documentation:
+%    (a) If pdftexcmds.drv is present:
+%           latex pdftexcmds.drv
+%    (b) Without pdftexcmds.drv:
+%           latex pdftexcmds.dtx; ...
+%    The class ltxdoc loads the configuration file ltxdoc.cfg
+%    if available. Here you can specify further options, e.g.
+%    use A4 as paper format:
+%       \PassOptionsToClass{a4paper}{article}
+%
+%    Programm calls to get the documentation (example):
+%       pdflatex pdftexcmds.dtx
+%       bibtex pdftexcmds.aux
+%       makeindex -s gind.ist pdftexcmds.idx
+%       pdflatex pdftexcmds.dtx
+%       makeindex -s gind.ist pdftexcmds.idx
+%       pdflatex pdftexcmds.dtx
+%
+% Installation:
+%    TDS:tex/generic/pdftexcmds/pdftexcmds.sty
+%    TDS:scripts/pdftexcmds/pdftexcmds.lua
+%    TDS:doc/latex/pdftexcmds/pdftexcmds.pdf
+%    TDS:source/latex/pdftexcmds/pdftexcmds.dtx
+%
+%<*ignore>
+\begingroup
+  \catcode123=1 %
+  \catcode125=2 %
+  \def\x{LaTeX2e}%
+\expandafter\endgroup
+\ifcase 0\ifx\install y1\fi\expandafter
+         \ifx\csname processbatchFile\endcsname\relax\else1\fi
+         \ifx\fmtname\x\else 1\fi\relax
+\else\csname fi\endcsname
+%</ignore>
+%<*install>
+\input docstrip.tex
+\Msg{************************************************************************}
+\Msg{* Installation}
+\Msg{* Package: pdftexcmds 2019/11/24 v0.31 Utility functions of pdfTeX for LuaTeX (HO)}
+\Msg{************************************************************************}
+
+\keepsilent
+\askforoverwritefalse
+
+\let\MetaPrefix\relax
+\preamble
+
+This is a generated file.
+
+Project: pdftexcmds
+Version: 2019/11/24 v0.31
+
+Copyright (C)
+   2007, 2009-2011  Heiko Oberdiek
+   2016-2019        Oberdiek Package Support Group
+
+This work 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. This version of this license is in
+   https://www.latex-project.org/lppl/lppl-1-3c.txt
+and the latest version of this license is in
+   https://www.latex-project.org/lppl.txt
+and version 1.3 or later is part of all distributions of
+LaTeX version 2005/12/01 or later.
+
+This work has the LPPL maintenance status "maintained".
+
+The Current Maintainers of this work are
+Heiko Oberdiek and the Oberdiek Package Support Group
+https://github.com/ho-tex/pdftexcmds/issues
+
+
+The Base Interpreter refers to any `TeX-Format',
+because some files are installed in TDS:tex/generic//.
+
+This work consists of the main source file pdftexcmds.dtx
+and the derived files
+   pdftexcmds.sty, pdftexcmds.pdf, pdftexcmds.ins, pdftexcmds.drv,
+   pdftexcmds.lua.
+
+\endpreamble
+\let\MetaPrefix\DoubleperCent
+
+\generate{%
+  \file{pdftexcmds.ins}{\from{pdftexcmds.dtx}{install}}%
+  \file{pdftexcmds.drv}{\from{pdftexcmds.dtx}{driver}}%
+  \nopreamble
+  \nopostamble
+  \file{pdftexcmds.bib}{\from{pdftexcmds.dtx}{bib}}%
+  \usepreamble\defaultpreamble
+  \usepostamble\defaultpostamble
+  \usedir{tex/generic/pdftexcmds}%
+  \file{pdftexcmds.sty}{\from{pdftexcmds.dtx}{package}}%
+%  \usedir{doc/latex/pdftexcmds/test}%
+%  \file{pdftexcmds-test1.tex}{\from{pdftexcmds.dtx}{test1}}%
+%  \file{pdftexcmds-test2.tex}{\from{pdftexcmds.dtx}{test2}}%
+%  \file{pdftexcmds-test-shell.tex}{\from{pdftexcmds.dtx}{test-shell}}%
+%  \file{pdftexcmds-test-escape.tex}{\from{pdftexcmds.dtx}{test-escape}}%
+  \nopreamble
+  \nopostamble
+%  \usedir{source/latex/pdftexcmds/catalogue}%
+%  \file{pdftexcmds.xml}{\from{pdftexcmds.dtx}{catalogue}}%
+}
+\def\MetaPrefix{-- }
+\def\defaultpostamble{%
+  \MetaPrefix^^J%
+  \MetaPrefix\space End of File `\outFileName'.%
+}
+\def\currentpostamble{\defaultpostamble}%
+\generate{%
+  \usedir{scripts/pdftexcmds}%
+  \file{pdftexcmds.lua}{\from{pdftexcmds.dtx}{lua}}%
+}
+
+\catcode32=13\relax% active space
+\let =\space%
+\Msg{************************************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the following}
+\Msg{* file into a directory searched by TeX:}
+\Msg{*}
+\Msg{*     pdftexcmds.sty}
+\Msg{*}
+\Msg{* And install the following script files:}
+\Msg{*}
+\Msg{*     pdftexcmds.lua}
+\Msg{*}
+\Msg{* To produce the documentation run the file `pdftexcmds.drv'}
+\Msg{* through LaTeX.}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*}
+\Msg{************************************************************************}
+
+\endbatchfile
+%</install>
+%<*bib>
+ at online{AndyThomas:Analog,
+  author={Thomas, Andy},
+  title={Analog of {\texttt{\csname textbackslash\endcsname}pdfelapsedtime} for
+      {\hologo{LuaTeX}} and {\hologo{XeTeX}}},
+  url={http://tex.stackexchange.com/a/32531},
+  urldate={2011-11-29},
+}
+%</bib>
+%<*ignore>
+\fi
+%</ignore>
+%<*driver>
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesFile{pdftexcmds.drv}%
+  [2019/11/24 v0.31 Utility functions of pdfTeX for LuaTeX (HO)]%
+\documentclass{ltxdoc}
+\usepackage{holtxdoc}[2011/11/22]
+\usepackage{paralist}
+\usepackage{csquotes}
+\usepackage[
+  backend=bibtex,
+  bibencoding=ascii,
+  alldates=iso8601,
+]{biblatex}[2011/11/13]
+\bibliography{oberdiek-source}
+\bibliography{pdftexcmds}
+\begin{document}
+  \DocInput{pdftexcmds.dtx}%
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \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
+%   Lower-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
+%   Digits        \0\1\2\3\4\5\6\7\8\9
+%   Exclamation   \!     Double quote  \"     Hash (number) \#
+%   Dollar        \$     Percent       \%     Ampersand     \&
+%   Acute accent  \'     Left paren    \(     Right paren   \)
+%   Asterisk      \*     Plus          \+     Comma         \,
+%   Minus         \-     Point         \.     Solidus       \/
+%   Colon         \:     Semicolon     \;     Less than     \<
+%   Equals        \=     Greater than  \>     Question mark \?
+%   Commercial at \@     Left bracket  \[     Backslash     \\
+%   Right bracket \]     Circumflex    \^     Underscore    \_
+%   Grave accent  \`     Left brace    \{     Vertical bar  \|
+%   Right brace   \}     Tilde         \~}
+%
+% \GetFileInfo{pdftexcmds.drv}
+%
+% \title{The \xpackage{pdftexcmds} package}
+% \date{2019/11/24 v0.31}
+% \author{Heiko Oberdiek\thanks
+% {Please report any issues at \url{https://github.com/ho-tex/pdftexcmds/issues}}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% \hologo{LuaTeX} provides most of the commands of \hologo{pdfTeX} 1.40. However
+% a number of utility functions are removed. This package tries to fill
+% the gap and implements some of the missing primitive using Lua.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \def\csi#1{\texttt{\textbackslash\textit{#1}}}
+%
+% \section{Documentation}
+%
+% Some primitives of \hologo{pdfTeX} \cite{pdftex-manual}
+% are not defined by \hologo{LuaTeX} \cite{luatex-manual}.
+% This package implements macro based solutions using Lua code
+% for the following missing \hologo{pdfTeX} primitives;
+% \begin{compactitem}
+% \item \cs{pdfstrcmp}
+% \item \cs{pdfunescapehex}
+% \item \cs{pdfescapehex}
+% \item \cs{pdfescapename}
+% \item \cs{pdfescapestring}
+% \item \cs{pdffilesize}
+% \item \cs{pdffilemoddate}
+% \item \cs{pdffiledump}
+% \item \cs{pdfmdfivesum}
+% \item \cs{pdfresettimer}
+% \item \cs{pdfelapsedtime}
+% \item |\immediate\write18|
+% \end{compactitem}
+% The original names of the primitives cannot be used:
+% \begin{itemize}
+% \item
+% The syntax for their arguments cannot easily
+% simulated by macros. The primitives using key words
+% such as |file| (\cs{pdfmdfivesum}) or |offset| and |length|
+% (\cs{pdffiledump}) and uses \meta{general text} for the other
+% arguments. Using token registers assignments, \meta{general text} could
+% be catched. However, the simulated primitives are expandable
+% and register assignments would destroy this important property.
+% (\meta{general text} allows something like |\expandafter\bgroup ...}|.)
+% \item
+% The original primitives can be expanded using one expansion step.
+% The new macros need two expansion steps because of the additional
+% macro expansion. Example:
+% \begin{quote}
+%   |\expandafter\foo\pdffilemoddate{file}|\\
+%   vs.\\
+%   |\expandafter\expandafter\expandafter|\\
+%   |\foo\pdf at filemoddate{file}|
+% \end{quote}
+% \end{itemize}
+%
+% \hologo{LuaTeX} isn't stable yet and thus the status of this package is
+% \emph{experimental}. Feedback is welcome.
+%
+% \subsection{General principles}
+%
+% \begin{description}
+% \item[Naming convention:]
+%   Usually this package defines a macro |\pdf@|\meta{cmd} if
+%   \hologo{pdfTeX} provides |\pdf|\meta{cmd}.
+% \item[Arguments:] The order of arguments in |\pdf@|\meta{cmd}
+%   is the same as for the corresponding primitive of \hologo{pdfTeX}.
+%   The arguments are ordinary undelimited \hologo{TeX} arguments,
+%   no \meta{general text} and without additional keywords.
+% \item[Expandibility:]
+%   The macro |\pdf@|\meta{cmd} is expandable if the
+%   corresponding \hologo{pdfTeX} primitive has this property.
+%   Exact two expansion steps are necessary (first is the macro
+%   expansion) except for \cs{pdf at primitive} and \cs{pdf at ifprimitive}.
+%   The latter ones are not macros, but have the direct meaning of the
+%   primitive.
+% \item[Without \hologo{LuaTeX}:]
+%   The macros |\pdf@|\meta{cmd} are mapped to the commands
+%   of \hologo{pdfTeX} if they are available. Otherwise they are undefined.
+% \item[Availability:]
+%   The macros that the packages provides are undefined, if
+%   the necessary primitives are not found and cannot be
+%   implemented by Lua.
+% \end{description}
+%
+% \subsection{Macros}
+%
+% \subsubsection[Strings]{Strings \cite[``7.15 Strings'']{pdftex-manual}}
+%
+% \begin{declcs}{pdf at strcmp} \M{stringA} \M{stringB}
+% \end{declcs}
+% Same as |\pdfstrcmp{|\meta{stringA}|}{|\meta{stringB}|}|.
+%
+% \begin{declcs}{pdf at unescapehex} \M{string}
+% \end{declcs}
+% Same as |\pdfunescapehex{|\meta{string}|}|.
+% The argument is a byte string given in hexadecimal notation.
+% The result are character tokens from 0 until 255 with
+% catcode 12 and the space with catcode 10.
+%
+% \begin{declcs}{pdf at escapehex} \M{string}\\
+%   \cs{pdf at escapestring} \M{string}\\
+%   \cs{pdf at escapename} \M{string}
+% \end{declcs}
+% Same as the primitives of \hologo{pdfTeX}. However \hologo{pdfTeX} does not
+% know about characters with codes 256 and larger. Thus the
+% string is treated as byte string, characters with more than
+% eight bits are ignored.
+%
+% \subsubsection[Files]{Files \cite[``7.18 Files'']{pdftex-manual}}
+%
+% \begin{declcs}{pdf at filesize} \M{filename}
+% \end{declcs}
+% Same as |\pdffilesize{|\meta{filename}|}|.
+%
+% \begin{declcs}{pdf at filemoddate} \M{filename}
+% \end{declcs}
+% Same as |\pdffilemoddate{|\meta{filename}|}|.
+%
+% \begin{declcs}{pdf at filedump} \M{offset} \M{length} \M{filename}
+% \end{declcs}
+% Same as |\pdffiledump offset| \meta{offset} |length| \meta{length}
+% |{|\meta{filename}|}|. Both \meta{offset} and \meta{length} must
+% not be empty, but must be a valid \hologo{TeX} number.
+%
+% \begin{declcs}{pdf at mdfivesum} \M{string}
+% \end{declcs}
+% Same as |\pdfmdfivesum{|\meta{string}|}|. Keyword |file| is supported
+% by macro \cs{pdf at filemdfivesum}.
+%
+% \begin{declcs}{pdf at filemdfivesum} \M{filename}
+% \end{declcs}
+% Same as |\pdfmdfivesum file{|\meta{filename}|}|.
+%
+% \subsubsection[Timekeeping]{Timekeeping \cite[``7.17 Timekeeping'']{pdftex-manual}}
+%
+% The timekeeping macros are based on Andy Thomas' work \cite{AndyThomas:Analog}.
+%
+% \begin{declcs}{pdf at resettimer}
+% \end{declcs}
+% Same as \cs{pdfresettimer}, it resets the internal timer.
+%
+% \begin{declcs}{pdf at elapsedtime}
+% \end{declcs}
+% Same as \cs{pdfelapsedtime}. It behaves like a read-only integer.
+% For printing purposes it can be prefixed by \cs{the} or \cs{number}.
+% It measures the time in scaled seconds (seconds multiplied with 65536)
+% since the latest call of \cs{pdf at resettimer} or start of
+% program/package. The resolution, the shortest time interval that
+% can be measured, depends on the program and system.
+% \begin{itemize}
+% \item \hologo{pdfTeX} with |gettimeofday|: $\ge$ 1/65536\,s
+% \item \hologo{pdfTeX} with |ftime|: $\ge$ 1\,ms
+% \item \hologo{pdfTeX} with |time|: $\ge$ 1\,s
+% \item \hologo{LuaTeX}: $\ge$ 10\,ms\\
+%  (|os.clock()| returns a float number with two decimal digits in
+%  \hologo{LuaTeX} beta-0.70.1-2011061416 (rev 4277)).
+% \end{itemize}
+%
+% \subsubsection[Miscellaneous]{Miscellaneous \cite[``7.21 Miscellaneous'']{pdftex-manual}}
+%
+% \begin{declcs}{pdf at draftmode}
+% \end{declcs}
+% If the \TeX\ compiler knows \cs{pdfdraftmode} or \cs{draftmode}
+% (\hologo{pdfTeX},
+% \hologo{LuaTeX}), then \cs{pdf at draftmode} returns, whether
+% this mode is enabled. The result is an implicit number:
+% one means the draft mode is available and enabled.
+% If the value is zero, then the mode is not active or
+% \cs{pdfdraftmode} is not available.
+% An explicit number is yielded by \cs{number}\cs{pdf at draftmode}.
+% The macro cannot
+% be used to change the mode, see \cs{pdf at setdraftmode}.
+%
+% \begin{declcs}{pdf at ifdraftmode} \M{true} \M{false}
+% \end{declcs}
+% If \cs{pdfdraftmode} is available and enabled, \meta{true} is
+% called, otherwise \meta{false} is executed.
+%
+% \begin{declcs}{pdf at setdraftmode} \M{value}
+% \end{declcs}
+% Macro \cs{pdf at setdraftmode} expects the number zero or one as
+% \meta{value}. Zero deactivates the mode and one enables the draft mode.
+% The macro does not have an effect, if the feature \cs{pdfdraftmode} is not
+% available.
+%
+% \begin{declcs}{pdf at shellescape}
+% \end{declcs}
+% Same as |\pdfshellescape|. It is or expands to |1| if external
+% commands can be executed and |0| otherwise. In \hologo{pdfTeX} external
+% commands must be enabled first by command line option or
+% configuration option. In \hologo{LuaTeX} option |--safer| disables
+% the execution of external commands.
+%
+% In \hologo{LuaTeX} before 0.68.0 \cs{pdf at shellescape} is not
+% available due to a bug in |os.execute()|. The argumentless form
+% crashes in some circumstances with segmentation fault.
+% (It is fixed in version 0.68.0 or revision 4167 of \hologo{LuaTeX}.
+% and packported to some version of 0.67.0).
+%
+% Hints for usage:
+% \begin{itemize}
+% \item Before its use \cs{pdf at shellescape} should be tested,
+% whether it is available. Example with package \xpackage{ltxcmds}
+% (loaded by package \xpackage{pdftexcmds}):
+%\begin{quote}
+%\begin{verbatim}
+%\ltx at IfUndefined{pdf at shellescape}{%
+%  % \pdf at shellescape is undefined
+%}{%
+%  % \pdf at shellescape is available
+%}
+%\end{verbatim}
+%\end{quote}
+% Use \cs{ltx at ifundefined} in expandable contexts.
+% \item \cs{pdf at shellescape} might be a numerical constant,
+% expands to the primitive, or expands to a plain number.
+% Therefore use it in contexts where these differences does not matter.
+% \item Use in comparisons, e.g.:
+%   \begin{quote}
+%     |\ifnum\pdf at shellescape=0 ...|
+%   \end{quote}
+% \item Print the number: |\number\pdf at shellescape|
+% \end{itemize}
+%
+% \begin{declcs}{pdf at system} \M{cmdline}
+% \end{declcs}
+% It is a wrapper for |\immediate\write18| in \hologo{pdfTeX} or
+% |os.execute| in \hologo{LuaTeX}.
+%
+% In theory |os.execute|
+% returns a status number. But its meaning is quite
+% undefined. Are there some reliable properties?
+% Does it make sense to provide an user interface to
+% this status exit code?
+%
+% \begin{declcs}{pdf at primitive} \csi{cmd}
+% \end{declcs}
+% Same as \cs{pdfprimitive} in \hologo{pdfTeX} or \hologo{LuaTeX}.
+% In \hologo{XeTeX} the
+% primitive is called \cs{primitive}. Despite the current definition
+% of the command \csi{cmd}, it's meaning as primitive is used.
+%
+% \begin{declcs}{pdf at ifprimitive} \csi{cmd}
+% \end{declcs}
+% Same as \cs{ifpdfprimitive} in \hologo{pdfTeX} or
+% \hologo{LuaTeX}. \hologo{XeTeX} calls
+% it \cs{ifprimitive}. It is a switch that checks if the command
+% \csi{cmd} has it's primitive meaning.
+%
+% \subsubsection{Additional macro: \cs{pdf at isprimitive}}
+%
+% \begin{declcs}{pdf at isprimitive} \csi{cmd1} \csi{cmd2} \M{true} \M{false}
+% \end{declcs}
+% If \csi{cmd1} has the primitive meaning given by the primitive name
+% of \csi{cmd2}, then the argument \meta{true} is executed, otherwise
+% \meta{false}. The macro \cs{pdf at isprimitive} is expandable.
+% Internally it checks the result of \cs{meaning} and is therefore
+% available for all \hologo{TeX} variants, even the original \hologo{TeX}.
+% Example with \hologo{LaTeX}:
+%\begin{quote}
+%\begin{verbatim}
+%\makeatletter
+%\pdf at isprimitive{@@input}{input}{%
+%  \typeout{\string\@@input\space is original\string\input}%
+%}{%
+%  \typeout{Oops, \string\@@input\space is not the %
+%           original\string\input}%
+%}
+%\end{verbatim}
+%\end{quote}
+%
+% \subsubsection{Experimental}
+%
+% \begin{declcs}{pdf at unescapehexnative} \M{string}\\
+%   \cs{pdf at escapehexnative} \M{string}\\
+%   \cs{pdf at escapenamenative} \M{string}\\
+%   \cs{pdf at mdfivesumnative} \M{string}
+% \end{declcs}
+% The variants without |native| in the macro name are supposed to
+% be compatible with \hologo{pdfTeX}. However characters with more than
+% eight bits are not supported and are ignored. If \hologo{LuaTeX} is
+% running, then its UTF-8 coded strings are used. Thus the full
+% unicode character range is supported. However the result
+% differs from \hologo{pdfTeX} for characters with eight or more bits.
+%
+% \begin{declcs}{pdf at pipe} \M{cmdline}
+% \end{declcs}
+% It calls \meta{cmdline} and returns the output of the external
+% program in the usual manner as byte string (catcode 12, space with
+% catcode 10). The Lua documentation says, that the used |io.popen|
+% may not be available on all platforms. Then macro \cs{pdf at pipe}
+% is undefined.
+%
+% \StopEventually{
+% }
+%
+% \section{Implementation}
+%
+%    \begin{macrocode}
+%<*package>
+%    \end{macrocode}
+%
+% \subsection{Reload check and package identification}
+%    Reload check, especially if the package is not used with \LaTeX.
+%    \begin{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+  \catcode13=5 % ^^M
+  \endlinechar=13 %
+  \catcode35=6 % #
+  \catcode39=12 % '
+  \catcode44=12 % ,
+  \catcode45=12 % -
+  \catcode46=12 % .
+  \catcode58=12 % :
+  \catcode64=11 % @
+  \catcode123=1 % {
+  \catcode125=2 % }
+  \expandafter\let\expandafter\x\csname ver at pdftexcmds.sty\endcsname
+  \ifx\x\relax % plain-TeX, first loading
+  \else
+    \def\empty{}%
+    \ifx\x\empty % LaTeX, first loading,
+      % variable is initialized, but \ProvidesPackage not yet seen
+    \else
+      \expandafter\ifx\csname PackageInfo\endcsname\relax
+        \def\x#1#2{%
+          \immediate\write-1{Package #1 Info: #2.}%
+        }%
+      \else
+        \def\x#1#2{\PackageInfo{#1}{#2, stopped}}%
+      \fi
+      \x{pdftexcmds}{The package is already loaded}%
+      \aftergroup\endinput
+    \fi
+  \fi
+\endgroup%
+%    \end{macrocode}
+%    Package identification:
+%    \begin{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+  \catcode13=5 % ^^M
+  \endlinechar=13 %
+  \catcode35=6 % #
+  \catcode39=12 % '
+  \catcode40=12 % (
+  \catcode41=12 % )
+  \catcode44=12 % ,
+  \catcode45=12 % -
+  \catcode46=12 % .
+  \catcode47=12 % /
+  \catcode58=12 % :
+  \catcode64=11 % @
+  \catcode91=12 % [
+  \catcode93=12 % ]
+  \catcode123=1 % {
+  \catcode125=2 % }
+  \expandafter\ifx\csname ProvidesPackage\endcsname\relax
+    \def\x#1#2#3[#4]{\endgroup
+      \immediate\write-1{Package: #3 #4}%
+      \xdef#1{#4}%
+    }%
+  \else
+    \def\x#1#2[#3]{\endgroup
+      #2[{#3}]%
+      \ifx#1\@undefined
+        \xdef#1{#3}%
+      \fi
+      \ifx#1\relax
+        \xdef#1{#3}%
+      \fi
+    }%
+  \fi
+\expandafter\x\csname ver at pdftexcmds.sty\endcsname
+\ProvidesPackage{pdftexcmds}%
+  [2019/11/24 v0.31 Utility functions of pdfTeX for LuaTeX (HO)]%
+%    \end{macrocode}
+%
+% \subsection{Catcodes}
+%
+%    \begin{macrocode}
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+  \catcode13=5 % ^^M
+  \endlinechar=13 %
+  \catcode123=1 % {
+  \catcode125=2 % }
+  \catcode64=11 % @
+  \def\x{\endgroup
+    \expandafter\edef\csname pdftexcmds at AtEnd\endcsname{%
+      \endlinechar=\the\endlinechar\relax
+      \catcode13=\the\catcode13\relax
+      \catcode32=\the\catcode32\relax
+      \catcode35=\the\catcode35\relax
+      \catcode61=\the\catcode61\relax
+      \catcode64=\the\catcode64\relax
+      \catcode123=\the\catcode123\relax
+      \catcode125=\the\catcode125\relax
+    }%
+  }%
+\x\catcode61\catcode48\catcode32=10\relax%
+\catcode13=5 % ^^M
+\endlinechar=13 %
+\catcode35=6 % #
+\catcode64=11 % @
+\catcode123=1 % {
+\catcode125=2 % }
+\def\TMP at EnsureCode#1#2{%
+  \edef\pdftexcmds at AtEnd{%
+    \pdftexcmds at AtEnd
+    \catcode#1=\the\catcode#1\relax
+  }%
+  \catcode#1=#2\relax
+}
+\TMP at EnsureCode{0}{12}%
+\TMP at EnsureCode{1}{12}%
+\TMP at EnsureCode{2}{12}%
+\TMP at EnsureCode{10}{12}% ^^J
+\TMP at EnsureCode{33}{12}% !
+\TMP at EnsureCode{34}{12}% "
+\TMP at EnsureCode{38}{4}% &
+\TMP at EnsureCode{39}{12}% '
+\TMP at EnsureCode{40}{12}% (
+\TMP at EnsureCode{41}{12}% )
+\TMP at EnsureCode{42}{12}% *
+\TMP at EnsureCode{43}{12}% +
+\TMP at EnsureCode{44}{12}% ,
+\TMP at EnsureCode{45}{12}% -
+\TMP at EnsureCode{46}{12}% .
+\TMP at EnsureCode{47}{12}% /
+\TMP at EnsureCode{58}{12}% :
+\TMP at EnsureCode{60}{12}% <
+\TMP at EnsureCode{62}{12}% >
+\TMP at EnsureCode{91}{12}% [
+\TMP at EnsureCode{93}{12}% ]
+\TMP at EnsureCode{94}{7}% ^ (superscript)
+\TMP at EnsureCode{95}{12}% _ (other)
+\TMP at EnsureCode{96}{12}% `
+\TMP at EnsureCode{126}{12}% ~ (other)
+\edef\pdftexcmds at AtEnd{%
+  \pdftexcmds at AtEnd
+  \escapechar=\number\escapechar\relax
+  \noexpand\endinput
+}
+\escapechar=92 %
+%    \end{macrocode}
+%
+% \subsection{Load packages}
+%
+%    \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+  \def\TMP at RequirePackage#1[#2]{%
+    \begingroup\expandafter\expandafter\expandafter\endgroup
+    \expandafter\ifx\csname ver@#1.sty\endcsname\relax
+      \input #1.sty\relax
+    \fi
+  }%
+  \TMP at RequirePackage{infwarerr}[2007/09/09]%
+  \TMP at RequirePackage{iftex}[2019/11/07]%%
+  \TMP at RequirePackage{ltxcmds}[2010/12/02]%
+\else
+  \RequirePackage{infwarerr}[2007/09/09]%
+  \RequirePackage{iftex}[2019/11/07]%
+  \RequirePackage{ltxcmds}[2010/12/02]%
+\fi
+%    \end{macrocode}
+%
+% \subsection{Without \hologo{LuaTeX}}
+%
+%    \begin{macrocode}
+\ifluatex
+\else
+  \def\pdftexcmds at nopdftex{%
+    \let\pdftexcmds at nopdftex\relax
+  }%
+  \def\pdftexcmds at temp#1{%
+    \begingroup\expandafter\expandafter\expandafter\endgroup
+    \expandafter\ifx\csname
+         \expandafter\ifx\csname pdf#1\endcsname\relax\else pdf\fi#1\endcsname\relax
+      \pdftexcmds at nopdftex
+    \else
+      \expandafter\def\csname pdf@#1\expandafter\endcsname
+        \expandafter{%
+        \csname\expandafter\ifx\csname pdf#1\endcsname\relax\else pdf\fi#1\endcsname
+      }%
+    \fi
+  }%
+  \pdftexcmds at temp{strcmp}%
+  \pdftexcmds at temp{escapehex}%
+  \let\pdf at escapehexnative\pdf at escapehex
+  \pdftexcmds at temp{unescapehex}%
+  \let\pdf at unescapehexnative\pdf at unescapehex
+  \pdftexcmds at temp{escapestring}%
+  \pdftexcmds at temp{escapename}%
+  \pdftexcmds at temp{filesize}%
+  \pdftexcmds at temp{filemoddate}%
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdfshellescape\endcsname\relax
+    \pdftexcmds at nopdftex
+    \ltx at IfUndefined{pdftexversion}{%
+    }{%
+      \ifnum\pdftexversion>120 % 1.21a supports \ifeof18
+        \ifeof18 %
+          \chardef\pdf at shellescape=0 %
+        \else
+          \chardef\pdf at shellescape=1 %
+        \fi
+      \fi
+    }%
+  \else
+    \def\pdf at shellescape{%
+      \pdfshellescape
+    }%
+  \fi
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdffiledump\endcsname\relax
+    \pdftexcmds at nopdftex
+  \else
+    \def\pdf at filedump#1#2#3{%
+      \pdffiledump offset#1 length#2{#3}%
+    }%
+  \fi
+%    \end{macrocode}
+%    \begin{macrocode}
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdfmdfivesum\endcsname\relax
+    \begingroup\expandafter\expandafter\expandafter\endgroup
+    \expandafter\ifx\csname mdfivesum\endcsname\relax
+      \pdftexcmds at nopdftex
+    \else
+      \def\pdf at mdfivesum#{\mdfivesum}%
+      \let\pdf at mdfivesumnative\pdf at mdfivesum
+      \def\pdf at filemdfivesum#{\mdfivesum file}%
+    \fi
+  \else
+    \def\pdf at mdfivesum#{\pdfmdfivesum}%
+    \let\pdf at mdfivesumnative\pdf at mdfivesum
+    \def\pdf at filemdfivesum#{\pdfmdfivesum file}%
+  \fi
+%    \end{macrocode}
+%    \begin{macrocode}
+  \def\pdf at system#{%
+    \immediate\write18%
+  }%
+  \def\pdftexcmds at temp#1{%
+    \begingroup\expandafter\expandafter\expandafter\endgroup
+    \expandafter\ifx\csname
+         \expandafter\ifx\csname pdf#1\endcsname\relax\else pdf\fi#1\endcsname\relax
+      \pdftexcmds at nopdftex
+    \else
+      \expandafter\let\csname pdf@#1\expandafter\endcsname
+      \csname\expandafter\ifx\csname pdf#1\endcsname\relax\else pdf\fi#1\endcsname
+    \fi
+  }%
+  \pdftexcmds at temp{resettimer}%
+  \pdftexcmds at temp{elapsedtime}%
+\fi
+%    \end{macrocode}
+%
+% \subsection{\cs{pdf at primitive}, \cs{pdf at ifprimitive}}
+%
+%    Since version 1.40.0 \hologo{pdfTeX} has \cs{pdfprimitive} and
+%    \cs{ifpdfprimitive}. And \cs{pdfprimitive} was fixed in
+%    version 1.40.4.
+%
+%    \hologo{XeTeX} provides them under the name \cs{primitive} and
+%    \cs{ifprimitive}. \hologo{LuaTeX} knows both name variants,
+%    but they have possibly to be enabled first (|tex.enableprimitives|).
+%
+%    Depending on the format TeX Live uses a prefix |luatex|.
+%
+%    Caution: \cs{let} must be used for the definition of
+%    the macros, especially because of \cs{ifpdfprimitive}.
+%
+% \subsubsection{Using \hologo{LuaTeX}'s \texttt{tex.enableprimitives}}
+%
+%    \begin{macrocode}
+\ifluatex
+%    \end{macrocode}
+%    \begin{macro}{\pdftexcmds at directlua}
+%    \begin{macrocode}
+  \ifnum\luatexversion<36 %
+    \def\pdftexcmds at directlua{\directlua0 }%
+  \else
+    \let\pdftexcmds at directlua\directlua
+  \fi
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macrocode}
+  \begingroup
+    \newlinechar=10 %
+    \endlinechar=\newlinechar
+    \pdftexcmds at directlua{%
+      if tex.enableprimitives then
+        tex.enableprimitives(
+          'pdf@',
+          {'primitive', 'ifprimitive', 'pdfdraftmode','draftmode'}
+        )
+        tex.enableprimitives('', {'luaescapestring'})
+      end
+    }%
+  \endgroup %
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\fi
+%    \end{macrocode}
+%
+% \subsubsection{Trying various names to find the primitives}
+%
+%    \begin{macro}{\pdftexcmds at strip@prefix}
+%    \begin{macrocode}
+\def\pdftexcmds at strip@prefix#1>{}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macrocode}
+\def\pdftexcmds at temp#1#2#3{%
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdf@#1\endcsname\relax
+    \begingroup
+      \def\x{#3}%
+      \edef\x{\expandafter\pdftexcmds at strip@prefix\meaning\x}%
+      \escapechar=-1 %
+      \edef\y{\expandafter\meaning\csname#2\endcsname}%
+    \expandafter\endgroup
+    \ifx\x\y
+      \expandafter\let\csname pdf@#1\expandafter\endcsname
+      \csname #2\endcsname
+    \fi
+  \fi
+}
+%    \end{macrocode}
+%
+%    \begin{macro}{\pdf at primitive}
+%    \begin{macrocode}
+\pdftexcmds at temp{primitive}{pdfprimitive}{pdfprimitive}% pdfTeX, oldLuaTeX
+\pdftexcmds at temp{primitive}{primitive}{primitive}% XeTeX, luatex
+\pdftexcmds at temp{primitive}{luatexprimitive}{pdfprimitive}% oldLuaTeX
+\pdftexcmds at temp{primitive}{luatexpdfprimitive}{pdfprimitive}% oldLuaTeX
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at ifprimitive}
+%    \begin{macrocode}
+\pdftexcmds at temp{ifprimitive}{ifpdfprimitive}{ifpdfprimitive}% pdfTeX, oldLuaTeX
+\pdftexcmds at temp{ifprimitive}{ifprimitive}{ifprimitive}% XeTeX, luatex
+\pdftexcmds at temp{ifprimitive}{luatexifprimitive}{ifpdfprimitive}% oldLuaTeX
+\pdftexcmds at temp{ifprimitive}{luatexifpdfprimitive}{ifpdfprimitive}% oldLuaTeX
+%    \end{macrocode}
+%    \end{macro}
+%
+%    Disable broken \cs{pdfprimitive}.
+%    \begin{macrocode}
+\ifluatex\else
+\begingroup
+  \expandafter\ifx\csname pdf at primitive\endcsname\relax
+  \else
+    \expandafter\ifx\csname pdftexversion\endcsname\relax
+    \else
+      \ifnum\pdftexversion=140 %
+        \expandafter\ifx\csname pdftexrevision\endcsname\relax
+        \else
+          \ifnum\pdftexrevision<4 %
+            \endgroup
+            \let\pdf at primitive\@undefined
+            \@PackageInfoNoLine{pdftexcmds}{%
+              \string\pdf at primitive\space disabled, %
+              because\MessageBreak
+              \string\pdfprimitive\space is broken until pdfTeX 1.40.4%
+            }%
+            \begingroup
+          \fi
+        \fi
+      \fi
+    \fi
+  \fi
+\endgroup
+\fi
+%    \end{macrocode}
+%
+% \subsubsection{Result}
+%
+%    \begin{macrocode}
+\begingroup
+  \@PackageInfoNoLine{pdftexcmds}{%
+    \string\pdf at primitive\space is %
+    \expandafter\ifx\csname pdf at primitive\endcsname\relax not \fi
+    available%
+  }%
+  \@PackageInfoNoLine{pdftexcmds}{%
+    \string\pdf at ifprimitive\space is %
+    \expandafter\ifx\csname pdf at ifprimitive\endcsname\relax not \fi
+    available%
+  }%
+\endgroup
+%    \end{macrocode}
+%
+% \subsection{\hologo{XeTeX}}
+%
+%    Look for primitives \cs{shellescape}, \cs{strcmp}.
+%    \begin{macrocode}
+\def\pdftexcmds at temp#1{%
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdf@#1\endcsname\relax
+    \begingroup
+      \escapechar=-1 %
+      \edef\x{\expandafter\meaning\csname#1\endcsname}%
+      \def\y{#1}%
+      \def\z##1->{}%
+      \edef\y{\expandafter\z\meaning\y}%
+    \expandafter\endgroup
+    \ifx\x\y
+      \expandafter\def\csname pdf@#1\expandafter\endcsname
+      \expandafter{%
+        \csname#1\endcsname
+      }%
+    \fi
+  \fi
+}%
+\pdftexcmds at temp{shellescape}%
+\pdftexcmds at temp{strcmp}%
+%    \end{macrocode}
+%
+% \subsection{\cs{pdf at isprimitive}}
+%
+%    \begin{macrocode}
+\def\pdf at isprimitive{%
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdf at strcmp\endcsname\relax
+    \long\def\pdf at isprimitive##1{%
+      \expandafter\pdftexcmds at isprimitive\expandafter{\meaning##1}%
+    }%
+    \long\def\pdftexcmds at isprimitive##1##2{%
+      \expandafter\pdftexcmds@@isprimitive\expandafter{\string##2}{##1}%
+    }%
+    \def\pdftexcmds@@isprimitive##1##2{%
+      \ifnum0\pdftexcmds at equal##1\delimiter##2\delimiter=1 %
+        \expandafter\ltx at firstoftwo
+      \else
+        \expandafter\ltx at secondoftwo
+      \fi
+    }%
+    \def\pdftexcmds at equal##1##2\delimiter##3##4\delimiter{%
+      \ifx##1##3%
+        \ifx\relax##2##4\relax
+          1%
+        \else
+          \ifx\relax##2\relax
+          \else
+            \ifx\relax##4\relax
+            \else
+              \pdftexcmds at equalcont{##2}{##4}%
+            \fi
+          \fi
+        \fi
+      \fi
+    }%
+    \def\pdftexcmds at equalcont##1{%
+      \def\pdftexcmds at equalcont####1####2##1##1##1##1{%
+        ##1##1##1##1%
+        \pdftexcmds at equal####1\delimiter####2\delimiter
+      }%
+    }%
+    \expandafter\pdftexcmds at equalcont\csname fi\endcsname
+  \else
+    \long\def\pdf at isprimitive##1##2{%
+      \ifnum\pdf at strcmp{\meaning##1}{\string##2}=0 %
+        \expandafter\ltx at firstoftwo
+      \else
+        \expandafter\ltx at secondoftwo
+      \fi
+    }%
+  \fi
+}
+\ifluatex
+\ifx\pdfdraftmode\@undefined
+  \let\pdfdraftmode\draftmode
+\fi
+\else
+  \pdf at isprimitive
+\fi
+%    \end{macrocode}
+%
+% \subsection{\cs{pdf at draftmode}}
+%
+%
+%    \begin{macrocode}
+\let\pdftexcmds at temp\ltx at zero %
+\ltx at IfUndefined{pdfdraftmode}{%
+  \@PackageInfoNoLine{pdftexcmds}{\ltx at backslashchar pdfdraftmode not found}%
+}{%
+  \ifpdf
+    \let\pdftexcmds at temp\ltx at one
+    \@PackageInfoNoLine{pdftexcmds}{\ltx at backslashchar pdfdraftmode found}%
+  \else
+    \@PackageInfoNoLine{pdftexcmds}{%
+      \ltx at backslashchar pdfdraftmode is ignored in DVI mode%
+    }%
+  \fi
+}
+\ifcase\pdftexcmds at temp
+%    \end{macrocode}
+%    \begin{macro}{\pdf at draftmode}
+%    \begin{macrocode}
+  \let\pdf at draftmode\ltx at zero
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at ifdraftmode}
+%    \begin{macrocode}
+  \let\pdf at ifdraftmode\ltx at secondoftwo
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdftexcmds at setdraftmode}
+%    \begin{macrocode}
+  \def\pdftexcmds at setdraftmode#1{}%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macrocode}
+\else
+%    \end{macrocode}
+%    \begin{macro}{\pdftexcmds at draftmode}
+%    \begin{macrocode}
+  \let\pdftexcmds at draftmode\pdfdraftmode
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at ifdraftmode}
+%    \begin{macrocode}
+  \def\pdf at ifdraftmode{%
+    \ifnum\pdftexcmds at draftmode=\ltx at one
+      \expandafter\ltx at firstoftwo
+    \else
+      \expandafter\ltx at secondoftwo
+    \fi
+  }%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at draftmode}
+%    \begin{macrocode}
+  \def\pdf at draftmode{%
+    \ifnum\pdftexcmds at draftmode=\ltx at one
+      \expandafter\ltx at one
+    \else
+      \expandafter\ltx at zero
+    \fi
+  }%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdftexcmds at setdraftmode}
+%    \begin{macrocode}
+  \def\pdftexcmds at setdraftmode#1{%
+    \pdftexcmds at draftmode=#1\relax
+  }%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macrocode}
+\fi
+%    \end{macrocode}
+%    \begin{macro}{\pdf at setdraftmode}
+%    \begin{macrocode}
+\def\pdf at setdraftmode#1{%
+  \begingroup
+    \count\ltx at cclv=#1\relax
+  \edef\x{\endgroup
+    \noexpand\pdftexcmds@@setdraftmode{\the\count\ltx at cclv}%
+  }%
+  \x
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdftexcmds@@setdraftmode}
+%    \begin{macrocode}
+\def\pdftexcmds@@setdraftmode#1{%
+  \ifcase#1 %
+    \pdftexcmds at setdraftmode{#1}%
+  \or
+    \pdftexcmds at setdraftmode{#1}%
+  \else
+    \@PackageWarning{pdftexcmds}{%
+      \string\pdf at setdraftmode: Ignoring\MessageBreak
+      invalid value `#1'%
+    }%
+  \fi
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+% \subsection{Load Lua module}
+%
+%    \begin{macrocode}
+\ifluatex
+\else
+  \expandafter\pdftexcmds at AtEnd
+\fi%
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\pdftexcmds at directlua{%
+  require("pdftexcmds")%
+}
+\ifnum\luatexversion>37 %
+  \ifnum0%
+      \pdftexcmds at directlua{%
+        if status.ini_version then %
+          tex.write("1")%
+        end%
+      }>0 %
+    \everyjob\expandafter{%
+      \the\everyjob
+      \pdftexcmds at directlua{%
+        require("pdftexcmds")%
+      }%
+    }%
+  \fi
+\fi
+\begingroup
+  \def\x{2019/11/24 v0.31}%
+  \ltx at onelevel@sanitize\x
+  \edef\y{%
+    \pdftexcmds at directlua{%
+      if oberdiek.pdftexcmds.getversion then %
+        oberdiek.pdftexcmds.getversion()%
+      end%
+    }%
+  }%
+  \ifx\x\y
+  \else
+    \@PackageError{pdftexcmds}{%
+      Wrong version of lua module.\MessageBreak
+      Package version: \x\MessageBreak
+      Lua module: \y
+    }\@ehc
+  \fi
+\endgroup
+%    \end{macrocode}
+%
+% \subsection{Lua functions}
+%
+% \subsubsection{Helper macros}
+%
+%    \begin{macro}{\pdftexcmds at toks}
+%    \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname newtoks\endcsname\relax
+  \toksdef\pdftexcmds at toks=0 %
+\else
+  \csname newtoks\endcsname\pdftexcmds at toks
+\fi
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\pdftexcmds at Patch}
+%    \begin{macrocode}
+\def\pdftexcmds at Patch{0}
+\ifnum\luatexversion>40 %
+  \ifnum\luatexversion<66 %
+    \def\pdftexcmds at Patch{1}%
+  \fi
+\fi
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macrocode}
+\ifcase\pdftexcmds at Patch
+  \catcode`\&=14 %
+\else
+  \catcode`\&=9 %
+%    \end{macrocode}
+%    \begin{macro}{\pdftexcmds at PatchDecode}
+%    \begin{macrocode}
+  \def\pdftexcmds at PatchDecode#1\@nil{%
+    \pdftexcmds at DecodeA#1^^A^^A\@nil{}%
+  }%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdftexcmds at DecodeA}
+%    \begin{macrocode}
+  \def\pdftexcmds at DecodeA#1^^A^^A#2\@nil#3{%
+    \ifx\relax#2\relax
+      \ltx at ReturnAfterElseFi{%
+        \pdftexcmds at DecodeB#3#1^^A^^B\@nil{}%
+      }%
+    \else
+      \ltx at ReturnAfterFi{%
+        \pdftexcmds at DecodeA#2\@nil{#3#1^^@}%
+      }%
+    \fi
+  }%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdftexcmds at DecodeB}
+%    \begin{macrocode}
+  \def\pdftexcmds at DecodeB#1^^A^^B#2\@nil#3{%
+    \ifx\relax#2\relax%
+      \ltx at ReturnAfterElseFi{%
+        \ltx at zero
+        #3#1%
+      }%
+    \else
+      \ltx at ReturnAfterFi{%
+        \pdftexcmds at DecodeB#2\@nil{#3#1^^A}%
+      }%
+    \fi
+  }%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macrocode}
+\fi
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\ifnum\luatexversion<36 %
+\else
+  \catcode`\0=9 %
+\fi
+%    \end{macrocode}
+%
+% \subsubsection[Strings]{Strings \cite[``7.15 Strings'']{pdftex-manual}}
+%
+%    \begin{macro}{\pdf at strcmp}
+%    \begin{macrocode}
+\long\def\pdf at strcmp#1#2{%
+  \directlua0{%
+    oberdiek.pdftexcmds.strcmp("\luaescapestring{#1}",%
+        "\luaescapestring{#2}")%
+  }%
+}%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macrocode}
+\pdf at isprimitive
+%    \end{macrocode}
+%    \begin{macro}{\pdf at escapehex}
+%    \begin{macrocode}
+\long\def\pdf at escapehex#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.escapehex("\luaescapestring{#1}", "byte")%
+  }%
+}%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at escapehexnative}
+%    \begin{macrocode}
+\long\def\pdf at escapehexnative#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.escapehex("\luaescapestring{#1}")%
+  }%
+}%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at unescapehex}
+%    \begin{macrocode}
+\def\pdf at unescapehex#1{%
+& \romannumeral\expandafter\pdftexcmds at PatchDecode
+  \the\expandafter\pdftexcmds at toks
+  \directlua0{%
+    oberdiek.pdftexcmds.toks="pdftexcmds at toks"%
+    oberdiek.pdftexcmds.unescapehex("\luaescapestring{#1}", "byte", \pdftexcmds at Patch)%
+  }%
+& \@nil
+}%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at unescapehexnative}
+%    \begin{macrocode}
+\def\pdf at unescapehexnative#1{%
+& \romannumeral\expandafter\pdftexcmds at PatchDecode
+  \the\expandafter\pdftexcmds at toks
+  \directlua0{%
+    oberdiek.pdftexcmds.toks="pdftexcmds at toks"%
+    oberdiek.pdftexcmds.unescapehex("\luaescapestring{#1}", \pdftexcmds at Patch)%
+  }%
+& \@nil
+}%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at escapestring}
+%    \begin{macrocode}
+\long\def\pdf at escapestring#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.escapestring("\luaescapestring{#1}")%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at escapename}
+%    \begin{macrocode}
+\long\def\pdf at escapename#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.escapename("\luaescapestring{#1}", "byte")%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at escapenamenative}
+%    \begin{macrocode}
+\long\def\pdf at escapenamenative#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.escapename("\luaescapestring{#1}")%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+% \subsubsection[Files]{Files \cite[``7.18 Files'']{pdftex-manual}}
+%
+%    \begin{macro}{\pdf at filesize}
+%    \begin{macrocode}
+\def\pdf at filesize#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.filesize("\luaescapestring{#1}")%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at filemoddate}
+%    \begin{macrocode}
+\def\pdf at filemoddate#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.filemoddate("\luaescapestring{#1}")%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at filedump}
+%    \begin{macrocode}
+\def\pdf at filedump#1#2#3{%
+  \directlua0{%
+    oberdiek.pdftexcmds.filedump("\luaescapestring{\number#1}",%
+        "\luaescapestring{\number#2}",%
+        "\luaescapestring{#3}")%
+  }%
+}%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at mdfivesum}
+%    \begin{macrocode}
+\long\def\pdf at mdfivesum#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.mdfivesum("\luaescapestring{#1}", "byte")%
+  }%
+}%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at mdfivesumnative}
+%    \begin{macrocode}
+\long\def\pdf at mdfivesumnative#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.mdfivesum("\luaescapestring{#1}")%
+  }%
+}%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at filemdfivesum}
+%    \begin{macrocode}
+\def\pdf at filemdfivesum#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.filemdfivesum("\luaescapestring{#1}")%
+  }%
+}%
+%    \end{macrocode}
+%    \end{macro}
+%
+% \subsubsection[Timekeeping]{Timekeeping \cite[``7.17 Timekeeping'']{pdftex-manual}}
+%
+%    \begin{macro}{\protected}
+%    \begin{macrocode}
+\let\pdftexcmds at temp=Y%
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname protected\endcsname\relax
+  \pdftexcmds at directlua0{%
+    if tex.enableprimitives then %
+      tex.enableprimitives('', {'protected'})%
+    end%
+  }%
+\fi
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname protected\endcsname\relax
+  \let\pdftexcmds at temp=N%
+\fi
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\numexpr}
+%    \begin{macrocode}
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname numexpr\endcsname\relax
+  \pdftexcmds at directlua0{%
+    if tex.enableprimitives then %
+      tex.enableprimitives('', {'numexpr'})%
+    end%
+  }%
+\fi
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname numexpr\endcsname\relax
+  \let\pdftexcmds at temp=N%
+\fi
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macrocode}
+\ifx\pdftexcmds at temp N%
+  \@PackageWarningNoLine{pdftexcmds}{%
+    Definitions of \ltx at backslashchar pdf at resettimer and%
+    \MessageBreak
+    \ltx at backslashchar pdf at elapsedtime are skipped, because%
+    \MessageBreak
+    e-TeX's \ltx at backslashchar protected or %
+    \ltx at backslashchar numexpr are missing%
+  }%
+\else
+%    \end{macrocode}
+%
+%    \begin{macro}{\pdf at resettimer}
+%    \begin{macrocode}
+  \protected\def\pdf at resettimer{%
+    \pdftexcmds at directlua0{%
+      oberdiek.pdftexcmds.resettimer()%
+    }%
+  }%
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\pdf at elapsedtime}
+%    \begin{macrocode}
+  \protected\def\pdf at elapsedtime{%
+    \numexpr
+      \pdftexcmds at directlua0{%
+        oberdiek.pdftexcmds.elapsedtime()%
+      }%
+    \relax
+  }%
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macrocode}
+\fi
+%    \end{macrocode}
+%
+% \subsubsection{Shell escape}
+%
+%    \begin{macro}{\pdf at shellescape}
+%
+%    \begin{macrocode}
+\ifnum\luatexversion<68 %
+\else
+  \protected\edef\pdf at shellescape{%
+   \numexpr\directlua{tex.sprint(%
+         \number\catcodetable at string,status.shell_escape)}\relax}
+\fi
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\pdf at system}
+%    \begin{macrocode}
+\def\pdf at system#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.system("\luaescapestring{#1}")%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macro}{\pdf at lastsystemstatus}
+%    \begin{macrocode}
+\def\pdf at lastsystemstatus{%
+  \directlua0{%
+    oberdiek.pdftexcmds.lastsystemstatus()%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%    \begin{macro}{\pdf at lastsystemexit}
+%    \begin{macrocode}
+\def\pdf at lastsystemexit{%
+  \directlua0{%
+    oberdiek.pdftexcmds.lastsystemexit()%
+  }%
+}
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macrocode}
+\catcode`\0=12 %
+%    \end{macrocode}
+%
+%    \begin{macro}{\pdf at pipe}
+%    Check availability of |io.popen| first.
+%    \begin{macrocode}
+\ifnum0%
+    \pdftexcmds at directlua{%
+      if io.popen then %
+        tex.write("1")%
+      end%
+    }%
+    =1 %
+  \def\pdf at pipe#1{%
+&   \romannumeral\expandafter\pdftexcmds at PatchDecode
+    \the\expandafter\pdftexcmds at toks
+    \pdftexcmds at directlua{%
+      oberdiek.pdftexcmds.toks="pdftexcmds at toks"%
+      oberdiek.pdftexcmds.pipe("\luaescapestring{#1}", \pdftexcmds at Patch)%
+    }%
+&   \@nil
+  }%
+\fi
+%    \end{macrocode}
+%    \end{macro}
+%
+%    \begin{macrocode}
+\pdftexcmds at AtEnd%
+%</package>
+%    \end{macrocode}
+%
+% \subsection{Lua module}
+%
+%    \begin{macrocode}
+%<*lua>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+oberdiek = oberdiek or {}
+local pdftexcmds = oberdiek.pdftexcmds or {}
+oberdiek.pdftexcmds = pdftexcmds
+local systemexitstatus
+function pdftexcmds.getversion()
+  tex.write("2019/11/24 v0.31")
+end
+%    \end{macrocode}
+%
+% \subsubsection[Strings]{Strings \cite[``7.15 Strings'']{pdftex-manual}}
+%
+%    \begin{macrocode}
+function pdftexcmds.strcmp(A, B)
+  if A == B then
+    tex.write("0")
+  elseif A < B then
+    tex.write("-1")
+  else
+    tex.write("1")
+  end
+end
+local function utf8_to_byte(str)
+  local i = 0
+  local n = string.len(str)
+  local t = {}
+  while i < n do
+    i = i + 1
+    local a = string.byte(str, i)
+    if a < 128 then
+      table.insert(t, string.char(a))
+    else
+      if a >= 192 and i < n then
+        i = i + 1
+        local b = string.byte(str, i)
+        if b < 128 or b >= 192 then
+          i = i - 1
+        elseif a == 194 then
+          table.insert(t, string.char(b))
+        elseif a == 195 then
+          table.insert(t, string.char(b + 64))
+        end
+      end
+    end
+  end
+  return table.concat(t)
+end
+function pdftexcmds.escapehex(str, mode)
+  if mode == "byte" then
+    str = utf8_to_byte(str)
+  end
+  tex.write((string.gsub(str, ".",
+    function (ch)
+      return string.format("%02X", string.byte(ch))
+    end
+  )))
+end
+%    \end{macrocode}
+%    See procedure |unescapehex| in file \xfile{utils.c} of \hologo{pdfTeX}.
+%    Caution: |tex.write| ignores leading spaces.
+%    \begin{macrocode}
+function pdftexcmds.unescapehex(str, mode, patch)
+  local a = 0
+  local first = true
+  local result = {}
+  for i = 1, string.len(str), 1 do
+    local ch = string.byte(str, i)
+    if ch >= 48 and ch <= 57 then
+      ch = ch - 48
+    elseif ch >= 65 and ch <= 70 then
+      ch = ch - 55
+    elseif ch >= 97 and ch <= 102 then
+      ch = ch - 87
+    else
+      ch = nil
+    end
+    if ch then
+      if first then
+        a = ch * 16
+        first = false
+      else
+        table.insert(result, a + ch)
+        first = true
+      end
+    end
+  end
+  if not first then
+    table.insert(result, a)
+  end
+  if patch == 1 then
+    local temp = {}
+    for i, a in ipairs(result) do
+      if a == 0 then
+        table.insert(temp, 1)
+        table.insert(temp, 1)
+      else
+        if a == 1 then
+          table.insert(temp, 1)
+          table.insert(temp, 2)
+        else
+          table.insert(temp, a)
+        end
+      end
+    end
+    result = temp
+  end
+  if mode == "byte" then
+    local utf8 = {}
+    for i, a in ipairs(result) do
+      if a < 128 then
+        table.insert(utf8, a)
+      else
+        if a < 192 then
+          table.insert(utf8, 194)
+          a = a - 128
+        else
+          table.insert(utf8, 195)
+          a = a - 192
+        end
+        table.insert(utf8, a + 128)
+      end
+    end
+    result = utf8
+  end
+%    \end{macrocode}
+%    this next line added for current luatex; this is the only
+%    change in the file.  eroux, 28apr13. (v 0.21)
+%    \begin{macrocode}
+  local unpack = _G["unpack"] or table.unpack
+  tex.settoks(pdftexcmds.toks, string.char(unpack(result)))
+end
+%    \end{macrocode}
+%    See procedure |escapestring| in file \xfile{utils.c} of \hologo{pdfTeX}.
+%    \begin{macrocode}
+function pdftexcmds.escapestring(str, mode)
+  if mode == "byte" then
+    str = utf8_to_byte(str)
+  end
+  tex.write((string.gsub(str, ".",
+    function (ch)
+      local b = string.byte(ch)
+      if b < 33 or b > 126 then
+        return string.format("\\%.3o", b)
+      end
+      if b == 40 or b == 41 or b == 92 then
+        return "\\" .. ch
+      end
+%    \end{macrocode}
+%    Lua 5.1 returns the match in case of return value |nil|.
+%    \begin{macrocode}
+      return nil
+    end
+  )))
+end
+%    \end{macrocode}
+%    See procedure |escapename| in file \xfile{utils.c} of \hologo{pdfTeX}.
+%    \begin{macrocode}
+function pdftexcmds.escapename(str, mode)
+  if mode == "byte" then
+    str = utf8_to_byte(str)
+  end
+  tex.write((string.gsub(str, ".",
+    function (ch)
+      local b = string.byte(ch)
+      if b == 0 then
+%    \end{macrocode}
+%    In Lua 5.0 |nil| could be used for the empty string,
+%    But |nil| returns the match in Lua 5.1, thus we use
+%    the empty string explicitly.
+%    \begin{macrocode}
+        return ""
+      end
+      if b <= 32 or b >= 127
+          or b == 35 or b == 37 or b == 40 or b == 41
+          or b == 47 or b == 60 or b == 62 or b == 91
+          or b == 93 or b == 123 or b == 125 then
+        return string.format("#%.2X", b)
+      else
+%    \end{macrocode}
+%    Lua 5.1 returns the match in case of return value |nil|.
+%    \begin{macrocode}
+        return nil
+      end
+    end
+  )))
+end
+%    \end{macrocode}
+%
+% \subsubsection[Files]{Files \cite[``7.18 Files'']{pdftex-manual}}
+%
+%    \begin{macrocode}
+function pdftexcmds.filesize(filename)
+  local foundfile = kpse.find_file(filename, "tex", true)
+  if foundfile then
+    local size = lfs.attributes(foundfile, "size")
+    if size then
+      tex.write(size)
+    end
+  end
+end
+%    \end{macrocode}
+%    See procedure |makepdftime| in file \xfile{utils.c} of \hologo{pdfTeX}.
+%    \begin{macrocode}
+function pdftexcmds.filemoddate(filename)
+  local foundfile = kpse.find_file(filename, "tex", true)
+  if foundfile then
+    local date = lfs.attributes(foundfile, "modification")
+    if date then
+      local d = os.date("*t", date)
+      if d.sec >= 60 then
+        d.sec = 59
+      end
+      local u = os.date("!*t", date)
+      local off = 60 * (d.hour - u.hour) + d.min - u.min
+      if d.year ~= u.year then
+        if d.year > u.year then
+          off = off + 1440
+        else
+          off = off - 1440
+        end
+      elseif d.yday ~= u.yday then
+        if d.yday > u.yday then
+          off = off + 1440
+        else
+          off = off - 1440
+        end
+      end
+      local timezone
+      if off == 0 then
+        timezone = "Z"
+      else
+        local hours = math.floor(off / 60)
+        local mins = math.abs(off - hours * 60)
+        timezone = string.format("%+03d'%02d'", hours, mins)
+      end
+      tex.write(string.format("D:%04d%02d%02d%02d%02d%02d%s",
+          d.year, d.month, d.day, d.hour, d.min, d.sec, timezone))
+    end
+  end
+end
+function pdftexcmds.filedump(offset, length, filename)
+  length = tonumber(length)
+  if length and length > 0 then
+    local foundfile = kpse.find_file(filename, "tex", true)
+    if foundfile then
+      offset = tonumber(offset)
+      if not offset then
+        offset = 0
+      end
+      local filehandle = io.open(foundfile, "rb")
+      if filehandle then
+        if offset > 0 then
+          filehandle:seek("set", offset)
+        end
+        local dump = filehandle:read(length)
+        pdftexcmds.escapehex(dump)
+        filehandle:close()
+      end
+    end
+  end
+end
+function pdftexcmds.mdfivesum(str, mode)
+  if mode == "byte" then
+    str = utf8_to_byte(str)
+  end
+  pdftexcmds.escapehex(md5.sum(str))
+end
+function pdftexcmds.filemdfivesum(filename)
+  local foundfile = kpse.find_file(filename, "tex", true)
+  if foundfile then
+    local filehandle = io.open(foundfile, "rb")
+    if filehandle then
+      local contents = filehandle:read("*a")
+      pdftexcmds.escapehex(md5.sum(contents))
+      filehandle:close()
+    end
+  end
+end
+%    \end{macrocode}
+%
+% \subsubsection[Timekeeping]{Timekeeping \cite[``7.17 Timekeeping'']{pdftex-manual}}
+%
+%    The functions for timekeeping are based on
+%    Andy Thomas' work \cite{AndyThomas:Analog}.
+%    Changes:
+%    \begin{itemize}
+%    \item Overflow check is added.
+%    \item |string.format| is used to avoid exponential number
+%          representation for sure.
+%    \item |tex.write| is used instead of |tex.print| to get
+%          tokens with catcode 12 and without appended \cs{endlinechar}.
+%    \end{itemize}
+%    \begin{macrocode}
+local basetime = 0
+function pdftexcmds.resettimer()
+  basetime = os.clock()
+end
+function pdftexcmds.elapsedtime()
+  local val = (os.clock() - basetime) * 65536 + .5
+  if val > 2147483647 then
+    val = 2147483647
+  end
+  tex.write(string.format("%d", val))
+end
+%    \end{macrocode}
+%
+% \subsubsection[Miscellaneous]{Miscellaneous \cite[``7.21 Miscellaneous'']{pdftex-manual}}
+%
+%    \begin{macrocode}
+function pdftexcmds.shellescape()
+  if os.execute then
+    if status
+        and status.luatex_version
+        and status.luatex_version >= 68 then
+      tex.write(os.execute())
+    else
+      local result = os.execute()
+      if result == 0 then
+        tex.write("0")
+      else
+        if result == nil then
+          tex.write("0")
+        else
+          tex.write("1")
+        end
+      end
+    end
+  else
+    tex.write("0")
+  end
+end
+function pdftexcmds.system(cmdline)
+  systemexitstatus = nil
+  texio.write_nl("log", "system(" .. cmdline .. ") ")
+  if os.execute then
+    texio.write("log", "executed.")
+    systemexitstatus = os.execute(cmdline)
+  else
+    texio.write("log", "disabled.")
+  end
+end
+function pdftexcmds.lastsystemstatus()
+  local result = tonumber(systemexitstatus)
+  if result then
+    local x = math.floor(result / 256)
+    tex.write(result - 256 * math.floor(result / 256))
+  end
+end
+function pdftexcmds.lastsystemexit()
+  local result = tonumber(systemexitstatus)
+  if result then
+    tex.write(math.floor(result / 256))
+  end
+end
+function pdftexcmds.pipe(cmdline, patch)
+  local result
+  systemexitstatus = nil
+  texio.write_nl("log", "pipe(" .. cmdline ..") ")
+  if io.popen then
+    texio.write("log", "executed.")
+    local handle = io.popen(cmdline, "r")
+    if handle then
+      result = handle:read("*a")
+      handle:close()
+    end
+  else
+    texio.write("log", "disabled.")
+  end
+  if result then
+    if patch == 1 then
+      local temp = {}
+      for i, a in ipairs(result) do
+        if a == 0 then
+          table.insert(temp, 1)
+          table.insert(temp, 1)
+        else
+          if a == 1 then
+            table.insert(temp, 1)
+            table.insert(temp, 2)
+          else
+            table.insert(temp, a)
+          end
+        end
+      end
+      result = temp
+    end
+    tex.settoks(pdftexcmds.toks, result)
+  else
+    tex.settoks(pdftexcmds.toks, "")
+  end
+end
+%    \end{macrocode}
+%    \begin{macrocode}
+%</lua>
+%    \end{macrocode}
+%
+% \section{Test}
+%
+% \subsection{Catcode checks for loading}
+%
+%    \begin{macrocode}
+%<*test1>
+%    \end{macrocode}
+%    \begin{macrocode}
+\catcode`\{=1 %
+\catcode`\}=2 %
+\catcode`\#=6 %
+\catcode`\@=11 %
+\expandafter\ifx\csname count@\endcsname\relax
+  \countdef\count@=255 %
+\fi
+\expandafter\ifx\csname @gobble\endcsname\relax
+  \long\def\@gobble#1{}%
+\fi
+\expandafter\ifx\csname @firstofone\endcsname\relax
+  \long\def\@firstofone#1{#1}%
+\fi
+\expandafter\ifx\csname loop\endcsname\relax
+  \expandafter\@firstofone
+\else
+  \expandafter\@gobble
+\fi
+{%
+  \def\loop#1\repeat{%
+    \def\body{#1}%
+    \iterate
+  }%
+  \def\iterate{%
+    \body
+      \let\next\iterate
+    \else
+      \let\next\relax
+    \fi
+    \next
+  }%
+  \let\repeat=\fi
+}%
+\def\RestoreCatcodes{}
+\count@=0 %
+\loop
+  \edef\RestoreCatcodes{%
+    \RestoreCatcodes
+    \catcode\the\count@=\the\catcode\count@\relax
+  }%
+\ifnum\count@<255 %
+  \advance\count@ 1 %
+\repeat
+
+\def\RangeCatcodeInvalid#1#2{%
+  \count@=#1\relax
+  \loop
+    \catcode\count@=15 %
+  \ifnum\count@<#2\relax
+    \advance\count@ 1 %
+  \repeat
+}
+\def\RangeCatcodeCheck#1#2#3{%
+  \count@=#1\relax
+  \loop
+    \ifnum#3=\catcode\count@
+    \else
+      \errmessage{%
+        Character \the\count@\space
+        with wrong catcode \the\catcode\count@\space
+        instead of \number#3%
+      }%
+    \fi
+  \ifnum\count@<#2\relax
+    \advance\count@ 1 %
+  \repeat
+}
+\def\space{ }
+\expandafter\ifx\csname LoadCommand\endcsname\relax
+  \def\LoadCommand{\input pdftexcmds.sty\relax}%
+\fi
+\def\Test{%
+  \RangeCatcodeInvalid{0}{47}%
+  \RangeCatcodeInvalid{58}{64}%
+  \RangeCatcodeInvalid{91}{96}%
+  \RangeCatcodeInvalid{123}{255}%
+  \catcode`\@=12 %
+  \catcode`\\=0 %
+  \catcode`\%=14 %
+  \LoadCommand
+  \RangeCatcodeCheck{0}{36}{15}%
+  \RangeCatcodeCheck{37}{37}{14}%
+  \RangeCatcodeCheck{38}{47}{15}%
+  \RangeCatcodeCheck{48}{57}{12}%
+  \RangeCatcodeCheck{58}{63}{15}%
+  \RangeCatcodeCheck{64}{64}{12}%
+  \RangeCatcodeCheck{65}{90}{11}%
+  \RangeCatcodeCheck{91}{91}{15}%
+  \RangeCatcodeCheck{92}{92}{0}%
+  \RangeCatcodeCheck{93}{96}{15}%
+  \RangeCatcodeCheck{97}{122}{11}%
+  \RangeCatcodeCheck{123}{255}{15}%
+  \RestoreCatcodes
+}
+\Test
+\csname @@end\endcsname
+\end
+%    \end{macrocode}
+%    \begin{macrocode}
+%</test1>
+%    \end{macrocode}
+%
+% \subsection{Test for \cs{pdf at isprimitive}}
+%
+%    \begin{macrocode}
+%<*test2>
+\catcode`\{=1 %
+\catcode`\}=2 %
+\catcode`\#=6 %
+\catcode`\@=11 %
+\input pdftexcmds.sty\relax
+\def\msg#1{%
+  \begingroup
+    \escapechar=92 %
+    \immediate\write16{#1}%
+  \endgroup
+}
+\long\def\test#1#2#3#4{%
+  \begingroup
+    #4%
+    \def\str{%
+      Test \string\pdf at isprimitive
+      {\string #1}{\string #2}{...}: %
+    }%
+    \pdf at isprimitive{#1}{#2}{%
+      \ifx#3Y%
+        \msg{\str true ==> OK.}%
+      \else
+        \errmessage{\str false ==> FAILED}%
+      \fi
+    }{%
+      \ifx#3Y%
+        \errmessage{\str true ==> FAILED}%
+      \else
+        \msg{\str false ==> OK.}%
+      \fi
+    }%
+  \endgroup
+}
+\test\relax\relax Y{}
+\test\foobar\relax Y{\let\foobar\relax}
+\test\foobar\relax N{}
+\test\hbox\hbox Y{}
+\test\foobar at hbox\hbox Y{\let\foobar at hbox\hbox}
+\test\if\if Y{}
+\test\if\ifx N{}
+\test\ifx\if N{}
+\test\par\par Y{}
+\test\hbox\par N{}
+\test\par\hbox N{}
+\csname @@end\endcsname\end
+%</test2>
+%    \end{macrocode}
+%
+% \subsection{Test for \cs{pdf at shellescape}}
+%
+%    \begin{macrocode}
+%<*test-shell>
+\catcode`\{=1 %
+\catcode`\}=2 %
+\catcode`\#=6 %
+\catcode`\@=11 %
+\input pdftexcmds.sty\relax
+\def\msg#{\immediate\write16}
+\def\MaybeEnd{}
+\ifx\luatexversion\UnDeFiNeD
+\else
+  \ifnum\luatexversion<68 %
+    \ifx\pdf at shellescape\@undefined
+      \msg{SHELL=U}%
+      \msg{OK (LuaTeX < 0.68)}%
+    \else
+      \msg{SHELL=defined}%
+      \errmessage{Failed (LuaTeX < 0.68)}%
+    \fi
+    \def\MaybeEnd{\csname @@end\endcsname\end}%
+  \fi
+\fi
+\MaybeEnd
+\ifx\pdf at shellescape\@undefined
+  \msg{SHELL=U}%
+\else
+  \msg{SHELL=\number\pdf at shellescape}%
+\fi
+\ifx\expected\@undefined
+\else
+  \ifx\expected\relax
+    \msg{EXPECTED=U}%
+    \ifx\pdf at shellescape\@undefined
+      \msg{OK}%
+    \else
+      \errmessage{Failed}%
+    \fi
+  \else
+    \msg{EXPECTED=\number\expected}%
+    \ifnum\pdf at shellescape=\expected\relax
+      \msg{OK}%
+    \else
+      \errmessage{Failed}%
+    \fi
+  \fi
+\fi
+\csname @@end\endcsname\end
+%</test-shell>
+%    \end{macrocode}
+%
+% \subsection{Test for escape functions}
+%
+%    \begin{macrocode}
+%<*test-escape>
+\catcode`\{=1 %
+\catcode`\}=2 %
+\catcode`\#=6 %
+\catcode`\^=7 %
+\catcode`\@=11 %
+\errorcontextlines=1000 %
+\input pdftexcmds.sty\relax
+\def\msg#1{%
+  \begingroup
+    \escapechar=92 %
+    \immediate\write16{#1}%
+  \endgroup
+}
+%    \end{macrocode}
+%    \begin{macrocode}
+\begingroup
+  \catcode`\@=11 %
+  \countdef\count@=255 %
+  \def\space{ }%
+  \long\def\@whilenum#1\do #2{%
+    \ifnum #1\relax
+      #2\relax
+      \@iwhilenum{#1\relax#2\relax}%
+    \fi
+  }%
+  \long\def\@iwhilenum#1{%
+    \ifnum #1%
+      \expandafter\@iwhilenum
+    \else
+      \expandafter\ltx at gobble
+    \fi
+    {#1}%
+  }%
+  \gdef\AllBytes{}%
+  \count@=0 %
+  \catcode0=12 %
+  \@whilenum\count@<256 \do{%
+    \lccode0=\count@
+    \ifnum\count@=32 %
+      \xdef\AllBytes{\AllBytes\space}%
+    \else
+      \lowercase{%
+        \xdef\AllBytes{\AllBytes^^@}%
+      }%
+    \fi
+    \advance\count@ by 1 %
+  }%
+\endgroup
+%    \end{macrocode}
+%    \begin{macrocode}
+\def\AllBytesHex{%
+  000102030405060708090A0B0C0D0E0F%
+  101112131415161718191A1B1C1D1E1F%
+  202122232425262728292A2B2C2D2E2F%
+  303132333435363738393A3B3C3D3E3F%
+  404142434445464748494A4B4C4D4E4F%
+  505152535455565758595A5B5C5D5E5F%
+  606162636465666768696A6B6C6D6E6F%
+  707172737475767778797A7B7C7D7E7F%
+  808182838485868788898A8B8C8D8E8F%
+  909192939495969798999A9B9C9D9E9F%
+  A0A1A2A3A4A5A6A7A8A9AAABACADAEAF%
+  B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF%
+  C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF%
+  D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF%
+  E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF%
+  F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF%
+}
+\ltx at onelevel@sanitize\AllBytesHex
+\expandafter\lowercase\expandafter{%
+  \expandafter\def\expandafter\AllBytesHexLC
+      \expandafter{\AllBytesHex}%
+}
+\begingroup
+  \catcode`\#=12 %
+  \xdef\AllBytesName{%
+    #01#02#03#04#05#06#07#08#09#0A#0B#0C#0D#0E#0F%
+    #10#11#12#13#14#15#16#17#18#19#1A#1B#1C#1D#1E#1F%
+    #20!"#23$#25&'#28#29*+,-.#2F%
+    0123456789:;#3C=#3E?%
+    @ABCDEFGHIJKLMNO%
+    PQRSTUVWXYZ#5B\ltx at backslashchar#5D^_%
+    `abcdefghijklmno%
+    pqrstuvwxyz#7B|#7D\string~#7F%
+    #80#81#82#83#84#85#86#87#88#89#8A#8B#8C#8D#8E#8F%
+    #90#91#92#93#94#95#96#97#98#99#9A#9B#9C#9D#9E#9F%
+    #A0#A1#A2#A3#A4#A5#A6#A7#A8#A9#AA#AB#AC#AD#AE#AF%
+    #B0#B1#B2#B3#B4#B5#B6#B7#B8#B9#BA#BB#BC#BD#BE#BF%
+    #C0#C1#C2#C3#C4#C5#C6#C7#C8#C9#CA#CB#CC#CD#CE#CF%
+    #D0#D1#D2#D3#D4#D5#D6#D7#D8#D9#DA#DB#DC#DD#DE#DF%
+    #E0#E1#E2#E3#E4#E5#E6#E7#E8#E9#EA#EB#EC#ED#EE#EF%
+    #F0#F1#F2#F3#F4#F5#F6#F7#F8#F9#FA#FB#FC#FD#FE#FF%
+  }%
+\endgroup
+\ltx at onelevel@sanitize\AllBytesName
+\edef\AllBytesFromName{\expandafter\ltx at gobble\AllBytes}
+\begingroup
+  \def\|{|}%
+  \edef\%{\ltx at percentchar}%
+  \catcode`\|=0 %
+  \catcode`\#=12 %
+  \catcode`\~=12 %
+  \catcode`\\=12 %
+  |xdef|AllBytesString{%
+    \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017%
+    \020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037%
+    \040!"#$|%&'\(\)*+,-./%
+    0123456789:;<=>?%
+    @ABCDEFGHIJKLMNO%
+    PQRSTUVWXYZ[\\]^_%
+    `abcdefghijklmno%
+    pqrstuvwxyz{||}~\177%
+    \200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217%
+    \220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237%
+    \240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257%
+    \260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277%
+    \300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317%
+    \320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337%
+    \340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357%
+    \360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377%
+  }%
+|endgroup
+\ltx at onelevel@sanitize\AllBytesString
+%    \end{macrocode}
+%    \begin{macrocode}
+\def\Test#1#2#3{%
+  \begingroup
+    \expandafter\expandafter\expandafter\def
+    \expandafter\expandafter\expandafter\TestResult
+    \expandafter\expandafter\expandafter{%
+      #1{#2}%
+    }%
+    \ifx\TestResult#3%
+    \else
+      \newlinechar=10 %
+      \msg{Expect:^^J#3}%
+      \msg{Result:^^J\TestResult}%
+      \errmessage{\string#2 -\string#1-> \string#3}%
+    \fi
+  \endgroup
+}
+\def\test#1#2#3{%
+  \edef\TestFrom{#2}%
+  \edef\TestExpect{#3}%
+  \ltx at onelevel@sanitize\TestExpect
+  \Test#1\TestFrom\TestExpect
+}
+\test\pdf at unescapehex{74657374}{test}
+\begingroup
+  \catcode0=12 %
+  \catcode1=12 %
+  \test\pdf at unescapehex{740074017400740174}{t^^@t^^At^^@t^^At}%
+\endgroup
+\Test\pdf at escapehex\AllBytes\AllBytesHex
+\Test\pdf at unescapehex\AllBytesHex\AllBytes
+\Test\pdf at escapename\AllBytes\AllBytesName
+\Test\pdf at escapestring\AllBytes\AllBytesString
+%    \end{macrocode}
+%    \begin{macrocode}
+\csname @@end\endcsname\end
+%</test-escape>
+%    \end{macrocode}
+%
+% \section{Installation}
+%
+% \subsection{Download}
+%
+% \paragraph{Package.} This package is available on
+% CTAN\footnote{\CTANpkg{pdftexcmds}}:
+% \begin{description}
+% \item[\CTAN{macros/latex/contrib/pdftexcmds/pdftexcmds.dtx}] The source file.
+% \item[\CTAN{macros/latex/contrib/pdftexcmds/pdftexcmds.pdf}] Documentation.
+% \end{description}
+%
+%
+% \paragraph{Bundle.} All the packages of the bundle `pdftexcmds'
+% are also available in a TDS compliant ZIP archive. There
+% the packages are already unpacked and the documentation files
+% are generated. The files and directories obey the TDS standard.
+% \begin{description}
+% \item[\CTANinstall{install/macros/latex/contrib/pdftexcmds.tds.zip}]
+% \end{description}
+% \emph{TDS} refers to the standard ``A Directory Structure
+% for \TeX\ Files'' (\CTAN{tds/tds.pdf}). Directories
+% with \xfile{texmf} in their name are usually organized this way.
+%
+% \subsection{Bundle installation}
+%
+% \paragraph{Unpacking.} Unpack the \xfile{pdftexcmds.tds.zip} in the
+% TDS tree (also known as \xfile{texmf} tree) of your choice.
+% Example (linux):
+% \begin{quote}
+%   |unzip pdftexcmds.tds.zip -d ~/texmf|
+% \end{quote}
+%
+% \paragraph{Script installation.}
+% Check the directory \xfile{TDS:scripts/pdftexcmds/} for
+% scripts that need further installation steps.
+%
+% \subsection{Package installation}
+%
+% \paragraph{Unpacking.} The \xfile{.dtx} file is a self-extracting
+% \docstrip\ archive. The files are extracted by running the
+% \xfile{.dtx} through \plainTeX:
+% \begin{quote}
+%   \verb|tex pdftexcmds.dtx|
+% \end{quote}
+%
+% \paragraph{TDS.} Now the different files must be moved into
+% the different directories in your installation TDS tree
+% (also known as \xfile{texmf} tree):
+% \begin{quote}
+% \def\t{^^A
+% \begin{tabular}{@{}>{\ttfamily}l@{ $\rightarrow$ }>{\ttfamily}l@{}}
+%   pdftexcmds.sty & tex/generic/pdftexcmds/pdftexcmds.sty\\
+%   pdftexcmds.lua & scripts/pdftexcmds/pdftexcmds.lua\\
+%   pdftexcmds.pdf & doc/latex/pdftexcmds/pdftexcmds.pdf\\
+%   pdftexcmds.dtx & source/latex/pdftexcmds/pdftexcmds.dtx\\
+% \end{tabular}^^A
+% }^^A
+% \sbox0{\t}^^A
+% \ifdim\wd0>\linewidth
+%   \begingroup
+%     \advance\linewidth by\leftmargin
+%     \advance\linewidth by\rightmargin
+%   \edef\x{\endgroup
+%     \def\noexpand\lw{\the\linewidth}^^A
+%   }\x
+%   \def\lwbox{^^A
+%     \leavevmode
+%     \hbox to \linewidth{^^A
+%       \kern-\leftmargin\relax
+%       \hss
+%       \usebox0
+%       \hss
+%       \kern-\rightmargin\relax
+%     }^^A
+%   }^^A
+%   \ifdim\wd0>\lw
+%     \sbox0{\small\t}^^A
+%     \ifdim\wd0>\linewidth
+%       \ifdim\wd0>\lw
+%         \sbox0{\footnotesize\t}^^A
+%         \ifdim\wd0>\linewidth
+%           \ifdim\wd0>\lw
+%             \sbox0{\scriptsize\t}^^A
+%             \ifdim\wd0>\linewidth
+%               \ifdim\wd0>\lw
+%                 \sbox0{\tiny\t}^^A
+%                 \ifdim\wd0>\linewidth
+%                   \lwbox
+%                 \else
+%                   \usebox0
+%                 \fi
+%               \else
+%                 \lwbox
+%               \fi
+%             \else
+%               \usebox0
+%             \fi
+%           \else
+%             \lwbox
+%           \fi
+%         \else
+%           \usebox0
+%         \fi
+%       \else
+%         \lwbox
+%       \fi
+%     \else
+%       \usebox0
+%     \fi
+%   \else
+%     \lwbox
+%   \fi
+% \else
+%   \usebox0
+% \fi
+% \end{quote}
+% If you have a \xfile{docstrip.cfg} that configures and enables \docstrip's
+% TDS installing feature, then some files can already be in the right
+% place, see the documentation of \docstrip.
+%
+% \subsection{Refresh file name databases}
+%
+% If your \TeX~distribution
+% (\teTeX, \mikTeX, \dots) relies on file name databases, you must refresh
+% these. For example, \teTeX\ users run \verb|texhash| or
+% \verb|mktexlsr|.
+%
+% \subsection{Some details for the interested}
+%
+% \paragraph{Unpacking with \LaTeX.}
+% The \xfile{.dtx} chooses its action depending on the format:
+% \begin{description}
+% \item[\plainTeX:] Run \docstrip\ and extract the files.
+% \item[\LaTeX:] Generate the documentation.
+% \end{description}
+% If you insist on using \LaTeX\ for \docstrip\ (really,
+% \docstrip\ does not need \LaTeX), then inform the autodetect routine
+% about your intention:
+% \begin{quote}
+%   \verb|latex \let\install=y\input{pdftexcmds.dtx}|
+% \end{quote}
+% Do not forget to quote the argument according to the demands
+% of your shell.
+%
+% \paragraph{Generating the documentation.}
+% You can use both the \xfile{.dtx} or the \xfile{.drv} to generate
+% the documentation. The process can be configured by the
+% configuration file \xfile{ltxdoc.cfg}. For instance, put this
+% line into this file, if you want to have A4 as paper format:
+% \begin{quote}
+%   \verb|\PassOptionsToClass{a4paper}{article}|
+% \end{quote}
+% An example follows how to generate the
+% documentation with pdf\LaTeX:
+% \begin{quote}
+%\begin{verbatim}
+%pdflatex pdftexcmds.dtx
+%bibtex pdftexcmds.aux
+%makeindex -s gind.ist pdftexcmds.idx
+%pdflatex pdftexcmds.dtx
+%makeindex -s gind.ist pdftexcmds.idx
+%pdflatex pdftexcmds.dtx
+%\end{verbatim}
+% \end{quote}
+%
+% \printbibliography[
+%   heading=bibnumbered,
+% ]
+%
+% \begin{History}
+%   \begin{Version}{2007/11/11 v0.1}
+%   \item
+%     First version.
+%   \end{Version}
+%   \begin{Version}{2007/11/12 v0.2}
+%   \item
+%     Short description fixed.
+%   \end{Version}
+%   \begin{Version}{2007/12/12 v0.3}
+%   \item
+%     Organization of Lua code as module.
+%   \end{Version}
+%   \begin{Version}{2009/04/10 v0.4}
+%   \item
+%     Adaptation for syntax change of \cs{directlua} in
+%     \hologo{LuaTeX} 0.36.
+%   \end{Version}
+%   \begin{Version}{2009/09/22 v0.5}
+%   \item
+%     \cs{pdf at primitive}, \cs{pdf at ifprimitive} added.
+%   \item
+%     \hologo{XeTeX}'s variants are detected for
+%     \cs{pdf at shellescape}, \cs{pdf at strcmp}, \cs{pdf at primitive},
+%     \cs{pdf at ifprimitive}.
+%   \end{Version}
+%   \begin{Version}{2009/09/23 v0.6}
+%   \item
+%     Macro \cs{pdf at isprimitive} added.
+%   \end{Version}
+%   \begin{Version}{2009/12/12 v0.7}
+%   \item
+%     Short info shortened.
+%   \end{Version}
+%   \begin{Version}{2010/03/01 v0.8}
+%   \item
+%     Required date for package \xpackage{ifluatex} updated.
+%   \end{Version}
+%   \begin{Version}{2010/04/01 v0.9}
+%   \item
+%     Use \cs{ifeof18} for defining \cs{pdf at shellescape} between
+%     \hologo{pdfTeX} 1.21a (inclusive) and 1.30.0 (exclusive).
+%   \end{Version}
+%   \begin{Version}{2010/11/04 v0.10}
+%   \item
+%     \cs{pdf at draftmode}, \cs{pdf at ifdraftmode} and
+%     \cs{pdf at setdraftmode} added.
+%   \end{Version}
+%   \begin{Version}{2010/11/11 v0.11}
+%   \item
+%     Missing \cs{RequirePackage} for package \xpackage{ifpdf} added.
+%   \end{Version}
+%   \begin{Version}{2011/01/30 v0.12}
+%   \item
+%     Already loaded package files are not input in \hologo{plainTeX}.
+%   \end{Version}
+%   \begin{Version}{2011/03/04 v0.13}
+%   \item
+%     Improved Lua function \texttt{shellescape} that also
+%     uses the result of \texttt{os.execute()} (thanks to Philipp Stephani).
+%   \end{Version}
+%   \begin{Version}{2011/04/10 v0.14}
+%   \item
+%     Version check of loaded module added.
+%   \item
+%     Patch for bug in \hologo{LuaTeX} between 0.40.6 and 0.65 that
+%     is fixed in revision 4096.
+%   \end{Version}
+%   \begin{Version}{2011/04/16 v0.15}
+%   \item
+%     \hologo{LuaTeX}: \cs{pdf at shellescape} is only supported
+%     for version 0.70.0 and higher due to a bug, \texttt{os.execute()}
+%     crashes in some circumstances. Fixed in \hologo{LuaTeX}
+%     beta-0.70.0, revision 4167.
+%   \end{Version}
+%   \begin{Version}{2011/04/22 v0.16}
+%   \item
+%     Previous fix was not working due to a wrong catcode of digit
+%     zero (due to easily support the old \cs{directlua0}).
+%     The version border is lowered to 0.68, because some
+%     beta-0.67.0 seems also to work.
+%   \end{Version}
+%   \begin{Version}{2011/06/29 v0.17}
+%   \item
+%     Documentation addition to \cs{pdf at shellescape}.
+%   \end{Version}
+%   \begin{Version}{2011/07/01 v0.18}
+%   \item
+%     Add Lua module loading in \cs{everyjob} for \hologo{iniTeX}
+%     (\hologo{LuaTeX} only).
+%   \end{Version}
+%   \begin{Version}{2011/07/28 v0.19}
+%   \item
+%     Missing space in an info message added (Martin M\"unch).
+%   \end{Version}
+%   \begin{Version}{2011/11/29 v0.20}
+%   \item
+%     \cs{pdf at resettimer} and \cs{pdf at elapsedtime} added
+%     (thanks Andy Thomas).
+%   \end{Version}
+%   \begin{Version}{2016/05/10 v0.21}
+%   \item
+%      local unpack added
+%     (thanks \'{E}lie Roux).
+%   \end{Version}
+%   \begin{Version}{2016/05/21 v0.22}
+%   \item
+%     adjust \cs{textbackslas}h usage in bib file for biber bug.
+%   \end{Version}
+%   \begin{Version}{2016/10/02 v0.23}
+%   \item
+%     add file.close to lua filehandles (github pull request).
+%   \end{Version}
+%   \begin{Version}{2017/01/29 v0.24}
+%   \item
+%     Avoid loading luatex-loader for current luatex. (Use
+%     pdftexcmds.lua not oberdiek.pdftexcmds.lua to simplify file
+%     search with standard require)
+%   \end{Version}
+%   \begin{Version}{2017/03/19 v0.25}
+%   \item
+%     New \cs{pdf at shellescape} for Lua\TeX, see github issue 20.
+%   \end{Version}
+%   \begin{Version}{2018/01/21 v0.26}
+%   \item
+%     use rb not r mode for file open github issue 34.
+%   \end{Version}
+%   \begin{Version}{2018/01/30 v0.27}
+%   \item
+%     \cs{pdf at mdfivesum} for \hologo{XeTeX}
+%   \end{Version}
+%   \begin{Version}{2018/09/07 v0.28}
+%   \item
+%     Fix catcode regime in luatex sprint for \cs{pdf at shellescape} GH issue 45
+%   \end{Version}
+%   \begin{Version}{2018/09/10 v0.29}
+%   \item
+%     Actually do the fix described above in the code, not just document it.
+%   \end{Version}
+%   \begin{Version}{2019/07/25 v0.30}
+%   \item
+%     Remove uses of module function, see PR70
+%   \end{Version}
+%   \begin{Version}{2019/11/24 v0.31}
+%   \item
+%     Use \xpackage{iftex} directly rather than \xpackage{ifluatex} and \xpackage{ifpdf} wrappers.
+%   \item detect \verb|\filmoddate| and other \hologo{XeTeX} commands.
+%   \item Adjust \cs{pdf at escapestring} in \hologo{LuaTeX} to produce
+%     the same as in \hologo{pdfTeX} in the 8bit
+%     range and not drop all non ascii characters.
+%   \end{Version}
+% \end{History}
+%
+% \PrintIndex
+%
+% \Finale
+\endinput


Property changes on: trunk/Master/texmf-dist/source/latex/pdftexcmds/pdftexcmds.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/tex/latex/pdftexcmds/pdftexcmds.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/pdftexcmds/pdftexcmds.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/pdftexcmds/pdftexcmds.sty	2019-11-24 21:44:23 UTC (rev 52913)
@@ -0,0 +1,745 @@
+%%
+%% This is file `pdftexcmds.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% pdftexcmds.dtx  (with options: `package')
+%% 
+%% This is a generated file.
+%% 
+%% Project: pdftexcmds
+%% Version: 2019/11/24 v0.31
+%% 
+%% Copyright (C)
+%%    2007, 2009-2011  Heiko Oberdiek
+%%    2016-2019        Oberdiek Package Support Group
+%% 
+%% This work 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. This version of this license is in
+%%    https://www.latex-project.org/lppl/lppl-1-3c.txt
+%% and the latest version of this license is in
+%%    https://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of
+%% LaTeX version 2005/12/01 or later.
+%% 
+%% This work has the LPPL maintenance status "maintained".
+%% 
+%% The Current Maintainers of this work are
+%% Heiko Oberdiek and the Oberdiek Package Support Group
+%% https://github.com/ho-tex/pdftexcmds/issues
+%% 
+%% 
+%% The Base Interpreter refers to any `TeX-Format',
+%% because some files are installed in TDS:tex/generic//.
+%% 
+%% This work consists of the main source file pdftexcmds.dtx
+%% and the derived files
+%%    pdftexcmds.sty, pdftexcmds.pdf, pdftexcmds.ins, pdftexcmds.drv,
+%%    pdftexcmds.lua.
+%% 
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+  \catcode13=5 % ^^M
+  \endlinechar=13 %
+  \catcode35=6 % #
+  \catcode39=12 % '
+  \catcode44=12 % ,
+  \catcode45=12 % -
+  \catcode46=12 % .
+  \catcode58=12 % :
+  \catcode64=11 % @
+  \catcode123=1 % {
+  \catcode125=2 % }
+  \expandafter\let\expandafter\x\csname ver at pdftexcmds.sty\endcsname
+  \ifx\x\relax % plain-TeX, first loading
+  \else
+    \def\empty{}%
+    \ifx\x\empty % LaTeX, first loading,
+      % variable is initialized, but \ProvidesPackage not yet seen
+    \else
+      \expandafter\ifx\csname PackageInfo\endcsname\relax
+        \def\x#1#2{%
+          \immediate\write-1{Package #1 Info: #2.}%
+        }%
+      \else
+        \def\x#1#2{\PackageInfo{#1}{#2, stopped}}%
+      \fi
+      \x{pdftexcmds}{The package is already loaded}%
+      \aftergroup\endinput
+    \fi
+  \fi
+\endgroup%
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+  \catcode13=5 % ^^M
+  \endlinechar=13 %
+  \catcode35=6 % #
+  \catcode39=12 % '
+  \catcode40=12 % (
+  \catcode41=12 % )
+  \catcode44=12 % ,
+  \catcode45=12 % -
+  \catcode46=12 % .
+  \catcode47=12 % /
+  \catcode58=12 % :
+  \catcode64=11 % @
+  \catcode91=12 % [
+  \catcode93=12 % ]
+  \catcode123=1 % {
+  \catcode125=2 % }
+  \expandafter\ifx\csname ProvidesPackage\endcsname\relax
+    \def\x#1#2#3[#4]{\endgroup
+      \immediate\write-1{Package: #3 #4}%
+      \xdef#1{#4}%
+    }%
+  \else
+    \def\x#1#2[#3]{\endgroup
+      #2[{#3}]%
+      \ifx#1\@undefined
+        \xdef#1{#3}%
+      \fi
+      \ifx#1\relax
+        \xdef#1{#3}%
+      \fi
+    }%
+  \fi
+\expandafter\x\csname ver at pdftexcmds.sty\endcsname
+\ProvidesPackage{pdftexcmds}%
+  [2019/11/24 v0.31 Utility functions of pdfTeX for LuaTeX (HO)]%
+\begingroup\catcode61\catcode48\catcode32=10\relax%
+  \catcode13=5 % ^^M
+  \endlinechar=13 %
+  \catcode123=1 % {
+  \catcode125=2 % }
+  \catcode64=11 % @
+  \def\x{\endgroup
+    \expandafter\edef\csname pdftexcmds at AtEnd\endcsname{%
+      \endlinechar=\the\endlinechar\relax
+      \catcode13=\the\catcode13\relax
+      \catcode32=\the\catcode32\relax
+      \catcode35=\the\catcode35\relax
+      \catcode61=\the\catcode61\relax
+      \catcode64=\the\catcode64\relax
+      \catcode123=\the\catcode123\relax
+      \catcode125=\the\catcode125\relax
+    }%
+  }%
+\x\catcode61\catcode48\catcode32=10\relax%
+\catcode13=5 % ^^M
+\endlinechar=13 %
+\catcode35=6 % #
+\catcode64=11 % @
+\catcode123=1 % {
+\catcode125=2 % }
+\def\TMP at EnsureCode#1#2{%
+  \edef\pdftexcmds at AtEnd{%
+    \pdftexcmds at AtEnd
+    \catcode#1=\the\catcode#1\relax
+  }%
+  \catcode#1=#2\relax
+}
+\TMP at EnsureCode{0}{12}%
+\TMP at EnsureCode{1}{12}%
+\TMP at EnsureCode{2}{12}%
+\TMP at EnsureCode{10}{12}% ^^J
+\TMP at EnsureCode{33}{12}% !
+\TMP at EnsureCode{34}{12}% "
+\TMP at EnsureCode{38}{4}% &
+\TMP at EnsureCode{39}{12}% '
+\TMP at EnsureCode{40}{12}% (
+\TMP at EnsureCode{41}{12}% )
+\TMP at EnsureCode{42}{12}% *
+\TMP at EnsureCode{43}{12}% +
+\TMP at EnsureCode{44}{12}% ,
+\TMP at EnsureCode{45}{12}% -
+\TMP at EnsureCode{46}{12}% .
+\TMP at EnsureCode{47}{12}% /
+\TMP at EnsureCode{58}{12}% :
+\TMP at EnsureCode{60}{12}% <
+\TMP at EnsureCode{62}{12}% >
+\TMP at EnsureCode{91}{12}% [
+\TMP at EnsureCode{93}{12}% ]
+\TMP at EnsureCode{94}{7}% ^ (superscript)
+\TMP at EnsureCode{95}{12}% _ (other)
+\TMP at EnsureCode{96}{12}% `
+\TMP at EnsureCode{126}{12}% ~ (other)
+\edef\pdftexcmds at AtEnd{%
+  \pdftexcmds at AtEnd
+  \escapechar=\number\escapechar\relax
+  \noexpand\endinput
+}
+\escapechar=92 %
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname RequirePackage\endcsname\relax
+  \def\TMP at RequirePackage#1[#2]{%
+    \begingroup\expandafter\expandafter\expandafter\endgroup
+    \expandafter\ifx\csname ver@#1.sty\endcsname\relax
+      \input #1.sty\relax
+    \fi
+  }%
+  \TMP at RequirePackage{infwarerr}[2007/09/09]%
+  \TMP at RequirePackage{iftex}[2019/11/07]%%
+  \TMP at RequirePackage{ltxcmds}[2010/12/02]%
+\else
+  \RequirePackage{infwarerr}[2007/09/09]%
+  \RequirePackage{iftex}[2019/11/07]%
+  \RequirePackage{ltxcmds}[2010/12/02]%
+\fi
+\ifluatex
+\else
+  \def\pdftexcmds at nopdftex{%
+    \let\pdftexcmds at nopdftex\relax
+  }%
+  \def\pdftexcmds at temp#1{%
+    \begingroup\expandafter\expandafter\expandafter\endgroup
+    \expandafter\ifx\csname
+         \expandafter\ifx\csname pdf#1\endcsname\relax\else pdf\fi#1\endcsname\relax
+      \pdftexcmds at nopdftex
+    \else
+      \expandafter\def\csname pdf@#1\expandafter\endcsname
+        \expandafter{%
+        \csname\expandafter\ifx\csname pdf#1\endcsname\relax\else pdf\fi#1\endcsname
+      }%
+    \fi
+  }%
+  \pdftexcmds at temp{strcmp}%
+  \pdftexcmds at temp{escapehex}%
+  \let\pdf at escapehexnative\pdf at escapehex
+  \pdftexcmds at temp{unescapehex}%
+  \let\pdf at unescapehexnative\pdf at unescapehex
+  \pdftexcmds at temp{escapestring}%
+  \pdftexcmds at temp{escapename}%
+  \pdftexcmds at temp{filesize}%
+  \pdftexcmds at temp{filemoddate}%
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdfshellescape\endcsname\relax
+    \pdftexcmds at nopdftex
+    \ltx at IfUndefined{pdftexversion}{%
+    }{%
+      \ifnum\pdftexversion>120 % 1.21a supports \ifeof18
+        \ifeof18 %
+          \chardef\pdf at shellescape=0 %
+        \else
+          \chardef\pdf at shellescape=1 %
+        \fi
+      \fi
+    }%
+  \else
+    \def\pdf at shellescape{%
+      \pdfshellescape
+    }%
+  \fi
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdffiledump\endcsname\relax
+    \pdftexcmds at nopdftex
+  \else
+    \def\pdf at filedump#1#2#3{%
+      \pdffiledump offset#1 length#2{#3}%
+    }%
+  \fi
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdfmdfivesum\endcsname\relax
+    \begingroup\expandafter\expandafter\expandafter\endgroup
+    \expandafter\ifx\csname mdfivesum\endcsname\relax
+      \pdftexcmds at nopdftex
+    \else
+      \def\pdf at mdfivesum#{\mdfivesum}%
+      \let\pdf at mdfivesumnative\pdf at mdfivesum
+      \def\pdf at filemdfivesum#{\mdfivesum file}%
+    \fi
+  \else
+    \def\pdf at mdfivesum#{\pdfmdfivesum}%
+    \let\pdf at mdfivesumnative\pdf at mdfivesum
+    \def\pdf at filemdfivesum#{\pdfmdfivesum file}%
+  \fi
+  \def\pdf at system#{%
+    \immediate\write18%
+  }%
+  \def\pdftexcmds at temp#1{%
+    \begingroup\expandafter\expandafter\expandafter\endgroup
+    \expandafter\ifx\csname
+         \expandafter\ifx\csname pdf#1\endcsname\relax\else pdf\fi#1\endcsname\relax
+      \pdftexcmds at nopdftex
+    \else
+      \expandafter\let\csname pdf@#1\expandafter\endcsname
+      \csname\expandafter\ifx\csname pdf#1\endcsname\relax\else pdf\fi#1\endcsname
+    \fi
+  }%
+  \pdftexcmds at temp{resettimer}%
+  \pdftexcmds at temp{elapsedtime}%
+\fi
+\ifluatex
+  \ifnum\luatexversion<36 %
+    \def\pdftexcmds at directlua{\directlua0 }%
+  \else
+    \let\pdftexcmds at directlua\directlua
+  \fi
+  \begingroup
+    \newlinechar=10 %
+    \endlinechar=\newlinechar
+    \pdftexcmds at directlua{%
+      if tex.enableprimitives then
+        tex.enableprimitives(
+          'pdf@',
+          {'primitive', 'ifprimitive', 'pdfdraftmode','draftmode'}
+        )
+        tex.enableprimitives('', {'luaescapestring'})
+      end
+    }%
+  \endgroup %
+\fi
+\def\pdftexcmds at strip@prefix#1>{}
+\def\pdftexcmds at temp#1#2#3{%
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdf@#1\endcsname\relax
+    \begingroup
+      \def\x{#3}%
+      \edef\x{\expandafter\pdftexcmds at strip@prefix\meaning\x}%
+      \escapechar=-1 %
+      \edef\y{\expandafter\meaning\csname#2\endcsname}%
+    \expandafter\endgroup
+    \ifx\x\y
+      \expandafter\let\csname pdf@#1\expandafter\endcsname
+      \csname #2\endcsname
+    \fi
+  \fi
+}
+\pdftexcmds at temp{primitive}{pdfprimitive}{pdfprimitive}% pdfTeX, oldLuaTeX
+\pdftexcmds at temp{primitive}{primitive}{primitive}% XeTeX, luatex
+\pdftexcmds at temp{primitive}{luatexprimitive}{pdfprimitive}% oldLuaTeX
+\pdftexcmds at temp{primitive}{luatexpdfprimitive}{pdfprimitive}% oldLuaTeX
+\pdftexcmds at temp{ifprimitive}{ifpdfprimitive}{ifpdfprimitive}% pdfTeX, oldLuaTeX
+\pdftexcmds at temp{ifprimitive}{ifprimitive}{ifprimitive}% XeTeX, luatex
+\pdftexcmds at temp{ifprimitive}{luatexifprimitive}{ifpdfprimitive}% oldLuaTeX
+\pdftexcmds at temp{ifprimitive}{luatexifpdfprimitive}{ifpdfprimitive}% oldLuaTeX
+\ifluatex\else
+\begingroup
+  \expandafter\ifx\csname pdf at primitive\endcsname\relax
+  \else
+    \expandafter\ifx\csname pdftexversion\endcsname\relax
+    \else
+      \ifnum\pdftexversion=140 %
+        \expandafter\ifx\csname pdftexrevision\endcsname\relax
+        \else
+          \ifnum\pdftexrevision<4 %
+            \endgroup
+            \let\pdf at primitive\@undefined
+            \@PackageInfoNoLine{pdftexcmds}{%
+              \string\pdf at primitive\space disabled, %
+              because\MessageBreak
+              \string\pdfprimitive\space is broken until pdfTeX 1.40.4%
+            }%
+            \begingroup
+          \fi
+        \fi
+      \fi
+    \fi
+  \fi
+\endgroup
+\fi
+\begingroup
+  \@PackageInfoNoLine{pdftexcmds}{%
+    \string\pdf at primitive\space is %
+    \expandafter\ifx\csname pdf at primitive\endcsname\relax not \fi
+    available%
+  }%
+  \@PackageInfoNoLine{pdftexcmds}{%
+    \string\pdf at ifprimitive\space is %
+    \expandafter\ifx\csname pdf at ifprimitive\endcsname\relax not \fi
+    available%
+  }%
+\endgroup
+\def\pdftexcmds at temp#1{%
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdf@#1\endcsname\relax
+    \begingroup
+      \escapechar=-1 %
+      \edef\x{\expandafter\meaning\csname#1\endcsname}%
+      \def\y{#1}%
+      \def\z##1->{}%
+      \edef\y{\expandafter\z\meaning\y}%
+    \expandafter\endgroup
+    \ifx\x\y
+      \expandafter\def\csname pdf@#1\expandafter\endcsname
+      \expandafter{%
+        \csname#1\endcsname
+      }%
+    \fi
+  \fi
+}%
+\pdftexcmds at temp{shellescape}%
+\pdftexcmds at temp{strcmp}%
+\def\pdf at isprimitive{%
+  \begingroup\expandafter\expandafter\expandafter\endgroup
+  \expandafter\ifx\csname pdf at strcmp\endcsname\relax
+    \long\def\pdf at isprimitive##1{%
+      \expandafter\pdftexcmds at isprimitive\expandafter{\meaning##1}%
+    }%
+    \long\def\pdftexcmds at isprimitive##1##2{%
+      \expandafter\pdftexcmds@@isprimitive\expandafter{\string##2}{##1}%
+    }%
+    \def\pdftexcmds@@isprimitive##1##2{%
+      \ifnum0\pdftexcmds at equal##1\delimiter##2\delimiter=1 %
+        \expandafter\ltx at firstoftwo
+      \else
+        \expandafter\ltx at secondoftwo
+      \fi
+    }%
+    \def\pdftexcmds at equal##1##2\delimiter##3##4\delimiter{%
+      \ifx##1##3%
+        \ifx\relax##2##4\relax
+          1%
+        \else
+          \ifx\relax##2\relax
+          \else
+            \ifx\relax##4\relax
+            \else
+              \pdftexcmds at equalcont{##2}{##4}%
+            \fi
+          \fi
+        \fi
+      \fi
+    }%
+    \def\pdftexcmds at equalcont##1{%
+      \def\pdftexcmds at equalcont####1####2##1##1##1##1{%
+        ##1##1##1##1%
+        \pdftexcmds at equal####1\delimiter####2\delimiter
+      }%
+    }%
+    \expandafter\pdftexcmds at equalcont\csname fi\endcsname
+  \else
+    \long\def\pdf at isprimitive##1##2{%
+      \ifnum\pdf at strcmp{\meaning##1}{\string##2}=0 %
+        \expandafter\ltx at firstoftwo
+      \else
+        \expandafter\ltx at secondoftwo
+      \fi
+    }%
+  \fi
+}
+\ifluatex
+\ifx\pdfdraftmode\@undefined
+  \let\pdfdraftmode\draftmode
+\fi
+\else
+  \pdf at isprimitive
+\fi
+\let\pdftexcmds at temp\ltx at zero %
+\ltx at IfUndefined{pdfdraftmode}{%
+  \@PackageInfoNoLine{pdftexcmds}{\ltx at backslashchar pdfdraftmode not found}%
+}{%
+  \ifpdf
+    \let\pdftexcmds at temp\ltx at one
+    \@PackageInfoNoLine{pdftexcmds}{\ltx at backslashchar pdfdraftmode found}%
+  \else
+    \@PackageInfoNoLine{pdftexcmds}{%
+      \ltx at backslashchar pdfdraftmode is ignored in DVI mode%
+    }%
+  \fi
+}
+\ifcase\pdftexcmds at temp
+  \let\pdf at draftmode\ltx at zero
+  \let\pdf at ifdraftmode\ltx at secondoftwo
+  \def\pdftexcmds at setdraftmode#1{}%
+\else
+  \let\pdftexcmds at draftmode\pdfdraftmode
+  \def\pdf at ifdraftmode{%
+    \ifnum\pdftexcmds at draftmode=\ltx at one
+      \expandafter\ltx at firstoftwo
+    \else
+      \expandafter\ltx at secondoftwo
+    \fi
+  }%
+  \def\pdf at draftmode{%
+    \ifnum\pdftexcmds at draftmode=\ltx at one
+      \expandafter\ltx at one
+    \else
+      \expandafter\ltx at zero
+    \fi
+  }%
+  \def\pdftexcmds at setdraftmode#1{%
+    \pdftexcmds at draftmode=#1\relax
+  }%
+\fi
+\def\pdf at setdraftmode#1{%
+  \begingroup
+    \count\ltx at cclv=#1\relax
+  \edef\x{\endgroup
+    \noexpand\pdftexcmds@@setdraftmode{\the\count\ltx at cclv}%
+  }%
+  \x
+}
+\def\pdftexcmds@@setdraftmode#1{%
+  \ifcase#1 %
+    \pdftexcmds at setdraftmode{#1}%
+  \or
+    \pdftexcmds at setdraftmode{#1}%
+  \else
+    \@PackageWarning{pdftexcmds}{%
+      \string\pdf at setdraftmode: Ignoring\MessageBreak
+      invalid value `#1'%
+    }%
+  \fi
+}
+\ifluatex
+\else
+  \expandafter\pdftexcmds at AtEnd
+\fi%
+\pdftexcmds at directlua{%
+  require("pdftexcmds")%
+}
+\ifnum\luatexversion>37 %
+  \ifnum0%
+      \pdftexcmds at directlua{%
+        if status.ini_version then %
+          tex.write("1")%
+        end%
+      }>0 %
+    \everyjob\expandafter{%
+      \the\everyjob
+      \pdftexcmds at directlua{%
+        require("pdftexcmds")%
+      }%
+    }%
+  \fi
+\fi
+\begingroup
+  \def\x{2019/11/24 v0.31}%
+  \ltx at onelevel@sanitize\x
+  \edef\y{%
+    \pdftexcmds at directlua{%
+      if oberdiek.pdftexcmds.getversion then %
+        oberdiek.pdftexcmds.getversion()%
+      end%
+    }%
+  }%
+  \ifx\x\y
+  \else
+    \@PackageError{pdftexcmds}{%
+      Wrong version of lua module.\MessageBreak
+      Package version: \x\MessageBreak
+      Lua module: \y
+    }\@ehc
+  \fi
+\endgroup
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname newtoks\endcsname\relax
+  \toksdef\pdftexcmds at toks=0 %
+\else
+  \csname newtoks\endcsname\pdftexcmds at toks
+\fi
+\def\pdftexcmds at Patch{0}
+\ifnum\luatexversion>40 %
+  \ifnum\luatexversion<66 %
+    \def\pdftexcmds at Patch{1}%
+  \fi
+\fi
+\ifcase\pdftexcmds at Patch
+  \catcode`\&=14 %
+\else
+  \catcode`\&=9 %
+  \def\pdftexcmds at PatchDecode#1\@nil{%
+    \pdftexcmds at DecodeA#1^^A^^A\@nil{}%
+  }%
+  \def\pdftexcmds at DecodeA#1^^A^^A#2\@nil#3{%
+    \ifx\relax#2\relax
+      \ltx at ReturnAfterElseFi{%
+        \pdftexcmds at DecodeB#3#1^^A^^B\@nil{}%
+      }%
+    \else
+      \ltx at ReturnAfterFi{%
+        \pdftexcmds at DecodeA#2\@nil{#3#1^^@}%
+      }%
+    \fi
+  }%
+  \def\pdftexcmds at DecodeB#1^^A^^B#2\@nil#3{%
+    \ifx\relax#2\relax%
+      \ltx at ReturnAfterElseFi{%
+        \ltx at zero
+        #3#1%
+      }%
+    \else
+      \ltx at ReturnAfterFi{%
+        \pdftexcmds at DecodeB#2\@nil{#3#1^^A}%
+      }%
+    \fi
+  }%
+\fi
+\ifnum\luatexversion<36 %
+\else
+  \catcode`\0=9 %
+\fi
+\long\def\pdf at strcmp#1#2{%
+  \directlua0{%
+    oberdiek.pdftexcmds.strcmp("\luaescapestring{#1}",%
+        "\luaescapestring{#2}")%
+  }%
+}%
+\pdf at isprimitive
+\long\def\pdf at escapehex#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.escapehex("\luaescapestring{#1}", "byte")%
+  }%
+}%
+\long\def\pdf at escapehexnative#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.escapehex("\luaescapestring{#1}")%
+  }%
+}%
+\def\pdf at unescapehex#1{%
+& \romannumeral\expandafter\pdftexcmds at PatchDecode
+  \the\expandafter\pdftexcmds at toks
+  \directlua0{%
+    oberdiek.pdftexcmds.toks="pdftexcmds at toks"%
+    oberdiek.pdftexcmds.unescapehex("\luaescapestring{#1}", "byte", \pdftexcmds at Patch)%
+  }%
+& \@nil
+}%
+\def\pdf at unescapehexnative#1{%
+& \romannumeral\expandafter\pdftexcmds at PatchDecode
+  \the\expandafter\pdftexcmds at toks
+  \directlua0{%
+    oberdiek.pdftexcmds.toks="pdftexcmds at toks"%
+    oberdiek.pdftexcmds.unescapehex("\luaescapestring{#1}", \pdftexcmds at Patch)%
+  }%
+& \@nil
+}%
+\long\def\pdf at escapestring#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.escapestring("\luaescapestring{#1}")%
+  }%
+}
+\long\def\pdf at escapename#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.escapename("\luaescapestring{#1}", "byte")%
+  }%
+}
+\long\def\pdf at escapenamenative#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.escapename("\luaescapestring{#1}")%
+  }%
+}
+\def\pdf at filesize#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.filesize("\luaescapestring{#1}")%
+  }%
+}
+\def\pdf at filemoddate#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.filemoddate("\luaescapestring{#1}")%
+  }%
+}
+\def\pdf at filedump#1#2#3{%
+  \directlua0{%
+    oberdiek.pdftexcmds.filedump("\luaescapestring{\number#1}",%
+        "\luaescapestring{\number#2}",%
+        "\luaescapestring{#3}")%
+  }%
+}%
+\long\def\pdf at mdfivesum#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.mdfivesum("\luaescapestring{#1}", "byte")%
+  }%
+}%
+\long\def\pdf at mdfivesumnative#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.mdfivesum("\luaescapestring{#1}")%
+  }%
+}%
+\def\pdf at filemdfivesum#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.filemdfivesum("\luaescapestring{#1}")%
+  }%
+}%
+\let\pdftexcmds at temp=Y%
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname protected\endcsname\relax
+  \pdftexcmds at directlua0{%
+    if tex.enableprimitives then %
+      tex.enableprimitives('', {'protected'})%
+    end%
+  }%
+\fi
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname protected\endcsname\relax
+  \let\pdftexcmds at temp=N%
+\fi
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname numexpr\endcsname\relax
+  \pdftexcmds at directlua0{%
+    if tex.enableprimitives then %
+      tex.enableprimitives('', {'numexpr'})%
+    end%
+  }%
+\fi
+\begingroup\expandafter\expandafter\expandafter\endgroup
+\expandafter\ifx\csname numexpr\endcsname\relax
+  \let\pdftexcmds at temp=N%
+\fi
+\ifx\pdftexcmds at temp N%
+  \@PackageWarningNoLine{pdftexcmds}{%
+    Definitions of \ltx at backslashchar pdf at resettimer and%
+    \MessageBreak
+    \ltx at backslashchar pdf at elapsedtime are skipped, because%
+    \MessageBreak
+    e-TeX's \ltx at backslashchar protected or %
+    \ltx at backslashchar numexpr are missing%
+  }%
+\else
+  \protected\def\pdf at resettimer{%
+    \pdftexcmds at directlua0{%
+      oberdiek.pdftexcmds.resettimer()%
+    }%
+  }%
+  \protected\def\pdf at elapsedtime{%
+    \numexpr
+      \pdftexcmds at directlua0{%
+        oberdiek.pdftexcmds.elapsedtime()%
+      }%
+    \relax
+  }%
+\fi
+\ifnum\luatexversion<68 %
+\else
+  \protected\edef\pdf at shellescape{%
+   \numexpr\directlua{tex.sprint(%
+         \number\catcodetable at string,status.shell_escape)}\relax}
+\fi
+\def\pdf at system#1{%
+  \directlua0{%
+    oberdiek.pdftexcmds.system("\luaescapestring{#1}")%
+  }%
+}
+\def\pdf at lastsystemstatus{%
+  \directlua0{%
+    oberdiek.pdftexcmds.lastsystemstatus()%
+  }%
+}
+\def\pdf at lastsystemexit{%
+  \directlua0{%
+    oberdiek.pdftexcmds.lastsystemexit()%
+  }%
+}
+\catcode`\0=12 %
+\ifnum0%
+    \pdftexcmds at directlua{%
+      if io.popen then %
+        tex.write("1")%
+      end%
+    }%
+    =1 %
+  \def\pdf at pipe#1{%
+&   \romannumeral\expandafter\pdftexcmds at PatchDecode
+    \the\expandafter\pdftexcmds at toks
+    \pdftexcmds at directlua{%
+      oberdiek.pdftexcmds.toks="pdftexcmds at toks"%
+      oberdiek.pdftexcmds.pipe("\luaescapestring{#1}", \pdftexcmds at Patch)%
+    }%
+&   \@nil
+  }%
+\fi
+\pdftexcmds at AtEnd%
+\endinput
+%%
+%% End of file `pdftexcmds.sty'.


Property changes on: trunk/Master/texmf-dist/tex/latex/pdftexcmds/pdftexcmds.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/tlpkg/bin/tlpkg-ctan-check
===================================================================
--- trunk/Master/tlpkg/bin/tlpkg-ctan-check	2019-11-24 21:38:59 UTC (rev 52912)
+++ trunk/Master/tlpkg/bin/tlpkg-ctan-check	2019-11-24 21:44:23 UTC (rev 52913)
@@ -528,7 +528,7 @@
     pdflatexpicscale pdfmarginpar pdfoverlay
     pdfpagediff pdfpages pdfpc-movie pdfprivacy pdfreview
     pdfscreen pdfslide pdfsync
-    pdftex-quiet pdftricks pdftricks2 pdfx pdfxup
+    pdftex-quiet pdftexcmds pdftricks pdftricks2 pdfx pdfxup
     pecha pedigree-perl penrose perception perfectcut perltex
     permute persian-bib
     petiteannonce petri-nets pfarrei

Modified: trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2019-11-24 21:38:59 UTC (rev 52912)
+++ trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2019-11-24 21:44:23 UTC (rev 52913)
@@ -887,6 +887,7 @@
 depend pdfscreen
 depend pdfslide
 depend pdfsync
+depend pdftexcmds
 depend pdfwin
 depend pdfx
 depend pecha

Added: trunk/Master/tlpkg/tlpsrc/pdftexcmds.tlpsrc
===================================================================


More information about the tex-live-commits mailing list