Skip to content

Commit

Permalink
docs: Add highlight-next-line (#2850)
Browse files Browse the repository at this point in the history
  • Loading branch information
eyurtsev authored Dec 21, 2024
2 parents a3c5b8f + 1e0aebc commit 9e31b82
Showing 1 changed file with 74 additions and 3 deletions.
77 changes: 74 additions & 3 deletions docs/_scripts/notebook_hooks.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import logging
import os
import re
from typing import Any, Dict

from mkdocs.structure.pages import Page
from mkdocs.structure.files import Files, File
from mkdocs.structure.pages import Page

from notebook_convert import convert_notebook

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -35,12 +37,81 @@ def on_files(files: Files, **kwargs: Dict[str, Any]):
return new_files


def _highlight_code_blocks(markdown: str) -> str:
"""Find code blocks with highlight comments and add hl_lines attribute.
Args:
markdown: The markdown content to process.
Returns:
updated Markdown code with code blocks containing highlight comments
updated to use the hl_lines attribute.
"""
# Pattern to find code blocks with highlight comments and without
# existing hl_lines for Python and JavaScript
# Pattern to find code blocks with highlight comments, handling optional indentation
code_block_pattern = re.compile(
r"(?P<indent>[ \t]*)```(?P<language>py|python|js|javascript)(?!\s+hl_lines=)\n"
r"(?P<code>((?:.*\n)*?))" # Capture the code inside the block using named group
r"(?P=indent)```" # Match closing backticks with the same indentation
)

def replace_highlight_comments(match: re.Match) -> str:
indent = match.group("indent")
language = match.group("language")
code_block = match.group("code")
lines = code_block.split("\n")
highlighted_lines = []

# Skip initial empty lines
while lines and not lines[0].strip():
lines.pop(0)

lines_to_keep = []

comment_syntax = (
"# highlight-next-line"
if language in ["py", "python"]
else "// highlight-next-line"
)

for line in lines:
if comment_syntax in line:
count = len(lines_to_keep) + 1
highlighted_lines.append(str(count))
else:
lines_to_keep.append(line)

# Reconstruct the new code block
new_code_block = "\n".join(lines_to_keep)

if highlighted_lines:
return (
f'{indent}```{language} hl_lines="{" ".join(highlighted_lines)}"\n'
# The indent and terminating \n is already included in the code block
f'{new_code_block}'
f'{indent}```'
)
else:
return (
f"{indent}```{language}\n"
# The indent and terminating \n is already included in the code block
f"{new_code_block}"
f"{indent}```"
)

# Replace all code blocks in the markdown
markdown = code_block_pattern.sub(replace_highlight_comments, markdown)
return markdown


def on_page_markdown(markdown: str, page: Page, **kwargs: Dict[str, Any]):
if DISABLED:
return markdown
if page.file.src_path.endswith(".ipynb"):
logger.info("Processing Jupyter notebook: %s", page.file.src_path)
body = convert_notebook(page.file.abs_src_path)
return body
markdown = convert_notebook(page.file.abs_src_path)
# Apply highlight comments to code blocks
markdown = _highlight_code_blocks(markdown)

return markdown

0 comments on commit 9e31b82

Please sign in to comment.