Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to write a macro scaleblock which takes 2 arguments title and content. It can be called like:

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

And it is equivalent to the follows:

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

Does anyone know how to write this kind of macro (with \begin and \end)?

share|improve this question
3  
Use the command \newenvironment. Look here for previous answer. tex.stackexchange.com/questions/60079/… –  R. Schumacher Aug 19 '12 at 20:38
1  
I think \newenvironment is yourt friend. –  knut Aug 19 '12 at 20:39
1  
I don't think that \newenvironment can suffice. I believe that \NewEnviron from environ package is needed, as suggested in cannaerus'es answer. –  tohecz Aug 19 '12 at 21:22
    
@tohez since the body is to be boxed anyway using newenvironment and newenvironment with lrbox as in egreg's answer would have several benefits, especially allowing verb and friends to work –  David Carlisle Aug 19 '12 at 21:54
    
@DavidCarlisle Ok, another approach, but still, the solely link provided by R. Schumacher would not help, you need to add information "... and use lrbox. Other than that, I agree that egreg's solution is elegant and efficient! –  tohecz Aug 20 '12 at 6:00
add comment

3 Answers 3

up vote 10 down vote accepted

You can define an environment just as you would define a macro. Only instead of saying \newcommand\mycmd[1]{...#1...} you must write

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

Here the last two parameters say what should be put before and after the contents.

This means the first try would be to write

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

But this does not reflect the intended nesting of parameters and you actually only give the begin part of your environment, while the end part is the newline character in the fourth line.

So in your case it is probably better to first collect everything inside the environments body and then use it. This can be done with the environ package. It provides the command \NewEnviron where you can use \BODY to access those content. Assuming block is the one from beamer, you can do the following:

\usepackage{environ}
\NewEnviron{scaleblock}[1]{\begin{block}{\scalebox{0.8}{#1}}
  \scalebox{0.8}{\vbox{\BODY}}
\end{block}}
share|improve this answer
1  
I think it's a beamer block. –  percusse Aug 19 '12 at 20:45
1  
You cannot directly use # in the ending part of a \newenvironment. –  Gonzalo Medina Aug 19 '12 at 20:49
    
@GonzaloMedina: Ah, thank you for the correction. –  canaaerus Aug 19 '12 at 20:51
add comment

Here's a "pure LaTeX" version:

\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}}
share|improve this answer
add comment

You have greater control with keys:

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

This may be used as:

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

EDIT (2012/08/23)

The above code is based on a version of keyreader package that isn't on CTAN. Here is a solution based on pgfkeys.

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

enter image description here

share|improve this answer
    
Where do those macros \krdmakekeys and \krdusekeys come from? –  canaaerus Aug 22 '12 at 5:26
    
Oops, I am sorry. The package that authored the macros isn't on CTAN. I will change the code soon. –  Ahmed Musa Aug 24 '12 at 4:04
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.