§ compatibility between xelatex/lualatex+{fontspec} and pdflatex+[utf8]{inputenc}

I'm having trouble with some macros and the § symbol. I can get things working with xelatex/lualatex, but not with pdflatex.

Here's my code:

\documentclass{article}

\usepackage{fontspec} % <- xelatex/lualatex works
%\usepackage[utf8]{inputenc} % <- pdflatex fails
\usepackage{etoolbox}

\makeatletter
\def\instring#1#2{TT\fi\begingroup
\edef\x{\endgroup\noexpand\in@{#1}{#2}}\x\ifin@}
\makeatletter

\begin{document}

\def\A{§ 2|1:3}

Spilt \A{}'' at |'':
\DeclareListParser{\dopipedlist}{|}
\edef\B{{\A}}
\renewcommand*{\do}[1]{\item #1}
\begin{itemize}
\expandafter\dopipedlist\B
\end{itemize}

Searching for §:
\if\instring{§}{\A}
Found.
\else
\fi

\end{document}


Ideally, I want to be able to define \A with § or \textsection or \S and have it work regardless of which flavour of *latex is used. (I know § won't work without fontspec/inputenc.)

I've had some success with \textsection by using \noexpand\textsection and moving to the more robust InSubStr from the xstring package, but this is not as neat as I want. \A is user provided and it seems unreasonable for an end user to have to decipher TeX's error message and know they need to add \noexpand.

Is there any solution that “just works”? It doesn't matter if the back end code is messy. I'm more concerned that \A is simple.

Finally, \A could potentially contain anything, though the only strange character I want to check for with instring is §.

• \edef\B{{\A}} is your problem \edef should never be used on general text strings, in pdftex § is multiple characters set up to parse and decode utf8 encoding and then multiple font specific code to typeset a § none of that will do the right thing inside \edef (also the \edef\x) – David Carlisle Jan 20 '16 at 11:23

Just to give the flavor, I define \itemizelist so that it splits the given input at | (or another character chosen at runtime) and adds \item in front of the various pieces. If the piece contains §, it is printed red.

\documentclass{article}

\usepackage{xparse,ifxetex}
\usepackage{xcolor}

\ifxetex
\usepackage{fontspec} % <- xelatex/lualatex works
\else
\usepackage[utf8]{inputenc} % <- pdflatex too
\fi
\usepackage{etoolbox}

\ExplSyntaxOn
\NewDocumentCommand{\itemizelist}{sO{|}m}
{
\IfBooleanTF { #1 }
{
\purton_itemizelist:no { #2 } { #3 }
}
{
\purton_itemizelist:nn { #2 } { #3 }
}
}

\cs_new_protected:Nn \purton_itemizelist:nn
{
\seq_set_split:Nnn \l_tmpa_seq { #1 } { #2 }
\seq_map_inline:Nn \l_tmpa_seq
{
\tl_if_in:nnTF { ##1 } { § }
{
\item \textcolor{red}{##1}
}
{
\item ##1
}
}
}
\cs_generate_variant:Nn \purton_itemizelist:nn { no }
\ExplSyntaxOff

\begin{document}

\def\A{§ 2|1:3}

\begin{itemize}
\itemizelist*{\A}
\itemizelist[;]{2:x;§ 3}
\end{itemize}

\end{document}


The macros are “engine agnostic”, so the result is the same for all of them.

• Thanks! I always forget about xparse! That gave me enough clues to do what I wanted. I see the magic is in generating the variant function with the argument that expands one level (\cs_generate_variant:Nn \purton_itemizelist:nn { no }). In my playing around, I couldn't directly define the function in this way. Why is this? – David Purton Jan 22 '16 at 3:01
• @DavidPurton It's by design; you can only define functions with arguments N or n (this can also be T or F, in relevant cases). Then you can apply the magic of \cs_generate_variant:Nn. – egreg Jan 22 '16 at 9:18