summaryrefslogtreecommitdiff
path: root/macros/latex-dev/required/tools/shellesc.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex-dev/required/tools/shellesc.dtx')
-rw-r--r--macros/latex-dev/required/tools/shellesc.dtx243
1 files changed, 243 insertions, 0 deletions
diff --git a/macros/latex-dev/required/tools/shellesc.dtx b/macros/latex-dev/required/tools/shellesc.dtx
new file mode 100644
index 0000000000..061ea4457c
--- /dev/null
+++ b/macros/latex-dev/required/tools/shellesc.dtx
@@ -0,0 +1,243 @@
+% \iffalse
+%% Source File: shellesc.dtx
+%% Copyright (C) 2015-2019
+%%
+%% The LaTeX3 Project and any individual authors listed elsewhere
+%% in this file.
+%%
+%% This file may be distributed under the terms of the LPPL.
+%% See README for details.
+%
+%<*dtx>
+ \ProvidesFile{shellesc.dtx}
+%</dtx>
+%<package>\ifx\ProvidesPackage\undefined
+%<package>\def\next#1#2[#3]{\wlog{#2 #3}}
+%<package>\ifx\PackageInfo\undefined\def\PackageInfo#1#2{\wlog{#1: #2}}\fi
+%<package>\ifx\PackageWarning\undefined\def\PackageWarning#1#2{\wlog{#1: #2}}\fi
+%<package>\expandafter\next\fi
+%<package>\ProvidesPackage{shellesc}
+%<driver> \ProvidesFile{shellesc.drv}
+% \fi
+% \ProvidesFile{shellesc.dtx}
+ [2016/06/07 v0.02b unified shell escape interface for LaTeX]
+%
+% \iffalse
+%<*driver>
+\documentclass{ltxdoc}
+\begin{document}
+\DocInput{shellesc.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \GetFileInfo{shellesc.dtx}
+%
+% \title{The \textsf{shellesc} Package\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}}
+% \author{LaTeX3 project}
+% \date{\filedate}
+% \maketitle
+%
+% \changes{v0.1b}{2016/02/02}{Doc typo fixes (JB)}
+% \changes{v0.2a}{2016/06/07}{Improve use with plain TeX}
+% \section{Introduction}
+%
+%
+% For many years web2c based \TeX\ implementations have used the syntax
+% of the \verb|\write| command to access system commands by using a
+% special stream 18 (streams above 15 can not be allocated to files in
+% classical \TeX\ so stream 18 would otherwise just print to the
+% terminal).
+%
+% This is a useful extension that did not break the strict rules on
+% extensions in classical \TeX. This package provides a simple
+% macro level interface hiding the \verb|write18| implementation
+% so a command to remove a file on a unix-like system could be
+% specified using \verb|\ShellEscape{rm file.txt}| (or \verb|del| in
+% windows). Note that by default system access is not allowed and
+% latex will typically need to be called with the \verb|--shell-escape|
+% command line option.
+%
+% The package may be used with standard \texttt{latex} or
+% \texttt{pdflatex} or \texttt{xetex}, however it is mostly motivated by
+% \texttt{lualatex} as from Lua\TeX~0.87 onwards Lua\TeX\ does \emph{not}
+% support the \verb|\write18| syntax to access system commands: it has
+% 256 write streams and stream 18 can be associated to a file and
+% (without this package) has no special significance. This packge
+% defines the same \verb|\ShellEscape| syntax in Lua\LaTeX, but the
+% implementation is via Lua and the \verb|os.execute| function.
+%
+% \verb|\ShellEscape| in fact corresponds to \verb|\immediate\write18|
+% (or \verb|\directlua|). Very rarely you may need to delay a system
+% command until the current page is output (when page numbers are
+% known) for this classically you could use \verb|\write18| (or
+% (\verb|\latelua|). This package provides \verb|\DelayedShellEscape|
+% as a common syntax for this use.
+%
+% To aid porting existing documents to Lua\TeX~0.87 this package does
+% overload the \verb|\write| command so that
+% \verb|\write18{rm file.txt}|
+% will work with Lua\TeX. Note that the redefinition of \verb|\write|
+% can not detect whether \verb|\immediate| has been used,
+% \verb|\immediate| will work as normal when writing to file streams
+% or the terminal but the special case of stream 18 which is defined to
+% use \verb|os.execute| always uses \verb|\directlua| (so corresponds
+% to \verb|\immediate\write18|. In the rare situations that you need
+% non-immediate \verb|\write18| in a document being ported to current
+% Lua\TeX, you will need to change to use the
+% \verb|\DelayedShellEscape| command.
+%
+% \section{Implementation}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \subsection{Status Check}
+%
+%
+% \changes{v0.2a}{2016/06/07}{spelling in messages}
+% \begin{macrocode}
+\ifcase
+ \ifx\pdfshellescape\@undefined
+ \ifx\shellescape\@undefined
+ \ifx\directlua\@undefined
+ \z@
+ \else
+ \directlua{%
+ tex.sprint((status.shell_escape or os.execute()) .. " ")}
+ \fi
+ \else
+ \shellescape
+ \fi
+ \else
+ \pdfshellescape
+ \fi
+ \PackageWarning{shellesc}{Shell escape disabled}
+\or
+ \PackageInfo {shellesc}{Unrestricted shell escape enabled}
+\else
+ \PackageInfo {shellesc}{Restricted shell escape enabled}
+\fi
+% \end{macrocode}
+%
+% \subsection{The shellesc package interface}
+%
+% \begin{macro}{\ShellEscape}
+% Execute the supplied tokens as a system dependent command, assuming
+% such execution is allowed.
+% \begin{macrocode}
+\ifx\lastsavedimageresourcepages\@undefined
+ \protected\def\ShellEscape{\immediate\write18 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\else
+ \protected\def\ShellEscape#1{%
+ \directlua{os.execute("\luaescapestring{#1}")}}
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\DelayedShellEscape}
+% \changes{v0.1c}{2016/04/29}{Define \cs{DelayedShellEscape} not \cs{ShellEscape}(UF)}
+% Execute the supplied tokens as a system dependent command, when this
+% node is shipped out with the completed page, assuming
+% such execution is allowed.
+% \begin{macrocode}
+\ifx\lastsavedimageresourcepages\@undefined
+ \protected\def\DelayedShellEscape{\relax\write18 }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\else
+ \protected\def\DelayedShellEscape#1{%
+ \latelua{os.execute("\luaescapestring{#1}")}}
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{The write18 package interface}
+%
+% In web2c based engines other than Lua\TeX, |\write18| may be used
+% directly. The same was true in older LuaTeX, but from version 0.85
+% onwards that is not available.
+%
+% The above |shellesc| package interface is recommended for new code,
+% however for ease of porting existing documents and packages to newer
+% Lua\TeX\ releases, a |\write18| interface is provided here via a
+% call to Lua's |os.execute|.
+%
+% Note that as currently written this always does an \emph{immediate}
+% call to the system.
+%
+% |\immediate| is supported but ignored, |\immediate\write18| and
+% |\write18| both execute immediately. To use a delayed execution at
+% the next shipout, use the |\DelayedShellEscape| command defined
+% above.
+%
+% Note that it would be easy to make |\wriete18| defined here use
+% delayed execution, just use |\DelayedShellEscape| instead of
+% |ShellEscape| in the definition below. However detecting
+% |\immediate| is tricky so the choice here is to always use the
+% immediate form, which is overwhelmingly more commonly used with
+% |\write18|.
+%
+% Stop at this point if not a recent Lua\TeX.
+% \begin{macrocode}
+\ifx\lastsavedimageresourcepages\@undefined\expandafter\endinput\fi
+% \end{macrocode}
+%
+% \begin{macrocode}
+\directlua{%
+% \end{macrocode}
+%
+% \begin{macrocode}
+shellesc = shellesc or {}
+% \end{macrocode}
+%
+% Lua function to use the token scanner to grab the following \TeX\
+% number, and then test if stream 18 is being used, and then insert an
+% appropriate \TeX\ command to handle the following brace group in
+% each case.
+% \begin{macrocode}
+local function write_or_execute()
+ local s = token.scan_int()
+ if (s==18) then
+ tex.sprint(\the\numexpr\catcodetable@atletter\relax,
+ "\string\\ShellEscape ")
+ else
+ tex.sprint(\the\numexpr\catcodetable@atletter\relax,
+ "\string\\shellesc@write " .. s)
+ end
+end
+% \end{macrocode}
+%
+% \begin{macrocode}
+shellesc.write_or_execute=write_or_execute
+% \end{macrocode}
+%
+% \begin{macrocode}
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\let\shellesc@write\write
+% \end{macrocode}
+%
+% \begin{macrocode}
+\protected\def\write{\directlua{shellesc.write_or_execute()}}
+% \end{macrocode}
+%
+%
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \Finale
+%