使用 LuaTeX 自动化 biblatex-apa 中的 \textcite 与 \nptextcite

使用 LuaTeX 自动化 biblatex-apa 中的 \textcite 与 \nptextcite

根据biblatex-apa文档(第 4.1 节)APA 规定括号内的引用不应包含额外的括号。因此,它提供了命令

\nptextcite[⟨prenote⟩][⟨postnote⟩]{⟨key⟩}⟨punctuation⟩

其工作原理类似\textcite,但取消了括号。

\textcite这一切都很好,除非你正在将你的文档从其他文档(例如 markdown)转换而来,在这种情况下你无法做出类似于和之间的区别\nptextcite。所以我想知道是否有办法自动化这个使用 LuaTeX? 我们能否定义一个命令,根据当前括号级别\autotextcite扩展为\textcite和?\nptextcite

为了在实践中可用,它最好按以下方式工作:

  • 它应该记住整个段落的括号级别,而不仅仅是单独的行,因此使用process_input_buffer回调逐行进行简单的正则表达式字符串替换是行不通的。
  • 应该为每个新段落重置括号级别,以便忘记)文本中的某个地方不会弄乱文档的其余部分。
  • 出于显而易见的原因,最好不要让字符()处于活动状态(这会破坏许多其他接口)。同样,用类似和的字符串分别替换(和也可能导致错误。)(\directlua{parlevel=parlevel+1}\directlua{parlevel=parlevel-1})

所以我希望的是这样的:

\begin{filecontents*}{ref.bib}

@online{tex.sx,
    author={{egreg et al.}},
    year={2022},
    title={{TeX Stack Exchange}},
    url={https://tex.stackexchange.com/},
}

\end{filecontents*}

\documentclass{article}

\usepackage[american]{babel}
\usepackage{csquotes}
\usepackage[style=apa]{biblatex}

\addbibresource{ref.bib}

\newcommand\autotextcite{%
    \ifinsideparentheses
        \nptextcite
    \else
        \textcite
    \fi
}


\begin{document}

This follows from \autotextcite[front page]{tex.sx}. % Should yield \textcite

(It also follows from \autotextcite[front page]{tex.sx}.) % Should yield \nptextcite

(It also follows from
\autotextcite[front page]{tex.sx} % Should yield \nptextcite
among other places.)

(It also follows from other resources. % Here we forget a ")"

But \autotextcite[front page]{tex.sx} is a good start. %Should yield \textcite

\printbibliography

\end{document}

答案1

您可以使用 Lua 查看当前正在构建的列表。在段落中,这通常是当前段落,而在\hbox(或\mbox或类似)中,这只会查看当前 hbox。通常这应该会导致预期的结果:

\begin{filecontents*}{find_parens.lua}
-- From Marcel Krüger's answer at https://tex.stackexchange.com/a/654261/80496

-- How to translate boolean results to TeX macros selecting the right arguments
local bool_to_token = {[false] = token.create'use_ii:nn', [true] = token.create'use_i:nn'}

-- The codepoints we have to look for
local left_paren = string.byte'('
local right_paren = string.byte')'

-- Some boilerplate to define an unexpandable command sequence from Lua
local id = luatexbase.new_luafunction'ifInParensTF'
token.set_lua('ifInParensTF', id, 'protected')
lua.get_functions_table()[id] = function()

  -- We want to look at the current list
  local head = tex.nest.top.head

  local level = 0
  -- and look at all unprocessed characters
  for _, char in node.traverse_char(head) do
    -- Track the nesting level
    if char == left_paren then
      level = level + 1
    elseif char == right_paren then
      if level > 0 then
        level = level - 1
      else
        -- Negative levels don't make sense, so we ignore the ) instead. Print a warning though to avoid surprises.
        luatexbase.module_warning('find_parens', '\z
          Unable to reliably determine if inside parentheses\n\z
          since the paragraphs contains an unmatched `)`.\n\z
          It will be ignored\z
        ')
      end
    end
  end
  -- Finally insert a macro which will select the first or second argument dependingon whether level > 0
  token.put_next(bool_to_token[level > 0])
end
\end{filecontents*}
\begin{filecontents*}{ref.bib}

@online{tex.sx,
    author={{egreg et al.}},
    year={2022},
    title={{TeX Stack Exchange}},
    url={https://tex.stackexchange.com/},
}

\end{filecontents*}

\documentclass{article}

\usepackage[american]{babel}
\usepackage{csquotes}
\usepackage[style=apa]{biblatex}

\directlua{require'find_parens'}

\addbibresource{ref.bib}

\NewDocumentCommand \autotextcite {}{%
  \ifInParensTF {%
    \nptextcite
  }{%
    \textcite
  }%
}


\begin{document}

This follows from \autotextcite[front page]{tex.sx}. % Should yield \textcite

(It also follows from \autotextcite[front page]{tex.sx}.) % Should yield \nptextcite

(It also follows from
\autotextcite[front page]{tex.sx} % Should yield \nptextcite
among other places.)

(It also follows from other resources. % Here we forget a ")"

But \autotextcite[front page]{tex.sx} is a good start. %Should yield \textcite

\printbibliography

\end{document}

在此处输入图片描述

相关内容