2 Script wrappers in TeX Live on Windows
6 Wrappers enable use of scripts on Windows as regular programs.
7 They are also required for some binary programs to set up the
8 right environment for them.
10 Batch scripts can be used for wrapping but they are not as universal
11 as binaries (there are some odd cases where they don't work) and
12 it is hard to make them robust and secure. Compiled binary wrappers
13 don't suffer from these problems but they are harder to write, debug
14 and maintain in comparison to scripts. For these reasons a hybrid
15 approach is taken that combines a binary stub with a launcher script.
17 Adding wrappers for user scripts
19 The script wrapping machinery is not limited to scripts shipped with
20 TeX Live. You can also use it for script programs from manually
21 installed packages. This should minimize problems when using them
24 First, make sure that there is an interpreter program available on
25 your system for the script you want to use. Interpreters for Perl
26 and Lua are bundled with TeX Live, all others have to be installed
27 independently. Lua scripts are the most efficient to run, so if you
28 consider writing a new script, that would be the recommended choice.
30 The following script types and their file extensions are currently
31 supported and searched in that order:
33 Lua (.tlu;.texlua;.lua) -- included
34 Perl (.pl) -- included
35 Ruby (.rb) -- requires installation
36 Python (.py) -- requires installation
37 Tcl (.tcl) -- requires installation
38 Java (.jar) -- requires installation
39 VBScript (.vbs) -- part of Windows
40 JScript (.js) -- part of Windows
41 Batch (.bat;.cmd) -- part of Windows
43 Finally, Unix-style extensionless scripts are searched as last and
44 the interpreter program is established based on the she-bang (#!)
45 specification on the very first line of the script. This can be
46 an arbitrary program but it must be present on the search path.
48 Next, the script program needs to be installed somewhere below the
49 'scripts' directory under one of the TEXMF trees (consult the
50 documentation or texmf/web2c/texmf.cnf file for a list). You may
51 need to update the file search database afterwards with:
55 It is also possible to use scripts that are outside of TEXMF hierarchy
56 by adjusting TEXMFSCRIPTS environment or kpathsea variable, see
57 kpathsea documentation for more information on setting its variables.
59 Test if the script can be located with:
61 kpsewhich --format=texmfscripts <script-name>.<ext>
63 This should output the full path to the script if everything is
64 properly installed and configured. If this test is successful,
65 the script can be run immediately with:
67 runscript <script-name> [script arguments]
69 If you prefer to call the script program simply by its name, copy
70 and rename bin/win32/runscript.exe to <script-name>.exe and put it
71 somewhere on the search path.
75 Wrappers consist of small binary stubs and a common texlua script.
76 The binary stubs are all the same, just different names (but CLI
77 and GUI stubs differ, see below, and GUI stubs are actually all
78 different due to different embedded icons).
80 The job of the binary stub is twofold: (a) call the texlua launcher
81 script 'runscript.tlu' from the same directory (or more precisely
82 from the directory containing 'runscript.dll') and (b) pass to it
83 argv[0] and the unparsed argument string as the last two arguments
84 (after adding a sentinel argument, which ends with a new line
85 character). Arbitrary C strings can be passed, because the script
86 is executed by linking with luatex.dll and calling the lua
87 interpreter internally rather than by spawning a new process.
89 There are two flavours of the binary stub: one for CLI programs
90 and another one for GUI programs. The GUI variant does not open
91 a console window nor does it block the command prompt if started
92 from there. It also uses a dialog box to display an error message
93 in addition to outputting to stderr.
95 The stubs are further split into a common DLL and EXE proxies
96 to it. This is for maintenance reasons - updates can be done by
97 replacement of a single DLL rather than all binary stubs.
99 The launcher script knows, which variant has been used to invoke it
100 based on the sentinel argument. The lack of this argument means
101 that it was invoked in a standard way, i.e., through texlua.exe.
103 All the hard work of locating a script/program to execute happens
104 in the launcher script. The located script/program is always
105 executed directly by spawning its interpreter (or binary) in a new
106 process. The system shell (cmd.exe) is never called (except for
107 batch scripts, of course). If the located script happens to be
108 a (tex)lua script, it is loaded and called internally from within
109 this script, i.e. no new process is spawned. Execution is done
110 using a protected call, so any compile or runtime errors are catched.
114 runscript.tlu launcher script for locating and dispatching
115 target scripts/programs
116 runscript_dll.c common DLL part of the binary stubs; locates and
117 calls the launcher script
118 runscript_exe.c EXE proxy to the common DLL for CLI mode stubs
119 wrunscript_exe.c EXE proxy to the common DLL for GUI mode stubs
121 Compilation of binaries (requires luatex.dll in the same directory)
123 with gcc (size optimized):
125 gcc -Os -s -shared -o runscript.dll runscript_dll.c -L./ -lluatex
126 gcc -Os -s -o runscript.exe runscript_exe.c -L./ -lrunscript
127 gcc -mwindows -Os -s -o wrunscript.exe wrunscript_exe.c -L./ -lrunscript
129 with tcc (extra small size):
131 tiny_impdef luatex.dll
132 tcc -shared -o runscript.dll runscript_dll.c luatex.def
133 tcc -o runscript.exe runscript_exe.c runscript.def
134 tcc -o wrunscript.exe wrunscript_exe.c runscript.def
138 Originally written in 2009 by Tomasz M. Trzeciak, Public Domain.
141 'tl-w32-wrapper.texlua' by Reinhard Kotucha and Norbert Preining.
142 'tl-w32-wrapper.cmd' by Tomasz M. Trzeciak.
149 - minor fixes for path & extension list parsing
151 - added support for GUI mode stubs
153 - enable GUI mode stubs for dviout, psv and texworks;
154 - added generic handling of sys programs
155 - added restricted repstopdf to alias_table
157 - added 'readme.txt' and changelog
158 - added support and docs for calling user added scripts;
159 (use path of 'runscript.dll' instead of .exe stub to
160 locate 'runscript.tlu' script)
161 - limit search for shell_escape_commands to system trees
162 - added function for creating directory hierarchy
163 - fixed directory creation for dviout & texworks aliases
164 - fixed arg[0] of repstopdf & rpdfcrop
166 - restructured docs, added --help and --version options
167 (available only when invoked under 'runscript' name)
168 - use TEXMF_RESTRICTED_SCRIPTS kpse var for searching
169 shell_escape_commands
170 - changed command validation to handle a list of commands
171 - prepend GUI mode command(s) to the command list
172 - added support for .tcl scripts
174 - fixed fatal bug in extention_map definition for GUI mode
176 - encapsulated main chunk in a function to execute with
177 pcall for more robustness and better error catching
178 - added texdoctk to scripts4tlperl table
179 - added tlgs and tlperl to alias_table; callable as e.g.:
183 - ensure only backslash is used in USERPROFILE variable
184 (Adobe Reader crash case)
185 - fixed argument processing for direct execution under texlua
188 - Windows XP or newer required to run TeXworks
190 - added support for Perl scripts starting with eval-exec-perl
191 construct in place of she-bang (#!)
193 - run internal tlperl only with our Perl
194 - added fontinst to alias_table
195 - added support for all tex4ht commands from mk4ht.pl
196 - removed some unsued aliases
197 - some code refactoring and cleanup
199 - use of external Perl now requires kpathsea variable
200 TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL to be explicitly set to 1
201 - alias_table replaced with if-elseif-end tests to streamline
202 special cases and to avoid hardcoding of texmf* file paths
203 - added a2ping to special cases (requires -x switch to Perl)
204 - set ASYMPTOTE_GS (for asy) to full path to tlgs
206 - removed tex4ht commands starting with ht from mk4ht aliases;
207 they have their own scripts and mk4ht calls them internally,
208 so aliasing results in an infinite recursion
209 - removed alias for fontinst (no fontinst.exe any more)
210 - fixed GUI-mode interpreter for Ruby
212 - added -dDisableFAPI=true to psview argument list. Needed by
215 - added '-i', '.' to psview argument list (author's request)
216 - added environment clean up from Perl specific variables
217 (when not using external Perl)
219 - added alias for fmtutil
221 - added alias mkluatexfontdb -> luaotfload-tool
223 - fix for psview and UNC paths in unix-style
224 - remove not needed is_abs_path function