Controlar el espaciado vertical antes de minipáginas vacías

Controlar el espaciado vertical antes de minipáginas vacías

Definí un nuevo entorno que dibuja una especie de cuadro de respuesta usando fbox alrededor de una minipágina. El entorno también coloca texto encima del cuadro de respuesta.

Aquí hay un ejemplo de trabajo mínimo:

\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}

Para mayor comodidad adjunto una captura de pantalla de la primera página:

ingrese la descripción de la imagen aquí

Como puede ver, hay un espacio vertical cuando el cuadro está vacío o cuando comienza inmediatamente con un entorno de lista. Intenté buscar pero no tengo idea de cómo se agrega este espacio o cómo deshacerme de él.

Además, ¿cómo puedo mantener el texto del "encabezado" junto con el cuadro cuando pasa a la página siguiente?

Respuesta1

El problema está en cómo se asegura el ancho del cuadro; en este caso es mejor agregar una regla de altura cero tan ancha como el cuadro. También necesitas recortar algo de ancho (para \fboxsepy \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}

ingrese la descripción de la imagen aquí

Tu código, con \begin{ansbox}{1.5in}, se convirtió

\begin{minipage}[t][1.5in]{\linewidth}
<environment's contents>
\vfill\hfill
\end{minipage}

Cuando el cuerpo ambiental está vacío, esto genera

\vfill
\hfill
\par\vfil

(los últimos tokens se agregan porque desea una [t]minipágina; \vfilse cancela con \vfill). El punto de referencia de la caja está determinado por el \vfill. Por otro lado, con un contenido no vacío, tienes

My name is
\vfill
\hfill
\vfil

y el punto de referencia está en la línea base del párrafo superior; ahora la altura de la caja se medirá como la altura de M más \fboxsepmás \fboxrule; esto equivale a 6,83331+3+0,4=10,23331 puntos. Esto claramente excede el umbral, por lo que TeX lo usará \lineskipentre la línea "Escribir respuesta en el cuadro:" y el cuadro. En el primer caso, la altura del cuadro es solo 3,4 puntos y la separación que ve es (ya que la línea de arriba no tiene profundidad) \baselineskipmenos 3,4 puntos.

Con mi solución, la caja siempre tendrá una altura de 3,4 puntos, porque la regla de altura cero determina el punto de referencia.

Respuesta2

Las minipáginas generalmente siguen reglas de espaciado de cuadros ( \lineskipen lugar de \baselineskip), por lo que me gusta agregar \strutletras en los bordes.

Hay otros problemas además del señalado. Francamente, me sorprende que el código se haya ejecutado.

En primer lugar, no debe utilizar \begin y \end en la definición de un entorno, ya que se expandirán desordenadamente. Este tipo de cosas se hace mejor usando el paquete ambiental.

En segundo lugar, a lstlisting no le gusta estar dentro de nada (excepto \hbox). El paquete tiene su propio software ambiental.

Si desea evitar un salto de página entre el texto y el cuadro, puede utilizar el paquete 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}

imagen de página completa

información relacionada