Modular, Markdown-based documentation generator that makes pdf, docx, html, and more.
—
Foliant's command-line interface provides the primary way to build documentation projects. Built on the cliar library, it features an extensible architecture that supports custom CLI commands and interactive backend selection.
The primary entry point for the Foliant CLI that dynamically inherits from all available CLI extensions.
def entry_point():
"""
Main entry point for the foliant command.
Creates and runs the dynamic Foliant CLI class.
"""
class Foliant(*get_available_clis().values()):
"""
Dynamic CLI class that inherits from all available CLI extensions.
Primary interface for the foliant command-line tool.
"""
def _root(self, version=False):
"""
Root command handler.
Parameters:
- version (bool): Show version and exit if True
"""Foundation class for all CLI extensions providing logging and common functionality.
class BaseCli(Cliar):
"""
Base CLI class that all CLI extensions must inherit from.
Provides logging setup and common CLI functionality.
"""
def __init__(self, logs_dir=None):
"""
Initialize base CLI with logging configuration.
Parameters:
- logs_dir (str, optional): Directory to store log files
"""Core CLI command for building documentation with various backends and output formats.
class Cli(BaseCli):
"""Main CLI class for the make command."""
def make(self, target, backend='', project_path=Path('.'),
config_file_name='foliant.yml', logs_dir='',
quiet=False, keep_tmp=False, debug=False):
"""
Build documentation target with specified backend.
Parameters:
- target (str): Output format (html, pdf, docx, etc.)
- backend (str): Backend to use (mkdocs, pandoc, etc.)
- project_path (Path): Path to Foliant project directory
- config_file_name (str): Configuration file name
- logs_dir (str): Directory for log files
- quiet (bool): Hide output except results
- keep_tmp (bool): Preserve temporary directory after build
- debug (bool): Enable debug logging
Returns:
str: Path to generated output
"""
@staticmethod
def validate_backend(backend: str, target: str) -> bool:
"""
Validate that backend exists and supports target format.
Parameters:
- backend (str): Backend name to validate
- target (str): Target format to check
Returns:
bool: True if valid
Raises:
BackendError: If backend not found or doesn't support target
"""
@staticmethod
def get_matching_backend(target: str, available_backends: Dict[str, Tuple[str]]) -> str:
"""
Find backend that supports target format, with user prompt if multiple.
Parameters:
- target (str): Target format to find backend for
- available_backends (dict): Available backends and their targets
Returns:
str: Selected backend name
Raises:
BackendError: If no matching backend found or user cancels
"""
def get_config(self, project_path: Path, config_file_name: str,
quiet=False, debug=False) -> dict:
"""
Parse and validate project configuration.
Parameters:
- project_path (Path): Project directory path
- config_file_name (str): Configuration file name
- quiet (bool): Suppress output
- debug (bool): Enable debug mode
Returns:
dict: Parsed configuration
Raises:
ConfigError: If configuration parsing fails
"""
def clean_registry(self, project_path):
"""
Clean multiproject cache registry files.
Parameters:
- project_path (str): Project directory path
"""Interactive validation for backend selection prompts.
class BackendValidator(Validator):
"""Validator for interactive backend selection prompt."""
def __init__(self, available_backends: List[str]):
"""
Initialize validator with available backends.
Parameters:
- available_backends (list): List of available backend names
"""
def validate(self, document):
"""
Validate user's backend selection.
Parameters:
- document: Input document from prompt_toolkit
Raises:
ValidationError: If backend not in available list
"""class ConfigError(Exception):
"""Raised when configuration parsing fails."""
class BackendError(Exception):
"""Raised when backend validation or selection fails."""from foliant.cli.make import Cli
from pathlib import Path
# Create CLI instance
cli = Cli()
# Simple HTML build
result = cli.make('html')
print(f"Documentation built at: {result}")
# PDF build with specific backend
result = cli.make('pdf', backend='pandoc')
# Build with full options
result = cli.make(
target='html',
backend='mkdocs',
project_path=Path('/path/to/docs'),
config_file_name='custom.yml',
quiet=True,
debug=False
)from foliant.cli.make import Cli
# Validate backend supports target
try:
Cli.validate_backend('pandoc', 'pdf') # Returns True
Cli.validate_backend('mkdocs', 'pdf') # Raises BackendError
except BackendError as e:
print(f"Backend validation failed: {e}")
# Find matching backend
from foliant.utils import get_available_backends
available = get_available_backends()
backend = Cli.get_matching_backend('html', available)
print(f"Selected backend: {backend}")from foliant.cli.make import Cli
from pathlib import Path
cli = Cli()
try:
config = cli.get_config(
project_path=Path('.'),
config_file_name='foliant.yml',
debug=True
)
print(f"Project title: {config.get('title', 'Untitled')}")
except ConfigError as e:
print(f"Config error: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-foliant