Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

While writing a package with a key-value interface, I had a lot of repetitive key definitions. Naturally, one would like to express these definitions with a loop. When the definition contains something more complicated like \PassOptionsToPackage, things get messy. The degree of messiness depends on the package used for the loops. etoolbox complains a lot, forarray not so much. Minimal working example for 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

This is the package, and the latex file is

    \documentclass{article}

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

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

This produces the warning

    ! LaTeX Error: Missing \begin{document}.

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

    l.13 {todonotes}

    ? 

No greater harm done, pressing return brings it to the end. Only the todonotes in the documents remains of the trouble, but the todo box has a nice shadow. What is wrong here?

share|improve this question
    
I don't understand \CommandForEach, you have to use a command as one token as second argument and the list element in the third argument need an additional pair of curly braces. There are better ways to parse comma separated lists. –  Heiko Oberdiek Sep 18 '12 at 19:14
    
@HeikoOberdiek So, the crucial thing is this " a command as one token as second argument"? –  Percival Ulysses Sep 19 '12 at 11:18

3 Answers 3

Solution using \comma@parse of 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
share|improve this answer
up vote 3 down vote accepted

Another (or, more precisely, the same) solution with 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

As I tested Heikos solution I realized that earlier with etoolbox, I just had forgotten a closing curly bracket while redefining \do. Sorry for the hassle, I still hope it was useful.

share|improve this answer

What you actually need is something like the following. You don't have to load etoolbox or any package for processing a list. The keyreader package has its own list processors.

\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

Test document:

\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}
share|improve this answer
1  
Thank you for your answer. When you compare it to Heikos or the one with etoolbox, it seems a bit complicated for someone with an only rudimentary understanding of TeX. But if you would provide a high level interface for loops/for eachs that hides your code in keyreader, i'd be happy to use it. –  Percival Ulysses Sep 21 '12 at 22:33
    
P.S. The most efficient way to communicate with the author of todonotes would, IMO, be the use of his email address. He provided it in the documentation. Just saying ;-) –  Percival Ulysses Sep 21 '12 at 22:40
    
OK, I have removed the recommendations for todonotes package. –  Ahmed Musa Sep 21 '12 at 22:59
    
The most important thing to me is that you can sort this out with Hendrik. An email just seems directer than a note left on a random website. Further, my documentation of keyreader does not mention \krdlistloop. I have other questions concerning keyreader, the most pressing concerns choicekeys. I think I first should update the TeX installation before dropping it here. Do you recommend reading keyreaders source as second step? –  Percival Ulysses Sep 21 '12 at 23:27
    
I am sorry, I am poor with - acutally, I lack time for - documentation. WRT choice keys, you can send an email to me. –  Ahmed Musa Sep 21 '12 at 23:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.