diff --git a/README.md b/README.md index f2259d1..34c2749 100644 --- a/README.md +++ b/README.md @@ -65,15 +65,15 @@ moffee is an open-source slide maker that transforms markdown documents into cle One of moffee's strengths is using dividers to organize text and images effectively. -___ +=== - Use `---` to trigger page breaks. -- Use `***` to arrange elements horizontally. -- Use `___` to split elements vertically. +- Use `<->` to arrange elements horizontally. +- Use `===` to split elements vertically. moffee automatically adjusts element sizes to accommodate large blocks of text or complex illustrations. -*** +<-> ![blue coffee](coffee.png) ``` @@ -158,23 +158,23 @@ Text on the next slide. You'll notice the second slide shares the `Page 1` title. moffee selects the most suitable title for each slide. -In addition to `---`, moffee supports `***` and `___` for in-slide layout. Use `***` to separate elements horizontally: +In addition to `---`, moffee supports `<->` and `===` for in-slide layout. Use `<->` to separate elements horizontally: ```markdown Text on the left. -*** +<-> ![Image on the right](https://placehold.co/600x400) ``` -`___` places elements vertically and takes precedence over `***`. Use them together for flexible layouts: +`===` places elements vertically and takes precedence over `<->`. Use them together for flexible layouts: ```markdown Top bun -___ +=== Patty on the left -*** +<-> Lettuce on the right -___ +=== Bottom bun ``` diff --git a/SECURITY.md b/SECURITY.md index 0991fbc..32a4411 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,7 +12,7 @@ currently being supported with security updates. ## Reporting a Vulnerability -If you discover a security vulnerability, please report it by creating an issue in our project's Issue Tracker. +If you discover a security vulnerability, please report it by creating an issue in our project's Issue Tracker. When reporting, please provide: - A brief description of the vulnerability diff --git a/docs/getting-started.md b/docs/getting-started.md index 28acefb..ef60b0b 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -53,23 +53,23 @@ Text on the next slide. You'll notice the second slide shares the `Page 1` title. moffee selects the most suitable title for each slide. -In addition to `---`, moffee supports `***` and `___` for in-slide layout. Use `***` to separate elements horizontally: +In addition to `---`, moffee supports `<->` and `===` for in-slide layout. Use `<->` to separate elements horizontally: ```markdown Text on the left. -*** +<-> ![Image on the right](https://placehold.co/600x400) ``` -`___` places elements vertically and takes precedence over `***`. Use them together for flexible layouts: +`===` places elements vertically and takes precedence over `<->`. Use them together for flexible layouts: ```markdown Top bun -___ +=== Patty on the left -*** +<-> Lettuce on the right -___ +=== Bottom bun ``` diff --git a/docs/syntax.md b/docs/syntax.md index cd7ad8c..a2b490d 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -15,7 +15,7 @@ Use headers to structure your presentation: Emphasize key points: - *Italic*: `*italic*` or `_italic_` - **Bold**: `**bold**` or `__bold__` -- ***Bold and Italic***: `***bold and italic***` +- <->Bold and Italic<->: `<->bold and italic<->` ### Lists Organize information clearly: @@ -131,18 +131,18 @@ Content for slide 2 ### In-slide Layout #### Horizontal Separation -Create columns with `***`: +Create columns with `<->`: ```markdown Left column content -*** +<-> Right column content ``` #### Vertical Separation -Stack content with `___`: +Stack content with `===`: ```markdown Top section -___ +=== Bottom section ``` @@ -150,11 +150,11 @@ Bottom section Create complex layouts: ```markdown Top row -___ +=== Left column -*** +<-> Right column -___ +=== Bottom row ``` diff --git a/moffee/compositor.py b/moffee/compositor.py index 37c2383..ce1d1ec 100644 --- a/moffee/compositor.py +++ b/moffee/compositor.py @@ -114,9 +114,9 @@ def chunk(self) -> Chunk: """ Split raw_md into chunk tree Chunk tree branches when in-page divider is met. - - adjacent "***"s create chunk with horizontal direction - - adjacent "___" create chunk with vertical direction - "___" possesses higher priority than "***" + - adjacent "<->"s create chunk with horizontal direction + - adjacent "===" create chunk with vertical direction + "===" possesses higher priority than "<->" :return: Root of the chunk tree """ @@ -133,12 +133,12 @@ def split_by_div(text, type) -> List[Chunk]: strs[-1] += line + "\n" return [Chunk(paragraph=s) for s in strs] - # collect "___" - vchunks = split_by_div(self.raw_md, "_") - # split by "***" if possible + # collect "===" + vchunks = split_by_div(self.raw_md, "=") + # split by "<->" if possible for i in range(len(vchunks)): - hchunks = split_by_div(vchunks[i].paragraph, "*") - if len(hchunks) > 1: # found *** + hchunks = split_by_div(vchunks[i].paragraph, "<") + if len(hchunks) > 1: # found <-> vchunks[i] = Chunk(children=hchunks, type=Type.NODE) if len(vchunks) == 1: @@ -259,7 +259,7 @@ def composite(document: str) -> List[Page]: Splitting criteria: - New h1/h2/h3 header (except when following another header) - - "---" Divider (___, ***, +++ not count) + - "---" Divider (===, <->, +++ not count) :param document: Input markdown document as a string. :param document_path: Optional string, will be used to redirect url in documents if given. diff --git a/moffee/utils/md_helper.py b/moffee/utils/md_helper.py index 034742c..f779c96 100644 --- a/moffee/utils/md_helper.py +++ b/moffee/utils/md_helper.py @@ -40,26 +40,30 @@ def is_empty(line: str) -> bool: return is_comment(line) or line.strip() == "" -def is_divider(line: str, type=None) -> bool: +def is_divider(line: str, type: Optional[str] = None) -> bool: """ - Determines if a given line is a Markdown divider (horizontal rule). - Markdown dividers are three or more hyphens, asterisks, or underscores, - without any other characters except spaces. + Determines if a given line is a Markdown divider (horizontal rule, vertical divider, or horizontal divider). :param line: The line to check - :param type: Which type to match, str. e.g. "*" to match "***" only. Defaults to "", match any of "*", "-" and "_". + :param type: Which type to match, str. e.g. "*" to match "***" only, "<" to match "<->", "=" to match "===". + Defaults to None, match any of "*", "-", "_", "<" or "=". :return: True if the line is a divider, False otherwise """ stripped_line = line.strip() - if len(stripped_line) < 3: - return False if type is None: - type = "-*_" - - assert type in "-*_", "type must be either '*', '-' or '_'" - return all(char in type for char in stripped_line) and any( - char * 3 in stripped_line for char in type - ) + return bool(re.match(r"^\s*([\*\-\_]{3,}|<->|={3,})\s*$", stripped_line)) + elif type == "*": + return bool(re.match(r"^\s*\*{3,}\s*$", stripped_line)) + elif type == "-": + return bool(re.match(r"^\s*\-{3,}\s*$", stripped_line)) + elif type == "_": + return bool(re.match(r"^\s*_{3,}\s*$", stripped_line)) + elif type == "<": + return bool(re.match(r"^\s*<->\s*$", stripped_line)) + elif type == "=": + return bool(re.match(r"^\s*={3,}\s*$", stripped_line)) + else: + return False def contains_image(line: str) -> bool: diff --git a/pyproject.toml b/pyproject.toml index 9a44973..2aa91d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ pymdown-extensions = "^10.8.1" livereload = "^2.7.0" click = "^8.1.7" beautifulsoup4 = "^4.12.3" +myst-parser = "^4.0.0" [tool.poetry.dev-dependencies] pytest = "^8.2.2" diff --git a/tests/test_builder.py b/tests/test_builder.py index e1ff007..75c892c 100644 --- a/tests/test_builder.py +++ b/tests/test_builder.py @@ -24,11 +24,11 @@ def setup_test_env(): ![Image-1](image.png) --- Paragraph 1 -___ +=== Paragraph 2 -*** +<-> Paragraph 3 -*** +<-> ![Image-2](image2.png) """ with tempfile.TemporaryDirectory() as temp_dir: diff --git a/tests/test_md_helper.py b/tests/test_md_helper.py index 51523ab..8681a20 100644 --- a/tests/test_md_helper.py +++ b/tests/test_md_helper.py @@ -40,6 +40,15 @@ def test_is_divider(): assert is_divider("***", type="*") is True assert is_divider("***", type="-") is False assert is_divider("* * *", type="*") is False + assert is_divider("<->") is True + assert is_divider("<->", type="<") is True + assert is_divider("<->", type="-") is False + assert is_divider("===") is True + assert is_divider("===", type="=") is True + assert is_divider("===", type="*") is False + assert is_divider(" === ") is True + assert is_divider("==") is False + assert is_divider("= = =") is False def test_contains_image(): diff --git a/tests/test_paginate.py b/tests/test_paginate.py index c8660e1..50f1fd3 100644 --- a/tests/test_paginate.py +++ b/tests/test_paginate.py @@ -112,7 +112,7 @@ def test_page_splitting_on_dividers(): Content 1 --- Content 2 -*** +<-> Content 3 """ pages = composite(doc) @@ -126,7 +126,7 @@ def test_escaped_area_paging(): --- Content 2 ``` -*** +<-> Content 3 """ pages = composite(doc) @@ -139,7 +139,7 @@ def test_escaped_area_chunking(): --- Content 2 ```bash -*** +<-> Content 3 ``` """ @@ -198,7 +198,7 @@ def test_chunking_trivial(): def test_chunking_vertical(): doc = """ Paragraph 1 -___ +=== Paragraph 2 """ @@ -213,10 +213,10 @@ def test_chunking_vertical(): def test_chunking_horizontal(): doc = """ Paragraph 1 -*** +<-> Paragraph 2 -*** +<-> """ pages = composite(doc) chunk = pages[0].chunk @@ -231,11 +231,11 @@ def test_chunking_hybrid(): Other Pages --- Paragraph 1 -___ +=== Paragraph 2 -*** +<-> Paragraph 3 -*** +<-> Paragraph 4 """ pages = composite(doc)