空のミニページの前の垂直間隔を制御する

空のミニページの前の垂直間隔を制御する

私は、ミニページの周囲に 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 の高さプラス\fboxsepプラスとして測定されます\fboxrule。つまり、6.83331+3+0.4=10.23331 ポイントになります。これは明らかにしきい値を超えているため、TeX は\lineskip「回答をボックスに記入してください:」行とボックスの間を使用します。前者の場合、ボックスの高さはちょうど 3.4 ポイントで、表示される分離は (上の行には深さがないため)\baselineskipマイナス 3.4 ポイントになります。

私の解決策では、ゼロ高さルールによって参照ポイントが決定されるため、ボックスの高さは常に 3.4 ポイントになります。

答え2

ミニページは通常、ボックスの間隔ルール (\lineskipではなく) に従うので、境界に s を\baselineskip追加します。\strut

指摘した以外にも問題があります。率直に言って、コードがまったく実行されなかったことに驚いています。

まず、環境の定義では \begin と \end を使用しないでください。これらは順序どおりに展開されないためです。このような処理は environ パッケージを使用して行うのが最適です。

2 番目に、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}

全ページ画像

関連情報