4

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}
5
  • 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
    Commented Oct 2, 2015 at 12:11
  • \unbox is an undefined command. Do I need a package?
    – FK82
    Commented Oct 2, 2015 at 12:21
  • 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
    Commented Oct 2, 2015 at 12:23
  • 1
    \savebox{\DefinitionContentBox}\bgroup% is absolutely not supported syntax!!! Use the lrbox environment. Commented Oct 2, 2015 at 12:40
  • @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
    Commented Oct 2, 2015 at 12:56

3 Answers 3

3

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

3
  • \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. Commented Oct 2, 2015 at 12:43
  • @DavidCarlisle Thanks for that reminder. Fixed. Commented Oct 2, 2015 at 12:49
  • Exactly what I wanted! Great!
    – FK82
    Commented Oct 2, 2015 at 12:59
2

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.

1

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}
1
  • I explain why I don't do this in the comment above.
    – FK82
    Commented Oct 2, 2015 at 12:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .