From a0d7323bec8d0e4f9dee3b52b44e1598ea2cbad1 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Fri, 20 Dec 2024 17:14:22 -0500 Subject: [PATCH 1/3] x --- docs/_scripts/notebook_hooks.py | 65 +++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/docs/_scripts/notebook_hooks.py b/docs/_scripts/notebook_hooks.py index c993b6d22..048bbd09a 100644 --- a/docs/_scripts/notebook_hooks.py +++ b/docs/_scripts/notebook_hooks.py @@ -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__) @@ -35,12 +37,69 @@ 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 + code_block_pattern = re.compile( + r"```(?Ppy|python|js)(?!\s+hl_lines=)\n" + r"(?P((?:.*\n)*?))" # Capture the code inside the block using named group + r"```" + ) + + def replace_highlight_comments(match: re.Match) -> str: + 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'```{language} hl_lines="{" ".join(highlighted_lines)}"\n{new_code_block}\n```' + else: + return f"```{language}\n{new_code_block}\n```" + + # 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 From 056f581342dea55c8649b0b825005cf78ffadbfa Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Fri, 20 Dec 2024 17:29:10 -0500 Subject: [PATCH 2/3] x --- docs/_scripts/notebook_hooks.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/_scripts/notebook_hooks.py b/docs/_scripts/notebook_hooks.py index 048bbd09a..54cb05de8 100644 --- a/docs/_scripts/notebook_hooks.py +++ b/docs/_scripts/notebook_hooks.py @@ -49,13 +49,15 @@ def _highlight_code_blocks(markdown: str) -> str: """ # 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"```(?Ppy|python|js)(?!\s+hl_lines=)\n" + r"(?P[ \t]*)```(?Ppy|python|js|javascript)(?!\s+hl_lines=)\n" r"(?P((?:.*\n)*?))" # Capture the code inside the block using named group - r"```" + 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") @@ -84,9 +86,13 @@ def replace_highlight_comments(match: re.Match) -> str: new_code_block = "\n".join(lines_to_keep) if highlighted_lines: - return f'```{language} hl_lines="{" ".join(highlighted_lines)}"\n{new_code_block}\n```' + return ( + f'{indent}```{language} hl_lines="{" ".join(highlighted_lines)}"' + f'{new_code_block}' # The indent is already included in the code block + f'\n{indent}```' + ) else: - return f"```{language}\n{new_code_block}\n```" + return f"{indent}```{language}\n{new_code_block}\n{indent}```" # Replace all code blocks in the markdown markdown = code_block_pattern.sub(replace_highlight_comments, markdown) From 1e0aebc3ec1adc1fd02574f61d09ceade6c25321 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Fri, 20 Dec 2024 17:38:20 -0500 Subject: [PATCH 3/3] x --- docs/_scripts/notebook_hooks.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/_scripts/notebook_hooks.py b/docs/_scripts/notebook_hooks.py index 54cb05de8..b18e3dad5 100644 --- a/docs/_scripts/notebook_hooks.py +++ b/docs/_scripts/notebook_hooks.py @@ -44,7 +44,7 @@ def _highlight_code_blocks(markdown: str) -> str: markdown: The markdown content to process. Returns: - updated markdown code with code blocks containing highlight comments + 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 @@ -87,12 +87,18 @@ def replace_highlight_comments(match: re.Match) -> str: if highlighted_lines: return ( - f'{indent}```{language} hl_lines="{" ".join(highlighted_lines)}"' - f'{new_code_block}' # The indent is already included in the code block - f'\n{indent}```' + 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{new_code_block}\n{indent}```" + 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)