%D \module
%D   [       file=core-ver,
%D        version=2000.05.09,
%D          title=\CONTEXT\ Core Macros,
%D       subtitle=Verbatim,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{Context Core Macros / Verbatim}

\startmessages  dutch  library: verbatims
  title: typen
      1: file -- bestaat niet
\stopmessages

\startmessages  english  library: verbatims
  title: verbatim
      1: file -- does not exist
\stopmessages

\startmessages  german  library: verbatims
  title: verbatim
      1: Datei -- existiert nicht
\stopmessages

\startmessages  czech  library: verbatims
  title: verbatim
      1: soubor -- neexistuje
\stopmessages

\startmessages  italian  library: verbatims
  title: verbatim
      1: il file -- non esiste
\stopmessages

\startmessages  norwegian  library: verbatims
  title: verbatim
      1: fil -- eksisterer ikke
\stopmessages

\startmessages  romanian  library: verbatims
  title: verbatim
      1: fisierul -- nu exista
\stopmessages

\startmessages  french  library: verbatims
  title: verbatim
      1: le fichier -- n'existe pas
\stopmessages

\unprotect

% \type{ <crlf> char} geeft bagger

%D We are going to embed the general verbatim support macros in
%D a proper environment. First we show the common setup
%D macro, so we know what features are supported. The options
%D are hooked into the support macros via the \type{\obey}
%D macros.

\newprettytrue % movet to here from cont-sys.tex

\def\prettyidentifier {TEX}
\def\prettypalet      {}

\def\installprettytype
  {\dodoubleargument\doinstallprettytype}

\def\doinstallprettytype[#1][#2]% map #1 onto #2
  {\uppercasestring#1\to\asciiA
   \uppercasestring#2\to\asciiB
   \setevalue{\??ty\??ty\asciiA}{\asciiB}}

\def\setupprettiesintype#1%
  {\uppercasestring#1\to\ascii
   \edef\prettyidentifier
     {\ifundefined{\??ty\??ty\ascii}TEX%
      \else\getvalue{\??ty\??ty\ascii}\fi}%
   \doifundefined{setuppretty\prettyidentifier type}%
     {\bgroup
      \setbox0\hbox % get rid of spaces when in-line \newpretty loading
        {\restorecatcodes % also needed when loading during \newpretty
         \startreadingfile % restore < and > if needed
         \lowercasestring verb-\prettyidentifier.tex\to\filename
         \readsysfile\filename\donothing\donothing
         \stopreadingfile}%
      \egroup}%
   \doifdefinedelse{setuppretty\prettyidentifier type}%
     {\let\uncatcodecharacters\uncatcodeallcharacters % ugly, should be switch
      \def\setupprettytype{\getvalue{setuppretty\prettyidentifier type}}}
     {\let\setupprettytype\relax}}

\installprettytype [RAW]        [RAW]

\installprettytype [TEX]        [TEX]

\installprettytype [PERL]       [PL]
\installprettytype [PL]         [PL]
\installprettytype [PM]         [PL]

\installprettytype [METAPOST]   [MP]
\installprettytype [METAFONT]   [MP]
\installprettytype [MP]         [MP]
\installprettytype [MF]         [MP]

\installprettytype [JAVASCRIPT] [JS]
\installprettytype [JAVA]       [JV]
\installprettytype [JS]         [JS]
\installprettytype [JV]         [JV]

\installprettytype [SQL]        [SQL]

\installprettytype [PASCAL]     [PAS]
\installprettytype [PAS]        [PAS]
\installprettytype [MODULA]     [PAS]
\installprettytype [MOD]        [PAS]

\installprettytype [EIFFEL]     [EIF]
\installprettytype [EIF]        [EIF]
\installprettytype [E]          [EIF]

\installprettytype [XML]        [XML]

\installnewpretty M {\setupprettiesintype {MP}\setupprettytype}
\installnewpretty P {\setupprettiesintype {PL}\setupprettytype}
\installnewpretty T {\setupprettiesintype{TEX}\setupprettytype}
\installnewpretty J {\setupprettiesintype {JV}\setupprettytype}
\installnewpretty S {\setupprettiesintype{SQL}\setupprettytype}
\installnewpretty W {\setupprettiesintype{PAS}\setupprettytype} % Wirth
\installnewpretty I {\setupprettiesintype{EIF}\setupprettytype} % E taken
\installnewpretty X {\setupprettiesintype{XML}\setupprettytype}

\def\setupcommonverbatim
  {\eightbitcharactersfalse % obey regime / encoding
   %
   \def\prettyidentifier{TEX}%
   %
   \doifelse{\typingparameter\c!text}\v!yes
     \naturaltextexttrue
     \naturaltextextfalse
   \def\prettyidentifierfont{\typingparameter\c!icommand}%
   \def\prettyvariablefont  {\typingparameter\c!vcommand}%
   \def\prettynaturalfont   {\typingparameter\c!ccommand}%
   %
   \doif{\typingparameter\c!space}\v!on
     {\def\obeyspaces{\setcontrolspaces}}%
   \doif{\typingparameter\c!page }\v!no
     {\def\obeypages {\ignorepages}}%
   %
   \doifelse{\typingparameter\c!tab}\v!yes
     {\def\obeytabs{\settabskips}}%
     {\doif{\typingparameter\c!tab}\s!ascii
        {\chardef\tabskipmode\plustwo % quit on >127
         \def\obeytabs{\settabskips}}}%
   %
   \ignorehyphens % default
   \ExpandFirstAfter\processaction
     [\typingparameter\c!lines]
     [        \v!yes=>\obeybreakpoints,
       \v!hyphenated=>\obeyhyphens]%
   \processaction
     [\typingparameter\c!empty]
     [\v!yes=>\obeyemptylines,
      \v!all=>\obeyallemptylines]%
   %
   \ExpandFirstAfter\processaction
     [\typingparameter\c!option]
     [     \v!none=>\let\obeycharacters\relax,
          \v!color=>\setupprettiesintype{TEX}%
                    \let\obeycharacters\setupprettytype
                    \let\obeytabs\ignoretabs,
         \v!normal=>\let\obeycharacters\setupgroupedtype,
       \v!commands=>\def\obeycharacters{\setupcommandsintype}% \let
                    \let\obeytabs\ignoretabs,
        \v!slanted=>\let\obeycharacters\setupslantedtype
                    \let\obeytabs\ignoretabs,
        \s!unknown=>\setupprettiesintype{\typingparameter\c!option}%
                    \let\obeycharacters\setupprettytype
                    \let\obeytabs\ignoretabs]%
   \doifnumberelse{\typingparameter\c!tab}
     {\def\obeytabs{\setfixedtabskips{\typingparameter\c!tab}}}%
     \donothing
%    \def\verbatimfont{\typingparameter\c!style\normalnoligatures\font}%
   \def\verbatimfont{\dosetfontattribute{\currenttypingclass\currenttyping}\c!style\normalnoligatures\font}%
   \setupverbatimcolor}

\ifx\normalnoligatures\undefined \let\normalnoligatures\gobbleoneargument \fi

%D The verbatim commands have a rather long and turbulent
%D history. Most users of \CONTEXT\ probably will never use
%D some of the features, but I've kept in mind that when one is
%D writing a users manual, about everything can and undoubtly
%D will be subject to a verbatim treatment.
%D
%D Verbatim command are very sensitive to argument processing,
%D which is a direct result of the \CATCODES\ being fixed at
%D reading time. With our growing understanding of \TEX,
%D especially of the mechanism that can be used for looking
%D ahead and manipulating \CATCODES, the verbatim support
%D became more and more advanced and natural.
%D
%D Typesetting inline verbatim can be accomplished by
%D \type{\type}, which in this sentence was typeset by saying
%D just \type{\type{\type}}, which in turn was typeset by
%D \unknown. Using the normal grouping characters \type{{}} is
%D the most natural way of using this command.
%D
%D A second, more or less redundant, alternative is delimiting
%D the argument with an own character. This method was
%D implemented in the context of a publication in the \MAPS,
%D where this way of delimiting is recognized by \LATEX\ users.
%D
%D The third, more original alternative, is the one using
%D \type{<<} and \type{>>} as delimiters. This alternative can
%D be used in situations where slanted typeseting is needed.

% todo: we can use \letter... here:

\def\lesscharacter {<}
\def\morecharacter {>}

\chardef\texescape     = `\\
\chardef\leftargument  = `\{
\chardef\rightargument = `\}

%D \macros
%D   {type}
%D
%D We define \type{\type} as a protected command. First we
%D set the catcodes of \type{<} and \type{>} and then we start
%D looking ahead.

% \starttyping
% normal: \par \type{xx<<..xx..<<xx <<xx>> >>..>>xx} \par \type<<....>> \par \type<<..<<xx>>..>> \par
% normal: \par \type{xx<..xx..<xx <slanted> >..>xx} \par \type{<....>} \par \type{<..<xx>..>}
% \setuptype[option=slanted]
% slanted: \par \type{xx<<..sl..<<xx <<sl>> xx>>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<<sl>>..>> \par
% slanted: \par \type{xx<<..sl..<xx <sl> xx>..sl..>>xx} \par \type<<..xx..>> \par \type<<..<sl>..>> \par
% \setuptype[option=none]
% none: \par \type{xx<<..xx..<<xx <<xx>> >>..>>xx} \par \type<<....>> \par \type<<..<<xx>>..>> \par
% \stoptyping

\unexpanded\def\type
  {\dotype\empty}

\def\dotype#1%
  {\bgroup
   \strut % new, enables leading space in \type { abc } at par start
   \let\currenttypingclass\??ty
   \edef\currenttyping{#1}%
   \catcode`\<=\@@other
   \catcode`\>=\@@other
   \futurelet\next\dodotype}

%D Next we distinguish between the three alternatives and call
%D for the appropriate macros.

\def\dodotypeA
  {\initializetype
   \initializetypegrouping
   \verbatimcolor
   \afterassignment\protectfirsttype\let\next=}

\def\dodotypeB
  {\initializetype
   \setupnotypegrouping
   \verbatimcolor
   \let\next=}

\def\dodotypeC<#1%
  {\initializetype
   \verbatimcolor
   \if#1<%
     \@EA\setupalternativetypegrouping
   \else
     \@EA#1%
   \fi}

\def\dodotypeD#1%
  {\initializetype
   \verbatimcolor
   \catcode`#1=\@@endgroup}

\def\dodotype%
  {\ifx\next\bgroup
     \@EA\dodotypeA
   \else\if\next<%
     \doifelse{\typingparameter\c!option}\v!none
       {\@EAEAEA\dodotypeB}{\@EAEAEA\dodotypeC}%
   \else
     \@EAEAEA\dodotypeD
   \fi\fi}

% Verbatim does not work when passed as an argument, so here is a
% workaround. Beware, spaces are introduced after a \type {\csname}.

\chardef\recodeverbatimmode\zerocount % 0=nothing 1=rescan 2=autorescan

% \appendtoks \chardef\recodeverbatimmode\plustwo \to \everytabulate
% \appendtoks \chardef\recodeverbatimmode\plustwo \to \everytable

\def\dodotypeA
  {\initializetype
   \initializetypegrouping
   \verbatimcolor
   \ifcase\recodeverbatimmode
     \@EA\dodotypeAA
   \or
     \@EA\dodotypeAB
   \or
     \ifnum\catcode`\{=\@@active
       \@EAEAEA\dodotypeAB
     \else
       \@EAEAEA\dodotypeAA
     \fi
   \else
     \@EA\dodotypeAA
   \fi}

\def\dodotypeAA
  {\afterassignment\protectfirsttype\let\next=}

\def\dodotypeAB
  {\bgroup
   \catcode`\}=\@@endgroup
   \catcode`\{=\@@begingroup
   \afterassignment\redotypeAB\global\globalscratchtoks}

\def\redotypeAB
  {\egroup
   \expandafter\convertargument\the\globalscratchtoks\to\ascii
   \ifx\scantokens\undefined\ascii\else\everyeof{\hskip-\spaceskip}\scantokens\expandafter{\ascii}\fi
   \egroup}

\bgroup
\catcode`\[=\@@begingroup
\catcode`\]=\@@endgroup
\catcode`\{=\@@active
\catcode`\}=\@@active
\gdef\initializetypegrouping
  [\ifnum\catcode`\{=\@@active
     \let\normalactivebgroup{%
     \let\normalactiveegroup}%
   \else
     \catcode`\{=\@@active
     \catcode`\}=\@@active
     \let\normalactivebgroup\leftargument
     \let\normalactiveegroup\rightargument
   \fi
   \def\activeleftargument
     [\bgroup
      \catcode`\}=\@@active
      \let}\activerightargument
      \normalactivebgroup]%
   \def\activerightargument
     [\normalactiveegroup
      \egroup]%
   \let{=\activeleftargument
   % not \let}=\egroup, otherwise things go wrong in alignments (???)
   \catcode`\}=\@@endgroup]
\egroup

\bgroup
\catcode`\<=\@@active
\catcode`\>=\@@active
\gdef\setupalternativetypegrouping
  {\catcode`\<=\@@active
   \catcode`\>=\@@active
   \def\doless
     {\ifx<\next
        \def\next
          {\bgroup\switchslantedtype
           \let\next=}%
      \else
        \let\next\lesscharacter
      \fi
      \next}%
   \def\domore
     {\ifx>\next
        \def\next
          {\egroup
           \let\next=}%
      \else
        \let\next\morecharacter
      \fi
      \next}%
   \def<{\futurelet\next\doless}%
   \def>{\futurelet\next\domore}}
\egroup

\def\setupnotypegrouping
  {\catcode`\<=\@@begingroup
   \catcode`\>=\@@endgroup}

%D When writing the manual to \CONTEXT\ and documenting this
%D source we needed to typeset \type{<<} and \type{>>}. Because
%D we wanted to do this in the natural way, we've adapted the
%D original definition a bit. We still show the original
%D because we think it's shows a bit better what we are
%D doing.
%D
%D \starttyping
%D \bgroup
%D \catcode`\<=\@@active
%D \catcode`\>=\@@active
%D \gdef\setupgroupedtype%
%D   {\catcode`\<=\@@active
%D    \catcode`\>=\@@active
%D    \def<%
%D      {\def\do%
%D         {\ifx\next<%
%D            \def\next{\bgroup\switchslantedtype\let\next=}%
%D          \else
%D            \let\next\lesscharacter
%D          \fi
%D          \next}%
%D       \futurelet\next\do}%
%D    \def>%
%D      {\def\do%
%D         {\ifx\next>%
%D            \def\next{\egroup\let\next=}%
%D          \else
%D            \let\next\morecharacter
%D          \fi
%D          \next}%
%D       \futurelet\next\do}}
%D \egroup
%D \stoptyping
%D
%D The final implementation looks a bit further and treats the
%D lone \type{<<} and \type{>>} a bit different. The \type
%D {\null} prevents ligatures, which unfortunately turn up
%D in Lucida fonts.

\def\doenterdoublelesstype
  {\ifx\next\egroup
      \lesscharacter\null\lesscharacter
   \else
     \bgroup\switchslantedtype
     \let\doenterdoublemoretype\egroup
   \fi}

\def\doenterdoublemoretype
  {\def\doenterdoubletype
     {\ifx\next\egroup
        \morecharacter\null\morecharacter
      \fi}}

\bgroup
\catcode`\<=\@@active
\catcode`\>=\@@active
\gdef\setupgroupedtype
  {\catcode`\<=\@@active
   \catcode`\>=\@@active
   \def\doless
     {\ifx<\next
        \def\next
          {\def\enterdoubletype{\futurelet\next\doenterdoublelesstype}%
           \afterassignment\enterdoubletype
           \let\next=}%
      \else
        \let\next\lesscharacter
      \fi
      \next}%
   \def\domore
     {\ifx>\next
        \def\next
          {\def\enterdoubletype{\futurelet\next\doenterdoublemoretype}%
           \afterassignment\enterdoubletype
           \let\next=}%
      \else
        \let\next\morecharacter
      \fi
      \next}%
   \def<{\futurelet\next\doless}%
   \def>{\futurelet\next\domore}}
\egroup

\newif\ifslantedtypeactivated
\newif\ifslantedtypepermitted

\def\switchslantedtype
  {\ifslantedtypepermitted
     \ifslantedtypeactivated
       \slantedtypeactivatedfalse\tttf
     \else
       \slantedtypeactivatedtrue\ttsl
     \fi
   \fi}

\def\setupcommandsintype% can also be \string\
  {\setupgroupedtype
   \edef\\{\typingparameter\c!escape}%
   \letvalue{\\}=\\% for instance \/=/
   \@EA\catcode\@EA`\\=\@@escape
   \def\BTEX##1\ETEX##2% ##2 gobbles active space
     {\naturaltextext##1\unskip\relax}}

%D The following lines show what happens when we set
%D \type {option=commands}.
%D
%D \startbuffer
%D \starttyping
%D test//test test/BTEX \footnote{test test test}/ETEX test
%D test//test test/BTEX \footnote{test test test}/ETEX  test
%D test test test/BTEX \bf(nota bene)/ETEX test
%D test test test /BTEX \bf(nota bene)/ETEX  test
%D \stoptyping
%D \stopbuffer
%D
%D % \bgroup\setuptyping[option=commands]\getbuffer\egroup
%D
%D this was keyed in as:
%D
%D \typebuffer

\def\setupslantedtype
  {\setupgroupedtype
   \slantedtypepermittedtrue}

\let\protectedfirsttype\string % \relax for special cases

% \bgroup
% \catcode`\<=\active
% \catcode`\>=\active
% \gdef\doprotectfirsttype
%   {\ifx\next<%
%      \let\next\relax
%    \else\ifx\next\bgroup
%      \let\next\relax
%    \else\ifx\next\egroup % takes care of \type{}
%      \let\next\relax
%    \else\ifx\next\activeleftargument
%      \let\next\relax
%    \else
%      \let\next\protectedfirsttype
%    \fi\fi\fi\fi
%    \next}
% \egroup
%
% \def\protectfirsttype
%   {\futurelet\next\doprotectfirsttype}
%
% The next one is safe for:
%
% \def\xx#1{\type{#1}} \xx{\ifx}

\bgroup
\catcode`\<=\active
\catcode`\>=\active
\gdef\doprotectfirsttype
  {\normalifx\next<%
     \endrobusttest \let\next\relax
   \normalelse\normalifx\next\bgroup
     \endrobusttest \let\next\relax
   \normalelse\normalifx\next\egroup % takes care of \type{}
     \endrobusttest \let\next\relax
   \normalelse\normalifx\next\activeleftargument
     \endrobusttest \let\next\relax
   \normalelse
     \endrobusttest \let\next\protectedfirsttype
   \normalfi\normalfi\normalfi\normalfi
   \next}
\egroup

\def\protectfirsttype
  {\beginrobusttest
   \futurelet\next\doprotectfirsttype}

%D The neccessary initializations are done by calling
%D \type{\initializetype} which in return calls for the support
%D macro \type{\setupinlineverbatim}.

\def\initializetype
  {\let\obeylines\ignorelines
   \setupcommonverbatim
   \setupinlineverbatim}

%D \macros
%D   {setuptype}
%D
%D Some characteristics of \type{\type} can be set up by:

\def\setuptype
  {\dodoubleempty\dosetuptype}

\def\dosetuptype[#1][#2]%
  {\ifsecondargument
     \getparameters[\??ty#1][#2]%
   \else
     \getparameters[\??ty][#1]%
   \fi}

%D The setups for inline verbatim default to:

\setuptype
  [ \c!space=\v!off,
    \c!color=,
    \c!style=\tt\tf, % \tttf gives problems with {\tx \type...}
     \c!page=\v!no,
      \c!tab=\v!yes,
    \c!palet=colorpretty,
   \c!option=\v!normal]

%D \macros
%D   {typ,obeyhyphens,obeybreakpoints}
%D
%D Although it's not clear from the macros, one character
%D trait of this macros, which are build on top of the support
%D module, is that they don't hyphenate. We therefore offer
%D the alternative \type{\typ}. The current implementation
%D works all right, but a decent hyphenation support of
%D \type{\tt} text will be implemented soon.

% \def\obeyhyphens
%   {\def\obeyedspace{\hskip\spaceskip}%
%    \edef\savedfont{\the\font}%
%    \ttsl\hyphenchar\font45
%    \tttf\hyphenchar\font45
%    \savedfont
%    \spaceskip.5em\!!plus.25em\!!minus.25em\relax}
%
% \def\obeybreakpoints
%   {\def\obeyedspace{\hskip\spaceskip}%
%    \spaceskip.5em
%    \veryraggedright}

\def\obeyhyphens
  {\def\obeyedspace {\hskip\spaceskip}%
   \def\controlspace{\hskip\zeropoint\hbox{\char32}\hskip\zeropoint}%
   \spaceskip.25em\!!plus.5em\!!minus.25em\relax}

\def\obeybreakpoints
  {\ignorehyphens
   \veryraggedright}

\def\ignorehyphens
  {\def\obeyedspace {\null\hskip\spaceskip\null}%
   \def\controlspace{\null\hskip\zeropoint\hbox{\char32}\hskip\zeropoint\null}%
   \spaceskip.5em\relax}

%\unexpanded\def\typ
%  {\bgroup
%   \obeyhyphens
%   \futurelet\next\dotype}

%\unexpanded\def\typ
%  {\bgroup
%   \obeyhyphens
%   \futurelet\next\dodotype}

\unexpanded\def\typ
  {\bgroup
   \let\@@tylines\v!hyphenated
   \futurelet\next\dodotype}

%D \macros
%D   {tex,arg,mat,dis}
%D
%D Sometimes, for instance when we pass verbatim text as an
%D argument, the fixed \CATCODES\ interfere with our wishes. An
%D experimental implementation of character by character
%D processing of verbatim text did overcome this limitation,
%D but we've decided not to use that slow and sometimes
%D troublesome solution. Instead we stick to some 'old'
%D \CONTEXT\ macros for typesetting typical \TEX\ characters.
%D
%D The next implementation is more clear but less versatile,
%D so we treated it for a beter one.
%D
%D \starttyping
%D \def\dospecialtype#1#2%
%D   {\bgroup
%D    \initializetype
%D    \catcode`\{=\@@begingroup
%D    \catcode`\}=\@@endgroup
%D    \def\dospecialtype%
%D      {\def\dospecialtype{#2\egroup}%
%D       \bgroup
%D       \aftergroup\dospecialtype
%D       #1}%
%D    \afterassignment\dospecialtype
%D    \let\next=}
%D
%D \unexpanded\def\tex{\dospecialtype\texescape\relax}
%D \unexpanded\def\arg{\dospecialtype\leftargument\rightargument}
%D \unexpanded\def\mat{\dospecialtype\$\$}
%D \unexpanded\def\dis{\dospecialtype{\$\$}{\$\$}}
%D \stoptyping
%D
%  %D For sometime we used the better but less readable is
%  %D alternative
%  %D
%  %D \starttyping
%  %D \def\doprocessgroup#1#2#3%
%  %D   {\bgroup
%  %D    #1%
%  %D    \def\doprocessgroup%
%  %D      {\def\doprocessgroup{#3\egroup}%
%  %D       \bgroup
%  %D       \aftergroup\doprocessgroup
%  %D       #2}%
%  %D    \afterassignment\doprocessgroup
%  %D    \let\next=}
%  %D
%  %D \def\setgroupedtype%
%  %D   {\initializetype
%  %D    \catcode`\{=\@@begingroup
%  %D    \catcode`\}=\@@endgroup}
%  %D
%  %D \unexpanded\def\tex{\doprocessgroup\setgroupedtype\texescape\relax}
%  %D \unexpanded\def\arg{\doprocessgroup\setgroupedtype\leftargument\rightargument}
%  %D \unexpanded\def\mat{\doprocessgroup\setgroupedtype\$\$}
%  %D \unexpanded\def\dis{\doprocessgroup\setgroupedtype{\$\$}{\$\$}}
%  %D \stoptyping
%  %D
%D
%D But since \type{\groupedcommand} became available, we use
%D however

\def\setgroupedtype
  {\let\currenttypingclass\??ty
   \initializetype
   \catcode`\{=\@@begingroup
   \catcode`\}=\@@endgroup}

\unexpanded\def\tex{\groupedcommand{\setgroupedtype\texescape}{\relax}}
\unexpanded\def\arg{\groupedcommand{\setgroupedtype\leftargument}{\rightargument}}
\unexpanded\def\mat{\groupedcommand{\setgroupedtype\$}{\$}}
\unexpanded\def\dis{\groupedcommand{\setgroupedtype\$\$}{\$\$}}

%D \macros
%D   {starttyping}
%D
%D Display verbatim is realized far more easy, which is mostly
%D due to the fact that we use \type{\stop...} as delimiter.
%D The implementation inherits  some features, for instance the
%D support of linenumbering, which can best be studied in the
%D documented support module.

\let\currenttyping     \empty
\let\currenttypingclass\??ty  % saveguard

\def\typingparameter#1%
  {\executeifdefined
     {\currenttypingclass\currenttyping#1}%
     {\executeifdefined{\currenttypingclass#1}\empty}}

\def\settypingparameter#1#2%
  {\setvalue{\currenttypingclass\currenttyping#1}{#2}}
\def\setxtypingparameter#1#2%
  {\setxvalue{\currenttypingclass\currenttyping#1}{#2}}

\def\initializetyping
  {%\donefalse
   \switchtobodyfont[\typingparameter\c!bodyfont]%
   \donefalse
   \scratchskip\typingparameter\c!oddmargin\relax
   \ifzeropt\scratchskip\else\donetrue\fi
   \scratchskip\typingparameter\c!evenmargin\relax
   \ifzeropt\scratchskip\else\donetrue\fi
   \ifdone
     \def\doopenupverbatimline
       {\getpagestatus
        \ifrightpage
          \hskip\typingparameter\c!oddmargin\relax
        \else
          \hskip\typingparameter\c!evenmargin\relax
        \fi}%
   \else
     \doadaptleftskip{\typingparameter\c!margin}%
   \fi
   \doifdefinedelse{\??bo\typingparameter\c!blank}
     {\edef\!!stringa{\csname\??bo\typingparameter\c!blank\endcsname}}
     {\edef\!!stringa{\typingparameter\c!blank}}%
   \processaction
     [\!!stringa]
     [ \v!standard=>\scratchskip\ctxparskip,
          \v!small=>\scratchskip\blankokleinmaat,
         \v!medium=>\scratchskip\blankomiddelmaat,
            \v!big=>\scratchskip\blankogrootmaat,
       \v!halfline=>\scratchskip.5\baselineskip,
           \v!line=>\scratchskip\baselineskip,
           \v!none=>\scratchskip\zeropoint,
        \s!unknown=>\scratchskip\commalistelement]%
   \ifgridsnapping
     \ifdim\scratchskip=.5\baselineskip\relax
       \edef\verbatimbaselineskip{\the\scratchskip}% new
     \else
       \edef\verbatimbaselineskip{\the\baselineskip}%
     \fi
   \else
     \edef\verbatimbaselineskip{\the\scratchskip}%
   \fi
   \setupcommonverbatim}

%D The basic display verbatim commands are defined in an
%D indirect way. As we will see, they are a specific case of a
%D more general mechanism.

% formal version
%
% \def\dostarttyping#1%
%   {\let\currenttypingclass\??tp
%    \edef\currenttyping{#1}%
%    \typingparameter\c!before
%    \startpacked % includes \bgroup
%    \dosetuptypelinenumbering{}%
%    \initializetyping
%    \startverbatimcolor
%    \expandafter\processdisplayverbatim\expandafter{\s!stop#1}}

% we need this hack because otherwise verbatim skips
% the first line (everything after the initial command)

\def\dostarttyping#1% tricky non standard lookahead
  {\bgroup
   \let\currenttypingclass\??tp
   \edef\currenttyping{#1}%
   \obeylines
   \futurelet\nexttoken\dodostarttyping}

\def\dodostarttyping
  {\ifx\nexttoken[%
     \expandafter\dododostarttyping
   \else
     \expandafter\nododostarttyping
   \fi}

\def\nododostarttyping
  {\dododostarttyping[]}

\def\dododostarttyping[#1]%
  {\typingparameter\c!before
   \startpacked % includes \bgroup
   \dosetuptypelinenumbering{#1}%
   \initializetyping
   \startverbatimcolor
   \expanded{\processdisplayverbatim{\s!stop\currenttyping}}}

\def\dostoptyping#1%
  {\stopverbatimcolor
   \stoppacked  % includes \egroup
   \typingparameter\c!after
   \egroup
   \dochecknextindentation{\??tp#1}%
   \dorechecknextindentation}

%D Line numbering for files is combined with filtering, while
%D display verbatim has the ability to continue.
%D
%D \starttyping
%D \typefile[numbering=file,start=10,stop=12]{test.tex}
%D
%D \definetyping[code][numbering=line]
%D
%D \starttext
%D \startcode
%D ...
%D ...
%D \stopcode
%D
%D \startcode[continue]
%D ...
%D ...
%D \stopcode
%D
%D \startcode[start=10]
%D ...
%D \stopcode
%D \stoptyping

%D \macros
%D   {setuptyping}
%D
%D The setup of typing accepts two arguments. The optional
%D first one identifies the user defined ones. If only one
%D argument is given, the values apply to both the standard
%D command \type{\starttyping} and \type{\typefile}.

%\indirect\def\setuptyping\dodoubleempty[#1][#2]%
%  {\iffirstargument
%     \getparameters[\??tp#1][#2]%
%   \else
%     \getparameters[\??tp][#1]%
%   \fi}
%
%\doubleemptied\def\setuptyping[#1][#2]%
%  {\iffirstargument
%     \getparameters[\??tp#1][#2]%
%   \else
%     \getparameters[\??tp][#1]%
%   \fi}

\def\dosetuptyping[#1][#2]%
  {\ifsecondargument
     \getparameters[\??tp#1][#2]%
   \else
     \getparameters[\??tp][#1]%
   \fi}

\def\setuptyping
  {\dodoubleempty\dosetuptyping}

%D The setups for display verbatim and file verbatim are
%D shared. One can adapt the extra defined typing environments,
%D but they also default to the values below. Watch the
%D alternative escape character.

\setuptyping
  [       \c!before=\blank,
           \c!after=\blank,
        \c!bodyfont=,
           \c!color=,
           \c!space=\v!off,
            \c!page=\v!no,
             \c!tab=\s!ascii,
          \c!option=\v!none,
           \c!palet=colorpretty,
            \c!text=\v!no,
           \c!style=\tttf,
        \c!icommand=\ttsl,
        \c!vcommand=,
        \c!ccommand=\tttf,
      \c!indentnext=\v!yes,
          \c!margin=\!!zeropoint,
      \c!evenmargin=\!!zeropoint,
       \c!oddmargin=\!!zeropoint,
           \c!blank=\v!line,
          \c!escape=/, % beware \string\ , should also be accepted
       \c!numbering=\v!no,
           \c!lines=,
           \c!empty=]

%D \macros
%D   {definetype}
%D
%D Specific inline verbatim commands can be defined with the
%D following command.

\def\definetype
  {\dodoubleempty\dodefinetype}

\def\dodefinetype[#1][#2]%
  {\unexpanded\setvalue{#1}{\dotype{#1}}%
%    \copyparameters % maybe no longer needed, implicit inheritance now
%      [\??ty#1][\??ty]
%      [\c!space,\c!palet,\c!color,\c!style,\c!page,\c!tab,\c!option]%
   \getparameters[\??ty#1][#2]}

%D \macros
%D   {definetyping}
%D
%D For most users the standard \type{\start}||\type{\stop}||pair
%D will suffice, but for documentation purposes the next
%D definition command can be of use:
%D
%D \starttyping
%D \definetyping[extratyping][margin=3em]
%D
%D \startextratyping
%D these extra ones are indented by 1 em
%D \stopextratyping
%D \stoptyping
%D
%D The definitions default to the standard typing values.

\def\presettyping[#1][#2]%
  {\copyparameters
     [\??tp#1][\??tp]
     [\c!color,\c!style]%
   \getparameters
     [\??tp#1]
     [#2]}

\def\dodefinetyping[#1][#2]%
  {\setvalue{\e!start#1}{\dostarttyping{#1}}%
   \setvalue{\e!stop #1}{\dostoptyping {#1}}%
   \presettyping[#1][#2]}

\def\definetyping
  {\dodoubleempty\dodefinetyping}

\definetyping[\v!typing]

\definetyping[RAW]   [\c!option=RAW]
\definetyping[MP]    [\c!option=MP]
\definetyping[PL]    [\c!option=PL]
\definetyping[PM]    [\c!option=PL]
\definetyping[JS]    [\c!option=JS]
\definetyping[JV]    [\c!option=JV]
\definetyping[SQL]   [\c!option=SQL]
\definetyping[TEX]   [\c!option=TEX]
\definetyping[PAS]   [\c!option=PAS]
\definetyping[PASCAL][\c!option=PAS]
\definetyping[MOD]   [\c!option=PAS]
\definetyping[MODULA][\c!option=PAS]
\definetyping[DELPHI][\c!option=PAS]
\definetyping[EIFFEL][\c!option=EIF]
\definetyping[XML]   [\c!option=XML]

%D We use the \CONTEXT\ color system for switching to and from
%D color mode. We can always redefine these colors afterwards.

\definecolor [colorprettyone]   [r=.9, g=.0, b=.0] % red
\definecolor [colorprettytwo]   [r=.0, g=.8, b=.0] % green
\definecolor [colorprettythree] [r=.0, g=.0, b=.9] % blue
\definecolor [colorprettyfour]  [r=.8, g=.8, b=.6] % yellow

\definecolor [grayprettyone]    [s=.30]
\definecolor [grayprettytwo]    [s=.45]
\definecolor [grayprettythree]  [s=.60]
\definecolor [grayprettyfour]   [s=.75]

\definepalet
  [colorpretty]
  [  prettyone=colorprettyone,
     prettytwo=colorprettytwo,
   prettythree=colorprettythree,
    prettyfour=colorprettyfour]

\definepalet
  [graypretty]
  [  prettyone=grayprettyone,
     prettytwo=grayprettytwo,
   prettythree=grayprettythree,
    prettyfour=grayprettyfour]

% ---> naar verb-* ? of predefine als undefined?

\definepalet [TEXcolorpretty]    [colorpretty]
\definepalet [TEXgraypretty]     [graypretty]
\definepalet [PLcolorpretty]     [colorpretty]
\definepalet [PLgraypretty]      [graypretty]
\definepalet [PMcolorpretty]     [colorpretty]
\definepalet [PMgraypretty]      [graypretty]
\definepalet [MPcolorpretty]     [colorpretty]
\definepalet [MPgraypretty]      [graypretty]
\definepalet [JVcolorpretty]     [colorpretty]
\definepalet [JVgraypretty]      [graypretty]
\definepalet [JScolorpretty]     [colorpretty]
\definepalet [JSgraypretty]      [graypretty]
\definepalet [SQLcolorpretty]    [colorpretty]
\definepalet [SQLgraypretty]     [graypretty]
\definepalet [PAScolorpretty]    [colorpretty]
\definepalet [PASgraypretty]     [graypretty]
\definepalet [EIFcolorpretty]    [colorpretty]
\definepalet [EIFgraypretty]     [graypretty]
\definepalet [XMLcolorpretty]    [colorpretty]
\definepalet [XMLgraypretty]     [graypretty]

% Some real in-depth knowlegde of palets: `palet:color' it is!

%D We can use some core color commands. These are faster than
%D the standard color switching ones and work ok on a line by
%D line basis.
%D
%D \starttyping
%D \def\setupverbatimcolor%
%D   {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}%
%D    \def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}%
%D    \def\endofpretty       {\stopcolormode}}
%D \stoptyping
%D
%D Since we support a global color too, the folowing
%D definition is better:

\def\setupverbatimcolor% fast and local versus slow and global
  {\doifelsenothing{\typingparameter\c!color}
     {\def\beginofpretty[##1]{\startcolormode{\prettypalet:##1}}%
      \let\endofpretty        \restorecolormode % \stopcolormode
      \let\startverbatimcolor \relax
      \let\stopverbatimcolor  \relax
      \let\verbatimcolor      \relax}
     {\def\beginofpretty[##1]{\startcolor[\prettypalet:##1]}%
      \let\endofpretty        \stopcolor
      \def\startverbatimcolor{\startcolor[\typingparameter\c!color]}%
      \let\stopverbatimcolor  \stopcolor
      \def\verbatimcolor     {\getvalue{\typingparameter\c!color}}}% command !
   \doifelsenothing{\typingparameter\c!palet}
     {\let\prettypalet\empty
      \let\endofpretty\relax
      \def\beginofpretty[##1]{}}
     {\edef\prettypalet{\prettyidentifier\typingparameter\c!palet}}}

\let\prettypalet       \empty
\let\startverbatimcolor\relax
\let\stopverbatimcolor \relax
\let\verbatimcolor     \relax

%D In the verbatim module, there are some examples given of
%D the more obscure features of the verbatim environments.
%D
%D \startbuffer
%D \startTEX
%D \def\mathematics#1%         % usage: \type {\mathematics{x^2}}
%D   {\ifmmode#1\else$#1$\fi}  % becomes: \mathematics{x^2}
%D \stopTEX
%D \stopbuffer
%D
%D \typebuffer
%D
%D This gives, as can be expected:
%D
%D \getbuffer
%D
%D When we want to see some typeset \TEX\ too, we can say:
%D
%D \startbuffer
%D \startTEX
%D \def\mathematics#1%         %%\ N  usage: \type {\mathematics{x^2}}
%D   {\ifmmode#1\else$#1$\fi}  %%\ N  becomes: \mathematics{x^2}
%D \stopTEX
%D \stopbuffer
%D
%D \typebuffer
%D
%D or:
%D
%D \getbuffer
%D
%D In a similar way:
%D
%D \startbuffer
%D \startSQL
%D select *       -- indeed, here we {\em do} select
%D   from tableA
%D   where 1 = 2
%D \stopSQL
%D \stopbuffer
%D
%D \typebuffer
%D
%D gives:
%D
%D \getbuffer
%D
%D The next examples sow how we can directly call for natural
%D \TEX\ comments:
%D
%D \startbuffer
%D \setuptyping
%D   [TEX]
%D   [text=yes]
%D
%D \startTEX
%D \def\mathematics#1%         % usage: \type {\mathematics{x^2}}
%D   {\ifmmode#1\else$#1$\fi}  % becomes: \mathematics{x^2}
%D \stopTEX
%D
%D \setuptyping
%D   [SQL]
%D   [text=yes,palet=,icommand=\bf,vcommand=,ccommand=\it]
%D
%D \startSQL
%D select *       -- indeed, here we {\em do} select
%D   from tableA
%D   where 1 = 2
%D \stopSQL
%D
%D \setuptyping
%D   [SQL]
%D   [ccommand=\tf\underbar]
%D
%D \startSQL
%D select *       -- indeed, here we {\em do} select
%D   from tableA
%D   where 1 = 2
%D \stopSQL
%D \stopbuffer
%D
%D \typebuffer
%D
%D Now watch:
%D
%D \getbuffer
%D
%D The natural \TEX\ typesetting was introduced when Tobias
%D and Berend started using verbatim \JAVASCRIPT\ and \SQL.

%D \macros
%D   {EveryPar, EveryLine, iflinepar}
%D
%D One of the features of these commands is the support of
%D \type{\EveryPar}, \type{\EveryLine} and \type{\iflinepar}.
%D In the documentation of the verbatim support module we give
%D some examples of line- and paragraph numbering using these
%D macros.

%D \macros
%D   {typefile}
%D
%D Typesetting files verbatim (for the moment) only supports
%D colorization of \TEX\ sources as valid option. The other
%D setup values are inherited from display verbatim.
%D The implementation of \type{\typefile} is straightforward:

% new feature (not yet 100\% ok)
%
% \setuptyping[file][numbering=file]
%
% \typefile[start=2,nlines=3]{zapf}
% \typefile[start=continue,nlines=13]{zapf}
% \typefile{zapf}
%
% \setuptyping[file][numbering=line]
%
% \typefile[start=4,step=3]{zapf}
% \typefile{zapf}

\presettyping[\v!file][]

\def\typefile
  {\dodoubleempty\dotypefile}

\def\dotypefile[#1][#2]#3%
  {\ifsecondargument
     \dodotypefile[#1][#2]{#3}%
   \else\iffirstargument
     \doifassignmentelse{#1}
       {\dodotypefile[\v!file][#1]{#3}}
       {\dodotypefile[#1][]{#3}}%
   \else
     \dodotypefile[\v!file][]{#3}%
   \fi\fi}

% \def\dosetuptypelinenumbering#1% fuzzy
%   {\doifundefined{\currenttypingclass\currenttyping\c!start}
%      {\setuptyping[\currenttyping][\c!start=1,\c!stop=,\c!step=1,\c!nlines=,#1]}%
%    \doifelse{\typingparameter\c!numbering}\v!file
%      {\setuplinenumbering[\c!method=\v!file]%
%       \donetrue}
%      {\doifelse{\typingparameter\c!numbering}\v!line
%         {% \setuplinenumbering defaults start/step to 1/1, so we need
%          \doifnothing{\typingparameter\c!start   }{\settypingparameter\c!start   {1}}%
%          \doifnothing{\typingparameter\c!step    }{\settypingparameter\c!step    {1}}%
%          \doifnothing{\typingparameter\c!continue}{\settypingparameter\c!continue{}}%
%          \setuplinenumbering
%            [\c!method=\v!type,
%             \c!continue=\typingparameter\c!continue,
%             \c!start=\typingparameter\c!start,
%             \c!step=\typingparameter\c!step]%
%          \donetrue}
%         {\donefalse}}%
%    \ifdone
%      \ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi
%      \ifx\stoplinenumbering \undefined \let\stoplinenumbering \relax \fi
%      \def\beginofverbatimlines{\startlinenumbering}%
%      \def\endofverbatimlines  {\stoplinenumbering }%
%    \fi}

\def\dosetuptypelinenumbering#1% fuzzy
  {\doifundefined{\currenttypingclass\currenttyping\c!start}
     {\setuptyping[\currenttyping][\c!start=1,\c!stop=,\c!step=1,\c!nlines=]}%
   \setuptyping[\currenttyping][#1]%
   \doifelse{\typingparameter\c!numbering}\v!file
     {% kind of special: filters lines !
      \setuplinenumbering[\c!method=\v!file]%
      \donetrue}
     {\doifelse{\typingparameter\c!numbering}\v!line
        {% \setuplinenumbering defaults start/step to 1/1, so we need
         \doifinsetelse\v!continue{#1,\typingparameter\c!start}
           {\scratchcounter0\typingparameter\c!n
            \setxtypingparameter\c!start{\ifnum\scratchcounter=0 1\else\number\scratchcounter\fi}}%
           {\doifnothing{\typingparameter\c!start}{\settypingparameter\c!start{1}}}%
         \doifnothing{\typingparameter\c!step}{\settypingparameter\c!step{1}}%
         \setuplinenumbering
           [\c!method=\v!type,
            \c!start=\typingparameter\c!start,
            \c!stop=\typingparameter\c!stop,
            \c!step=\typingparameter\c!step]%
         \donetrue}
        {\donefalse}}%
   \ifdone
     \ifx\startlinenumbering\undefined \let\startlinenumbering\relax \fi
     \ifx\stoplinenumbering \undefined \let\stoplinenumbering \relax \fi
     \def\beginofverbatimlines{\startlinenumbering}%
     \def\endofverbatimlines  {\stoplinenumbering\setxtypingparameter\c!n{\number\linenumber}}%
   \fi}

% \setuptyping % not needed
%   [\v!file]
%   [\c!start=1,
%    \c!stop=,
%    \c!step=1,
%    \c!continue=,
%    \c!nlines=]

\setuptyping
  [\c!start=1,
   \c!stop=,
   \c!step=1,
   \c!continue=,
   \c!nlines=]

\def\dodotypefile[#1][#2]#3%
  {\bgroup
   \let\currenttypingclass\??tp
   \edef\currenttyping{#1}%
   \typingparameter\c!before
   \doiflocfileelse{#3}
     \donetrue % sets \readfilename
     {\doifinputfileelse{#3}
        {\donetrue
         \def\readfilename{\pathplusfile\filepath{#3}}}
        \donefalse}%
   \ifdone
     \startpacked % includes \bgroup
      \dosetuptypelinenumbering{#2}%
      \doifinset{\typingparameter\c!option}{\v!commands,\v!slanted,\v!normal}
        {\setuptyping[#1][\c!option=\v!none]}%
      \doif{\typingparameter\c!option}\v!color
        {\expandafter\aftersplitstring#3\at.\to\prettyidentifier
         \settypingparameter\c!option{\prettyidentifier}}%
      \initializetyping
      \startverbatimcolor
      \doifundefinedelse{\currenttypingclass#3\v!global\c!start}
        {\scratchcounter\zerocount}
        {\scratchcounter\getvalue{\currenttypingclass#3\v!global\c!start}}%
      \advance\scratchcounter\plusone
      \setxvalue{\currenttypingclass#3\v!global\c!start}{\the\scratchcounter}%
      \doifelsenothing{\typingparameter\c!start}
        {\processfileverbatim\readfilename}
        {\doif{\typingparameter\c!start}\v!continue
           {\setevalue{\currenttypingclass#1\c!start}%
              {\getvalue{\currenttypingclass#3\v!global\c!start}}}%
         \doifelsenothing{\typingparameter\c!stop}
           {\doifelsenothing{\typingparameter\c!nlines}
              {\processfileverbatim\readfilename}
              {\scratchcounter\typingparameter\c!start
               \advance\scratchcounter\typingparameter\c!nlines
               \advance\scratchcounter\minusone
               \setxvalue{\currenttypingclass#3\v!global\c!start}%
                 {\the\scratchcounter}%
               \processfilelinesverbatim\readfilename
                 {\typingparameter\c!start}
                 {\getvalue{\currenttypingclass#3\v!global\c!start}}}}%
           {\processfilelinesverbatim\readfilename
              {\typingparameter\c!start}
              {\typingparameter\c!stop }}}%
      \stopverbatimcolor
      \stoppacked  % includes \egroup
   \else
      \ifmmode\hbox\fi\bgroup
      \expanded{\convertargument#3}\to\ascii
      \tttf[\makemessage\m!verbatims1\ascii]%
      \showmessage\m!verbatims1\ascii
      \egroup
   \fi
   \typingparameter\c!after
   \egroup}

%D \macros
%D   {filename}
%D
%D Typesetting filenames in monospaced fonts is possible with
%D
%D \starttyping
%D \filename{here/there/filename.suffix}
%D \stoptyping
%D
%D The definition is not that spectacular.

\unexpanded\def\filename#1{{\tttf\hyphenatedfile{#1}}}

%D This leaves some settings:

\permitshiftedendofverbatim
\optimizeverbatimtrue

%D And a bonus macro:

\def\verbatim#1{\convertargument#1\to\ascii\ascii}

\protect \endinput
