动态设置 \crefname

动态设置 \crefname

我的目标:

\begin{equation}[singular=<sing_flag>,plural=<plur_flag>]\label{eq:1}
    a < b
\end{equation}
\cref{eq:1}

收益<sing_flag> (1)任何输入对于singularplural(我想避免手动\crefname为每种方程类型指定)。

基本思想:当singular和/或plural传递时,创建新的计数器(在等式内)作为cleveref和传递singular/plural到的锚\crefname

问题:

  • 仅设置\crefname不起作用,出于某种原因,我必须设置\crefformat等,这很麻烦并且不能很好地通过 Babel 实现自动化
  • Even\crefformat不太管用。它只是使用singular和的默认设置plural

梅威瑟:

\documentclass[]{article}

%% Packages
\usepackage{xkeyval}
\usepackage{xparse}
\usepackage{ifthen}
\usepackage{aliascnt}
\usepackage{cleveref}


\makeatletter

%% New Counter for counting new types of equations
\newcounter{misitex@formulatypes}

%% Set up for options
\define@cmdkey[misitex]{equation}{singular}{}
\define@cmdkey[misitex]{equation}{plural}{}
\setkeys[misitex]{equation}{singular=none,plural=none} % initialize

%% Save old equation env
\let\oldequation\equation
\let\endoldequation\endequation

%% Set Crefformat
\newcommand{\misitex@setcrefformat}[3]{
    SetCrefFormat gets: \noexpand{#2} \noexpand{#3}

    %% Shouldn't this suffice?
    \crefname{#1}{#2}{#3}
    \Crefname{#1}{#2}{#3}

    %% Why do I need this?
    \crefformat{#1}{##2#2~\upshape{(##1)}##3}
    \crefrangeformat{#1}{
        ##3#3~\upshape{(##1)}##4 to~##5\upshape{(##2)}##6
    }
    \crefmultiformat{#1}{##2#3~\upshape{(##1)}##3}%
        { and~##2\upshape{(##1)}##3}%
        {, ##2\upshape{(##1)})}%
        { and~##2\upshape{(##1)}##3}
}

%% Set options only if passed
\NewDocumentCommand{\misitex@equation@parse}{m m}{
    \IfValueTF{#1}{\setkeys[misitex]{equation}{#1}}{}
    \IfValueTF{#2}{\setkeys[misitex]{equation}{#2}}{}
}

%% Create new type of equation
\newcommand{\misitex@eqaution@setnew}[2]{
    % Add new equation counter
    \stepcounter{misitex@formulatypes}
    \newaliascnt{misitex@formulatype@\themisitex@formulatypes}{equation}

    % Set cref format
    \misitex@setcrefformat{misitex@formulatype@\themisitex@formulatypes}{#1}{#2}

    % Refstep for cref
    \refstepcounter{misitex@formulatype@\themisitex@formulatypes}

    % Set Equation Numbering
    \def\eqNumber{\eqno{\hbox{\upshape{
                    (\csname themisitex@formulatype@\themisitex@formulatypes \endcsname)
        }}}\@ignoretrue}
}

%% Renew Equation env
%% If singular/plural is passed: cerate new counter and apply cref names
%% Else just use old equation env
\RenewDocumentEnvironment{equation}{>{\SplitArgument{1}{,}}o}{
    % Parse Arguments
    \IfValueT{#1}{\misitex@equation@parse #1}%

    \ifthenelse{\equal{\cmdmisitex@equation@singular}{none}}%
    {%
        \ifthenelse{\equal{\cmdmisitex@equation@plural}{none}}%
            {%
                \oldequation%
            }{%
                \misitex@eqaution@setnew%
                    {\cref@equation@name}{\cmdmisitex@equation@plural}%
                $$
            }%
    }{%
        \ifthenelse{\equal{\cmdmisitex@equation@plural}{none}}%
            {%
                \misitex@eqaution@setnew%
                    {\cmdmisitex@equation@singular}{\cref@equation@name@plural}%
                $$%
            }{%
                \misitex@eqaution@setnew%
                    {\cmdmisitex@equation@singular}
                    {\cmdmisitex@equation@plural}%
                $$%
            }%
    }%
}{
    \ifthenelse{\equal{\cmdmisitex@equation@singular}{none}}%
    {%
        \ifthenelse{\equal{\cmdmisitex@equation@plural}{none}}%
            {
                \endoldequation
            }%
            {\eqNumber $$}%
    }{
        \eqNumber $$
    }
}

\makeatother

\begin{document}

    \begin{equation}[singular=Ineq.,plural=Ineqs.]\label{test}
     a = b
    \end{equation}

    \cref{test}

    \begin{equation}\label{test2}
    a = b
    \end{equation}

    \cref{test,test2}
\end{document}

输出:

在此处输入图片描述

因此,虽然看起来singularplural已正确传递\crefformat\cref但使用默认的none


虽然我知道这是一个相当具体的问题,但我还是很高兴得到任何建议:)

答案1

问题似乎是,它没有定义全局命令。一种解决方法是在编译之前使用读取文件\crefname的功能。通过将指令写入该文件,即可实现所需的解决方案。cleverefcleveref.cfg\crefname

梅威瑟:

请注意,命令处理已被改变,但这并不是问题的实际重点。

\documentclass{scrartcl}

\usepackage{hyperref}
\usepackage{mathtools}
\usepackage{aliascnt}
\usepackage{cleveref}
\usepackage{xparse}

\makeatletter

\newcounter{misitex@formulatypes}

\let\oldequation\equation
\let\endoldequation\endequation

%% Open file
\newwrite\cleverefcfg
\immediate\openout\cleverefcfg=cleveref.cfg

%% Some shortcuts to write special characters to file
\begingroup\lccode`?=`# \lowercase{\endgroup
    \newcommand{\hashsymb}{?}
}
\begingroup\lccode`?=`{ \lowercase{\endgroup
    \newcommand{\bracksymbo}{?}
}
\begingroup\lccode`?=`} \lowercase{\endgroup
    \newcommand{\bracksymbc}{?}
}
\begingroup\lccode`?=`\% \lowercase{\endgroup
    \newcommand{\commentsymb}{?}
}

%% write cleveref directives to file
\newcommand{\creflabelformat@tofile}[1]{
    \if@cref@nameinlink
        \protected@write\cleverefcfg{}{
            \string\creflabelformat{#1}\bracksymbo\hashsymb\commentsymb%
        }
        \protected@write\cleverefcfg{}{
            2\string\textup\bracksymbo(\hashsymb\commentsymb
        }
        \protected@write\cleverefcfg{}{
            1)\bracksymbc\hashsymb\commentsymb
        }
        \protected@write\cleverefcfg{}{
            3\bracksymbc\commentsymb
        }
    \else
        \protected@write\cleverefcfg{}{
            \string\creflabelformat{#1}\bracksymbo\string\textup\bracksymbo(\hashsymb\commentsymb%
        }
        \protected@write\cleverefcfg{}{
            2\hashsymb\commentsymb
        }
        \protected@write\cleverefcfg{}{
            1\hashsymb\commentsymb
        }
        \protected@write\cleverefcfg{}{
            3)\bracksymbc\bracksymbc\commentsymb
        }
    \fi
}

%% Renew equation env
%% Input may be [<cstm number>], [<sing>][<plur>], or [<cstm number>][<sing>][<plur>]
\RenewDocumentEnvironment{equation}{o o o}{
    \IfNoValueTF{#3}{
        \IfNoValueTF{#2}{
            \oldequation
            \IfValueT{#1}{\tag{#1}}
        }{
            \IfValueT{#1}{
                \stepcounter{misitex@formulatypes}
                \newaliascnt{misitex@formulatype@\themisitex@formulatypes}{equation}
                
                %% Write \crefname instruction to config file
                \protected@write\cleverefcfg{}{
                    \string\crefname{misitex@formulatype@\themisitex@formulatypes}{#1}{#2}
                    \string\Crefname{misitex@formulatype@\themisitex@formulatypes}{#1}{#2}
                }
                \creflabelformat@tofile{misitex@formulatype@\themisitex@formulatypes}
            }
            \oldequation
            \IfValueT{#1}{
                \addtocounter{equation}{-1}
                \refstepcounter{misitex@formulatype@\themisitex@formulatypes}
            }
        }
    }{
        \IfValueT{#2}{
            \stepcounter{misitex@formulatypes}
            \newaliascnt{misitex@formulatype@\themisitex@formulatypes}{equation}
    
            %% Write \crefname instruction to config file
            \protected@write\cleverefcfg{}{
                \string\crefname{misitex@formulatype@\themisitex@formulatypes}{#2}{#3}
                \string\Crefname{misitex@formulatype@\themisitex@formulatypes}{#2}{#3}
            }
            \creflabelformat@tofile{misitex@formulatype@\themisitex@formulatypes}
        }
        \oldequation
        \IfNoValueTF{#1}{}{
            \IfValueT{#2}{
                \expandafter\def\csname themisitex@formulatype@\themisitex@formulatypes\endcsname{#1}
                \addtocounter{equation}{-1}
            }
            \renewcommand{\theequation}{#1}
        }
        \IfValueT{#2}{
            \addtocounter{equation}{-1}
            \refstepcounter{misitex@formulatype@\themisitex@formulatypes}
        }
    }
}{
    \endoldequation
}

\makeatother

\begin{document}

    \begin{equation}[a]\label{test}
     a = b
    \end{equation}
    
    \begin{equation}[Ineq][Ineqs]\label{test2}
    a = b
    \end{equation}
    
    \begin{equation}[c]\label{test3}
    a = b
    \end{equation}
    
    \begin{equation}[Formula][Formulae]\label{test4}
    a = b
    \end{equation}
    
    \begin{equation}[Formula][Formulae]\label{test45}
    a = b
    \end{equation}
    
    \begin{equation}\label{test5}
    a = b
    \end{equation}
    
    
    \cref{test,test2,test3,test4,test5,test45}
    
\end{document}

输出: 在此处输入图片描述

笔记

如图所示,方程(2)(3)没有分组为Formulae (2) and (3)。然而,这是一个普遍的问题,可以在更简单的设置中重现。一种解决方法是\crefformat除了明确设置之外,还明确设置\crefname

相关内容