Skip to content

Commit 2c70925

Browse files
add note for auto-generated documentation
1 parent accb8fd commit 2c70925

File tree

3 files changed

+120
-119
lines changed

3 files changed

+120
-119
lines changed

docs/editors/neovim.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
title: Neovim
33
---
44

5+
<!--
6+
THIS FILE IS AUTO-GENERATED
7+
DO NOT EDIT THIS FILE DIRECTLY
8+
Generated via docs/processor.py from editors/nvim/README.md
9+
-->
10+
511
# djls.nvim
612

713
A Neovim plugin for the Django Language Server.

docs/index.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
title: Home
33
---
44

5+
<!--
6+
THIS FILE IS AUTO-GENERATED
7+
DO NOT EDIT THIS FILE DIRECTLY
8+
Generated via docs/processor.py from README.md
9+
-->
10+
511
# django-language-server
612

713
A language server for the Django web framework.

docs/processor.py

Lines changed: 108 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import logging
1515
import re
1616
from dataclasses import dataclass
17+
from dataclasses import field
1718
from difflib import Differ
1819
from functools import reduce
1920
from itertools import islice
@@ -37,8 +38,6 @@
3738
)
3839
logger = logging.getLogger(__name__)
3940

40-
ProcessingFunc = Callable[[str], str]
41-
4241

4342
def compose(*functions: ProcessingFunc) -> ProcessingFunc:
4443
"""Compose multiple processing functions into a single function."""
@@ -270,50 +269,63 @@ def preview_changes(original: str, processed: str) -> None:
270269
print_change_group(group)
271270

272271

273-
def process_file(
274-
input: str = "README.md",
275-
output: str = "docs/index.md",
276-
processors: list[ProcessingFunc] | None = None,
277-
preview: bool = True,
278-
description: str | None = None,
279-
) -> bool:
280-
"""
281-
Process a file with given processing functions.
282-
283-
Args:
284-
input: Path to the input file
285-
output: Path where the processed file will be saved
286-
processors: List of processing functions to apply
287-
preview: Whether to show a preview of changes
288-
description: Optional description for status message
289-
290-
Returns:
291-
bool: True if processing was successful, False otherwise
292-
"""
293-
status_msg = f"[bold green]Processing {description or input}..."
294-
with console.status(status_msg) as status:
295-
input_path = Path(input)
296-
output_path = Path(output)
297-
298-
content = read_file(input_path)
299-
if content is None:
300-
return False
301-
302-
original_content = content
303-
304-
try:
305-
for proc in track(processors, description="Applying processors"):
306-
status.update(f"[bold green]Running {proc.__name__}...")
307-
content = proc(content)
308-
309-
if preview:
310-
preview_changes(original_content, content)
311-
312-
return write_file(output_path, content)
313-
314-
except Exception as e:
315-
console.print(f"[red]Error during processing:[/red] {e}")
316-
return False
272+
@dataclass
273+
class File:
274+
"""A file to be processed."""
275+
276+
input_path: Path | str
277+
output_path: Path | str
278+
repo_url: str = "https://github.com/joshuadavidthomas/django-language-server"
279+
content: str = ""
280+
processors: list[ProcessingFunc] = field(default_factory=list)
281+
282+
def __post_init__(self):
283+
self.input_path = Path(self.input_path)
284+
self.output_path = Path(self.output_path)
285+
286+
def process(self, preview: bool = True) -> bool:
287+
"""Process the file with given processing functions."""
288+
with console.status(
289+
f"[bold green]Processing {self.input_path}{self.output_path}..."
290+
) as status:
291+
content = read_file(self.input_path)
292+
if content is None:
293+
return False
294+
295+
self.content = content
296+
original_content = content
297+
298+
try:
299+
for proc in track(self.processors, description="Applying processors"):
300+
status.update(f"[bold green]Running {proc.__name__}...")
301+
content = proc(content, self)
302+
303+
if preview:
304+
preview_changes(original_content, content)
305+
306+
return write_file(self.output_path, content)
307+
308+
except Exception as e:
309+
console.print(f"[red]Error during processing:[/red] {e}")
310+
return False
311+
312+
313+
ProcessingFunc = Callable[[str, File], str]
314+
315+
316+
def add_generated_warning(content: str, file: File) -> str:
317+
"""Add a warning comment indicating the file is auto-generated."""
318+
script_path = Path(__file__).relative_to(Path(__file__).parent.parent)
319+
warning = [
320+
"<!--",
321+
"THIS FILE IS AUTO-GENERATED",
322+
"DO NOT EDIT THIS FILE DIRECTLY",
323+
f"Generated via {script_path} from {file.input_path}",
324+
"-->",
325+
"",
326+
"",
327+
]
328+
return "\n".join(warning) + content
317329

318330

319331
def add_frontmatter(
@@ -345,7 +357,7 @@ def add_frontmatter(
345357
Content here
346358
"""
347359

348-
def processor(content: str) -> str:
360+
def processor(content: str, _file: File) -> str:
349361
# Remove existing frontmatter if present
350362
content_without_frontmatter = re.sub(
351363
r"^---\n.*?\n---\n", "", content, flags=re.DOTALL
@@ -371,7 +383,7 @@ def processor(content: str) -> str:
371383
return processor
372384

373385

374-
def convert_admonitions(content: str) -> str:
386+
def convert_admonitions(content: str, _file: File) -> str:
375387
"""
376388
Convert GitHub-style admonitions to Material for MkDocs-style admonitions.
377389
@@ -431,106 +443,83 @@ def process_match(match: re.Match[str]) -> str:
431443
return re.sub(pattern, process_match, content)
432444

433445

434-
def convert_repo_links(repo_url: str) -> ProcessingFunc:
435-
"""
436-
Convert relative repository links to absolute URLs.
446+
def convert_repo_links(content: str, file: File) -> str:
447+
"""Convert relative repository links to absolute URLs."""
437448

438-
Args:
439-
repo_url: The base repository URL (e.g., 'https://github.com/username/repo')
449+
def replace_link(match: re.Match[str]) -> str:
450+
text = match.group(1)
451+
path = match.group(2)
440452

441-
Returns:
442-
A processor function that converts relative links to absolute URLs
443-
444-
Example:
445-
Input:
446-
See the [`LICENSE`](LICENSE) file for more information.
447-
Check the [Neovim](/docs/editors/neovim.md) guide.
448-
Open an [issue](../../issues/new) to report bugs.
449-
450-
Output:
451-
See the [`LICENSE`](https://github.com/username/repo/blob/main/LICENSE) file for more information.
452-
Check the [Neovim](editors/neovim.md) guide.
453-
Open an [issue](https://github.com/username/repo/issues/new) to report bugs.
454-
"""
455-
456-
def processor(content: str) -> str:
457-
def replace_link(match: re.Match[str]) -> str:
458-
text = match.group(1)
459-
path = match.group(2)
453+
# Skip anchor links
454+
if path.startswith("#"):
455+
return match.group(0)
460456

461-
# Skip anchor links
462-
if path.startswith("#"):
463-
return match.group(0)
457+
# Skip already absolute URLs
458+
if path.startswith(("http://", "https://")):
459+
return match.group(0)
464460

465-
# Skip already absolute URLs
466-
if path.startswith(("http://", "https://")):
467-
return match.group(0)
461+
# Handle docs directory links
462+
if path.startswith(("/docs/", "docs/")):
463+
# Remove /docs/ or docs/ prefix and .md extension
464+
clean_path = path.removeprefix("/docs/").removeprefix("docs/")
465+
return f"[{text}]({clean_path})"
468466

469-
# Handle docs directory links
470-
if path.startswith(("/docs/", "docs/")):
471-
# Remove /docs/ or docs/ prefix and .md extension
472-
clean_path = path.removeprefix("/docs/").removeprefix("docs/")
473-
return f"[{text}]({clean_path})"
467+
# Handle relative paths with ../ or ./
468+
if "../" in path or "./" in path:
469+
# Special handling for GitHub-specific paths
470+
if "issues/" in path or "pulls/" in path:
471+
clean_path = path.replace("../", "").replace("./", "")
472+
return f"[{text}]({file.repo_url}/{clean_path})"
474473

475-
# Handle relative paths with ../ or ./
476-
if "../" in path or "./" in path:
477-
# Special handling for GitHub-specific paths
478-
if "issues/" in path or "pulls/" in path:
479-
clean_path = path.replace("../", "").replace("./", "")
480-
return f"[{text}]({repo_url}/{clean_path})"
474+
# Handle root-relative paths
475+
if path.startswith("/"):
476+
path = path.removeprefix("/")
481477

482-
# Handle root-relative paths
483-
if path.startswith("/"):
484-
path = path.removeprefix("/")
478+
# Remove ./ if present
479+
path = path.removeprefix("./")
485480

486-
# Remove ./ if present
487-
path = path.removeprefix("./")
481+
# Construct the full URL for repository files
482+
full_url = f"{file.repo_url.rstrip('/')}/blob/main/{path}"
483+
return f"[{text}]({full_url})"
488484

489-
# Construct the full URL for repository files
490-
full_url = f"{repo_url.rstrip('/')}/blob/main/{path}"
491-
return f"[{text}]({full_url})"
492-
493-
# Match markdown links: [text](url)
494-
pattern = r"\[((?:[^][]|\[[^]]*\])*)\]\(([^)]+)\)"
495-
return re.sub(pattern, replace_link, content)
496-
497-
processor.__name__ = "convert_repo_links"
498-
return processor
485+
# Match markdown links: [text](url)
486+
pattern = r"\[((?:[^][]|\[[^]]*\])*)\]\(([^)]+)\)"
487+
return re.sub(pattern, replace_link, content)
499488

500489

501490
def main():
502491
"""Process documentation files."""
503492
console.print("[bold blue]Documentation Processor[/bold blue]")
504493

494+
# Common processors
505495
common_processors = [
496+
add_generated_warning,
506497
convert_admonitions,
507-
convert_repo_links(
508-
"https://github.com/joshuadavidthomas/django-language-server"
509-
),
498+
convert_repo_links,
510499
]
511500

512-
readme_success = process_file(
513-
input="README.md",
514-
output="docs/index.md",
501+
readme = File(
502+
input_path="README.md",
503+
output_path="docs/index.md",
515504
processors=[
516-
add_frontmatter({"title": "Home"}),
517505
*common_processors,
506+
add_frontmatter({"title": "Home"}),
518507
],
519-
preview=True,
520-
description="README.md → docs/index.md",
521508
)
522509

523-
nvim_success = process_file(
524-
input="editors/nvim/README.md",
525-
output="docs/editors/neovim.md",
510+
nvim = File(
511+
input_path="editors/nvim/README.md",
512+
output_path="docs/editors/neovim.md",
526513
processors=[
527-
add_frontmatter({"title": "Neovim"}),
528514
*common_processors,
515+
add_frontmatter({"title": "Neovim"}),
529516
],
530-
preview=True,
531-
description="Neovim docs → docs/editors/neovim.md",
532517
)
533518

519+
# Process files
520+
readme_success = readme.process(preview=True)
521+
nvim_success = nvim.process(preview=True)
522+
534523
if readme_success and nvim_success:
535524
console.print("\n[green]✨ All files processed successfully![/green]")
536525
else:

0 commit comments

Comments
 (0)