Open leo-liu opened 6 years ago
利用 \AtBeginDocument
延迟设置比较好,简单易行,并可定义设置开关,使用户可以控制显示结果。
使用 \AtBeginDocument
这种方式也可能一些细节问题,比如与现有部分中文 biblatex 模板冲突需要与作者沟通之类。
这个问题和 beamer 当时汉化有点像,ctexbeamer 的作法还是通过 beamer 的接口定义了 translator。
我再想想。目前只是写东西遇到这个问题,暂时没有时间仔细看代码去改。
从实践看,中文文档不需要使用babel或者polyglossia。 因此默认本地化语言是英文,反正中文处理是另一套体系,所以并没有多大影响。
现在的关键问题是biblatex功能过多,导致问题复杂化,如果简单的借用原来bibtex的思路,那么是可以给出一定的设定的。
目前biblatex参考文献标题的修改主要有三种方式:
\defbibheading{bibliography}[\bibname]{%
\chapter*{#1}%
\markboth{#1}{#1}}
一般情况下这个标题会读取一个参数作为标题内容,该参数缺省时就把\bibname作为标题内容这可以从下面代码中看出:
% {<name>}[<default>]{<code>}
\newrobustcmd*{\defbibheading}[1]{%
\@ifnextchar[%]
{\blx@defbibheading{blx@head@#1}}
{\blx@defbibheading{blx@head@#1}[\bibname]}}
\def\blx@defbibheading#1[#2]{%
\csundef{#1}%
\expandafter\newcommand\csname#1\endcsname[1][#2]}
理论上似乎我们重定义\bibname就可以得到需要的标题内容,但实际上biblatex对\bibname做了特殊的处理:
% {<language>}{<strings>}
\newrobustcmd*{\DefineBibliographyStrings}[2]{%
\blx@lbxcheck{#1}%
\csgappto{blx@hook@strings@#1}{%
\begingroup
\let\blx@defstring\blx@cfg@defstring
\blx@defbibstrings{#1}{#2}%
\endgroup}}
\@onlypreamble\DefineBibliographyStrings
\def\blx@defbibstrings#1#2{%
\def\do##1{\csundef{abx@lstr@##1}\csundef{abx@sstr@##1}}%
\abx@dostrings
\csuse{abx@strings@#1}%
\setkeys{blx@lbx}{#2}%
\let\do\blx@defbibstrings@i
\csxdef{abx@strings@#1}{\abx@dostrings}%
\csgappto{abx@strings@#1}{%
\ifcsdef{\abx@str @bibliography}
{\letcs\bibname{\abx@str @bibliography}}
{\let\bibname\@empty}%
\ifcsdef{\abx@str @references}
{\letcs\refname{\abx@str @references}}
{\let\refname\@empty}%
\ifcsdef{\abx@str @shorthands}
{\letcs\biblistname{\abx@str @shorthands}}
{\let\biblistname\@empty}}}
biblatex把\bibname与本地化字符串做了关联,这个处理是在文档开始处完成的,看如下例子:
\documentclass[twoside]{ctexbook}%article
\usepackage{xcolor}
\usepackage{hyperref}
\usepackage{lipsum}
\usepackage[top=10pt,bottom=10pt,left=10pt,right=10pt]{geometry}
\usepackage[backend=biber,style=gb7714-2015]{biblatex}
\DefineBibliographyStrings{english}{
bibliography = {ckwx},
references = {ckwx},
}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@REPORT{calvo2006phoenix,
AUTHOR = {Calvo, Guillermo A and Izquierdo, Alejandro and Talvi, Ernesto},
INSTITUTION = {National Bureau of Economic Research},
DATE = {2006},
KEYWORDS = {calvo2006phoenix},
TITLE = {Phoenix miracles in emerging markets: recovering without credit from systemic financial crises},
}
\end{filecontents}
\addbibresource{\jobname.bib}
%
%\ctexset{
%bibname ={文\quad 献}
%}
%
\show\bibname
\newcommand{\bibname}{文\quad 献}
\show\bibname
\begin{document}
%\meaning\bibname
\show\bibname
文献\nocite{*}
\meaning\bibname
\renewcommand{\bibname}{文\quad 献}
\meaning\bibname
\show\bibname
\printbibliography%[title=参考文献]
\end{document}
因此说在导言区中做bibname重定义时没有效果的。
此外,还有其他的一些问题。假设用户仅使用这种默认设置,那么重定义参考文献标题是可以考虑的。比如:
\defbibheading{bibliography}{%
\chapter*{参考文献}%
\markboth{参考文献}{参考文献}}
这种方式直接避开了bibname宏处理问题,注意:对于article类(区别于book和report)是\refname宏。
但如果用户有其它选择,比如要用\printshorthands打印一个缩略表,那么就要重定义一个shorthands的标题。 如果用户还要用\printbiblist打印一些参考文献信息的缩略表,那么还要定义对应的标题。 而且如果用户还要使用heading=subbibliography等对应不同层级标题格式的设置,那么还要定义subbibliography。
当然通常情况下,一般用户用不了这么多功能,因此只需要重定义bibliography就行了。
当然如果仅需要修改标题的内容,那么还有如下两种方式:
\printbibliography[title=参考文献]
那么该标题‘参考文献’会作为上述bibname定义宏中的#1传递给它,进而自动成为参考标题内容。如果不给出该选项,那么就会使用本地化字符串来做#1,即前面说过的 ,将本地化字符串处理为\bibname,因此修改标题内容就是要修改本地化字符串的值:
\DefineBibliographyStrings{english}{
bibliography = {参考文献},
references = {参考文献},
}
从一般用户的角度看可能使用一个\printbibliography命令就够了,那么这时可以修改本地化字符串,也可以重定义bibliography标题。 直接重定义bibliography标题避开bibname宏处理是比较简单的方法。
另外因为biblatex的特殊性,其实可以考虑不在沿用以前bibtex的模式,非要定义一个bibname来设置参考文献标题。 因为biblatex定义标题内容的方式是很灵活的。
供探讨。
当然,如果要用bibname的话,可以做一个简单的反处理,即重定义
\def\blx@defbibstrings#1#2{%
\def\do##1{\csundef{abx@lstr@##1}\csundef{abx@sstr@##1}}%
\abx@dostrings
\csuse{abx@strings@#1}%
\setkeys{blx@lbx}{#2}%
\let\do\blx@defbibstrings@i
\csxdef{abx@strings@#1}{\abx@dostrings}%
}
这样直接使用ctexset就没有问题了。
比如
\ctexset{
bibname={文献}
}
\printbibliography
示例为:
\documentclass[twoside]{ctexbook}%article
\usepackage{xcolor}
\usepackage{hyperref}
\usepackage{etoolbox}
\usepackage{lipsum}
\usepackage[top=10pt,bottom=10pt,left=10pt,right=10pt]{geometry}
\usepackage[backend=biber,style=gb7714-2015]{biblatex}
\makeatletter
\def\blx@defbibstrings#1#2{%
\def\do##1{\csundef{abx@lstr@##1}\csundef{abx@sstr@##1}}%
\abx@dostrings
\csuse{abx@strings@#1}%
\setkeys{blx@lbx}{#2}%
\let\do\blx@defbibstrings@i
\csxdef{abx@strings@#1}{\abx@dostrings}%
}
\makeatother
\defbibheading{bibliography}[\bibname]{%
\section*{#1}}
\DefineBibliographyStrings{english}{
bibliography = {ckwx},
references = {ckwx},
}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@REPORT{calvo2006phoenix,
AUTHOR = {Calvo, Guillermo A and Izquierdo, Alejandro and Talvi, Ernesto},
INSTITUTION = {National Bureau of Economic Research},
DATE = {2006},
KEYWORDS = {calvo2006phoenix},
TITLE = {Phoenix miracles in emerging markets: recovering without credit from systemic financial crises},
}
\end{filecontents}
\addbibresource{\jobname.bib}
%
\begin{document}
cite:\nocite{*}
ctexbook类的默认设置:\meaning\bibname
\printbibliography
\renewcommand{\bibname}{文\quad 献}
重定义bibname设置:\meaning\bibname
\printbibliography
\ctexset{
bibname ={ctexckwx}
}
ctexset对bibname设置:\meaning\bibname
\printbibliography
\csgdef{bibname}{refs}
\meaning\bibname
\csgdef{bibnamea}{refa}
\cslet{bibname}{\bibnamea}
\meaning\bibname
\csgdef{bibnameb}{refb}
\letcs\bibname{bibnameb}
\meaning\bibname
\renewrobustcmd*{\bibname}{references}
etoolbox的命令对bibname设置:\meaning\bibname
\printbibliography
\end{document}
这种方式保留了使用printbibliography的title选项设置标题内容的方式, 去除了使用本地化字符串设置的方式, 但获得了利用ctexset设置的途径,有得有失,但对中文用户来说也不失为更好的选择。
与许多宏包一样,
biblatex
基于babel
做本地化。默认语言用的是english
,然后会在\begin{document}
之后修改\refname
、\bibname
的值,造成问题。biblatex
自己的本地化文献是.lbx
文件,会语言保存相关的串。对于中文文档,
ctex
包对\refname
或\bibname
的修改早于biblatex
的重定义,会造成无效。简单的处理方式是让
\ctexset
设置bibname
延迟(利用\AtBeginDocument
)。目前已有的
biblatex
格式,如biblatex-gb7714-2015
、biblatex-caspervector
,则是直接在.bbx
文件定义中类似这样设置:这种设置也有一些风险。
需要考虑一下怎么设置比较好。