我想创建一个自定义定义环境。该环境应使用一些本地命令来声明定义的逻辑部分(例如使用命令的假设Let
)。定义文本应为纯文本(不包含在命令中)。
我想在环境的结束组中存储和处理所有信息(例如动态格式化)。对于定义文本,我在环境的开始组中使用 savebox 命令。
我的问题是:当我简单地\usebox
在环境的结束组中使用时,框会溢出并且一些内容会被截断。我该如何防止或解决这个问题?
梅威瑟:
\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
这是\unhbox
egreg 在评论中建议的一种方法。它\unhbox
允许在以前被框起来的材料周围应用格式。因此,例如,在这里,我将内容放在 ed 中\fbox
。\parbox
我可以轻松地使用一个,\unhbox\DefinitionContentBox
它只会使用现行的边距格式设置框起来的内容。
已编辑以lrbox
代替\hbox\bgroup...\egroup
(感谢大卫)。
\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}
答案2
您应该使用\unhbox
而不是\usebox
:区别在于后者传递的是盒子的内容,而不是盒子本身。但是,这不是我推荐的方法,除非您在环境主体中有逐字材料。
我将用于environ
此目的:
\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}
\unhbox
该方法的局限性
语言属性被忽略,即在环境中设置\language=<number>
(通过或类似方法)将不起作用。\foreignlanguage
environ
该方法的局限性
您不能在环境主体中包含逐字材料。
答案3
保存框是 LR 框(如\mbox
或\fbox
),其内容不会跨行。以段落模式排版的文本必须放入\parboxes
或中minipages
,它们知道(根据其必需参数)最终行的长度,以便能够正确放置换行符。
你为什么不直接说:
\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}