
Я не специалист по TeX/LaTeX, недавно я написал пакет, касающийся «проблем» и «решений», который должен отображаться в конце документа, однако он не ограничивается этими целями. Чтобы добиться такого поведения, среди прочих функций, я использовал пакет xkeyval
с большим количеством ключевых макросов и булевых ключей.
Я хочу предоставить лучшую версию и избавиться от десятков строк определений макросов клавиш и определений булевых клавиш, которые в принципе выглядят одинаково, но просто устанавливают некоторые флаги, заменив утомительный ввод кода LaTeX несколькими короткими командами, такими как
\GenerateBoolKey[true]{SomeKeys}{DummyBoolKey}
Это должно определить логический ключ, DummyBoolKey
принадлежащий семейству SomeKeys
, как если бы кто-то написал
\define@boolkey{SomeKeys}{DummyBoolKey}[true]{%
\ifKV@SomeKeys@DummyBoolKey%
%Do something if true%
\else%
%Do something different if false%
\fi%
}%
В xkeyval
документации (версия 2.6b) на странице 7 сказано, что макрос определен \ifKV@fam@key
как\newif
Ну, мне не удалось написать указанную выше команду и использовать макрос \ifKV
, вот минимальный (не)рабочий пример, который дает сбой во время компиляции с сообщением об ошибке
! Too many }'s.
Вот минимальный пример
\documentclass{minimal}
\usepackage{xkeyval}
\makeatletter
\providecommand{\GenerateBoolKey}[3][false]{%
\define@boolkey{#2}{#3}[#1]{%
\csname ifKV@#2@#3 \endcsname%
\typeout{true}% % Do something if true
\else%
\typeout{false}% % Do something different if false
\fi%
}% End of \define@boolkey
}% End of \providecommand
\makeatother
% Key Family is called SomeKeys
% Use a fake command for testing purposes
\providecommand{\DummyCommand}[1][false]{%
\setkeys{SomeKeys}{#1}%
% Do something useful inside this command...
}%
\begin{document}
\GenerateBoolKey{SomeKeys}{DummyBoolKey}%
\DummyCommand[DummyBoolKey=true]%
\end{document}
Как я могу предоставить \newif
команду «на лету» с моим кодом-«оберткой», чтобы обеспечить \ifKV
булеву проверку?
решение1
Похоже, это проблема с условным вложением. Лучшим подходом здесь, как мне кажется, будет принудительное расширение имени «спереди», чтобы у вас было определение, идентичное тому, которое вы получили бы «вручную».
\documentclass{article}
\usepackage{xkeyval}
\makeatletter
\providecommand{\GenerateBoolKey}[3][false]{%
\begingroup
\edef\x{\endgroup
\noexpand\define@boolkey{#2}{#3}[#1]{%
\expandafter\noexpand\csname ifKV@#2@#3\endcsname%
\noexpand\typeout{true}% % Do something if true
\noexpand\else%
\noexpand\typeout{false}% % Do something different if false
\noexpand\fi%
}% End of \define@boolkey
}% End of defintion of \x
\x
}% End of \providecommand
\makeatother
% Key Family is called SomeKeys
% Use a fake command for testing purposes
\providecommand{\DummyCommand}[1][false]{%
\setkeys{SomeKeys}{#1}%
% Do something useful inside this command...
}%
\begin{document}
\GenerateBoolKey{SomeKeys}{DummyBoolKey}%
\DummyCommand[DummyBoolKey=true]%
\end{document}
Это работает путем определения \x
внутри группы, которая закрывается, когда мыиспользовать \x
, и что заставляет расширять имя, не расширяя ничего другого (отсюда и много \noexpand
s).