%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 / 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 XML Support / Initialization} \registerctxluafile{lxml-tab}{1.001} \registerctxluafile{lxml-pth}{1.001} \registerctxluafile{lxml-ent}{1.001} \registerctxluafile{lxml-mis}{1.001} \registerctxluafile{lxml-ini}{1.001} \unprotect \def\xmlmain #1{\ctxlua{lxml.main("#1")}} \def\xmlall #1#2{\ctxlua{lxml.all("#1","#2")}} \def\xmlatt #1#2{\ctxlua{lxml.attribute("#1","/","#2")}} \def\xmlattdef #1#2#3{\ctxlua{lxml.attribute("#1","/","#2","#3")}} \def\xmlattribute #1#2#3{\ctxlua{lxml.attribute("#1","#2","#3")}} \def\xmlattributedef #1#2#3#4{\ctxlua{lxml.attribute("#1","#2","#3","#4")}} \def\xmlcommand #1#2#3{\ctxlua{lxml.command("#1","#2","#3")}} \def\xmlconcat #1#2#3{\ctxlua{lxml.concat("#1","#2",[[\detokenize{#3}]])}} \def\xmlconcatrange#1#2#3#4#5{\ctxlua{lxml.concatrange("#1","#2","#3","#4",[[\detokenize{#5}]])}} \def\xmlcount #1#2{\ctxlua{lxml.count("#1","#2")}} \def\xmldelete #1#2{\ctxlua{xml.delete(lxml.id("#1"),"#2")}} \def\xmldirectives #1{\ctxlua{lxml.directives.setup("#1")}} \def\xmldirectivesbefore #1{\ctxlua{lxml.directives.before("#1")}} \def\xmldirectivesafter #1{\ctxlua{lxml.directives.after("#1")}} \def\xmlfilter #1#2{\ctxlua{lxml.filter("#1",\!!bs#2\!!es)}} \def\xmlfirst #1#2{\ctxlua{lxml.first("#1","#2")}} \def\xmlflush #1{\ctxlua{lxml.flush("#1")}} % \def\xmlcontent #1{\ctxlua{lxml.content("#1")}} % \def\xmlstrip #1{\ctxlua{lxml.strip("#1")}} % \def\xmlflushstripped #1{\ctxlua{lxml.strip("#1",true)}} \def\xmldirect #1{\ctxlua{lxml.direct("#1")}} % in loops, not dt but root \def\xmlidx #1#2#3{\ctxlua{lxml.idx("#1","#2",\number#3)}} \def\xmlinclude #1#2#3{\ctxlua{lxml.include("#1","#2","#3",true)}} \def\xmlindex #1#2#3{\ctxlua{lxml.index("#1","#2",\number#3)}} \def\xmlinfo #1{\hbox{\ttxx[\ctxlua{lxml.info("#1")}]}} \def\xmlshow #1{\startpacked\ttx\xmlverbatim{#1}\stoppacked} \def\xmllast #1#2{\ctxlua{lxml.last("#1","#2")}} \def\xmlload #1#2{\ctxlua{lxml.load("#1","#2")}} \def\xmlloadbuffer #1#2{\ctxlua{lxml.loadbuffer("#1","#2")}} \def\xmlloaddata #1#2{\ctxlua{lxml.loaddata("#1",\!!bs#2\!!es)}} \def\xmlloadregistered #1#2{\ctxlua{lxml.loadregistered("#1")}} \def\xmlloaddirectives #1{\ctxlua{lxml.directives.load("#1")}} \def\xmlname #1{\ctxlua{lxml.name("#1")}} \def\xmlnamespace #1{\ctxlua{lxml.namespace("#1")}} \def\xmlnonspace #1#2{\ctxlua{lxml.nonspace("#1","#2")}} \def\xmlraw #1#2{\ctxlua{lxml.raw("#1","#2")}} \def\xmlsnippet #1#2{\ctxlua{lxml.snippet("#1",#2)}} \def\xmlelement #1#2{\ctxlua{lxml.element("#1",#2)}} \def\xmlnofelements #1{\ctxlua{lxml.nofelements("#1")}} \def\xmlregisterns #1#2{\ctxlua{xml.registerns("#1","#2")}} % document \def\xmlremapname #1#2#3#4{\ctxlua{xml.remapname(lxml.id("#1"),"#2","#3","#4")}} % element \def\xmlremapnamespace #1#2#3{\ctxlua{xml.rename_space(lxml.id("#1"),"#2","#3")}} % document \def\xmlchecknamespace #1#2#3{\ctxlua{xml.check_namespace(lxml.id("#1"),"#2","#3")}} % element \def\xmlsetfunction #1#2#3{\ctxlua{lxml.setaction("#1","#2",#3)}} \def\xmlsetsetup #1#2#3{\ctxlua{lxml.setsetup("#1","#2","#3")}} \def\xmlstrip #1#2{\ctxlua{lxml.strip("#1","#2")}} \def\xmlstripped #1#2{\ctxlua{lxml.stripped("#1","#2")}} \def\xmlstripnolines #1#2{\ctxlua{lxml.strip("#1","#2",true)}} \def\xmlstrippednolines #1#2{\ctxlua{lxml.stripped("#1","#2",true)}} \def\xmltag #1{\ctxlua{lxml.tag("#1")}} \def\xmltext #1#2{\ctxlua{lxml.text("#1","#2")}} \def\xmltags #1#2{\ctxlua{lxml.tags("#1","#2")}} \def\xmlutfize #1{\ctxlua{lxml.utfize("#1")}} \def\xmlverbatim #1{\ctxlua{lxml.verbatim("#1")}} \def\xmldisplayverbatim #1{\ctxlua{lxml.displayverbatim("#1")}} \def\xmlinlineverbatim #1{\ctxlua{lxml.inlineverbatim("#1")}} %def\xmldoifelse #1#2{\ctxlua{cs.testcase(xml.found(lxml.id("#1"),"#2",false))}} %def\xmldoifelsetext #1#2{\ctxlua{cs.testcase(xml.found(lxml.id("#1"),"#2",true ))}} % kind of special: \def\xmlstartraw{\ctxlua{lxml.startraw()}} \def\xmlstopraw {\ctxlua{lxml.stopraw()}} % todo: \xmldoifelseattribute \def\xmldoif #1#2{\ctxlua{lxml.doif("#1","#2")}} \def\xmldoifnot #1#2{\ctxlua{lxml.doifnot("#1","#2")}} \def\xmldoifelse #1#2{\ctxlua{lxml.doifelse("#1","#2")}} \def\xmldoiftext #1#2{\ctxlua{lxml.doiftext("#1","#2")}} \def\xmldoifnottext #1#2{\ctxlua{lxml.doifnottext("#1","#2")}} \def\xmldoifelsetext #1#2{\ctxlua{lxml.doifelsetext("#1","#2")}} \def\xmldoifelseempty #1#2{\ctxlua{lxml.doifelseempty("#1","#2")}} % #2, "*" or "" == self not yet implemented \def\xmldoifelseselfempty #1{\ctxlua{lxml.doifelseempty("#1")}} \def\xmldefaulttotext #1{\ifcase\xmlprocessingmode\or\or \ctxlua{lxml.set_command_to_text("#1")}\fi} \def\xmldefaulttonone #1{\ifcase\xmlprocessingmode\or\or\or\ctxlua{lxml.set_command_to_none("#1")}\fi} % \startxmlsetups xml:include % \xmlinclude{main}{include}{filename|href} % \stopxmlsetups % % \xmlprependsetup{xml:include} \let\xmlgrab\xmlsetsetup \def\xmlsetup#1#2% % we pass the reference so that we have access to the frozen number {\def\xmlself{#1}% % by using #1 inside a setup; maybe self becomes obsolete \setupwithargument{#2}{#1}} \newtoks \registeredxmlsetups % todo: 1:xml:whatever alwas before 3:xml:something \def\xmlprependsetup #1{\ctxlua{lxml.installsetup(1,"*","#1")}} \def\xmlappendsetup #1{\ctxlua{lxml.installsetup(2,"*","#1")}} \def\xmlbeforesetup #1#2{\ctxlua{lxml.installsetup(3,"*","#1","#2"))}} \def\xmlaftersetup #1#2{\ctxlua{lxml.installsetup(4,"*","#1","#2"))}} \def\xmlprependdocumentsetup #1#2{\ctxlua{lxml.installsetup(1,"#1","#2")}} \def\xmlappenddocumentsetup #1#2{\ctxlua{lxml.installsetup(2,"#1","#2")}} \def\xmlbeforedocumentsetup#1#2#3{\ctxlua{lxml.installsetup(3,"#1","#2","#3"))}} \def\xmlafterdocumentsetup #1#2#3{\ctxlua{lxml.installsetup(4,"#1","#2","#3"))}} \def\xmlremovesetup #1{\ctxlua{lxml.removesetup("*","#1")}} \def\xmlremovedocumentsetup #1#2{\ctxlua{lxml.removesetup("#1","#2")}} \def\xmlflushdocumentsetups #1{\ctxlua{lxml.flushsetups("*","#1")}} \def\xmlresetdocumentsetups #1{\ctxlua{lxml.resetsetups("#1")}} \let\xmlregistersetup \xmlappendsetup \let\xmlregisterdocumentsetup\xmlappenddocumentsetup \def\xmldocument{main} \def\xmlregisteredsetups {\xmlstarttiming \xmlflushsetups \xmldefaulttotext\xmldocument % after include \xmlstoptiming} \def\xmlregistereddocumentsetups#1% {\xmlstarttiming % todo: test for duplicates ! \xmlflushdocumentsetups{#1}% \xmldefaulttotext{#1}% after include \xmlstoptiming} \def\xmlstarttiming{\ctxlua{statistics.starttiming(lxml)}} \def\xmlstoptiming {\ctxlua{statistics.stoptiming (lxml)}} \def\doxmlprocess#1#2#3#4% {\begingroup \edef\xmldocument{#2}% #2 can be \xmldocument and set as such #1{#2}{#3}% \ifcase\xmlprocessingmode \enableXML \else \setcatcodetable\notcatcodes \fi \doifelsenothing{#4} {\directsetup{xml:process}} {\directsetup{#4}}% \endgroup} \def\xmlprocessfile {\doxmlprocess\xmlload} \def\xmlprocessdata {\doxmlprocess\xmlloaddata} \def\xmlprocessbuffer {\doxmlprocess\xmlloadbuffer} \def\xmlprocessregistered{\doxmlprocess\xmlloadregistered} \let\xmlprocess \xmlprocessfile % beware: \xmlmain takes the real root, so also processing % instructions preceding the root element; well, in some % sense that is the root \startsetups xml:process \xmlregistereddocumentsetups\xmldocument \xmlmain\xmldocument \stopsetups \long\def\xmlloop#1#2#3% {\def\xmli##1##2{\xmlidx{#1}{#2/##1}{##2}}% \dorecurse{\xmlcount{#1}{#2}}{#3}} \long\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} \def\xmlcdataobeyedline {\obeyedline} \def\xmlcdataobeyedspace{\strut\obeyedspace} \def\xmlcdatabefore {\bgroup\tt} \def\xmlcdataafter {\egroup} % verbatim (dodo:pre/post whitespace, maybe splot verbatim and % cdata commands), experimental: % % \xmlsetfunction{main}{verbatim}{lxml.displayverbatim} % \xmlsetfunction{main}{verb} {lxml.inlineverbatim} % \def\startxmldisplayverbatim[#1]{} % \def\stopxmldisplayverbatim {} % \def\startxmlinlineverbatim [#1]{} % \def\stopxmlinlineverbatim {} % we use an xml: namespace so one has to define a suitable verbatim, say % % \definetyping[xml:verbatim][typing] % % this is experimental! \def\startxmldisplayverbatim[#1]% {\startpacked % \begingroup \let\currenttypingclass\??tp \edef\currenttyping{xml:#1}% \def\stopxmldisplayverbatim {\endofverbatimlines \stoppacked} % \endgroup \mkinitializeverbatim \beginofverbatimlines} \def\startxmlinlineverbatim[#1]% {\begingroup \let\currenttypingclass\??ty \edef\currenttyping{xml:#1}% \let\stopxmldisplayverbatim\endgroup \mkinitializeverbatim} % will move but is developed for xml \newtoks \collectingtoks \def\startcollect#1\stopcollect {\collectingtoks\@EA{\the\collectingtoks#1}} \def\startexpandedcollect#1\stopexpandedcollect {\expanded{\collectingtoks{\the\collectingtoks#1}}} \def\startcollecting{\collectingtoks\emptytoks} \def\stopcollecting {\the\collectingtoks} \def\inlinemessage #1{\dontleavehmode{\tttf#1}} \def\displaymessage#1{\blank\inlinemessage{#1}\blank} \def\xmltraceentities {\ctxlua{xml.set_text_cleanup(lxml.trace_text_entities)}% \appendtoks\ctxlua{lxml.show_text_entities()}\to\everygoodbye} % processing instructions \def\xmlcontextdirective#1% kind class key value {\executeifdefined{xml#1directive}\gobblethreearguments} % setting up xml: % % \setupxml[\c!method=mkii] % mixed mkiv and mkii % \setupxml[\c!method=mkiv,\c!default=] % mkiv only % \setupxml[\c!method=mkiv,\c!default=\v!none] % mkiv only, undefined -> hidden % \setupxml[\c!method=mkiv,\c!default=\v!text] % mkiv only, undefined -> text % \def\xmlctxdirective#1#2#3{\doif{#1}{clue}{\doif{#2}{page}}{\page[#3]}} \chardef\xmlprocessingmode=0 % 0=mixed, 1=mkivonly, 2=mkivonly-default-text, 3=mkivonly-default-none % \setupxml[method=mkiv,strip=yes,entities=yes,default=text] \newtoks\everysetupxml \def\setupxml[#1]{\getparameters[\??xm][#1]\the\everysetupxml} \def\c!entities{entities} % to be internationalized \def\s!mkiv {mkiv} \def\s!mkii {mkii} % entities \newif\ifautoXMLentities \def\xmlkeepentities{\ctxlua{lxml.reset_entityhandler()}} \def\xmlmkiientities{\ctxlua{lxml.set_mkii_entityhandler()}\autoXMLentitiestrue} \def\xmlmkiventities{\ctxlua{lxml.set_mkiv_entityhandler()}} \let\xmlresolveentities\xmlmkiventities % will become \xmlmkiventities \letvalue{\??xm:1:\s!mkii }\zerocount \letvalue{\??xm:1:\s!mkiv }\plusone \letvalue{\??xm:2:\v!none }\plusone \letvalue{\??xm:2:\v!text }\plustwo \letvalue{\??xm:2:\v!hidden}\plusthree \letvalue{\??xm:ii:\v!yes }\xmlresolveentities \letvalue{\??xm:ii:\v!no }\xmlkeepentities \letvalue{\??xm:ii:\s!mkii}\xmlmkiientities \letvalue{\??xm:ii:\s!mkiv}\xmlmkiventities \letvalue{\??xm:iv:\v!yes }\xmlresolveentities \letvalue{\??xm:iv:\v!no }\xmlkeepentities \letvalue{\??xm:iv:\s!mkii}\xmlmkiventities \letvalue{\??xm:iv:\s!mkiv}\xmlmkiventities \appendtoks \chardef\xmlprocessingmode\executeifdefined{\??xm:1:\@@xmmethod}\zerocount \ifcase\xmlprocessingmode % mkii, permits both methods \executeifdefined{\??xm:ii:\@@xmentities}\xmlkeepentities \or % mkiv, mkiv exclusively \chardef\xmlprocessingmode\executeifdefined{\??xm:2:\@@xmdefault}\plusone \executeifdefined{\??xm:iv:\@@xmentities}\xmlresolveentities \else % unset \fi \ifcase\xmlprocessingmode \ctxlua{characters.setmkiientities()}% \else \ctxlua{characters.setmkiventities()}% \fi \doifelse\@@xmcompress\v!yes % this key may change, maybe compress=yes|no {\ctxlua{xml.strip_cm_and_dt=true}} {\ctxlua{xml.strip_cm_and_dt=false}}% \to \everysetupxml \def\xmlinitialize{\the\everysetupxml} \newcount\charactersactiveoffset \charactersactiveoffset="10000 \startextendcatcodetable\ctxcatcodes \catcode\numexpr\charactersactiveoffset+`<\relax=13 \catcode\numexpr\charactersactiveoffset+`&\relax=13 \catcode\numexpr\charactersactiveoffset+`>\relax=13 \stopextendcatcodetable \startextendcatcodetable\xmlcatcodes \catcode\numexpr\charactersactiveoffset+`<\relax=13 \catcode\numexpr\charactersactiveoffset+`&\relax=13 \catcode\numexpr\charactersactiveoffset+`>\relax=13 \stopextendcatcodetable \ctxlua { % entities are remembered in the format characters.remapentity("<",characters.active_offset + utf.byte("<")) characters.remapentity("&",characters.active_offset + utf.byte("&")) characters.remapentity(">",characters.active_offset + utf.byte(">")) } \setupxml [\c!method=mkii, % mixed mode \c!default=\v!hidden, % ignore elements that are not defined \c!compress=\v!no, % strip comment \c!entities=\v!yes] % replace entities % \defineXMLenvironment[y]{(}{)} % % \startxmlsetups x % /\xmlflush{#1}/ % \stopxmlsetups % % \startxmlsetups xx % \xmlsetsetup{main}{x}{*} % \stopxmlsetups % % \xmlregistersetup{xx} % % \startbuffer % a <&>{b} c % \stopbuffer % % mkii: [\processXMLbuffer]\quad mkiv: [\xmlprocessbuffer{main}{}{}] % some mkii commands, but mkiv-ified \def\xmlmapvalue#1#2#3{\setvalue{\??xm:v:#1:#2}{#3}} % keep #3 to grab spaces \def\xmlvalue #1#2#3{\executeifdefined{\??xm:v:#1:#2}{#3}} \let\xmlmapval\xmlmapvalue \let\xmlval \xmlvalue % brrrr, give this at the top of a style that needs to stub mkiv loading \def\remapXMLtoMKIV {\ifx\xmldocument\undefined\def\xmldocument{main}\fi \def\processXMLfile ##1{\xmlprocessfile \xmldocument{##1}{}}% \def\processXMLfilegrouped ##1{\xmlprocessfile \xmldocument{##1}{}}% maybe still grouped? \def\processXMLbuffer {\dosingleempty\doprocessXMLbuffer}% \def\doprocessXMLbuffer [##1]{\xmlprocessbuffer\xmldocument{##1}{}}% \def\XMLdata ##1{\xmlprocessdata \xmldocument{##1}{}}% \def\startXMLdata##1\stopXMLdata{\xmlprocessdata \xmldocument{##1}{}}} \let\normalprocessXMLfilegrouped\processXMLfilegrouped \def\processXMLfileMKIV % one-shot, will become obsolete, personal hack {\dosingleempty\doprocessXMLfileMKIV} \def\doprocessXMLfileMKIV[#1]% {\def\processXMLfilegrouped##1% {\let\processXMLfilegrouped\normalprocessXMLfilegrouped \doifelsenothing{#1}{\xmlprocess{main}{##1}{}}{\xmlprocess{#1}{##1}{}}}} \protect \endinput