# Changing a tcolorbox listing option based on the number of lines of its listing

Consider the following code which produces listings:

% ---------------------------------------------------------------------------- %
% Preamble
\documentclass[12pt]{article}
% ---------------------------------------------------------------------------- %
% Packages
\usepackage{calc}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{multicol}
\usepackage{printlen}
\usepackage[most]{tcolorbox}
% ---------------------------------------------------------------------------- %
% Length
\newlength{\evenlength}
\setlength{\evenlength}{0pt}
\newlength{\oddlength}
\setlength{\oddlength}{10pt}
% ---------------------------------------------------------------------------- %
% Listing
\newtcblisting{lstbox}[4][\normalsize]{
code = {},
enhanced,
listing only,
top = 0pt,
%%%%%%
% I want bottom to be equal to:
% - \evenlength if the listing has an even number of lines
% - \oddlength if the listing has an even number of lines
bottom = 0pt,
%%%%%%
left = 0pt,
right = 0pt,
arc = 0pt,
outer arc = 0pt,
boxsep = 0pt,
titlerule = 0pt,
colback = red,
colframe = black,
boxrule = 2pt,
title = {\centering{\fontfamily{cmtt}\selectfont#2\strut}},
listing options = {
language = C++,
framesep = 0pt,
rulesep = 0pt,
aboveskip = 0pt,
belowskip = 0pt,
backgroundcolor = \color{lightgray},
basicstyle = \fontfamily{cmtt}\selectfont#1,
#3,
},
#4,
}
% ---------------------------------------------------------------------------- %
% Document
\pagestyle{empty}
\begin{document}
\begin{lstbox}[\small]{title}{}{}
1
2
\end{lstbox}
\begin{lstbox}[\small]{title}{}{}
1
2
3
\end{lstbox}
\begin{lstbox}[\small]{title}{}{}
1
2
3
4
\end{lstbox}
\end{document}
% ---------------------------------------------------------------------------- %


Would there be a way to make the tcolorbox bottom option equal to

• \evenlength when the listing has an even number of lines
• \oddlength when the listing has an odd number of lines

To your list of \newtcblisting options, add the following one

process code = {%
\tcbset{ bottom = \ifodd\lst@lineno \oddlength \else \evenlength \fi }%
}


and wrap that command in \makeatletter/\makeatother.

The code in process code will be executed in a hook used in \end{lstbox}. At that point the number of lines in the listing code is already know (last value of \lst@lineno), but the bottom hasn't been printed yet, so the bottom option can still be changed.

Output

• Does it also work if the firstnumber has been set to something different than 1? And if not, how to deal with it? – Vincent Apr 28 at 7:38
• @Vincent Could you extend your samples to all the different use cases you want the solution to deal with? – siracusa Apr 28 at 16:55