Code Listings in LaTeX: Source Code Formatting and Syntax Highlighting
Drop a code snippet into a word processor and you get smart quotes where you wanted straight ones, autocorrect mangling your variable names, and indentation that drifts. LaTeX handles code listings properly: it preserves whitespace, highlights syntax, and numbers lines you can reference later. This guide covers the two packages that do the work, listings and minted, plus algorithms and a few formatting tricks worth knowing. For a second, more reference-style take on the same package, see the LaTeX code listings guide.
Why LaTeX for Code Documentation?
A few things LaTeX does well that a general-purpose editor doesn’t:
- Consistent formatting across every snippet in the document
- Syntax highlighting for a long list of languages, with the ability to define your own
- Line numbering you can cross-reference like any other label
- Preserved indentation and spacing, exactly as written
- Typography tuned for readability rather than guesswork
The listings Package
Basic Setup
\usepackage{listings}
\usepackage{xcolor} % For syntax coloring
% Basic code inclusion
\begin{lstlisting}
def hello_world():
print("Hello, LaTeX!")
return True
\end{lstlisting} Language-Specific Formatting
% Python code with syntax highlighting
\begin{lstlisting}[language=Python]
def fibonacci(n):
"""Calculate Fibonacci sequence"""
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
# List comprehension example
squares = [x**2 for x in range(10)]
\end{lstlisting}
% JavaScript with highlighting
\begin{lstlisting}[language=JavaScript]
const fetchData = async (url) => {
try {
const response = await fetch(url);
const data = await response.json();
return data;
} catch (error) {
console.error('Error:', error);
}
};
\end{lstlisting} Advanced listings Configuration
Custom Style Definition
\lstdefinestyle{mystyle}{
backgroundcolor=\color{gray!5},
commentstyle=\color{green!60!black},
keywordstyle=\color{blue},
numberstyle=\tiny\color{gray},
stringstyle=\color{orange},
basicstyle=\ttfamily\footnotesize,
breakatwhitespace=false,
breaklines=true,
captionpos=b,
keepspaces=true,
numbers=left,
numbersep=5pt,
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=4,
frame=single,
rulecolor=\color{black!30},
xleftmargin=10pt,
framexleftmargin=10pt,
framexrightmargin=5pt,
framexbottommargin=5pt
}
\lstset{style=mystyle} Language-Specific Styles
% C++ style
\lstdefinestyle{cpp}{
language=C++,
style=mystyle,
keywordstyle=\color{blue}\bfseries,
stringstyle=\color{red},
commentstyle=\color{green!50!black}\itshape,
morecomment=[l][\color{magenta}]{\#},
morekeywords={override, final, constexpr, nullptr}
}
% Usage
\begin{lstlisting}[style=cpp]
#include <iostream>
#include <vector>
template<typename T>
class SmartContainer {
private:
std::vector<T> data;
public:
void add(const T& item) {
data.push_back(item);
}
size_t size() const noexcept {
return data.size();
}
};
\end{lstlisting} Including External Code Files
Direct File Inclusion
% Include entire file
\lstinputlisting[language=Python]{scripts/data_analysis.py}
% Include specific lines
\lstinputlisting[
language=Java,
firstline=10,
lastline=25
]{src/Main.java}
% Include with custom caption
\lstinputlisting[
language=C,
caption={Memory allocation function},
label={lst:malloc}
]{src/memory.c} Automatic Language Detection
% Define file extensions
\lstset{
inputencoding=utf8,
extendedchars=true,
literate={á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1,
language=Python,
}
% Auto-detect from extension
\lstinputlisting[language={}]{script.py} % Uses Python
\lstinputlisting[language={}]{style.css} % Uses CSS The minted Package: Modern Syntax Highlighting
Setup and Requirements
% Requires Python Pygments: pip install Pygments
% Compile with: pdflatex -shell-escape document.tex
\usepackage{minted}
% Basic usage
\begin{minted}{python}
import numpy as np
import matplotlib.pyplot as plt
def plot_function(f, x_range):
x = np.linspace(*x_range, 1000)
y = f(x)
plt.figure(figsize=(10, 6))
plt.plot(x, y, 'b-', linewidth=2)
plt.grid(True, alpha=0.3)
plt.show()
\end{minted} Advanced minted Features
% Custom styling
\usemintedstyle{monokai}
% With line numbers and highlighting
\begin{minted}[
linenos,
numbersep=5pt,
frame=lines,
framesep=2mm,
bgcolor=gray!5,
fontsize=\footnotesize,
highlightlines={3,5-7}
]{rust}
fn main() {
let mut vec = Vec::new();
vec.push(1);
vec.push(2);
for item in &vec {
println!("Value: {}", item);
}
}
\end{minted} Professional Code Formatting Techniques
Inline Code
% Using listings
The function \lstinline{calculate_sum(a, b)} returns the sum.
% With custom style
\lstinline[style=mystyle]|vector<int> numbers;|
% Using minted
The \mintinline{python}{lambda x: x**2} function squares input. Side-by-Side Code Comparison
\usepackage{multicol}
\begin{multicols}{2}
\begin{lstlisting}[language=Python, caption=Python Version]
def factorial(n):
if n <= 1:
return 1
return n * factorial(n-1)
\end{lstlisting}
\columnbreak
\begin{lstlisting}[language=C, caption=C Version]
int factorial(int n) {
if (n <= 1) {
return 1;
}
return n * factorial(n-1);
}
\end{lstlisting}
\end{multicols} Algorithm Presentation
The algorithm2e Package
\usepackage[ruled,vlined]{algorithm2e}
\begin{algorithm}[H]
\DontPrintSemicolon
\SetAlgoLined
\KwResult{Sorted array}
\SetKwFunction{FQuickSort}{QuickSort}
\SetKwProg{Fn}{Function}{:}{}
\Fn{\FQuickSort{$A, low, high$}}{
\If{$low < high$}{
$pivot \gets$ \texttt{Partition}$(A, low, high)$\;
\FQuickSort{$A, low, pivot-1$}\;
\FQuickSort{$A, pivot+1, high$}\;
}
}
\caption{QuickSort Algorithm}
\end{algorithm} Pseudocode with algorithmicx
\usepackage{algorithm}
\usepackage{algpseudocode}
\begin{algorithm}
\caption{Binary Search}
\begin{algorithmic}[1]
\Procedure{BinarySearch}{$arr, target$}
\State $left \gets 0$
\State $right \gets \text{length}(arr) - 1$
\While{$left \leq right$}
\State $mid \gets \lfloor(left + right) / 2\rfloor$
\If{$arr[mid] = target$}
\State \Return $mid$
\ElsIf{$arr[mid] < target$}
\State $left \gets mid + 1$
\Else
\State $right \gets mid - 1$
\EndIf
\EndWhile
\State \Return $-1$
\EndProcedure
\end{algorithmic}
\end{algorithm} Code Organization and References
Listing Captions and Labels
\begin{lstlisting}[
caption={RESTful API endpoint implementation},
label={lst:api-endpoint}
]
@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
user = User.query.get_or_404(user_id)
return jsonify(user.to_dict())
\end{lstlisting}
% Reference in text
As shown in Listing~\ref{lst:api-endpoint}, the API endpoint... Creating a List of Listings
% Add after \tableofcontents
\lstlistoflistings
% Custom title
\renewcommand{\lstlistlistingname}{Code Examples} Syntax Highlighting for Custom Languages
Defining New Languages
\lstdefinelanguage{Docker}{
keywords={FROM, RUN, CMD, LABEL, EXPOSE, ENV, WORKDIR, COPY, ADD, ENTRYPOINT, VOLUME, USER, ARG},
keywordstyle=\color{blue}\bfseries,
comment=[l]{\#},
commentstyle=\color{green!50!black},
stringstyle=\color{red},
string=[b]",
morestring=[b]',
sensitive=false,
morecomment=[l]{//},
}
\begin{lstlisting}[language=Docker]
FROM node:14-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
\end{lstlisting} Enhancing Existing Languages
% Add keywords to Python
\lstdefinestyle{python-extended}{
language=Python,
morekeywords={async, await, yield, with, as},
morekeywords=[2]{self, cls},
keywordstyle=[2]\color{purple},
} Performance Optimization
Managing Large Code Bases
listings is lighter to compile than minted, which shells out to Pygments for every listing. If a draft is slow, one easy win is to switch off the listings you aren’t actively reviewing with a conditional:
% Conditional inclusion
\newif\ifincludecode
\includecodetrue % or \includecodefalse
\ifincludecode
\lstinputlisting{large-file.cpp}
\else
\texttt{[Code omitted for brevity]}
\fi If you do need minted, its caching is on by default and stores compiled output under a _minted-<jobname> directory, so repeated builds only reprocess listings that changed.
Code Documentation Best Practices
Effective Code Comments
\lstset{
morecomment=[s][\color{blue}\bfseries]{@}{@}, % Highlight special comments
}
\begin{lstlisting}[language=Java]
public class DatabaseConnection {
@ Important: Always close connections @
private Connection conn;
// Regular comment
public void connect(String url) {
/* Multi-line comment
explaining the connection process */
conn = DriverManager.getConnection(url);
}
}
\end{lstlisting} Code Annotations
% Using line notes
\begin{lstlisting}[
language=Python,
escapechar=|
]
def process_data(data):
cleaned = data.strip() |\colorbox{yellow}{Step 1}|
validated = validate(cleaned) |\colorbox{orange}{Step 2}|
return transform(validated) |\colorbox{green}{Step 3}|
\end{lstlisting} Documenting Code in the Browser
minted is the nicer of the two packages, but it needs Python, Pygments, and a -shell-escape build, which is exactly the kind of local setup people get stuck on. A browser-based editor sidesteps that. With inscrive.io you write LaTeX in the browser and compile on their servers, so a minted document just works without you installing a toolchain.
For a paper or manual full of listings, the practical wins are mundane: real-time collaboration so two people can edit the same source without merge conflicts, version history to rewind a listing that broke the build, and a shared template library so a team’s code style stays consistent. The free tier covers up to 10 projects with a 60-second compile window; Pro stretches that to 480 seconds, which helps when minted reprocesses a long file. Everything is stored in the EU (Hetzner, Germany and Finland) under a signed DPA, and your documents are never used to train AI models.
Team Code Standards
% Define team coding style
\lstdefinestyle{company-style}{
% Company-specific formatting
basicstyle=\ttfamily\small,
keywordstyle=\color{companyblue},
commentstyle=\color{companygreen},
% ... more settings
}
% Enforce consistent usage
\lstset{style=company-style} Advanced Features
Code Folding Representation
\begin{lstlisting}[language=JavaScript]
class UserManager {
constructor() {
// ... constructor code ...
}
addUser(userData) {
// ... validation ...
// ... database operation ...
// ... logging ...
}
// ... more methods ...
}
\end{lstlisting} Diff Highlighting
\lstdefinestyle{diff}{
morecomment=[f][\color{red}]-,
morecomment=[f][\color{green}]+,
morecomment=[f][\color{gray}]{@@},
}
\begin{lstlisting}[style=diff]
@@ -10,7 +10,7 @@
function calculate(x, y) {
- return x + y;
+ return x * y;
}
\end{lstlisting} Troubleshooting Common Issues
Character Encoding
% Fix UTF-8 issues
\lstset{
inputencoding=utf8,
extendedchars=true,
literate=
{á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1
{ó}{{\'o}}1 {ú}{{\'u}}1 {ñ}{{\~n}}1
} Long Lines
% Handle long lines
\lstset{
breaklines=true,
breakatwhitespace=true,
prebreak=\mbox{\textcolor{red}{$\searrow$}},
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
} Integration with Development Workflows
Automated Documentation
#!/bin/bash
# Extract code examples for LaTeX
find ./src -name "*.py" -exec echo "lstinputlisting[language=Python]{{}}" ; > code-listings.tex CI/CD Integration
# .github/workflows/docs.yml
- name: Generate Code Documentation
run: |
python scripts/extract_examples.py
pdflatex -shell-escape main.tex Accessibility Considerations
Screen Reader Friendly
% Provide alternative text
\begin{lstlisting}[
caption={[Function to calculate factorial]Recursive factorial implementation},
label={lst:factorial}
]
def factorial(n):
return 1 if n <= 1 else n * factorial(n-1)
\end{lstlisting} Wrapping Up
Pick listings when you want a fast, dependency-free build and don’t mind defining the odd language yourself. Pick minted when you want Pygments-grade highlighting and can run a -shell-escape build. Either way, the habits that matter are the same: caption and label your listings so you can reference them, keep one style across the document, and break long lines sensibly.
If a local TeX setup is the part standing in your way, inscrive.io compiles listings and minted documents in the browser, free to start, with EU-hosted storage and no install.




