
Рассмотрим следующий код, взятый изздесьдля создания красивого списка:
% PACKAGES
\documentclass[11pt,a4paper]{book}
\usepackage[top=1in, bottom=1in, left=1in, right=1in]{geometry}
\usepackage{lmodern}
\usepackage{multicol}
\usepackage{lipsum}
\usepackage{xcolor}
\usepackage{tcolorbox}
\tcbuselibrary{skins,listings}
\definecolor{nicedarkgreen}{RGB}{0,127,0}
\definecolor{nicedarkblue}{RGB}{0, 0, 102}
% LISTINGS
\newtcblisting{cpplisting}[1][]{%
enhanced,
arc = 0pt,
outer arc = 0pt,
colback = blue!5,
colframe = nicedarkblue,
listing only,
fonttitle = \bfseries,
listing options = {%
basicstyle=\tiny\ttfamily,
keywordstyle=\color{blue},
language = C++,
commentstyle=\color{nicedarkgreen},
tabsize=2,
morekeywords={constexpr},
multicols = 2,
numbers = left,
xleftmargin = 0.5em,
showstringspaces = false,
},
overlay = {%
\fill[gray!30]
(interior.north west)
rectangle
([xshift = 1.25em]interior.south west);
\fill[gray!30]
([xshift = -1em]interior.north)
rectangle
([xshift = 0.25em]interior.south);
\draw[ultra thick, nicedarkblue]
([xshift = -1em]interior.north) --
([xshift = -1em]interior.south);
}
/utils/exec = {%
\def\thelstnumber{%
\texttt{\csname two@digits\endcsname{\the\value{lstnumber}}}}},
title = {\centering\ttfamily #1}
}
% TEST
\begin{document}
\lipsum[1]
\begin{cpplisting}[An example of C++ file]
// Include
#include <iostream>
// Example
int main()
{
std::cout<<"Hello World"<<std::endl;
std::cout<<"This is just an example"<<std::endl;
std::cout<<"With two columns"<<std::endl;
return 0;
}
\end{cpplisting}
\end{document}
С :
- альфа: ширина текста в одну колонку
- бета: ширина первого столбца
- гамма: ширина второго столбца
- му: ширина столбца чисел
- ню: расстояние между числами и текстом
- сигма:му+ню
- фи: расстояние между заголовком и первой строкой
- пси: расстояние после последней строки
Выглядит отлично... но выравнивание не очень, и это вызывает у меня головную боль... Вместо текущего результата я хочу:
- бета = гамма: одинаковая общая ширина столбцов (поэтому синяя линия посередине будет соответствовать середине страницы)
- му: для настройки на содержит 3 цифры (и когда число состоит из трех цифр, я хочу, чтобы оно было центрировано наму)
- фи = пси: одинаковое верхнее и нижнее поле
Чтобы точно знать логику, было бы здорово, если бы все это можно было реализовать программно, используя:
\newlength{...}
\setlength{...}{...}
или что-то подобное.
Как этого добиться?
решение1
Вот результат после более чем 3 часов колебаний и экспериментов. Он дает тот результат, который я хочу для моего конкретного шрифта/размера шрифта, но он все еще экспериментальный. Улучшения, которые сделают его масштабируемым правильно для разных шрифтов/размеров шрифтов, были бы весьма признательны:
% PACKAGES
\documentclass[11pt,a4paper]{book}
\usepackage[top=1in, bottom=1in, left=1in, right=1in]{geometry}
\usepackage{lmodern}
\usepackage{multicol}
\usepackage{lipsum}
\usepackage{xcolor}
\usepackage{tcolorbox}
\usepackage{layouts}
\usepackage{calc}
\tcbuselibrary{skins,listings}
\definecolor{nicedarkgreen}{RGB}{0,127,0}
\definecolor{nicedarkblue}{RGB}{0, 0, 102}
\definecolor{lstgrey}{RGB}{217, 217, 217}
\definecolor{lstback}{RGB}{242, 242, 255}
% LISTINGS
\newlength{\zerolength}
\setlength{\zerolength}{0em}
\newlength{\tinyheight}
\setlength{\tinyheight}{\totalheightof{\tiny\ttfamily PpQq}}
\newlength{\beforetitle}
\setlength{\beforetitle}{2pt}
\newlength{\numberlength}
\setlength{\numberlength}{\widthof{\tiny\ttfamily 9999}}
\setlength{\numberlength}{0.25\numberlength}
\makeatletter
\def\three@digits#1{\ifnum#1<10 00\else\ifnum#1<100 0\fi\fi\number#1}
\makeatother
\newtcblisting{cpplisting}[1][]{%
% Frame
enhanced,
arc = \zerolength,
outer arc = \zerolength,
% Title
fonttitle = \ttfamily,
toptitle = \zerolength,
bottomtitle = \zerolength,
titlerule = \zerolength,
toptitle = \beforetitle,
bottomtitle = \beforetitle,
% Vertical alignment
top = -0.5\tinyheight,
bottom = 0.25\tinyheight,
% Horizontal alignment
left = \zerolength,
right = 1.5\numberlength,
colback = lstback,
colframe = nicedarkblue,
% Contents
listing only,
title = {\centering #1},
listing options = {%
% Language
language = C++,
tabsize=2,
basicstyle=\tiny\ttfamily,
keywordstyle=\color{blue},
commentstyle=\color{nicedarkgreen},
morekeywords={constexpr},
showstringspaces = false,
% Alignment
multicols = 2,
numbers = left,
numbersep = 2\numberlength,
xleftmargin = 5\numberlength,
framesep = \zerolength,
aboveskip = \zerolength,
belowskip = \zerolength,
},
overlay = {%
\fill[lstgrey] (interior.north west) rectangle ([xshift = 5\numberlength] interior.south west);
\draw[ultra thick, nicedarkblue] ([xshift = \zerolength] interior.north) -- ([xshift = \zerolength] interior.south);
\fill[lstgrey] (interior.north) rectangle ([xshift = 5\numberlength] interior.south);
},
%/utils/exec = {%
% \def\thelstnumber{%
% \texttt{\csname three@digits\endcsname{\the\value{lstnumber}}}}}
}
% TEST
\begin{document}
\lipsum[1]
\begin{cpplisting}[An example of a C++ file]
// Include
#include <iostream>
// Example
int main()
{
std::cout<<"Hello World"<<std::endl;
std::cout<<"This is just an example"<<std::endl;
std::cout<<"With two columns"<<std::endl;
return 0;
}
\end{cpplisting}
\end{document}