Bạn đang gặp rắc rối với việc số dòng bị lệch khi sử dụng đồng thời tcolorbox và minted để hiển thị code trong LaTeX? Bài viết này sẽ cung cấp một giải pháp toàn diện, giúp bạn trình bày code một cách chuyên nghiệp và dễ đọc hơn. Chúng ta sẽ đi sâu vào nguyên nhân của vấn đề và đưa ra các bước khắc phục chi tiết, kèm theo ví dụ minh họa cụ thể.
Sự kết hợp giữa tcolorbox và minted trong LaTeX mang lại khả năng tạo ra các khối code màu sắc, đẹp mắt. Tuy nhiên, khi sử dụng tham số capture=hbox
trong tcolorbox để thu gọn chiều rộng của box vừa với code, số dòng có thể bị hiển thị không chính xác, thường là bị lệch ra ngoài hoặc bị che khuất. Điều này xảy ra do cách minted và tcolorbox tương tác với môi trường Verbatim
và BVerbatim
.
Cụ thể, minted mặc định sử dụng môi trường Verbatim
để hiển thị code. Khi capture=hbox
được kích hoạt, tcolorbox sử dụng BVerbatim
. Sự khác biệt trong cách hai môi trường này xử lý số dòng là nguyên nhân chính dẫn đến lỗi hiển thị.
capture=hbox
(và tùy chỉnh chiều rộng)Một cách đơn giản để khắc phục lỗi là loại bỏ tham số capture=hbox
. Tuy nhiên, điều này sẽ khiến box code kéo dài toàn bộ chiều rộng trang. Để khắc phục điều này, bạn có thể tùy chỉnh chiều rộng của box bằng cách sử dụng tham số width
trong định nghĩa boxedCodeBlock
.
Ví dụ:
\documentclass{article}
\usepackage[dvipsnames]{xcolor}
\usepackage{tcolorbox}
\tcbuselibrary{minted,skins}
\renewcommand{\theFancyVerbLine}{\textcolor{white}{\scriptsize\arabic{FancyVerbLine}}}
\newtcblisting{boxedCodeBlock}[2][]{
#1,
minted language=#2,
listing engine=minted,
listing only,
enhanced,
frame hidden,
drop fuzzy shadow,
colback=Gray!15,
width=0.6\textwidth,
minted options={
style=staroffice,
linenos,
mathescape,
autogobble,
escapeinside=||,
fontsize=\footnotesize,
ignorelexererrors=true,
numbersep=24pt,
xleftmargin=24pt
},
overlay={
\begin{tcbclipinterior}
\fill[Black!50!Red](frame.south west)rectangle([xshift=5mm]frame.north west);
\end{tcbclipinterior}
},
left=6pt,
}
\begin{document}
\begin{boxedCodeBlock}{matlab}
function result = factorial(n)
if n == 0 || n == 1
result = 1;
else
result = n * factorial(n-1);
end
end
fact5 = factorial(5)
\end{boxedCodeBlock}
\end{document}
Trong ví dụ này, width=0.6\textwidth
đặt chiều rộng của box bằng 60% chiều rộng của trang. Bạn cũng có thể điều chỉnh numbersep
và xleftmargin
để đảm bảo số dòng hiển thị đúng vị trí.
Một giải pháp phức tạp hơn nhưng mạnh mẽ hơn là sử dụng các package piton, nicematrix và TikZ để tạo box code. Piton chịu trách nhiệm định dạng code, nicematrix và TikZ tạo khung và nền cho box.
Ví dụ:
\documentclass{article}
\usepackage{piton}
\usepackage{nicematrix}
\usepackage{varwidth}
\usepackage{tikz}
\NewPitonEnvironment{Matlab}{}{}
{
\PitonOptions{language=matlab,line-numbers,width=min,left-margin=5mm}
\begin{NiceTabular}{V{8cm}}
\CodeBefore
\begin{tikzpicture}
\draw[rounded corners,clip] (1-|1) rectangle (2-|2) ;
\fill[fill=gray!15] (1-|1) rectangle (2-|2) ;
\fill[fill=gray!30] (1-|1) rectangle ([xshift=5.5mm]2-|1) ;
\end{tikzpicture}
\Body
}
{
\end{NiceTabular}
}
\NewPitonLanguage{Matlab}
% {morekeywords={...}} % Các keywords của Matlab, lược bỏ cho ngắn gọn
\begin{document}
\begin{Matlab}
function result = factorial(n)
if n == 0 || n == 1
result = 1;
else
result = n * factorial(n-1);
end
end
fact5 = factorial(5)
\end{Matlab}
\end{document}
Giải pháp này yêu cầu biên dịch bằng LuaLaTeX và có thể cần nhiều lần biên dịch để nicematrix hoạt động chính xác.
\FancyVerbFormatLine
Giải pháp này liên quan đến việc định nghĩa lại macro \FancyVerbFormatLine
để tự thêm số dòng vào trước mỗi dòng code. Điều này cho phép kiểm soát hoàn toàn vị trí và định dạng của số dòng.
Ví dụ:
\documentclass{article}
\usepackage[dvipsnames]{xcolor}
\usepackage{tcolorbox}
\tcbuselibrary{minted,skins}
\usepackage{showframe} % Để hiển thị vị trí của box bên trong vùng in
\newtcblisting{boxedCodeBlock}[2][]{
#1,
minted language=#2,
capture=hbox,
listing engine=minted,
listing only,
enhanced,
frame hidden,
drop fuzzy shadow,
colback=Gray!15,
boxrule=0pt, % Loại bỏ khoảng trắng xung quanh tcolorbox
boxsep=0pt, % Loại bỏ khoảng trắng bên trong tcolorbox
left=0pt, % Đặt lề trái về 0
before upper={
\def\FancyVerbFormatLine#1{
\hbox to 4mm{ % Chiều rộng của box số dòng
\hfill\color{white}\theFancyVerbLine
}\kern\csname FV@NumberSep\endcsname#1
}
},
minted options={
style=staroffice,
mathescape,
autogobble,
escapeinside=||,
fontsize=\footnotesize,
ignorelexererrors=true,
numbersep=\dimexpr 2mm+4pt, % Khoảng cách giữa box số và code
},
overlay={
\begin{tcbclipinterior}
\fill[Black!50!Red](frame.south west)rectangle([xshift=6mm]frame.north west);
\end{tcbclipinterior}
}
}
\begin{document}
\begin{boxedCodeBlock}{matlab}
function result = factorial(n)
if n == 0 || n == 1
result = 1;
else
result = n * factorial(n-1);
end
end
fact5 = factorial(5)
\end{boxedCodeBlock}
\end{document}
Giải pháp này đòi hỏi phải điều chỉnh các tham số như chiều rộng của box số dòng (\hbox to 4mm
) và khoảng cách giữa box số dòng và code (numbersep
) để có được kết quả ưng ý.
Việc khắc phục lỗi số dòng lệch khi sử dụng tcolorbox và minted đòi hỏi sự hiểu biết về cách hai package này tương tác với nhau. Bài viết này đã trình bày ba giải pháp khác nhau, từ đơn giản đến phức tạp, giúp bạn lựa chọn phương pháp phù hợp nhất với nhu cầu và trình độ của mình. Hy vọng rằng, với những hướng dẫn chi tiết này, bạn sẽ có thể trình bày code trong LaTeX một cách chuyên nghiệp và dễ đọc hơn.
Bài viết liên quan