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.
This commit is contained in:
Daniel Kessler
2023-01-29 16:40:32 -08:00
committed by John MacFarlane
parent 5d3b61a048
commit 9dbb75dacb
5 changed files with 29 additions and 19 deletions
+16 -10
View File
@@ -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
+8 -8
View File
@@ -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
----
+2 -1
View File
@@ -146,7 +146,8 @@ testMediaBag name odtFile = buildTest $ testMediaBagIO name odtFile
namesOfTestsComparingToMarkdown :: [ String ]
namesOfTestsComparingToMarkdown = [ "bold"
namesOfTestsComparingToMarkdown = [ "blockquote2"
, "bold"
-- , "citation"
, "endnote"
, "externalLink"
+3
View File
@@ -0,0 +1,3 @@
Paragraph
> A blockquote.
Binary file not shown.