%D \module
%D   [      file=t-vimsyntax
%D        version=2006.12.26,
%D          title=ViM to \CONTEXT,
%D       subtitle=Use ViM to generate code listing,
%D         author=Mojca Miklavec \& Aditya Mahajan,
%D          email=<mojca.miklavec.lists@gmail.com>
%D           date=\currentdate,
%D      copyright=Public Domain]

%D \CONTEXT\ has an excellent pretty printing capabilities for many languages.
%D The code is written in \TEX, and due to catcode jugglary verbatim
%D typesetting is perhaps the trickiest part of \TEX. This makes it difficult
%D for a \quotation{normal} user to define syntax highlighting rules for a new
%D language. This module, takes the onus of defining syntax highlighting rules
%D away from the user and uses ViM editor to generate the syntax highlighting.
%D There is a helper \filename{2context.vim} script to do the syntax parsing
%D in ViM. This is a stop|-|gap method, and hopefully with \LUATEX, things
%D will be much easier. 

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

\startmodule[vimsyntax]

\unprotect

\definesystemvariable {vs}  % Vim Syntax

%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 \macro{vimsyntax}
%D This macro is inserted by \filename{2context.vim} script, and takes care of
%D properly highlighting different syntax regions.

\def\vimsyntax
  {\dosingleargument\dovimsyntax}

\def\dovimsyntax[#1]#2%
  {\dostartattributes{\??vs\vimcolorscheme Normal}\c!style\c!color\empty%
   \dostartattributes{\??vs\vimcolorscheme #1}\c!style\c!color\empty%
   \getvalue{\??vs#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.

\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\dodotypeVIMfile[#1]#2%
  {\bgroup
   \initializeVIMtyping{#1}
   \def\vimcolorscheme{\@@vscolorscheme}
   \runVIMsyntax{#2}
   \startlines \input #2-vimsyntax.tmp \stoplines
   \@@vsafter
   \egroup}

\def\initializeVIMtyping#1
  {\setupVIMtyping[#1]
   %Make sure that stop is not empty
   \doifempty{\@@vsstop}{\setvalue{\@@vsstop}{0}}
   \@@vsbefore
   \setuplines[space=\@@vsspace]}

\def\runVIMsyntax#1
   {\executesystemcommand
      {vim -u NONE  % No need to read unnessary configurations
           -e       % run in ex mode
%            -V10log  % For debugging only, will go away later.
           -c "set noswapfile"
           -c "set tabstop=\@@vstab"
           -c "set cp"
           -c "syntax on"
           -c "set syntax=\@@vssyntax"
           -c "let contextstartline=\@@vsstart"
           -c "let contextstopline=\@@vsstop"
           -c "source 2context.vim"
           -c "wqa" #1}}


%D \macro{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]}}

\def\defineVIMtyping
  {\dodoubleargument\dodefineVIMtyping}

\def\dodefineVIMtyping[#1][#2]%
  {\setevalue{\e!start#1}{\noexpand\dostartbuffer[vimsyntax][\e!start#1][\e!stop#1]}%
   \setvalue{\e!stop#1}{\dodotypeVIMfile[#2]{\TEXbufferfile{vimsyntax}}}}

%D Some defaults.

\setupVIMtyping
  [     syntax=context,
        \c!tab=8,
      \c!space=\v!yes,
      \c!start=1,
       \c!stop=0, %stop should be set to some value.
     \c!before=,
      \c!after=,
   colorscheme=pscolor,
  ]

%D Pre-defined Syntax : {{{ Based on \filename{ps_color.vim}
%D Perhaps this should be customizable

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

\startvimcolorscheme[pscolor]

\setupcolor[hex]

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

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


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

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

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

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

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

\definevimsyntaxsynonyms
  [Function]
  [Identifier]

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

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

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

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

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

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

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

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

\definevimsyntax
  [Comment,SpecialComment]
  [\c!style=\v!mono,\c!color=vimsyntax!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!Error]

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

\stopvimcolorscheme
% }}}

\protect

\stopmodule

% TODO: Enable line numbering
% TODO: Get start=continue to work.

\doifnotmode{demo}{\endinput}

\setupcolors[state=start]

\setupbodyfont[10pt]

\defineVIMtyping  [MATLAB]  [syntax=matlab]

\starttext
\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

\page

\typeVIMfile{\jobname.tex}

\stoptext

