From 4d1506f6272f10c5185330feb4623789cfa09fe6 Mon Sep 17 00:00:00 2001 From: fallintoplace <38443830+fallintoplace@users.noreply.github.com> Date: Sun, 4 Oct 2026 16:28:21 +0200 Subject: [PATCH] fix(rss): separate entry dates from previous bodies --- .../markitdown/converters/_rss_converter.py | 4 ++ packages/markitdown/tests/test_rss.py | 65 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/packages/markitdown/src/markitdown/converters/_rss_converter.py b/packages/markitdown/src/markitdown/converters/_rss_converter.py index ce768b8473..14645da47c 100644 --- a/packages/markitdown/src/markitdown/converters/_rss_converter.py +++ b/packages/markitdown/src/markitdown/converters/_rss_converter.py @@ -184,6 +184,8 @@ def _parse_atom_type( if entry_title: md_text += f"\n## {entry_title}\n" if entry_updated: + if md_text and not md_text.endswith("\n"): + md_text += "\n\n" md_text += f"Updated on: {entry_updated}\n" body_parts = ( self._render_atom_content( @@ -312,6 +314,8 @@ def _parse_rss_type( if title: md_text += f"\n## {title}\n" if pubDate: + if md_text and not md_text.endswith("\n"): + md_text += "\n\n" md_text += f"Published on: {pubDate}\n" body_parts = ( self._parse_content( diff --git a/packages/markitdown/tests/test_rss.py b/packages/markitdown/tests/test_rss.py index 89d2cbb796..dbcccddc2e 100644 --- a/packages/markitdown/tests/test_rss.py +++ b/packages/markitdown/tests/test_rss.py @@ -464,6 +464,71 @@ def test_feed_body_fields_are_separated(extension: str) -> None: assert result.markdown.split("## Entry\n", 1)[1] == "Summary.\n\nBody." +@pytest.mark.parametrize("extension", [".rss", ".atom"]) +@pytest.mark.parametrize( + "title, separator", + [ + ("", "\n\n"), + ("", "\n\n"), + ("<title> \n ", "\n\n"), + ("Second", "\n## Second\n"), + ], + ids=["missing-title", "empty-title", "blank-title", "titled"], +) +@pytest.mark.parametrize("include_dates", [False, True], ids=["undated", "dated"]) +@pytest.mark.parametrize( + "first_body", + ["First body.", "First body.

]]>"], + ids=["inline-body", "paragraph-body"], +) +def test_feed_entry_dates_are_separated_from_previous_body( + extension: str, title: str, separator: str, include_dates: bool, first_body: str +) -> None: + if extension == ".rss": + start, end = '', "" + entry_tag, date_tag, body_tag = "item", "pubDate", "description" + label = "Published on" + first_date, second_date = ( + "Mon, 01 Jan 2024 00:00:00 GMT", + "Tue, 02 Jan 2024 00:00:00 GMT", + ) + else: + start, end = '', "" + entry_tag, date_tag, body_tag = "entry", "updated", 'content type="html"' + label = "Updated on" + first_date, second_date = "2024-01-01T00:00:00Z", "2024-01-02T00:00:00Z" + + body_end_tag = body_tag.split()[0] + dates = [ + f"<{date_tag}>{date}" if include_dates else "" + for date in (first_date, second_date) + ] + feed = ( + f"{start}Feed" + f"<{entry_tag}>First{dates[0]}" + f"<{body_tag}>{first_body}" + f"<{entry_tag}>{title}{dates[1]}" + f"<{body_tag}>Second body.{end}" + ).encode() + expected = ( + "# Feed\n\n## First\n" + + (f"{label}: {first_date}\n" if include_dates else "") + + "First body." + + separator + + (f"{label}: {second_date}\n" if include_dates else "") + + "Second body." + ) + stream_info = StreamInfo(extension=extension) + + direct = RssConverter().convert(io.BytesIO(feed), stream_info) + public = MarkItDown(enable_plugins=False).convert_stream( + io.BytesIO(feed), stream_info=stream_info + ) + + assert direct.markdown == expected + assert public.markdown == expected + + @pytest.mark.parametrize("extension", [".rss", ".atom"]) @pytest.mark.parametrize( "summary, content, expected",