# environment without line breaks

I already read How can I prevent breaks in a custom environment? but this somehow does not solve my problem. I want to define an environment that defines a heading and then there is one line of text and a huge AVM. All of this has to stay on the same page. I tried samepage but LaTeX is stubborn and breaks anyway. I tried minipage but then the space before and after the environment is gone.

\documentclass{article}

\usepackage{array}

\newcounter{schema}
\newenvironment{schema}[1][]
{% \begin{schema}[<title>]
\goodbreak%
\refstepcounter{schema}%
\begin{list}{}{\setlength{\labelwidth}{0pt}\setlength{\labelsep}{0pt}\setlength{\rightmargin}{0pt}\setlength{\leftmargin}{0pt}}%
\item[{\textbf{Schema~\theschema}}]\hspace{.5em}\textbf{(#1)}\nopagebreak[4]\par\nobreak}%
{\end{list}}% \end{schema}

\newcommand{\onems}[2][]{%
\mbox{%
\delimiterfactor=1000 \delimitershortfall=0pt
\tabcolsep=0pt
$\left[% \begin{tabular}{>{\upshape\scshape}l} \if\relax\detokenize{#1}\relax\else {\normalfont\itshape #1}% \\ \fi #2% \end{tabular}% \right]$%
}%
\vspace{1mm}%
}

\begin{document}

\label{schema-hc-flat}
\onems{
synsem|loc|cat|comps <>\\
}\\
}
\end{schema}

\end{document}


Edit: This is the version of the code with minipage wrapper (commented out). The minipage version eats the space before and after the environment. I do not know how to fix this.

\documentclass{article}

\usepackage{array,lipsum}

\newcounter{schema}
\newenvironment{schema}[1][]
{% \begin{schema}[<title>]
\goodbreak%
\refstepcounter{schema}%
\begin{list}{}{\setlength{\labelwidth}{0pt}\setlength{\labelsep}{0pt}\setlength{\rightmargin}{0pt}\setlength{\leftmargin}{0pt}}%
\item[{\textbf{Schema~\theschema}}]\hspace{.5em}\textbf{(#1)}\nopagebreak[4]\par\nobreak}%
{\end{list}}% \end{schema}

%% \newenvironment{schema}[1][]
%%   {% \begin{schema}[<title>]
%%   \goodbreak%
%%   \refstepcounter{schema}%
%%   \begin{minipage}{\linewidth}%
%%   \begin{list}{}{\setlength{\rightmargin}{\leftmargin}}%
%%     \item[{\textbf{Schema~\theschema:}}]#1\par\nobreak}%
%%   {\end{list}\end{minipage}}% \end{schema}

\newcommand{\onems}[2][]{%
\mbox{%
\delimiterfactor=1000 \delimitershortfall=0pt
\tabcolsep=0pt
$\left[% \begin{tabular}{>{\upshape\scshape}l} \if\relax\detokenize{#1}\relax\else {\normalfont\itshape #1}% \\ \fi #2% \end{tabular}% \right]$%
}%
\vspace{1mm}%
}

\begin{document}

\lipsum[2]
\label{schema-hc-flat}
\onems{
synsem|loc|cat|comps <>\\
}\\
}
\end{schema}
\lipsum[2]

\end{document}

• The only sensible way to force everything in a block is to use minipage or \parbox. You say you "tried minipage but then the space before and after the environment is gone". It would be best you posted this MWE and we can take it from there. Dec 6, 2019 at 13:06
• I added the minipage version. Dec 6, 2019 at 19:01

As I said in a comment, IMO the only sensible way to avoid a page break at all costs is to put the content in a minipage or \parbox. The spacing before and after the minipage can be added with an explicit \bigskip (or \medskip, or whatever you find pleasant). A little care is needed for the spacing after the environment, but here the kernel macro \@endparenv comes in handy.

\documentclass{article}

\usepackage{array,lipsum}

\newcounter{schema}

\makeatletter
\newenvironment{schema}[1][]
{%
\refstepcounter{schema}%
\par\bigskip\noindent
\minipage{\linewidth}%
\textbf{Schema~\theschema: \ifx&#1&\else(#1)\fi}\par
}{\endminipage\par\bigskip\@endparenv}%
\makeatother

\newcommand{\onems}[2][]{%
\mbox{%
\delimiterfactor=1000 \delimitershortfall=0pt
\tabcolsep=0pt
$\left[% \begin{tabular}{>{\upshape\scshape}l} \if\relax\detokenize{#1}\relax\else {\normalfont\itshape #1}% \\ \fi #2% \end{tabular}% \right]$%
}%
\vspace{1mm}%
}

\begin{document}

\lipsum[66]
\begin{schema}[Foo]
\label{foo}
\onems{
synsem|loc|cat|comps <>\\
}\\
}
\end{schema}
See schemes \ref{foo} and \ref{baz}.
\lipsum[66]
\begin{schema}[Baz]
\label{baz}
\onems{
synsem|loc|cat|comps <>\\

The advantage of closing the environment with \@endparenv is that the indentation after \end{schema} is suppressed unless you leave an explicit empty line.
(I assume you noticed that with small caps you get <> but the | is rendered as an em-dash. I hope you know what you are doing there :-).)