I want to write an XML-like key-value-parser for LaTeX. That is, kv-pairs are separated by spaces, and values are separated from keys by = and encapsulated by double qoutes. The following minimal example does that:
\documentclass[english]{book}
\usepackage{babel}
\makeatletter
\def\tp@parse@attributes#1\@nil{%
\if!#1!\else\@tp@parse@attributes#1 ="" =""\@nil\fi}
\def\@tp@parse@attributes#1="#2" #3=""\@nil{%
\edef\@argi{#1}\edef\@argiii{#3}%
\ifx\@argi\@empty\else%
\ifx\@argi\space\else%
\expandafter\def\csname tp@attr@#1\endcsname{#2}%
\ifx\@argiii\@empty\else
\ifx\@argiii\space\else
\def\@tempa{="" }%
\ifx\@argiii\@tempa\else%
\expandafter\@tp@parse@attributes #3=""\@nil%
\fi\fi\fi\fi\fi}%
\def\test{\@ifnextchar [\@test{\@test[class="default"]}}%]
\def\@test[#1]#2{%
\tp@parse@attributes#1\@nil
Class: {\ttfamily\tp@attr@class}\space
Content: {\sffamily #2}\par
\let\tp@attr@class\relax}% reset class for next instance
\parindent\z@
\makeatother
\begin{document}
1st test: \test{Content}
2nd test: \test[class="foobar"]{Content}
\end{document}
This works as long as the document language is english.
For german texts, the same code throws an error ! Argument of \language@active@arg" has an extra }.
I figured that babel shorthands are to blame, so I played around with the catcodes and came up with the following code (…
means that the code is the same as in the MWE above):
\documentclass[german]{book}
\usepackage{babel}
\makeatletter
\begingroup
\catcode`\"=\active
\gdef\tp@parse@attributes#1\@nil{…}
\gdef\@tp@parse@attributes#1="#2" #3=""\@nil{…}%
\gdef\test{…}%
\gdef\@test[#1]#2{…}
\endgroup
\parindent\z@
\makeatother
\begin{document}
…
\end{document}
Unfortunately, this option does not work, when the (only) language is english (! Undefined control sequence.^^J<argument> ="
). However, it does work when both languages are loaded (\documentclass[english,german]{book}
)
If the language turkish is added (or single language), none of those options work.
I also attempted to locally switch off babel shorthands using \shorthandoff{"=}
, but since I do not know what languages are actually loaded, I cannot anticipate which characters are active shorthands and which are not.
My question is: How must I alter my code so it works with all languages, and without globally deactivating babel shorthands?
class="default" color="red"
and sometimesclass=default, color=red
."
is not the only character that is altered by babel for turkish, otherwise the german fix should work (right?). Besides, i don't want to risk destroying any other packages by globally altering catcodes like that.,
as separators and i fear that such values may interfer with the parser of some KV-packages. Besides, the answer would help me greatly to understand how catcodes work and what can be done to cope with catcode conflicts like that. ("Es geht um's Prinzip")