LaTeX Code Listings: Syntax Highlighting and Custom Styling with the listings Package
If you’ve ever pasted code into a paper and watched the indentation collapse, this guide is for you. The LaTeX listings package handles code listings the way they should be handled: whitespace preserved, keywords highlighted, lines numbered and referenceable. This is the reference-style companion to our code listings overview, focused on the listings package and how to bend it to a house style.
Understanding the Listings Package
The listings package is the most widely used option for code in LaTeX. It ships with definitions for dozens of languages, lets you define your own, and gives you fine control over colors, frames, and line numbers. Its main trade-off against minted is that highlighting is rule-based rather than a full lexer, so it occasionally mishighlights tricky syntax. In exchange, it compiles fast and needs no external tools.
Basic Package Setup
Begin with the essential package configuration:
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{fancyvrb}
\usepackage{upquote}
% Basic listings configuration
\lstset{
basicstyle=\ttfamily\footnotesize,
breaklines=true,
frame=single,
numbers=left,
numberstyle=\tiny,
stepnumber=1,
numbersep=5pt,
backgroundcolor=\color{gray!10},
commentstyle=\color{green!60!black},
keywordstyle=\color{blue},
stringstyle=\color{red},
showstringspaces=false,
tabsize=2
} Syntax Highlighting Fundamentals
Effective syntax highlighting improves code readability by distinguishing between different code elements. The listings package supports comprehensive language-specific highlighting rules.
Language-Specific Configurations
Different programming languages require tailored highlighting schemes:
% Python syntax highlighting
\lstdefinelanguage{Python}{
keywords={def, class, from, import, return, if, else, elif, for, while, try, except, finally, with, as, in, is, not, and, or, True, False, None},
keywordstyle=\color{blue}\bfseries,
identifierstyle=\color{black},
sensitive=false,
comment=[l]{\#},
morecomment=[s]{"""}{"""},
stringstyle=\color{red},
string=[b]{"},
string=[b]{'},
morestring=[b]{"""},
morestring=[b]{'''}
}
% JavaScript syntax highlighting
\lstdefinelanguage{JavaScript}{
keywords={function, var, let, const, if, else, for, while, switch, case, break, continue, return, try, catch, finally, class, extends, import, export, default, async, await},
keywordstyle=\color{blue}\bfseries,
identifierstyle=\color{black},
sensitive=false,
comment=[l]{//},
morecomment=[s]{/*}{*/},
stringstyle=\color{red},
string=[b]{"},
string=[b]{'},
morestring=[b]{`}
} Advanced Styling Techniques
Custom Color Schemes
Professional documents benefit from carefully chosen color schemes that enhance readability:
% Professional color scheme
\definecolor{codegreen}{rgb}{0,0.6,0}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
\definecolor{codepurple}{rgb}{0.58,0,0.82}
\definecolor{backcolour}{rgb}{0.95,0.95,0.92}
\lstdefinestyle{mystyle}{
backgroundcolor=\color{backcolour},
commentstyle=\color{codegreen},
keywordstyle=\color{magenta},
numberstyle=\tiny\color{codegray},
stringstyle=\color{codepurple},
basicstyle=\ttfamily\footnotesize,
breakatwhitespace=false,
breaklines=true,
captionpos=b,
keepspaces=true,
numbers=left,
numbersep=5pt,
showspaces=false,
showstringspaces=false,
showtabs=false,
tabsize=2
} Frame and Background Options
Custom frames and backgrounds enhance visual appeal:
% Professional frame styling
\lstdefinestyle{framed}{
frame=trBL,
frameround=tttt,
framesep=4pt,
framexleftmargin=15pt,
framextopmargin=3pt,
framexbottommargin=3pt,
backgroundcolor=\color{gray!5},
rulecolor=\color{blue!50}
}
% Minimalist styling
\lstdefinestyle{minimal}{
frame=none,
backgroundcolor=\color{white},
basicstyle=\ttfamily\small,
numbers=none,
breaklines=true,
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space}
} Code Inclusion Strategies
External File Inclusion
For large code files, external inclusion provides better organization:
% Include external code files
\lstinputlisting[language=Python, style=mystyle]{src/algorithm.py}
% Include with line number range
\lstinputlisting[language=Java, firstline=10, lastline=25]{src/Example.java}
% Include with custom caption
\lstinputlisting[language=C++, caption=Optimized Sorting Algorithm]{src/sort.cpp} Inline Code Presentation
Short code snippets benefit from inline formatting:
% Inline code with custom styling
\lstinline[language=Python, style=\color{blue}\ttfamily]{def fibonacci(n):}
% Inline code with background
\lstinline[backgroundcolor=\color{yellow!20}]{import numpy as np} Mathematical Code Integration
LaTeX excels at presenting mathematical algorithms and computational code:
% Mathematical algorithm presentation
\begin{lstlisting}[language=Python, caption=Gradient Descent Implementation]
def gradient_descent(f, grad_f, x0, learning_rate=0.01, max_iter=1000):
"""
Gradient descent optimization algorithm
Parameters:
f: objective function
grad_f: gradient function
x0: initial point
learning_rate: step size
max_iter: maximum iterations
"""
x = x0
for i in range(max_iter):
gradient = grad_f(x)
x_new = x - learning_rate * gradient
if np.linalg.norm(x_new - x) < 1e-6:
break
x = x_new
return x
\end{lstlisting} Collaborative Code Editing
When several authors share a document full of listings, a defined style and a single source of truth keep things consistent. A browser-based editor like inscrive.io lets a team edit the same LaTeX source in real time, so two people can adjust a listing and its surrounding text at once without merge conflicts. It also avoids the minted setup hurdle: there’s no local Pygments install or -shell-escape flag to configure, because compilation runs server-side.
A few things that help with code-heavy documents:
- Real-time editing, so multiple authors work on the same listings at once
- No merge conflicts, since edits sync live rather than being reconciled after the fact
- Advanced version history, a full trail you can rewind to any earlier version
- A shared template library, so everyone starts from the same listing style
inscrive runs on EU infrastructure (Hetzner in Germany and Finland, ISO 27001-certified) with a signed DPA, and it never uses your documents to train AI models. The free tier covers up to 10 projects with unlimited collaborators.
Best Practices for Code Presentation
Readability Guidelines
- Consistent formatting: Maintain uniform style throughout the document
- Appropriate line length: Limit code lines to 80-100 characters
- Clear comments: Include meaningful comments in code examples
- Logical organization: Group related code sections together
Technical Considerations
- Font selection: Use monospace fonts for code (Courier, Consolas)
- Color contrast: Ensure sufficient contrast for accessibility
- Line numbering: Include line numbers for reference
- Break handling: Configure appropriate line breaking for long code blocks
Language-Specific Optimizations
Python Code Presentation
Python code benefits from specific formatting considerations:
\lstdefinestyle{python}{
language=Python,
basicstyle=\ttfamily\small,
keywordstyle=\color{blue}\bfseries,
commentstyle=\color{green!60!black}\itshape,
stringstyle=\color{red},
numberstyle=\tiny\color{gray},
numbers=left,
frame=single,
breaklines=true,
postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space},
showstringspaces=false,
tabsize=4
} R Code Presentation
Statistical computing code requires specialized formatting:
\lstdefinelanguage{R}{
keywords={function, if, else, for, while, repeat, break, next, return, TRUE, FALSE, NULL, NA, Inf, NaN},
keywordstyle=\color{blue}\bfseries,
commentstyle=\color{green!60!black},
stringstyle=\color{red},
morecomment=[l]{\#},
morestring=[b]{"},
morestring=[b]{'}
} Accessibility and Internationalization
Screen Reader Compatibility
Ensure code listings are accessible to users with visual impairments:
\usepackage{accessibility}
% Enable screen reader support
\lstset{
literate={%
{->}{$\rightarrow$}{1}
{<-}{$\leftarrow$}{1}
{>=}{$\geq$}{1}
{<=}{$\leq$}{1}
{!=}{$\neq$}{1}
{==}{$\equiv$}{1}
}
} Unicode Support
Modern code often contains Unicode characters:
\usepackage[utf8]{inputenc}
\usepackage{newunicodechar}
% Define Unicode characters for code
\newunicodechar{→}{$\rightarrow$}
\newunicodechar{←}{$\leftarrow$}
\newunicodechar{≥}{$\geq$}
\newunicodechar{≤}{$\leq$} Performance Optimization
Compilation Efficiency
Large documents with extensive code listings benefit from optimization:
% Optimize for compilation speed
\lstset{
cache=true,
cachepath={cache/},
deletekeywords={...},
deletekeywords=[2]{...},
deletekeywords=[3]{...}
} Wrapping Up
Good code listings come down to a \lstset you set once, a style you reuse everywhere, and captions and labels so you can reference listings like any other float. Define the languages you need, pick a readable color scheme, and turn on line breaking for the long lines. The package rewards a little upfront configuration and then mostly stays out of your way.
If you’d rather skip the local setup, inscrive.io compiles listings documents in the browser, free to start, with EU-hosted storage and real-time collaboration for shared technical writing.
Further reading
References
- The listings package documentation (CTAN)
- The minted package documentation (CTAN)
- Lamport, Leslie. LaTeX: A Document Preparation System. Addison-Wesley, 2nd ed., 1994.
- Mittelbach, Frank, and Michel Goossens. The LaTeX Companion. Addison-Wesley, 2nd ed., 2004.




