sw/source/filter/md/wrtmd.cxx | 160 ++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 74 deletions(-)
New commits: commit ee0fe0e1b8b5202e0443cc5dfc3249110ffee86d Author: Miklos Vajna <[email protected]> AuthorDate: Fri Oct 3 08:58:20 2025 +0200 Commit: Caolán McNamara <[email protected]> CommitDate: Fri Oct 3 15:20:34 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/+/191810 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> diff --git a/sw/source/filter/md/wrtmd.cxx b/sw/source/filter/md/wrtmd.cxx index 5707a1e0db0d..235116150fe5 100644 --- a/sw/source/filter/md/wrtmd.cxx +++ b/sw/source/filter/md/wrtmd.cxx @@ -144,6 +144,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) { @@ -213,53 +265,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,38 @@ bool ShouldCloseIt(int prev, int curr) { return prev != curr && prev >= 0 && cur bool ShouldOpenIt(int prev, int curr) { return prev != curr && prev <= 0 && curr > 0; } 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")"); + } +} + void OutFormattingChange(SwMDWriter& rWrt, NodePositions& positions, sal_Int32 pos, FormattingStatus& current) { @@ -495,33 +533,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 = result;
