CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-foliant

Modular, Markdown-based documentation generator that makes pdf, docx, html, and more.

Pending
Overview
Eval results
Files

config.mddocs/

Configuration System

Foliant's configuration system provides flexible YAML-based project configuration with extensible tag support for includes, path resolution, and environment variables. The modular parser architecture allows custom configuration features through plugin extensions.

Capabilities

Main Configuration Parser

Dynamic parser class that inherits from all available configuration parsers, providing unified access to all configuration features.

class Parser(*get_available_config_parsers().values()):
    """
    Main configuration parser that combines all available parsers.
    Provides unified interface for parsing foliant.yml files.
    """

Base Configuration Parser

Foundation class for all configuration parsers providing core YAML parsing functionality.

class BaseParser:
    """Base configuration parser with core YAML functionality."""
    
    _defaults = {
        'src_dir': Path('./src'),
        'tmp_dir': Path('./__folianttmp__')
    }
    
    def __init__(self, project_path: Path, config_file_name: str, 
                 logger: Logger, quiet: bool = False):
        """
        Initialize configuration parser.
        
        Parameters:
        - project_path (Path): Path to project directory
        - config_file_name (str): Name of configuration file
        - logger (Logger): Logger instance for parsing messages
        - quiet (bool): Suppress parsing output
        """
    
    def parse(self) -> dict:
        """
        Parse configuration file into Python dictionary.
        Applies defaults and converts paths to Path objects.
        
        Returns:
        dict: Parsed configuration with defaults applied
        
        Raises:
        FileNotFoundError: If configuration file not found
        yaml.YAMLError: If YAML parsing fails
        """

Include Parser

Handles !include YAML tags for including external configuration files or sections.

class Parser(BaseParser):
    """Parser for !include YAML tags."""
    
    def _resolve_include_tag(self, _, node) -> str | dict:
        """
        Replace !include tag with content from referenced file.
        
        Supports two formats:
        - !include file.yml (includes entire file)
        - !include file.yml#section (includes specific section)
        
        Parameters:
        - _ (unused): YAML loader parameter
        - node: YAML node containing include path
        
        Returns:
        str | dict: Content from included file
        
        Raises:
        ValueError: If include syntax has more than one # separator
        FileNotFoundError: If included file not found
        """
    
    def __init__(self, *args, **kwargs):
        """
        Initialize include parser and register !include constructor.
        
        Parameters:
        - *args: Arguments passed to BaseParser
        - **kwargs: Keyword arguments passed to BaseParser
        """

Path Parser

Handles path-related YAML tags for flexible path resolution relative to project directory.

class Parser(BaseParser):
    """Parser for path-related YAML tags."""
    
    def _resolve_path_tag(self, _, node) -> str:
        """
        Convert !path tag to absolute POSIX path.
        Relative paths are resolved relative to project directory.
        
        Parameters:
        - _ (unused): YAML loader parameter  
        - node: YAML node containing path value
        
        Returns:
        str: Absolute POSIX path
        
        Raises:
        FileNotFoundError: If path does not exist (strict=True)
        """
    
    def _resolve_project_path_tag(self, _, node) -> Path:
        """
        Convert !project_path tag to absolute path relative to project.
        Does not check for file existence.
        
        Parameters:
        - _ (unused): YAML loader parameter
        - node: YAML node containing path value
        
        Returns:
        Path: Absolute path object
        """
    
    @staticmethod
    def _resolve_rel_path_tag(_, node) -> Path:
        """
        Convert !rel_path tag to Path object without resolution.
        
        Parameters:
        - _ (unused): YAML loader parameter
        - node: YAML node containing path value
        
        Returns:
        Path: Path object from node value
        """
    
    def __init__(self, *args, **kwargs):
        """
        Initialize path parser and register path-related constructors.
        
        Parameters:
        - *args: Arguments passed to BaseParser
        - **kwargs: Keyword arguments passed to BaseParser
        """

Environment Variable Parser

Handles !env YAML tags for including environment variable values in configuration.

class Parser(BaseParser):
    """Parser for !env YAML tags."""
    
    @staticmethod
    def _resolve_env_tag(_, node) -> str | int | bool | dict | list | None:
        """
        Replace !env tag with environment variable value.
        
        Parameters:
        - _ (unused): YAML loader parameter
        - node: YAML node containing environment variable name
        
        Returns:
        Any: Environment variable value parsed as YAML, or None if not found
        """
    
    def __init__(self, *args, **kwargs):
        """
        Initialize environment parser and register !env constructor.
        
        Parameters:
        - *args: Arguments passed to BaseParser
        - **kwargs: Keyword arguments passed to BaseParser
        """

Usage Examples

Basic Configuration Parsing

from foliant.config import Parser
from pathlib import Path
import logging

# Set up logger
logger = logging.getLogger('foliant')

# Parse configuration
parser = Parser(
    project_path=Path('./my-project'),
    config_file_name='foliant.yml',
    logger=logger,
    quiet=False
)

config = parser.parse()
print(f"Source directory: {config['src_dir']}")
print(f"Temp directory: {config['tmp_dir']}")
print(f"Project title: {config.get('title', 'Untitled')}")

Configuration with Include Tags

Example foliant.yml:

title: My Documentation
chapters:
  - !include chapters.yml
preprocessors:
  - !include config/preprocessors.yml#development

Example usage:

from foliant.config import Parser
from pathlib import Path
import logging

parser = Parser(Path('.'), 'foliant.yml', logging.getLogger())
config = parser.parse()

# chapters.yml and preprocessors.yml content is merged
print(config['chapters'])
print(config['preprocessors'])

Configuration with Path Tags

Example foliant.yml:

title: Documentation
src_dir: !path ./sources
custom_path: !project_path ./assets/images
relative_path: !rel_path ./templates

Example usage:

config = parser.parse()

# Paths are resolved appropriately
print(config['src_dir'])        # Absolute path to ./sources
print(config['custom_path'])    # Absolute path to ./assets/images  
print(config['relative_path'])  # Path object for ./templates

Configuration with Environment Variables

Example foliant.yml:

title: !env PROJECT_TITLE
debug: !env DEBUG_MODE
api_key: !env API_KEY

Example usage:

import os

# Set environment variables
os.environ['PROJECT_TITLE'] = 'My Project'
os.environ['DEBUG_MODE'] = 'true'
os.environ['API_KEY'] = 'secret123'

config = parser.parse()
print(config['title'])    # 'My Project'
print(config['debug'])    # True (parsed as YAML boolean)
print(config['api_key'])  # 'secret123'

Custom Configuration Parser

from foliant.config.base import BaseParser
from yaml import add_constructor

class CustomParser(BaseParser):
    """Custom parser with additional YAML tags."""
    
    def _resolve_custom_tag(self, _, node):
        """Handle custom !mytag syntax."""
        return f"processed: {node.value}"
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        add_constructor('!mytag', self._resolve_custom_tag)

# Use custom parser
parser = CustomParser(Path('.'), 'foliant.yml', logger)
config = parser.parse()

Configuration File Structure

Default configuration structure:

# Required
title: Project Title

# Optional with defaults
src_dir: ./src                    # Source directory
tmp_dir: ./__folianttmp__        # Temporary build directory

# Backend configuration
backend_config:
  mkdocs:
    theme: material
  pandoc:
    template: custom.tex

# Preprocessors
preprocessors:
  - includes
  - plantuml:
      format: png

# Custom settings
chapters:
  - index.md
  - guide.md

Install with Tessl CLI

npx tessl i tessl/pypi-foliant

docs

backends.md

cli.md

config.md

index.md

preprocessors.md

utils.md

tile.json