fix: preserve pre-fence text and post-fence content in rendered blocks

When a fence () closes inside a block, prepend any content
that came before the fence to renderedHtml so both text and the
highlighted fence show up. When content is appended after the fence,
keep renderedHtml in sync by appending the escaped text. This prevents
the fence from 'eating' surrounding content.
This commit is contained in:
Levi Neely 2026-08-02 11:13:22 +02:00
parent 67b33f95d2
commit 753467db5b
1 changed files with 15 additions and 2 deletions

View File

@ -224,8 +224,15 @@ void ChatBlockModel::appendContent(const QString &line)
if (!last.content.isEmpty())
last.content += '\n';
last.content += line;
// Keep renderedHtml in sync if a fence was rendered earlier
// in this block, so post-fence content isn't invisible.
if (!last.renderedHtml.isEmpty()) {
if (!last.renderedHtml.endsWith('\n'))
last.renderedHtml += '\n';
last.renderedHtml += line.toHtmlEscaped();
}
QModelIndex idx = index(m_blocks.size() - 1);
emit dataChanged(idx, idx, {ContentRole});
emit dataChanged(idx, idx, {ContentRole, RenderedHtmlRole});
}
void ChatBlockModel::processLine(const QString &line)
@ -248,7 +255,13 @@ void ChatBlockModel::processLine(const QString &line)
if (!m_blocks.isEmpty()) {
ChatBlock &last = m_blocks.last();
last.renderedHtml = rendered;
// Prepend any content that came before the fence so it
// isn't lost — the view uses renderedHtml exclusively
// when non-empty.
if (!last.content.isEmpty())
last.renderedHtml = escapeHtml(last.content) + '\n' + rendered;
else
last.renderedHtml = rendered;
QModelIndex idx = index(m_blocks.size() - 1);
emit dataChanged(idx, idx, {RenderedHtmlRole});
}