Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to make one framed environment with the following behavior.

  1. Only the last 8 lines of the content must be displayed. If the content have more than 8 lines, a gentle warning must be produced by LaTeX.
  2. The width of the frame is exactly equal to 16 letters.
  3. A fixed width font must be used.
  4. The content cannot contain formulas. If it is the case, an error must be sent.

This is for imitate the screen of one calculator.

The following solution nearly works except that I would like a better symetric spacing between the content and the box.

enter image description here

What are the changes to do ?

\documentclass{article}
    \usepackage{adjustbox}
    \usepackage{color}

% For tests
    \usepackage{comment}


    \makeatletter
        \catcode`\$=\active
        \newenvironment{calculator}{%
            \ttfamily
            \let\(\calculator@error
            \let\[\calculator@error
            \let\array\calculator@error
            % etc.
            \catcode`\$=\active
            \let$\calculator@error
            \begin{lrbox}{\@tempboxa}%
            \minipage[b]{8em}%
        }{%
            \endminipage
            \end{lrbox}%
            \par\smallskip
            % Measure height and clip if required
            \ifdim\ht\@tempboxa>8\baselineskip
                \PackageWarning{calculator}{%
                    calculator environment to long%
                }%
                % clip to only show the 8 last lines:
                \fbox{\clipbox*{0pt {\depth} {\width} 7.5\baselineskip}{%
                    \usebox\@tempboxa
                }}%
            \else
                \fbox{\usebox\@tempboxa}%
            \fi
            \smallskip
        }
        \catcode`\$=3

        \newcommand{\calculator@error}{%
            \PackageError{calculator}{%
                No math is allowed inside calculator environment%
            }{}%
        }

        \newcommand{\tiFocus}[1]{%
            \hspace{-\fboxsep}%
            \colorbox{black}{\textcolor{white}{#1}}%
            \hspace{-\fboxsep}%
        }
    \makeatother


\begin{document}

\section*{8 lines}

\begin{calculator}
\tiFocus{1 3 5 7 9 B D F}
.2 4 6 8 A C E
1 3 5 7 9 B D F
.2 4 6 \tiFocus{8} A C E
1 3 5 7 9 B D F
.2 4 6 8 A C E
1 3 5 7 9 B D F
.2 4 6 8 A C E
\end{calculator} 
share|improve this question
add comment

2 Answers

up vote 4 down vote accepted

EDIT: Sorry I used the new version which is currently not available on CTAN. I think in the next days the upload will be finished.

To compile please use the version of github mdframed

If you want to use mdframed here a solution:

I used the math error macro of Martin.

@Martin: I hope it's ok.

EDIT 2: Changed the detection of math inside the environment.

\documentclass{article}
\usepackage[paper=a5paper]{geometry}
\usepackage{microtype}

\usepackage[skipabove=\topskip,skipbelow=\topskip]{mdframed}
\makeatletter
\newif\ifmathinside\mathinsidefalse
\def\IfContainsMathMode{%
  \ifmathinside
    \expandafter\@firstoftwo%
  \else
    \expandafter\@secondoftwo%
  \fi%
  }


\preto\detected@md@put@frame{%
 \IfContainsMathMode{\calculator@error}{}
   \ifdimless{\ht\@tempboxa}{8\baselineskip}
    {}{%
    \splitmaxdepth\z@ \splittopskip\z@
    \dimen@=\dimexpr\ht\@tempboxa-7.9\baselineskip\relax
    \setbox0\vsplit\@tempboxa to \z@
    \setbox\tw@\vsplit\@tempboxa to \dimen@
    \setbox\@tempboxa\vbox{\unvbox0\unvbox\@tempboxa}
    \md@reset
    }%
}
\newcommand{\calculator@error}{%
    \PackageWarning{calculator}{%
        No math is allowed inside calculator environment\MessageBreak%
    }%
}

\newenvironment{calculator}{%
  \begin{mdframed}[linecolor=red,%innerleftmargin=0pt,innerrightmargin=0pt,%
                   settings={\ttfamily\everymath={\global\mathinsidetrue}\sloppy},
                   userdefinedwidth=\dimexpr8em+20.8pt\relax,
                   ]%
 }%
 {%
  \end{mdframed}
  \global\mathinsidefalse
}
\begin{document}


8 lines:

\begin{calculator}

1 3 5 7 9 B D F 
.2 4 6 8 A C E 
1 3 5 7 9 B D F 
.2 4 6 8 A C E 
1 3 5 7 9 B D F 
.2 4 6 8 A C E 
1 3 5 7 9 B D F 
.2 4 6 8 A C E 
\end{calculator}

% 
9 lines:
\begin{calculator}
.5 5 5 5 5 C E 
.2 4 6 8 A C E 
1 3 5 7 9 B D F 
.2 4 6 8 A C E 
1 3 5 7 9 B D F 
.2 4 6 8 A C E 
1 3 5 7 9 B D F 
.2 4 6 8 A C E 
.4 4 4 4 A C E 
\end{calculator}



8 lines:
\begin{calculator}
1 3 5 7 9 B D F 
.2 4 6 8 A C E 
1 3 5 7 9 B D F 
.2 4 6 8 A C E 
1 3 5 7 9 B D F 
.2 4 6 8 A C E 
1 3 5 7 9 B D F 
.2 4 6 8 A C E 
\end{calculator}
math:
\begin{calculator}
1 3 5 7 9 B D F
.2 4 6 8 A C E
1 \(a+b\) B D F
.2 4 6 8 A C E
1 $a+b$  B D F
.2 4 6 8 A C E
1 \[i+b\] B D F
.2 4 6 8 A C E
\end{calculator}
\end{document}

enter image description here

share|improve this answer
    
Thanks but my compilation gives the following error : ! LaTeX Error: \begin{mdframed} on input line 94 ended by \end{calculator}.. –  projetmbc Dec 8 '11 at 18:24
    
@projetmbc: I edited my post –  Marco Daniel Dec 8 '11 at 18:51
    
That works now. Thanks. –  projetmbc Dec 8 '11 at 22:33
    
@projetmbc: Please wait some minutes. At the moment I am working on the code to improve the behavior. –  Marco Daniel Dec 8 '11 at 22:53
    
@projetmbc: I edited the code. First I thought the Underfull \hbox (badness 10000) based on mdframed but it based on the font. At the moment I have no idea to reduce the boxes. –  Marco Daniel Dec 8 '11 at 23:02
add comment

You can use the following steps to achieve the wanted behaviour:

  1. can be done by boxing and measuring the content. Overlong boxes can be clipped and a warning can be issued. Either the collectbox or adjustbox package can help you with this. Not that cropping multiple lines is not without risks. You can also use some lower level TeX code to make TeX break after 8 lines and then discard the rest yourself, but this is more complicated (at least for me).

  2. Wrap it in a {minipage}{8em} environment should do it. You need to test if the width is OK, but for mono-space font it should be.

  3. Add \ttfamily (before the minipage, so that 16em gives you the tt value)

  4. You can locally redefine common math macros ($, \[, \(, ...) to produce an error.

I assume here that the content does not have to break over page borders.

The following should do it:

\documentclass{article}

\usepackage{adjustbox}

\makeatletter
\catcode`\$=\active
\newenvironment{calculator}{%
    \ttfamily
    \let\(\calculator@error
    \let\[\calculator@error
    \let\array\calculator@error
    % etc.
    \catcode`\$=\active
    \let$\calculator@error
    \begin{lrbox}{\@tempboxa}%
    \minipage[b]{8em}%
}{%
    \endminipage
    \end{lrbox}%
    \par\smallskip
    % Measure height and clip if required
    \ifdim\ht\@tempboxa>8\baselineskip
        \PackageWarning{calculator}{%
            calculator environment to long%
        }%
        % clip to only show the 8 last lines:
        \fbox{\clipbox*{0pt {\depth} {\width} 7.5\baselineskip}{%
            \usebox\@tempboxa
        }}%
    \else
        \fbox{\usebox\@tempboxa}%
    \fi
    \par\smallskip
}
\catcode`\$=3

\newcommand{\calculator@error}{%
    \PackageError{calculator}{%
        No math is allowed inside calculator environment%
    }{}%
}
\makeatother

\begin{document}

8 lines:
\begin{calculator}
 1 3 5 7 9 B D F
 .2 4 6 8 A C E
 1 3 5 7 9 B D F
 .2 4 6 8 A C E
 1 3 5 7 9 B D F
 .2 4 6 8 A C E
 1 3 5 7 9 B D F
 .2 4 6 8 A C E
\end{calculator}

9 lines:
\begin{calculator}
 1 3 5 7 9 B D F
 .2 4 6 8 A C E
 1 3 5 7 9 B D F
 .2 4 6 8 A C E
 1 3 5 7 9 B D F
 .2 4 6 8 A C E
 1 3 5 7 9 B D F
 .2 4 6 8 A C E
 1 3 5 7 9 B D F
\end{calculator}

math:
\begin{calculator}
 1 3 5 7 9 B D F
 .2 4 6 8 A C E
 1 \(a+b\) B D F
 .2 4 6 8 A C E
 1 $a+b$  B D F
 .2 4 6 8 A C E
 1 \[i+b\] B D F
 .2 4 6 8 A C E
\end{calculator}

\end{document}
share|improve this answer
    
Thanks for this. Is there a way to display only the last, and not the first 8 lines ? –  projetmbc Dec 8 '11 at 11:16
    
@projetmbc: That's actually easier. I updated my question to do it. –  Martin Scharrer Dec 8 '11 at 11:20
    
Thanks. That's great ! –  projetmbc Dec 8 '11 at 11:23
    
Is ther one possibility to use the mdframed instead of standard boxes ? –  projetmbc Dec 8 '11 at 11:37
    
Using mdframed after saving the content in a box gives you no benefits. You would need to use some mdframed settings or code to make it clip the content for you. I don't now the internals of this package good enough. –  Martin Scharrer Dec 8 '11 at 11:49
show 6 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.