
Me gustaría escribir una macro scaleblock
que tome 2 argumentos title
y 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 \begin
y \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 environ
paquete. Proporciona el comando \NewEnviron
que puede utilizar \BODY
para acceder a ese contenido. Suponiendo block
que 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}