CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-sphinx-gallery

A Sphinx extension that builds an HTML gallery of examples from any set of Python scripts.

Overview
Eval results
Files

sorting.mddocs/

Gallery Sorting

Flexible sorting system for organizing galleries and examples within galleries. Sphinx-Gallery provides built-in sorting functions and supports custom sorting logic for complete control over gallery organization.

Capabilities

Explicit Ordering

Sort key class for explicit ordering of gallery subsections.

class ExplicitOrder:
    """
    Sorting key for explicit ordering of gallery subsections.
    
    Allows you to specify the exact order of gallery subsections
    by providing a list of subsection names. Subsections not in
    the list appear after ordered ones in alphabetical order.
    """
    
    def __init__(self, ordered_list):
        """
        Parameters:
        - ordered_list: list, explicit order of subsection names
        """
    
    def __call__(self, item):
        """
        Sorting key function.
        
        Parameters:
        - item: str, subsection name to sort
        
        Returns:
        tuple: Sort key for the item
        """

Usage Example

from sphinx_gallery.sorting import ExplicitOrder

sphinx_gallery_conf = {
    'subsection_order': ExplicitOrder([
        'basic_examples',
        'intermediate_examples', 
        'advanced_examples',
        'expert_examples'
    ]),
}

Built-in Sorting Functions

File Size Sorting

def FileSizeKey(filename):
    """
    Sort examples by file size.
    
    Parameters:
    - filename: str, path to the example file
    
    Returns:
    int: File size in bytes for sorting
    """

Code Lines Sorting

def NumberOfCodeLinesSortKey(filename):
    """
    Sort examples by number of lines of code.
    
    Parameters:
    - filename: str, path to the example file
    
    Returns:
    int: Number of lines of code for sorting
    """

Filename Sorting

def FileNameSortKey(filename):
    """
    Sort examples alphabetically by filename.
    
    Parameters:
    - filename: str, path to the example file
    
    Returns:
    str: Filename for alphabetical sorting
    """

Example Date Sorting

def ExampleTitleSortKey(filename):
    """
    Sort examples by title extracted from docstring.
    
    Parameters:
    - filename: str, path to the example file
    
    Returns:
    str: Example title for sorting
    """

Configuration

Subsection Ordering

Control the order of gallery subsections (directories):

from sphinx_gallery.sorting import ExplicitOrder

sphinx_gallery_conf = {
    # Use explicit ordering
    'subsection_order': ExplicitOrder(['basic', 'advanced', 'expert']),
    
    # Or use a custom function
    'subsection_order': lambda x: x.lower(),  # Alphabetical, case-insensitive
}

Within-Subsection Ordering

Control the order of examples within each subsection:

from sphinx_gallery.sorting import NumberOfCodeLinesSortKey, FileSizeKey

sphinx_gallery_conf = {
    # Sort by number of code lines (default)
    'within_subsection_order': NumberOfCodeLinesSortKey,
    
    # Sort by file size
    'within_subsection_order': FileSizeKey,
    
    # Sort alphabetically by filename
    'within_subsection_order': lambda filename: os.path.basename(filename),
}

Custom Sorting Functions

Creating Custom Sort Functions

def custom_sort_key(filename):
    """
    Custom sorting function example.
    
    Sort by complexity level indicated in filename prefix.
    """
    basename = os.path.basename(filename)
    
    # Extract complexity level from filename
    if basename.startswith('beginner_'):
        return (1, basename)
    elif basename.startswith('intermediate_'):
        return (2, basename)
    elif basename.startswith('advanced_'):
        return (3, basename)
    else:
        return (4, basename)  # Unknown complexity last

# Usage
sphinx_gallery_conf = {
    'within_subsection_order': custom_sort_key,
}

Multi-Level Sorting

def multi_level_sort(filename):
    """
    Multi-level sorting by category and then alphabetically.
    """
    import os
    import re
    
    basename = os.path.basename(filename)
    
    # Primary sort by category prefix
    category_order = {
        'plot_': 1,
        'example_': 2,
        'tutorial_': 3,
    }
    
    category = 999  # Default for unknown categories
    for prefix, order in category_order.items():
        if basename.startswith(prefix):
            category = order
            break
    
    # Secondary sort alphabetically
    return (category, basename.lower())

sphinx_gallery_conf = {
    'within_subsection_order': multi_level_sort,
}

Time-Based Sorting

def modification_time_sort(filename):
    """
    Sort by file modification time (newest first).
    """
    import os
    return -os.path.getmtime(filename)  # Negative for reverse order

sphinx_gallery_conf = {
    'within_subsection_order': modification_time_sort,
}

Advanced Sorting Patterns

Directory-Based Subsection Ordering

def directory_priority_sort(subsection_dir):
    """
    Sort subsections by directory name with priorities.
    """
    priority_dirs = {
        'getting_started': 1,
        'basic_usage': 2,
        'advanced_features': 3,
        'tutorials': 4,
        'examples': 5,
    }
    
    dir_name = os.path.basename(subsection_dir)
    return priority_dirs.get(dir_name, 999), dir_name

sphinx_gallery_conf = {
    'subsection_order': directory_priority_sort,
}

Content-Based Sorting

def docstring_complexity_sort(filename):
    """
    Sort by complexity indicated in docstring.
    """
    try:
        with open(filename, 'r') as f:
            content = f.read()
        
        # Extract docstring
        import ast
        tree = ast.parse(content)
        docstring = ast.get_docstring(tree)
        
        if docstring:
            # Look for complexity indicators
            complexity_words = ['basic', 'simple', 'introduction']
            advanced_words = ['advanced', 'complex', 'expert']
            
            docstring_lower = docstring.lower()
            
            if any(word in docstring_lower for word in complexity_words):
                return (1, filename)
            elif any(word in docstring_lower for word in advanced_words):
                return (3, filename)
            else:
                return (2, filename)
    except:
        pass
    
    return (2, filename)  # Default to middle complexity

sphinx_gallery_conf = {
    'within_subsection_order': docstring_complexity_sort,
}

Integration Examples

Complete Sorting Configuration

from sphinx_gallery.sorting import ExplicitOrder, NumberOfCodeLinesSortKey

# Custom subsection order
tutorial_order = ExplicitOrder([
    '01_introduction',
    '02_basic_usage', 
    '03_advanced_features',
    '04_customization',
    '05_integration',
])

# Custom example sorting within subsections
def example_sort(filename):
    """Sort examples by number in filename, then alphabetically."""
    import re
    basename = os.path.basename(filename)
    
    # Extract number from filename like "plot_001_example.py"
    match = re.search(r'(\d+)', basename)
    if match:
        number = int(match.group(1))
        return (number, basename)
    return (999, basename)  # Files without numbers last

sphinx_gallery_conf = {
    'subsection_order': tutorial_order,
    'within_subsection_order': example_sort,
}

Conditional Sorting

def conditional_sort(filename):
    """
    Apply different sorting logic based on directory.
    """
    dir_name = os.path.dirname(filename)
    basename = os.path.basename(filename)
    
    if 'tutorials' in dir_name:
        # Sort tutorials by number prefix
        import re
        match = re.search(r'(\d+)', basename)
        return int(match.group(1)) if match else 999
    elif 'examples' in dir_name:
        # Sort examples by complexity
        if 'simple' in basename or 'basic' in basename:
            return (1, basename)
        elif 'advanced' in basename:
            return (3, basename)
        else:
            return (2, basename)
    else:
        # Default alphabetical
        return basename

sphinx_gallery_conf = {
    'within_subsection_order': conditional_sort,
}

Best Practices

Naming Conventions

Use consistent filename prefixes for easier sorting:

basic_examples/
├── plot_001_simple_line.py
├── plot_002_bar_chart.py
└── plot_003_scatter_plot.py

advanced_examples/
├── plot_101_custom_colors.py
├── plot_102_animations.py
└── plot_103_interactive.py

Progressive Complexity

Organize examples from simple to complex:

complexity_order = ExplicitOrder([
    'getting_started',    # Basic concepts
    'common_tasks',       # Everyday usage
    'advanced_features',  # Power user features
    'customization',      # Theming and styling
    'integration',        # With other tools
])

Topic-Based Organization

Group related functionality:

topic_order = ExplicitOrder([
    'data_visualization', # Core plotting
    'statistical_plots',  # Stats and analysis
    'geographic_maps',    # Geospatial data
    'time_series',        # Temporal data
    'interactive_plots',  # User interaction
])

Troubleshooting

Common Issues

  • Inconsistent Ordering: Ensure sort functions return consistent types
  • Missing Examples: Check that all examples are in expected directories
  • Unicode Issues: Handle non-ASCII filenames in sort functions
  • Performance: Simple sort functions work better with large galleries

Debugging Sorting

def debug_sort(filename):
    """Sort function with debugging output."""
    key = NumberOfCodeLinesSortKey(filename)
    print(f"Sorting {filename}: key={key}")
    return key

sphinx_gallery_conf = {
    'within_subsection_order': debug_sort,
    'log_level': {'examples_log_level': 'DEBUG'},
}

Install with Tessl CLI

npx tessl i tessl/pypi-sphinx-gallery

docs

directives.md

extension-setup.md

index.md

notebooks.md

scrapers.md

sorting.md

utilities.md

tile.json