guess we don't want the build dir
[latex2e.git] / trunk / required / tools / shellesc.dtx
blobebc436ad96e4f607cb96e78b8ebc903f8b30456c
1 % \iffalse
2 %% Source File: shellesc.dtx
3 %% Copyright 2015-2016 LaTeX3 project
4 %%
5 %% This file may be distributed under the terms of the LPPL.
6 %% See README for details.
8 %<*dtx>
9           \ProvidesFile{shellesc.dtx}
10 %</dtx>
11 %<package>\ifx\ProvidesPackage\undefined
12 %<package>\def\next#1#2[#3]{\wlog{#2 #3}}
13 %<package>\ifx\PackageInfo\undefined\def\PackageInfo#1#2{\wlog{#1: #2}}\fi
14 %<package>\ifx\PackageWarning\undefined\def\PackageWarning#1#2{\wlog{#1: #2}}\fi
15 %<package>\expandafter\next\fi
16 %<package>\ProvidesPackage{shellesc}
17 %<driver> \ProvidesFile{shellesc.drv}
18 % \fi
19 %         \ProvidesFile{shellesc.dtx}
20        [2016/06/07 v0.02a unified shell escape interface for LaTeX]
22 % \iffalse
23 %<*driver>
24 \documentclass{ltxdoc}
25 \begin{document}
26 \DocInput{shellesc.dtx}
27 \end{document}
28 %</driver>
29 % \fi
31 % \GetFileInfo{shellesc.dtx}
33 % \title{The \textsf{shellesc} Package\thanks{This file
34 %        has version number \fileversion, last
35 %        revised \filedate.}}
36 % \author{LaTeX3 project}
37 % \date{\filedate}
38 % \maketitle
40 % \changes{v0.1b}{2016/02/02}{Doc typo fixes (JB)}
41 % \changes{v0.2a}{2016/06/07}{Improve use with plain TeX}
42 % \section{Introduction}
44
45 % For many years web2c based \TeX\ implementations have used the syntax
46 % of the \verb|\write| command to access  system commands by using a
47 % special stream 18 (streams above 15 can not be allocated to files in
48 % classical \TeX\ so stream 18 would otherwise just print to the
49 % terminal).
51 % This is a useful extension that did not break the strict rules on
52 % extensions in classical \TeX.  This package provides a simple
53 % macro level interface hiding the \verb|write18| implementation
54 % so a command to remove a file on a unix-like system could be
55 % specified  using \verb|\ShellEscape{rm file.txt}| (or \verb|del| in
56 % windows). Note that by default system access is not allowed and
57 % latex will typically need to be called with the \verb|--shell-escape|
58 % command line option.
60 % The package may be used with standard \texttt{latex} or
61 % \texttt{pdflatex} or \texttt{xetex}, however it is mostly motivated by
62 % \texttt{lualatex} as from Lua\TeX~0.87 onwards Lua\TeX\ does \emph{not}
63 % support the \verb|\write18| syntax to access system commands: it has
64 % 256 write streams and stream 18 can be associated to a file and
65 % (without this package) has no special significance. This packge
66 % defines the same \verb|\ShellEscape| syntax in Lua\LaTeX, but the
67 % implementation is via Lua and the \verb|os.execute| function.
69 % \verb|\ShellEscape| in fact corresponds to \verb|\immediate\write18|
70 % (or \verb|\directlua|). Very rarely you may need to delay a system
71 % command until the current page is output (when page numbers are
72 % known) for this classically you could use \verb|\write18| (or
73 % (\verb|\latelua|). This package provides \verb|\DelayedShellEscape|
74 % as a common syntax for this use.
76 % To aid porting existing documents to Lua\TeX~0.87 this package does
77 % overload the \verb|\write| command so that
78 % \verb|\write18{rm file.txt}|
79 % will work with Lua\TeX. Note that the redefinition of \verb|\write|
80 % can not detect whether \verb|\immediate| has been used,
81 % \verb|\immediate| will work as normal when writing to file streams
82 % or the terminal but the special case of stream 18 which is defined to
83 % use \verb|os.execute| always uses \verb|\directlua| (so corresponds
84 % to \verb|\immediate\write18|. In the rare situations that you need
85 % non-immediate \verb|\write18| in a document being ported to current
86 % Lua\TeX, you will need to change to use the
87 % \verb|DelayedShellescape| command.
88
89 % \section{Implementation}
91 %    \begin{macrocode}
92 %<*package>
93 %    \end{macrocode}
95 % \subsection{Status Check}
98 % \changes{v0.2a}{2016/06/07}{spelling in messages}
99 %    \begin{macrocode}
100 \ifcase
101   \ifx\pdfshellescape\@undefined
102     \ifx\shellescape\@undefined
103       \ifx\directlua\@undefined
104         \z@
105       \else
106         \directlua{%
107           tex.sprint((status.shell_escape or os.execute()) .. " ")}
108       \fi
109     \else
110       \shellescape
111     \fi
112   \else
113     \pdfshellescape
114   \fi
115   \PackageWarning{shellesc}{Shell escape disabled}
117   \PackageInfo   {shellesc}{Unrestricted shell escape enabled}
118 \else
119   \PackageInfo   {shellesc}{Restricted shell escape enabled}
121 %    \end{macrocode}
123 % \subsection{The shellesc package interface}
125 % \begin{macro}{\ShellEscape}
126 % Execute the supplied tokens as a system dependent command, assuming 
127 % such execution is allowed.
128 %    \begin{macrocode}
129 \ifx\lastsavedimageresourcepages\@undefined
130   \protected\def\ShellEscape{\immediate\write18 }
131 %    \end{macrocode}
133 %    \begin{macrocode}
134 \else
135   \protected\def\ShellEscape#1{%
136     \directlua{os.execute("\luaescapestring{#1}")}}
138 %    \end{macrocode}
139 % \end{macro}
141 % \begin{macro}{\DelayedShellEscape}
142 % \changes{v0.1c}{2016/04/29}{Define \cs{DelayedShellEscape} not \cs{ShellEscape}(UF)}
143 % Execute the supplied tokens as a system dependent command, when this
144 % node is shipped out with the completed page, assuming 
145 % such execution is allowed.
146 %    \begin{macrocode}
147 \ifx\lastsavedimageresourcepages\@undefined
148   \protected\def\DelayedShellEscape{\relax\write18 }
149 %    \end{macrocode}
151 %    \begin{macrocode}
152 \else
153   \protected\def\DelayedShellEscape#1{%
154     \latelua{os.execute("\luaescapestring{#1}")}}
156 %    \end{macrocode}
157 % \end{macro}
161 % \subsection{The write18 package interface}
163 % In web2c based engines other than Lua\TeX, |\write18| may be used
164 % directly.  The same was true in older LuaTeX, but from version 0.85
165 % onwards that is not available.
167 % The above |shellesc| package interface is recommended for new code,
168 % however for ease of porting existing documents and packages to newer
169 % Lua\TeX\ releases, a |\write18| interface is provided here via a
170 % call to Lua's |os.execute|.
172 % Note that as currently written this always does an \emph{immediate}
173 % call to the system.
175 % |\immediate| is supported but ignored, |\immediate\write18| and
176 % |\write18| both execute immediately. To use a delayed execution at
177 % the next shipout, use the |\DelayedShellEscape| command defined
178 % above.
180 % Note that it would be easy to make |\wriete18| defined here use
181 % delayed execution, just use |\DelayedShellEscape| instead of
182 % |ShellEscape| in the definition below. However detecting
183 % |\immediate| is tricky so the choice here is to always use the
184 % immediate form, which is overwhelmingly more commonly used with
185 % |\write18|.
187 % Stop at this point if not a recent Lua\TeX.
188 %    \begin{macrocode}
189 \ifx\lastsavedimageresourcepages\@undefined\expandafter\endinput\fi
190 %    \end{macrocode}
192 %    \begin{macrocode}
193 \directlua{%
194 %    \end{macrocode}
196 %    \begin{macrocode}
197 shellesc = shellesc or {}
198 %    \end{macrocode}
200 % Lua function to use the token scanner to grab the following \TeX\
201 % number, and then test if stream 18 is being used, and then insert an
202 % appropriate \TeX\ command to handle the following brace group in
203 % each case.
204 %    \begin{macrocode}
205 local function write_or_execute()
206   local s = token.scan_int()
207   if (s==18) then
208      tex.sprint(\the\numexpr\catcodetable@atletter\relax,
209                 "\string\\ShellEscape ")
210   else
211      tex.sprint(\the\numexpr\catcodetable@atletter\relax,
212                 "\string\\shellesc@write " .. s)
213   end
215 %    \end{macrocode}
217 %    \begin{macrocode}
218 shellesc.write_or_execute=write_or_execute
219 %    \end{macrocode}
221 %    \begin{macrocode}
223 %    \end{macrocode}
225 %    \begin{macrocode}
226 \let\shellesc@write\write
227 %    \end{macrocode}
229 %    \begin{macrocode}
230 \protected\def\write{\directlua{shellesc.write_or_execute()}}
231 %    \end{macrocode}
235 %    \begin{macrocode}
236 %</package>
237 %    \end{macrocode}
239 % \Finale