Sign up ×
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 want to create a custom Definition environment. The environment should use some local commands to declare logical parts of the definition (e.g. assumptions using a command Let). The definition text should be plain text (not wrapped in a command).

I want to store and process all information in the end group of the environment (e.g. for dynamic formatting). For the definition text, I'm using the savebox command within the begin group of the environment.

My problem is: when I simply use \usebox in the environment's end group the box overflows and some content is cut off. How can I prevent or work around this?


MWE:

\documentclass[a4paper,11pt]{article}

\usepackage{etoolbox}
\usepackage{lipsum}

\newcommand{\DefinitionLet}[3][]{%
}
\newsavebox{\DefinitionContentBox}

\newenvironment{Definition}[1][]{%
    \let\Let\DefinitionLet%
    \def\DefinitionName{#1}
    \savebox{\DefinitionContentBox}\bgroup%
}{%
    \egroup%
    \noindent (Definition) \DefinitionName\\
    \newline\usebox{\DefinitionContentBox}
}

\begin{document}
\begin{Definition}[Definition A]
\Let{$A$}{some set}
\Let{$a$}{element of $A$}
\lipsum[100]
\end{Definition}
\end{document}
share|improve this question
1  
Using a box will make dynamic formatting impossible (unless you \unbox instead of \usebox). I think you're interested to the environ package. –  egreg yesterday
    
\unbox is an undefined command. Do I need a package? –  FK82 yesterday
    
Sorry, \unhbox; but you should make clearer what you have in mind: I don't see any real advantage in storing the environment's content, as the typesetting parameters can be set in the “begin” part. By the way, note that \savebox{<box bin>}\bgroup is not really supported. –  egreg yesterday
1  
\savebox{\DefinitionContentBox}\bgroup% is absolutely not supported syntax!!! Use the lrbox environment. –  David Carlisle yesterday
    
@egreg Basically I want to be able to rearrange the logical parts of the definition (e.g. assumptions and text). More specifically I want to display the contents of the Let commands in a list (above or below the definition text). –  FK82 yesterday

3 Answers 3

up vote 3 down vote accepted

Here's an \unhbox approach as suggested by egreg in the comments. What \unhbox allows is for formatting to be applied around the formerly boxed material. So, for instance, here, I place the content in an \fboxed \parbox. I could just as easily settled for an \unhbox\DefinitionContentBox which would just set the boxed content with the prevailing margin formatting.

EDITED to use lrbox instead of \hbox\bgroup...\egroup (thanks, David).

\documentclass[a4paper,11pt]{article}

\usepackage{etoolbox}
\usepackage{lipsum}

\newcommand{\DefinitionLet}[3][]{%
}
\newsavebox{\DefinitionContentBox}

\newenvironment{Definition}[1][]{%
    \let\Let\DefinitionLet%
    \def\DefinitionName{#1}
    \begin{lrbox}{\DefinitionContentBox}%
}{%
    \end{lrbox}\noindent (Definition) \DefinitionName\\
    \newline\fbox{%
    \parbox{\dimexpr\textwidth-2\fboxsep-2\fboxrule}{\unhbox\DefinitionContentBox}}
    \par\bigskip
}
\begin{document}
\begin{Definition}[Definition A]
\Let{$A$}{some set}
\Let{$a$}{element of $A$}
\lipsum[100]
\end{Definition}
\lipsum[2]
\end{document}

enter image description here

share|improve this answer
    
\setbox0=\hbox\bgroup% is not supported syntax and will do completely the wrong thing if colour is being used. lrbox environment was introduced for this use. –  David Carlisle yesterday
    
@DavidCarlisle Thanks for that reminder. Fixed. –  Steven B. Segletes yesterday
    
Exactly what I wanted! Great! –  FK82 yesterday

You should use \unhbox and not \usebox: the difference is that the latter delivers the contents of the box, rather than the box itself. However, this is not the method I recommend, unless you have verbatim material in the body of the environment.

I would use environ for this purpose:

\documentclass[a4paper,11pt]{article}

\usepackage{environ}
\usepackage{lipsum}

\newcommand{\DefinitionLet}[3][]{}

\NewEnviron{Definition}[1][]{%
  \let\Let\DefinitionLet 
  \def\DefinitionName{#1}%
  \par\bigskip\noindent (Definition) \DefinitionName\\*
  \fbox{%
    \parbox{\dimexpr\textwidth-2\fboxsep-2\fboxrule}{\BODY}%
  }%
  \par\bigskip
}

\begin{document}

\lipsum[200]

\begin{Definition}[Definition A]
\Let{$A$}{some set}
\Let{$a$}{element of $A$}
\lipsum[100]
\end{Definition}

\lipsum[2]

\end{document}

enter image description here

Limitations of the \unhbox approach

Language attributes are ignored, in the sense that setting \language=<number> (via \foreignlanguage or similar method) in the environment will not work.

Limitations of the environ approach

You can't include verbatim material in the body of the environment.

share|improve this answer

Saveboxes are LR boxes (like \mbox or \fbox) whose contents will not be broken across lines. Text to be typeset in paragraph mode must be placed into \parboxes or minipages which know (from their required arguments) how long lines will finally be in order to be able to place line breaks properly.

Why don't you just say:

\documentclass[a4paper,11pt]{article}

\usepackage{etoolbox}
\usepackage{lipsum}

\newcommand{\DefinitionLet}[3][]{%
}

\newenvironment{Definition}[1][]{%
    \let\Let\DefinitionLet%
    \def\DefinitionName{#1}
    \noindent (Definition) \DefinitionName\\
    \newline
}{}%

\begin{document}
\begin{Definition}[Definition A]
\Let{$A$}{some set}
\Let{$a$}{element of $A$}
\lipsum[100]
\end{Definition}
\end{document}
share|improve this answer
    
I explain why I don't do this in the comment above. –  FK82 yesterday

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.