当\cref
一个定理时,为了显示与其上下文中原来出现相对应的引用名称(即,如果你在英文上下文中写了一条定理,后来在法文上下文中引用它,那么就Theorem
应该显示英文名称),我定义了单独的计数器theorem-english
和,theorem-french
然后将它们别名为theorem
,并\crefname
给这些计数器定义了单独的。
问题在于它\crefname
很慢,所以随着语言和类定理环境的数量增加,这种方法很快就会变得难以忍受的慢。
一个想法是减少使用\crefname
,只为计数器定义一次theorem-\languagename
(这里\languagename
用作占位符)。但是我不知道这是否真的可行——我尝试将其设置为计数器theorem- \exp_not:N \languagename
,但最终出现了几个错误。
下面是 MWE。
\documentclass{article}
\usepackage[french,english]{babel}
\usepackage{amsthm}
\usepackage{aliascnt}
\usepackage[french,english]{cleveref}
\makeatletter
\ExplSyntaxOn
\newtheorem{theorem}{ \tl_use:c { c_projlib_theorem_name_theorem_ \languagename _tl } }
\newtheorem{definition}[theorem]{ \tl_use:c { c_projlib_theorem_name_definition_ \languagename _tl } }
\newaliascnt{theorem-english}{theorem}
\newaliascnt{theorem-french}{theorem}
%% Too many crefnames thus too slow
\crefname{theorem-english}{\c_projlib_theorem_name_theorem_english_tl}{\c_projlib_theorem_name_theorem_plural_english_tl}
\crefname{theorem-french}{\c_projlib_theorem_name_theorem_french_tl}{\c_projlib_theorem_name_theorem_plural_french_tl}
%% Does not work
% \crefname{theorem- \exp_not:N \languagename}
% { \tl_use:c { c_projlib_theorem_name_theorem_\languagename_tl } }
% { \tl_use:c { c_projlib_theorem_name_theorem_plural_\languagename_tl } }
% Temporary names
\tl_set:Nn \c_projlib_theorem_name_theorem_english_tl { Theorem }
\tl_set:Nn \c_projlib_theorem_name_theorem_plural_english_tl { Theorems }
\tl_set:Nn \c_projlib_theorem_name_theorem_french_tl { Théorème }
\tl_set:Nn \c_projlib_theorem_name_theorem_plural_french_tl { Théorèmes }
\tl_set:Nn \c_projlib_theorem_name_definition_english_tl { Definition }
\tl_set:Nn \c_projlib_theorem_name_definition_plural_english_tl { Definitions }
\tl_set:Nn \c_projlib_theorem_name_definition_french_tl { Définition }
\tl_set:Nn \c_projlib_theorem_name_definition_plural_french_tl { Définitions }
\ExplSyntaxOff
\makeatother
\begin{document}
\begin{theorem}
\addtocounter{theorem-english}{-1}
\refstepcounter{theorem-english}
\label{thm1}
In english.
\end{theorem}
\begin{definition}\label{def1}
In english.
\end{definition}
\cref{thm1,thm2,def1,def2}
\selectlanguage{french}
\begin{theorem}
\addtocounter{theorem-french}{-1}
\refstepcounter{theorem-french}
\label{thm2}
En français.
\end{theorem}
\begin{definition}\label{def2}
En français.
\end{definition}
\cref{thm1,thm2,def1,def2}
% \makeatletter
% \meaning\cref@old@refstepcounter
% \meaning\refstepcounter@noarg
\end{document}
下面是一个复杂的版本,包含应该是构建projlib-theorem
模块的一部分的代码。如果取消注释该To slow
部分,这是上述 MWE 的行为,但具有更完整的配置。
\begin{filecontents*}[overwrite]{projlib-language.sty}
\NeedsTeXFormat{LaTeX2e}[2020-10-01]
\RequirePackage{l3keys2e}
\ProvidesExplPackage
{projlib-language}
{2022/02/10} {}
{Multi-language configuration}
\clist_new:N \c__projlib_language_supported_clist
\clist_new:N \g__projlib_language_babel_option_clist
\clist_set:Nn \c__projlib_language_supported_clist
{
english ,
french ,
ngerman ,
italian ,
portuguese ,
brazilian ,
spanish ,
schinese ,
tchinese ,
japanese ,
russian ,
}
\str_new:N \g__projlib_language_main_str
\bool_new:N \g__projlib_language_enabled_all_bool
\bool_gset_true:N \g__projlib_language_enabled_all_bool
\clist_map_inline:Nn \c__projlib_language_supported_clist
{
\bool_new:c { g__projlib_language_enabled_ #1 _bool }
\bool_gset_false:c { g__projlib_language_enabled_ #1 _bool }
}
\cs_new:Nn \projlib_language_set_option_no_babel:n
{
\bool_gset_false:N \g__projlib_language_enabled_all_bool
\bool_gset_true:c { g__projlib_language_enabled_ #1 _bool }
\str_if_empty:NT \g__projlib_language_main_str
{
\str_gset:Nn \g__projlib_language_main_str { #1 }
}
}
\cs_new:Nn \projlib_language_set_option:n
{
\projlib_language_set_option_no_babel:n { #1 }
\clist_gput_left:Nn \g__projlib_language_babel_option_clist { #1 }
}
\keys_define:nn { projlib-language }
{
, EN .code:n = { \projlib_language_set_option:n { english } }
, english .code:n = { \projlib_language_set_option:n { english } }
, English .code:n = { \projlib_language_set_option:n { english } }
, FR .code:n = { \projlib_language_set_option:n { french } }
, french .code:n = { \projlib_language_set_option:n { french } }
, French .code:n = { \projlib_language_set_option:n { french } }
, DE .code:n = { \projlib_language_set_option:n { ngerman } }
, german .code:n = { \projlib_language_set_option:n { ngerman } }
, ngerman .code:n = { \projlib_language_set_option:n { ngerman } }
, German .code:n = { \projlib_language_set_option:n { ngerman } }
, IT .code:n = { \projlib_language_set_option:n { italian } }
, italian .code:n = { \projlib_language_set_option:n { italian } }
, Italian .code:n = { \projlib_language_set_option:n { italian } }
, PT .code:n = { \projlib_language_set_option:n { portuguese } }
, portuguese .code:n = { \projlib_language_set_option:n { portuguese } }
, Portuguese .code:n = { \projlib_language_set_option:n { portuguese } }
, BR .code:n = { \projlib_language_set_option:n { brazilian } }
, brazilian .code:n = { \projlib_language_set_option:n { brazilian } }
, Brazilian .code:n = { \projlib_language_set_option:n { brazilian } }
, ES .code:n = { \clist_gput_left:Nn \g__projlib_language_babel_option_clist { es-notilde, es-noquoting } \projlib_language_set_option:n { spanish } }
, spanish .code:n = { \clist_gput_left:Nn \g__projlib_language_babel_option_clist { es-notilde, es-noquoting } \projlib_language_set_option:n { spanish } }
, Spanish .code:n = { \clist_gput_left:Nn \g__projlib_language_babel_option_clist { es-notilde, es-noquoting } \projlib_language_set_option:n { spanish } }
, CN .code:n = { \projlib_language_set_option_no_babel:n { schinese } }
, chinese .code:n = { \projlib_language_set_option_no_babel:n { schinese } }
, schinese .code:n = { \projlib_language_set_option_no_babel:n { schinese } }
, simplifiedchinese .code:n = { \projlib_language_set_option_no_babel:n { schinese } }
, Chinese .code:n = { \projlib_language_set_option_no_babel:n { schinese } }
, SChinese .code:n = { \projlib_language_set_option_no_babel:n { schinese } }
, SimplifiedChinese .code:n = { \projlib_language_set_option_no_babel:n { schinese } }
, TC .code:n = { \projlib_language_set_option_no_babel:n { tchinese } }
, tchinese .code:n = { \projlib_language_set_option_no_babel:n { tchinese } }
, traditionalchinese .code:n = { \projlib_language_set_option_no_babel:n { tchinese } }
, TChinese .code:n = { \projlib_language_set_option_no_babel:n { tchinese } }
, TraditionalChinese .code:n = { \projlib_language_set_option_no_babel:n { tchinese } }
, JP .code:n = { \projlib_language_set_option:n { japanese } }
, japanese .code:n = { \projlib_language_set_option:n { japanese } }
, Japanese .code:n = { \projlib_language_set_option:n { japanese } }
, RU .code:n = { \projlib_language_set_option:n { russian } }
, russian .code:n = { \projlib_language_set_option:n { russian } }
, Russian .code:n = { \projlib_language_set_option:n { russian } }
, unknown .code:n = {}
}
\ProcessKeysOptions { projlib-language }
\cs_new_protected:Nn \projlib_language_clear_global_option:n
{
\clist_remove_all:cn { @classoptionslist } { #1 }
}
\projlib_language_clear_global_option:n { chinese }
\projlib_language_clear_global_option:n { Chinese }
\clist_gput_right:Nn \g__projlib_language_babel_option_clist { shorthands = off }
\str_if_empty:NT \g__projlib_language_main_str
{
\str_gset:Nn \g__projlib_language_main_str { english }
}
\bool_if:NT \g__projlib_language_enabled_all_bool
{
\clist_map_inline:Nn \c__projlib_language_supported_clist
{
\bool_gset_true:c { g__projlib_language_enabled_ #1 _bool }
}
}
\cs_new:Nn \projlib_language_str_to_languagename:n
{
\str_case_e:nnF { \str_foldcase:n { #1 } }
{
{all} {common}
{common} {common}
{cn} {schinese}
{chinese} {schinese}
{schinese} {schinese}
{simplifiedchinese} {schinese}
{tc} {tchinese}
{tchinese} {tchinese}
{traditionalchinese} {tchinese}
{jp} {japanese}
{japanese} {japanese}
{en} {english}
{english} {english}
{fr} {french}
{french} {french}
{de} {ngerman}
{german} {ngerman}
{ngerman} {ngerman}
{it} {italian}
{italian} {italian}
{pt} {portuguese}
{portuguese} {portuguese}
{br} {brazilian}
{brazilian} {brazilian}
{es} {spanish}
{spanish} {spanish}
{ru} {russian}
{russian} {russian}
}
{ #1 }
}
\cs_new:Nn \projlib_language_str_to_languagetype:n
{
\str_case_e:nn { \str_foldcase:n { #1 } }
{
{cn} {cjk}
{chinese} {cjk}
{schinese} {cjk}
{simplifiedchinese} {cjk}
{tc} {cjk}
{tchinese} {cjk}
{traditionalchinese} {cjk}
{jp} {cjk}
{japanese} {cjk}
{en} {latin}
{english} {latin}
{fr} {latin}
{french} {latin}
{de} {latin}
{german} {latin}
{ngerman} {latin}
{it} {latin}
{italian} {latin}
{pt} {latin}
{portuguese} {latin}
{br} {latin}
{brazilian} {latin}
{es} {latin}
{spanish} {latin}
{ru} {latin}
{russian} {latin}
}
}
\sys_if_engine_pdftex:T
{
\RequirePackage [T1] { fontenc }
\RequirePackage { inputenc }
}
\bool_if:NTF \g__projlib_language_enabled_all_bool
{
\sys_if_engine_pdftex:F
{
\PassOptionsToPackage { japanese, russian } { babel }
}
\PassOptionsToPackage { italian, portuguese, brazilian, spanish, es-notilde, es-noquoting, ngerman, french, english, shorthands = off } { babel }
}
{
\PassOptionsToPackage { \g__projlib_language_babel_option_clist } { babel }
}
\PassOptionsToPackage { italian, brazilian, spanish, ngerman, french, english } { cleveref }
\RequirePackage { babel }
\bool_if:NT \g__projlib_language_enabled_french_bool
{
\frenchsetup { PartNameFull = false }
}
\bool_if:NT \g__projlib_language_enabled_portuguese_bool
{
\cs_set_eq:NN \__projlib_language_babel_ord: \ord
\cs_undefine:N \ord
\hook_gput_code:nnn { begindocument } { projlib-language }
{
\cs_if_exist:NT \ord
{
\cs_set_eq:NN \__projlib_language_user_ord: \ord
\cs_set_protected:Npn \ord
{
\mode_if_math:TF
{ \__projlib_language_user_ord: }
{ \__projlib_language_babel_ord: }
}
}
}
}
\babelprovide { schinese }
\babelprovide { tchinese }
\NewCommandCopy \projlib_language_backup_today:n \today
\tl_new:N \g_projlib_language_settings_common_tl
\clist_map_inline:Nn \c__projlib_language_supported_clist
{
\tl_new:c { g_projlib_language_settings_ #1 _tl }
}
\tl_gput_right:Nn \g_projlib_language_settings_common_tl
{
\cs_if_exist:NT \ProjLibToday
{
\RenewCommandCopy \today \ProjLibToday
}
}
\tl_gput_right:Nn \g_projlib_language_settings_schinese_tl
{
\g_projlib_language_settings_common_tl
\tl_gset:Nn \languagename { schinese }
\tl_gset:cn { abstractname } { 摘要 }
\tl_gset:cn { proofname } { 证明 }
\tl_gset:cn { contentsname } { 目录 }
\tl_gset:cn { listfigurename } { 插图 }
\tl_gset:cn { listtablename } { 表格 }
\tl_gset:cn { figurename } { 图 }
\tl_gset:cn { tablename } { 表 }
\tl_gset:cn { indexname } { 索引 }
\tl_gset:cn { appendixname } { 附录 }
\tl_gset:cn { refname } { 参考文献 }
\tl_gset:cn { bibname } { 参考文献 }
}
\tl_gput_right:Nn \g_projlib_language_settings_tchinese_tl
{
\g_projlib_language_settings_common_tl
\tl_gset:Nn \languagename { tchinese }
\tl_gset:cn { abstractname } { 摘要 }
\tl_gset:cn { proofname } { 證明 }
\tl_gset:cn { contentsname } { 目錄 }
\tl_gset:cn { listfigurename } { 插圖 }
\tl_gset:cn { listtablename } { 表格 }
\tl_gset:cn { figurename } { 圖 }
\tl_gset:cn { tablename } { 表 }
\tl_gset:cn { indexname } { 索引 }
\tl_gset:cn { appendixname } { 附錄 }
\tl_gset:cn { refname } { 參考文獻 }
\tl_gset:cn { bibname } { 參考文獻 }
}
\tl_gput_right:Nn \g_projlib_language_settings_japanese_tl
{
\selectlanguage { japanese }
\g_projlib_language_settings_common_tl
}
\tl_gput_right:Nn \g_projlib_language_settings_english_tl
{
\selectlanguage { english }
\g_projlib_language_settings_common_tl
}
\tl_gput_right:Nn \g_projlib_language_settings_french_tl
{
\selectlanguage { french }
\g_projlib_language_settings_common_tl
\tl_gset:cn { frenchpartname } { Partie }
}
\tl_gput_right:Nn \g_projlib_language_settings_ngerman_tl
{
\selectlanguage { ngerman }
\g_projlib_language_settings_common_tl
}
\tl_gput_right:Nn \g_projlib_language_settings_italian_tl
{
\selectlanguage { italian }
\g_projlib_language_settings_common_tl
}
\tl_gput_right:Nn \g_projlib_language_settings_portuguese_tl
{
\selectlanguage { portuguese }
\g_projlib_language_settings_common_tl
}
\tl_gput_right:Nn \g_projlib_language_settings_brazilian_tl
{
\selectlanguage { brazilian }
\g_projlib_language_settings_common_tl
}
\tl_gput_right:Nn \g_projlib_language_settings_spanish_tl
{
\selectlanguage { spanish }
\g_projlib_language_settings_common_tl
}
\tl_gput_right:Nn \g_projlib_language_settings_russian_tl
{
\selectlanguage { russian }
\g_projlib_language_settings_common_tl
}
\NewDocumentCommand \AddLanguageSetting { O{} m }
{
\IfNoValueTF { #1 }
{
\tl_gput_right:Nn \g_projlib_language_settings_common_tl { #2 }
}
{
\tl_gput_right:cn { g_projlib_language_settings_ \projlib_language_str_to_languagename:n { #1 } _tl } { #2 }
}
}
\RequirePackage { setspace }
\tl_new:N \g_projlib_language_linespacing_latin_tl
\tl_new:N \g_projlib_language_linespacing_cjk_tl
\tl_gset:Nn \g_projlib_language_linespacing_latin_tl
{
\setstretch { 1.00 }
}
\tl_gset:Nn \g_projlib_language_linespacing_cjk_tl
{
\onehalfspacing
}
\cs_new:Nn \projlib_language_set_linespacing_latin:n
{
\tl_gset:Nn \g_projlib_language_linespacing_latin_tl { #1 }
}
\cs_new:Nn \projlib_language_set_linespacing_cjk:n
{
\tl_gset:Nn \g_projlib_language_linespacing_cjk_tl { #1 }
}
\tl_new:N \g_projlib_language_parindent_latin_tl
\tl_new:N \g_projlib_language_parindent_cjk_tl
\@ifclassloaded{beamer}
{
\tl_gset:Nn \g_projlib_language_parindent_latin_tl
{
\dim_set:Nn \parindent { 0em }
}
\tl_gset:Nn \g_projlib_language_parindent_cjk_tl
{
\dim_set:Nn \parindent { 0em }
}
}
{
\tl_gset:Nn \g_projlib_language_parindent_latin_tl
{
\dim_set:Nn \parindent { 1.5em }
}
\tl_gset:Nn \g_projlib_language_parindent_cjk_tl
{
\dim_set:Nn \parindent { 2em }
}
}
\cs_new:Nn \projlib_language_set_parindent_latin:n
{
\tl_gset:Nn \g_projlib_language_parindent_latin_tl { #1 }
}
\cs_new:Nn \projlib_language_set_parindent_cjk:n
{
\tl_gset:Nn \g_projlib_language_parindent_cjk_tl { #1 }
}
\cs_new:Nn \projlib_language_use_language_pure:n
{
\tl_use:c { g_projlib_language_settings_ \projlib_language_str_to_languagename:n { #1 } _tl }
}
\cs_new:Nn \projlib_language_use_language:n
{
\projlib_language_use_language_pure:n { #1 }
\tl_use:c { g_projlib_language_linespacing_ \projlib_language_str_to_languagetype:n { #1 } _tl }
\tl_use:c { g_projlib_language_parindent_ \projlib_language_str_to_languagetype:n { #1 } _tl }
}
\cs_generate_variant:Nn \projlib_language_use_language:n { e }
\NewDocumentCommand \UseLanguage { m }
{
\hook_gput_code:nnn { begindocument } { projlib-language }
{
\projlib_language_use_language:e { #1 }
}
}
\NewDocumentCommand \UseOtherLanguage { m m }
{
\group_begin: \group_begin:
\projlib_language_use_language_pure:e { #1 }
#2
\group_end: \group_end:
}
\UseLanguage { \g__projlib_language_main_str }
\cs_new:Nn \projlib_langauge_define_multilingual_text:Nn
{ % #1 = command name
% #2 = key-value name configuration
\keyval_parse:nnn
{}
{
\__projlib_langauge_define_multilingual_text_do:nnn
{ \cs_to_str:N #1 }
}
{ #2 }
\tl_gset:Nn #1
{
\tl_use:c { \cs_to_str:N #1 _projlib_language_text_ \languagename }
}
}
\cs_generate_variant:Nn \projlib_langauge_define_multilingual_text:Nn { cn }
\cs_new:Nn \__projlib_langauge_define_multilingual_text_do:nnn
{ % #1 = command name
% #2 = language name
% #3 = the text
\exp_args:Ne \tl_gset:cn { #1 _projlib_language_text_ \projlib_language_str_to_languagename:n { #2 } } { #3 }
}
\endinput
%%
%% End of file `projlib-language.sty'.
\end{filecontents*}
\documentclass{article}
\usepackage{projlib-language}
\usepackage{amsthm}
\usepackage{aliascnt}
\usepackage{cleveref}
\makeatletter
\ExplSyntaxOn
\bool_new:N \l__projlib_theorem_regionalref_bool
\bool_new:N \l__projlib_theorem_originalref_bool
\bool_set_true:N \l__projlib_theorem_originalref_bool
% \bool_set_false:N \l__projlib_theorem_originalref_bool
\clist_set:Nn \c__projlib_theorem_supported_clist
{
theorem ,
lemma ,
proposition ,
corollary ,
property ,
fact ,
conjecture ,
definition ,
axiom ,
assumption ,
convention ,
hypothesis ,
notation ,
exemple ,
problem ,
question ,
exercise ,
remark ,
observation ,
definition-proposition ,
definition-theorem ,
}
\clist_map_inline:Nn \c__projlib_theorem_supported_clist
{
\clist_map_inline:Nn \c__projlib_language_supported_clist
{
\tl_new:c { c_projlib_theorem_name_ #1 _ ##1 _tl }
\tl_new:c { c_projlib_theorem_name_ #1 _plural_ ##1 _tl }
\tl_new:c { c_projlib_theorem_name_uppercase_ #1 _ ##1 _tl }
\tl_new:c { c_projlib_theorem_name_uppercase_ #1 _plural_ ##1 _tl }
}
}
\clist_map_inline:Nn \c__projlib_theorem_supported_clist
{
\newtheorem { #1 _projlib_regional } { \tl_use:c { c_projlib_theorem_name_ #1 _ \languagename _tl } }
\NewDocumentEnvironment { #1 } { O{} }
{
\begin{ #1 _projlib_regional }[##1]
\bool_if:NT \l__projlib_theorem_originalref_bool
{
\addtocounter { #1 _projlib_original_\languagename } { -1 }
\refstepcounter { #1 _projlib_original_\languagename }
}
}
{
\end{ #1 _projlib_regional }
}
}
\bool_if:NTF \l__projlib_theorem_originalref_bool
{% "originalref" mode
\clist_map_inline:Nn \c__projlib_theorem_supported_clist
{
\clist_map_inline:Nn \c__projlib_language_supported_clist
{
\newaliascnt { #1 _projlib_original_ ##1 } { #1 _projlib_regional }
%% Too slow
% \crefname { #1 _projlib_original_ ##1 }
% { \tl_use:c { c_projlib_theorem_name_ #1 _ ##1 _tl } }
% { \tl_use:c { c_projlib_theorem_name_ #1 _plural_ ##1 _tl } }
% \Crefname { #1 _projlib_original_ ##1 }
% { \tl_use:c { c_projlib_theorem_name_uppercase_ #1 _ ##1 _tl } }
% { \tl_use:c { c_projlib_theorem_name_uppercase_ #1 _plural_ ##1 _tl } }
}
%% Does not work
% \crefname { #1 _projlib_original_ \exp_not:N \languagename }
% { \tl_use:c { c_projlib_theorem_name_ #1 _ \languagename _tl } }
% { \tl_use:c { c_projlib_theorem_name_ #1 _plural_ \languagename _tl } }
}
}
{% "regionalref" mode
\clist_map_inline:Nn \c__projlib_theorem_supported_clist
{
\crefname { #1 _projlib_regional }
{ \tl_use:c { c_projlib_theorem_name_ #1 _ \languagename _tl } }
{ \tl_use:c { c_projlib_theorem_name_ #1 _plural_ \languagename _tl } }
\Crefname { #1 _projlib_regional }
{ \tl_use:c { c_projlib_theorem_name_uppercase_ #1 _ \languagename _tl } }
{ \tl_use:c { c_projlib_theorem_name_uppercase_ #1 _plural_ \languagename _tl } }
}
}
% Temporary names
\tl_set:Nn \c_projlib_theorem_name_theorem_english_tl { Theorem }
\tl_set:Nn \c_projlib_theorem_name_theorem_plural_english_tl { Theorems }
\tl_set:Nn \c_projlib_theorem_name_theorem_french_tl { Théorème }
\tl_set:Nn \c_projlib_theorem_name_theorem_plural_french_tl { Théorèmes }
\tl_set:Nn \c_projlib_theorem_name_definition_english_tl { Definition }
\tl_set:Nn \c_projlib_theorem_name_definition_plural_english_tl { Definitions }
\tl_set:Nn \c_projlib_theorem_name_definition_french_tl { Définition }
\tl_set:Nn \c_projlib_theorem_name_definition_plural_french_tl { Définitions }
\ExplSyntaxOff
\makeatother
\begin{document}
\UseLanguage{English}
\begin{theorem}\label{thm1}
In english.
\end{theorem}
\begin{definition}\label{def1}
In english.
\end{definition}
\cref{thm1,thm2,def1,def2}
\UseLanguage{French}
\begin{theorem}\label{thm2}
En français.
\end{theorem}
\begin{definition}\label{def2}
En français.
\end{definition}
\cref{thm1,thm2,def1,def2}
\end{document}
答案1
自从这个问题提出半年多以来寻求更快的 \CreateTheorem 实现,我想我终于意识到是什么在“originalref”模式中真正耗费了这么多时间。
内部调用,尽管创建了名称宏和,但仍将当前计数器名称添加到。从那时起,确实花费了大量时间。在中\crefname
,可以找到以下代码来处理中每个项目的名称、格式等:\@crefname
\cref@...@name
\cref@...@name@plural
\cref@label@types
cleveref.dtx
\cref@label@types
% Define any undefined formats listed in \cmd{\cref@label@types} using
% the components.
% \begin{macrocode}
\let\@tempstack\cref@label@types%
\cref@isstackfull{\@tempstack}%
\@whilesw\if@cref@stackfull\fi{%
\edef\@tempa{\cref@stack@top{\@tempstack}}%
\@ifundefined{cref@\@tempa @name}{%
\expandafter\def\expandafter\@tempb\expandafter{%
\csname cref@\@tempa @name\endcsname}%
\expandafter\def\expandafter\@tempc\expandafter{%
\csname cref@\@tempa @name@preamble\endcsname}%
\expandafter\expandafter\expandafter%
\let\expandafter\@tempb\@tempc%
\expandafter\def\expandafter\@tempb\expandafter{%
\csname cref@\@tempa @name@plural\endcsname}%
\expandafter\def\expandafter\@tempc\expandafter{%
\csname cref@\@tempa @name@plural@preamble\endcsname}%
\expandafter\expandafter\expandafter%
\let\expandafter\@tempb\@tempc%
}{%
\edef\@tempb{%
\expandafter\noexpand\csname extras\cref@language\endcsname}%
\expandafter\def\expandafter\@tempc\expandafter{%
\expandafter\crefname\expandafter{\@tempa}}%
\expandafter\expandafter\expandafter\cref@addto%
\expandafter\expandafter\expandafter\@tempc%
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\expandafter{%
\csname cref@\@tempa @name\endcsname}}%
\expandafter\expandafter\expandafter\cref@addto%
\expandafter\expandafter\expandafter\@tempc%
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\expandafter{%
\csname cref@\@tempa @name@plural\endcsname}}%
\expandafter\expandafter\expandafter\cref@addto%
\expandafter\@tempb\expandafter{\@tempc}%
}%
\@ifundefined{Cref@\@tempa @name}{%
\expandafter\def\expandafter\@tempb\expandafter{%
\csname Cref@\@tempa @name\endcsname}%
\expandafter\def\expandafter\@tempc\expandafter{%
\csname Cref@\@tempa @name@preamble\endcsname}%
\expandafter\expandafter\expandafter%
\let\expandafter\@tempb\@tempc%
\expandafter\def\expandafter\@tempb\expandafter{%
\csname Cref@\@tempa @name@plural\endcsname}%
\expandafter\def\expandafter\@tempc\expandafter{%
\csname Cref@\@tempa @name@plural@preamble\endcsname}%
\expandafter\expandafter\expandafter%
\let\expandafter\@tempb\@tempc%
}{%
\edef\@tempb{%
\expandafter\noexpand\csname extras\cref@language\endcsname}%
\expandafter\def\expandafter\@tempc\expandafter{%
\expandafter\Crefname\expandafter{\@tempa}}%
\expandafter\expandafter\expandafter\cref@addto%
\expandafter\expandafter\expandafter\@tempc%
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\expandafter{%
\csname Cref@\@tempa @name\endcsname}}%
\expandafter\expandafter\expandafter\cref@addto%
\expandafter\expandafter\expandafter\@tempc%
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\expandafter{%
\csname Cref@\@tempa @name@plural\endcsname}}%
\expandafter\expandafter\expandafter\cref@addto%
\expandafter\@tempb\expandafter{\@tempc}%
}%
% \end{macrocode}
% We only define the reference-range and multi-reference formats if the
% plural form of the name is defined in the corresponding
% \cmd{\cref\meta{type}@name@plural}. Though \cmd{\crefname} and
% \cmd{\Crefname} always define both the singular and plural forms
% together, cross-reference names can also be defined automatically by
% \cmd{\newtheorem}, which can only define the singular form. For
% symmetry, we apply the same logic to the normal cross-reference format
% definition (only defining it if the singular form of the name is
% defined in \cmd{\cref\meta{type}@name}), though this should always be
% the case.
% \begin{macrocode}
\@ifundefined{cref@\@tempa @format}{%
\@ifundefined{cref@\@tempa @name}{}{%
\expandafter\@crefdefineformat\expandafter{\@tempa}}}{}%
\@ifundefined{crefrange@\@tempa @format}{%
\@ifundefined{cref@\@tempa @name@plural}{}{%
\expandafter\@crefrangedefineformat\expandafter{\@tempa}}}{}%
\@ifundefined{cref@\@tempa @format@first}{%
\@ifundefined{cref@\@tempa @name@plural}{}{%
\expandafter\@crefdefinemultiformat\expandafter{\@tempa}}}{}%
\@ifundefined{crefrange@\@tempa @format@first}{%
\@ifundefined{cref@\@tempa @name@plural}{}{%
\expandafter\@crefrangedefinemultiformat%
\expandafter{\@tempa}}}{}%
\cref@stack@pop{\@tempstack}%
\cref@isstackfull{\@tempstack}}%
% \end{macrocode}
%
% If formats for subsections are undefined, define them to be identical
% to the formats for sections. Similarly for subsections within
% appendices, subfigures, subtables, subequations and enums.
% \begin{macrocode}
\@crefcopyformats{section}{subsection}%
\@crefcopyformats{subsection}{subsubsection}%
\@crefcopyformats{appendix}{subappendix}%
\@crefcopyformats{subappendix}{subsubappendix}%
\@crefcopyformats{figure}{subfigure}%
\@crefcopyformats{table}{subtable}%
\@crefcopyformats{equation}{subequation}%
%
\@crefcopyformats{enumi}{enumii}%
\@crefcopyformats{enumii}{enumiii}%
\@crefcopyformats{enumiii}{enumiv}%
\@crefcopyformats{enumiv}{enumv}%
% \end{macrocode}
由于所有这些单独的定理计数器都具有相同的格式,因此可以简单地使用\@crefcopyformats
。也就是说,除了\crefname
,还可以这样做:
\tl_gset:cn { cref@ ... @name } { ... }
\tl_gset:cn { cref@ ... @name@plural } { ... }
\@crefcopyformats { <the main counter> } { <the separate counter> }
对于originalref
模式,这将节省大量时间,使其几乎与regionalref
模式一样快(最终)。
完整的例子是:
\documentclass{article}
\usepackage{projlib-language}
\usepackage{amsthm}
\usepackage{aliascnt}
\usepackage{hyperref}
\usepackage[nameinlink]{cleveref}
\makeatletter
\ExplSyntaxOn
\bool_new:N \l__projlib_theorem_regionalref_bool
\bool_new:N \l__projlib_theorem_originalref_bool
\bool_set_true:N \l__projlib_theorem_originalref_bool
% \bool_set_false:N \l__projlib_theorem_originalref_bool
\clist_const:Nn \c__projlib_theorem_supported_clist
{
theorem ,
lemma ,
proposition ,
corollary ,
property ,
fact ,
conjecture ,
definition ,
axiom ,
assumption ,
convention ,
hypothesis ,
notation ,
example ,
problem ,
question ,
exercise ,
remark ,
observation ,
definition-proposition ,
definition-theorem ,
}
\clist_map_inline:Nn \c__projlib_theorem_supported_clist
{
\clist_map_inline:Nn \c__projlib_language_supported_clist
{
\tl_new:c { c_projlib_theorem_name_ #1 _ ##1 _tl }
\tl_new:c { c_projlib_theorem_name_ #1 _plural_ ##1 _tl }
\tl_new:c { c_projlib_theorem_name_uppercase_ #1 _ ##1 _tl }
\tl_new:c { c_projlib_theorem_name_uppercase_ #1 _plural_ ##1 _tl }
}
}
\clist_map_inline:Nn \c__projlib_theorem_supported_clist
{
\newtheorem { #1 _projlib_regional } { \tl_use:c { c_projlib_theorem_name_ #1 _ \languagename _tl } }
\NewDocumentEnvironment { #1 } { O{} }
{
\begin{ #1 _projlib_regional }[##1]
\bool_if:NT \l__projlib_theorem_originalref_bool
{
\addtocounter { #1 _projlib_original_\languagename } { -1 }
\refstepcounter { #1 _projlib_original_\languagename }
}
}
{
\end{ #1 _projlib_regional }
}
}
\bool_if:NTF \l__projlib_theorem_originalref_bool
{% "originalref" mode
\clist_map_inline:Nn \c__projlib_theorem_supported_clist
{
\clist_map_inline:Nn \c__projlib_language_supported_clist
{
\newaliascnt { #1 _projlib_original_ ##1 } { #1 _projlib_regional }
%% Too slow
% \crefname { #1 _projlib_original_ ##1 }
% { \tl_use:c { c_projlib_theorem_name_ #1 _ ##1 _tl } }
% { \tl_use:c { c_projlib_theorem_name_plural_ #1 _ ##1 _tl } }
% \Crefname { #1 _projlib_original_ ##1 }
% { \tl_use:c { c_projlib_theorem_name_uppercase_ #1 _ ##1 _tl } }
% { \tl_use:c { c_projlib_theorem_name_plural_uppercase_ #1 _ ##1 _tl } }
\tl_gset:cn { cref@ #1 _projlib_original_ ##1 @name } { \tl_use:c { c_projlib_theorem_name_ #1 _ ##1 _tl } }
\tl_gset:cn { cref@ #1 _projlib_original_ ##1 @name@plural } { \tl_use:c { c_projlib_theorem_name_plural_ #1 _ ##1 _tl } }
% Two ways to add items in \cref@label@types, just for testing
% \cref@stack@push{ #1 _projlib_original_ ##1 }{\cref@label@types}
% \regex_replace_once:nnN { \c{@nil} } { #1 _projlib_original_ ##1 , \c{@nil} } \cref@label@types
\@crefcopyformats { #1_projlib_regional } { #1 _projlib_original_ ##1 }
}
}
}
{% "regionalref" mode
\clist_map_inline:Nn \c__projlib_theorem_supported_clist
{
\crefname { #1 _projlib_regional }
{ \tl_use:c { c_projlib_theorem_name_ #1 _ \languagename _tl } }
{ \tl_use:c { c_projlib_theorem_name_plural_ #1 _ \languagename _tl } }
\Crefname { #1 _projlib_regional }
{ \tl_use:c { c_projlib_theorem_name_uppercase_ #1 _ \languagename _tl } }
{ \tl_use:c { c_projlib_theorem_name_plural_uppercase_ #1 _ \languagename _tl } }
}
}
% Temporary names
\tl_set:Nn \c_projlib_theorem_name_theorem_english_tl { Theorem }
\tl_set:Nn \c_projlib_theorem_name_plural_theorem_english_tl { Theorems }
\tl_set:Nn \c_projlib_theorem_name_theorem_french_tl { Théorème }
\tl_set:Nn \c_projlib_theorem_name_plural_theorem_french_tl { Théorèmes }
\tl_set:Nn \c_projlib_theorem_name_definition_english_tl { Definition }
\tl_set:Nn \c_projlib_theorem_name_plural_definition_english_tl { Definitions }
\tl_set:Nn \c_projlib_theorem_name_definition_french_tl { Définition }
\tl_set:Nn \c_projlib_theorem_name_plural_definition_french_tl { Définitions }
\ExplSyntaxOff
\makeatother
\begin{document}
\UseLanguage{English}
Current language: \languagename
\begin{theorem}\label{thm1}
In english.
\end{theorem}
\begin{theorem}\label{thm2}
In english.
\end{theorem}
\begin{definition}\label{def1}
In english.
\end{definition}
\cref{thm1,thm2,thm3,def1,def2}
\vspace{1cm}
\UseLanguage{French}
Current language: \languagename
\begin{theorem}\label{thm3}
En français.
\end{theorem}
\begin{definition}\label{def2}
En français.
\end{definition}
\cref{thm1,thm2,thm3,def1,def2}
\end{document}
如果取消注释\bool_set_false:N \l__projlib_theorem_originalref_bool
以启用该regionalref
模式,结果将是: