A comprehensive Python document processing library that renders structured documents to PDF with advanced typography and customizable styling
—
Comprehensive document template system providing page layouts, headers/footers, document structure configuration, and template-based document generation. The template system enables consistent document formatting and professional layouts across different document types.
Core template classes that define overall document structure, page layouts, and formatting rules.
class DocumentTemplate(TemplateConfiguration):
"""
Base class for document templates defining structure and layout.
Provides the foundation for creating different document types with
consistent formatting, page layouts, and structural elements.
Parameters:
- name: str, template name identifier
- configuration: TemplateConfiguration, template settings
"""
def __init__(self, name=None, configuration=None): ...
@property
def stylesheet(self): ... # Associated stylesheet
@property
def parts(self): ... # Document parts configuration
def document(self, document_tree, stylesheet=None, language=None,
backend=None): ... # Create document with this template
class Article(DocumentTemplate):
"""
Article template for academic papers, reports, and articles.
Provides single-column layout with title page, abstract, sections,
and appropriate styling for scholarly documents.
"""
def __init__(self): ...
class Book(DocumentTemplate):
"""
Book template for multi-chapter documents and publications.
Provides book-style layout with chapters, table of contents,
index, and appropriate pagination for longer documents.
"""
def __init__(self): ...Configuration system for customizing template behavior, options, and document structure.
class TemplateConfiguration(RuleSet):
"""
Configuration container for template settings and options.
Manages template-specific settings including page layouts,
document parts, styling rules, and behavioral options.
Parameters:
- name: str, configuration name
- base: TemplateConfiguration, base configuration to inherit from
- **options: configuration option key-value pairs
"""
def __init__(self, name, base=None, **options): ...
def get_entry_point_flowables(self, document_part): ... # Get part content
def get_page_template(self, document_part, page_type): ... # Get page template
class TemplateConfigurationFile(TemplateConfiguration):
"""
Template configuration loaded from file.
Parameters:
- file: str or file-like, path to or open template configuration file
"""
def __init__(self, file): ...
class Option:
"""
Template option descriptor with validation and default values.
Defines configurable options for templates with type checking,
validation, and documentation.
Parameters:
- default: default value for the option
- description: str, option description
- validator: callable, validation function
"""
def __init__(self, default, description=None, validator=None): ...Page layout templates defining the structure and positioning of page elements.
class PageTemplate:
"""
Base class for page layout templates.
Defines the structure of a page including margins, headers, footers,
and content areas with precise positioning and sizing.
Parameters:
- name: str, page template name
- page_size: Paper, page dimensions
- page_orientation: str, 'portrait' or 'landscape'
- left_margin: Dimension, left page margin
- right_margin: Dimension, right page margin
- top_margin: Dimension, top page margin
- bottom_margin: Dimension, bottom page margin
"""
def __init__(self, name, page_size, page_orientation='portrait',
left_margin=None, right_margin=None,
top_margin=None, bottom_margin=None): ...
@property
def page_size(self): ... # Page dimensions
@property
def page_orientation(self): ... # Page orientation
@property
def body_width(self): ... # Content area width
@property
def body_height(self): ... # Content area height
class BodyPageTemplate(PageTemplate):
"""
Page template for main document content pages.
Provides standard layout for body text with headers, footers,
and content area configuration.
"""
def __init__(self, page_size, page_orientation='portrait', **margins): ...
class TitlePageTemplate(PageTemplate):
"""
Page template for document title/cover pages.
Specialized layout for title pages with different margins,
content positioning, and styling from body pages.
"""
def __init__(self, page_size, page_orientation='portrait', **margins): ...
class ContentsPartTemplate(PageTemplate):
"""
Page template for table of contents and similar navigation pages.
Optimized layout for multi-column content lists with appropriate
spacing and formatting for navigation elements.
"""
def __init__(self, page_size, columns=1, **kwargs): ...
class FixedDocumentPartTemplate(PageTemplate):
"""
Page template for fixed-content document parts.
Used for document parts with predetermined content and layout
that doesn't flow like regular body text.
"""
def __init__(self, flowables, **kwargs): ...Specialized page components and type definitions for different parts of documents.
class BodyPage:
"""
Definition for main content pages in document body.
Specifies layout, headers, footers, and content flow for
the primary text content of documents.
"""
def __init__(self, page_template, header=None, footer=None): ...
class TitlePage:
"""
Definition for document title/cover pages.
Specialized page for title content with different layout
and formatting from body pages.
"""
def __init__(self, page_template, content): ...
class PageNumberFormat:
"""
Page numbering format and positioning configuration.
Controls how page numbers are formatted, positioned, and
displayed across different document parts.
Parameters:
- format: NumberFormat, numbering format (arabic, roman, etc.)
- start: int, starting page number
- restart: bool, whether to restart numbering
"""
def __init__(self, format=NUMBER, start=1, restart=False): ...Document part system for organizing content into logical sections with different layouts and numbering.
class DocumentPart:
"""
Logical section of document with specific template and numbering.
Represents distinct parts of documents (front matter, body, appendices)
that may have different page templates, numbering, and formatting.
Parameters:
- name: str, part identifier
- page_template: PageTemplate, layout for this part
- page_number_format: PageNumberFormat, numbering configuration
- flowables: list, content for this part
"""
def __init__(self, name, page_template=None, page_number_format=None,
flowables=None): ...
class FrontMatter(DocumentPart):
"""Document front matter (title page, TOC, abstract, etc.)."""
class Body(DocumentPart):
"""Main document body content."""
class BackMatter(DocumentPart):
"""Document back matter (appendices, index, bibliography, etc.)."""Utility functions and classes for template management and document generation.
def register_template(name, template_class):
"""
Register template class for use by name.
Parameters:
- name: str, template identifier
- template_class: class, DocumentTemplate subclass
"""
...
def get_template(name):
"""
Get registered template by name.
Parameters:
- name: str, template identifier
Returns:
- DocumentTemplate subclass
"""
...
class TemplateConfigurationError(Exception):
"""Exception for template configuration errors."""
class PageLayoutError(Exception):
"""Exception for page layout errors."""from rinohtype.template import Article, Book
from rinohtype import Document, DocumentTree
from rinohtype.structure import Section, Heading
from rinohtype.paragraph import Paragraph
# Create document content
content = DocumentTree([
Section([
Heading("Introduction"),
Paragraph("This is the introduction...")
])
])
# Use article template
article_template = Article()
document = article_template.document(content)
document.render('article_output')
# Use book template
book_template = Book()
book_document = book_template.document(content)
book_document.render('book_output')from rinohtype.template import DocumentTemplate, TemplateConfiguration
from rinohtype.template import BodyPageTemplate, TitlePageTemplate
from rinohtype.paper import A4
from rinohtype.dimension import MM
class CustomTemplate(DocumentTemplate):
"""Custom document template with specific formatting."""
def __init__(self):
# Define page templates
body_template = BodyPageTemplate(
page_size=A4,
left_margin=25*MM,
right_margin=25*MM,
top_margin=30*MM,
bottom_margin=25*MM
)
title_template = TitlePageTemplate(
page_size=A4,
left_margin=40*MM,
right_margin=40*MM,
top_margin=50*MM,
bottom_margin=50*MM
)
# Create configuration
config = TemplateConfiguration('custom')
config['body_page'] = body_template
config['title_page'] = title_template
super().__init__('custom', config)
# Use custom template
custom_template = CustomTemplate()
document = custom_template.document(content)from rinohtype.template import BodyPageTemplate, PageNumberFormat
from rinohtype.structure import Header, Footer
from rinohtype.reference import Field, PAGE_NUMBER, DOCUMENT_TITLE
from rinohtype.text import SingleStyledText
from rinohtype.paper import LETTER
from rinohtype.dimension import INCH
# Create page template with headers and footers
page_template = BodyPageTemplate(
page_size=LETTER,
left_margin=1*INCH,
right_margin=1*INCH,
top_margin=0.75*INCH,
bottom_margin=0.75*INCH
)
# Define header content
header_content = Header([
Paragraph([SingleStyledText("Document Title")])
])
# Define footer with page numbers
footer_content = Footer([
Paragraph([
SingleStyledText("Page "),
Field(PAGE_NUMBER),
SingleStyledText(" of "),
Field(NUMBER_OF_PAGES)
])
])
# Configure page numbering
page_numbering = PageNumberFormat(
format=NUMBER, # Arabic numerals
start=1,
restart=False
)from rinohtype.template import DocumentTemplate, FrontMatter, Body, BackMatter
from rinohtype.template import TitlePageTemplate, BodyPageTemplate
from rinohtype.number import ROMAN_LC, NUMBER
class ThesisTemplate(DocumentTemplate):
"""Template for academic thesis with multiple parts."""
def __init__(self):
config = TemplateConfiguration('thesis')
# Title page template
title_template = TitlePageTemplate(A4, top_margin=50*MM)
# Front matter template (TOC, abstract, etc.)
front_template = BodyPageTemplate(A4)
front_numbering = PageNumberFormat(format=ROMAN_LC, start=1)
# Body template
body_template = BodyPageTemplate(A4)
body_numbering = PageNumberFormat(format=NUMBER, start=1, restart=True)
# Back matter template (appendices, bibliography)
back_template = BodyPageTemplate(A4)
back_numbering = PageNumberFormat(format=NUMBER, restart=False)
# Configure document parts
config.document_parts = [
FrontMatter('front', front_template, front_numbering),
Body('body', body_template, body_numbering),
BackMatter('back', back_template, back_numbering)
]
super().__init__('thesis', config)from rinohtype.template import Option, TemplateConfiguration
class ConfigurableTemplate(DocumentTemplate):
"""Template with configurable options."""
# Define template options
font_size = Option(11, "Base font size in points")
line_spacing = Option(1.2, "Line spacing multiplier")
two_column = Option(False, "Use two-column layout")
def __init__(self, **options):
config = TemplateConfiguration('configurable')
# Apply options
for name, value in options.items():
if hasattr(self, name):
setattr(self, name, value)
# Configure based on options
if self.two_column:
config['columns'] = 2
else:
config['columns'] = 1
super().__init__('configurable', config)
# Use with options
template = ConfigurableTemplate(
font_size=12,
line_spacing=1.5,
two_column=True
)from rinohtype.template import register_template
# Register custom template
register_template('custom_article', CustomTemplate)
# Use registered template by name
def create_document_with_template(content, template_name):
template_class = get_template(template_name)
template = template_class()
return template.document(content)
document = create_document_with_template(content, 'custom_article')from rinohtype.template import PageTemplate
from rinohtype.layout import Container, DownExpandingContainer
class CustomPageTemplate(PageTemplate):
"""Custom page template with special layout."""
def __init__(self, **kwargs):
super().__init__('custom_page', **kwargs)
def create_page_containers(self, page):
"""Create custom container layout."""
# Main content area
content_container = DownExpandingContainer(
'content',
parent=page,
left=self.left_margin,
top=self.top_margin,
width=self.body_width
)
# Sidebar container
sidebar_container = DownExpandingContainer(
'sidebar',
parent=page,
left=self.left_margin + self.body_width + 10*MM,
top=self.top_margin,
width=40*MM
)
return {
'content': content_container,
'sidebar': sidebar_container
}from rinohtype.template import TemplateConfigurationError, PageLayoutError
def safe_template_creation():
"""Create template with error handling."""
try:
template = CustomTemplate()
return template
except TemplateConfigurationError as e:
print(f"Template configuration error: {e}")
# Fall back to default template
return Article()
except PageLayoutError as e:
print(f"Page layout error: {e}")
return None
def validate_template_options(template, **options):
"""Validate template options before use."""
for name, value in options.items():
if not hasattr(template, name):
raise TemplateConfigurationError(f"Unknown option: {name}")
option = getattr(template.__class__, name)
if hasattr(option, 'validator') and option.validator:
if not option.validator(value):
raise TemplateConfigurationError(f"Invalid value for {name}: {value}")Install with Tessl CLI
npx tessl i tessl/pypi-rinohtype