From 699b8a5329e6c19a2fc85c859009e746e95e2067 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 6 Jul 2026 23:12:21 +0200 Subject: [PATCH] Fix consecutive
collapsing into a single line break RichTextRenderer's Inline.LineBreak case called startParagraph(0), which only emits model.nl() when the current paragraph is "occupied". A single
correctly closes the preceding text into its own paragraph, but a second consecutive
(e.g. citation styles using

for a blank line) found the paragraph already unoccupied and silently produced nothing, collapsing the blank line. Mark the paragraph occupied after emitting the break, mirroring the existing empty-line handling for preserved "\n\n" in appendRun. --- .../org/jabref/htmltonode/rich/RichTextRenderer.java | 10 ++++++++-- .../org/jabref/htmltonode/RichTextRendererTest.java | 10 ++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jabref/htmltonode/rich/RichTextRenderer.java b/src/main/java/org/jabref/htmltonode/rich/RichTextRenderer.java index 7714254..08cb91b 100644 --- a/src/main/java/org/jabref/htmltonode/rich/RichTextRenderer.java +++ b/src/main/java/org/jabref/htmltonode/rich/RichTextRenderer.java @@ -166,8 +166,14 @@ private void paragraph(List inlines, double scale, int minWeight, double } appendRun(text, effective); } - case Inline.LineBreak ignored -> - startParagraph(0); + case Inline.LineBreak ignored -> { + // A break renders as a blank line even with no content of its own, so a second + // consecutive break (e.g. `

`) still triggers a fresh model.nl() in the next + // startParagraph() call instead of being swallowed by separateParagraph()'s + // occupied-check (mirrors the empty-line handling for preserved "\n\n" in appendRun). + startParagraph(0); + paragraphOccupied = true; + } case Inline.Image image -> { if (RenderSupport.createImageView(image, options, baseSize) != null) { model.addNodeSegment(() -> RenderSupport.createImageView(image, options, baseSize)); diff --git a/src/test/java/org/jabref/htmltonode/RichTextRendererTest.java b/src/test/java/org/jabref/htmltonode/RichTextRendererTest.java index 8f31bc7..8cc70a9 100644 --- a/src/test/java/org/jabref/htmltonode/RichTextRendererTest.java +++ b/src/test/java/org/jabref/htmltonode/RichTextRendererTest.java @@ -81,6 +81,16 @@ void lineBreaksSplitParagraphs() { assertEquals("b", model.getPlainText(1)); } + @Test + void consecutiveLineBreaksKeepTheBlankLineBetweenThem() { + StyledTextModel model = model("a

b"); + + assertEquals(3, model.size()); + assertEquals("a", model.getPlainText(0)); + assertEquals("", model.getPlainText(1)); + assertEquals("b", model.getPlainText(2)); + } + @Test void preservedNewlinesInPreSplitParagraphs() { StyledTextModel model = model("
x = 1\ny = 2
");