93 lines
2.6 KiB
Python
93 lines
2.6 KiB
Python
from typing import Callable
|
|
|
|
from src.markdown.extract import extract_markdown_images, extract_markdown_links
|
|
from src.nodes.text import TextNode, TextType
|
|
|
|
|
|
def split_nodes_delimiter(
|
|
old_nodes: list[TextNode], delimiter: str, text_type: TextType
|
|
) -> list[TextNode]:
|
|
result = []
|
|
|
|
for node in old_nodes:
|
|
if node.text_type != TextType.PLAIN:
|
|
result.append(node)
|
|
continue
|
|
|
|
parts = node.text.split(delimiter)
|
|
|
|
if len(parts) % 2 == 0:
|
|
raise RuntimeError("No matching delimiter found")
|
|
|
|
for i in range(len(parts)):
|
|
current_text = parts[i]
|
|
|
|
if i % 2 == 0:
|
|
result.append(TextNode(current_text, TextType.PLAIN))
|
|
else:
|
|
result.append(TextNode(current_text, text_type))
|
|
|
|
return result
|
|
|
|
|
|
def split_nodes_image(old_nodes: list[TextNode]) -> list[TextNode]:
|
|
return split_nodes(
|
|
old_nodes,
|
|
extracter=extract_markdown_images,
|
|
pattern_builder=lambda t: f"![{t[0]}]({t[1]})",
|
|
node_creator=lambda t: TextNode(t[0], TextType.IMAGE, t[1]),
|
|
)
|
|
|
|
|
|
def split_nodes_link(old_nodes: list[TextNode]) -> list[TextNode]:
|
|
return split_nodes(
|
|
old_nodes,
|
|
extracter=extract_markdown_links,
|
|
pattern_builder=lambda t: f"[{t[0]}]({t[1]})",
|
|
node_creator=lambda t: TextNode(t[0], TextType.LINK, t[1]),
|
|
)
|
|
|
|
|
|
def split_nodes(
|
|
old_nodes: list[TextNode],
|
|
extracter: Callable[[str], list[tuple[str, str]]],
|
|
pattern_builder: Callable[[tuple[str, str]], str],
|
|
node_creator: Callable[[tuple[str, str]], TextNode],
|
|
) -> list[TextNode]:
|
|
result = []
|
|
|
|
for node in old_nodes:
|
|
if node.text_type != TextType.PLAIN:
|
|
result.append(node)
|
|
continue
|
|
|
|
extracted = extracter(node.text)
|
|
|
|
node_text = node.text
|
|
|
|
for match in extracted:
|
|
pattern = pattern_builder(match)
|
|
parts = node_text.split(pattern, maxsplit=1)
|
|
|
|
result.append(TextNode(parts[0], TextType.PLAIN))
|
|
|
|
matched_node = node_creator(match)
|
|
result.append(matched_node)
|
|
|
|
node_text = parts[1]
|
|
|
|
if len(node_text) > 0:
|
|
result.append(TextNode(node_text, TextType.PLAIN))
|
|
|
|
return result
|
|
|
|
|
|
def text_to_text_node(text: str) -> list[TextNode]:
|
|
old_nodes = [TextNode(text, TextType.PLAIN)]
|
|
old_nodes = split_nodes_delimiter(old_nodes, "**", TextType.BOLD)
|
|
old_nodes = split_nodes_delimiter(old_nodes, "_", TextType.ITALIC)
|
|
old_nodes = split_nodes_delimiter(old_nodes, "`", TextType.CODE)
|
|
old_nodes = split_nodes_image(old_nodes)
|
|
old_nodes = split_nodes_link(old_nodes)
|
|
return old_nodes
|