From 84e39ff36f9a52c55e18a6ec9321b4feb997b3c4 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 15 Feb 2026 01:59:26 +0100 Subject: [PATCH] Odt reader: Support Preformatted Text from pandoc writer pandoc generates a separate style class like P123 for each paragraph, inheriting the desired style using `parent-style-name`. Previously, we did not support that but it is pretty easy to add. Though for simplicity this fix does not extend to finding the parent style recursively when deeper hierarchies are involved. --- src/Text/Pandoc/Readers/ODT/ContentReader.hs | 7 ++++--- test/Tests/Readers/ODT.hs | 1 + .../native/preformattedTextParentStyle.native | 4 ++++ test/odt/odt/preformattedTextParentStyle.odt | Bin 0 -> 7150 bytes 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 test/odt/native/preformattedTextParentStyle.native create mode 100644 test/odt/odt/preformattedTextParentStyle.odt diff --git a/src/Text/Pandoc/Readers/ODT/ContentReader.hs b/src/Text/Pandoc/Readers/ODT/ContentReader.hs index 9efaa1906..2e192f3e3 100644 --- a/src/Text/Pandoc/Readers/ODT/ContentReader.hs +++ b/src/Text/Pandoc/Readers/ODT/ContentReader.hs @@ -656,13 +656,14 @@ read_paragraph = matchingElement NsText "p" $ liftA CombiningBlocks $ proc blocks -> do fStyle <- readStyleByName -< blocks case fStyle of - Right (styleName, _) | isPreformattedStyle styleName -> do + Right style | isPreformattedStyle style -> do liftA (codeBlock . stringify) $ matchParagraphContent -< blocks _ -> constructPara $ liftA para $ withNewStyle matchParagraphContent -< blocks where - isPreformattedStyle :: StyleName -> Bool - isPreformattedStyle "Preformatted_20_Text" = True + isPreformattedStyle :: (StyleName, Style) -> Bool + isPreformattedStyle ("Preformatted_20_Text", _) = True + isPreformattedStyle (_, Style { styleParentName = Just "Preformatted_20_Text" }) = True isPreformattedStyle _ = False diff --git a/test/Tests/Readers/ODT.hs b/test/Tests/Readers/ODT.hs index fe59f73cf..0e39839aa 100644 --- a/test/Tests/Readers/ODT.hs +++ b/test/Tests/Readers/ODT.hs @@ -177,6 +177,7 @@ namesOfTestsComparingToNative = [ "blockquote" , "orderedListSimple" , "orderedListHeader" , "preformattedText" + , "preformattedTextParentStyle" , "referenceToChapter" , "referenceToListItem" , "referenceToText" diff --git a/test/odt/native/preformattedTextParentStyle.native b/test/odt/native/preformattedTextParentStyle.native new file mode 100644 index 000000000..99c54b4a6 --- /dev/null +++ b/test/odt/native/preformattedTextParentStyle.native @@ -0,0 +1,4 @@ +[ CodeBlock + ( "" , [] , [] ) + "void main() {\n printf(\"Hello world\");\n}" +] diff --git a/test/odt/odt/preformattedTextParentStyle.odt b/test/odt/odt/preformattedTextParentStyle.odt new file mode 100644 index 0000000000000000000000000000000000000000..48ebff5e7e98b984e1ad77d630e4c64bed3ecc8c GIT binary patch literal 7150 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 OzC8Lb@%WPbvHk<{0xP)y literal 0 HcmV?d00001