%D \module %D [ file=lxml-ini, %D version=2007.08.17, %D title=\CONTEXT\ \XML\ Support, %D subtitle=Initialization, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. %D Todo: auto apply setups (manage at lua end) %D Todo: manuak: \xmlinclusion \xmlinclusions \writestatus{loading}{ConTeXt XML Support / Initialization} %registerctxluafile{lxml-tab}{} % loader %registerctxluafile{lxml-lpt}{} % parser %registerctxluafile{lxml-xml}{} % xml finalizers %registerctxluafile{lxml-aux}{} % extras using parser %registerctxluafile{lxml-mis}{} % extras independent of parser \registerctxluafile{lxml-ent}{} % entity hacks \registerctxluafile{lxml-tex}{} % tex finalizers \registerctxluafile{lxml-dir}{} % ctx hacks \registerctxluafile{lxml-ini}{} % interface \unprotect % todo: { } mandate so that we can alias % undocumented: \def\ctxlxml #1{\ctxlua{lxml.#1}} % for now indirect .. this will change when we have updated luatex (scan_argument) \def\xmlconcat #1#2#3{\clf_xmlconcat {#1}{#2}{\detokenize{#3}}} \def\xmlconcatrange #1#2#3#4#5{\clf_xmlconcatrange{#1}{#2}{#3}{#4}{\detokenize{#5}}} %D Maybe I should add \type {\unexpanded} here: \def\xmlloadfile #1#2{\clf_xmlloadfile {#1}{#2}{\directxmlparameter\c!compress}} \def\xmlloadbuffer#1#2{\clf_xmlloadbuffer{#1}{#2}{\directxmlparameter\c!compress}} \def\xmlloaddata #1#2{\clf_xmlloaddata {#1}{#2}{\directxmlparameter\c!compress}} \let\xmlload\xmlloadfile % aliased %let\xmlall \clf_xmlall %let\xmlatt \clf_xmlatt %let\xmlattdef \clf_xmlattdef %let\xmlattribute \clf_xmlattribute %let\xmlattributedef \clf_xmlattributedef %let\xmlbadinclusions \clf_xmlbadinclusions %let\xmlchainatt \clf_xmlchainatt %let\xmlchainattdef \clf_xmlchainattdef %let\xmlchecknamespace \clf_xmlchecknamespace %let\xmlcommand \clf_xmlcommand %let\xmlcontext \clf_xmlcontext %let\xmlcount \clf_xmlcount %let\xmldelete \clf_xmldelete %let\xmldirect \clf_xmldirect % in loops, not dt but root %let\xmldirectives \clf_xmldirectives %let\xmldirectivesafter \clf_xmldirectivesafter %let\xmldirectivesbefore \clf_xmldirectivesbefore %let\xmldisplayverbatim \clf_xmldisplayverbatim %let\xmlelement \clf_xmlelement %let\xmlfilter \clf_xmlfilter %let\xmlfilterlist \clf_xmlfilterlist %let\xmlfirst \clf_xmlfirst %let\xmlflush \clf_xmlflush %let\xmlflushcontext \clf_xmlflushcontext %let\xmlflushlinewise \clf_xmlflushlinewise %let\xmlflushpure \clf_xmlflushpure %let\xmlflushspacewise \clf_xmlflushspacewise %let\xmlflushtext \clf_xmlflushtext %let\xmlfunction \clf_xmlfunction %let\xmlinclude \clf_xmlinclude %let\xmlincludeoptions \clf_xmlincludeoptions %let\xmlinclusion \clf_xmlinclusion %let\xmlinclusionbase \clf_xmlinclusionbase %let\xmlinclusions \clf_xmlinclusions %let\xmlindex \clf_xmlindex %let\xmlinlineverbatim \clf_xmlinlineverbatim %let\xmllast \clf_xmllast %let\xmllastatt \clf_xmllastatt %let\xmllastmatch \clf_xmllastmatch %let\xmllastpar \clf_xmllastpar %let\xmlloaddirectives \clf_xmlloaddirectives %let\xmlmain \clf_xmlmain %let\xmlmatch \clf_xmlmatch %let\xmlname \clf_xmlname %let\xmlnamespace \clf_xmlnamespace %let\xmlnonspace \clf_xmlnonspace %let\xmlpar \clf_xmlpar %let\xmlparam \clf_xmlparam %let\xmlpath \clf_xmlpath %let\xmlpopmatch \clf_xmlpopmatch %let\xmlpos \clf_xmlpos %let\xmlpure \clf_xmlpure %let\xmlpushmatch \clf_xmlpushmatch %let\xmlraw \clf_xmlraw %let\xmlrefatt \clf_xmlrefatt %let\xmlregisterns \clf_xmlregisterns % document %let\xmlremapname \clf_xmlremapname % element %let\xmlremapnamespace \clf_xmlremapnamespace % document %let\xmlsave \clf_xmlsave %let\xmlsetatt \clf_xmlsetatt %let\xmlsetattribute \clf_xmlsetattribute %let\xmlsetpar \clf_xmlsetpar %let\xmlsetparam \clf_xmlsetparam %let\xmlsetsetup \clf_xmlsetsetup %let\xmlsnippet \clf_xmlsnippet %let\xmlstrip \clf_xmlstrip %let\xmlstripanywhere \clf_xmlstripanywhere %let\xmlstripnolines \clf_xmlstripnolines %let\xmlstripped \clf_xmlstripped %let\xmlstrippednolines \clf_xmlstrippednolines %let\xmltag \clf_xmltag %let\xmltext \clf_xmltext %let\xmltobuffer \clf_xmltobuffer % id pattern name %let\xmltobuffertextonly \clf_xmltobuffertextonly % id pattern name %let\xmltobufferverbose \clf_xmltobufferverbose % id pattern name %let\xmltofile \clf_xmltofile % id pattern filename %let\xmltoparameters \clf_xmltoparameters %let\xmlverbatim \clf_xmlverbatim \let\xmlposition \xmlindex \unexpanded\def\xmlinfo#1{\hbox{\ttxx[\xmlname{#1}]}} \unexpanded\def\xmlshow#1{\startpacked\ttx\xmlverbatim{#1}\stoppacked} % the next one is handy for mode runs because it enforces a consistent % #1 indexing (needed when using \xmltext{main:123}{...} like calls %let\xmladdindex \clf_xmladdindex % we need to pass the last argument as function, so \unexpanded\def\xmlsetfunction#1#2#3{\ctxcommand{xmlsetfunction("#1",\!!bs#2\!!es,#3)}} % goodie: \def\xmltempbuffername{xml-temp} \unexpanded\def\prettyprintbuffer#1#2% only used here {\ifdefined\scitebuffer \scitebuffer[#2][#1]% \else \typebuffer[#1][\c!option=#2]% \fi} \unexpanded\def\xmlprettyprint#1#2% {\xmltobufferverbose{#1}{.}{\xmltempbuffername}% \prettyprintbuffer\xmltempbuffername{#2}} \unexpanded\def\xmlprettyprinttext#1#2% {\xmltobuffertextonly{#1}{.}{\xmltempbuffername}% \prettyprintbuffer\xmltempbuffername{#2}} \unexpanded\def\inlineprettyprintbuffer#1#2% only used here {\ifdefined\sciteinlinebuffer \sciteinlinebuffer[#2][#1]% \else \typeinlinebuffer[#1][\c!option=#2]% \fi} \unexpanded\def\xmlinlineprettyprint#1#2% {\xmltobufferverbose{#1}{.}{\xmltempbuffername}% \inlineprettyprintbuffer\xmltempbuffername{#2}} \unexpanded\def\xmlinlineprettyprinttext#1#2% {\xmltobuffertextonly{#1}{.}{\xmltempbuffername}% \inlineprettyprintbuffer\xmltempbuffername{#2}} % kind of special: \let\xmlstartraw\clf_xmlstartraw \let\xmlstopraw \clf_xmlstopraw \let\startxmlraw\clf_xmlstartraw \let\stopxmlraw \clf_xmlstopraw % these are expandable! todo: \xmldoifelseattribute %let\xmldoif \clf_xmldoif %let\xmldoifnot \clf_xmldoifnot %let\xmldoifelse \clf_xmldoifelse %let\xmldoiftext \clf_xmldoiftext %let\xmldoifnottext \clf_xmldoifnottext %let\xmldoifelsetext \clf_xmldoifelsetext %let\xmldoifatt \clf_xmldoifatt %let\xmldoifnotatt \clf_xmldoifnotatt %let\xmldoifelseatt \clf_xmldoifelseatt %let\xmldoifempty \clf_xmldoifempty %let\xmldoifnotempty \clf_xmldoifnotempty %let\xmldoifelseempty \clf_xmldoifelseempty %let\xmldoifselfempty \clf_xmldoifselfempty %let\xmldoifnotselfempty \clf_xmldoifnotselfempty %let\xmldoifelseselfempty \clf_xmldoifelseselfempty \let\xmldoiftextelse \xmldoifelsetext \let\xmldoifemptyelse \xmldoifelseempty \let\xmldoifselfemptyelse \xmldoifelseselfempty % \startxmlsetups xml:include % \xmlinclude{main}{include}{filename|href} % \stopxmlsetups % % \xmlprependsetup{xml:include} % \let\xmlgrab\xmlsetsetup % obsolete % \let\xmlself\s!unknown % obsolete \let\xmlsetup\setupwithargumentswapped \let\xmls \setupwithargumentswapped % hardly any faster \let\xmlw \setupwithargument % hardly any faster % todo: 1:xml:whatever always before 3:xml:something \unexpanded\def\xmlprependsetup #1{\clf_xmlprependsetup{*}{#1}} \unexpanded\def\xmlappendsetup #1{\clf_xmlappendsetup {*}{#1}} \unexpanded\def\xmlbeforesetup #1#2{\clf_xmlbeforesetup {*}{#1}{#2}} \unexpanded\def\xmlaftersetup #1#2{\clf_xmlaftersetup {*}{#1}{#2}} \unexpanded\def\xmlremovesetup #1{\clf_xmlremovesetup {*}{#1}} \unexpanded\def\xmlresetsetups {\clf_xmlresetsetups {*}} \unexpanded\def\xmlprependdocumentsetup #1#2{\clf_xmlprependsetup{#1}{#2}} \unexpanded\def\xmlappenddocumentsetup #1#2{\clf_xmlappendsetup {#1}{#2}} \unexpanded\def\xmlbeforedocumentsetup #1#2#3{\clf_xmlbeforesetup {#1}{#2}{#3}} \unexpanded\def\xmlafterdocumentsetup #1#2#3{\clf_xmlaftersetup {#1}{#2}{#3}} \unexpanded\def\xmlremovedocumentsetup #1#2{\clf_xmlremovesetup {#1}{#2}} \unexpanded\def\xmlresetdocumentsetups #1{\clf_xmlresetsetups {#1}} \unexpanded\def\xmlflushsetups #1{\clf_xmlflushsetups {#1}{*}{}} % #1 == id where to apply * \unexpanded\def\xmlflushdocumentsetups #1#2{\clf_xmlflushsetups {#1}{*}{#2}} % #1 == id where to apply * and #2 \let\xmlregistersetup \xmlappendsetup \let\xmlregisterdocumentsetup\xmlappenddocumentsetup \def\xmldocument{main} \unexpanded\def\xmlregisteredsetups {\xmlstarttiming \xmlflushsetups\xmldocument \xmldefaulttotext\xmldocument % after include \xmlstoptiming} \unexpanded\def\xmlregistereddocumentsetups#1#2% id setups {\xmlstarttiming % todo: test for duplicates ! \xmlflushdocumentsetups{#1}{#2}% \xmldefaulttotext{#1}% after include \xmlstoptiming} \unexpanded\def\xmlstarttiming{\clf_xmlstarttiming} % undocumented \unexpanded\def\xmlstoptiming {\clf_xmlstoptiming} % undocumented \def\lxml_process#1#2#3#4#5% flag \loader id name what initializersetup {\begingroup \edef\xmldocument{#3}% #2 can be \xmldocument and set as such %xmlpushdocument{#3}% #2{#3}{#4}% \setcatcodetable\notcatcodes \doifelsenothing{#5}% {\xmlsetup{#3}{xml:process}}% {\xmlsetup{#3}{#5}}% %xmlpopdocument \endgroup} \unexpanded\def\xmlprocessfile {\lxml_process\plusone \xmlload} \unexpanded\def\xmlprocessdata {\lxml_process\zerocount\xmlloaddata} \unexpanded\def\xmlprocessbuffer {\lxml_process\zerocount\xmlloadbuffer} \let\xmlprocess \xmlprocessfile \startxmlsetups xml:flush \xmlflush{#1} \stopxmlsetups \startxmlsetups xml:process \xmlregistereddocumentsetups{#1}{#1} \xmlmain{#1} \stopxmlsetups \unexpanded\def\xmlloadonly#1#2#3% {\xmlload{#1}{#2}% \xmlregistereddocumentsetups{#1}{#3}} % replaced by concat % % \unexpanded\def\xmlconnect#1#2#3% inefficient % {\scratchcounter\xmlcount{#1}{#2}\relax % \ifcase\scratchcounter \or % \xmlall{#1}{#2}% % \else % \dorecurse \scratchcounter % {\ifnum\recurselevel>\plusone#3\fi % \xmlidx{#1}{#2}\recurselevel}% % \fi} \unexpanded\def\xmlcdataobeyedline {\obeyedline} \unexpanded\def\xmlcdataobeyedspace{\strut\obeyedspace} \unexpanded\def\xmlcdatabefore {\begingroup\tt} \unexpanded\def\xmlcdataafter {\endgroup} % verbatim (dodo:pre/post whitespace, maybe splot verbatim and % cdata commands), experimental: % % \xmlsetfunction{main}{verbatim}{lxml.displayverbatim} % \xmlsetfunction{main}{verb} {lxml.inlineverbatim} % we use an xml: namespace so one has to define a suitable verbatim, say % % \definetyping[xml:verbatim][typing] % % this is experimental! \unexpanded\def\startxmldisplayverbatim {\dosingleempty\lxml_start_display_verbatim} \let\stopxmldisplayverbatim\relax \def\lxml_start_display_verbatim[#1]% {\startpacked \edef\currenttyping{#1}% \ifx\currenttyping\empty \let\currenttyping\v!typing \else % maybe test for existence \edef\currenttyping{xml:\currenttyping}% \fi \unexpanded\def\stopxmldisplayverbatim {\endofverbatimlines \stoppacked}% \doinitializeverbatim \beginofverbatimlines} \unexpanded\def\startxmlinlineverbatim {\dosingleempty\lxml_start_inline_verbatim} \let\stopxmlinlineverbatim\relax \unexpanded\def\lxml_start_inline_verbatim[#1]% {\begingroup \edef\currenttype{#1}% \ifx\currenttype\empty \let\currenttype\v!type \else % maybe test for existence \edef\currenttype{xml:\currenttype}% \fi \let\stopxmlinlineverbatim\endgroup \doinitializeverbatim} % processing instructions \unexpanded\def\xmlinstalldirective#1#2% {\clf_xmlinstalldirective{#1}{\csstring#2}} % an example: % \appendtoks \xmlinstalldirective{tex}{xmltexcommand}% \to \everyjob \def\xmltexcommand#1{\begincsname#1\endcsname} % \def\xmlcontextdirective#1% kind class key value % {\executeifdefined{xml#1directive}\gobblethreearguments} % setting up xml: % % \setupxml[\c!default=] % mkiv only == text % \setupxml[\c!default=\v!none] % mkiv only, undefined -> hidden % \setupxml[\c!default=\v!text] % mkiv only, undefined -> text % \def\xmlctxdirective#1#2#3{\doif{#1}{clue}{\doif{#2}{page}}{\page[#3]}} \newconstant\xmlprocessingmode % 0=unset, 1=text, 2=hidden \installcorenamespace{xml} \installcorenamespace{xmldefaults} \installcorenamespace{xmlmapvalue} \installdirectcommandhandler \??xml {xml} \letvalue{\??xmldefaults\v!normal}\zerocount \letvalue{\??xmldefaults\v!none }\zerocount \letvalue{\??xmldefaults\v!text }\plusone \letvalue{\??xmldefaults\v!hidden}\plustwo \unexpanded\def\xmldefaulttotext {\ifcase\xmlprocessingmode \expandafter\gobbleoneargument % 0 (none) \or \expandafter\clf_xmlsetcommandtotext % 1 (normal) \or \expandafter\clf_xmlsetcommandtonone % 2 (hidden) \else \expandafter\gobbleoneargument % (none) \fi} \appendtoks \xmlprocessingmode\executeifdefined{\??xmldefaults\directxmlparameter\c!default}\plusone \to \everysetupxml \setupxml [\c!default=, % flush all \c!compress=\v!no, % strip comment \c!entities=\v!no] % load big entity file \appendtoks \doif{\directxmlparameter\c!entities}\v!yes\clf_xmlloadentities \to \everysetupxml \def\xmlmapvalue #1#2#3{\setvalue{\??xmlmapvalue#1:#2}{#3}} % keep #3 to grab spaces \def\xmldoifelsevalue #1#2{\ifcsname\??xmlmapvalue#1:#2\endcsname\expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi} \def\xmlvalue#1#2% #3 {\ifcsname\??xmlmapvalue#1:#2\endcsname \expandafter\expandafter\expandafter\lastnamedcs\expandafter\gobbleoneargument \else \expandafter\firstofoneargument \fi} \def\xmlmappedvalue#1#2#3% {\ifcsname\??xmlmapvalue#1:#2\endcsname \expandafter\lastnamedcs \else \csname\??xmlmapvalue#1:#3\expandafter\endcsname \fi} \let\xmldoifvalueelse\xmldoifelsevalue \let\xmlmapval\xmlmapvalue \let\xmlval \xmlvalue %D Experimental: \def\xmlgetindex #1{\clf_xmlgetindex {\xmldocument}{#1}} \def\xmlwithindex #1#2{\clf_xmlwithindex{\xmldocument}{#1}{#2}} \def\xmlreference #1#2{\string\xmlwithindex{#1}{#2}} %D Entities: %D %D \starttyping %D \xmlsetentity{tex}{\TEX{}} % {} needed %D \stoptyping \unexpanded\def\xmlsetentity#1#2{\clf_xmlsetentity{#1}{\detokenize{#2}}} \unexpanded\def\xmltexentity#1#2{\clf_xmltexentity{#1}{\detokenize{#2}}} %D The following might change (or even disappear) so we keep it undocumented. \setnewconstant\xmlautoentities\plusone % 0=off, 1=upper, 2=upper,lower \unexpanded\def\xmle {\ifcase\xmlautoentities \expandafter\lxml_e_none \or \expandafter\lxml_e_upper \or \expandafter\lxml_e_upperlower \else \expandafter\lxml_e_none \fi} \def\lxml_e_none#1#2% safe {#1} \def\lxml_e_upper#1#2% can be abbreviation {\ifcsname#2\endcsname \csname#2\expandafter\endcsname \else #1% \fi} \def\lxml_e_upperlower#1#2% can be anything, so unsafe {\ifcsname#2\endcsname \csname#2\expandafter\endcsname \else\ifcsname#1\endcsname \csname#1\expandafter\expandafter\expandafter\endcsname \else #1% \fi\fi} % \def\lxml_e_upper#1#2% can be abbreviation % {\ifcsname\detokenize{#2}\endcsname % \lastnamedcs % \else % \detokenize{#1}% % \fi} % \def\lxml_e_upperlower#1#2% can be anything, so unsafe % {\ifcsname\detokenize{#2}\endcsname % \expandafter\lastnamedcs % \else\ifcsname\detokenize{#1}\endcsname % \doubleexpandafter\lastnamedcs % \else % \detokenize{#1}% % \fi\fi} %D We keep these around as there are also MP, LUA and TEX variants but %D they are not the same as in \MKII. \unexpanded\def\processXMLbuffer {\dosingleempty\lxml_process_buffer} \def\lxml_process_buffer[#1]% {\xmlprocessbuffer{temp}{#1}{}} \unexpanded\def\processXMLfile#1% {\xmlprocessfile{temp}{#1}{}} \unexpanded\def\XMLdata#1% {\xmlprocessdata{temp}{#1}{}} \let\processxmlbuffer\processXMLbuffer \let\processxmlfile \processXMLfile \let\xmldata \XMLdata \unexpanded\def\xmlsetinjectors[#1]% {\clf_xmlsetinjectors{#1}} \unexpanded\def\xmlresetinjectors {\clf_xmlresetinjectors{}} % \def\xmlinjector#1{\executeifdefined{#1}\donothing} \def\xmlinjector#1{\fastsetup{xml:directive:injector:#1}} \startsetups xml:directive:injector:page \page \stopsetups \startsetups xml:directive:injector:column \column \stopsetups \startsetups xml:directive:injector:blank \blank \stopsetups \startsetups xml:directive:injector:noline \vskip-\lineheight \stopsetups \let\xmlapplyselectors\clf_xmlapplyselectors % \let\xmlcatcodes\notcatcodes \protect \endinput % \newcount\charactersactiveoffset \charactersactiveoffset="10000 % % \startextendcatcodetable\ctxcatcodes % \catcode\numexpr\charactersactiveoffset+`<\relax=13 % \catcode\numexpr\charactersactiveoffset+`&\relax=13 % \catcode\numexpr\charactersactiveoffset+`>\relax=13 % \stopextendcatcodetable % % \startextendcatcodetable\xmlcatcodes % not needed % \catcode\numexpr\charactersactiveoffset+`<\relax=13 % \catcode\numexpr\charactersactiveoffset+`&\relax=13 % \catcode\numexpr\charactersactiveoffset+`>\relax=13 % \stopextendcatcodetable % % \ctxlua { % entities are remembered in the format % commands.remapentity("<",characters.activeoffset + utf.byte("<")) % commands.remapentity("&",characters.activeoffset + utf.byte("&")) % commands.remapentity(">",characters.activeoffset + utf.byte(">")) % }