%D \module
%D   [       file=xtag-xsl,
%D        version=2002.03.07,
%D          title=\CONTEXT\ XML Support,
%D       subtitle=XSLT processing,
%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.

% FOR THIS TO WORK YOU NEED A PROPER cp8bit VECTOR
%
% 8 bit support has been messed up in a couple of distributions
%
% 0x00   0x00
% 0x01   0x01
% 0x02   0x02
% etc

%D This module is rather experimental so users may expect
%D changes in the interface.

\unprotect

\definesystemvariable {xl}

\newif\iftraceXSLTprocessing % \traceXSLTprocessingtrue

\def\XSLTscriptfile{\bufferprefix xlscript}

% to be sped up:

\def\presetXSLTcharacters
  {\let\par\empty
   \def\{{\rawcharacter{`\{}}%  \string^^..
   \def\}{\rawcharacter{`\}}}%  \string^^..
   \def\\{\rawcharacter{`\\}}}% \string^^..

\def\obeyXSLTcharacters
  {\setnaturalcatcodes
   \catcode`\\=\@@escape}

\long\def\startXSLTscript #1 #2 %
  {\bgroup
   \obeyXSLTcharacters
   \doifelse{#2}{capsule}\dostartXSLTscript\nostartXSLTscript#1 #2 }

\long\def\dostartXSLTscript#1 #2 #3 %
  {\obeylines
   \dodostartXSLTscript#1 #2 #3 }

\long\def\dodostartXSLTscript#1 #2 #3 #4\stopXSLTscript
  {\egroup
   \long\setvalue{\??xl#1}{\doXSLTscript{#3}{#4}}}

\long\def\nostartXSLTscript
  {\obeylines
   \nonostartXSLTscript}

\long\def\nonostartXSLTscript#1 #2\stopXSLTscript
  {\egroup
   \long\setvalue{\??xl#1}{\doXSLTscript\empty{#2}}}

\long\def\donormalXSLTscript#1#2%
  {\includeXSLTscript{b-capsule-#1}%
   #2%
   \includeXSLTscript{e-capsule-#1}}

\def\includeXSLTscript#1%
  {\csname\ifcsname\??xl#1\endcsname\??xl#1\else\s!empty\fi\endcsname}

\startXSLTscript b-capsule-1.0
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
\stopXSLTscript

\startXSLTscript e-capsule-1.0
</xsl:stylesheet>
\stopXSLTscript

\def\applyXSLTscript
  {\dotripleempty\doapplyXSLTscript}

\long\def\doapplyXSLTscript[#1][#2][#3]%
  {\ifthirdargument
     \bgroup
     \let\doXSLTscript\donormalXSLTscript
     \presetXSLTcharacters
     \donefalse
     \def\docommand##1{\dodoapplyXSLTscript{##1}{\ifdone#3\else#2\fi}{#3}\donetrue}%
     \processcommalist[#1]\docommand
     \egroup
   \else
     \applyXSLTscript[#1][#2][#2]%
   \fi}

% Since a \XML\ file is loaded into memory as a tree, we
% can safely use the same input and output filename, thereby
% avoiding temporary files.

\def\dodoapplyXSLTscript#1#2#3%
  {\bgroup
   \doifundefined{\??xl#1}%
     {\writestatus{XSLT}{unknown script #1}}
     {\writestatus{XSLT}{convert #2 into #3 using #1}%
      \edef\par{\outputnewlinechar}%
      \edef\!!stringc{\getvalue{\??xl#1}}%
      \immediate\openout\scratchwrite=\XSLTscriptfile.xsl
      \immediate\write\scratchwrite{\!!stringc}%
      \immediate\closeout\scratchwrite
      \iftraceXSLTprocessing\wait\fi
      \executeXSLT{\XSLTscriptfile.xsl}{#2}{#3}%
      \iftraceXSLTprocessing\wait\fi}%
   \egroup}

\def\executeXSLT#1#2#3% script input output
  {\executesystemcommand{xsltproc -o #3 #1 #2}}

\long\def\applyXSLTtobuffer
  {\dodoubleempty\doapplyXSLTtobuffer}

\long\def\doapplyXSLTtobuffer[#1][#2]%
  {\expanded{\applyXSLTscript[#1][\TEXbufferfile{\ifsecondargument#2\else\jobname\fi}]}}

\def\resetXSLTscripting#1%
  {\setgvalue{\??xl\s!dummy}{\doXSLTscript{#1}{}}}

\resetXSLTscripting{1.0}

\def\startXSLTscripting
  {\bgroup
   \obeyXSLTcharacters
   \obeylines
   \dostartXSLTscripting}

\long\def\dostartXSLTscripting#1\stopXSLTscripting
  {\egroup
   \let\doXSLTscript\doextendXSLTscript
   \getvalue{\??xl\s!dummy}{#1}}

\long\def\doextendXSLTscript#1#2#3%
  {\setgvalue{\??xl\s!dummy}{\doXSLTscript{#1}{#2#3}}}

\def\applyXSLTscripting
  {\applyXSLTscript[\s!dummy]}

\protect

\doifnotmode{demo}{\endinput}

% \def\Whow{Whow It Works}
%
% \startXSLTscript test capsule 1.0
% <xsl:output method="text"/>
%
% <xsl:template match="/figurelibrary/figure">
%   \Whow \\ #<xsl:apply-templates/>
% </xsl:template>
%
% <xsl:template match="/">
%   <xsl:apply-templates/>
% </xsl:template>
% \stopXSLTscript
%
% \applyXSLTscript [test] [figtest.xml] [crap.tmp] \typefile{crap.tmp}
%
% \startbuffer
% <hello>world</hello>
% \stopbuffer
%
% \applyXSLTtobuffer[test] \typebuffer
%
% \startXSLTscripting
% <xsl:output method="text"/>
% \stopXSLTscripting
%
% \startXSLTscripting
% <xsl:template match="/figurelibrary/figure">
%   <xsl:apply-templates/>
% </xsl:template>
% \stopXSLTscripting
%
% \startXSLTscripting
% <xsl:template match="/">
%   <xsl:apply-templates/>
% </xsl:template>
% \stopXSLTscripting
%
% \applyXSLTscripting [figtest.xml] [crap.tmp]  \typefile{crap.tmp}

\starttext

\startXSLTscript another
<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:cd="http://www.pragma-ade.com/commands"
                version="1.0">

<xsl:output method="text"/>

<xsl:template match="/">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="cd:interface">
  <xsl:apply-templates><xsl:sort order="descending" select="@name"/></xsl:apply-templates>
</xsl:template>

<xsl:template match="cd:command">
  name: <xsl:value-of select="@name"/>\\par
</xsl:template>

</xsl:stylesheet>
\stopXSLTscript

\applyXSLTscript [another] [cont-en.xml] [whatever.tmp]

\readfile{whatever.tmp}{}{}

\stoptext
