我定義了一個新環境,它使用 fbox 在小型頁面周圍繪製一種答案框。這個環境還在答案框上方放置了一些文字。
這是一個最小的工作範例:
\documentclass{article}
\usepackage{listings}
\newsavebox{\mybox}
\newenvironment{ansbox}[1]{Write answer in the box:\newline
\begin{lrbox}{\mybox}\begin{minipage}[t][#1]{\linewidth}}
{\vfill\hfill\end{minipage}\end{lrbox}\fbox{\usebox{\mybox}}}
\setlength{\parskip}{\baselineskip}
\setlength{\parindent}{0ex}
\begin{document}
Description of problem.
\begin{ansbox}{2in}
%empty box
\end{ansbox}
What is your name?
\begin{ansbox}{2in}
My name is
\end{ansbox}
Implement a factorial function.
\begin{ansbox}{2in}
\begin{lstlisting}
def factorial(n):
\end{lstlisting}
\end{ansbox}
\end{document}
為了方便起見,我附上第一頁的螢幕截圖:
如您所看到的,當框為空時,或當它立即以 lstlisting 環境開始時,會有一個垂直空間。我嘗試四處搜索,但不知道如何添加這個空間或如何刪除它。
另外,當「標題」文字進入下一頁時,如何將其與框保持在一起?
答案1
問題在於如何確保盒子的寬度;在這種情況下,最好添加與框一樣寬的零高度規則。您還需要修剪一些寬度(對於\fboxsep
和\fboxrule
)。
\documentclass{article}
\usepackage{listings}
\newsavebox{\mybox}
\newenvironment{ansbox}[1]
{%
Write answer in the box:\\*
\begin{lrbox}{\mybox}
\begin{minipage}[t][#1]{\dimexpr\linewidth-2\fboxsep-2\fboxrule}
\hrule width \textwidth height 0pt
}
{\end{minipage}\end{lrbox}\fbox{\usebox{\mybox}}}
\setlength{\parskip}{\baselineskip}
\setlength{\parindent}{0ex}
\begin{document}
Description of problem.
\begin{ansbox}{1.5in}
%empty box
\end{ansbox}
What is your name?
\begin{ansbox}{1.5in}
My name is
\end{ansbox}
Implement a factorial function.
\begin{ansbox}{1.5in}
\begin{lstlisting}
def factorial(n):
\end{lstlisting}
\end{ansbox}
\end{document}
你的程式碼,\begin{ansbox}{1.5in}
變成了
\begin{minipage}[t][1.5in]{\linewidth}
<environment's contents>
\vfill\hfill
\end{minipage}
當環境主體為空時,這使得
\vfill
\hfill
\par\vfil
(添加最後一個標記是因為您想要一個[t]
小型頁面;\vfil
被取消\vfill
)。盒子的參考點由 決定\vfill
。另一方面,對於非空內容,你有
My name is
\vfill
\hfill
\vfil
參考點位於頂部段落的基線處;現在盒子的高度將被測量為 M plus \fboxsep
plus的高度\fboxrule
;這就是 6.83331+3+0.4=10.23331 點。這顯然超出了閾值,因此 TeX 將\lineskip
在「在框中寫入答案:」行和框之間使用。在前一種情況下,框的高度僅為 3.4pt,您看到的間距為(因為上面的線沒有深度)\baselineskip
減去 3.4pt。
在我的解決方案中,盒子的高度始終為 3.4pt,因為零高度規則決定了參考點。
答案2
迷你頁通常遵循框間距規則(\lineskip
而不是\baselineskip
),所以我喜歡\strut
在邊框處添加 s。
除了所指出的問題之外,還有其他問題。坦白說,我對程式碼的運行感到驚訝。
首先,您不應在環境定義中使用 \begin 和 \end,因為它們會亂序擴展。這種事情最好使用 environ 套件來完成。
其次,lstlisting 不喜歡位於任何東西的內部(除了 \hbox)。該軟體包有自己的環境軟體。
如果您想要防止文字和方塊之間出現分頁符,可以使用 needspace 套件。
\documentclass{article}
\usepackage{listings}
\usepackage{environ}
\newsavebox{\mybox}
\NewEnviron{ansbox}[1]{Write answer in the box:\strut\newline
\fbox{\begin{minipage}[t][#1][s]{\dimexpr \linewidth-2\fboxsep-2\fboxrule}
\strut\BODY\vfill\hfill
\end{minipage}}}
\lstnewenvironment{lstbox}{\global\setbox\mybox=\hbox\bgroup}{\egroup}
\setlength{\parskip}{\baselineskip}
\setlength{\parindent}{0ex}
\begin{document}
Description of problem.
\begin{ansbox}{2in}
\end{ansbox}
What is your name?
\begin{ansbox}{2in}
My name is
\end{ansbox}
Implement a factorial function.
\begin{lstbox}
def factorial(n):
\end{lstbox}
\begin{ansbox}{1in}
\usebox{\mybox}
\end{ansbox}
\end{document}