循环/每个语句中更复杂的键定义

循环/每个语句中更复杂的键定义

在编写带有键值接口的包时,我有很多重复的键定义。自然,人们想用循环来表达这些定义。当定义包含更复杂的东西时\PassOptionsToPackage,事情就会变得混乱。混乱程度取决于用于循环的包。etoolbox抱怨很多,forarray但不是那么多。的最小工作示例forarray

    \NeedsTeXFormat{LaTeX2e}[1994/12/01]
    \ProvidesPackage{package}
    [2012/09/18 Example]
    \RequirePackage{keyreader}
    \RequirePackage{forarray}
    \DeclareOptionX*{%
    \PackageWarningNoLine{}{Cant understand option(s): \CurrentOption}%
    }

    \CommandForEach{,}{%
    \krdDeclareOption{#1}{\PassOptionsToPackage{##1}{#1}}%
    }%
    {todonotes}

    \krdProcessOptions

这是包,latex文件是

    \documentclass{article}

    \usepackage[todonotes=shadow]{package}
    \usepackage{todonotes}

    \begin{document}
    \todo{2 do}
    \end{document}

这会产生警告

    ! LaTeX Error: Missing \begin{document}.

    See the LaTeX manual or LaTeX Companion for explanation.
    Type  H <return>  for immediate help.
     ...                                              

    l.13 {todonotes}

    ? 

没有造成更大的伤害,紧迫返回结束。只有待办事项文档中的问题仍然存在,但待办事项框有一个漂亮的阴影。这里出了什么问题?

答案1

解决方案\comma@parse使用kvsetkeys

\NeedsTeXFormat{LaTeX2e}[1994/12/01]
\ProvidesPackage{package}[2012/09/18 Example]
\RequirePackage{keyreader}
\RequirePackage{kvsetkeys}
\DeclareOptionX*{%
  \PackageWarningNoLine{}{Cant understand option(s): \CurrentOption}%
}
\def\TempDefOption#1{%
  \krdDeclareOption{#1}{\PassOptionsToPackage{##1}{#1}}%
}
\comma@parse{todonotes}\TempDefOption

\krdProcessOptions

答案2

另一个(或者更准确地说,相同的)解决方案是etoolbox

\NeedsTeXFormat{LaTeX2e}[1994/12/01]
\ProvidesPackage{package}
[2012/09/18 Example]
\RequirePackage{keyreader}
\RequirePackage{etoolbox}

\renewcommand*{\do}[1]{%
  \krdDeclareOption{#1}{\PassOptionsToPackage{##1}{#1}}%
}

\docsvlist{todonotes}

\krdProcessOptions

当我测试 Heikos 解决方案时,我意识到之前使用 时etoolbox,我只是在重新定义 时忘记了右花括号\do。抱歉给您带来麻烦,我仍然希望它有用。

答案3

你真正需要的是类似下面的内容。你不必加载电子工具箱或任何用于处理列表的包。键盘阅读器包有自己的列表处理器。

\NeedsTeXFormat{LaTeX2e}[2011/06/27]
\ProvidesPackage{ulysis}[2012/09/18 Example package]
\RequirePackage{keyreader}
\krdDeclareOption*{%
  \PackageWarningNoLine{ulysis}{Unknown option `\CurrentOption' ignored}%
}
\newif\ifuly@verbose
\krdDeclareOption{verbose}[true]{\@nameuse{uly@verbose#1}}

% Declare options with default values that will be used when the options
% are called without user values:
\protected\def\DeclarePassedOptions#1{%
  \edef\uly@tempa{\unexpanded{#1}}%
  \krdkvnormalize\uly@tempa
  % The looping macro used here is \krdfor, but the list has to be first normalized.
  \def\do##1{%
    \def\@do####1=####2=####3\@nil{%
      \krdDeclareOption{####1}[####2]{%
        \PassOptionsToPackage{########1}{####1}%
      }%
      % To avoid passing options to eventually unloaded packages:
      \AtBeginDocument{%
        \ifuly@verbose
          \krdifcsndef{ver@####1.sty}{}{%
            \@latexerr{Package '####1' wasn't loaded}
              {There are specified but unloaded packages}%
          }%
        \fi
      }%
    }%
    \@do##1==\@nil
  }%
  \expandafter\krdfor\expandafter{\uly@tempa}%
}
\DeclarePassedOptions{%
  todonotes={backgroundcolor=gray!15},xcolor=svgnames
}
\krdProcessOptions*

\endinput

测试文档:

\documentclass[12pt]{article}
\usepackage[
  verbose,
  todonotes={shadow,linecolor=red,backgroundcolor=white},
  xcolor=dvipsnames
]{ulysis}
\usepackage{todonotes}
\usepackage{xcolor}

\begin{document}
\textcolor{MidnightBlue}{%
  \todo{{\bf\large 1 do}}
}

\textcolor{ForestGreen}{%
  \todo{\bf\large 2 do}
}
\end{document}

相关内容