CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pylatex

A comprehensive Python library for programmatically creating and compiling LaTeX documents and snippets.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

layout.mddocs/

Layout and Positioning

Advanced layout control with positioning, spacing, alignment, and minipage environments for precise document formatting. PyLaTeX provides comprehensive tools for managing document layout, from simple spacing commands to complex multi-column layouts and precise element positioning.

Capabilities

Spacing Commands

Control horizontal and vertical spacing between document elements with precise measurements.

class HorizontalSpace(CommandBase):
    def __init__(self, size, *, star=True):
        """
        Add horizontal space between elements.
        
        Parameters:
        - size: str, amount of space to add (e.g., '1cm', '10pt', '0.5in')
        - star: bool, use starred version (hspace*) that doesn't disappear at line breaks
        """

class VerticalSpace(CommandBase):
    def __init__(self, size, *, star=True):
        """
        Add vertical space between elements.
        
        Parameters:
        - size: str, amount of space to add (e.g., '1cm', '10pt', '0.5em')
        - star: bool, use starred version (vspace*) that doesn't disappear at page breaks
        """

Usage example:

from pylatex import Document, Section, NoEscape
from pylatex.position import HorizontalSpace, VerticalSpace

doc = Document()

with doc.create(Section('Spacing Examples')):
    doc.append('Text before horizontal space')
    doc.append(HorizontalSpace('2cm'))
    doc.append('Text after 2cm space')
    
    doc.append(VerticalSpace('1cm'))
    doc.append('Text after 1cm vertical space')
    
    # Negative spacing (overlap)
    doc.append('Overlapping')
    doc.append(HorizontalSpace('-0.5cm'))
    doc.append('Text')
    
    # Various units
    doc.append(VerticalSpace('2em'))  # Relative to font size
    doc.append('Text after 2em space')
    
    doc.append(VerticalSpace('12pt'))  # Points
    doc.append('Text after 12pt space')
    
    doc.append(VerticalSpace('0.2in'))  # Inches
    doc.append('Text after 0.2 inch space')

Alignment Environments

Control text and content alignment within specific regions of the document.

class Center(Environment):
    """
    Center-aligned environment.
    
    Requires:
    - ragged2e package (automatically added)
    """

class FlushLeft(Environment):
    """
    Left-aligned environment.
    
    Requires:
    - ragged2e package (automatically added)
    """

class FlushRight(Environment):
    """
    Right-aligned environment.
    
    Requires:
    - ragged2e package (automatically added)
    """

Usage example:

from pylatex import Document, Section
from pylatex.position import Center, FlushLeft, FlushRight

doc = Document()

with doc.create(Section('Text Alignment')):
    with doc.create(Center()):
        doc.append('This text is centered on the page.')
        doc.append('Multiple lines are all centered.')
    
    with doc.create(FlushLeft()):
        doc.append('This text is left-aligned.')
        doc.append('Even in a document with different default alignment.')
    
    with doc.create(FlushRight()):
        doc.append('This text is right-aligned.')
        doc.append('Useful for signatures or dates.')

# Centering specific elements
with doc.create(Section('Centered Elements')):
    doc.append('Normal paragraph text flows naturally.')
    
    with doc.create(Center()):
        doc.append('--- Important Notice ---')
    
    doc.append('Back to normal text flow after the centered element.')

MiniPage Environment

Create flexible sub-documents within the main document with independent formatting and layout control.

class MiniPage(Environment):
    def __init__(self, *, width=NoEscape(r"\textwidth"), pos=None, 
                 height=None, content_pos=None, align=None, 
                 fontsize=None, data=None):
        """
        Create a minipage environment for complex layouts.
        
        Parameters:
        - width: str or NoEscape, width of minipage (default: full text width)
        - pos: str, vertical alignment relative to baseline ('c', 't', 'b')
          - 'c': center (default)
          - 't': top
          - 'b': bottom
        - height: str, fixed height of minipage
        - content_pos: str, content position within minipage ('c', 't', 'b', 's')
          - 'c': center
          - 't': top
          - 'b': bottom
          - 's': stretch (spread content)
        - align: str, text alignment within minipage
        - fontsize: str, font size for minipage content
        - data: initial content
        
        Requires:
        - ragged2e package (automatically added)
        """

Usage example:

from pylatex import Document, Section, NoEscape
from pylatex.position import MiniPage
from pylatex.figure import StandAloneGraphic

doc = Document()

with doc.create(Section('Complex Layouts')):
    # Side-by-side content
    with doc.create(MiniPage(width=NoEscape(r'0.45\textwidth'))) as left:
        left.append('This is the left column content. ')
        left.append('It can contain multiple paragraphs and will wrap ')
        left.append('within the specified width.')
    
    doc.append(NoEscape(r'\hfill'))  # Push to opposite sides
    
    with doc.create(MiniPage(width=NoEscape(r'0.45\textwidth'))) as right:
        right.append('This is the right column content. ')
        right.append('Both minipages will appear side by side ')
        right.append('on the same horizontal line.')

# Text and image layout
with doc.create(Section('Mixed Content Layout')):
    with doc.create(MiniPage(width=NoEscape(r'0.6\textwidth'), 
                           pos='t')) as text_box:
        text_box.append('Detailed explanation of the concept. ')
        text_box.append('This text appears alongside the diagram. ')
        text_box.append('The minipage allows precise control over ')
        text_box.append('the text width and positioning.')
    
    doc.append(NoEscape(r'\hfill'))
    
    with doc.create(MiniPage(width=NoEscape(r'0.35\textwidth'), 
                           pos='t')) as image_box:
        image_box.append(StandAloneGraphic('diagram.png', 
                                         image_options=NoEscape(r'width=\textwidth')))

# Vertical alignment examples
with doc.create(Section('Vertical Alignment')):
    with doc.create(MiniPage(width=NoEscape(r'0.3\textwidth'), 
                           height='4cm', pos='t', content_pos='t')) as top:
        top.append('Content aligned to top of minipage.')
    
    doc.append(NoEscape(r'\hfill'))
    
    with doc.create(MiniPage(width=NoEscape(r'0.3\textwidth'), 
                           height='4cm', pos='t', content_pos='c')) as center:
        center.append('Content centered in minipage.')
    
    doc.append(NoEscape(r'\hfill'))
    
    with doc.create(MiniPage(width=NoEscape(r'0.3\textwidth'), 
                           height='4cm', pos='t', content_pos='b')) as bottom:
        bottom.append('Content aligned to bottom.')

Advanced Layout Patterns

Multi-Column Layouts

from pylatex import Document, Section, NoEscape
from pylatex.position import MiniPage

doc = Document()

with doc.create(Section('Three-Column Layout')):
    # Three equal columns
    column_width = NoEscape(r'0.32\textwidth')
    
    with doc.create(MiniPage(width=column_width, pos='t')) as col1:
        col1.append('First Column')
        col1.append('Content for the first column goes here. ')
        col1.append('This could be text, lists, or other elements.')
    
    doc.append(NoEscape(r'\hfill'))
    
    with doc.create(MiniPage(width=column_width, pos='t')) as col2:
        col2.append('Second Column')
        col2.append('Content for the second column. ')
        col2.append('Each column is independent.')
    
    doc.append(NoEscape(r'\hfill'))
    
    with doc.create(MiniPage(width=column_width, pos='t')) as col3:
        col3.append('Third Column')
        col3.append('Final column content. ')
        col3.append('Columns align at the top.')

# Asymmetric layout
with doc.create(Section('Asymmetric Layout')):
    # Wide left, narrow right
    with doc.create(MiniPage(width=NoEscape(r'0.7\textwidth'))) as main:
        main.append('Main Content Area')
        main.append('This wider area contains the primary content. ')
        main.append('It takes up most of the page width.')
    
    doc.append(NoEscape(r'\hfill'))
    
    with doc.create(MiniPage(width=NoEscape(r'0.25\textwidth'))) as sidebar:
        sidebar.append('Sidebar')
        sidebar.append('Notes, references, or supplementary information.')

Boxed Content

from pylatex import Document, Section, Command, NoEscape
from pylatex.position import MiniPage, Center

doc = Document()

with doc.create(Section('Boxed Content')):
    # Framed minipage
    with doc.create(Center()):
        doc.append(Command('fbox', 
            MiniPage(width=NoEscape(r'0.8\textwidth'), data=[
                'Important Information',
                NoEscape(r'\\[0.5em]'),
                'This content is highlighted in a box for emphasis. ',
                'The minipage provides the content structure, while ',
                'fbox adds the border.'
            ])
        ))

# Custom spacing and padding
with doc.create(Section('Padded Boxes')):
    with doc.create(Center()):
        # Custom padding using fboxsep
        doc.append(Command('setlength', arguments=[NoEscape(r'\fboxsep'), '10pt']))
        doc.append(Command('fbox',
            MiniPage(width=NoEscape(r'0.6\textwidth'), data=[
                'Padded Content',
                NoEscape(r'\\[0.5em]'),
                'Extra padding makes this more readable.'
            ])
        ))

Header and Footer Layouts

from pylatex import Document, Section, NoEscape
from pylatex.position import MiniPage, FlushLeft, FlushRight, Center

doc = Document()

# Custom header layout
def create_header(title, author, date):
    with doc.create(MiniPage(width=NoEscape(r'\textwidth'))) as header:
        with header.create(FlushLeft()):
            header.append(f'Title: {title}')
        
        with header.create(Center()):
            header.append(f'Author: {author}')
        
        with header.create(FlushRight()):
            header.append(f'Date: {date}')
    
    doc.append(NoEscape(r'\hrule'))
    doc.append(NoEscape(r'\vspace{1em}'))

create_header('Research Report', 'Dr. Jane Smith', '2024-01-15')

with doc.create(Section('Document Content')):
    doc.append('Main document content follows the custom header.')

Text Block Positioning

class TextBlock(Environment):
    def __init__(self, width, horizontal_pos, vertical_pos, *, 
                 indent=False, data=None):
        """
        Create positioned text block using textpos package.
        
        Parameters:
        - width: float, width of text block in TPHorizModule units
        - horizontal_pos: float, horizontal position in TPHorizModule units
        - vertical_pos: float, vertical position in TPVertModule units
        - indent: bool, enable paragraph indentation (default False)
        - data: initial content for the text block
        
        Requires:
        - textpos package (automatically added)
        """

Usage example:

from pylatex import Document, Package
from pylatex.position import TextBlock

doc = Document()
doc.packages.append(Package('textpos'))

# Absolute positioning
with doc.create(TextBlock(width='5cm', horizontal_pos=2, vertical_pos=3)):
    doc.append('This text block is positioned at specific coordinates.')
    doc.append('Useful for overlays, annotations, or precise layouts.')

Layout Utilities and Helpers

Flexible Spacing

from pylatex import Document, NoEscape
from pylatex.position import HorizontalSpace, VerticalSpace

doc = Document()

# Responsive spacing
doc.append('Text')
doc.append(HorizontalSpace(NoEscape(r'0.1\textwidth')))  # 10% of text width
doc.append('More text')

# Fill remaining space
doc.append('Left')
doc.append(NoEscape(r'\hfill'))  # Fills all available space
doc.append('Right')

# Stretchable space
doc.append('Item 1')
doc.append(NoEscape(r'\hspace{\stretch{1}}'))
doc.append('Item 2')
doc.append(NoEscape(r'\hspace{\stretch{2}}'))  # Twice as much space
doc.append('Item 3')

Page Layout Control

from pylatex import Document, Command, Package, NoEscape
from pylatex.position import VerticalSpace

doc = Document()
doc.packages.append(Package('geometry', options=['margin=1in']))

# Page-level spacing adjustments
doc.preamble.append(Command('setlength', arguments=[NoEscape(r'\parskip'), '1em']))
doc.preamble.append(Command('setlength', arguments=[NoEscape(r'\parindent'), '0pt']))

# Dynamic page breaks
doc.append('Content before page break')
doc.append(VerticalSpace(NoEscape(r'\fill')))  # Push to bottom
doc.append('Content at bottom of page')
doc.append(Command('newpage'))
doc.append('Content on next page')

Advanced Layout Techniques

Overlay Positioning

from pylatex import Document, Package, NoEscape, Command
from pylatex.position import MiniPage

doc = Document()
doc.packages.append(Package('tikz'))

# TikZ overlay on minipage
with doc.create(MiniPage(width=NoEscape(r'0.8\textwidth'))) as container:
    container.append('Base content that will have overlays.')
    container.append(NoEscape(r'\\[2em]'))
    container.append('More base content here.')
    
    # Add TikZ overlay
    container.append(NoEscape(r'''
        \begin{tikzpicture}[remember picture, overlay]
            \node[red, font=\Large] at (2, 0) {Overlay Text};
            \draw[blue, thick] (0, -1) rectangle (4, 1);
        \end{tikzpicture}
    '''))

Responsive Layouts

from pylatex import Document, Command, NoEscape
from pylatex.position import MiniPage

doc = Document()

# Conditional layout based on text width
doc.preamble.append(Command('newlength', arguments=NoEscape(r'\columnwidth')))
doc.preamble.append(Command('setlength', arguments=[
    NoEscape(r'\columnwidth'), NoEscape(r'0.45\textwidth')
]))

# Use calculated width
with doc.create(MiniPage(width=NoEscape(r'\columnwidth'))) as responsive:
    responsive.append('This minipage uses a calculated width.')
    responsive.append('It adapts to different document settings.')

Package Dependencies

Layout functionality requires specific LaTeX packages:

  • Basic spacing: No additional packages
  • Alignment environments: ragged2e package (automatically added)
  • MiniPage: ragged2e package (automatically added)
  • TextBlock: textpos package (must be added manually)
  • Advanced positioning: tikz package for overlays
from pylatex import Document, Package

doc = Document()

# Layout packages
doc.packages.append(Package('ragged2e'))
doc.packages.append(Package('textpos'))
doc.packages.append(Package('tikz'))
doc.packages.append(Package('geometry', options=['margin=1in']))

Layout Best Practices

Consistent Spacing

from pylatex import Document, Command, NoEscape
from pylatex.position import VerticalSpace

doc = Document()

# Define standard spacing units
doc.preamble.append(Command('newlength', arguments=NoEscape(r'\standardspace')))
doc.preamble.append(Command('setlength', arguments=[
    NoEscape(r'\standardspace'), '1em'
]))

# Use consistent spacing throughout
doc.append('Section 1')
doc.append(VerticalSpace(NoEscape(r'\standardspace')))
doc.append('Section 2')
doc.append(VerticalSpace(NoEscape(r'\standardspace')))
doc.append('Section 3')

Modular Layout Components

from pylatex import Document, NoEscape
from pylatex.position import MiniPage, Center

def create_info_box(title, content, width=NoEscape(r'0.8\textwidth')):
    """Create a standardized information box."""
    with doc.create(Center()):
        with doc.create(MiniPage(width=width)) as box:
            with box.create(Center()):
                box.append(Command('textbf', title))
            box.append(NoEscape(r'\\[0.5em]'))
            box.append(content)
    return box

doc = Document()

# Reusable layout components
create_info_box('Important Note', 'This is highlighted information.')
create_info_box('Warning', 'Please review this carefully.')

The layout system in PyLaTeX provides powerful tools for creating professional, precisely controlled document layouts while maintaining the flexibility to adapt to different content requirements.

Install with Tessl CLI

npx tessl i tessl/pypi-pylatex

docs

base-classes.md

configuration.md

document.md

figures.md

index.md

layout.md

lists.md

math.md

quantities.md

references.md

sectioning.md

tables.md

text-formatting.md

tikz.md

utilities.md

tile.json