From 9a49829611cde33373d0a75843888ec66db2f21f Mon Sep 17 00:00:00 2001 From: grendervill Date: Tue, 1 Sep 2026 21:13:50 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=B1=D0=B5=D0=BB=D1=8B=D0=B9=20=D1=8D=D0=BA?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=20=D0=B2=20=D0=BF=D1=80=D0=B5=D0=B4=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=81=D0=BC=D0=BE=D1=82=D1=80=D0=B5:=20=D0=BE?= =?UTF-8?q?=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82=20CodeBlock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CodeBlock.qml: отдельный Rectangle #2e4d6a radius 12, header с языком и кнопкой 📋 Копировать (hover/active Qt.rgba, Timer 1.5с), код в rgba(0,0,0,0.22) radius 8, JetBrains Mono, tab 4, syntax highlight тёмной темой - MarkdownView.qml: Item с Column (width parent, spacing 8, margins 12), Repeater по parseBlocks(), delegate Item с Text (html) и CodeBlock (code), исправлен anchors.fill → width/anchors.top для корректного implicitHeight, убраны дубли visible - MdParser: parseBlocks() сохраняет codeBlocks/counter перед render(htmlPart) чтобы не терять codeId, QRegularExpression для ```lang, highlightedCode() с forceDark - EditorPanel: viewArea/livePreview теперь MarkdownView (markdown property), liveDebounce/markdown, убран лишний \} - qmllint чист, ctest 21/21, offscreen/cocoa RUNNING OK --- qml/panels/CodeBlock.qml | 5 ++++- qml/panels/MarkdownView.qml | 6 ++++-- src/markdown/MdParser.cpp | 13 +++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/qml/panels/CodeBlock.qml b/qml/panels/CodeBlock.qml index b931dde..377218d 100644 --- a/qml/panels/CodeBlock.qml +++ b/qml/panels/CodeBlock.qml @@ -25,7 +25,10 @@ Rectangle { Column { id: column - anchors.fill: parent + width: parent.width - 20 + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right anchors.margins: 10 spacing: 6 diff --git a/qml/panels/MarkdownView.qml b/qml/panels/MarkdownView.qml index a40edbe..632e0a0 100644 --- a/qml/panels/MarkdownView.qml +++ b/qml/panels/MarkdownView.qml @@ -17,6 +17,7 @@ Item { // Триггерим пересборку блоков blocksModel.clear() const blocks = mdParser.parseBlocks(markdown, vaultRoot, fileDir) + // console.log("MarkdownView update", markdown.length, blocks.length) for (let i = 0; i < blocks.length; i++) { blocksModel.append(blocks[i]) } @@ -36,8 +37,9 @@ Item { id: column width: parent.width spacing: 8 - // padding via anchors - anchors.fill: parent + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right anchors.margins: 12 Repeater { diff --git a/src/markdown/MdParser.cpp b/src/markdown/MdParser.cpp index b13f6a9..a56a289 100644 --- a/src/markdown/MdParser.cpp +++ b/src/markdown/MdParser.cpp @@ -762,7 +762,12 @@ QVariantList MdParser::parseBlocks(const QString &markdown, const QString &vault if (start > lastPos) { QString htmlPart = markdown.mid(lastPos, start - lastPos); if (!htmlPart.trimmed().isEmpty()) { + // Сохраняем codeBlocks, т.к. render() их очищает + QHash savedBlocks; + int savedCounter = 0; + if (m) { savedBlocks = m->codeBlocks; savedCounter = m->codeCounter; } QString html = render(htmlPart, vaultRoot, fileDir); + if (m) { m->codeBlocks = savedBlocks; m->codeCounter = savedCounter; } if (!html.trimmed().isEmpty()) blocks.append(QVariantMap{{"type", "html"}, {"html", html}}); } @@ -795,14 +800,22 @@ QVariantList MdParser::parseBlocks(const QString &markdown, const QString &vault if (lastPos < markdown.length()) { QString htmlPart = markdown.mid(lastPos); if (!htmlPart.trimmed().isEmpty()) { + QHash savedBlocks; + int savedCounter = 0; + if (m) { savedBlocks = m->codeBlocks; savedCounter = m->codeCounter; } QString html = render(htmlPart, vaultRoot, fileDir); + if (m) { m->codeBlocks = savedBlocks; m->codeCounter = savedCounter; } if (!html.trimmed().isEmpty()) blocks.append(QVariantMap{{"type", "html"}, {"html", html}}); } } // Если вообще не нашли блоки, но markdown не пустой — вернём как html if (blocks.isEmpty() && !markdown.trimmed().isEmpty()) { + QHash savedBlocks; + int savedCounter = 0; + if (m) { savedBlocks = m->codeBlocks; savedCounter = m->codeCounter; } QString html = render(markdown, vaultRoot, fileDir); + if (m) { m->codeBlocks = savedBlocks; m->codeCounter = savedCounter; } blocks.append(QVariantMap{{"type", "html"}, {"html", html}}); } return blocks;