From 1026695da79fe64805e344abe43c1012bf71a74a Mon Sep 17 00:00:00 2001 From: shym Date: Thu, 7 May 2026 11:13:14 +0900 Subject: [PATCH] feat: add .qmd file extension support Adds support for Quarto markdown (.qmd) files by: - Adding '.qmd' to document file extensions in detection - Updating export logic to handle .qmd in filename sanitization - Adding .qmd extractor dispatch using the existing markdown extractor - Updating watch comments to include .qmd files --- graphify/detect.py | 2 +- graphify/export.py | 2 +- graphify/extract.py | 1 + graphify/watch.py | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/graphify/detect.py b/graphify/detect.py index 519a838aa..c65266cd6 100644 --- a/graphify/detect.py +++ b/graphify/detect.py @@ -19,7 +19,7 @@ class FileType(str, Enum): _MANIFEST_PATH = "graphify-out/manifest.json" CODE_EXTENSIONS = {'.py', '.ts', '.js', '.jsx', '.tsx', '.mjs', '.ejs', '.go', '.rs', '.java', '.groovy', '.gradle', '.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.rb', '.swift', '.kt', '.kts', '.cs', '.scala', '.php', '.lua', '.luau', '.toc', '.zig', '.ps1', '.ex', '.exs', '.m', '.mm', '.jl', '.vue', '.svelte', '.dart', '.v', '.sv', '.sql', '.r', '.f', '.F', '.f90', '.F90', '.f95', '.F95', '.f03', '.F03', '.f08', '.F08'} -DOC_EXTENSIONS = {'.md', '.mdx', '.txt', '.rst', '.html', '.yaml', '.yml'} +DOC_EXTENSIONS = {'.md', '.mdx', '.qmd', '.txt', '.rst', '.html', '.yaml', '.yml'} PAPER_EXTENSIONS = {'.pdf'} IMAGE_EXTENSIONS = {'.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg'} OFFICE_EXTENSIONS = {'.docx', '.xlsx'} diff --git a/graphify/export.py b/graphify/export.py index 7121a2c69..4687caed5 100644 --- a/graphify/export.py +++ b/graphify/export.py @@ -646,7 +646,7 @@ def to_obsidian( def safe_name(label: str) -> str: cleaned = re.sub(r'[\\/*?:"<>|#^[\]]', "", label.replace("\r\n", " ").replace("\r", " ").replace("\n", " ")).strip() # Strip trailing .md/.mdx/.markdown so "CLAUDE.md" doesn't become "CLAUDE.md.md" - cleaned = re.sub(r"\.(md|mdx|markdown)$", "", cleaned, flags=re.IGNORECASE) + cleaned = re.sub(r"\.(md|mdx|qmd|markdown)$", "", cleaned, flags=re.IGNORECASE) return cleaned or "unnamed" node_filename: dict[str, str] = {} diff --git a/graphify/extract.py b/graphify/extract.py index 43c2bf61f..ac71386d3 100644 --- a/graphify/extract.py +++ b/graphify/extract.py @@ -4426,6 +4426,7 @@ def _check_tree_sitter_version() -> None: ".sql": extract_sql, ".md": extract_markdown, ".mdx": extract_markdown, + ".qmd": extract_markdown, } diff --git a/graphify/watch.py b/graphify/watch.py index 0b7bd9561..5b1dac8dd 100644 --- a/graphify/watch.py +++ b/graphify/watch.py @@ -70,7 +70,7 @@ def _rebuild_code(watch_path: Path, *, follow_symlinks: bool = False, force: boo detected = detect(watch_path, follow_symlinks=follow_symlinks) code_files = [Path(f) for f in detected['files']['code']] - # Include document files that have AST extractors (e.g. .md, .mdx) + # Include document files that have AST extractors (e.g. .md, .mdx, .qmd) from graphify.extract import _get_extractor for doc_file in detected['files'].get('document', []): p = Path(doc_file)