# Safeguard an environment against tabular mode

The semantics of a given environment require that it is typeset inside a minipage if it is used inside a tabular. If I add the minipage declaration for a positive check for "internal" mode in the environment using \ifinner, it works: the minipage is added only if in tabular mode. (This can be seen in the output because the minipage does not expand over the full text width.) I have the following questions:

1. Why does the check for inner mode succeed when the kframe environment is closed? Is TeX in "internal" mode inside a minipage environment?
2. Is there a more reliable way to do this detection? Is the detection correct at all?

The kframe environment is used in code generated by knitr; it should work both inside and outside of a tabular.

\documentclass{article}
\pagestyle{empty}

\usepackage{color}
\usepackage{framed}

\newenvironment{kframe}{%
% The \ifinner check below is necessary
\ifinner\begin{minipage}{.8\textwidth}\else\fi%
\def\FrameCommand##1{\colorbox{yellow}{##1}}%
\MakeFramed{}}{%
\endMakeFramed%
% Why does this \ifinner check work?
\ifinner\end{minipage}\fi}

\begin{document}

\begin{kframe}
Any text long enough will do here.
Any text long enough will do here.
Any text long enough will do here.
\end{kframe}

\begin{tabular}{l}
\begin{kframe}
Any text long enough will do here.
Any text long enough will do here.
Any text long enough will do here.
\end{kframe}
\end{tabular}

\end{document}


-
\ifinner is true in internal vertical mode (so also inside a minipage), restricted horizontal mode (so also inside a tabular), in inline math mode and in any subformula in display math mode. –  egreg Jun 20 '12 at 12:01

It would be very peculiar to need a minipage inside a tabular, there is virtually nothing about a tabular cell which isn't shared by \mbox (for l columns) or \parbox (for p columns.).

It looks to me like you need a minipage if in an l column or \mbox or other restricted horizontal mode so I think you want

  \ifinner\ifhmode  start minipage \fi\fi


This would start a minipage in a tabular l but not a tabular p. The code below contains the full implementation including egreg's remark on closing the minipage environment.

\makeatletter
\newenvironment{kframe}{%
\def\at@end@of@kframe{}%
\ifinner\ifhmode%
\def\at@end@of@kframe{\end{minipage}}%
\begin{minipage}{.8\textwidth}%
\fi\fi%
\def\FrameCommand##1{\colorbox{yellow}{##1}}%
\MakeFramed{}}{%
\endMakeFramed%
\at@end@of@kframe}
\makeatother

-
And <start minipage> should contain something like \def\closekframe{\end{minipage}}, while the normal definition would be \def\closekframe{}. At the end of the kframe environment \closekframe should be executed. –  egreg Jun 20 '12 at 12:25
@egreg: Thank you, good point! –  krlmlr Jun 20 '12 at 13:19
David: Thank you. The code works in my case. Do you mind if I update your answer with the fixed code, also containing egreg's remark? –  krlmlr Jun 20 '12 at 13:27
sure edit away:-) –  David Carlisle Jun 20 '12 at 13:27