CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-markdown-include

A Python-Markdown extension which provides an 'include' function

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

Markdown-Include

A Python-Markdown extension which provides an 'include' function, similar to that found in LaTeX (and also the C pre-processor and Fortran). This extension enables recursive file inclusion using the syntax {!filename!} and supports advanced features like line range selection, heading depth inheritance, configurable base paths, and custom file encoding.

Package Information

  • Package Name: markdown-include
  • Package Type: pypi
  • Language: Python
  • Installation: pip install markdown-include

Core Imports

import markdown
from markdown_include.include import MarkdownInclude

For factory function usage:

from markdown_include.include import makeExtension

Basic Usage

Extension Registration

import markdown

# Simple usage with default settings
html = markdown.markdown(source, extensions=['markdown_include.include'])

Programmatic Configuration

import markdown
from markdown_include.include import MarkdownInclude

# Create extension with custom configuration
markdown_include = MarkdownInclude(
    configs={
        'base_path': '/srv/content/',
        'encoding': 'iso-8859-1',
        'inheritHeadingDepth': True,
        'headingOffset': 1,
        'throwException': False
    }
)

html = markdown.markdown(source, extensions=[markdown_include])

Factory Function Usage

import markdown
from markdown_include.include import makeExtension

extension = makeExtension(base_path='/srv/content/', encoding='utf-8')
html = markdown.markdown(source, extensions=[extension])

MkDocs Integration

markdown_extensions:
    - markdown_include.include:
        base_path: docs
        inheritHeadingDepth: true

Include Syntax

Basic File Inclusion

{!filename.md!}

Includes the entire content of filename.md. The extension works recursively, so any include statements within the included file will also be processed.

Line-Specific Inclusion

{!filename.md!lines=1 3 8-10 2}

Includes specific lines and ranges from the file:

  • Individual lines: 1, 3, 2
  • Line ranges: 8-10 (includes lines 8, 9, and 10)
  • Order matters: lines are included in the specified order, not file order

Capabilities

Extension Class

The main extension class that integrates with Python-Markdown.

class MarkdownInclude(Extension):
    def __init__(self, configs={}):
        """
        Initialize the markdown-include extension.
        
        Parameters:
        - configs (dict): Configuration dictionary with extension settings
        """
    
    def extendMarkdown(self, md):
        """
        Register the include preprocessor with the Markdown instance.
        
        Parameters:
        - md: Markdown instance to extend
        """

Preprocessor Class

The core processor that handles file inclusion syntax.

class IncludePreprocessor(Preprocessor):
    def __init__(self, md, config):
        """
        Initialize the include preprocessor.
        
        Parameters:
        - md: Markdown instance
        - config (dict): Configuration dictionary from MarkdownInclude
        """
    
    def run(self, lines):
        """
        Process markdown lines to replace include statements with file contents.
        
        Parameters:
        - lines (list): List of markdown lines to process
        
        Returns:
        list: Processed lines with include statements replaced
        """

Factory Function

Creates a MarkdownInclude extension instance.

def makeExtension(*args, **kwargs):
    """
    Factory function to create MarkdownInclude extension instance.
    
    Parameters:
    - *args: Variable arguments (unused)
    - **kwargs: Keyword arguments passed as configs to MarkdownInclude
    
    Returns:
    MarkdownInclude: Extension instance ready for use with Python-Markdown
    """

Configuration Options

All configuration options can be specified when initializing the extension:

# Configuration parameters for MarkdownInclude
configs = {
    'base_path': str,        # Default: "." - Base directory for relative paths
    'encoding': str,         # Default: "utf-8" - File encoding for included files
    'inheritHeadingDepth': bool,  # Default: False - Inherit heading depth from context
    'headingOffset': int,    # Default: 0 - Additional heading depth offset
    'throwException': bool   # Default: False - Whether to throw exceptions on file not found
}

Configuration Details

  • base_path: Directory from which relative paths are evaluated. Defaults to the current working directory.
  • encoding: Character encoding used when reading included files. Defaults to UTF-8.
  • inheritHeadingDepth: When true, headings in included files are increased by the depth of the previous heading in the parent document.
  • headingOffset: Additional heading levels to add to all headings in included files, combined with inheritHeadingDepth.
  • throwException: When true, missing files raise exceptions that can be caught. When false (default), warnings are printed and processing continues.

Advanced Features

Heading Depth Management

# Example with heading depth inheritance
markdown_include = MarkdownInclude(
    configs={'inheritHeadingDepth': True, 'headingOffset': 1}
)

Source document:

# Main Heading
{!included.md!}
## Sub Heading  
{!included.md!}

If included.md contains:

# Included Heading
Content here.

Result with inheritHeadingDepth=True:

# Main Heading
## Included Heading
Content here.
## Sub Heading
### Included Heading
Content here.

Line Range Processing

The extension supports flexible line selection:

{!large_file.md!lines=1-5 10 15-20}
  • Ranges are inclusive: 1-5 includes lines 1, 2, 3, 4, and 5
  • Out-of-bounds lines are handled gracefully with warnings
  • Invalid ranges are corrected automatically

Error Handling

# Exception mode - raises FileNotFoundError for missing files
strict_include = MarkdownInclude(configs={'throwException': True})

try:
    html = markdown.markdown(source, extensions=[strict_include])
except FileNotFoundError as e:
    print(f"Include file not found: {e}")

# Warning mode (default) - prints warnings and continues
normal_include = MarkdownInclude(configs={'throwException': False})
html = markdown.markdown(source, extensions=[normal_include])

Types

# Import types from markdown library
from markdown.extensions import Extension
from markdown.preprocessors import Preprocessor

# Regular expression patterns used internally
import re
INC_SYNTAX = re.compile(r"{!\s*(.+?)\s*!((\blines\b)=([0-9 -]+))?}")
HEADING_SYNTAX = re.compile("^#+")

docs

index.md

tile.json