%M \logo [VIM] {VIM} % Needed for the title

%D \module
%D   [      file=t-vim,
%D        version=2008.07.15,
%D          title=\VIM\ to \CONTEXT,
%D       subtitle=Use \VIM\ to generate code listing,
%D         author=Mojca Miklavec \& Aditya Mahajan,
%D          email=adityam at umich dot edu,
%D           date=\currentdate,
%D      copyright=Public Domain]

%M
%M \usemodule [vim]
%M \usemodule[int-load]
%M \loadsetups[t-vim.xml]
%M \usetypescript[modern-base][texnansi] \setupbodyfont[modern]
%M \setuptyping[option=color]
%M \setupcolors[state=start]

%D \section   {User Manual}
%D
%D \CONTEXT\ has an excellent pretty printing capabilities for many languages.
%D The code for pretty printing is written in \TEX, and due to catcode
%D jugglery verbatim typesetting is perhaps the trickiest part of \TEX. This
%D makes it difficult for a \quotation{normal} user to define syntax
%D highlighting rules for a new language. This module, takes the onus of
%D defining syntax highlighting rules away from the user and uses \VIM\ editor
%D to generate the syntax highlighting.  There is a helper
%D \filename{2context.vim} script to do the syntax parsing in \VIM. This is a
%D stop|-|gap method, and hopefully with \LUATEX, things will be much easier. 
%D
%D The main macro of this module is \type{\definevimtyping}. The best way to
%D explain it is by using an example. Suppose you want to pretty print ruby
%D code in \CONTEXT. So you can do
%D \starttyping
%D \definevimtyping [RUBY]  [syntax=ruby]
%D \stoptyping
%D after which you can get ruby highlighting by
%D \starttyping
%D \startRUBY
%D ....
%D \stopRUBY
%D \stoptyping
%D
%D For example
%D \startbuffer
%D \definevimtyping [RUBY] [syntax=ruby]
%D
%D \startRUBY
%D #! /usr/bin/ruby
%D # This is my first ruby program
%D puts "Hello World"
%D \stopRUBY
%D \stopbuffer
%D {\getbuffer}
%D This was typed as \typebuffer
%D
%D The typing can be setup using \type{\setupvimtyping}.
%D
%D \showsetup{setupvimtyping}
%D
%D Here \type{syntax} is the syntax file in \VIM\ for the language
%D highlighting that you want. See \type{:he syntax.txt} inside \VIM\ for
%D details. \type{colorscheme} provides the syntax highlighting for various
%D regions. Right now, two colorschemes are defined. The \type{default}
%D colorscheme is based on on \filename{ps_color.vim} colorscheme in \VIM, and
%D the \type{blackandwhite} colorscheme is based on \filename{print_bw.vim}.
%D If there is a particular colorscheme that you will like, you can convert it
%D into \CONTEXT. \type{space=(yes|on|no)} makes the space significant,
%D visible, and insignificant respectively. \type{tab} specifies the number of
%D spaces a tab is equivalent to. It's default value is 8. \type{start} and
%D \type{stop} specify which lines to read from a file. These options only
%D make sense for highlighting files and should not to be set by
%D \type{\setupvimtyping}.  \type{numbering} enables line numbering, and
%D \type{step} specifies which lines are numbered. \type{numberstyle} and
%D \type{numbercolor} specify the style and color of line numbers. By
%D default the numbers are placed on the left. The location of the numbers can
%D be configured using \type{numbercommand} option.
%D
%D A new typing region can be define using \type{\definevimtyping}.
%D
%D \showsetup{definevimtyping}
%D
%D Minor changes in syntax highlighting can be made easily. For example, Mojca
%D likes \quote{void} to be bold in C programs. This can be done as follows
%D
%D \startbuffer
%D \definevimtyping [C] [syntax=c,numbering=on]
%D 
%D \startvimcolorscheme[default]
%D 
%D \definevimsyntax
%D   [Type]
%D   [style=boldmono]
%D
%D \definevimsyntax
%D   [PreProc]
%D   [style=slantedmono]
%D 
%D \stopvimcolorscheme
%D 
%D \startC
%D #include <stdio.h>
%D #include <stdlib.h>
%D 
%D void main() 
%D {
%D    printf("Hello World\n") ;
%D    return;
%D }
%D \stopC
%D \stopbuffer 
%D \typebuffer which gives {\getbuffer}
%D
%D The second command provided by this module is \type{\definetypevimfile} for
%D typesetting files.  The syntax of this command is
%D
%D \showsetup{definetypevimfile}
%D
%D For example, to pretty print a ruby file you can do
%D \starttyping
%D \definetypevimfile[typeRUBY] [syntax=ruby]
%D \stoptyping
%D after which one can use
%D \starttyping
%D \typeRUBY[option]{rubyfile}
%D \stoptyping
%D
%D We hope that this is sufficient to get you started. The rest of this
%D document gives the implementation details of the module. If you want to
%D change something, read ahead.

%D \section   {Module Details}
%D The syntax highlighting of the source here is done using \type{t-vim}
%D module. There is a bug in the module due to which line numberings for
%D different filetypes use the same counter. In the source round||about
%D method to correct this. Right now, in case someone needs this module for
%D numbering more than one filetype, let me know, and I will try to iron
%D out the bug.

%M % Due to the bug in numbering
%M \definevimtyping [definition]  [syntax=context,start=1,numbering=on]

\writestatus  {loading}   {Context Module for ViM Sytax Highlighting}

%M \definevimtyping [definition]  [syntax=context,start=continue,numbering=on]

\startmodule[vim]

\unprotect

\definesystemvariable {vs}  % Vim Syntax

%D First of all we take care of bold monotype. By default, \CONTEXT\ uses
%D latin modern fonts. If you want to get bold monotype in latin modern, you
%D need to use \type{modern-base} typescript. For example:
%D \starttyping
%D \usetypescript[modern-base][texnansi] \setupbodyfont[modern]
%D \starttext
%D {\tt\bf This is bold monotype}
%D \stoptext
%D \stoptyping
%D \CONTEXT\ does not provide any style alternative for bold monotype and
%D slanted monotype, so we provide one here. These will only work if your font
%D setup knows about bold and slanted monotype.

\definealternativestyle [\v!bold\v!mono,\v!mono\v!bold]       [\ttbf] []
\definealternativestyle [\v!slanted\v!mono,\v!mono\v!slanted] [\ttsl] []

%D \macros{startvimcolorscheme}
%D To start a new vim colorscheme.

\def\startvimcolorscheme[#1]%
  {\pushmacro\vimcolorscheme
   \edef\vimcolorscheme{#1}}

\def\stopvimcolorscheme
  {\popmacro\vimcolorscheme}

%D \macros{definevimsyntax, definevimsyntaxsynonyms} 
%D These macros should always occur inside a \type{\startvimcolorschme}
%D \unknown \type{\stopvimcolorscheme} pair.  The \type{\definevimsyntax}
%D macro defines syntax highlighting rules for \VIM's syntax highlighting
%D regions. It takes three arguments \type{style}, \type{color} and
%D \type{command}. The most common \VIM\ syntax highlighting regions are defined
%D in the end of this file. The \type{\definevimsyntaxsynonyms} macro just
%D copies the settings from another syntax highlighting region.

\def\definevimsyntax
  {\dodoubleargumentwithset\dodefinevimsyntax}

\def\dodefinevimsyntax[#1]% [#2]
  {\getparameters[\??vs\vimcolorscheme#1]} %[#2]

\def\definevimsyntaxsynonyms
  {\dodoubleargumentwithset\dodefinevimsyntaxsynonyms}

\def\dodefinevimsyntaxsynonyms[#1][#2]%
  {\copyparameters[\??vs\vimcolorscheme#1][\??vs\vimcolorscheme#2]
                  [\c!style,\c!color,\c!command]}


%D \macros{vimsyntax}
%D This is just a placeholder macro. The \filename{2context.vim} script marks
%D the highlightin reigions by \type{\s[...]{...}}. While typing the generated
%D files, we locally redefine \type{\s} to \type{\vimsyntax}.

\def\vimsyntax[#1]#2%
  {\dostartattributes{\??vs\vimcolorscheme Normal}\c!style\c!color\empty%
   \dostartattributes{\??vs\vimcolorscheme #1}\c!style\c!color\empty%
   \getvalue{\??vs\vimcolorscheme #1\c!command}{#2}%
    \dostopattributes%
    \dostopattributes}

%D \macros{setupvimtyping, typevimfile}
%D There are three settings for \type{\setupvimtyping}: \type{syntax}, which
%D tells \VIM\ which syntax rules to use; \type{tab}, which sets the
%D \type{tabstop} in \VIM; and \type{space} which takes care of spaces.
%D
%D \type{\typevimfile} macro basically calls \VIM\ with appropriate settings and
%D sources the \filename{2context.vim} script. The result is slow, because
%D parsing by \VIM\ is slow. Do not use this method for anything larger than a
%D few hundred lines. For large files, one option is to pre||prase them, and
%D then typeset the result. We have not provided any interface for that, but
%D it is relatively easy to implement.
%D
%D Taking care of line||numbering is more tricky. We could not get
%D \type{\setuplinenumbering} to work properly, so implement our own
%D line||numbering mechanism. This is a bit awkward, since it places
%D line||number after each \type{^M} in the source file. So, if the source
%D code line is larger than one typeset line, the line number will be on the
%D second line. To do it correctly, we need to read lines from the vimsyntax
%D file one|-|by|-|one. Our own mechanism for line||numbering is plain.
%D Unlike \CONTEXT's core verbatim highlighting, multiple blank lines are
%D displayed and numbered.

\def\setupvimtyping
  {\dosingleargument\getparameters[\??vs]}

\def\typevimfile
  {\dosingleempty\dotypevimfile}

\def\notypevimfile[#1][#2]#3%
  {\dotypevimfile[#1,#2]{#3}}

\def\dotypevimfile[#1]#2%
  {\doiffileelse{#2}
   {\dodotypevimfile[#1]{#2}}
   {\reporttypingerror{#2}}}


\def\saveandtypevimfile[#1]%
  {\savevimbuffer
   \dotypevimfile[#1]{\TEXbufferfile{vimsyntax}}}


\let\savevimbuffer\donothing

\beginLUATEX

\def\savevimbuffer{\savebuffer[vimsyntax]}

\endLUATEX

\def\dodotypevimfile[#1]#2%
  {\@@vsbefore
   \bgroup
   \initializevimtyping{#1}%
   \runvimsyntax{#2}%
    % The strut is needed for the output to be the same when not using
    % numbering. Otherwise, multiple par's are ignored. We need to figure out
    % a mechanism to imitate this behaviour even while using line numbering.
    \ifconditional\vimtypinginline \else
      \strut%else the first line is shifted to the left
    \fi
    \input #2-vimsyntax.tmp\relax%
    \ifconditional\vimtypinginline \removeunwantedspaces \fi
   \egroup
   \@@vsafter}

\makecounter{vimlinenumber}

\def\doplacevimlinenumber 
  {%Always place the first linenumber
   \showvimlinenumber
   %Calculate step in futute
   \let\placevimlinenumber\dodoplacevimlinenumber
   \pluscounter{vimlinenumber}}

\def\dodoplacevimlinenumber
  {\ifnum\numexpr(\countervalue{vimlinenumber}/\@@vsstep)*\@@vsstep\relax=%
         \numexpr\countervalue{vimlinenumber}\relax
      \showvimlinenumber
  \fi
   \pluscounter{vimlinenumber}}
   
\def\showvimlinenumber
  {\@@vsnumbercommand
      {\dostartattributes\??vs\c!numberstyle\c!numbercolor\empty
       \countervalue{vimlinenumber}
       \dostopattributes}}

\def\initializevimtyping#1%
  {\setupvimtyping[#1]%
   %Make sure that stop is not empty
   \ifconditional\vimtypinginline \else
     \doifempty{\@@vsstop}{\setvalue{\@@vsstop}{0}}%
     \doifelse{\@@vsstart}{\v!continue}
      {\setvalue{@@vsstart}{\countervalue{vimlinenumber}}}
      {\setcounter{vimlinenumber}{\doifnumberelse{\@@vsstart}{\@@vsstart}{1}}}%
     \whitespace
    %\page[\v!preference]} gaat mis na koppen, nieuw: later \nobreak
     \setupwhitespace[\v!none]%
     \obeylines
   \fi
   \ignoreeofs
   \ignorespaces
   \let\s=\vimsyntax
   \def\tab##1{\dorecurse{##1}{\space}}% TODO: allow customization
   \def\vimcolorscheme{\@@vscolorscheme}%
   \ifconditional\vimtypinginline 
    \let\placevimlinenumber\relax
   \else
     \activatespacehandler\@@vsspace
     \processaction[\@@vsnumbering]
     [     \v!on=>\let\placevimlinenumber\doplacevimlinenumber,
          \v!off=>\let\placevimlinenumber\relax,
      \s!unknown=>\let\placevimlinenumber\relax,
      \s!default=>\let\placevimlinenumber\relax,
     ]%
     \def\obeyedline{\placevimlinenumber\par\strut}%
   \fi
   }


\def\shellescapedquote{\letterbackslash\letterdoublequote}
\def\shellescapedquote{\letterdoublequote}

\def\runvimsyntax#1%
{\executesystemcommand
      {mtxrun --verbose --noquotes bin:vim ""
           -u NONE  % No need to read unnessary configurations
           -e       % run in ex mode
           -C       % Set compatibile
           -n       % No swap
%          -V10log  % For debugging only, will go away later.
           -c \shellescapedquote set tabstop=\@@vstab \shellescapedquote\space    
           -c \shellescapedquote syntax on\shellescapedquote\space 
           -c \shellescapedquote set syntax=\@@vssyntax\shellescapedquote\space
           -c \shellescapedquote let contextstartline=\@@vsstart\shellescapedquote\space
           -c \shellescapedquote let contextstopline=\@@vsstop\shellescapedquote  \space
           -c \shellescapedquote source kpse:2context.vim\shellescapedquote\space
           -c \shellescapedquote wqa\shellescapedquote\space    
            \shellescapedquote#1\shellescapedquote}}


%D \macros{definetypevimfile}
%D This macro allows you to define new file typing commands. For example
%D \starttyping
%D \definetypevimfile[typeRUBY] [syntax=ruby]
%D \stoptyping
%D after which one can use
%D \starttyping
%D \typeRUBY[option]{rubyfile}
%D \stoptyping

\def\definetypevimfile
  {\dodoubleargument\dodefinetypevimfile}

\def\dodefinetypevimfile[#1][#2]%
  {\unexpanded\setvalue{#1}{\dodoubleempty\notypevimfile[#2]}}

%D \macros{definevimtyping}
%D
%D This macro allows you to pretty print code snippets. For example
%D \startbuffer
%D \definevimtyping [RUBY] [syntax=ruby]
%D \startRUBY
%D # This is my first ruby program
%D puts "Hello World"
%D \stopRUBY
%D \stopbuffer
%D \typebuffer gives \getbuffer

%M %More bug fixes to get the line numbering in documentation right.
%M \definevimtyping [definition]  [syntax=context,start=119,numbering=on]

\def\definevimtyping
  {\dodoubleargument\dodefinevimtyping}

%M %More bug fixes to get the line numbering in documentation right.
%M \definevimtyping [definition]  [syntax=context,start=continue,numbering=on]

\newconditional\vimtypinginline \setfalse\vimtypinginline

\def\dodefinevimtyping[#1][#2]%
  {\setevalue{\e!start#1}%
    {\setfalse\vimtypinginline
     \noexpand\dostartbuffer[vimsyntax][\e!start#1][\e!stop#1]}%
   \setvalue{\e!stop#1}{\saveandtypevimfile[#2]}%
  \setevalue{\e!start inline#1}%
    {\settrue\vimtypinginline
     \noexpand\dostartbuffer[vimsyntax][\e!start inline#1][\e!stop inline#1]}%
   \setvalue{\e!stop inline#1}{\saveandtypevimfile[#2]}}


%D Some defaults.

\setupvimtyping
  [        syntax=context,
           \c!tab=8,
         \c!space=\v!yes,
         \c!start=1,
          \c!stop=0,
        \c!before=,
         \c!after=,
     \c!numbering=\v!off,
 \c!numbercommand=\inleft, 
   \c!numberstyle=\v!smallslanted,
   \c!numbercolor=,
          \c!step=1,
      colorscheme=default,
  ]

%D Pre-defined Syntax : % {{{ 
%D This is based on \filename{ps_color.vim}, which does not use any bold
%D typeface.

%D \VIM\ uses hex mode for setting colors, I do not want to convert them to rgb
%D values.

\startvimcolorscheme[default]

\setupcolor[hex]

\definecolor  [vimsyntax!default!Special]     [h=907000]
\definecolor  [vimsyntax!default!Comment]     [h=606000]
\definecolor  [vimsyntax!default!Number]      [h=907000]
\definecolor  [vimsyntax!default!Constant]    [h=007068]
\definecolor  [vimsyntax!default!PreProc]     [h=009030]
\definecolor  [vimsyntax!default!Statement]   [h=2060a8]
\definecolor  [vimsyntax!default!Type]        [h=0850a0]
\definecolor  [vimsyntax!default!Todo]        [h=e0e090]

\definecolor  [vimsyntax!default!Error]       [h=c03000]
\definecolor  [vimsyntax!default!Identifier]  [h=a030a0]
\definecolor  [vimsyntax!default!SpecialKey]  [h=1050a0]
\definecolor  [vimsyntax!default!Underline]   [h=6a5acd]


\definevimsyntax
  [Normal]
  [\c!style=\tttf,\c!color=\maintextcolor]

\definevimsyntax 
  [Constant]
  [\c!style=\v!mono,\c!color=vimsyntax!default!Constant]

\definevimsyntaxsynonyms
  [Character,Boolean,Float]
  [Constant]

\definevimsyntax
  [Number]
  [\c!style=\v!mono,\c!color=vimsyntax!default!Number]

\definevimsyntax
  [Identifier]
  [\c!style=\v!mono,\c!color=vimsyntax!default!Identifier]

\definevimsyntaxsynonyms
  [Function]
  [Identifier]

\definevimsyntax 
  [Statement]
  [\c!style=\v!mono,\c!color=vimsyntax!default!Statement]

\definevimsyntaxsynonyms
  [Conditional,Repeat,Label,Operator,Keyword,Exception]
  [Statement]

\definevimsyntax 
  [PreProc]
  [\c!style=\v!mono,\c!color=vimsyntax!default!PreProc]

\definevimsyntaxsynonyms
  [Include,Define,Macro,PreCondit]
  [PreProc]

\definevimsyntax 
  [Type,StorageClass, Structure, Typedef]
  [\c!style=\v!mono, \c!color=vimsyntax!default!Type]

\definevimsyntax 
  [Special]
  [\c!style=\v!mono,\c!color=vimsyntax!default!Special]

\definevimsyntax 
  [SpecialKey]
  [\c!style=\v!mono,\c!color=vimsyntax!default!SpecialKey]

\definevimsyntax
  [Tag,Delimiter]
  [\c!style=\v!mono]

\definevimsyntax
  [Comment,SpecialComment]
  [\c!style=\v!mono,\c!color=vimsyntax!default!Comment]

\definevimsyntax
  [Debug]
  [\c!style=\v!mono]

\definevimsyntax
  [Underlined]
  [\c!style=\v!mono,\c!command=\underbar]

\definevimsyntax 
  [Ignore]
  [\c!style=\v!mono]

\definevimsyntax 
  [Error]
  [\c!style=\v!mono,\c!color=vimsyntax!default!Error]

\definevimsyntax 
  [Todo]
  [\c!style=\v!mono,\c!color=vimsyntax!default!Todo]

\stopvimcolorscheme
% }}}

\startvimcolorscheme[blackandwhite]

\definevimsyntax
  [Normal]
  [\c!style=\tttf,\c!color=\maintextcolor]

\definevimsyntax 
  [Constant]
  [\c!style=\v!mono,\c!color=]

\definevimsyntaxsynonyms
  [Character,Boolean,Float]
  [Constant]

\definevimsyntax
  [Number]
  [\c!style=\v!mono,\c!color=]

\definevimsyntax
  [Identifier]
  [\c!style=\v!mono,\c!color=]

\definevimsyntaxsynonyms
  [Function]
  [Identifier]

\definevimsyntax 
  [Statement]
  [\c!style=\v!mono\v!bold,\c!color=]

\definevimsyntaxsynonyms
  [Conditional,Repeat,Label,Operator,Keyword,Exception]
  [Statement]

\definevimsyntax 
  [PreProc]
  [\c!style=\v!bold\v!mono,\c!color=]

\definevimsyntaxsynonyms
  [Include,Define,Macro,PreCondit]
  [PreProc]

\definevimsyntax 
  [Type,StorageClass, Structure, Typedef]
  [\c!style=\v!bold\v!mono, \c!color=]

\definevimsyntax 
  [Special]
  [\c!style=\v!mono,\c!color=]

\definevimsyntax 
  [SpecialKey]
  [\c!style=\v!mono,\c!color=]

\definevimsyntax
  [Tag,Delimiter]
  [\c!style=\v!mono,\c!color=]

\definevimsyntax
  [Comment,SpecialComment]
  [\c!style=\v!slanted\v!mono,\c!color=]

\definevimsyntax
  [Debug]
  [\c!style=\v!mono,\c!color=]

\definevimsyntax
  [Underlined]
  [\c!style=\v!mono,\c!color=,\c!command=\underbar]

\definevimsyntax 
  [Ignore]
  [\c!style=\v!mono,\c!color=]

\definevimsyntax 
  [Error]
  [\c!style=\v!mono,\c!color=,\c!command=\overstrike]

\definevimsyntax 
  [Todo]
  [\c!style=\v!mono,\c!command=\inframed]

\stopvimcolorscheme
% }}}


\protect

\stopmodule


%D An example usage: % {{{

\doifnotmode{demo}{\endinput}

\setupcolors[state=start]

\usetypescript[modern-base][texnansi]

\setupbodyfont[modern,10pt]

\starttext

\title{Matlab Code Listing -- Color}

\definevimtyping  [MATLAB]  [syntax=matlab]

\startMATLAB
function russell_demo()
% Do the example in ch 17 (p501) of Russell and Norvig
% (1,1) is top left corner.
r = 3; c = 4; p = 0.8; action_cost = -1/25;
obstacle = zeros(r,c); obstacle(2,2)=1;
terminal = zeros(r,c); terminal(1,4)=1; terminal(2,4)=1;
absorb = 1;
wrap_around = 0;
noop = 0;
T = mk_grid_world(r, c, p, obstacle, terminal, absorb, wrap_around, noop);
% Add rewards for terminal states
nstates = r*c + 1;
if noop
  nact = 5;
else
  nact = 4;
end
R = action_cost*ones(nstates, nact);
R(10,:) = 1;
R(11,:) = -1;
R(nstates,:) = 0;
discount_factor = 1;

V = value_iteration(T, R, discount_factor);
%reshape(V(1:end-1),[r c])
%    0.8116    0.8678    0.9178    1.0000
%    0.7616    0.7964    0.6603   -1.0000
%    0.7053    0.6553    0.6114    0.3878
% Same as the book p501

Q = Q_from_V(V, T, R, discount_factor);
[V, p] = max(Q, [], 2);


use_val_iter = 1;
% (I-gT) is singular since g=1 and there is an absorbing state (i.e., T(i,i)=1)
% Hence we cannot use value determination.
[p,V] = policy_iteration(T, R, discount_factor, use_val_iter);

%reshape(V(1:end-1),[r c])
%    0.8115    0.8678    0.9178    1.0000
%    0.7615    0.7964    0.6603   -1.0000
%    0.7048    0.6539    0.6085    0.3824
\stopMATLAB

\title{Lua Code Listing -- Black and White}

\definevimtyping  [LUA]  [syntax=lua,colorscheme=blackandwhite]

\startLUA
-- version   : 1.0.0 - 07/2005
-- author    : Hans Hagen - PRAGMA ADE - www.pragma-ade.com
-- copyright : public domain or whatever suits
-- remark    : part of the context distribution

-- TODO: name space for local functions

-- loading: scite-ctx.properties

-- generic functions

local crlf = "\n"

function traceln(str)
    trace(str .. crlf)
    io.flush()
end

table.len  = table.getn
table.join = table.concat

function table.found(tab, str)
    local l, r, p
    if string.len(str) == 0 then
        return false
    else
        l, r = 1, table.len(tab)
        while l <= r do
            p = math.floor((l+r)/2)
            if str < tab[p] then
                r = p - 1
            elseif str > tab[p] then
                l = p + 1
            else
                return true
            end
        end
        return false
    end
end

function string.grab(str, delimiter)
    local list = {}
    for snippet in string.gfind(str,delimiter) do
        table.insert(list, snippet)
    end
    return list
end

function string.join(list, delimiter)
    local size, str = table.len(list), ''
    if size > 0 then
        str = list[1]
        for i = 2, size, 1 do
            str = str .. delimiter .. list[i]
        end
    end
    return str
end

function string.spacy(str)
    if string.find(str,"^%s*$") then
        return true
    else
        return false
    end
end

function string.alphacmp(a,b,i) -- slow but ok
    if i and i > 0 then
        return string.lower(string.gsub(string.sub(a,i),'0',' ')) < string.lower(string.gsub(string.sub(b,i),'0',' '))
    else
        return string.lower(a) < string.lower(b)
    end
end

function table.alphasort(list,i)
    table.sort(list, function(a,b) return string.alphacmp(a,b,i) end)
end

function io.exists(filename)
    local ok, result, message = pcall(io.open,filename)
    if result then
        io.close(result)
        return true
    else
        return false
    end
end

function os.envvar(str)
    if os.getenv(str) ~= '' then
        return os.getenv(str)
    elseif os.getenv(string.upper(str)) ~= '' then
        return os.getenv(string.upper(str))
    elseif os.getenv(string.lower(str)) ~= '' then
        return os.getenv(string.lower(str))
    else
        return ''
    end
end

function string.expand(str)
    return string.gsub(str, "ENV%((%w+)%)", os.envvar)
end

function string.strip(str)
    return string.gsub(string.gsub(str,"^%s+",''),"%s+$",'')
end

function string.replace(original,pattern,replacement)
    local str = string.gsub(original,pattern,replacement)
--     print(str) -- indirect, since else str + nofsubs
    return str -- indirect, since else str + nofsubs
end

\stopLUA

% \title{Source Code of the Module}

% \typevimfile[numbering=on,numbercolor=red,step=5]{\jobname.tex}

\stoptext

% }}}
