编写一个用 \begin 和 \end 调用的宏

编写一个用 \begin 和 \end 调用的宏

我想编写一个scaleblock带有 2 个参数title和 的宏content。可以像这样调用它:

\begin{scaleblock}{a_title}
   a_content
\end{scaleblock}

它等效于以下内容:

\begin{block}{\scalebox{0.8}{a_title}}
  \scalebox{0.8}{\vbox{a_content}}
\end{block}

有人知道如何编写这种宏(使用\begin\end)吗?

答案1

你可以像定义宏一样定义环境。只不过\newcommand\mycmd[1]{...#1...}你不必写成

\newenvironment{myenv}[1]{Begin...#1...}{End}

这里的最后两个参数说明应该在内容之前和之后放置什么。

这意味着第一次尝试是写

\newenvironment{scaleblock}[1]{\begin{block}{\scalebox{0.4}{#1}}
    \scalebox{0.4}{\vbox{}%
  {}}
\end{block}}

但这并未反映出参数的预期嵌套,实际上您只给出了环境的开始部分,而结束部分是第四行的换行符。

因此,对于您来说,最好先收集环境主体内的所有内容,然后使用它。这可以通过包来完成。它提供了可用于访问这些内容的environ命令。假设是来自的命令,您可以执行以下操作:\NewEnviron\BODYblockbeamer

\usepackage{environ}
\NewEnviron{scaleblock}[1]{\begin{block}{\scalebox{0.8}{#1}}
  \scalebox{0.8}{\vbox{\BODY}}
\end{block}}

答案2

这是一个“纯 LaTeX”版本:

\newsavebox{\scaleblockbox}
\newenvironment{scaleblock}[1]
  {\begin{block}{\scalebox{0.8}{#1}
   \begin{lrbox}{\scaleblockbox}
   \begin{minipage}{\textwidth}}
  {\end{minipage}
   \end{lrbox}
   \scalebox{0.8}{\usebox{\scaleblockbox}}
   \end{block}}

答案3

您可以使用按键进行更好的控制:

\krdmakekeys[
  prefix=KV,
  family=collectbody,
  hp=mp,
  initialize,
  endlinechar=-1
]{%
  cmd/title//,
  zcmd/title scale/1,
  zcmd/body scale/1,
  cmd/width/\textwidth,
  zcmd/title text style//,
  zcmd/body text style//,
  cmd/action//
}

\newsavebox{\boxbody}
\newenvironment{collectbody}[1][]{%
  \krdusekeys[prefix=KV,family=collectbody]{#1}%
  \ifx\mptitle\@empty\else\krdafterfi
    \begin{center}%
    \scalebox{\mptitlescale}{\mptitletextstyle\mptitle}%
    \end{center}%
  \fi
  \begin{lrbox}{\boxbody}%
  \begin{minipage}{\mpwidth}%
  \mpbodytextstyle\mpaction
}{%
  \end{minipage}%
  \end{lrbox}%
  \scalebox{\mpbodyscale}{\usebox{\boxbody}}%
}

这可以用作:

\documentclass{article}
\usepackage[dvipsname]{xcolor}
\usepackage{graphicx}
\usepackage{lipsum}
\begin{collectbody}[
  title=Example of collect body,
  title scale=.8,
  title text style=\ttfamily\color{red}
]
\lipsum[1]
\end{collectbody}
\end{document} 

编辑(2012/08/23)

上述代码基于键盘阅读器不在 CTAN 上的软件包。以下是基于鍵盤

\documentclass{standalone}
\usepackage[dvipsname]{xcolor}
\usepackage{graphicx}
\usepackage{pgfkeys}
\usepackage{lipsum}
\makeatletter
\def\pgfkeysafterfi#1\fi{\fi#1}
\def\pgfkeysafterelse@i#1\else#2\fi{\fi#1}
\def\pgfkeysifkeydefined#1#2#3{%
  \ifcsname pgfk@#1/.@cmd\endcsname
    \pgfkeysafterelse@i{#2}\else\pgfkeysafterfi{#3}\fi
}
\pgfkeys{
  /handlers/.protected estore in/.code=
    \pgfkeys{
      \pgfkeyscurrentpath/.code=\protected@edef#1{##1}
    },
  /handlers/.default and initial/.code=
    \pgfkeys{
      \pgfkeyscurrentpath/.initial=#1,
      \pgfkeyscurrentpath/.default=#1,
      \pgfkeyscurrentpath=#1%
    },
  /handlers/.new key/.code 2 args=
    \pgfkeysifkeydefined{\pgfkeyscurrentpath}{%
      \@latexerr{Key '\pgfkeyscurrentpath' already exists}\@ehd
    }{%
      \pgfkeys{
        \pgfkeyscurrentpath/.store in=#1,
        \pgfkeyscurrentpath/.default and initial=#2%
      }%
    }%
}
\pgfkeys{%
  /collectbody/.is family,/collectbody/.cd,
  title/.new key=\mptitle\@empty,
  title scale/.new key=\mptitlescale{1},
  body scale/.new key=\mpbodyscale{1},
  width/.new key=\mpwidth\textwidth,
  title text style/.new key=\mptitletextstyle\@empty,
  body text style/.new key=\mpbodytextstyle\@empty,
  action/.new key=\mpaction\@empty
}
\def\@@empty{\@empty}
\newsavebox{\boxbody}
\newenvironment{collectbody}[1][]{%
  \pgfkeys{/collectbody/.cd,#1}%
  \ifx\mptitle\@@empty\else\pgfkeysafterfi
    \begin{center}%
    \scalebox{\mptitlescale}{\mptitletextstyle\mptitle}%
    \end{center}%
  \fi
  \begin{lrbox}{\boxbody}%
  \begin{minipage}{\mpwidth}%
  \mpbodytextstyle\mpaction
}{%
  \end{minipage}%
  \end{lrbox}%
  \scalebox{\mpbodyscale}{\usebox{\boxbody}}%
}
\makeatother

% Example:
\begin{document}
\begin{collectbody}[
  title=Example of \texttt{collect body} environment,
  title scale=.8,
  title text style=\scshape\color{red}
]
\lipsum[1]
\end{collectbody}
\end{document}

在此处输入图片描述

相关内容