From 9dbb75dacb26e8482f62fcfaeb7a48ff7b1d7f0e Mon Sep 17 00:00:00 2001 From: Daniel Kessler Date: Sun, 29 Jan 2023 13:38:54 -0800 Subject: ODT reader: fix blockquote indent detection The ODT reader is supposed to detect blockquotes by checking a paragraph style's indentation level. But it's broken for two reasons: * The parser fails on non-integers. So "1in" will get read as 25mm, but "1.0in" fails. By default, the Quotations style is "0.3937in". * The reader doesn't check indentation levels of parent styles. In my test documents, LibreOffice often creates child styles for individual paragraphs, so it's important to check parents (ODT files created by the Pandoc ODT writer don't have this issue though). I added a new test "blockquote2" whose ODT file is generated directly from the corresponding Markdown file with pandoc. Fixes #3437. --- src/Text/Pandoc/Readers/ODT/ContentReader.hs | 26 ++++++++++++++++---------- src/Text/Pandoc/Readers/ODT/StyleReader.hs | 16 ++++++++-------- 2 files changed, 24 insertions(+), 18 deletions(-) (limited to 'src/Text') diff --git a/src/Text/Pandoc/Readers/ODT/ContentReader.hs b/src/Text/Pandoc/Readers/ODT/ContentReader.hs index 97f51d5fa..a1c3e9cf2 100644 --- a/src/Text/Pandoc/Readers/ODT/ContentReader.hs +++ b/src/Text/Pandoc/Readers/ODT/ContentReader.hs @@ -370,16 +370,21 @@ _MINIMUM_INDENTATION_FOR_BLOCKQUOTES_IN_PERCENT_ :: Int _MINIMUM_INDENTATION_FOR_BLOCKQUOTES_IN_MM_ = 5 _MINIMUM_INDENTATION_FOR_BLOCKQUOTES_IN_PERCENT_ = 5 --- | Returns either 'id' or 'blockQuote' depending on the current indentation -getParaModifier :: Style -> ParaModifier -getParaModifier Style{..} | Just props <- paraProperties styleProperties - , isBlockQuote (indentation props) - (margin_left props) - = blockQuote - | otherwise - = id +-- | Returns either 'id' or 'blockQuote' depending if any of the StyleProperties +-- are indented at quote level. +getParaModifier :: [StyleProperties] -> ParaModifier +getParaModifier props | any isBlockQuote props + = blockQuote + | otherwise + = id where - isBlockQuote mIndent mMargin + isBlockQuote SProps {..} | Just paraProps <- paraProperties + , isQuoteWidth (indentation paraProps) + (margin_left paraProps) + = True + | otherwise + = False + isQuoteWidth mIndent mMargin | LengthValueMM indent <- mIndent , indent > _MINIMUM_INDENTATION_FOR_BLOCKQUOTES_IN_MM_ = True @@ -413,7 +418,8 @@ constructPara reader = proc blocks -> do blocks' <- reader -< blocks arr tableCaptionP -< blocks' Right (_, style) -> do - let modifier = getParaModifier style + props <- fromStyles extendedStylePropertyChain -< [style] + let modifier = getParaModifier props blocks' <- reader -< blocks arr modifier -<< blocks' where diff --git a/src/Text/Pandoc/Readers/ODT/StyleReader.hs b/src/Text/Pandoc/Readers/ODT/StyleReader.hs index dadd37dcc..474303bd6 100644 --- a/src/Text/Pandoc/Readers/ODT/StyleReader.hs +++ b/src/Text/Pandoc/Readers/ODT/StyleReader.hs @@ -330,14 +330,14 @@ instance Read XslUnit where -- so I could not really easily calculate anything exact here even if I wanted. -- But I do not care about exactness right now, as I only use measures -- to determine if a paragraph is "indented" or not. -estimateInMillimeter :: Int -> XslUnit -> Int -estimateInMillimeter n XslUnitMM = n -estimateInMillimeter n XslUnitCM = n * 10 -estimateInMillimeter n XslUnitInch = n * 25 -- \* 25.4 -estimateInMillimeter n XslUnitPoints = n `div` 3 -- \* 1/72 * 25.4 -estimateInMillimeter n XslUnitPica = n * 4 -- \* 12 * 1/72 * 25.4 -estimateInMillimeter n XslUnitPixel = n `div`3 -- \* 1/72 * 25.4 -estimateInMillimeter n XslUnitEM = n * 7 -- \* 16 * 1/72 * 25.4 +estimateInMillimeter :: Double -> XslUnit -> Int +estimateInMillimeter n XslUnitMM = round n +estimateInMillimeter n XslUnitCM = round $ n * 10 +estimateInMillimeter n XslUnitInch = round $ n * 25.4 +estimateInMillimeter n XslUnitPoints = round $ n * (1/72) * 25.4 +estimateInMillimeter n XslUnitPica = round $ n * 12 * (1/72) * 25.4 +estimateInMillimeter n XslUnitPixel = round $ n * (1/72) * 25.4 +estimateInMillimeter n XslUnitEM = round $ n * 16 * (1/72) * 25.4 ---- -- cgit v1.2.3