mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-09-30 05:25:05 +02:00
docs: fix up edge cases with links in notebooks (#3414)
* Adds another notebook conversion * Fix up some edge cases for handling links in notebooks. Notebooks links were using a different convention than markdown links. We'll need to push additional logic to use an appropriate suffix (.md or .ipynb) for cross-references between how-to guides (though these should be rare).
This commit is contained in:
@@ -26,10 +26,57 @@ class EscapePreprocessor(Preprocessor):
|
||||
cell.source,
|
||||
)
|
||||
else:
|
||||
# Keep format but replace the .ipynb extension with .md
|
||||
# We want to update markdown links in cell.source by replacing a '.ipynb'
|
||||
# extension with '.md', but only for links that:
|
||||
# - are not image links (i.e. not preceded by '!')
|
||||
# - do not contain '//' in the URL (to avoid external links)
|
||||
|
||||
# Define the regex pattern in parts for clarity:
|
||||
pattern = (
|
||||
r"(?<!!)" # Negative lookbehind: ensure the link is not an image (i.e., doesn't start with "!")
|
||||
r"\[" # Literal '[' indicating the start of the link text.
|
||||
r"(?P<text>[^\]]*)" # Named group 'text': match any characters except ']', representing the link text.
|
||||
r"\]" # Literal ']' indicating the end of the link text.
|
||||
r"\(" # Literal '(' indicating the start of the URL.
|
||||
r"(?![^\)]*//)" # Negative lookahead: ensure that the URL does not contain '//' (skip absolute URLs).
|
||||
r"(?P<url>[^)]*)" # Named group 'url': match any characters except ')', representing the URL.
|
||||
r"\)" # Literal ')' indicating the end of the URL.
|
||||
)
|
||||
|
||||
def custom_replacement(match):
|
||||
"""logic will correct the link format used in ipython notebooks
|
||||
|
||||
Ipython notebooks were being converted directly into HTML links
|
||||
instead of markdown links that retain the markdown extension.
|
||||
|
||||
It needs to handle the following cases:
|
||||
- optional fragments (e.g., `#section`)
|
||||
e.g., `[text](url/#section)` -> `[text](url.md#section)`
|
||||
e.g., `[text](url#section)` -> `[text](url.md#section)`
|
||||
- relative paths (e.g., `../path/to/file`) need to be
|
||||
denested by 1 level
|
||||
"""
|
||||
text = match.group("text")
|
||||
url = match.group("url")
|
||||
|
||||
if url.startswith("../"):
|
||||
# we strip the "../" from the start of the URL
|
||||
# We only need to denest one level.
|
||||
url = url[3:]
|
||||
|
||||
url = url.rstrip("/") # Strip `/` from the end of the URL
|
||||
|
||||
# if url has a fragment
|
||||
if "#" in url:
|
||||
url, fragment = url.split("#")
|
||||
# Strip `/` from the end of the URL
|
||||
return f"[{text}]({url}.md#{fragment})"
|
||||
# Otherwise add the .md extension
|
||||
return f"[{text}]({url}.md)"
|
||||
|
||||
cell.source = re.sub(
|
||||
r"(?<!!)\[([^\]]*)\]\((?![^\)]*//)([^)]*)(?:\.ipynb)?\)",
|
||||
r"[\1](\2.md)",
|
||||
pattern,
|
||||
custom_replacement,
|
||||
cell.source,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user