From b41b595dee61d2c8d41ca176e7b647d5544f51d8 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Tue, 30 Apr 2024 11:20:41 -0400 Subject: [PATCH] working through the to html functions --- src/markdown_blocks.py | 129 ++++++++++++++++++++++++++++++++++++ src/test_markdown_blocks.py | 101 ++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 src/markdown_blocks.py create mode 100644 src/test_markdown_blocks.py diff --git a/src/markdown_blocks.py b/src/markdown_blocks.py new file mode 100644 index 0000000..7601119 --- /dev/null +++ b/src/markdown_blocks.py @@ -0,0 +1,129 @@ +import re + +from htmlnode import LeafNode, ParentNode + +block_type_paragraph = "paragraph" +block_type_heading = "heading" +block_type_code = "code" +block_type_quote = "quote" +block_type_unordered_list = "unordered_list" +block_type_ordered_list = "ordered_list" + +def markdown_to_blocks(markdown): + blocks = re.split("\n\n", markdown) + final = [] + for block in blocks: + if block != "": + final.append(block.strip()) + return final + +def block_to_block_type(block): + heading_regex = "^#{1,6} " + code_regex = "^```.*```$" + quote_regex = "^>" + unordered_regex = "^[-,*] " + ordered_regex = "^[0-9]{1,10}\\. " + if re.search(heading_regex, block): + return block_type_heading + elif re.search(code_regex, block): + return block_type_code + elif re.search(quote_regex, block): + is_true = True + lines = re.split("\n", block) + for line in lines: + if re.search(quote_regex, line): + is_true = True + else: + is_true = False + if is_true: + return block_type_quote + elif re.search(unordered_regex, block): + is_true = True + lines = re.split("\n", block) + for line in lines: + if re.search(unordered_regex, line): + is_true = True + else: + is_true = False + if is_true: + return block_type_unordered_list + elif re.search(ordered_regex, block): + is_true = True + lines = re.split("\n", block) + for i in range(len(lines)): + if re.search(ordered_regex, lines[i]) and int(re.search("^[0-9]{1,10}", lines[i]).group()) == (i+1): + is_true = True + else: + is_true = False + if is_true: + return block_type_ordered_list + else: + return block_type_paragraph + +def paragraph_to_html_node(block): + return LeafNode("p", block) + +def heading_to_html_node(block): + regexed_block = re.search("(^#{1,6}) (.*)", block) + count = len(regexed_block.groups(1)) + data = regexed_block.groups(2) + return LeafNode(f"h{count}", data) + +def code_to_html_node(block): + code_data = re.search("^```(.*)```$", block).groups(1)[0] + return ParentNode( + "pre", + [ + LeafNode("code", code_data) + ] + ) + +def quote_to_html_node(block): + quote_lines = re.split("\n?> ", block) + if quote_lines[0] == "": + quote_lines = quote_lines[1:] + quote = [] + for quote_line in quote_lines: + quote.append(quote_line.strip()) + data = "\n".join(quote) + return LeafNode("blockquote", data) + +def unordered_list_to_html_node(block): + nodes = [] + bullets = re.split("\n?[*,-] ", block) + for bullet in bullets: + if bullet != "": + nodes.append(LeafNode("li", bullet)) + return ParentNode("ul", nodes) + +def ordered_list_to_html_node(block): + nodes = [] + bullets = re.split("\n?[0-9]{1,10}\\. ", block) + for bullet in bullets: + if bullet != "": + nodes.append(LeafNode("li", bullet)) + return ParentNode("ol", nodes) + +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(paragraph_to_html_node(block)) + case "code": + nodes.append(code_to_html_node(block)) + case "heading": + nodes.append(heading_to_html_node(block)) + case "quote": + nodes.append(quote_to_html_node(block)) + case "unordered_list": + nodes.append(unordered_list_to_html_node(block)) + case "ordered_list": + nodes.append(ordered_list_to_html_node(block)) + return ParentNode("div", nodes) + + +quote_block = "> quote first line\n> quote second line" +print(quote_to_html_node(quote_block)) \ No newline at end of file diff --git a/src/test_markdown_blocks.py b/src/test_markdown_blocks.py new file mode 100644 index 0000000..adc4ff0 --- /dev/null +++ b/src/test_markdown_blocks.py @@ -0,0 +1,101 @@ +import unittest + +from htmlnode import LeafNode, ParentNode +from markdown_blocks import (block_to_block_type, code_to_html_node, heading_to_html_node, markdown_to_blocks, + block_type_heading, block_type_code, block_type_paragraph, + block_type_ordered_list, block_type_unordered_list, block_type_quote, ordered_list_to_html_node, paragraph_to_html_node, quote_to_html_node, unordered_list_to_html_node) + +class TestMarkdownToHTML(unittest.TestCase): + def test_markdown_to_blocks(self): + markdown = """ +This is **bolded** paragraph + +This is another paragraph with *italic* text and `code` here +This is the same paragraph on a new line + + + + +* This is a list +* with items +""" + blocks = markdown_to_blocks(markdown) + self.assertEqual([ +"This is **bolded** paragraph", +"""This is another paragraph with *italic* text and `code` here +This is the same paragraph on a new line""", +"""* This is a list +* with items""", + ], blocks) + + def test_block_to_block_type_heading(self): + heading_block = "### This is a 3rd heading" + run = block_to_block_type(heading_block) + self.assertEqual(block_type_heading, run) + + def test_block_to_block_type_code(self): + code_block = "```code_block```" + run = block_to_block_type(code_block) + self.assertEqual(block_type_code, run) + + def test_block_to_block_type_quote(self): + quote_block = "> quote first line\n> quote second line" + run = block_to_block_type(quote_block) + self.assertEqual(block_type_quote, run) + + def test_block_to_block_type_unordered_list(self): + unordered_block = "* list first line\n* list second line" + run = block_to_block_type(unordered_block) + self.assertEqual(block_type_unordered_list, run) + + def test_block_to_block_type_ordered_list(self): + ordered_block = "1. list first line\n2. list second line" + run = block_to_block_type(ordered_block) + self.assertEqual(block_type_ordered_list, run) + + def test_block_to_block_type_paragraph(self): + paragraph_block = "This is a general paragraph.\nJust another general paragraph." + run = block_to_block_type(paragraph_block) + self.assertEqual(block_type_paragraph, run) + + + + def test_heading_to_html_node(self): + heading_block = "### This is a 3rd heading" + run = heading_to_html_node(heading_block) + self.assertEqual(LeafNode("h3", "This is a 3rd heading"), run) + + def test_code_to_html_node(self): + code_block = "```code_block```" + run = code_to_html_node(code_block) + self.assertEqual( + ParentNode("pre", [ + LeafNode("code", "code_block") + ]), run) + + def test_quote_to_html_node(self): + quote_block = "> quote first line\n> quote second line" + run = quote_to_html_node(quote_block) + self.assertEqual(LeafNode("blockquote", "quote first line\nquote second line"), run) + + def test_unordered_list_to_html_node(self): + unordered_block = "* list first line\n* list second line" + run = unordered_list_to_html_node(unordered_block) + self.assertEqual(ParentNode("ul", [ + LeafNode("li", "list first line"), + LeafNode("li", "list second line"), + ]), run) + + def test_ordered_list_to_html_node(self): + ordered_block = "1. list first line\n2. list second line" + run = ordered_list_to_html_node(ordered_block) + self.assertEqual(ParentNode("ol", [ + LeafNode("li", "list first line"), + LeafNode("li", "list second line"), + ]), run) + + def test_paragraph_to_html_node(self): + paragraph_block = "This is a general paragraph.\nJust another general paragraph." + run = paragraph_to_html_node(paragraph_block) + self.assertEqual(LeafNode("p", "This is a general paragraph.\nJust another general paragraph."), + run) \ No newline at end of file