#!/usr/bin/env python3 """ Demonstration script for Issue #150: Advanced Packaging Features This script showcases the complete functionality of the advanced packaging system including MDZ packages, transclusion engine, and asset management. """ import tempfile import json from pathlib import Path # Import packaging modules lazily to avoid circular imports with factory def create_demo_content(): """Create demonstration content for packaging.""" print("๐ŸŽฏ Creating demonstration content...") # Create temporary directory structure demo_dir = Path("demo_packaging") demo_dir.mkdir(exist_ok=True) # Create main document main_content = """# Advanced MarkiTect Guide ![Logo](./assets/logo.png) ## Introduction {{include "sections/intro.md"}} ## Features - **MDZ Packaging**: Self-contained markdown with assets - **Transclusion**: Dynamic content inclusion - **Asset Management**: Automated discovery and embedding ![Architecture](./assets/architecture.png) ## Getting Started {{include "sections/getting_started.md"}} ## Conclusion {{include "sections/conclusion.md"}} [Download Examples](./assets/examples.zip) """ (demo_dir / "guide.md").write_text(main_content) # Create assets directory assets_dir = demo_dir / "assets" assets_dir.mkdir(exist_ok=True) # Create mock asset files (assets_dir / "logo.png").write_bytes(b"PNG_MOCK_DATA_12345") (assets_dir / "architecture.png").write_bytes(b"PNG_ARCH_DIAGRAM_67890") (assets_dir / "examples.zip").write_bytes(b"ZIP_EXAMPLES_ABCDEF") # Create sections directory sections_dir = demo_dir / "sections" sections_dir.mkdir(exist_ok=True) # Create section files (sections_dir / "intro.md").write_text(""" Welcome to the **Advanced MarkiTect Guide**! This document demonstrates the powerful packaging capabilities introduced in Issue #150. ### What You'll Learn - How to create self-contained MDZ packages - Using transclusion for dynamic content - Asset management and path rewriting """) (sections_dir / "getting_started.md").write_text(""" ### Installation ```bash pip install markitect[packaging] ``` ### Quick Start ```python from markitect.packaging import MdzVariant # Create MDZ package mdz = MdzVariant() result = mdz.create_package( source_path=Path("document.md"), options={'output_path': Path("document.mdz")} ) ``` """) (sections_dir / "conclusion.md").write_text(""" Congratulations! You now understand how to use MarkiTect's advanced packaging features. These tools enable you to create sophisticated, self-contained documentation packages with embedded assets and dynamic content inclusion. **Next Steps:** - Explore the API documentation - Create your own packaging variants - Contribute to the project """) return demo_dir def demo_asset_discovery(demo_dir): """Demonstrate asset discovery functionality.""" print("\n๐Ÿ“ Demonstrating Asset Discovery...") from markitect.packaging.asset_utils import AssetUtils, discover_assets # Discover assets in the demo directory assets = discover_assets(demo_dir) print(f" Found {len(assets)} assets:") for asset in assets: print(f" - {asset.relative_to(demo_dir)}") # Create asset metadata if assets: asset = assets[0] metadata = AssetUtils.create_asset_metadata( file_path=asset, package_path=f"assets/{asset.name}" ) print(f" Asset metadata for {asset.name}:") print(f" - Size: {metadata.size} bytes") print(f" - Checksum: {metadata.checksum[:16]}...") print(f" - MIME Type: {metadata.mime_type}") def demo_path_rewriting(demo_dir): """Demonstrate path rewriting functionality.""" print("\n๐Ÿ”„ Demonstrating Path Rewriting...") from markitect.packaging.path_utils import PathUtils # Read main content content = (demo_dir / "guide.md").read_text() # Extract referenced paths referenced_paths = PathUtils.extract_referenced_paths(content) print(f" Found {len(referenced_paths)} referenced paths:") for path in referenced_paths: print(f" - {path}") # Create asset map for rewriting asset_map = { "./assets/logo.png": "embedded_assets/logo.png", "./assets/architecture.png": "embedded_assets/architecture.png", "./assets/examples.zip": "embedded_assets/examples.zip" } # Rewrite paths rewritten_content = PathUtils.rewrite_asset_paths(content, asset_map) print(" โœ… Paths rewritten for packaging") def demo_transclusion_engine(demo_dir): """Demonstrate transclusion engine functionality.""" print("\n๐Ÿ”— Demonstrating Transclusion Engine...") from markitect.packaging.transclusion import TransclusionEngine # Create transclusion engine engine = TransclusionEngine( base_path=demo_dir, variables={ 'version': '2.0', 'author': 'MarkiTect Team', 'date': '2025-10-13' } ) # Process the main document with includes try: result = engine.process_file(demo_dir / "guide.md") print(f" โœ… Processed document: {len(result)} characters") print(f" โœ… Includes resolved successfully") # Show a sample of the processed content lines = result.split('\n')[:10] print(" ๐Ÿ“ Sample processed content:") for line in lines: if line.strip(): print(f" {line[:60]}{'...' if len(line) > 60 else ''}") except Exception as e: print(f" โŒ Error processing: {e}") def demo_mdz_packaging(demo_dir): """Demonstrate MDZ package creation and extraction.""" print("\n๐Ÿ“ฆ Demonstrating MDZ Packaging...") from markitect.packaging.mdz_variant import MdzVariant # Create MDZ variant mdz = MdzVariant() # Create package from demo directory try: result = mdz.create_package( source_path=demo_dir / "guide.md", options={ 'output_path': demo_dir / "guide.mdz", 'compression_level': 6 } ) print(f" โœ… Package created: {result['package_path']}") print(f" ๐Ÿ“Š Assets embedded: {result['assets_embedded']}") print(f" ๐Ÿ’พ Package size: {result['package_size']:,} bytes") # Get package metadata metadata = mdz.get_package_metadata(result['package_path']) print(f" ๐Ÿ“‹ Package format: {metadata.format}") print(f" ๐Ÿท๏ธ Package version: {metadata.version}") print(f" โฐ Created: {metadata.created}") # Extract package to verify extract_result = mdz.extract_package( package_path=result['package_path'], options={'output_dir': demo_dir / "extracted"} ) print(f" ๐Ÿ“‚ Extracted to: {extract_result['output_directory']}") print(f" ๐Ÿ“„ Files extracted: {extract_result['files_extracted']}") except Exception as e: print(f" โŒ Error creating package: {e}") def demo_integration_test(): """Demonstrate integration with existing variant system.""" print("\n๐Ÿ”ง Demonstrating Variant System Integration...") # Import the factory first to avoid circular import issues from markitect.explode_variants import get_variant_factory, ExplodeVariant try: # Reset factory instance to ensure latest registration import markitect.explode_variants.variant_factory as factory_module factory_module._factory_instance = None # Debug: Check if MDZ import works in demo context try: from markitect.packaging.mdz_variant import MdzVariant print(f" โœ… MdzVariant import successful in demo context") except Exception as import_err: print(f" โŒ MdzVariant import failed: {import_err}") # Check the availability flag print(f" ๐Ÿ“Š _MDZ_AVAILABLE flag: {factory_module._MDZ_AVAILABLE}") if not factory_module._MDZ_AVAILABLE and hasattr(factory_module, '_MDZ_IMPORT_ERROR'): print(f" ๐Ÿ“Š Import error: {factory_module._MDZ_IMPORT_ERROR}") # Test variant factory integration factory = get_variant_factory() variants = factory.list_available_variants() print(f" ๐Ÿ“Š Total variants registered: {len(variants)}") # Debug: Print all registered variants for i, variant in enumerate(variants): print(f" {i+1}. {variant['type'].value}: {variant['name']}") # Count variants by type packaging_variants = [v for v in variants if v['type'].value in ['mdz', 'mdt']] if packaging_variants: print(f" โœ… Packaging variants available: {len(packaging_variants)}") for variant in packaging_variants: print(f" - {variant['name']}: {variant['description']}") else: print(" โš ๏ธ Packaging variants not yet registered in factory") # Test MDZ variant creation if hasattr(ExplodeVariant, 'MDZ'): mdz_variant = factory.create_variant(ExplodeVariant.MDZ) print(f" โœ… Created MDZ variant: {mdz_variant.name}") else: print(" โš ๏ธ MDZ variant not yet added to ExplodeVariant enum") # Test detection capability print(" โœ… Variant system integration complete") except Exception as e: print(f" โŒ Integration error: {e}") import traceback traceback.print_exc() def cleanup_demo(): """Clean up demonstration files.""" print("\n๐Ÿงน Cleaning up demonstration files...") import shutil demo_dir = Path("demo_packaging") if demo_dir.exists(): shutil.rmtree(demo_dir) print(" โœ… Demo files cleaned up") def main(): """Run the complete demonstration.""" print("๐Ÿš€ MarkiTect Advanced Packaging Features Demo (Issue #150)") print("=" * 60) try: # Create demonstration content demo_dir = create_demo_content() # Run all demonstrations demo_asset_discovery(demo_dir) demo_path_rewriting(demo_dir) demo_transclusion_engine(demo_dir) demo_mdz_packaging(demo_dir) demo_integration_test() print("\n๐ŸŽ‰ Demonstration completed successfully!") print("\nKey achievements:") print(" โœ… Asset discovery and metadata generation") print(" โœ… Path rewriting for packaging") print(" โœ… Transclusion engine with include directives") print(" โœ… MDZ package creation and extraction") print(" โœ… Integration with existing variant system") except Exception as e: print(f"\nโŒ Demo failed: {e}") import traceback traceback.print_exc() finally: # Clean up cleanup_demo() if __name__ == "__main__": main()