I'm trying to write a package to help setting up the multi-language configuration and to define theorem-like environments with multi-language support. The result is great but the code takes very long time to run.
Thus, I separated the most time-consuming part in the MWE below. It mainly consists of two part, one part with \UseLanguage, the other with \CreateTheorem. Due to my limited knowledge of LaTeX, these two macros are written in a very complicated manner.
My question is: is it possible to modify these two macros in some way so that they can achieve the same result, but in less time?
ADD: After some trial and error, I found that the time seems to be mainly consumed by these few lines on \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}%
But I can't see what can be optimized up to this point.
(The complete code can be found in: https://github.com/Jinwen-XU/ProjLib, the MWE below contains part of the code in PLlang.sty and PLthm.sty.)
Below is a 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}
7.5son my PC, but without the\crefnamelines it only takes about1.8s. And if all code in the preamble is commented, it takes about0.9s. Thus, my goal is to make the code compile in less than3s. – Jinwen May 13 '21 at 00:36\CreateTheoremthen I can show you, hot to implement it without anyxparseand similar tools, simply by TeX primitives. And you will see that the result will take only 0.1 sec or less. – wipet May 14 '21 at 19:06\CreateTheorem: https://tex.stackexchange.com/q/597713. Could you please kindly take a look at it? – Jinwen May 19 '21 at 14:03