# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_core.ipynb.

# %% auto 0
__all__ = ['MarkdownProcessor', 'MarkdownWatcher', 'literati', 'md_to_py']

# %% ../nbs/00_core.ipynb 4
from fastcore.basics import *
from fastcore.foundation import *
from fastcore.test import *
from fastcore.script import call_parse, Param

from pathlib import Path
import re, time
import threading

from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

from tempfile import NamedTemporaryFile
from tempfile import TemporaryDirectory
import signal
import subprocess


class MarkdownProcessor:
    """Handles the processing of markdown files to extract code blocks"""
    def __init__(self, output_dir='py'):
        self.output_dir = Path(output_dir)
    
    def should_process(self, path):
        "Check if the markdown file should be processed"
        return path.suffix == '.md' and path.name.lower() != 'readme.md'
    
    def extract_code(self, md_content):
        "Extract code blocks from markdown content"
        pattern = r'`{3}[\w\s]*\n(.*?)`{3}|`([^`]+)`'
        code_blocks = []
        for match in re.finditer(pattern, md_content, re.DOTALL):
            code = match.group(1) or match.group(2)
            if code: code_blocks.append(code)
        return '\n'.join(code_blocks)
    
    def process_file(self, md_path):
        "Process a markdown file and save extracted code"
        if not self.should_process(Path(md_path)): return None
        
        content = Path(md_path).read_text()
        code = self.extract_code(content)
        if code:  # only create an output file if any code was extracted
            self.output_dir.mkdir(exist_ok=True)
            py_path = self.output_dir/f"{Path(md_path).stem}.py"
            py_path.write_text(code)
            return py_path
        return None

    def process_directory(self, input_dir):
        "Process all markdown files in the given directory"
        input_path = Path(input_dir)
        if not input_path.exists():
            raise ValueError(f"Directory {input_dir} does not exist")
        
        processed_files_containing_code = []
        for md_file in input_path.glob('**/*.md'):  # includes subdirectories
            if result := self.process_file(md_file):
                processed_files_containing_code.append(result)
    
        return processed_files_containing_code

# %% ../nbs/00_core.ipynb 16
class MarkdownWatcher(FileSystemEventHandler):
    """Watches for markdown file changes and triggers processing"""
    def __init__(self, processor):
        self.processor = processor
    
    def on_modified(self, event):
        self.processor.process_file(event.src_path)
        
    def on_created(self, event):
        self.processor.process_file(event.src_path)

# %% ../nbs/00_core.ipynb 20
@call_parse
def literati(path:Param("Directory to monitor", str)='.', 
             output_dir:Param("Output directory for Python files", str)='py'):
    "Monitor markdown files and extract code blocks to Python files"
    processor = MarkdownProcessor(output_dir=output_dir)
    
    # Process existing files first
    processor.process_directory(path)
    
    handler = MarkdownWatcher(processor)
    
    observer = Observer()
    observer.schedule(handler, path, recursive=False)
    observer.start()
    
    print(f"G'day! Monitoring {path} for markdown files...")
    print(f"Python files will be saved to {output_dir}/")
    print("Optimizing the servo run... (Press Ctrl+C to stop)")
    
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
        observer.join()
    
    return observer

@call_parse
def md_to_py(
    input_dir: Param("Input directory containing markdown files", str),
    output_dir: Param("Output directory for Python files", str)='py'
):
    "Convert markdown files in input_dir to Python files in output_dir"
    processor = MarkdownProcessor(output_dir=output_dir)
    processed = processor.process_directory(input_dir)
    print(f"Processed {len(processed)} files:")
    for file in processed:
        print(f"  {file}")
