A comprehensive Python library for programmatically creating and compiling LaTeX documents and snippets.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Label creation and cross-referencing system for equations, figures, sections, and pages with automatic formatting. PyLaTeX provides comprehensive support for LaTeX's labeling and referencing system, enabling automatic numbering, cross-references, and intelligent reference formatting.
The core labeling system allows you to mark elements and reference them throughout the document with automatic numbering.
class Marker(LatexObject):
def __init__(self, name, prefix="", del_invalid_char=True):
"""
Create a marker for labeling and referencing.
Parameters:
- name: str, unique identifier for the marker
- prefix: str, optional prefix for organization (e.g., 'fig', 'eq', 'sec')
- del_invalid_char: bool, automatically remove invalid characters
"""
class Label(RefLabelBase):
def __init__(self, marker):
"""
Create a label at current position.
Parameters:
- marker: str or Marker, label identifier
"""
class Ref(RefLabelBase):
def __init__(self, marker):
"""
Create a reference to a labeled element.
Parameters:
- marker: str or Marker, label identifier to reference
"""Usage example:
from pylatex import Document, Section, Subsection
from pylatex.labelref import Label, Ref, Marker
doc = Document()
# Create labeled sections
with doc.create(Section('Introduction')) as intro:
intro.append(Label(Marker('intro', 'sec')))
intro.append('This section introduces the main concepts.')
with doc.create(Section('Methods')) as methods:
methods.append(Label(Marker('methods', 'sec')))
methods.append('As discussed in ')
methods.append(Ref(Marker('intro', 'sec')))
methods.append(', we now present the methodology.')
with methods.create(Subsection('Data Collection')) as data:
data.append(Label('data-collection'))
data.append('Details about data collection procedures.')
# Reference sections by number
with doc.create(Section('Results')):
doc.append('Building on the methods from Section ')
doc.append(Ref('methods'))
doc.append(' and specifically ')
doc.append(Ref('data-collection'))
doc.append(', we present our findings.')Reference the page number where a labeled element appears.
class Pageref(RefLabelBase):
def __init__(self, marker):
"""
Reference the page number of a labeled element.
Parameters:
- marker: str or Marker, label identifier to reference
"""Usage example:
from pylatex import Document, Section, NewPage
from pylatex.labelref import Label, Ref, Pageref
doc = Document()
with doc.create(Section('First Section')):
doc.append(Label('first-section'))
doc.append('This content appears on the first page.')
doc.append(NewPage())
with doc.create(Section('Later Section')):
doc.append('Reference to Section ')
doc.append(Ref('first-section'))
doc.append(' on page ')
doc.append(Pageref('first-section'))
doc.append(' contains important background information.')Specialized referencing for mathematical equations with proper formatting.
class Eqref(RefLabelBase):
def __init__(self, marker):
"""
Reference an equation with proper formatting.
Parameters:
- marker: str or Marker, equation label identifier
Requires:
- amsmath package (automatically added)
"""Usage example:
from pylatex import Document, Section, NoEscape
from pylatex.math import Alignat
from pylatex.labelref import Label, Eqref
doc = Document()
with doc.create(Section('Mathematical Analysis')):
# Labeled equations
with doc.create(Alignat(numbering=True)) as equations:
equations.append(NoEscape(r'E &= mc^2'))
equations.append(Label('einstein'))
equations.append(NoEscape(r'\\'))
equations.append(NoEscape(r'F &= ma'))
equations.append(Label('newton'))
equations.append(NoEscape(r'\\'))
equations.append(NoEscape(r'a &= \frac{F}{m}'))
equations.append(Label('acceleration'))
# Reference equations
doc.append('From Einstein\'s mass-energy equivalence ')
doc.append(Eqref('einstein'))
doc.append(' and Newton\'s second law ')
doc.append(Eqref('newton'))
doc.append(', we can derive the acceleration formula ')
doc.append(Eqref('acceleration'))
doc.append('.')Advanced referencing with automatic context-aware formatting.
class Autoref(RefLabelBase):
def __init__(self, marker):
"""
Automatic reference with type prefix (e.g., 'Figure 1', 'Section 2').
Parameters:
- marker: str or Marker, label identifier
Requires:
- hyperref package
"""
class Cref(RefLabelBase):
def __init__(self, marker):
"""
Clever reference with intelligent formatting.
Parameters:
- marker: str or Marker, label identifier
Requires:
- cleveref package (automatically added)
"""
class Hyperref(RefLabelBase):
def __init__(self, marker, text=None):
"""
Create hyperlinked reference.
Parameters:
- marker: str or Marker, label identifier
- text: str, custom link text (optional)
Requires:
- hyperref package
"""Usage example:
from pylatex import Document, Section, Package
from pylatex.figure import Figure
from pylatex.table import Table, Tabular
from pylatex.labelref import Label, Autoref, Cref
doc = Document()
doc.packages.append(Package('hyperref'))
doc.packages.append(Package('cleveref'))
with doc.create(Section('Results')) as results:
results.append(Label('results'))
# Labeled figure
with results.create(Figure(position='htbp')) as fig:
fig.add_image('data_plot.png')
fig.add_caption('Experimental data visualization.')
fig.append(Label('fig:data'))
# Labeled table
with results.create(Table(position='htbp')) as table:
table.add_caption('Summary statistics.')
table.append(Label('tab:stats'))
with table.create(Tabular('lcc')) as tabular:
tabular.add_row(['Metric', 'Value', 'Error'])
tabular.add_hline()
tabular.add_row(['Mean', '12.5', '±0.3'])
tabular.add_row(['StdDev', '2.1', '±0.1'])
with doc.create(Section('Discussion')):
# Automatic references with type detection
doc.append(Autoref('fig:data')) # Produces "Figure 1"
doc.append(' shows the trend, while ')
doc.append(Autoref('tab:stats')) # Produces "Table 1"
doc.append(' provides numerical summaries.')
# Clever references with better formatting
doc.append(' As shown in ')
doc.append(Cref('results')) # Produces "section 1" with proper formatting
doc.append(', the data supports our hypothesis.')from pylatex import Document, Section, NoEscape
from pylatex.labelref import Label, Ref
doc = Document()
# Multiple labeled items
with doc.create(Section('Multiple Items')):
doc.append('Item A')
doc.append(Label('item-a'))
doc.append(' and Item B')
doc.append(Label('item-b'))
doc.append(' and Item C')
doc.append(Label('item-c'))
# Reference multiple items
with doc.create(Section('References')):
doc.append('Items ')
doc.append(Ref('item-a'))
doc.append(', ')
doc.append(Ref('item-b'))
doc.append(', and ')
doc.append(Ref('item-c'))
doc.append(' are all related.')
# Using cleveref for range references
doc.append('Items ')
doc.append(NoEscape(r'\crefrange{item-a}{item-c}')) # Produces "items 1 to 3"
doc.append(' form a series.')from pylatex import Document, Section, Package, Command, NoEscape
from pylatex.labelref import Label, Cref
doc = Document()
doc.packages.append(Package('cleveref'))
# Define custom reference types
doc.preamble.append(Command('crefname', arguments=['algorithm', 'Algorithm', 'Algorithms']))
doc.preamble.append(Command('Crefname', arguments=['algorithm', 'Algorithm', 'Algorithms']))
with doc.create(Section('Algorithms')):
# Custom labeled environment
doc.append(NoEscape(r'\refstepcounter{algorithm}'))
doc.append(NoEscape(r'\textbf{Algorithm \thealgorithm}:'))
doc.append(Label('alg:quicksort'))
doc.append(' Quicksort implementation.')
doc.append(NoEscape(r'\refstepcounter{algorithm}'))
doc.append(NoEscape(r'\textbf{Algorithm \thealgorithm}:'))
doc.append(Label('alg:mergesort'))
doc.append(' Mergesort implementation.')
with doc.create(Section('Analysis')):
doc.append(Cref('alg:quicksort')) # Produces "Algorithm 1"
doc.append(' has better average case performance than ')
doc.append(Cref('alg:mergesort')) # Produces "Algorithm 2"
doc.append('.')from pylatex import Document, Chapter, Section, Subsection
from pylatex.labelref import Label, Ref, Marker
doc = Document(documentclass='report')
# Organized label hierarchy
with doc.create(Chapter('Introduction')) as intro:
intro.append(Label(Marker('introduction', 'chap')))
with intro.create(Section('Background')) as bg:
bg.append(Label(Marker('background', 'sec')))
with bg.create(Subsection('Historical Context')) as hist:
hist.append(Label(Marker('history', 'subsec')))
hist.append('Historical overview of the field.')
with bg.create(Subsection('Current State')) as current:
current.append(Label(Marker('current', 'subsec')))
current.append('Current developments in the area.')
with doc.create(Chapter('Methods')) as methods:
methods.append(Label(Marker('methods', 'chap')))
methods.append('Building on the background from ')
methods.append(Ref(Marker('background', 'sec')))
methods.append(' in ')
methods.append(Ref(Marker('introduction', 'chap')))
methods.append(', we now present our approach.')from pylatex import Document, Section
from pylatex.figure import Figure, SubFigure
from pylatex.table import Table, Tabular
from pylatex.labelref import Label, Ref, Autoref
doc = Document()
with doc.create(Section('Data Presentation')):
# Multi-panel figure with individual labels
with doc.create(Figure(position='htbp')) as fig:
with fig.create(SubFigure(width=NoEscape(r'0.45\textwidth'))) as subfig_a:
subfig_a.add_image('plot_a.png')
subfig_a.add_caption('Dataset A results.')
subfig_a.append(Label('fig:data-a'))
fig.append(NoEscape(r'\hfill'))
with fig.create(SubFigure(width=NoEscape(r'0.45\textwidth'))) as subfig_b:
subfig_b.add_image('plot_b.png')
subfig_b.add_caption('Dataset B results.')
subfig_b.append(Label('fig:data-b'))
fig.add_caption('Comparison of experimental datasets.')
fig.append(Label('fig:comparison'))
# Complex table with sections
with doc.create(Table(position='htbp')) as table:
table.add_caption('Detailed experimental results.')
table.append(Label('tab:results'))
with table.create(Tabular('lccc')) as tabular:
tabular.add_row(['Parameter', 'Method A', 'Method B', 'Method C'])
tabular.add_hline()
tabular.add_row(['Accuracy', '92.3%', '89.7%', '94.1%'])
tabular.add_row(['Speed', '150ms', '200ms', '120ms'])
with doc.create(Section('Discussion')):
doc.append('The results shown in ')
doc.append(Autoref('fig:comparison'))
doc.append(' demonstrate clear trends. Specifically, ')
doc.append(Ref('fig:data-a'))
doc.append(' shows one pattern while ')
doc.append(Ref('fig:data-b'))
doc.append(' shows another. The quantitative analysis in ')
doc.append(Autoref('tab:results'))
doc.append(' supports these observations.')from pylatex.labelref import Label, Marker
# Recommended naming patterns
figure_labels = [
Marker('architecture', 'fig'), # fig:architecture
Marker('results-plot', 'fig'), # fig:results-plot
Marker('comparison', 'fig') # fig:comparison
]
section_labels = [
Marker('introduction', 'sec'), # sec:introduction
Marker('methodology', 'sec'), # sec:methodology
Marker('conclusions', 'sec') # sec:conclusions
]
equation_labels = [
Marker('energy-conservation', 'eq'), # eq:energy-conservation
Marker('momentum', 'eq'), # eq:momentum
Marker('angular-momentum', 'eq') # eq:angular-momentum
]from pylatex import Document, Section
from pylatex.figure import Figure
from pylatex.labelref import Label, Ref, Marker
def create_labeled_figure(doc, image_path, caption, label_name):
"""Create a figure with automatic labeling."""
with doc.create(Figure(position='htbp')) as fig:
fig.add_image(image_path)
fig.add_caption(caption)
fig.append(Label(Marker(label_name, 'fig')))
return f'fig:{label_name}'
def create_labeled_section(doc, title, label_name):
"""Create a section with automatic labeling."""
section = doc.create(Section(title))
section.append(Label(Marker(label_name, 'sec')))
return section, f'sec:{label_name}'
# Usage
doc = Document()
# Create labeled content
section, sec_label = create_labeled_section(doc, 'Results', 'results')
with section:
fig_label = create_labeled_figure(doc, 'plot.png', 'Main results', 'main-plot')
doc.append('This section presents findings as shown in ')
doc.append(Ref(fig_label))
doc.append('.')
# Reference the section later
with doc.create(Section('Discussion')):
doc.append('As demonstrated in ')
doc.append(Ref(sec_label))
doc.append(', our approach is effective.')from pylatex import Document, Package, Command
from pylatex.labelref import Label, Ref
# Enable cross-document references
doc = Document()
doc.packages.append(Package('xr'))
doc.preamble.append(Command('externaldocument', arguments='other-document'))
# Reference labels from other documents
with doc.create(Section('Related Work')):
doc.append('As shown in the previous report ')
doc.append(Ref('other-doc:main-result')) # From other-document.tex
doc.append(', this approach has been validated.')Reference functionality requires specific LaTeX packages:
amsmath package (automatically added with Eqref)hyperref packagecleveref package (automatically added with Cref)xr packagefrom pylatex import Document, Package
doc = Document()
# Reference packages
doc.packages.append(Package('hyperref'))
doc.packages.append(Package('cleveref'))
doc.packages.append(Package('xr'))# Clear, descriptive labels
Label('fig:system-architecture') # Good
Label('fig1') # Avoid
# Consistent prefixes
Label('sec:methodology')
Label('sec:results')
Label('sec:conclusions')
# Hierarchical organization
Label('sec:methods')
Label('subsec:data-collection')
Label('subsubsec:survey-design')from pylatex import Document, NoEscape
from pylatex.labelref import Ref, Autoref
doc = Document()
# Use appropriate reference types
doc.append(Autoref('fig:results')) # "Figure 1"
doc.append(' shows that...')
doc.append('As seen in ')
doc.append(Ref('sec:methods')) # "2" (section number only)
doc.append(', we used...')
# Combine with text for clarity
doc.append('Section ')
doc.append(Ref('sec:background'))
doc.append(' provides context.')The reference system in PyLaTeX enables professional document cross-referencing with automatic numbering, intelligent formatting, and seamless integration with LaTeX's native labeling capabilities.
Install with Tessl CLI
npx tessl i tessl/pypi-pylatex