%D \module
%D   [     file=t-syntax-highlight,
%D      version=2013.04.15,
%D        title=\CONTEXT\ User Module,
%D     subtitle=Code syntax highlighting,
%D       author=Aditya Mahajan,
%D         date=\currentdate,
%D    copyright=Aditya Mahajan,
%D        email=adityam <at> ieee <dot> org,
%D      license=Simplified BSD License]

\writestatus{loading}{Code syntax highlighting (ver: 2013.04.15)}

\startmodule    [syntax-highlight]
\usemodule      [syntax-groups]
\usemodule      [filter] % loads module-catcodes

\unprotectmodulecatcodes

\startinterface all
  \setinterfaceconstant {syntax}          {syntax}
  \setinterfaceconstant {highlight}       {highlight}
  \setinterfaceconstant {highlightcolor}  {highlightcolor}
\stopinterface

%D Name space

\def\syntaxhighlighting@id          {syntaxhighlighting}
\def\syntaxhighlighting@namespace   {@@@@\syntaxhighlighting@id}
\def\syntaxhighlighting@name        {}

\edef\t!syntaxhighlighting            {\syntaxhighlighting@id}

\installparameterhandler \syntaxhighlighting@namespace \syntaxhighlighting@id
\installsetuphandler     \syntaxhighlighting@namespace \syntaxhighlighting@id

%D Helper macro

\def\syntaxhighlighting@yes{\v!yes,\v!on}

\def\definesyntaxhighlighting
  {\dodoubleargument\syntaxhighlighting@define}

\starttexdefinition syntaxhighlighting@define [#1][#2]
    \setupsyntaxhighlighting[#1][\s!parent=\syntaxhighlighting@namespace,#2]

    \edef\syntaxhighlighting@name{#1}
    \defineexternalfilter[#1][\s!parent=\syntaxhighlighting@namespace#1]

    \doifmode\s!mkiv{\setups{syntaxhighlighting@setup_line_number_mkiv}}

    \setvalue{type#1file}{\getvalue{process#1file}}

\stoptexdefinition

\startsetups syntaxhighlighting@setup

  \edef\syntaxhighlighting@name{\currentexternalfilter}
  \edef\colorscheme@name{\externalfilterparameter\c!alternative}

  \let\SYN\syntaxgroup
  \edef\HGL{\externalfilterparameter{\c!highlight\c!command}}
  \let\\\textbackslash
  \let\{\textbraceleft
  \let\}\textbraceright
  \let\SYNBOL\donothing
  \let\SYNEOL\donothing

  \def\tab##1%
      {\dorecurse{##1}{\obeyedspace}}%

  \setups{syntaxhighlighting@setup_line_number_mkii}%

  \forgetall
  \doifinset{\externalfilterparameter\c!option}{\v!packed}
      {\setupwhitespace[\v!none,\v!flexible]}%

  \doifnotinset{\externalfilterparameter\c!option}{\v!hyphenated}
      {\language\minusone}%

  \setcatcodetable\externalfilter@minimal_catcodes
  \expandafter\def\activeendoflinetoken{\strut\par}
  \activatespacehandler{\syntaxhighlighting@namespace\externalfilterparameter\c!space}
  \raggedright
\stopsetups

\startsetups syntaxhighlighting@setup_line_number_mkiv
\definelinenumbering [#1]

\setuplinenumbering
   [#1]
   [\c!conversion=\externalfilterparameter\c!numberconversion,
        \c!start=\externalfilterparameter{\c!number\c!start},
         \c!step=\externalfilterparameter{\c!number\c!step},
        \c!method=\externalfilterparameter{\c!number\c!method},
      \c!location=\externalfilterparameter{\c!number\c!location},
         \c!style=\externalfilterparameter\c!numberstyle,
         \c!color=\externalfilterparameter\c!numbercolor,
         \c!width=\externalfilterparameter{\c!number\c!width},
          \c!left=\externalfilterparameter{\c!number\c!left},
         \c!right=\externalfilterparameter{\c!number\c!right},
       \c!command=\externalfilterparameter\c!numbercommand,
      \c!distance=\externalfilterparameter{\c!number\c!distance},
         \c!align=\externalfilterparameter{\c!number\c!align},
   ]
\stopsetups

\doifmode\s!mkii
    {\newcount\syntaxhighlighting@linenumber}

\startsetups syntaxhighlighting@setup_line_number_mkii
\doifinset{\externalfilterparameter\c!numbering}\syntaxhighlighting@yes
    {% setuplinenumbering resets \linenumber. So we save the value of linenumber and
     % revert it back.
     \syntaxhighlighting@linenumber=\linenumber

     \setuplinenumbering
       [\c!conversion=\externalfilterparameter\c!numberconversion,
            \c!start=\externalfilterparameter{\c!number\c!start},
             \c!step=\externalfilterparameter{\c!number\c!step},
            \c!method=\externalfilterparameter{\c!number\c!method},
          \c!location=\externalfilterparameter{\c!number\c!location},
             \c!style=\externalfilterparameter\c!numberstyle,
             \c!color=\externalfilterparameter\c!numbercolor,
             \c!width=\externalfilterparameter{\c!number\c!width},
              \c!left=\externalfilterparameter{\c!number\c!left},
             \c!right=\externalfilterparameter{\c!number\c!right},
           \c!command=\externalfilterparameter\c!numbercommand,
          \c!distance=\externalfilterparameter{\c!number\c!distance},
             \c!align=\externalfilterparameter{\c!number\c!align},
       ]

    \linenumber=\syntaxhighlighting@linenumber}
\stopsetups

\starttexdefinition syntaxhighlighting@read_command #1
    \syntaxhighlighting@linenumbering_start
    \ReadFile{#1}
    \syntaxhighlighting@linenumbering_stop
\stoptexdefinition


\starttexdefinition syntaxhighlighting@linenumbering_stop
  \dostoptagged
   \doifinset{\externalfilterparameter\c!numbering}\syntaxhighlighting@yes
      {\stoplinenumbering}
\stoptexdefinition

\starttexdefinition syntaxhighlighting@linenumbering_start
    \doifinset{\externalfilterparameter\c!numbering}\syntaxhighlighting@yes
        {\doifelse{\externalfilterparameter{\c!number\c!continue}}\syntaxhighlighting@yes
            {\startlinenumbering[\v!continue]}
            {\startlinenumbering}}
\stoptexdefinition
\starttexdefinition syntaxhighlighting@linenumbering_stop
   \doifinset{\externalfilterparameter\c!numbering}\syntaxhighlighting@yes
      {\stoplinenumbering}
\stoptexdefinition


\setupsyntaxhighlighting
  [\c!tab=4,
   \c!space=\v!off,
   \c!lines=\v!split,
   \c!start=1,
   \c!stop=0,
   % \c!syntax=context,
   \c!alternative=pscolor,
   \c!before=,
   \c!after=,
   \c!spacebefore=\v!none,
   \c!spaceafter=\v!none,
   \c!location=\v!paragraph,
   \c!style=\tttf,
   \c!color=,
   \c!align={\v!flushleft,\v!nothyphenated}, %Does not work due to \forgetall
   \c!filtercommand=echo, % placeholder
   \c!continue=yes,
   \c!read=\v!yes,
   \c!readcommand=\syntaxhighlighting@read_command,
   \c!output=\externalfilterinputfile, % placeholder
   \c!setups=syntaxhighlighting@setup,
   \c!option=\v!packed, % \v!hyphenated
   \s!parent=\externalfilter@namespace,
   % Numbering options
   \c!numbering=\v!no,
   \c!number\c!start=1,
   \c!number\c!step=1,
   \c!number\c!continue=\v!no,
   \c!numberconversion=\v!numbers,
   \c!number\c!method=\v!first,
   \c!number\c!location=\v!left,
   \c!numberstyle=\ttx,
   \c!numbercolor=,
   \c!number\c!width=2em,
   \c!number\c!left=,
   \c!number\c!right=,
   \c!numbercommand=,
   \c!number\c!distance=0.5em,
   \c!number\c!align=\v!flushright,
   %Highlight options
   \c!highlight=,
   \c!highlightcolor=lightgray,
   \c!highlight\c!command=\syntaxhighlightline,
  ]

\def\currentsyntaxhighlighting  {\syntaxhighlighting@name}

% Space handler
%
% The space handing code for MkII and MkIV is not consistent. So, we provide our
% own versions.

\setvalue{\syntaxhighlighting@namespace @\c!lines @\v!split}{\hskip}
\setvalue {\syntaxhighlighting@namespace @\c!lines @\v!fixed}{\dontleavehmode\kern}

% default
\setvalue{\syntaxhighlighting@namespace @\c!lines @}{\hskip}

\def\syntaxhighlighting@split%
    {\getvalue{\syntaxhighlighting@namespace @\c!lines @\externalfilterparameter\c!lines}}

% Visible space
\installspacehandler {\syntaxhighlighting@namespace\v!on}
  {\obeyspaces
   \unexpanded\def\obeyedspace
      {\syntaxhighlighting@split\zeropoint\relax
       \hbox{\normalcontrolspace}%
       \syntaxhighlighting@split\zeropoint\relax}}%

% Invisible space
\installspacehandler {\syntaxhighlighting@namespace\v!off}
  {\obeyspaces
   \unexpanded\def\obeyedspace
      {\syntaxhighlighting@split\interwordspace\relax}}

% Default
\installspacehandler {\syntaxhighlighting@namespace}
  {\activatespacehandler {\syntaxhighlighting@namespace\v!off}}

% Line highlighting

\definetextbackground[syntaxhighlightline]
                     [\c!location=\v!text,
                      %% location=paragraph causes a spurious line break
                   \c!alternative=0,
                         \c!frame=\v!off,
                    \c!background=\v!color,
               \c!backgroundcolor=\externalfilterparameter\c!highlightcolor,
                        \c!before=,
                         \c!after=,
                     ]


\protectmodulecatcodes

\stopmodule
