% A set of macros to generate XML in Latex
% Peter McBrien
% 6th January 2001
%
\ProvidesPackage{xml}

\usepackage{ifthen}
\usepackage{colours}
\usepackage{stdpjmmacros}

%\usepackage{colours}
\definecolor{xmlcomment}{named}{RawSienna}
\definecolor{xmlcdata}{named}{Bittersweet}
\definecolor{xmlprocess}{named}{CadetBlue}
\definecolor{xmlentity}{named}{Violet}
\definecolor{xmlelement}{named}{Blue}
\definecolor{xmlattribute}{named}{Red}
\definecolor{xmltext}{named}{Black}

\newcount\xmlc
\xmlc=0

\def\xmltabstop{\ifthenelse{\boolean{xmlshowwhitespace}}{\chsp\chsp}{\mbox{\hspace{1em}}}}
\def\xmlnl{\ifthenelse{\boolean{xmlshowwhitespace}}{\chnl}{}\\}

% Don't know why I need to do this!
\def\xmltab#1{\stdx=#1\advance\stdx -1\xmltabr{\stdx}}
\def\xmltabr#1{%V=\arabic{xmlindent}%
\ifnum#1=0\else{}\xmltabstop%
\stdx=#1%
\advance\stdx -1%
\xmltabr{\stdx}\fi}

\def\xmlmacro#1#2#3{{\sf$\langle$#1 #2$\rangle$\xmlnl
\advance \xmlc 1
\xmltab{\xmlc}#3\xmlnl
$\langle$#1$\rangle$}}

\newcounter{xmlline}
\setcounter{xmlline}{1}
\newcounter{xmlindent}
\setcounter{xmlindent}{-1}
\newcounter{xmloid}
\setcounter{xmloid}{0}
\newboolean{xmllinenumbering}
\setboolean{xmllinenumbering}{false}
\newboolean{xmlshowwhitespace}
\setboolean{xmlshowwhitespace}{false}
\newboolean{xmldonefirstline}
\setboolean{xmldonefirstline}{false}
\newboolean{xmlautoformat}
\setboolean{xmlautoformat}{false}
\newboolean{xmlelementoids}
\setboolean{xmlelementoids}{false}

\def\xmlarabic#1{%\ifthenelse{\value{xmlline}<100}{0}{}%
\ifthenelse{\value{#1}<10}{0}{}%
\arabic{#1}}

\def\xmllineno#1{\texttt{#1}}

\def\xmlreportline{\ifthenelse{\boolean{xmldonefirstline}}{\ifthenelse{\boolean{xmlshowwhitespace}}{\chnl}{}}{}%
\setboolean{xmldonefirstline}{true}%
\ifthenelse{\boolean{xmllinenumbering}}%
{\item[\texttt{\xmlarabic{xmlline}}]\stepcounter{xmlline}}%
{\item[]}}

\def\xmleol{\xmlnl
\xmlreportline}

\def\xmloid#1{\colorbox{PCAone}{\begin{sf}\&#1\end{sf}}}
\def\xmlnextoid{\ifthenelse{\boolean{xmlelementoids}}{\xmloid{\arabic{xmloid}}
\addtocounter{xmloid}{1}}{}}

\def\xmlprocess#1#2{\xmlautoformat\textcolor{xmlprocess}{\xmlfont{$\langle$?\textcolor{xmlprocess}{#1} #2?$\rangle$}}}
\def\xmlcomment#1{\xmlautoformat\xmlopencomment\xmlfont{\textcolor{xmlcomment}{#1}}\xmlclosecomment}
\def\xmlopencomment{\textcolor{xmlcomment}{\xmlfont{$\langle$!-{}-}}}
\def\xmlclosecomment{\textcolor{xmlcomment}{\xmlfont{-{}-$\rangle$}}}
\def\xmlcdata#1{\xmlopencdata\xmlfont{#1}\xmlclosecdata}
\def\xmlmixedmodetext#1{\xmlautoformat\xmlfont{#1}}
\def\xmlopencdata{\textcolor{xmlcdata}{\xmlfont{$\langle$![CDATA[}}}
\def\xmlclosecdata{\textcolor{xmlcdata}{\xmlfont{]]$\rangle$}}}
\def\xmltagname#1{\textcolor{xmlelement}{#1}}
%\def\xmlelement#1{\textcolor{xmlelement}{\xmlfont{#1}}}
\def\xmlentity#1{\textcolor{xmlentity}{\xmlfont{\&#1;}}}
\def\xmlfont#1{\textsf{#1}}
\def\xmlopentag#1#2{\mbox{\xmlfont{$\langle$\xmltagname{#1}#2$\rangle$}}}
\def\xmlopenclosetag#1#2{\xmlautoformat{\xmlfont{$\langle$\xmltagname{#1}#2/$\rangle$}}}
\def\xmlheader#1{\xmlautoformat \mbox{\xmlfont{$\langle$? \xmltagname{xml}#1$?\rangle$}}}
\def\xmldoctype#1{\xmlautoformat \mbox{\xmlfont{$\langle$!DOCTYPE #1$\rangle$}}}
\def\xmltag#1{\mbox{\sf$\langle$\xmltagname{#1}$\rangle$}}
\def\xmlclosetag#1{\mbox{\sf$\langle$/\xmltagname{#1}$\rangle$}}
\def\xmlblock#1#2#3{\xmlautoformat\xmlopentag{#1}{#2}\xmlfont{#3}\xmlclosetag{#1}\ifthenelse{\boolean{xmlelementoids}}{~\xmloid{\arabic{xmloid}}
\addtocounter{xmloid}{1}}{}}
\def\xmlid#1{\mbox{\xmlfont{#1}}}
% define how to present elements, attributes and text value strings
\def\xmle#1{\textcolor{xmlelement}{\mbox{\xmlfont{#1}}}}
\def\xmla#1{\textcolor{xmlattribute}{\mbox{\xmlfont{#1}}}}
\def\xmlt#1{\textcolor{xmltext}{\mbox{\xmlfont{#1}}}}
% an `XML pattern' i.e. BNF style <type>
\def\xmlp#1{\textcolor{Purple}{\mbox{\xmlfont{\tuple{#1}}}}}
% an attribute and text value pair, or attribute and pattern pair
\def\xmlav#1#2{ \xmla{#1}=\xmlt{``#2''}}
%\def\xmlav#1#2{ \xmla{#1}=\xmlp{#2}}
% constraints and types in DTD
\def\dtdc#1{\textcolor{black}{\mbox{\xmlfont{#1}}}}
\def\dtdt#1{\textcolor{black}{\mbox{\xmlfont{#1}}}}
\def\dtdelement#1#2{\mbox{\sf$\langle$!ELEMENT \xmle{#1} }$\mathsf{#2}\rangle$}
\def\dtdattribute#1#2#3#4{\mbox{\sf$\langle$!ATTLIST \xmle{#1} \xmla{#2} \dtdt{#3} \dtdc{#4}$\rangle$}}

%\newenvironment{xml}[2]{\raggedright
%\parindent=0em
%\def\xmldef{#1}
%\xmlopentag{#1}{#2}\parskip=0em\\\xmlreportline
%\begin{list}{}{\partopsep=0em \parsep=0em \topsep=0pt
%\leftmargin=1em \rightmargin=0pt}\def\labelitemi{}\item[]}{\end{list}
%\xmlclosetag{\xmldef}}

\newenvironment{xmlelement}[2]{\raggedright%
\def\xmldef{#1}%
\xmlautoformat%
\xmlopentag{#1}{#2}%
\ifthenelse{\boolean{xmlelementoids}}{~\xmloid{\arabic{xmloid}}
\addtocounter{xmloid}{1}}{}
\addtocounter{xmlindent}{1}}{\addtocounter{xmlindent}{-1}%
\xmlautoformat\xmlclosetag{\xmldef}}

\newenvironment{xml}{\raggedright%
\addtocounter{xmlindent}{1}%
\ifthenelse{\value{xmlindent}=0}{\begin{list}{}{%
\setboolean{xmlautoformat}{true}%
\setboolean{xmldonefirstline}{false}%
\ifthenelse{\boolean{xmllinenumbering}}%
{\leftmargin=1em}{\leftmargin=0em}\topsep=0em\partopsep=0em\parsep=0em\parskip=0em\itemsep=0em\itemindent=0em}}{}}%
{\ifthenelse{\value{xmlindent}=0}{\setboolean{xmlautoformat}{false}%
\end{list}}{}%
\addtocounter{xmlindent}{-1}}

\def\xmlautoformat{\ifthenelse{\boolean{xmlautoformat}}{\xmlreportline\xmltab{\value{xmlindent}}}{}}
%\def\xmlindent#1{\ifthenelse{\value{xmlindent}>-1}{\addtocounter{xmlindent}{#1}}{}}


\def\xmllb{\xmlnl\xmltabstop}

\newcounter{xtnodeid}
\setcounter{xtnodeid}{1}
\newboolean{xtnodenumbering}
\setboolean{xtnodenumbering}{false}

\def\xtnid#1{\&#1}

\def\xtnodenumber(#1,#2){\ifthenelse{\boolean{xtnodenumbering}}%
{\put(#1,#2){\makebox(0,0){\&\arabic{xtnodeid}}}%
\stepcounter{xtnodeid}}{}}

\def\xtattribute(#1,#2)#3#4{\horizontaldogleg(0,0)(#1,#2)
\put(#1,#2){\begin{picture}(0,0)
\putcolourcircle(0,0){xmlattribute}{1}{}
\xtnodenumber(0,1.5)
\end{picture}}
\stdx=#1
\advance \stdx 1
\put(\stdx,#2){\makebox(0,0)[l]{\tiny\xmlav{#3}{\shortstack[l]{#4}}\xmlnextoid}}}

\def\xtverticaldogleg(#1,#2)(#3,#4){\stdz=#2%
\advance\stdz 1%
\stdv=#4%
\advance\stdv -1%
\verticaldogleg(#1,\stdz)(#3,\stdv)}

\def\xtelement(#1,#2)(#3,#4)#5#6{
\xtverticaldogleg(#1,#2)(#3,#4)
\put(#1,#2){\begin{picture}(0,0)
\put(-1.2,0){\makebox(0,0)[r]{\xmlnextoid\textcolor{xmlelement}{\shortstack[r]{#5}}}}
\xtnodenumber(-2,2)%
#6
\putcolourcircle(0,0){xmlelement}{2}{}
\end{picture}}}

\def\xtprocess(#1,#2)(#3,#4)#5#6{
\xtverticaldogleg(#1,#2)(#3,#4)
\put(#1,#2){\begin{picture}(0,0)
\xtnodenumber(2,2)%
{\shade\color{xmlprocess}\path(-1,-1)(0,1)(1,-1)(-1,-1)}
\put(-1.2,0){\makebox(0,0)[r]{\textcolor{xmlprocess}{#5}}}
\put(0,-1){\makebox(0,0)[t]{\textcolor{xmlprocess}{#6}}}
\end{picture}}}

\def\xtcdata(#1,#2)(#3,#4)#5{\xtverticaldogleg(#1,#2)(#3,#4)%
\put(#1,#2){\begin{picture}(0,0)
\xtnodenumber(3,0)%
{\shade\color{xmlcdata}\path(-1,0)(0,1)(1,0)(0,-1)(-1,0)}%
\put(0,-1.2){\makebox(0,0)[t]{\shortstack{#5}}}
\end{picture}}}

\def\xtcomment(#1,#2)(#3,#4)#5{
\xtverticaldogleg(#1,#2)(#3,#4)
\put(#1,#2){\begin{picture}(0,0)
\xtnodenumber(2,2)%
\putcolourbox(-1,-1)(2,2){xmlcomment}{}
\put(0,-1){\makebox(0,0)[t]{\textcolor{xmlcomment}{\shortstack{#5}}}}
\end{picture}}}
