我正在尝试编写一个包来帮助设置多语言配置并定义具有多语言支持的定理类环境。结果很棒,但代码运行时间很长。
因此,我将最耗时的部分从下面的 MWE 中分离出来。它主要由两部分组成,一部分是\UseLanguage
,另一部分是\CreateTheorem
。由于我对 LaTeX 的了解有限,这两个宏的编写方式非常复杂。
我的问题是:是否可以以某种方式修改这两个宏,以便它们能够实现相同的结果,但花费更少的时间?
添加:经过反复试验,我发现时间似乎主要被以下几行所消耗\crefname
:
\crefname{#1#2#3}%
{\csname#1name#2\endcsname}%
{\csname#1name#2\endcsname}%
\Crefname{#1#2#3}%
{\csname#1name#2\endcsname}%
{\csname#1name#2\endcsname}%
但到目前为止我看不出还有什么可以优化的。
(完整代码可以在以下位置找到:https://github.com/Jinwen-XU/ProjLibPLlang.sty
,下面的MWE包含和中的部分代码PLthm.sty
。)
下面是 MWE。
%! TEX program = xelatex
\documentclass{article}
\makeatletter
%%-------------------------------------------------------
%% PART I
%%-------------------------------------------------------
\RequirePackage{iftex}
\newcommand\englishABBR{EN}
\newcommand\frenchABBR{FR}
\newcommand\ngermanABBR{DE}
\newcommand\chineseABBR{CN}
\newcommand\tchineseABBR{TC}
\newcommand\japaneseABBR{JP}
\newcommand\russianABBR{RU}
\ifPDFTeX\else
\PassOptionsToPackage{japanese,russian}{babel}
\fi
\PassOptionsToPackage{italian,portuguese,brazilian,spanish.noquoting,ngerman,french,english,shorthands=off}{babel}
\PassOptionsToPackage{italian,brazilian,spanish,ngerman,french,english}{cleveref}
\RequirePackage{babel}
\frenchsetup{PartNameFull=false}
\newcommand{\PLlang@langconfig@common}{}
\newcommand{\PLlang@langconfig@chinese}{%
\renewcommand{\languagename}{chinese}%
}
\newcommand{\PLlang@langconfig@tchinese}{%
\renewcommand{\languagename}{tchinese}%
}
\newcommand{\PLlang@langconfig@japanese}{%
\selectlanguage{japanese}%
}
\newcommand{\PLlang@langconfig@english}{%
\selectlanguage{english}%
}
\newcommand{\PLlang@langconfig@french}{%
\selectlanguage{french}%
\def\frenchpartname{Partie}%
}
\newcommand{\PLlang@langconfig@german}{%
\selectlanguage{ngerman}%
}
\newcommand{\PLlang@langconfig@russian}{%
\selectlanguage{russian}%
}
\RequirePackage{setspace}
\def\PL@config@linespacing{\setstretch{1.00}}
\def\PL@config@CJKlinespacing{\onehalfspacing}
\newcommand{\PLsetlinespacing}[1]{\renewcommand{\PL@config@linespacing}{#1}}
\newcommand{\PLsetCJKlinespacing}[1]{\renewcommand{\PL@config@CJKlinespacing}{#1}}
\newcommand{\UseLanguageCORE}[1]{%
\PLlang@langconfig@common%
\ifstrequal{#1}{chinese}{\PL@config@CJKlinespacing\PLlang@langconfig@chinese}{}%
\ifstrequal{#1}{Chinese}{\PL@config@CJKlinespacing\PLlang@langconfig@chinese}{}%
\ifstrequal{#1}{schinese}{\PL@config@CJKlinespacing\PLlang@langconfig@chinese}{}%
\ifstrequal{#1}{SChinese}{\PL@config@CJKlinespacing\PLlang@langconfig@chinese}{}%
\ifstrequal{#1}{simplifiedchinese}{\PL@config@CJKlinespacing\PLlang@langconfig@chinese}{}%
\ifstrequal{#1}{SimplifiedChinese}{\PL@config@CJKlinespacing\PLlang@langconfig@chinese}{}%
\ifstrequal{#1}{tchinese}{\PL@config@CJKlinespacing\PLlang@langconfig@tchinese}{}%
\ifstrequal{#1}{TChinese}{\PL@config@CJKlinespacing\PLlang@langconfig@tchinese}{}%
\ifstrequal{#1}{traditionalchinese}{\PL@config@CJKlinespacing\PLlang@langconfig@tchinese}{}%
\ifstrequal{#1}{TraditionalChinese}{\PL@config@CJKlinespacing\PLlang@langconfig@tchinese}{}%
\ifstrequal{#1}{japanese}{\PL@config@CJKlinespacing\PLlang@langconfig@japanese}{}%
\ifstrequal{#1}{Japanese}{\PL@config@CJKlinespacing\PLlang@langconfig@japanese}{}%
\ifstrequal{#1}{english}{\PL@config@linespacing\PLlang@langconfig@english}{}%
\ifstrequal{#1}{English}{\PL@config@linespacing\PLlang@langconfig@english}{}%
\ifstrequal{#1}{french}{\PL@config@linespacing\PLlang@langconfig@french}{}%
\ifstrequal{#1}{French}{\PL@config@linespacing\PLlang@langconfig@french}{}%
\ifstrequal{#1}{ngerman}{\PL@config@linespacing\PLlang@langconfig@german}{}%
\ifstrequal{#1}{german}{\PL@config@linespacing\PLlang@langconfig@german}{}%
\ifstrequal{#1}{German}{\PL@config@linespacing\PLlang@langconfig@german}{}%
\ifstrequal{#1}{russian}{\PL@config@linespacing\PLlang@langconfig@russian}{}%
\ifstrequal{#1}{Russian}{\PL@config@linespacing\PLlang@langconfig@russian}{}%
}
\newcommand{\UseLanguage}[1]{%
\ifx\@onlypreamble\@notprerr%
\UseLanguageCORE{#1}%
\else%
\AfterEndPreamble{\UseLanguageCORE{#1}}%
\fi%
}
\UseLanguage{English}
%%-------------------------------------------------------
%% PART II
%%-------------------------------------------------------
\RequirePackage{amsmath,amsthm}
\RequirePackage{aliascnt}
\PassOptionsToPackage{nameinlink}{cleveref}
\RequirePackage{cleveref}
\RequirePackage{xstring}
\newcommand\PassFirstToSecond[2]{#2{#1}}%
\NewDocumentCommand{\CreateTheorem}{sm}{%
\begingroup
\protected@edef\temp{#2}%
\expandafter\IfEndWith\expandafter{\temp}{*}{%
\expandafter\StrGobbleRight\expandafter{\temp}{1}[\temp]%
\PassFirstToSecond{*}%
}{%
\PassFirstToSecond{}%
}%
{\expandafter\PassFirstToSecond%
\expandafter{\temp}{\endgroup\InnerCreateTheorem{#1}}}%
}%
\NewDocumentCommand{\InnerCreateTheorem}{mmmod<>d()}{%
\IfBooleanTF{#1}{%
\IfValueTF{#4}
{\@firstoftwo}
{\IfValueTF{#5}{\@firstoftwo}{\@secondoftwo}}%
}{%
\IfValueTF{#4}
{\IfValueTF{#5}{\@firstoftwo}{\@secondoftwo}}{
\@secondoftwo}
}%
{%
\GenericError{}%
{\string\CreateTheorem\space syntax error\on@line}{%
You cannot call the starred variant with optional argument,\MessageBreak
nor call the unstarred variant with several optional arguments.}%
{}%
}{%
\IfValueTF{#6}{%
\IfBooleanTF{#1}{%
\ifcsmacro{#2#3}%
{\renewenvironment{#2#3}{\begin{#6*}}{\end{#6*}}}%
{\newenvironment{#2#3}{\begin{#6*}}{\end{#6*}}}%
}{%
\ifcsmacro{#2#3}%
{\renewenvironment{#2#3}{\begin{#6}}{\end{#6}}}%
{\newenvironment{#2#3}{\begin{#6}}{\end{#6}}}%
}
}{%
\IfBooleanTF{#1}{%
\newtheorem*{#2EN#3}{\csname#2nameEN\endcsname}
\newtheorem*{#2FR#3}{\csname#2nameFR\endcsname}
\newtheorem*{#2DE#3}{\csname#2nameDE\endcsname}
\newtheorem*{#2CN#3}{\csname#2nameCN\endcsname}
\newtheorem*{#2TC#3}{\csname#2nameTC\endcsname}
\newtheorem*{#2JP#3}{\csname#2nameJP\endcsname}
\newtheorem*{#2RU#3}{\csname#2nameRU\endcsname}
}{%
\IfValueTF{#5}{%
\newcounter{#2#3}[{#5}]%
\expandafter\renewcommand\expandafter*%
\csname the#2#3\expandafter\endcsname%
\expandafter{\csname the#5\endcsname.\arabic{#2#3}}%
}{%
\IfValueTF{#4}
{\newaliascnt{#2#3}{#4}}
{\newcounter{#2#3}}%
}%
%---------------------------------------------------------------
\CreateTheoremNumberedLikeAliasCounter{#2}{EN}{#3}%
\CreateTheoremNumberedLikeAliasCounter{#2}{FR}{#3}%
\CreateTheoremNumberedLikeAliasCounter{#2}{DE}{#3}%
\CreateTheoremNumberedLikeAliasCounter{#2}{CN}{#3}%
\CreateTheoremNumberedLikeAliasCounter{#2}{TC}{#3}%
\CreateTheoremNumberedLikeAliasCounter{#2}{JP}{#3}%
\CreateTheoremNumberedLikeAliasCounter{#2}{RU}{#3}%
%---------------------------------------------------------------
}%
\NewDocumentEnvironment{#2#3}{}
{\csname#2\csname\languagename ABBR\endcsname#3\endcsname}%
{\csname end#2\csname\languagename ABBR\endcsname#3\endcsname}%
}
}%
}%
\NewDocumentCommand{\CreateTheoremNumberedLikeAliasCounter}{mmm}{%
\newaliascnt{#1#2#3}{#1#3}%
\newtheorem{#1#2#3}[{#1#2#3}]{\csname#1name#2\endcsname}%
\aliascntresetthe{#1#2#3}%
\crefname{#1#2#3}%
{\csname#1name#2\endcsname}%
{\csname#1name#2\endcsname}%
\Crefname{#1#2#3}%
{\csname#1name#2\endcsname}%
{\csname#1name#2\endcsname}%
}%
\def\theoremnameEN{Theorem}\def\lemmanameEN{Lemma}
\def\propositionnameEN{Proposition}
\def\corollarynameEN{Corollary}
\def\propertynameEN{Property}
\def\factnameEN{Fact}
\def\conjecturenameEN{Conjecture}
\def\definitionnameEN{Definition}
\def\axiomnameEN{Axiom}
\def\assumptionnameEN{Assumption}
\def\conventionnameEN{Convention}
\def\hypothesisnameEN{Hypothesis}
\def\notationnameEN{Notation}
\def\examplenameEN{Example}
\def\problemnameEN{Problem}
\def\questionnameEN{Question}
\def\exercisenameEN{Exercise}
\def\remarknameEN{Remark}
\expandafter\def\csname definition-propositionnameEN\endcsname{\definitionnameEN-\propositionnameEN}
\expandafter\def\csname definition-theoremnameEN\endcsname{\definitionnameEN-\theoremnameEN}
\CreateTheorem{theorem}<section>
\CreateTheorem{lemma}[theorem]
\CreateTheorem{proposition}[theorem]
\CreateTheorem{corollary}[theorem]
\CreateTheorem{definition-proposition}[theorem]
\CreateTheorem{definition-theorem}[theorem]
\CreateTheorem{property}[theorem]
\CreateTheorem{fact}[theorem]
\CreateTheorem{conjecture}[theorem]
\CreateTheorem*{theorem*}
\CreateTheorem*{lemma*}
\CreateTheorem*{proposition*}
\CreateTheorem*{corollary*}
\CreateTheorem*{definition-proposition*}
\CreateTheorem*{definition-theorem*}
\CreateTheorem*{property*}
\CreateTheorem*{fact*}
\CreateTheorem*{conjecture*}
\CreateTheorem{definition}[theorem]
\CreateTheorem{axiom}[theorem]
\CreateTheorem{assumption}[theorem]
\CreateTheorem{convention}[theorem]
\CreateTheorem{hypothesis}[theorem]
\CreateTheorem{notation}[theorem]
\CreateTheorem{example}[theorem]
\CreateTheorem{problem}[theorem]
\CreateTheorem{question}[theorem]
\CreateTheorem{exercise}[theorem]
\CreateTheorem*{definition*}
\CreateTheorem*{axiom*}
\CreateTheorem*{assumption*}
\CreateTheorem*{convention*}
\CreateTheorem*{hypothesis*}
\CreateTheorem*{notation*}
\CreateTheorem*{example*}
\CreateTheorem*{problem*}
\CreateTheorem*{question*}
\CreateTheorem*{exercise*}
\CreateTheorem{remark}<section>
\CreateTheorem*{remark*}
%%-------------------------------------------------------
\makeatother
\begin{document}
Some text
% \begin{theorem}
% Some text
% \end{theorem}
\end{document}
答案1
无需测试,但你\UseLanguageCORE
可以像这样缩短
%make the line spacing language dependant (or move into language config)
\let \PL@config@chineselinespacing \PL@config@CJKlinespacing
% more linespacing command
\let\PL@config@englishlinespacing \PL@config@linespacing
\newcommand\UseLanguageCORE[1]
{%
\PLlang@langconfig@common%
\csname PL@config@#1linespacing\endcsname
\csname PLlang@langconfig@#1\endcsname
}