all2md.converter_registry

Converter registry for dynamic converter management.

This module implements a registry pattern for parsers, enabling: - Lazy loading of converter modules - Dynamic converter discovery and registration - Proper dependency error handling - Format detection and converter routing

all2md.converter_registry.check_package_installed(import_name: str) bool

Check if a package is installed and importable.

Parameters:

import_name (str) – Name to use in import statement (e.g., ‘docx’ for python-docx package)

Returns:

True if package is installed and importable

Return type:

bool

class all2md.converter_registry.ConverterRegistry

Bases: object

Registry for managing document parsers and renderers.

This class provides a central registry for all parsers and renderers, handling: - Converter registration and discovery - Priority-based parser/renderer selection - Format detection from files/content - Lazy loading of converter modules - Dependency checking and error handling

The registry supports multiple parsers and renderers for the same format, with priority-based selection. Higher priority converters are tried first, allowing plugins to override built-in converters or provide fallback options.

Variables:
  • _instance (ConverterRegistry or None) – Singleton instance of the registry

  • _converters (dict) – Registered converters by format name, with each format mapping to a priority-sorted list of ConverterMetadata objects

  • _initialized (bool) – Whether auto-discovery has been run

Create or return singleton instance.

static __new__(cls) ConverterRegistry

Create or return singleton instance.

register(metadata: ConverterMetadata) None

Register a converter with its metadata.

Parameters:

metadata (ConverterMetadata) – Converter metadata to register

Notes

Multiple converters can be registered for the same format_name with different priorities. When retrieving a parser or renderer, the highest priority converter with available dependencies is used.

Converters are automatically sorted by priority (highest first) when registered. If no priority is specified, it defaults to 0.

unregister(format_name: str) bool

Unregister a converter.

Parameters:

format_name (str) – Format name to unregister

Returns:

True if unregistered, False if not found

Return type:

bool

get_parser_options_class(format_name: str) type | None

Get parser options class for a format.

Parameters:

format_name (str) – Format name to get parser options class for

Returns:

Parser options class or None if format has no parser options

Return type:

type or None

Raises:

FormatError – If format not registered

Notes

Returns the parser options class from the highest priority converter that has a parser_options_class specified.

get_renderer_options_class(format_name: str) type | None

Get renderer options class for a format.

Parameters:

format_name (str) – Format name to get renderer options class for

Returns:

Renderer options class or None if format has no renderer options

Return type:

type or None

Raises:

FormatError – If format not registered

Notes

Returns the renderer options class from the highest priority converter that has a renderer_options_class specified.

get_parser(format_name: str) type

Get parser class for a format with priority-based selection.

Parameters:

format_name (str) – Format name to get parser for

Returns:

Parser class (subclass of BaseParser)

Return type:

type

Raises:

Notes

When multiple converters are registered for the same format, this method tries them in priority order (highest first). It returns the first parser that can be successfully loaded. This allows for graceful fallback if high-priority converters have missing dependencies.

get_renderer(format_name: str) type

Get renderer class for a format with priority-based selection.

Parameters:

format_name (str) – Format name to get renderer for

Returns:

Renderer class (subclass of BaseRenderer)

Return type:

type

Raises:

FormatError – If format not registered or no renderer available

Notes

When multiple converters are registered for the same format, this method tries them in priority order (highest first). It returns the first renderer that can be successfully loaded. This allows for graceful fallback if high-priority converters have missing dependencies.

detect_format(input_data: str | Path | IO[bytes] | bytes, hint: str | None = None) str

Detect format from input data.

Uses multiple strategies: 1. Explicit hint if provided 2. Filename extension matching (validated with content_detector if available) 3. MIME type detection 4. Magic bytes content analysis 5. Default fallback

Parameters:
  • input_data (various types) – Input data to detect format from

  • hint (str, optional) – Format hint to prefer

Returns:

Detected format name

Return type:

str

list_formats() List[str]

List all registered format names.

Returns:

Sorted list of format names

Return type:

list[str]

get_format_info(format_name: str) List[ConverterMetadata] | None

Get metadata list for a specific format.

Parameters:

format_name (str) – Format to get info for

Returns:

List of metadata objects for the format (sorted by priority), or None if not registered

Return type:

list of ConverterMetadata or None

Notes

Returns all registered converters for the format, sorted by priority (highest first). For backward compatibility with code expecting a single metadata object, you can access the first element of the returned list to get the highest priority converter.

get_default_extension_for_format(format_name: str) str

Return the preferred file extension for a format.

Parameters:

format_name (str) – Converter format name (e.g., “markdown”, “docx”).

Returns:

Preferred extension beginning with a leading dot.

Return type:

str

get_all_extensions() set[str]

Get all supported file extensions from registered converters.

This method dynamically queries all registered converters and collects their supported file extensions. Useful for CLI file filtering, format detection, and determining which files can be processed.

Returns:

Set of all supported file extensions with leading dots (e.g., {‘.pdf’, ‘.docx’, ‘.md’})

Return type:

set[str]

Notes

This method provides a dynamic alternative to hardcoded extension lists. When new parsers are registered (including via plugins), their extensions are automatically included.

Examples

Check if a file extension is supported:
>>> extensions = registry.get_all_extensions()
>>> '.webarchive' in extensions
True
>>> '.xyz' in extensions
False
Get all supported extensions for file filtering:
>>> from pathlib import Path
>>> supported = registry.get_all_extensions()
>>> files = [f for f in Path('.').glob('*') if f.suffix in supported]
check_dependencies(format_name: str | None = None, input_data: str | Path | IO[bytes] | bytes | None = None, operation: str = 'both') Dict[str, List[str]]

Check which dependencies are missing.

Parameters:
  • format_name (str, optional) – Check specific format, or all if None

  • input_data (various types, optional) – Input data to use for context-aware dependency checking

  • operation (str, default="both") – Operation type to check dependencies for: “parse”, “render”, or “both”

Returns:

Format names mapped to list of missing packages

Return type:

dict

auto_discover() None

Register built-in converters from the manifest, then discover plugins.

Built-in converter metadata is registered from the generated manifest (all2md._converter_manifest), which is a leaf module of pure literals. This avoids importing all ~40 parser/renderer modules at startup just to read their CONVERTER_METADATA — the parser/renderer/options classes and content detectors are imported lazily on first use instead. This is the primary CLI/import startup optimization.

External plugins are still discovered eagerly via entry points.

The manifest is kept in sync with the live modules by scripts/generate_converter_manifest.py and guarded by a unit test. If the manifest module is entirely absent (e.g. during its own first generation, or a broken install) we fall back to the slow directory scan so the library still works; a present-but-empty manifest is treated as corruption and raises.

discover_by_scanning() None

Discover converters by importing every parser/renderer module.

This is the original, slow auto-discovery: it scans the parsers and renderers packages, imports each module, and reads its CONVERTER_METADATA. It is retained only for the manifest generator script and the manifest sync test, which run it against a fresh registry. It is NOT used during normal startup (see auto_discover).