%D \module %D [ file=xtag-pre, %D version=2000.12.20, %D title=\CONTEXT\ XML Macros, %D subtitle=Predefined Things, %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. \writestatus{loading}{ConTeXt XML Macros / Predefined} %D Here we predefine some escapes, processing instructions, %D entities and other handy things. \unprotect %D For \MKIV: \setvalue{@u@s@"}#1#2"{#2} \setvalue{@g@s@"}#1#2"{\scratchtoks{#2}} \setvalue{@u@s@'}#1#2'{#2} \setvalue{@g@s@'}#1#2'{\scratchtoks{#2}} \setvalue{@u@s@ }#1#2 {#2} \setvalue{@g@s@ }#1#2 {\scratchtoks{#2}} \def\unstringed#1{\csname\ifcsname @u@s@#1\endcsname @u@s@#1\else\s!empty\fi\endcsname#1} \def\grabstring#1{\csname\ifcsname @g@s@#1\endcsname @g@s@#1\else\s!empty\fi\endcsname#1} \def\dowithgrabbedstring#1% {\def\@@dowithgrabbedstring{#1}% \afterassignment\@@dowithgrabbedstring\grabstring} %D Let's get rid of ligatures: % \definefonthandling [default] [noligs] %D First we define the default error handler. When tracing is %D activated, the unknown element is showed verbatim. \defineXMLenvironment [\s!default] \defaultXMLelement \defaultXMLelement \defineXMLsingular [\s!default] \defaultXMLelement % \def\defaultXMLelement % {\iftraceXMLelements[\currentXMLfullidentifier]\fi} \def\defaultXMLelement {\iftraceXMLelements{\infofont<\currentXMLfullidentifier>}\fi} %D We can use the default handler to implement automatic %D element hiding. Beware: this overloads the tracer. % \def\startXMLignore{\dododefineXMLignore \s!default} % \def\stopXMLignore {\dododefineXMLprocess\s!default} \newcount\xmlignoredepth \def\startXMLignore{\ifcase\xmlignoredepth\dododefineXMLignore\s!default\fi\advance\xmlignoredepth\plusone} \def\stopXMLignore {\advance\xmlignoredepth\minusone\ifcase\xmlignoredepth\dododefineXMLprocess\s!default\fi} %D The following entities need to be defined anyway. They %D may be overloaded later. % rest also \letter \defineXMLentities [amp] {\letterampersand} {\&} \defineXMLentities [gt] {\string>} {\mathematics{>}} \defineXMLentities [lt] {\string<} {\mathematics{<}} \defineXMLentities [quot] {\string"} {\mathematics{"}} \defineXMLentities [apos] {\string`} {\mathematics{'}} %D Of course we define: \defineXMLentities [tex] {tex} {\TeX} \defineXMLentities [context] {context} {\ConTeXt} \defineXMLentities [xml] {xml} {XML} \defineXMLentities [xsd] {xsd} {XSD} \defineXMLentities [html] {html} {HTML} %D The following entities are used for internal purposes and %D concern characters that are kind of problematic in \TEX\ %D input. \defineXMLentities [tex-hash] {\letterhash} {\#} \defineXMLentities [tex-dollar] {\letterdollar} {\$} \defineXMLentities [tex-percent] {\letterpercent} {\%} \defineXMLentities [tex-backslash] {\letterbackslash} {\texescape} \defineXMLentities [tex-hat] {\letterhat} {\^{}} \defineXMLentities [tex-underscore] {\letterunderscore} {\_} \defineXMLentities [tex-leftbrace] {\letterleftbrace} {\leftargument} \defineXMLentities [tex-rightbrace] {\letterrightbrace} {\rightargument} \defineXMLentities [tex-bar] {\letterbar} {\vl} \defineXMLentities [tex-tilde] {\lettertilde} {\~{}} %D Some pretty printing macros will use color, for which we %D define a dedicated palet here. \definepalet [xtag] [0=darkgray, 1=darkred, 2=darkgreen, 3=darkblue, 4=darkcyan, 5=darkmagenta, 6=darkyellow, 7=black, 8=black] %D An example of its usage can be found in the pretty %D printing macros in the run time module. \newif\ifautoXMLshow \autoXMLshowtrue \newif\ifshowXMLarguments \showXMLargumentstrue \def\setupXMLfile{\dodoubleargument\getparameters[\??xf]} \setupXMLfile [\c!inbetween=\blank, \c!level=1] \fetchruntimecommand\showXMLfile {\f!xtagprefix\s!run} \fetchruntimecommand\showXMLbuffer{\f!xtagprefix\s!run} \fetchruntimecommand\showXMLtext {\f!xtagprefix\s!run} \fetchruntimecommand\showXMLign {\f!xtagprefix\s!run} \fetchruntimecommand\showXMLnop {\f!xtagprefix\s!run} \fetchruntimecommand\showXMLtxt {\f!xtagprefix\s!run} \fetchruntimecommand\showXMLpar {\f!xtagprefix\s!run} \fetchruntimecommand\showXMLlin {\f!xtagprefix\s!run} \fetchruntimecommand\showXMLwrd {\f!xtagprefix\s!run} \fetchruntimecommand\showXMLemp {\f!xtagprefix\s!run} \fetchruntimecommand\showXMLbreak {\f!xtagprefix\s!run} %D By default, we will ignore escape commands, preceded by %D \type {}. \defineXMLescape [\s!default] {\gobbleuntil{>}} %D The comment escape has the form: %D %D \starttyping %D %D \stoptyping \defineXMLescape [--] {\gobbleuntil{-->}} %D The \type {CDATA} escape is kind of unique in its %D strange syntax. %D %D \starttyping %D %D \stoptyping %D %D Watch this rather obscure definition (we need to pass an %D \type {[} to the macro. \chardef\XMLcdatamethod=1 \newtoks \everyXMLcdata % \appendtoks \tt \to \everyXMLcdata \setvalue{XMLcdatamethod1}% {\skipfirstverbatimlinefalse \processtaggeddisplayverbatim{]]>}} \setvalue{XMLcdatamethod2}% {\begingroup \obeylines \obeyspaces \the\everyXMLcdata \processXMLcdata} \long\def\processXMLcdata#1]]>% {#1\endgroup} \defineXMLescape [CDATA] {\executeifdefined{XMLcdatamethod\number\XMLcdatamethod}{\begingroup\processXMLcdata}} %D \starttyping %D %D %D \stoptyping \defineXMLescape [ATTLIST]{\gobbleuntil>} \defineXMLescape [ELEMENT]{\gobbleuntil>} %D \starttyping %D %D %D %D \stoptyping \defineXMLescape [ENTITY] \handleXMLentityescape \def\handleXMLentityescape#1>% {\dohandleXMLentityescape#1 @ @ @ @ @ @>} \def\dohandleXMLentityescape#1 #2 #3 #4> {\doifnot{#1}\letterpercent {\doifelse{#2}{SYSTEM} {\dohandleXMLentitySYSTEM#1 #2 #3 #4>} {\dohandleXMLentityDEFINE#1 #2 #3 #4>}}} \def\dohandleXMLentitySYSTEM#1 #2 #3 #4 #5 #6>% name SYSTEM .... {\doifelse{#4}{@} {\expanded{\defineXMLentity[#1]{\noexpand\readXMLsystem{\unstringed#3}}}} {\doif{#4}{NDATA} % maybe we should also store the NDATA {\expanded{\defineXMLentity[#1]{\noexpand\readXMLndata{\unstringed#3}}}}}} \def\readXMLsystem#1% {\readfile{#1} {\writestatus{xml-system}{reading #1}} {\writestatus{xml-system}{unable to locate #1}}} \def\readXMLndata#1% {#1} % {\externalfigure[#1]} \def\dohandleXMLentityDEFINE#1 %#2 #3 #4 #5 #6>% name replacement {\def\docommand##1>{\expanded{\defineXMLentity[#1]{\the\scratchtoks}}}% \afterassignment\docommand\grabstring} %D Such entities can be encapsulated in a \type {DOCTYPE} %D element. Therefore we remove the outer level of document %D type definitions. %D %D \starttyping %D %D %D %D %D %D %D %D %D %D \stoptyping \defineXMLescape [DOCTYPE] \handleXMLdoctype \def\handleXMLdoctype {\let\XMLdoctype\empty \dohandleXMLdoctype} \def\dohandleXMLdoctype {\futurelet\nexttoken\dohandleXMLdoctok} \def\dohandleXMLdoctok {\ifx\nexttoken>% % [doctype: \XMLdoctype] \@EA\gobbleuntil\@EA>% \else\ifx\nexttoken\blankspace % [doctype: \XMLdoctype] \@EAEAEA\dodohandleXMLdoctype \else \@EAEAEA\redoXMLdoctype \fi\fi} \def\redoXMLdoctype#1% {\edef\XMLdoctype{\XMLdoctype#1}\dohandleXMLdoctype} \def\dodohandleXMLdoctype#1% {\executeifdefined{XMLdoctype#1}{\gobbleuntil>}} \setvalue{XMLdoctype>}{} \setvalue{XMLdoctype[}{\processuntil{]>}} % or \gobbleuntil{]>}} \def\XMLdoctypeS YSTEM % {\dowithgrabbedstring\dodohandleXMLdoctype} \def\XMLdoctypeP UBLIC % {\dowithgrabbedstring{\dowithgrabbedstring\dodohandleXMLdoctype}} % wrong % % \def\XMLdoctypeS YSTEM {\XMLgrabstring} % \def\XMLdoctypeP UBLIC {\XMLgrabstring} % % \def\XMLgrabstring % {\doifnextcharelse>{\gobbleuntil>}{\dowithgrabbedstring\XMLgrabstring}} %D Some day we may need to support entities within a %D document type namespace. %D As an example of processing instructions, we implement a %D \CONTEXT\ code handler: \defineXMLprocessor [context] \contextXMLcommand \defineXMLprocessor [context-command] \contextXMLcommand % we need to get rid of the endlinechar inserted by \scantokens % % \def\saveendlinechar% % {\ifx\restoreendlinechar\undefined % \edef\restoreendlinechar{\endlinechar\the\endlinechar\space}% % \fi % \endlinechar=-1 } % % \def\scanXMLtokens#1% % {\saveendlinechar\scantokens{#1}\restoreendlinechar} %D For security reasons, we provide a switch to turn this %D mechanism on and off. When turned off, there is no way to %D turn it on from within an \XML\ encoded document, simply %D because the possibility to process \CONTEXT\ commands is %D gone. \setupXMLprocessing[\c!command=\v!yes] %\def\contextXMLcommand#1% % {\doif\@@xpcommando\v!ja % {\pushmacro\disableXML % \def\disableXML{\global\let\afterXMLprocessor\empty}% % \global\let\afterXMLprocessor\enableXML % \setnormalcatcodes\scantokens{#1}\afterXMLprocessor % \popmacro\disableXML}} \def\contextXMLcommand#1% we don't use #1 here {\doif\@@xpcommand\v!yes {\disableXML\scantokens\@EA{\currentXMLprocess}\enableXML}} %D The indirect method (using the macro \type %D {\currentXMLprocess} instead of \type {#}) is needed %D because of the \type {\scantokens}. Given the previous %D definition, and given that \ETEX\ is used, we can now %D say: %D %D \starttyping %D %D \stoptyping %D %D A non||\ETEX\ solution is also possible, using buffers, %D but for the moment we assume that \ETEX\ is used. %D Next we implement a general purpose directive. This one %D can be used to set variables that can be accessed with %D \type {\XMLvar}. \defineXMLprocessor [context-directive] \contextXMLdirective \def\contextXMLdirective#1% {\docontextXMLdirective#1 @ @ @\end} \def\docontextXMLdirective#1 #2 #3 #4\end % class variable value {\expandafter\def\csname\@@XMLvariable:#1:#2\endcsname{#3}} %D A simple processing instruction is the following. It just %D writes a message to the screen. \defineXMLprocessor [context-message] {\writestatus{xml-message}} %D The following processing instruction permits you to tag %D parts of the file in such a way that you can filter data. %D We use this method when documenting schemas. \defineXMLprocessor [context-block] \handleXMLcontextblock \def\handleXMLcontextblock#1% {\dohandleXMLcontextblock#1 \relax} \def\dohandleXMLcontextblock#1 #2 #3\relax {\dodohandleXMLcontextblock{#1}{#2}} \let\dodohandleXMLcontextblock\gobbletwoarguments \def\hideXMLcontextblock[#1]% {\def\dodohandleXMLcontextblock {\dododohandleXMLcontextblock\doifinset{#1}}} \def\videXMLcontextblock[#1]% {\def\dodohandleXMLcontextblock {\dododohandleXMLcontextblock\doifnotinset{#1}}} \protect \def\dododohandleXMLcontextblock#1#2#3#4% {\let\next\relax \doifelse{#3}{begin} {#1{#4}{#2} {%\writestatus{xml-block}{skipping begin #4}% \long\def\next##1?context-block end #4 ##2?>{}}} {\doif{#3}{name} {#1{#4}{#2} {%\writestatus{xml-block}{skipping name #4}% \long\def\next##1?context-block ##2?>{}}}}% \next} \unprotect %D Say that a file contains blocks like the following: %D %D \starttyping %D %D %D maybe so much %D %D %D \stoptyping %D %D The following commands will show only this block: %D %D \starttyping %D \videXMLcontextblock[whatevername] \showXMLfile{yourfile} %D \stoptyping %D %D You can also mark blocks in the following way, thereby %D saving yourself some work: %D %D \starttyping %D %D %D What do you want? %D %D %D %D How do you want? %D %D %D \stoptyping % yet undocumented and experimental % \defineXMLprocessor [context-eof] {\endinput} % already defined in xtag-ini % \defineXMLsingular [begingroup] {\begingroup} % \defineXMLsingular [endgroup] {\endgroup} % % \defineXMLsingular [gobblespacetokens] {\gobblespacetokens} %D We automatically switch regimes (beware of nested files!): %D %D \starttyping %D \startXMLdata %D %D ÀÁÂÃÄÅàáâãäåÆÇæç %D ÈÉÊËèéêëÌÍÎÏÞìíîïþ %D ÐðÑñÒÓÔÕÖòóôõöØø %D ÙÚÛÜùúûÝýÿß %D \stopXMLdata %D \stoptyping \defineXMLprocessor [xml] {\handleXMLbanner} \def\handleXMLbanner#1% {\getXMLarguments{xml}{\s!encoding='' #1}% \doifsomething{\XMLpar{xml}\s!encoding\empty} {\doif\currentregime\s!default % style regimes will take precedence {\enableregime[\XMLpar{xml}\s!encoding\empty]}\donothing}} \protect \endinput