sw/source/filter/md/wrtmd.cxx | 159 ++++++++++++++++++++++-------------------- 1 file changed, 85 insertions(+), 74 deletions(-)
New commits: commit 3c29e1277bda566b4455123a7a53c8f0fc6eda98 Author: Miklos Vajna <[email protected]> AuthorDate: Fri Oct 3 08:58:20 2025 +0200 Commit: Miklos Vajna <[email protected]> CommitDate: Fri Oct 3 17:14:27 2025 +0200 tdf#168662 sw markdown export: extract inline image export functions 1) ApplyItem() knows how to convert a fly frame format of an inline image and store it in an SwMDImageInfo, but this can be extracted to a new ApplyFlyFrameFormat(), to be reused for anchored images later. 2) Similarly, OutFormattingChange() knows how to write an SwMDImageInfo of an inline image with markdown syntax, but this can be extracted to a new OutMarkdown_SwMDImageInfo(), to be reused for anchored images later. No functional changes intended, but this allows to reduce the size of the actual anchored image support patch. Change-Id: I62a90518a0df6561f5957c04ac364d5b1cfce29e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191823 Tested-by: Jenkins Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sw/source/filter/md/wrtmd.cxx b/sw/source/filter/md/wrtmd.cxx index 5ec4008939a2..eedc49433ba4 100644 --- a/sw/source/filter/md/wrtmd.cxx +++ b/sw/source/filter/md/wrtmd.cxx @@ -150,6 +150,58 @@ struct NodePositions } }; +void ApplyFlyFrameFormat(const SwFlyFrameFormat& rFrameFormat, SwMDWriter& rWrt, + FormattingStatus& rChange) +{ + const SwFormatContent& rFlyContent = rFrameFormat.GetContent(); + SwNodeOffset nStart = rFlyContent.GetContentIdx()->GetIndex() + 1; + Graphic aGraphic; + OUString aGraphicURL; + if (rWrt.m_pDoc->GetNodes()[nStart]->GetNodeType() == SwNodeType::Grf) + { + SwGrfNode* pGrfNode = rWrt.m_pDoc->GetNodes()[nStart]->GetGrfNode(); + aGraphic = pGrfNode->GetGraphic(); + if (pGrfNode->IsLinkedFile()) + { + pGrfNode->GetFileFilterNms(&aGraphicURL, /*pFilterNm=*/nullptr); + } + else + { + // Not linked, image data goes into the "URL". + OUString aGraphicInBase64; + if (!XOutBitmap::GraphicToBase64(aGraphic, aGraphicInBase64)) + { + return; + } + + aGraphicURL = "data:" + aGraphicInBase64; + } + } + else + { + SwOLENode* pOLENode = rWrt.m_pDoc->GetNodes()[nStart]->GetOLENode(); + assert(pOLENode->GetGraphic()); + aGraphic = *pOLENode->GetGraphic(); + // TODO fill aGraphicURL with the right info + } + + const OUString& rBaseURL = rWrt.GetBaseURL(); + INetURLObject aGraphicURLObject(aGraphicURL); + if (!rBaseURL.isEmpty() && aGraphicURLObject.GetProtocol() != INetProtocol::Data) + { + aGraphicURL = URIHelper::simpleNormalizedMakeRelative(rBaseURL, aGraphicURL); + } + OUString aTitle = rFrameFormat.GetObjTitle(); + OUString aDescription = rFrameFormat.GetObjDescription(); + OUString aLink; + if (rFrameFormat.GetAttrSet().HasItem(RES_URL)) + { + const SwFormatURL& rLink = rFrameFormat.GetURL(); + aLink = rLink.GetURL(); + } + rChange.aImages.emplace(aGraphicURL, aTitle, aDescription, aLink); +} + void ApplyItem(SwMDWriter& rWrt, FormattingStatus& rChange, const SfxPoolItem& rItem, int increment) { auto IterateItemSet = [&rWrt, &rChange, increment](const SfxItemSet& set) { @@ -219,53 +271,7 @@ void ApplyItem(SwMDWriter& rWrt, FormattingStatus& rChange, const SfxPoolItem& r const SwFormatFlyCnt& rFormatFlyCnt = rItem.StaticWhichCast(RES_TXTATR_FLYCNT); const auto& rFrameFormat = static_cast<const SwFlyFrameFormat&>(*rFormatFlyCnt.GetFrameFormat()); - const SwFormatContent& rFlyContent = rFrameFormat.GetContent(); - SwNodeOffset nStart = rFlyContent.GetContentIdx()->GetIndex() + 1; - Graphic aGraphic; - OUString aGraphicURL; - if (rWrt.m_pDoc->GetNodes()[nStart]->GetNodeType() == SwNodeType::Grf) - { - SwGrfNode* pGrfNode = rWrt.m_pDoc->GetNodes()[nStart]->GetGrfNode(); - aGraphic = pGrfNode->GetGraphic(); - if (pGrfNode->IsLinkedFile()) - { - pGrfNode->GetFileFilterNms(&aGraphicURL, /*pFilterNm=*/nullptr); - } - else - { - // Not linked, image data goes into the "URL". - OUString aGraphicInBase64; - if (!XOutBitmap::GraphicToBase64(aGraphic, aGraphicInBase64)) - { - break; - } - - aGraphicURL = "data:" + aGraphicInBase64; - } - } - else - { - SwOLENode* pOLENode = rWrt.m_pDoc->GetNodes()[nStart]->GetOLENode(); - assert(pOLENode->GetGraphic()); - aGraphic = *pOLENode->GetGraphic(); - // TODO fill aGraphicURL with the right info - } - - const OUString& rBaseURL = rWrt.GetBaseURL(); - INetURLObject aGraphicURLObject(aGraphicURL); - if (!rBaseURL.isEmpty() && aGraphicURLObject.GetProtocol() != INetProtocol::Data) - { - aGraphicURL = URIHelper::simpleNormalizedMakeRelative(rBaseURL, aGraphicURL); - } - OUString aTitle = rFrameFormat.GetObjTitle(); - OUString aDescription = rFrameFormat.GetObjDescription(); - OUString aLink; - if (rFrameFormat.GetAttrSet().HasItem(RES_URL)) - { - const SwFormatURL& rLink = rFrameFormat.GetURL(); - aLink = rLink.GetURL(); - } - rChange.aImages.emplace(aGraphicURL, aTitle, aDescription, aLink); + ApplyFlyFrameFormat(rFrameFormat, rWrt, rChange); break; } case RES_TXTATR_CONTENTCONTROL: @@ -329,6 +335,37 @@ bool ShouldOpenIt(int prev, int curr) { return prev != curr && prev <= 0 && curr void OutEscapedChars(SwMDWriter& rWrt, std::u16string_view chars); +void OutMarkdown_SwMDImageInfo(const SwMDImageInfo& rImageInfo, SwMDWriter& rWrt) +{ + if (!rImageInfo.aLink.isEmpty()) + { + // Start image link. + rWrt.Strm().WriteUnicodeOrByteText(u"["); + } + + rWrt.Strm().WriteUnicodeOrByteText(u"; + rWrt.Strm().WriteUnicodeOrByteText(rImageInfo.aURL); + + if (!rImageInfo.aTitle.isEmpty()) + { + rWrt.Strm().WriteUnicodeOrByteText(u" \""); + OutEscapedChars(rWrt, rImageInfo.aTitle); + rWrt.Strm().WriteUnicodeOrByteText(u"\""); + } + + rWrt.Strm().WriteUnicodeOrByteText(u")"); + + if (!rImageInfo.aLink.isEmpty()) + { + // End image link. + rWrt.Strm().WriteUnicodeOrByteText(u"]("); + rWrt.Strm().WriteUnicodeOrByteText(rImageInfo.aLink); + rWrt.Strm().WriteUnicodeOrByteText(u")"); + } +} + // Calculate the updated status of properties. Then compare the status before and after; and for // each event when a value changes from 0 to a positive number, output respective opening markup; // when a value is decreased to 0, a closing markup is written. For redlines, closing markup is @@ -476,33 +513,7 @@ void OutFormattingChange(SwMDWriter& rWrt, NodePositions& positions, sal_Int32 p continue; } - if (!rImageInfo.aLink.isEmpty()) - { - // Start image link. - rWrt.Strm().WriteUnicodeOrByteText(u"["); - } - - rWrt.Strm().WriteUnicodeOrByteText(u"; - rWrt.Strm().WriteUnicodeOrByteText(rImageInfo.aURL); - - if (!rImageInfo.aTitle.isEmpty()) - { - rWrt.Strm().WriteUnicodeOrByteText(u" \""); - OutEscapedChars(rWrt, rImageInfo.aTitle); - rWrt.Strm().WriteUnicodeOrByteText(u"\""); - } - - rWrt.Strm().WriteUnicodeOrByteText(u")"); - - if (!rImageInfo.aLink.isEmpty()) - { - // End image link. - rWrt.Strm().WriteUnicodeOrByteText(u"]("); - rWrt.Strm().WriteUnicodeOrByteText(rImageInfo.aLink); - rWrt.Strm().WriteUnicodeOrByteText(u")"); - } + OutMarkdown_SwMDImageInfo(rImageInfo, rWrt); } current = std::move(result);
