%D \module %D [ file=t-filter, %D version=2010.09.25, %D title=\CONTEXT\ User Module, %D subtitle=Filter, %D author=Aditya Mahajan, %D date=\currentdate, %D copyright=Aditya Mahajan, %D email=adityam umich edu, %D license=Simplified BSD License] \writestatus{loading}{ConTeXt User Module / Filter} \startmodule [filter] \unprotect \startmode[\s!mkiv] \ctxloadluafile{t-filter} \stopmode \startinterface all \setinterfaceconstant {filter} {filter} \setinterfaceconstant {filtercommand} {filtercommand} \setinterfaceconstant {output} {output} \setinterfaceconstant {read} {read} \setinterfaceconstant {readcommand} {readcommand} \setinterfacevariable {httpget} {httpget} \setinterfacevariable {httppost} {httppost} \stopinterface \def\??externalfilter??{externalfilter} \def\currentexternalfilter{} \def\externalfiltercountername{\??externalfilter??-\currentexternalfilter-counter} \newwrite\externalfilterwrite \def\externalfilterparameter#1% {\csname \docheckparentparameter{\??externalfilter??\currentexternalfilter}{#1}% \endcsname} \def\docheckparentparameter#1#2% {\ifcsname#1#2\endcsname #1#2% \else \expandafter\redocheckparentparameter\csname#1\s!parent\endcsname{#2}% \fi} \def\redocheckparentparameter#1#2% {\ifx#1\relax \s!empty \else \docheckparentparameter{#1}{#2}% \fi} \def\setupexternalfilters {\dodoubleargument\dosetupexternalfilters} \def\dosetupexternalfilters[#1][#2]% {\ifsecondargument \getparameters[\??externalfilter??#1][#2]% \else \getparameters[\??externalfilter??][#1]% \fi} \def\defineexternalfilter {\dodoubleargument\dodefineexternalfilter} \def\dodefineexternalfilter[#1][#2]% {\edef\currentexternalfilter{#1}% \getparameters[\??externalfilter??#1][\s!parent=\??externalfilter??,#2]% \doif{\externalfilterparameter\c!continue}\v!yes {\expandafter\newcounter\csname\externalfiltercountername\endcsname}% \setvalue{\e!start#1}{\bgroup\obeylines\dodoubleargument\dostartexternalfilter[#1]}% \setvalue{\e!stop#1}{\doprocessexternalfilter}% \setvalue{process#1file}{\dodoubleargument\doprocessexternalfiler[#1]}% \setvalue{inline#1}{\doinlineexternalfilter[#1]} } \chardef\externalfilter!!method\zerocount %0 = os, 1 = httpget, 2 = httppost \def\dostartexternalfilter[#1][#2]% filter options {% Initializations \egroup %\bgroup in \start#1 \begingroup % to keep assignments local \edef\currentexternalfilter {#1}% \getparameters[\??externalfilter??#1][\c!name=,#2]% \processaction[\externalfilterparameter\c!method] [\v!httpget => \chardef\externalfilter!!method\plusone , \v!httppost => \chardef\externalfilter!!method\plustwp , \v!default => \chardef\externalfilter!!method\zerocount , \v!unknown => \chardef\externalfilter!!method\zerocount ]% % Set the name of temp file for os filter \setexternalfilterfilenames % Capture the contents of the buffer \dostartbuffer[\externalfiltertmpfile][\e!start#1][\e!stop#1]} \def\setexternalfilterfilenames% {% Set the name of temp file for os filter \doifelse{\externalfilterparameter\c!continue}\v!yes {\edef\externalfiltertmpfile{\??externalfilter??-\currentexternalfilter-\csname\externalfiltercountername\endcsname}} {\edef\externalfiltertmpfile{\??externalfilter??-\currentexternalfilter}} \doifsomething{\externalfilterparameter\c!name} {\edef\externalfiltertmpfile{\externalfilterparameter\c!name}} % The following macros are useful for filter= and filtercommand= options % The basename of the external file \edef\externalfilterbasefile {\jobname-\externalfiltertmpfile}% % The name of the buffer to which data is written \edef\externalfilterinputfile {\externalfilterbasefile.tmp}% % The name of the file to which the output is written \edef\externalfilteroutputfile{\externalfilterparameter\c!output}% } \def\doprocessexternalfilter% {\ifcase\externalfilter!!method % os % By defualt, buffers are in memory in MkIV \doifmode\s!mkiv{\savebuffer[\externalfiltertmpfile]}% % Run external command \doexecuteexternalfilter \or % httpget \doexecutehttpgetfilter \or % httppost \doexecutehttpostfilter \fi \doreadprocessedfile \endgroup % Finalization \ifnum\externalfilter!!method=\zerocount \doif{\externalfilterparameter\c!continue}\v!yes {\expandafter\increment\csname\externalfiltercountername\endcsname}% \fi } \def\doexecuteexternalfilter {\doifelse{\externalfilterparameter\c!continue}\v!yes {\doifmode{*first} {\executesystemcommand {mtxrun --ifchanged=\externalfilterinputfile\space bin:\externalfilterparameter\c!filtercommand}}} {\executesystemcommand {\externalfilterparameter\c!filtercommand}}} \def\doexecutehttpgetfilter {\doifmodeelse{\s!mkiv} {\edef\externalfilteroutputfile{\ctxlua{thirddata.externalfilter.httpget (\!!bs\externalfilterparameter\c!filter\!!es , \!!bs\externalfiltertmpfile\!!es , \!!bs\externalfilterparameter\c!separator\!!es)}}} {{\tttf TODO: httpget does not work in MkII}}} \def\doexecutehttppostfilter {{\tttf TODO: httppost is not yet implemented}} \def\doreadprocessedfile {\doif{\externalfilterparameter\c!read}\v!yes {\doiffileelse{\externalfilteroutputfile} {\dodoreadprocessedfile} %TODO: Proper error message {{\tttf File \externalfilteroutputfile\ not found! Check your definition}}}} \def\dodoreadprocessedfile {\begingroup \externalfilterparameter\c!before \processcommacommand[\externalfilterparameter\c!setups]\directsetup \externalfilterparameter\c!readcommand\externalfilteroutputfile \externalfilterparameter\c!after \endgroup} \def\doprocessexternalfiler[#1][#2]% {\edef\currentexternalfilter {#1}% \edef\externalfilterinputfile {#2}% \splitfiletype {#2}% %BEWARE. \edef doesn not work \def\externalfilterbasefile {\splitoffname} \def\externalfilteroutputfile{\externalfilterparameter\c!output}% \doexecuteexternalfilter \doreadprocessedfile} \def\doinlineexternalfilter[#1]% {\begingroup % to keep assignments local \edef\currentexternalfilter {#1}% \getparameters[\??externalfilter??#1][\c!name=,\c!continue=\v!no]% \setexternalfilterfilenames \pushcatcodetable \futurelet\next\dodoinlineexternalfilter} \def\dodoinlineexternalfilter {\ifx\next\bgroup \expandafter\dodoinlineexternalfilterA \else \expandafter\dodoinlineexternalfilterB \fi} \def\dodoinlineexternalfilterA {\setcatcodetable \typcatcodesa \redoinlineexternalfilter} \def\dodoinlineexternalfilterB#1% {\setcatcodetable \vrbcatcodes \def\dododoinlineexternalfilterB##1#1{\redoinlineexternalfilter{##1}}% \dododoinlineexternalfilterB} \def\redoinlineexternalfilter#1% {\immediate\openout \externalfilterwrite\externalfilterinputfile \immediate\write \externalfilterwrite{\detokenize{#1}}% \immediate\closeout\externalfilterwrite \popcatcodetable \doexecuteexternalfilter \doreadprocessedfile \endgroup} \setupexternalfilters [ \c!before=, \c!after=, \c!setups=, \c!continue=\v!no, \c!read=\v!yes, \c!readcommand=\ReadFile, \c!output=\externalfilterbasefile.tex, \c!filter=, \c!method=\v!default, \c!filtercommand={\externalfilterparameter\c!filter\space \externalfilterinputfile}, \c!separator=, ] % For tracing \def\showexternalfilterstate {\starttable[|l|l|] \NC currentexternalfilter \NC \currentexternalfilter \NC \AR \NC externalfilterinputfile \NC \externalfilterinputfile \NC \AR \NC externalfilteroutputfile \NC \externalfilteroutputfile \NC \AR \NC externalfilterbasefile \NC \externalfilterbasefile \NC \AR \stoptable} \protect \stopmodule