%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}{1.001} % loader %registerctxluafile{lxml-lpt}{1.001} % parser %registerctxluafile{lxml-xml}{1.001} % xml finalizers %registerctxluafile{lxml-aux}{1.001} % extras using parser %registerctxluafile{lxml-mis}{1.001} % extras independent of parser \registerctxluafile{lxml-ent}{1.001} % entity hacks \registerctxluafile{lxml-tex}{1.001} % tex finalizers \registerctxluafile{lxml-dir}{1.001} % ctx hacks \registerctxluafile{lxml-ini}{1.001} % interface \unprotect % todo \!!bs \!!es where handy (slower) % todo: { } mandate % avoid # \def\ctxlxml #1{\ctxlua{lxml.#1}} %def\xmlall #1#2{\clf_xmlall {#1}{#2}} %def\xmlatt #1#2{\clf_xmlatt {#1}{#2}} %def\xmlattdef #1#2#3{\clf_xmlattdef {#1}{#2}{#3}} %def\xmlattribute #1#2#3{\clf_xmlattribute {#1}{#2}{#3}} %def\xmlattributedef #1#2#3#4{\clf_xmlattributedef {#1}{#2}{#3}{#4}} %def\xmlchainatt #1#2{\clf_xmlchainatt {#1}{#2}} %def\xmlchainattdef #1#2#3{\clf_xmlchainattdef {#1}{#2}{#3}} %def\xmlrefatt #1#2{\clf_xmlrefatt {#1}{#2}} %def\xmlchecknamespace #1#2#3{\clf_xmlchecknamespace {#1}{#2}{#3}} % element %def\xmlcommand #1#2#3{\clf_xmlcommand {#1}{#2}{#3}} \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}}} %def\xmlcontext #1#2{\clf_xmlcontext {#1}{#2}} %def\xmlcount #1#2{\clf_xmlcount {#1}{#2}} %def\xmldelete #1#2{\clf_xmldelete {#1}{#2}} %def\xmldirect #1{\clf_xmldirect {#1}} % in loops, not dt but root %def\xmldirectives #1{\clf_xmldirectives {#1}} %def\xmldirectivesafter #1{\clf_xmldirectivesafter {#1}} %def\xmldirectivesbefore #1{\clf_xmldirectivesbefore {#1}} %def\xmldisplayverbatim #1{\clf_xmldisplayverbatim {#1}} %def\xmlelement #1#2{\clf_xmlelement {#1}{#2}} %def\xmlfilter #1#2{\clf_xmlfilter {#1}{#2}} %def\xmlfilterlist #1#2{\clf_xmlfilterlist {#1}{#2}} %def\xmlfirst #1#2{\clf_xmlfirst {#1}{#2}} %def\xmlflush #1{\clf_xmlflush {#1}} %def\xmlflushcontext #1{\clf_xmlflushcontext {#1}} %def\xmlflushlinewise #1{\clf_xmlflushlinewise {#1}} %def\xmlflushspacewise #1{\clf_xmlflushspacewise {#1}} %def\xmlfunction #1#2{\clf_xmlfunction {#1}{#2}} %def\xmlinclude #1#2#3{\clf_xmlinclude {#1}{#2}{#3}} %def\xmlincludeoptions#1#2#3#4{\clf_xmlincludeoptions {#1}{#2}{#3}{#4}} %def\xmlinclusion #1{\clf_xmlinclusion {#1}} %def\xmlinclusions #1{\clf_xmlinclusions {#1}} %def\xmlbadinclusions #1{\clf_xmlbadinclusions {#1}} %def\xmlindex #1#2#3{\clf_xmlindex {#1}{#2}{#3}} %let\xmlposition \xmlindex %def\xmlinlineverbatim #1{\clf_xmlinlineverbatim {#1}} %def\xmllast #1#2{\clf_xmllast {#1}{#2}} \def\xmlload #1#2{\clf_xmlload {#1}{#2}{\directxmlparameter\c!entities}{\directxmlparameter\c!compress}} \def\xmlloadbuffer #1#2{\clf_xmlloadbuffer {#1}{#2}{\directxmlparameter\c!entities}{\directxmlparameter\c!compress}} \def\xmlloaddata #1#2{\clf_xmlloaddata {#1}{#2}{\directxmlparameter\c!entities}{\directxmlparameter\c!compress}} %def\xmlloaddirectives #1{\clf_xmlloaddirectives {#1}} \def\xmlloadregistered #1#2{\clf_xmlloadregistered {#1}{\directxmlparameter\c!entities}{\directxmlparameter\c!compress}} %def\xmlmain #1{\clf_xmlmain {#1}} %def\xmlmatch #1{\clf_xmlmatch {#1}} %def\xmlname #1{\clf_xmlname {#1}} %def\xmlnamespace #1{\clf_xmlnamespace {#1}} %def\xmlnonspace #1#2{\clf_xmlnonspace {#1}{#2}} %def\xmlpos #1{\clf_xmlpos {#1}} %def\xmlraw #1#2{\clf_xmlraw {#1}{#2}} %def\xmlregisterns #1#2{\clf_xmlregisterns {#1}{#2}} % document %def\xmlremapname #1#2#3#4{\clf_xmlremapname {#1}{#2}{#3}{#4}} % element %def\xmlremapnamespace #1#2#3{\clf_xmlremapnamespace {#1}{#2}{#3}} % document %def\xmlsave #1#2{\clf_xmlsave {#1}{#2}} %def\xmlsetfunction #1#2#3{\clf_xmlsetfunction {#1}{#2}{#3}} %def\xmlsetsetup #1#2#3{\clf_xmlsetsetup {#1}{#2}{#3}} %def\xmlsnippet #1#2{\clf_xmlsnippet {#1}{#2}} %def\xmlstrip #1#2{\clf_xmlstrip {#1}{#2}} %def\xmlstripanywhere #1#2{\clf_xmlstripanywhere {#1}{#2}} %def\xmlstripnolines #1#2{\clf_xmlstripnolines {#1}{#2}} %def\xmlstripped #1#2{\clf_xmlstripped {#1}{#2}} %def\xmlstrippednolines #1#2{\clf_xmlstrippednolines {#1}{#2}} %def\xmltag #1{\clf_xmltag {#1}} %def\xmltext #1#2{\clf_xmltext {#1}{#2}} %def\xmltobuffer #1#2#3{\clf_xmltobuffer {#1}{#2}{#3}} % id pattern name %def\xmltobufferverbose #1#2#3{\clf_xmltobufferverbose {#1}{#2}{#3}} % id pattern name %def\xmltofile #1#2#3{\clf_xmltofile {#1}{#2}{#3}} % id pattern filename %def\xmltoparameters #1{\clf_xmltoparameters {#1}} %def\xmlverbatim #1{\clf_xmlverbatim {#1}} % experiment: \let\xmlall \clf_xmlall \let\xmlatt \clf_xmlatt \let\xmlattdef \clf_xmlattdef \let\xmlattribute \clf_xmlattribute \let\xmlattributedef \clf_xmlattributedef \let\xmlchainatt \clf_xmlchainatt \let\xmlchainattdef \clf_xmlchainattdef \let\xmlrefatt \clf_xmlrefatt \let\xmlchecknamespace \clf_xmlchecknamespace \let\xmlcommand \clf_xmlcommand % \xmlconcat % \xmlconcatrange \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\xmlflushspacewise \clf_xmlflushspacewise \let\xmlfunction \clf_xmlfunction \let\xmlinclude \clf_xmlinclude \let\xmlincludeoptions \clf_xmlincludeoptions \let\xmlinclusion \clf_xmlinclusion \let\xmlinclusions \clf_xmlinclusions \let\xmlbadinclusions \clf_xmlbadinclusions \let\xmlindex \clf_xmlindex \let\xmlposition \clf_xmlindex \let\xmlinlineverbatim \clf_xmlinlineverbatim \let\xmllast \clf_xmllast % \xmlload % \xmlloadbuffer % \xmlloaddata \let\xmlloaddirectives \clf_xmlloaddirectives % \xmlloadregistered \let\xmlmain \clf_xmlmain \let\xmlmatch \clf_xmlmatch \let\xmlname \clf_xmlname \let\xmlnamespace \clf_xmlnamespace \let\xmlnonspace \clf_xmlnonspace \let\xmlpos \clf_xmlpos \let\xmlraw \clf_xmlraw \let\xmlregisterns \clf_xmlregisterns % document \let\xmlremapname \clf_xmlremapname % element \let\xmlremapnamespace \clf_xmlremapnamespace % document \let\xmlsave \clf_xmlsave %let\xmlsetfunction \clf_xmlsetfunction \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\xmltobufferverbose \clf_xmltobufferverbose % id pattern name \let\xmltofile \clf_xmltofile % id pattern filename \let\xmltoparameters \clf_xmltoparameters \let\xmlverbatim \clf_xmlverbatim \def\xmlinfo #1{\hbox{\ttxx[\clf_xmlinfo{#1}]}} \def\xmlshow #1{\startpacked\ttx\xmlverbatim{#1}\stoppacked} % we need to pass the last argument as function, so \def\xmlsetfunction#1#2#3{\ctxcommand{xmlsetfunction("#1",\!!bs#2\!!es,#3)}} % goodie: \unexpanded\def\xmlprettyprint#1#2% {\xmltobufferverbose{#1}{.}{xml-temp}% \ifdefined\scitebuffer \scitebuffer[#2][xml-temp]% \else \typebuffer[xml-temp][\c!option=#2]% \fi} % kind of special: %def\xmlstartraw{\clf_xmlstartraw} %def\xmlstopraw {\clf_xmlstopraw} \let\xmlstartraw\clf_xmlstartraw \let\xmlstopraw \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\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 %\ef\xmlsetup#1#2{\setupwithargument{#2}{#1}} \let\xmlsetup\setupwithargumentswapped \let\xmls\setupwithargumentswapped % hardly any faster \let\xmlw\setupwithargument % hardly any faster \newtoks \registeredxmlsetups % 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\xmlprependdocumentsetup #1#2{\clf_xmlprependdocumentsetup{#1}{#2}} \unexpanded\def\xmlappenddocumentsetup #1#2{\clf_xmlappenddocumentsetup {#1}{#2}} \unexpanded\def\xmlbeforedocumentsetup #1#2#3{\clf_xmlbeforedocumentsetup {#1}{#2}{#3}} \unexpanded\def\xmlafterdocumentsetup #1#2#3{\clf_xmlafterdocumentsetup {#1}{#2}{#3}} \unexpanded\def\xmlremovesetup #1{\clf_xmlremovesetup {*}{#1}} \unexpanded\def\xmlremovedocumentsetup #1#2{\clf_xmlremovedocumentsetup {#1}{#2}} \unexpanded\def\xmlflushdocumentsetups #1#2{\clf_xmlflushdocumentsetups {#1}{*}{#2}} % #1 == id where to apply * and #2 \unexpanded\def\xmlresetdocumentsetups #1{\clf_xmlresetdocumentsetups {#1}} \let\xmlregistersetup \xmlappendsetup \let\xmlregisterdocumentsetup\xmlappenddocumentsetup \def\xmldocument{main} \unexpanded\def\xmlregisteredsetups {\xmlstarttiming \xmlflushsetups \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} \unexpanded\def\xmlstoptiming {\clf_xmlstoptiming} \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} \unexpanded\def\xmlprocessregistered{\lxml_process\zerocount\xmlloadregistered} \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}} % beware: \xmlmain takes the real root, so also processing % instructions preceding the root element; well, in some % sense that is the root \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 {\bgroup\tt} \unexpanded\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} % we use an xml: namespace so one has to define a suitable verbatim, say % % \definetyping[xml:verbatim][typing] % % this is experimental! \unexpanded\def\startxmldisplayverbatim[#1]% {\startpacked % \begingroup \edef\currenttyping{xml:#1}% \unexpanded\def\stopxmldisplayverbatim {\endofverbatimlines \stoppacked} % \endgroup \doinitializeverbatim \beginofverbatimlines} \unexpanded\def\startxmlinlineverbatim[#1]% {\begingroup \edef\currenttype{xml:#1}% \let\stopxmlinlineverbatim\endgroup \doinitializeverbatim} % will move but is developed for xml \newtoks \collectingtoks \unexpanded\def\startcollect#1\stopcollect {\collectingtoks\@EA{\the\collectingtoks#1}} \unexpanded\def\startexpandedcollect#1\stopexpandedcollect {\normalexpanded{\collectingtoks{\the\collectingtoks#1}}} \unexpanded\def\startcollecting{\collectingtoks\emptytoks} \unexpanded\def\stopcollecting {\the\collectingtoks} \def\inlinemessage #1{\dontleavehmode{\tttf#1}} \def\displaymessage#1{\blank\inlinemessage{#1}\blank} % processing instructions \unexpanded\def\xmlinstalldirective#1#2% {\clf_xmlinstalldirective{#1}{\checkedstrippedcsname#2}} % \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 % unset \or \expandafter\clf_xmlsetcommandtotext % 1 \or \expandafter\clf_xmlsetcommandtonone % 2 \else \expandafter\gobbleoneargument % unset \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!yes] % replace entities \def\xmlmapvalue #1#2#3{\setvalue{\??xmlmapvalue#1:#2}{#3}} % keep #3 to grab spaces \def\xmlvalue #1#2#3{\executeifdefined{\??xmlmapvalue#1:#2}{#3}} %def\xmlvalue #1#2{\ifcsname\??xmlmapvalue#1:#2\endcsname\csname\??xmlmapvalue#1:#2\expandafter\expandafter\gobbleoneargument\expandafter\endcsname\else\expandafter\firstofoneargument\fi} \def\xmldoifelsevalue #1#2{\ifcsname\??xmlmapvalue#1:#2\endcsname\expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\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 (might change): \setnewconstant\xmlautoentities\plusone % 0=off, 1=upper, 2=upper,lower \unexpanded\def\xmlsetentity#1#2{\clf_xmlsetentity{#1}{\detokenize{#2}}} \unexpanded\def\xmltexentity#1#2{\clf_xmltexentity{#1}{\detokenize{#2}}} % \xmlsetentity{tex}{\TEX{}} % {} needed \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} % handy helpers (analogue to MP and LUA and TEX and also 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} \let\xmlapplyselectors\clf_xmlapplyselectors \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(">")) % }