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

  • \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 Oct 2 '15 at 12:43
  • @DavidCarlisle Thanks for that reminder. Fixed. – Steven B. Segletes Oct 2 '15 at 12:49
  • Exactly what I wanted! Great! – FK82 Oct 2 '15 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}
  • I explain why I don't do this in the comment above. – FK82 Oct 2 '15 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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