On 12 December 2010 Patrick Gundlach wrote:

 > Hello Reinhard,
 > 
 > > these are two different questions.  First, the #! line works
 > > everywhere except on Windows.  It finds the interpreter (not your
 > > script) in PATH.  There is no reasonable alternative on Windows.
 > > You have to associate filename extensions with interpreters in
 > > the registry.  If you are using TeX Live, you can start your
 > > script from a wrapper instead.
 > 
 > OK, thanks.
 > 
 > > Try this:
 > > -------------------------------------------------------
 > > #!/usr/bin/env texlua
 > > 
 > > dirname, filename = string.match(arg[0], '(.*[/\\])(.*)')
 > > 
 > > print('dirname='..dirname)
 > > print('filename='..filename)
 > > -------------------------------------------------------
 > > 
 > > it works as expected on Unix:
 > > 
 > 
 > On every Unix? I once tried this with sh (echo $0) and if I
 > remember correctly it gave me a relative path on solaris and an
 > absolute path on linux.

Hi Patrick,
it depends on how you invoke the program.  If you specify a path on
the command line, this path is used.  It might be absolute or relative
to $PWD.  For instance:

$ /usr/local/bin/testarg0.lua
dirname=/usr/local/bin/
$ ../../../../usr/local/bin/testarg0.lua 
dirname=../../../../usr/local/bin/

If you don't specify a path, /usr/bin/env searches the binary in PATH.

$ testarg0.lua 
dirname='/usr/local/bin/'

I assume that /usr/bin/env is available on all Unix systems.  I've
read somewhere that some shells require a space after #! but it seems
that it's not required on the Unix supported by TeX Live.

I'm wondering why you prefer an absolute path.  It actually doesn't
matter.  You can write

   dirname = string.match(arg[0], '(.*[/\\])(.*)')
   package.path = dirname .. "../modules/"
   require "mylib"

and mylib.lua will be found regardless whether the path to the program
is absolute or relative.

 > > You will certainly get similar results in TeX Live
 > 
 > I don't use TeXlive in this case, just one LuaTeX binary for luatex
 > and texlua.
 > 
 > > because the location of your script is determined by the wrapper,
 > > and hence by kpathsea, which returns the full path.  Please note
 > > that dirname found by string.match() in the example above
 > > contains the leading directory separator already and that
 > > backslashes are supported too.
 > 
 > So I assume from your answer that arg[0] in my lua skript is set by
 > kpathsea, and it contains the full path. So I can find out where I
 > am by looking at it?

Sorry, I was quite unprecise.  kpathsea is only involved if the script
is launched by a wrapper and the wrappers are only for Windows.  They
are needed because there are no symlinks on Windows and because we
have to set a few environment variables for the hidden Perl and
Ghostscript before launching a script.

If you want to provide a tiny distribution for several platforms, you
can steal some stuff from TeX Live.  One nice thing is that, if you
use the wrappers, you don't have to put anything into the registry.
All you have to do is to add bin/win32 to PATH.  The wrappers are
explained in detail in bin/win32/runscript.tlu.

There is one thing which can cause trouble.  Sorry that it didn't come
earlier to my mind.  Because runscript is mostly written in texlua, it
doesn't invoke Lua scripts as usual.  For efficiency, it determines
the location of the script and then runs the Lua function dofile().  
I don't know which impact this has on arg[0], but, if necessary, you
can always change runscript.tlu so that it invokes Lua scripts as it
invokes Perl scripts, i.e. with os.spawn().  It's advantageous, at
least, that the wrappers are written in a scripting language and can
easily be adapted.  Below is an excerpt from runscript.tlu.

Regards,
  Reinhard



  Script wrappers in TeX Live on Windows
  
  Rationale
  
    Wrappers enable use of scripts on Windows as regular programs.  
    They are also required for some binary programs to set up the 
    right environment for them. 
    
    Batch scripts can be used for wrapping but they are not as universal 
    as binaries (there are some odd cases where they don't work) and 
    it is hard to make them robust and secure.  Compiled binary wrappers 
    don't suffer from these problems but they are harder to write, debug
    and maintain in comparison to scripts.  For these reasons a hybrid 
    approach is taken that combines a binary stub with a launcher script.
  
  Adding wrappers for user scripts
  
    The script wrapping machinery is not limited to scripts shipped with 
    TeX Live.  You can also use it for script programs from manually 
    installed packages, which should minimize the problems when using 
    them with TeX Live. 
    
    First, make sure that there is an interpreter program available on 
    your system for the script you want to use.  Interpreters for Perl 
    and Lua are bundled with TeX Live, all others have to be installed 
    independently.  Lua scripts are the most efficient to run, so if you
    consider writing a new script, that would be the recommended choice.
    
    The following script types and their file extensions are currently 
    supported and searched in that order:
    
      Lua      (.tlu;.texlua;.lua) --  included
      Perl     (.pl)               --  included
      Ruby     (.rb)               --  requires installation
      Python   (.py)               --  requires installation
      Tcl      (.tcl)              --  requires installation
      Java     (.jar)              --  requires installation
      VBScript (.vbs)              --  part of Windows
      JScript  (.js)               --  part of Windows
      Batch    (.bat;.cmd)         --  part of Windows
    
    Finally, Unix-style extensionless scripts are searched as last and 
    the interpreter program is established based on the she-bang (#!) 
    specification on the very first line of the script.  This can be 
    an arbitrary program but it must be present on the search path.
    
    Next, the script program needs to be installed somewhere below the 
    'scripts' directory under one of the TEXMF trees (consult the 
    documentation or texmf/web2c/texmf.cnf file for a list).  You may 
    need to update the file search database afterwards with:
    
      mktexlsr [TEXMFDIR]
      
    It is also possible to use scripts that are outside of TEXMF hierarchy 
    by adjusting TEXMFSCRIPTS environment or kpathsea variable, see 
    kpathsea documentation for more information on setting its variables.
    
    Test if the script can be located with:
    
      kpsewhich --format=texmfscripts <script-name>.<ext>
    
    This should output the full path to the script if everything is 
    properly installed and configured.  If this test is successful, 
    the script can be run immediately with:
    
      runscript <script-name> [script arguments]
    
    If you prefer to call the script program simply by its name, copy 
    and rename bin/win32/runscript.exe to <script-name>.exe and put it 
    in bin/win32/ directory of your TeX Live installation or, if you 
    don't have the write permissions there, somewhere else on the search 
    path.]]

local docstr = [[

  Wrapper structure
  
    Wrappers consist of small binary stubs and a common texlua script.  
    The binary stubs are all the same, just different names (but CLI 
    and GUI stubs differ, see below, and GUI stubs are actually all 
    different due to different embedded icons).
    
    The job of the binary stub is twofold: (a) call the texlua launcher
    script 'runscript.tlu' from the same directory (or more precisely 
    from the directory containing 'runscript.dll') and (b) pass to it 
    argv[0] and the unparsed argument string as the last two arguments 
    (after adding a sentinel argument, which ends with a new line 
    character).  Arbitrary C strings can be passed, because the script 
    is executed by linking with luatex.dll and calling the lua 
    interpreter internally rather than by spawning a new process.
    
    There are two flavours of the binary stub: one for CLI programs 
    and another one for GUI programs.  The GUI variant does not open 
    a console window nor does it block the command prompt if started 
    from there.  It also uses a dialog box to display an error message 
    in addition to outputting to stderr.
    
    The stubs are further split into a common DLL and EXE proxies 
    to it.  This is for maintenance reasons - updates can be done by 
    replacement of a single DLL rather than all binary stubs.
    
    The launcher script knows, which variant has been used to invoke it 
    based on the sentinel argument.  The lack of this argument means 
    that it was invoked in a standard way, i.e. through texlua.exe. 
    
    All the hard work of locating a script/program to execute happens 
    in the launcher script.  The located script/program is always 
    executed directly by spawning its interpreter (or binary) in a new 
    process. The system shell (cmd.exe) is never called (except for 
    batch scripts, of course).  If the located script happens to be 
    a (tex)lua script, it is loaded and called internally from within 
    this script, i.e. no new process is spawned.  Execution is done 
    using a protected call, so any compile or runtime errors are catched.
    
  Source files
  
    runscript.tlu     launcher script for locating and dispatching 
                      target scripts/programs
    runscript_dll.c   common DLL part of the binary stubs; locates and
                      calls the launcher script
    runscript_exe.c   EXE proxy to the common DLL for CLI mode stubs
    wrunscript_exe.c  EXE proxy to the common DLL for GUI mode stubs
  

-- 
----------------------------------------------------------------------------
Reinhard Kotucha                                      Phone: +49-511-3373112
Marschnerstr. 25
D-30167 Hannover                              mailto:[email protected]
----------------------------------------------------------------------------
Microsoft isn't the answer. Microsoft is the question, and the answer is NO.
----------------------------------------------------------------------------
_______________________________________________
dev-luatex mailing list
[email protected]
http://www.ntg.nl/mailman/listinfo/dev-luatex

Reply via email to