implemented md to html
This commit is contained in:
parent
590f8548b0
commit
105f1eee29
3 changed files with 90 additions and 38 deletions
|
|
@ -1,9 +1,28 @@
|
|||
from textnode import TextType, TextNode
|
||||
from htmlnode import LeafNode
|
||||
from htmlnode import ParentNode, LeafNode
|
||||
import re
|
||||
|
||||
# ====Markdown Parsing and Block Handling====
|
||||
|
||||
def markdown_to_blocks(markdown):
|
||||
lines = markdown.split('\n')
|
||||
blocks = []
|
||||
current_block = []
|
||||
for line in lines:
|
||||
stripped = line.strip()
|
||||
if stripped == "":
|
||||
if current_block == []:
|
||||
continue
|
||||
else:
|
||||
blocks.append("\n".join(current_block).strip())
|
||||
current_block = []
|
||||
else:
|
||||
current_block.append(line)
|
||||
if current_block != []:
|
||||
blocks.append("\n".join(current_block).strip())
|
||||
current_block = []
|
||||
return blocks
|
||||
|
||||
def block_to_block_type(markdown):
|
||||
markdown = markdown.strip() # Remove leading/trailing whitespace
|
||||
|
||||
|
|
@ -49,37 +68,56 @@ def block_to_block_type(markdown):
|
|||
else:
|
||||
return "paragraph"
|
||||
|
||||
|
||||
def markdown_to_blocks(markdown):
|
||||
lines = markdown.split('\n')
|
||||
blocks = []
|
||||
current_block = []
|
||||
for line in lines:
|
||||
stripped = line.strip()
|
||||
if stripped == "":
|
||||
if current_block == []:
|
||||
continue
|
||||
else:
|
||||
blocks.append("\n".join(current_block).strip())
|
||||
current_block = []
|
||||
else:
|
||||
current_block.append(line)
|
||||
if current_block != []:
|
||||
blocks.append("\n".join(current_block).strip())
|
||||
current_block = []
|
||||
return blocks
|
||||
|
||||
|
||||
# ====Markdown Node Conversion====
|
||||
def markdown_to_html_node(markdown):
|
||||
blocks = markdown_to_blocks(markdown)
|
||||
nodes = []
|
||||
for block in blocks:
|
||||
block_type = block_to_block_type(block)
|
||||
match block_type:
|
||||
case "paragraph":
|
||||
nodes.append(ParentNode("p",text_to_children(block)))
|
||||
case "heading":
|
||||
nodes.append(ParentNode(f"h{block.count("#")}",text_to_children(block.strip("#"*block.count("#")+" "))))
|
||||
case "quote":
|
||||
nodes.append(ParentNode("blockquote",text_to_children(block.strip("> "))))
|
||||
case "code":
|
||||
tnodes = text_to_textnodes(block.strip("```").strip("\n"))
|
||||
hnodes = []
|
||||
for node in tnodes:
|
||||
hnodes.append(text_node_to_html_node(node))
|
||||
nodes.append(ParentNode("pre",[ParentNode("code",hnodes)]))
|
||||
case "ordered_list":
|
||||
items = block.split("\n")
|
||||
trimmed = []
|
||||
for item in items:
|
||||
item = re.sub(r'^\d+\. ', '', item)
|
||||
trimmed.append(ParentNode("li",text_to_children(item)))
|
||||
nodes.append(ParentNode("ol",trimmed))
|
||||
case "unordered_list":
|
||||
items = block.split("\n")
|
||||
trimmed = []
|
||||
for item in items:
|
||||
item = item.lstrip("* ")
|
||||
item = item.lstrip("- ")
|
||||
trimmed.append(ParentNode("li",text_to_children(item)))
|
||||
nodes.append(ParentNode("ul",trimmed))
|
||||
return ParentNode("div",nodes)
|
||||
# ====Markdown to HTML Helpers====
|
||||
def text_to_children(text):
|
||||
text_nodes = text_to_textnodes(text)
|
||||
html_nodes = []
|
||||
for node in text_nodes:
|
||||
html_nodes.append(text_node_to_html_node(node))
|
||||
return html_nodes
|
||||
|
||||
def text_node_to_html_node(text_node):
|
||||
match text_node.text_type:
|
||||
case TextType.NORMAL_TEXT:
|
||||
return LeafNode(value=text_node.text)
|
||||
case TextType.BOLD_TEXT:
|
||||
return LeafNode(value=text_node.text, tag="b")
|
||||
return LeafNode(value=text_node.text, tag="strong")
|
||||
case TextType.ITALIC_TEXT:
|
||||
return LeafNode(value=text_node.text, tag="i")
|
||||
return LeafNode(value=text_node.text, tag="em")
|
||||
case TextType.CODE_TEXT:
|
||||
return LeafNode(value=text_node.text, tag="code")
|
||||
case TextType.LINK_TEXT:
|
||||
|
|
|
|||
15
src/main.py
15
src/main.py
|
|
@ -1,15 +1,10 @@
|
|||
from textnode import TextNode,TextType
|
||||
from conversions import markdown_to_blocks
|
||||
from conversions import markdown_to_html_node
|
||||
def main():
|
||||
md = """# This is a heading
|
||||
|
||||
This is a paragraph of text. It has some **bold** and *italic* words inside of it.
|
||||
|
||||
* This is the first list item in a list block
|
||||
* This is a list item
|
||||
* This is another list item
|
||||
"""
|
||||
print(markdown_to_blocks(md))
|
||||
test_input = "This is *italics* and **bold**"
|
||||
result = markdown_to_html_node(test_input).to_html()
|
||||
print(f"Expected: <div><p>This is <em>italics</em> and <strong>bold</strong></p></div>")
|
||||
print(f"Got: {result}")
|
||||
|
||||
if __name__=="__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import unittest
|
||||
from htmlnode import LeafNode
|
||||
from conversions import text_node_to_html_node,split_nodes_delimiter,extract_markdown_images,extract_markdown_links,split_nodes_image,split_nodes_link,text_to_textnodes,markdown_to_blocks,block_to_block_type
|
||||
from conversions import text_node_to_html_node,split_nodes_delimiter,extract_markdown_images,extract_markdown_links,split_nodes_image,split_nodes_link,text_to_textnodes,markdown_to_blocks,block_to_block_type,markdown_to_html_node
|
||||
from textnode import TextType,TextNode
|
||||
import re
|
||||
class TestConversions(unittest.TestCase):
|
||||
|
|
@ -15,13 +15,13 @@ class TestConversions(unittest.TestCase):
|
|||
def test_bold_node_to_html_node(self):
|
||||
bold_node = TextNode("Hello, world!", TextType.BOLD_TEXT)
|
||||
html_node = text_node_to_html_node(bold_node)
|
||||
assert html_node.tag == "b"
|
||||
assert html_node.tag == "strong"
|
||||
assert html_node.value == "Hello, world!"
|
||||
|
||||
def test_italic_node_to_html_node(self):
|
||||
italic_node = TextNode("Hello, world!", TextType.ITALIC_TEXT)
|
||||
html_node = text_node_to_html_node(italic_node)
|
||||
assert html_node.tag == "i"
|
||||
assert html_node.tag == "em"
|
||||
assert html_node.value == "Hello, world!"
|
||||
|
||||
def test_code_node_to_html_node(self):
|
||||
|
|
@ -287,6 +287,25 @@ class TestBlockToBlockType(unittest.TestCase):
|
|||
self.assertEqual(block_to_block_type("Random text without markdown"), "paragraph")
|
||||
self.assertEqual(block_to_block_type("Another paragraph"), "paragraph")
|
||||
|
||||
class TestMDToHTML(unittest.TestCase):
|
||||
def test_markdown_to_html_node(self):
|
||||
# Basic blocks
|
||||
assert markdown_to_html_node("This is a paragraph").to_html() == "<div><p>This is a paragraph</p></div>"
|
||||
assert markdown_to_html_node("# Header").to_html() == "<div><h1>Header</h1></div>"
|
||||
assert markdown_to_html_node("## Header 2").to_html() == "<div><h2>Header 2</h2></div>"
|
||||
|
||||
# Lists
|
||||
assert markdown_to_html_node("- Item 1\n- Item 2").to_html() == "<div><ul><li>Item 1</li><li>Item 2</li></ul></div>"
|
||||
assert markdown_to_html_node("1. First\n2. Second").to_html() == "<div><ol><li>First</li><li>Second</li></ol></div>"
|
||||
|
||||
# Code blocks
|
||||
assert markdown_to_html_node("```\ncode block\n```").to_html() == "<div><pre><code>code block</code></pre></div>"
|
||||
|
||||
# Quotes
|
||||
assert markdown_to_html_node("> Quote").to_html() == "<div><blockquote>Quote</blockquote></div>"
|
||||
|
||||
# Mixed inline formatting
|
||||
assert markdown_to_html_node("This is *italics* and **bold**").to_html() == "<div><p>This is <em>italics</em> and <strong>bold</strong></p></div>"
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue