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