aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kessler <[email protected]>2023-01-29 13:38:54 -0800
committerJohn MacFarlane <[email protected]>2023-01-29 16:40:32 -0800
commit9dbb75dacb26e8482f62fcfaeb7a48ff7b1d7f0e (patch)
tree636fe0d8a8bfae81716a165b9878126c10a42205
parent5d3b61a048bf0101e780bf61faabeea21ef93f90 (diff)
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.
-rw-r--r--src/Text/Pandoc/Readers/ODT/ContentReader.hs26
-rw-r--r--src/Text/Pandoc/Readers/ODT/StyleReader.hs16
-rw-r--r--test/Tests/Readers/ODT.hs3
-rw-r--r--test/odt/markdown/blockquote2.md3
-rw-r--r--test/odt/odt/blockquote2.odtbin0 -> 9024 bytes
5 files changed, 29 insertions, 19 deletions
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
----
diff --git a/test/Tests/Readers/ODT.hs b/test/Tests/Readers/ODT.hs
index 54b9818ec..b48dbe9a3 100644
--- a/test/Tests/Readers/ODT.hs
+++ b/test/Tests/Readers/ODT.hs
@@ -146,7 +146,8 @@ testMediaBag name odtFile = buildTest $ testMediaBagIO name odtFile
namesOfTestsComparingToMarkdown :: [ String ]
-namesOfTestsComparingToMarkdown = [ "bold"
+namesOfTestsComparingToMarkdown = [ "blockquote2"
+ , "bold"
-- , "citation"
, "endnote"
, "externalLink"
diff --git a/test/odt/markdown/blockquote2.md b/test/odt/markdown/blockquote2.md
new file mode 100644
index 000000000..0e666aa98
--- /dev/null
+++ b/test/odt/markdown/blockquote2.md
@@ -0,0 +1,3 @@
+Paragraph
+
+> A blockquote.
diff --git a/test/odt/odt/blockquote2.odt b/test/odt/odt/blockquote2.odt
new file mode 100644
index 000000000..b6c922d89
--- /dev/null
+++ b/test/odt/odt/blockquote2.odt
Binary files differ