我希望创建一个frame级别的环境,也就是基于frame的自定义环境。它可以使用户比较方便地调节行距,而不是每次都调用\begin{spacing}{<arg>}...\end{spacing}
之类的代码,同时它要接受一些参数,并将其传递给frame环境,考虑到frame环境是一个脆弱的环境,我的尝试总是失败。
\documentclass{beamer}
\usepackage{setspace}
%\newenvironment{myframe}[2][1.5]
% {\begin{frame}[#2]\begin{spacing}{#1}}
% {\end{spacing}\end{frame}}
\begin{document}
% \begin{myframe}
% Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum.
% \end{myframe}
\begin{frame}
\begin{spacing}{1.5}
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
\end{spacing}
\end{frame}
\end{document}
\documentclass{beamer}
\usepackage{lipsum}
\usepackage{setspace}
\newenvironment{myframe}[2][1.5]
{%
\begin{frame}[#2]
\setstretch{#1}
}%
{%
\end{frame}
}%
\begin{document}
\begin{frame}
\lipsum[1][1-5]
\end{frame}
\begin{myframe}[3]{t}
\lipsum[1][1-5]
\end{myframe}
\begin{myframe}[2]{c}
\lipsum[1][1-5]
\end{myframe}
\begin{frame}
\lipsum[1][1-5]
\end{frame}
\end{document}
同时它要接受一些参数,并将其传递给frame环境,考虑到frame环境是一个脆弱的环境,我的尝试总是失败。
当提到「总是失败」时,最好贴一下报错信息,这样更容易让这个问题被别人搜索到,也更完整。下面看我的几个探索。
你的问题和参数有关吗?并不是。下面的例子中,frame
没问题;但myframe
有问题。
\documentclass{beamer}
\usepackage{lipsum}
\usepackage{setspace}
\newenvironment{myframe}
{%
\begin{frame}
\begin{spacing}{2}
}%
{%
\end{spacing}
\end{frame}
}%
\begin{document}
\begin{frame}
\begin{spacing}{2}
\lipsum[1][1-5]
\end{spacing}
\end{frame}
\begin{myframe}
\lipsum[1][1-5]
\end{myframe}
\end{document}
报错信息:
! File ended while scanning use of \beamer@collect@@body.
<inserted text>
\par
<*> mwe
?
这个问题和beamer
提供的frame
环境有关吗?换成minipage
看看(?)
\documentclass{beamer}
\usepackage{lipsum}
\usepackage{setspace}
\newenvironment{myframe}
{%
\begin{minipage}{\textwidth}
\begin{spacing}{2}
}%
{%
\end{spacing}
\end{minipage}
}%
\begin{document}
\begin{minipage}{\textwidth}
\begin{spacing}{2}
\lipsum[1][1-5]
\end{spacing}
\end{minipage}
\begin{myframe}
\lipsum[1][1-5]
\end{myframe}
\end{document}
并没有报错,所以这是"非常独特的",当且仅当同时使用frame
内嵌spacing
才会触发错误。
最后从这个链接来看,用\setstretch
可以规避这一问题,所以有了workaround...
翻到一个神奇的结论:
由于beamer
实在是太坏了。egreg说:
Moral of the story
Don't usesetspace
withbeamer
😀.
x-post
实际上,这里给出的
myframe
环境的两个参数#1
和#2
都是必选的非空参数。并不能使用默认参数和空参数。鉴于此,我决定舍弃这个做法。@u101077
第一个不是必选的。
对于
#2
,你希望填入的是什么内容呢?我不太理解\begin{frame}[xxxx]
这里要实现什么...如果你需要更精细的参数类型控制,你也许应该使用
\NewDocumentEnvironment
这句多少有些伤人...
在x-post里:
永远不要在
beamer
里用setspace
!!!永远不要把
frame
封装到另一个命令/环境里去!!!@u70550 通常来说 ,frame环境无需添加可选参数,只有在必要的时候才会添加可选参数。而这个由
\newenvironment
定义的myframe环境,希望能够继承该原则。而myframe的最简写法是:
\begin{myframe}{<#2>}...\end{myframe}
。即使行距采取默认值,也不能丢弃掉参数#2
,例如,你得写个{c}
什么的,充当必要的必选参数。在违背了在通常情况下无需可选参数,而只在必要的时候才添加可选参数的原则。这是实际上的冗余代码。如果使用
\NewDocumentEnvironment
来创建O{1.5}O{}+b
格式的环境,那么将不能舍弃\begin{myframe}[#1][#2]...\end{myframe}
中的任何一个可选参数,且参数不能为空,这反倒成为了事实上的必选参数。本提问创建的需求,本身就不太合理,所以舍弃掉该做法我认为也不是不可原谅。虽然参考xpost后的例子很好地开始工作:
但为了避免出现不可预料的复杂情况,还是决定考虑定义一个固定格式的myframe环境:
@u101077
确实,你这样几乎是想要两个连续的「可选参数」...这是不被推荐的,也是你要把两个环境的参数混合到一个新环境并且同时「希望能够继承该原则」而导致的...