Escribe una macro que se llame con \begin y \end

Escribe una macro que se llame con \begin y \end

Me gustaría escribir una macro scaleblockque tome 2 argumentos titley content. Se puede llamar así:

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

Y es equivalente a lo siguiente:

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

¿Alguien sabe cómo escribir este tipo de macro (con \beginy \end)?

Respuesta1

Puede definir un entorno tal como definiría una macro. Solo que en lugar de decir \newcommand\mycmd[1]{...#1...}debes escribir

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

Aquí los dos últimos parámetros dicen qué se debe poner antes y después del contenido.

Esto significa que el primer intento sería escribir

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

Pero esto no refleja el anidamiento de parámetros previsto y en realidad solo proporciona la parte inicial de su entorno, mientras que la parte final es el carácter de nueva línea en la cuarta línea.

Entonces, en su caso, probablemente sea mejor recolectar primero todo lo que hay dentro del cuerpo del entorno y luego usarlo. Esto se puede hacer con el environpaquete. Proporciona el comando \NewEnvironque puede utilizar \BODYpara acceder a ese contenido. Suponiendo blockque sea el de beamer, puedes hacer lo siguiente:

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

Respuesta2

Aquí hay una versión "látex puro":

\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}}

Respuesta3

Tienes mayor control con las teclas:

\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}}%
}

Esto puede usarse como:

\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} 

EDITAR (23/08/2012)

El código anterior está basado en una versión delector de clavespaquete que no está en CTAN. Aquí hay una solución basada enclavespgf.

\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}

ingrese la descripción de la imagen aquí

información relacionada