0

I would like to know whether it is possible with biblatex and pdflatex to automatically select the in-text look of the \cite command, with the author-year style. For instance, I would like citations following in, that is in~\cite{label}... to come with brackets while I would like other citations not to be bracketed. The rule would then be something like: if \cite{label} follows in then use \parencite else use \cite. I could certainly achieve this by hand, but I would like not to.

\documentclass{article}
\usepackage{filecontents}
\usepackage[backend=bibtex,style=authoryear]{biblatex}
\addbibresource{database.bib}

\begin{filecontents*}{database.bib}
@article{art:article1,
title = {Title 1},
author = {Author1},
year={2018},
journal = {journal 1},
}
@article{art:article2,
title = {Title 2},
author = {Author2},
year={2018},
journal = {journal 2},
}
\end{filecontents*}

\begin{document}
As stated by~\cite{art:article1}, sky is blue. However, in~\cite{art:article2}, the author thinks that. By the way, the previous citation should look like (\cite{art:article2}).
\printbibliography

\end{document}
  • 2
    Please -- as usual here -- add a short compilable tex code building your bibliography and do not forget to add two bib entrys to your question ... – Kurt Nov 20 '18 at 15:09
  • 2
    In general \cite commands (and even more generally all LaTeX macros) don't really know the text around them. It is possible to let them see the text that comes after them to some extent (\cite can for example deal with following punctuation), but the usual methods won't work for entire words or phrases. A macro has absolutely no way of knowing what text came before it (again, with spacefactors a limited detection of punctuation might be possible, but not something like detecting an "in"). So you would have to resort to solutions that work from outside \cite. ... – moewe Nov 20 '18 at 15:30
  • 1
    With LuaLaTeX it would certainly be possible to perform RegExp replacement on the text and turn every \cite except those in in~\cite into \parencite. It might also be possible to cook something up with expl3, but you would somehow have to process the entire document body with the RegExp, not sure if and how that is supported (it sounds as though that could cause all kinds of issues, but LaTeX3 can do a lot of things). I would say: Don't bother and just use the correct macros in the first place, but you might think this endeavour is worth while. – moewe Nov 20 '18 at 15:34
  • @moewe yes, the RegExp replacement can be done easily directly on the tex file in most text editor. However, I thought it could be a good exercise to perform this directly during a (whatever)tex compilation. – pluton Nov 20 '18 at 15:38
1

As I wrote in the comments, LaTeX macros usually don't know a lot about the text that surrounds them. With a few sly tricks it is possible to catch a glimpse of what comes after the macro (the naive solution of absorbing another argument at least gives us the next token), but the usual tricks won't work for entire words or phrases. It is even harder to find out what happened before the macro. There are limited methods to find out about punctuation before a macro, but usually not for more.

So your best bet is an approach from outside the \cite macro, essentially something like a full search and replace job on the document text.

Naturally you can do that in your favourite editor. The advantage there is that you can double check each occurrence manually and assess the usefulness of a replacement.

If you insist on a solution that leaves your actual .tex input unchanged and only happens upon the TeX run I guess your best bets are LuaTeX and expl3. expl3's RegExp is really impressive, but I'm not sure whether it was intended to essentially canvass the entire document body.

A LuaLaTeX solution could look like this answer by Mico's answer to Macro: Replace all occurrences of a word. I was trying to be careful and execute the filter only at the beginning of the document to avoid replacing anything in packages.

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage{luacode}
\begin{luacode}
function replace_cite (line)
  return string.gsub(line, "%f[%l_]in~\\cite" , "in~\\parencite") 
end
\end{luacode}

\usepackage[style=authoryear, backend=biber]{biblatex}

\addbibresource{biblatex-examples.bib}

\AtBeginDocument{%
  \luadirect{
    luatexbase.add_to_callback( "process_input_buffer",  replace_cite, "replace_cite")}}

\begin{document}
Lorem~\cite{sigfridsson}
this is replaced: in~\cite{sigfridsson}
but not: bin~\cite{sigfridsson}

in~\cite{sigfridsson}

\printbibliography
\end{document}

Lorem Sigfridsson and Ryde 1998 this is replaced: in (Sigfridsson and Ryde 1998) but not: bin Sigfridsson and Ryde 1998//in (Sigfridsson and Ryde 1998)

I personally am not too fond of this kind of automation. It should be a conscious decision by the document author what kind of general citation format she wants (with brackets, without brackets, with different brackets) if there are several possible alternatives. Especially if the choice is context dependent, depends on the structure of the surrounding text or carries a certain connotation a human should make the decisions. But maybe I'm just trying to rationalise a shortcoming of LaTeX's macro system.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.