我正在尝试定义一个参数命令:特别是代码
\definecoloredblock{example}{black}{bg=red!50!white,fg=black}{bg=red!30!white,fg=black}
应定义命令\example
、\@exampleA
和\@exampleB
。 (参见下面的代码)
\makeatletter
% definecolorblock <blockname> <titlecolor> <titlebg> <bodybg>
\def\definecoloredblock#1#2#3#4{%
\expandafter\def\csname @#1A\endcsname[##1]%
\expandafter{%
\block{\textcolor{#2}{##1}}%
}
\expandafter\def\csname @#1B\endcsname%
\expandafter{%
\vspace*{-3ex}%
\block{\vspace*{-5ex}}%
}
\expandafter\def\csname #1\endcsname%
{%
\expandafter\begingroup%
\expandafter{\setbeamercolor{block title}{#3}}%
\expandafter{\setbeamercolor{block body}{#4}}%
\expandafter\@ifnextchar\expandafter[%
\csname @#1A\endcsname%
\csname @#1B\endcsname%
% ]
}
\expandafter\def\csname end#1\endcsname%
\expandafter{%
\endblock%
\endgroup%
}
}
\makeatother
\definecoloredblock{example}{black}{bg=red!50!white,fg=black}{bg=red!30!white,fg=black}
这段代码没有显示任何错误,但是当我尝试使用它时,例如:
\documentclass[10pt]{beamer}
\begin{document}
\begin{frame}{Frame title}
\begin{example}[Fake example]
Some text
\end{example}
\end{frame}
\end{document}
我收到错误
! Use of \@exampleB doesn't match its definition.
\beamer@doifinframe ...me title} \begin {example}[
Fake example] Some
text...
l.44 \end{frame}
\csname
我该如何解决我的问题?我猜这与之后有关\@ifnextchar
。
请参阅 egreg 的答案以了解解决方案。
答案1
您对 的使用\expandafter
大部分是错误的。请注意,定义期间不会扩展任何内容。
有\expandafter\def\csname...\endcsname
和 for的简写形式\csname...\endcsname
,更易于使用。
\documentclass{article}
\makeatletter
% definecolorblock <blockname> <titlecolor> <titlebg> <bodybg>
\def\definecoloredblock#1#2#3#4{%
\@namedef{@#1A}[##1]{%
\block{\textcolor{#2}{##1}}%
}%
\@namedef{@#1B}{%
\vspace*{-3ex}%
\block{\vspace*{-5ex}}%
}
\@namedef{#1}{%
\begingroup
\setbeamercolor{block title}{#3}%
\setbeamercolor{block body}{#4}%
\@ifnextchar[{\@nameuse{@#1A}}{\@nameuse{@#1B}}%]
}
\@namedef{end#1}{%
\endblock
\endgroup
}%
}
\makeatother
\definecoloredblock{example}{black}{bg=red!50!white,fg=black}{bg=red!30!white,fg=black}
\makeatletter
\show\example
\show\@exampleA
\show\@exampleB
\show\endexample
\makeatother
\stop
以下是控制台中的内容
> \example=macro:
->\begingroup \setbeamercolor {block title}{bg=red!50!white,fg=black}\setbeamer
color {block body}{bg=red!30!white,fg=black}\@ifnextchar [{\@nameuse {@exampleA
}}{\@nameuse {@exampleB}}.
l.29 \show\example
?
> \@exampleA=macro:
[#1]->\block {\textcolor {black}{#1}}.
l.30 \show\@exampleA
?
> \@exampleB=macro:
->\vspace *{-3ex}\block {\vspace *{-5ex}}.
l.31 \show\@exampleB
?
> \endexample=macro:
->\endblock \endgroup .
l.32 \show\endexample
?
)
No pages of output.
但是,它对于工作来说更容易使用xparse
。请注意,我更改了定义环境的名称,因为example
已经在中定义了beamer
。使用\def
会面临多种风险。
\documentclass{beamer}
\usepackage{xparse}
\NewDocumentCommand{\definecoloredblock}{mmmm}{%
\NewDocumentEnvironment{#1}{o}
{% start code
\setbeamercolor{block title}{#3}%
\setbeamercolor{block body}{#4}%
\IfNoValueTF{##1}
{\vspace*{-3ex}\block{\vspace*{-5ex}}}% no optional argument
{\block{\textcolor{#2}{##1}}}%
}
{% end code
\endblock
}
}
\definecoloredblock
{myexample}
{black}
{bg=red!50!white,fg=black}
{bg=red!30!white,fg=black}
\begin{document}
\begin{frame}
Text
\begin{myexample}
Text in the block
\end{myexample}
Text
\begin{myexample}[Title]
Text in the block
\end{myexample}
\end{frame}
\end{document}
答案2
尽可能猜测其含义,
\documentclass[10pt]{beamer}
\begin{document}
\makeatletter
\def\definecoloredblock#1{%
\expandafter\@definecoloredblock
\csname#1\expandafter\endcsname
\csname end#1\expandafter\endcsname
\csname @#1A\expandafter\endcsname
\csname @#1B\endcsname}
\def\@definecoloredblock#1#2#3#4#5#6#7{%
\def#3[##1]{%
\block{\textcolor{#5}{##1}}%
}%
\def#4{%
\vspace*{-3ex}%
\block{\vspace*{-5ex}}%
}%
\def#1{%
\setbeamercolor{block title}{#6}%
\setbeamercolor{block body}{#7}%
\@ifnextchar[#3#4%
%]
}%
\def#2{%
\endblock
}%
}
\definecoloredblock{example}{black}{bg=red!50!white,fg=black}{bg=red!30!white,fg=black}
\makeatother
\begin{frame}{Frame title}
\begin{example}[Fake example]
Some text
\end{example}
\end{frame}
\end{document}