3

This is a follow-up to Abbreviate resolved abbreviations in authors' first names in biblatex, where @PLK provided an answer in which brackets [] and characters between them are replaced by a dot .

One problem here is that I have entries in my .bib file that are anonymous publications, yet we know who the author is. In those cases I fill in the entire name within brackets, as in [John Lennon] below. In such cases where the entire name is between brackets, no replacement with a dot . should take place.

Question: Is there a way to replace brackets with intervening characters with a dot except when the entire author field contains such a sequence (e.g. author = J[ohn] Lennon is replaced by author = J. Lennon, but author = [John Lennon] remains author = [John Lennon]?

Or put differently, can I somehow "protect" the entry author = [John Lennon] below from being targeted by the DeclareSourcemap command?

\documentclass{article}
\usepackage[style = authoryear-comp]{biblatex}
\DeclareSourcemap{\maps[datatype = bibtex]{\map{\step[fieldsource = author, match = \regexp{\[[^]]+\]}, replace = .]}}}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@BOOK{lennon1970,
    AUTHOR = "J[ohn] Lennon",
    TITLE = "My life with the Beatles",
    YEAR = "1970",
    SORTNAME = "John Lennon"}
@BOOK{lennon1971,
    AUTHOR = "[John Lennon]",
    TITLE = "Moving on",
    YEAR = "1971",
    SORTNAME = "John Lennon"}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\nocite{*}
\printbibliography
\end{document}

enter image description here

The question Brackets in biblatex entries might also be relevant here.

Sverre
  • 20,729
  • biber gives errors for me (and doesn't generate output) on your original but .\[[^]]+\] wouldn't match a field that only had [ at the start. – David Carlisle Nov 17 '14 at 19:38
  • What about using author = "{John} {Lennon}"? – Werner Nov 17 '14 at 19:51
  • @DavidCarlisle The MWE compiles fine with pdflatex + biber in texlive 2014. Also, using \regexp{.\[[^]]+\]} will reduce the former output Lennon, J. to Lennon, .. – Sverre Nov 17 '14 at 20:52
  • @Werner Isn't that equivalent to just writing author = "John Lennon"? It won't, in other words, indicate in the output that I have supplied the name myself. The output should read [Lennon, John], not Lennon, John. – Sverre Nov 17 '14 at 20:54
  • @Sverre: Bracing protects, hence the suggestion. What about author = {[Lennon, John]}? – Werner Nov 17 '14 at 21:09
  • @Werner That would be equivalent to author = "[Lennon, John]". I've also tried "{[Lennon, John]}". They are all replaced by a dot as in the MWE. – Sverre Nov 17 '14 at 21:43

1 Answers1

4

You can anchor regexp searches to the beginning of a string by \A and to the end by \Z, see http://perldoc.perl.org/perlre.html#Regular-Expressions . If your input was encoded as

author = {[Lennon, John]}

then you simply add a first test

\step[fieldsource = author, notmatch = \regexp{\A\[.+\]\Z}, final]

to skip fields entirely contained brackets. This also works with

author = {[John Lennon]}

but biber/biblatex then treats Lennon] as the surname and [John as the first name and prints

Lennon], [John

in the bibliography, which is not what you want. So one needs to process these entries once more splitting on the final space before the surname.

\documentclass{article}

\usepackage[style = authoryear-comp]{biblatex}

\DeclareSourcemap{\maps[datatype = bibtex]{
\map{
  \step[fieldsource = author, notmatch = \regexp{\A\[.+\]\Z}, final]
  \step[fieldsource = author, match = \regexp{\[[^]]+\]}, replace = .]
}
\map{
 \step[fieldsource = author, match = \regexp{\A\[(.+)\s+([^\s]+)\]\Z},
 replace = {[$2, $1]}]}
}}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@BOOK{lennon1970,
    AUTHOR = "J[ohn] Lennon",
    TITLE = "My life with the Beatles",
    YEAR = "1970",
    SORTNAME = "John Lennon"}
@BOOK{lennon1971,
    AUTHOR = "[John Lennon]",
    TITLE = "Moving on",
    YEAR = "1971",
    SORTNAME = "John Lennon"}
@BOOK{lennon1972,
    AUTHOR = "[J. John Lennon]",
    TITLE = "Moving further on",
    YEAR = "1972",
    SORTNAME = "John Lennon"}
@BOOK{aasen1990,
    AUTHOR = "[{\AA}ge {\AA}sen]",
    TITLE = "Mitt liv",
    YEAR = "1990",
    SORTNAME = "{\AA}ge {\AA}sen"}
@BOOK{estevez1990,
    AUTHOR = "[{\'E}milio {\'E}stevez]",
    TITLE = "Hola",
    YEAR = "1990",
    SORTNAME = "{\'E}milio {\'E}stevez"}
@BOOK{aasen1991,
    AUTHOR = "{\AA}[ge] {\AA}sen",
    TITLE = "Mitt liv 2",
    YEAR = "1991",
    SORTNAME = "{\AA}ge {\AA}sen"}
@BOOK{estevez1991,
    AUTHOR = "{\'E}[milio] {\'E}stevez",
    TITLE = "Hola 2",
    YEAR = "1991",
    SORTNAME = "{\'E}milio {\'E}stevez"}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}

\nocite{*}
\printbibliography

\end{document}

enter image description here

Sverre
  • 20,729
Andrew Swann
  • 95,762
  • I've edited your code to show that it works when names begin with LaTeX macros like {\AA} and {\'E} as well (which I suspected it wouldn't, given the regexp \A and \Z). – Sverre Nov 18 '14 at 12:39