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"),
+ (" \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}{date_tag}>" 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}{body_end_tag}>{entry_tag}>"
+ f"<{entry_tag}>{title}{dates[1]}"
+ f"<{body_tag}>Second body.{body_end_tag}>{entry_tag}>{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",