add note for auto-generated documentation

This commit is contained in:
Josh Thomas 2025-01-03 09:13:23 -06:00
parent accb8fdfb4
commit 2c70925918
3 changed files with 112 additions and 111 deletions

View file

@ -2,6 +2,12 @@
title: Neovim
---
<!--
THIS FILE IS AUTO-GENERATED
DO NOT EDIT THIS FILE DIRECTLY
Generated via docs/processor.py from editors/nvim/README.md
-->
# djls.nvim
A Neovim plugin for the Django Language Server.

View file

@ -2,6 +2,12 @@
title: Home
---
<!--
THIS FILE IS AUTO-GENERATED
DO NOT EDIT THIS FILE DIRECTLY
Generated via docs/processor.py from README.md
-->
# django-language-server
A language server for the Django web framework.

View file

@ -14,6 +14,7 @@ from __future__ import annotations
import logging
import re
from dataclasses import dataclass
from dataclasses import field
from difflib import Differ
from functools import reduce
from itertools import islice
@ -37,8 +38,6 @@ logging.basicConfig(
)
logger = logging.getLogger(__name__)
ProcessingFunc = Callable[[str], str]
def compose(*functions: ProcessingFunc) -> ProcessingFunc:
"""Compose multiple processing functions into a single function."""
@ -270,50 +269,63 @@ def preview_changes(original: str, processed: str) -> None:
print_change_group(group)
def process_file(
input: str = "README.md",
output: str = "docs/index.md",
processors: list[ProcessingFunc] | None = None,
preview: bool = True,
description: str | None = None,
) -> bool:
"""
Process a file with given processing functions.
@dataclass
class File:
"""A file to be processed."""
Args:
input: Path to the input file
output: Path where the processed file will be saved
processors: List of processing functions to apply
preview: Whether to show a preview of changes
description: Optional description for status message
input_path: Path | str
output_path: Path | str
repo_url: str = "https://github.com/joshuadavidthomas/django-language-server"
content: str = ""
processors: list[ProcessingFunc] = field(default_factory=list)
Returns:
bool: True if processing was successful, False otherwise
"""
status_msg = f"[bold green]Processing {description or input}..."
with console.status(status_msg) as status:
input_path = Path(input)
output_path = Path(output)
def __post_init__(self):
self.input_path = Path(self.input_path)
self.output_path = Path(self.output_path)
content = read_file(input_path)
if content is None:
return False
def process(self, preview: bool = True) -> bool:
"""Process the file with given processing functions."""
with console.status(
f"[bold green]Processing {self.input_path}{self.output_path}..."
) as status:
content = read_file(self.input_path)
if content is None:
return False
original_content = content
self.content = content
original_content = content
try:
for proc in track(processors, description="Applying processors"):
status.update(f"[bold green]Running {proc.__name__}...")
content = proc(content)
try:
for proc in track(self.processors, description="Applying processors"):
status.update(f"[bold green]Running {proc.__name__}...")
content = proc(content, self)
if preview:
preview_changes(original_content, content)
if preview:
preview_changes(original_content, content)
return write_file(output_path, content)
return write_file(self.output_path, content)
except Exception as e:
console.print(f"[red]Error during processing:[/red] {e}")
return False
except Exception as e:
console.print(f"[red]Error during processing:[/red] {e}")
return False
ProcessingFunc = Callable[[str, File], str]
def add_generated_warning(content: str, file: File) -> str:
"""Add a warning comment indicating the file is auto-generated."""
script_path = Path(__file__).relative_to(Path(__file__).parent.parent)
warning = [
"<!--",
"THIS FILE IS AUTO-GENERATED",
"DO NOT EDIT THIS FILE DIRECTLY",
f"Generated via {script_path} from {file.input_path}",
"-->",
"",
"",
]
return "\n".join(warning) + content
def add_frontmatter(
@ -345,7 +357,7 @@ def add_frontmatter(
Content here
"""
def processor(content: str) -> str:
def processor(content: str, _file: File) -> str:
# Remove existing frontmatter if present
content_without_frontmatter = re.sub(
r"^---\n.*?\n---\n", "", content, flags=re.DOTALL
@ -371,7 +383,7 @@ def add_frontmatter(
return processor
def convert_admonitions(content: str) -> str:
def convert_admonitions(content: str, _file: File) -> str:
"""
Convert GitHub-style admonitions to Material for MkDocs-style admonitions.
@ -431,106 +443,83 @@ def convert_admonitions(content: str) -> str:
return re.sub(pattern, process_match, content)
def convert_repo_links(repo_url: str) -> ProcessingFunc:
"""
Convert relative repository links to absolute URLs.
def convert_repo_links(content: str, file: File) -> str:
"""Convert relative repository links to absolute URLs."""
Args:
repo_url: The base repository URL (e.g., 'https://github.com/username/repo')
def replace_link(match: re.Match[str]) -> str:
text = match.group(1)
path = match.group(2)
Returns:
A processor function that converts relative links to absolute URLs
# Skip anchor links
if path.startswith("#"):
return match.group(0)
Example:
Input:
See the [`LICENSE`](LICENSE) file for more information.
Check the [Neovim](/docs/editors/neovim.md) guide.
Open an [issue](../../issues/new) to report bugs.
# Skip already absolute URLs
if path.startswith(("http://", "https://")):
return match.group(0)
Output:
See the [`LICENSE`](https://github.com/username/repo/blob/main/LICENSE) file for more information.
Check the [Neovim](editors/neovim.md) guide.
Open an [issue](https://github.com/username/repo/issues/new) to report bugs.
"""
# Handle docs directory links
if path.startswith(("/docs/", "docs/")):
# Remove /docs/ or docs/ prefix and .md extension
clean_path = path.removeprefix("/docs/").removeprefix("docs/")
return f"[{text}]({clean_path})"
def processor(content: str) -> str:
def replace_link(match: re.Match[str]) -> str:
text = match.group(1)
path = match.group(2)
# Handle relative paths with ../ or ./
if "../" in path or "./" in path:
# Special handling for GitHub-specific paths
if "issues/" in path or "pulls/" in path:
clean_path = path.replace("../", "").replace("./", "")
return f"[{text}]({file.repo_url}/{clean_path})"
# Skip anchor links
if path.startswith("#"):
return match.group(0)
# Handle root-relative paths
if path.startswith("/"):
path = path.removeprefix("/")
# Skip already absolute URLs
if path.startswith(("http://", "https://")):
return match.group(0)
# Remove ./ if present
path = path.removeprefix("./")
# Handle docs directory links
if path.startswith(("/docs/", "docs/")):
# Remove /docs/ or docs/ prefix and .md extension
clean_path = path.removeprefix("/docs/").removeprefix("docs/")
return f"[{text}]({clean_path})"
# Construct the full URL for repository files
full_url = f"{file.repo_url.rstrip('/')}/blob/main/{path}"
return f"[{text}]({full_url})"
# Handle relative paths with ../ or ./
if "../" in path or "./" in path:
# Special handling for GitHub-specific paths
if "issues/" in path or "pulls/" in path:
clean_path = path.replace("../", "").replace("./", "")
return f"[{text}]({repo_url}/{clean_path})"
# Handle root-relative paths
if path.startswith("/"):
path = path.removeprefix("/")
# Remove ./ if present
path = path.removeprefix("./")
# Construct the full URL for repository files
full_url = f"{repo_url.rstrip('/')}/blob/main/{path}"
return f"[{text}]({full_url})"
# Match markdown links: [text](url)
pattern = r"\[((?:[^][]|\[[^]]*\])*)\]\(([^)]+)\)"
return re.sub(pattern, replace_link, content)
processor.__name__ = "convert_repo_links"
return processor
# Match markdown links: [text](url)
pattern = r"\[((?:[^][]|\[[^]]*\])*)\]\(([^)]+)\)"
return re.sub(pattern, replace_link, content)
def main():
"""Process documentation files."""
console.print("[bold blue]Documentation Processor[/bold blue]")
# Common processors
common_processors = [
add_generated_warning,
convert_admonitions,
convert_repo_links(
"https://github.com/joshuadavidthomas/django-language-server"
),
convert_repo_links,
]
readme_success = process_file(
input="README.md",
output="docs/index.md",
readme = File(
input_path="README.md",
output_path="docs/index.md",
processors=[
add_frontmatter({"title": "Home"}),
*common_processors,
add_frontmatter({"title": "Home"}),
],
preview=True,
description="README.md → docs/index.md",
)
nvim_success = process_file(
input="editors/nvim/README.md",
output="docs/editors/neovim.md",
nvim = File(
input_path="editors/nvim/README.md",
output_path="docs/editors/neovim.md",
processors=[
add_frontmatter({"title": "Neovim"}),
*common_processors,
add_frontmatter({"title": "Neovim"}),
],
preview=True,
description="Neovim docs → docs/editors/neovim.md",
)
# Process files
readme_success = readme.process(preview=True)
nvim_success = nvim.process(preview=True)
if readme_success and nvim_success:
console.print("\n[green]✨ All files processed successfully![/green]")
else: