# Shrink monospaced font in custom (verbatim) environments

I'm redesigning lecture notes for a university class since the students wanted to read the notes on their tablets, e-book readers, etc.

I have code blocks in these documents, defined in the cdblk and codeblocks environments. The codeblocks environment is a verbatim environment, while cdblk is not, but I need them both, since for example \textquotesingle doesn't display correctly in verbatim (that's what I use cdblk for).

I also have defined a \paper key in the preamble of the A4 paper version of the document, while in tablet versions I defined a \tablet key. I also have two commands \ifpaper{} and \iftablet{} for paper and tablet specific tex code.

I would like to adjust the font size the above mentioned cdblk and codeblock environments when a small paper size (\iftablet{}) is used like in the MWE below.

This is what I have tried so far, but neither of them work:

1. I've tried to use adjustbox around cdblk and codeblock environments, but I run into an error.

! Missing \endgroup inserted.
<inserted text>
\endgroup
l.61     \begin{codeblock}

2. I've tried to set monospaced font shrinkage with microtype, but it doesn't seem to have any effect. (Included in the MWE below.)

\SetExpansion[shrink=100]{family=tt*}{}

3. I've tried to define different font size cdblk environments for the paper and tablet versions in the preamble using \ifpaper{} and \iftablet{}, but when I compile the document the compiler doesn't notice those definitions, so it thinks that the environment is not defined.

At least 72 characters should fit in the cdblk and codeblock environments with the smallest paper size I use (used in the MWE). Of course, fitting 80 characters would be better but I need 72 at least.

Here is the example minimal working example:

\documentclass[10pt, titlepage]{article}

%\def\paper{1}
\def\tablet{1}

\usepackage[nohead,%
nofoot,%
nomarginpar,%
paperwidth=106.68mm,%
paperheight=142.24mm,%
tmargin=2.5mm,%
rmargin=2.5mm,%
bmargin=2.5mm,%
lmargin=2.5mm,
vscale=1,%
hscale=1]{geometry}
%\usepackage[a4paper]{geometry}
%\usepackage[headings]{fullpage}

\newcommand{\ifpaper}[1]{\ifx\paper\undefined\else{#1}\fi}
\newcommand{\iftablet}[1]{\ifx\tablet\undefined\else{#1}\fi}

\usepackage[cmyk, pdftex]{xcolor}

\definecolor{PMS420}{cmyk}{0, 0, 0, 0.15}

\usepackage[protrusion=true,%
expansion=true]{microtype}

\SetExpansion[shrink=100]{family=tt*}{}

\usepackage{verbatim}

\usepackage[framemethod=tikz,%
innerleftmargin=\parindent,%
skipabove=0.4\baselineskip,%
skipbelow=0.4\baselineskip,%
innertopmargin=0.4\baselineskip,%
innerbottommargin=0.4\baselineskip]{mdframed}

\newmdenv[linewidth=0pt,%
linecolor=PMS420,%
backgroundcolor=PMS420,%
settings={\setlength{\parindent}{0pt}}]{cdblk}
\newenvironment{codeblock}{\endgraf\verbatim}{\endverbatim}
\BeforeBeginEnvironment{codeblock}{\begin{cdblk}}
\AfterEndEnvironment{codeblock}{\end{cdblk}}

\pagestyle{empty}

\begin{document}

\begin{cdblk}
\verb+80 characters should                      fit in                        one line+
\end{cdblk}

\begin{codeblock}
80 characters should                      fit in                        one line
\end{codeblock}

\end{document}

• Does this one help? tex.stackexchange.com/questions/142394/… – egreg Dec 30 '13 at 10:57
• @egreg It did, thank you! However I had to decrease the number of iterations from 80 to 72 to fit 80 characters in one line, but I don't know why. Also could you please post this as an answer, so I can accept your answer and give you the credit. (I only had to replace \lstset{basicstyle=\fontsize{\eightytt}{1.2\eightytt}\ttfamily} with cdblk's and codeblock's definition and added font=\fontsize{\eightytt}{1.2\eightytt}\ttfamily to its definition.) – szantaii Dec 30 '13 at 11:21
• You could also just add the font size commands to the settings key of your newmdenv. Using plain tex conditionals, if you have \newif\ifsmall and \smalltrue then settings={\ifsmall\fontsize{6pt}{7pt}\selectfont\fi... would do what you want – Thruston Dec 30 '13 at 11:27

## 3 Answers

One possible way to do this would be to create a new conditional and then add a font size switch to the settings key of your newmdenv.

\newif\ifsmall
\smalltrue    % we want small sizes
%\smallfalse  % uncomment to turn off small sizes
\newmdenv[linewidth=0pt, linecolor=PMS420, backgroundcolor=PMS420,%
settings={\ifsmall\fontsize{6pt}{7pt}\selectfont\fi\setlength{\parindent}{0pt}}]{cdblk}


\documentclass[10pt, titlepage]{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{microtype}

\newcommand*\verbfont{%
\fontfamily{lmtt}\fontseries{lc}\fontshape{n}\selectfont%
\SetTracking{encoding=*}{-50}\lsstyle}
%\def\paper{1}
\def\tablet{1}

\usepackage[nohead,%
nofoot,%
nomarginpar,%
paperwidth=106.68mm,%
paperheight=142.24mm,%
tmargin=2.5mm,%
rmargin=2.5mm,%
bmargin=2.5mm,%
lmargin=2.5mm,
vscale=1,%
hscale=1]{geometry}
%\usepackage[a4paper]{geometry}
%\usepackage[headings]{fullpage}

\newcommand{\ifpaper}[1]{\ifx\paper\undefined\else{#1}\fi}
\newcommand{\iftablet}[1]{\ifx\tablet\undefined\else{#1}\fi}

\usepackage[cmyk, pdftex]{xcolor}
\definecolor{PMS420}{cmyk}{0, 0, 0, 0.15}

\usepackage{verbatim}
\makeatletter
\def\verbatim@font{\verbfont\setbox0=\hbox{1}\fontdimen2\font=\the\wd0}
\makeatother

\usepackage[framemethod=tikz,%
innerleftmargin=\parindent,%
skipabove=0.4\baselineskip,%
skipbelow=0.4\baselineskip,%
innertopmargin=0.4\baselineskip,%
innerbottommargin=0.4\baselineskip]{mdframed}
\newmdenv[linewidth=0pt,%
linecolor=PMS420,%
backgroundcolor=PMS420,%
settings={\setlength{\parindent}{0pt}}]{cdblk}
\newenvironment{codeblock}{\endgraf\verbatim}{\endverbatim}
\BeforeBeginEnvironment{codeblock}{\begin{cdblk}}
\AfterEndEnvironment{codeblock}{\end{cdblk}}
\pagestyle{empty}
\begin{document}

\begin{cdblk}
\verb+80 characters should                      fit in                        one line+
\end{cdblk}

\begin{codeblock}
80 characters should                      fit in                        one line
01234567890123456789012345678901234567890123456789012345678901234567890123456789
\end{codeblock}

{\verbfont
01234567890123456789012345678901234567890123456789012345678901234567890123456789}

\ttfamily
01234567890123456789012345678901234567890123456789012345678901234567890123456789
\end{document}


The \fontdimen2\font controls the width between two words. It must be set to the width of a character of the mono font, e.g. the "1" as seen above.

I'm adding the answer egreg pointed me to (listings font size that fits 80 columns?). I like this because it will select the font size according to the page size (more precisely to \textwidth), so I can use this with all paper sizes I work with, resulting that 80 characters will fit into cdblk or codeblock environments.

All I had to do is to replace cdblk's and codeblock's definition with:

\newlength{\eightytt}

\newcommand{\testthewidth}{%
\fontsize{\dimen0}{0}\selectfont%
\sbox0{x\global\dimen1=0.6em}%
\ifdim 73\dimen1>\textwidth%
\advance\dimen0 by -.1pt%
\expandafter\testthewidth%
\else%
\global\eightytt\dimen0%
\fi%
}

\AtBeginDocument{%
\dimen0=\csname f@size\endcsname pt%
\begingroup%
\ttfamily%
\testthewidth%
\endgroup%
\newmdenv[font=\fontsize{\eightytt}{1.2\eightytt}\ttfamily,%
linewidth=0pt,%
linecolor=PMS420,%
backgroundcolor=PMS420,%
settings={\setlength{\parindent}{0pt}}]{cdblk}
\newenvironment{codeblock}{\endgraf\verbatim}{\endverbatim}
\BeforeBeginEnvironment{codeblock}{\begin{cdblk}}
\AfterEndEnvironment{codeblock}{\end{cdblk}}
}


Fully working example:

\documentclass[10pt, titlepage]{article}

%\def\paper{1}
\def\tablet{1}

\usepackage[nohead,%
nofoot,%
nomarginpar,%
paperwidth=106.68mm,%
paperheight=142.24mm,%
tmargin=2.5mm,%
rmargin=2.5mm,%
bmargin=2.5mm,%
lmargin=2.5mm,
vscale=1,%
hscale=1]{geometry}
%\usepackage[a4paper]{geometry}
%\usepackage[headings]{fullpage}

\newcommand{\ifpaper}[1]{\ifx\paper\undefined\else{#1}\fi}
\newcommand{\iftablet}[1]{\ifx\tablet\undefined\else{#1}\fi}

\usepackage[cmyk, pdftex]{xcolor}

\definecolor{PMS420}{cmyk}{0, 0, 0, 0.15}

\usepackage[protrusion=true,%
expansion=true]{microtype}

\SetExpansion[shrink=100]{family=tt*}{}

\usepackage{verbatim}

\usepackage[framemethod=tikz,%
innerleftmargin=\parindent,%
skipabove=0.4\baselineskip,%
skipbelow=0.4\baselineskip,%
innertopmargin=0.4\baselineskip,%
innerbottommargin=0.4\baselineskip]{mdframed}

\pagestyle{empty}

% egreg's solution:
\newlength{\eightytt}

\newcommand{\testthewidth}{%
\fontsize{\dimen0}{0}\selectfont%
\sbox0{x\global\dimen1=0.6em}%
\ifdim 73\dimen1>\textwidth%
\advance\dimen0 by -.1pt%
\expandafter\testthewidth%
\else%
\global\eightytt\dimen0%
\fi%
}

\AtBeginDocument{%
\dimen0=\csname f@size\endcsname pt%
\begingroup%
\ttfamily%
\testthewidth%
\endgroup%
\newmdenv[font=\fontsize{\eightytt}{1.2\eightytt}\ttfamily,%
linewidth=0pt,%
linecolor=PMS420,%
backgroundcolor=PMS420,%
settings={\setlength{\parindent}{0pt}}]{cdblk}
\newenvironment{codeblock}{\endgraf\verbatim}{\endverbatim}
\BeforeBeginEnvironment{codeblock}{\begin{cdblk}}
\AfterEndEnvironment{codeblock}{\end{cdblk}}
}

\begin{document}

\begin{cdblk}
\verb+80 characters should                      fit in                        one line+
\end{cdblk}

\begin{codeblock}
80 characters should                      fit in                        one line
\end{codeblock}

\end{document}