plk/biber

Using `\DeclareSourcemap` to match text containing `\&`

Closed this issue · 8 comments

I am declaring a sourcemap essentially as follows.

\DeclareSourcemap{
	\maps[datatype = bibtex]{
		\map[overwrite, foreach = {journal, journaltitle}]{
			\step[fieldsource = \regexp{$MAPLOOP}, matchi = {^foo$}, final]
			\step[fieldset = \regexp{$MAPLOOP}, fieldvalue = {{bar}}]
		}
	}
}

My question is: how can I match text containing literal \&? (Where foo is, in the above.) I have tried escaping it in various different ways, including \\? and \\\?, but they all lead to biber errors, as follows.

INFO - Logfile is 'build/foo.blg'
ERROR - build/foo.bcf is malformed, last biblatex run probably failed. Deleted build/foo.bbl
INFO - ERRORS: 1
Biber error: [193] Utils.pm:411> ERROR - build/foo.bcf is malformed, last biblatex run probably failed. Deleted build/foo.bbl

@plk I just realised I probably should have posted this in the biblatex repo, sorry. Hopefully it's okay here anyway, since it's just a question.

@plk Sorry to bother you... any thoughts?

plk commented

Have you tried:

matchi = \regexp{^foo$}

@plk Yep, that works fine. The problem is trying to match a literal \&.

plk commented

Can you paste in a full MWE showing the issue so I can reproduce?

\begin{filecontents*}[overwrite]{\jobname.bib}
@article{author00,
    title = {{A Title}},
    year = {2008},
    journal = {Foo \& Bar},
    author = {Author, A},
}
@article{buthor00,
    title = {{B Title}},
    year = {1990},
    journal = {Foo \& Bar},
    author = {Buthor, B},
}
\end{filecontents*}

\documentclass{article}

\usepackage[backend = biber]{biblatex}

\addbibresource{\jobname.bib}

\DeclareSourcemap{
    \maps[datatype = bibtex]{
        \map[overwrite]{
            \step[fieldsource = {journal}, matchi = {^Foo \& Bar$}, final]
            \step[fieldset = {journal}, fieldvalue = {{{Bar \& Foo}}}]
        }
    }
}

\begin{document}

    \citeauthor{author00} has written \textcite{author00}.
    \citeauthor{buthor00} has written \textcite{buthor00}.

    \nocite{*}
    \printbibliography

\end{document}

I've tried lots of variations on the value of matchi, all to no avail.

plk commented

Can you try this?

\DeclareSourcemap{
    \maps[datatype = bibtex]{
        \map[overwrite]{
            \step[fieldsource = {journal}, matchi = \regexp{^Foo\s\\\x26\sBar$}, final]
            \step[fieldset = {journal}, fieldvalue = {Bar \& Foo}]
        }
    }
}

Generally, just use an octal or hex escape in regexps to avoid special char issues.

@plk Thanks, that works! Including \regexp too was important. Obviously this syntax is not pretty, but since I am auto-generating this file, it is no problem.