sw/qa/filter/md/data/quote.md | 5 ++++ sw/qa/filter/md/md.cxx | 51 ++++++++++++++++++++++++++++++++++++++++++ sw/source/filter/md/swmd.cxx | 7 +---- sw/source/filter/md/wrtmd.cxx | 7 +++++ 4 files changed, 65 insertions(+), 5 deletions(-)
New commits: commit f8b289b91e4f53f28e6de46f509668da6138e6cf Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Mon Sep 8 08:43:23 2025 +0200 Commit: Caolán McNamara <caolan.mcnam...@collabora.com> CommitDate: Mon Sep 8 09:30:23 2025 +0200 sw markdown export: handle block quote <https://spec.commonmark.org/0.31.2/#example-228> says the quote block markup should be written first, then the heading, so do it in that order. Also fix the import side: set the paragraph style in SwMarkdownParser::AddBlockQuote(), similar to how HtmlTokenId::BLOCKQUOTE_ON is handled in SwHTMLParser::NextToken(), so the export side has an easier time with recognizing this is a block quote. Change-Id: I305c7a31832cba44cb66943a5fc45a966ad62d55 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190654 Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sw/qa/filter/md/data/quote.md b/sw/qa/filter/md/data/quote.md new file mode 100644 index 000000000000..9d3f8dd0fada --- /dev/null +++ b/sw/qa/filter/md/data/quote.md @@ -0,0 +1,5 @@ +before + +> quote + +after diff --git a/sw/qa/filter/md/md.cxx b/sw/qa/filter/md/md.cxx index f4a48930623a..f1a47d89e9a9 100644 --- a/sw/qa/filter/md/md.cxx +++ b/sw/qa/filter/md/md.cxx @@ -24,6 +24,7 @@ #include <fmtcntnt.hxx> #include <ndgrf.hxx> #include <itabenum.hxx> +#include <ndtxt.hxx> namespace { @@ -367,6 +368,56 @@ CPPUNIT_TEST_FIXTURE(Test, testExportingTable) CPPUNIT_ASSERT_EQUAL(aExpected, aActual); } +CPPUNIT_TEST_FIXTURE(Test, testBlockQuoteMdImport) +{ + // Given a document with a "block quote" 2nd paragraph: + // When importing that document: + setImportFilterName("Markdown"); + createSwDoc("quote.md"); + + // Then make sure that the paragraph style is set correctly: + SwDocShell* pDocShell = getSwDocShell(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + pWrtShell->Down(/*bSelect=*/false); + SwCursor* pCursor = pWrtShell->GetCursor(); + SwTextNode* pTextNode = pCursor->GetPointNode().GetTextNode(); + SwFormatColl* pActual = pTextNode->GetFormatColl(); + SwDoc* pDoc = pDocShell->GetDoc(); + IDocumentStylePoolAccess& rIDSPA = pDoc->getIDocumentStylePoolAccess(); + SwFormatColl* pExpected = rIDSPA.GetTextCollFromPool(RES_POOLCOLL_HTML_BLOCKQUOTE); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: Block Quotation + // - Actual : Body Text + // i.e. the paragraph style was not set. + CPPUNIT_ASSERT_EQUAL(pExpected->GetName(), pActual->GetName()); +} + +CPPUNIT_TEST_FIXTURE(Test, testBlockQuoteMdExport) +{ + // Given a document where the only paragraph is a block quote: + createSwDoc(); + SwDocShell* pDocShell = getSwDocShell(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + SwCursor* pCursor = pWrtShell->GetCursor(); + SwDoc* pDoc = pDocShell->GetDoc(); + IDocumentStylePoolAccess& rIDSPA = pDoc->getIDocumentStylePoolAccess(); + SwTextFormatColl* pColl = rIDSPA.GetTextCollFromPool(RES_POOLCOLL_HTML_BLOCKQUOTE); + pDoc->SetTextFormatColl(*pCursor, pColl); + pWrtShell->Insert(u"test"_ustr); + + // When saving that to markdown: + save(mpFilter); + + // Then make sure the format of the paragraph is exported: + std::string aActual = TempFileToString(); + std::string aExpected("> test" SAL_NEWLINE_STRING); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: > test + // - Actual : test + // i.e. the block quote markup was missing. + CPPUNIT_ASSERT_EQUAL(aExpected, aActual); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/filter/md/swmd.cxx b/sw/source/filter/md/swmd.cxx index 81e893839050..8218a4047632 100644 --- a/sw/source/filter/md/swmd.cxx +++ b/sw/source/filter/md/swmd.cxx @@ -208,11 +208,8 @@ void SwMarkdownParser::AddBlockQuote() m_nBlockQuoteDepth++; - sal_Int32 nBaseLeftIndent = pColl->GetTextLeftMargin().ResolveTextLeft({}); - sal_Int32 nLeftIndent = nBaseLeftIndent + m_nBlockQuoteDepth * nBaseLeftIndent; - SvxTextLeftMarginItem aLeftMargin(pColl->GetTextLeftMargin()); - aLeftMargin.SetTextLeft(SvxIndentValue::twips(nLeftIndent)); - m_xDoc->getIDocumentContentOperations().InsertPoolItem(*m_pPam, aLeftMargin); + // Set the style on the current paragraph. + m_xDoc->SetTextFormatColl(*m_pPam, pColl); } void SwMarkdownParser::EndBlockQuote() diff --git a/sw/source/filter/md/wrtmd.cxx b/sw/source/filter/md/wrtmd.cxx index d162771f02b9..c4f9ed0ac18b 100644 --- a/sw/source/filter/md/wrtmd.cxx +++ b/sw/source/filter/md/wrtmd.cxx @@ -456,6 +456,13 @@ void OutMarkdown_SwTextNode(SwMDWriter& rWrt, const SwTextNode& rNode, bool bFir if (!bFirst && !oCellInfo) rWrt.Strm().WriteUnicodeOrByteText(u"" SAL_NEWLINE_STRING); + const SwFormatColl* pFormatColl = rNode.GetFormatColl(); + if (pFormatColl->GetPoolFormatId() == RES_POOLCOLL_HTML_BLOCKQUOTE) + { + // <https://spec.commonmark.org/0.31.2/#block-quotes> first block quote, then heading. + rWrt.Strm().WriteUnicodeOrByteText(u"> "); + } + int nHeadingLevel = 0; for (const SwFormat* pFormat = &rNode.GetAnyFormatColl(); pFormat; pFormat = pFormat->DerivedFrom())