summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephan Meijer <me@stephanmeijer.com>2023-11-07 04:15:37 +0100
committerGitHub <noreply@github.com>2023-11-06 19:15:37 -0800
commit56f7f114732b32870093ea1cd9bf7b8d5b1f2260 (patch)
tree7bf21e1056cdbe885000be066b36b8112b7cefa2 /src
parent76cd115d3bccc77df527b048ae7cad111e477d3d (diff)
ODT reader: Support attr `text:continue-numbering` (#8998)
Closes #8979.
Diffstat (limited to 'src')
-rw-r--r--src/Text/Pandoc/Readers/ODT/ContentReader.hs94
1 files changed, 66 insertions, 28 deletions
diff --git a/src/Text/Pandoc/Readers/ODT/ContentReader.hs b/src/Text/Pandoc/Readers/ODT/ContentReader.hs
index 7b8723dd0..863bd7ca9 100644
--- a/src/Text/Pandoc/Readers/ODT/ContentReader.hs
+++ b/src/Text/Pandoc/Readers/ODT/ContentReader.hs
@@ -75,6 +75,12 @@ data ReaderState
, styleTrace :: [Style]
-- | Keeps track of the current depth in nested lists
, currentListLevel :: ListLevel
+ -- | Keeps track of the previous list start counters,
+ -- so whenever a new list continues numbering,
+ -- we know what number to start from.
+ -- If list does not continue numbering, the counter
+ -- is being reset.
+ , listContinuationStartCounters :: M.Map ListLevel Int
-- | Lists may provide their own style, but they don't have
-- to. If they do not, the style of a parent list may be used
-- or even a default list style from the paragraph style.
@@ -92,7 +98,7 @@ data ReaderState
deriving ( Show )
readerState :: Styles -> Media -> ReaderState
-readerState styles media = ReaderState styles [] 0 Nothing M.empty media mempty
+readerState styles media = ReaderState styles [] 0 M.empty Nothing M.empty media mempty
--
pushStyle' :: Style -> ReaderState -> ReaderState
@@ -103,12 +109,16 @@ popStyle' :: ReaderState -> ReaderState
popStyle' state = case styleTrace state of
_:trace -> state { styleTrace = trace }
_ -> state
-
--
modifyListLevel :: (ListLevel -> ListLevel) -> (ReaderState -> ReaderState)
modifyListLevel f state = state { currentListLevel = f (currentListLevel state) }
--
+modifyListContinuationStartCounter :: ListLevel -> Int -> (ReaderState -> ReaderState)
+modifyListContinuationStartCounter listLevel count state =
+ state { listContinuationStartCounters = M.insert listLevel count (listContinuationStartCounters state) }
+
+--
shiftListLevel :: ListLevel -> (ReaderState -> ReaderState)
shiftListLevel diff = modifyListLevel (+ diff)
@@ -199,6 +209,17 @@ getCurrentListLevel :: ODTReaderSafe _x ListLevel
getCurrentListLevel = getExtraState >>^ currentListLevel
--
+getListContinuationStartCounters :: ODTReaderSafe _x (M.Map ListLevel Int)
+getListContinuationStartCounters = getExtraState >>^ listContinuationStartCounters
+
+
+--
+getPreviousListStartCounter :: ODTReaderSafe ListLevel Int
+getPreviousListStartCounter = proc listLevel -> do
+ counts <- getListContinuationStartCounters -< ()
+ returnA -< M.findWithDefault 0 listLevel counts
+
+--
updateMediaWithResource :: ODTReaderSafe (FilePath, B.ByteString) (FilePath, B.ByteString)
updateMediaWithResource = keepingTheValue (
(keepingTheValue getExtraState
@@ -430,15 +451,15 @@ constructPara reader = proc blocks -> do
type ListConstructor = [Blocks] -> Blocks
-getListConstructor :: ListLevelStyle -> ListConstructor
-getListConstructor ListLevelStyle{..} =
+getListConstructor :: ListLevelStyle -> Int -> ListConstructor
+getListConstructor ListLevelStyle{..} startNum =
case listLevelType of
LltBullet -> bulletList
LltImage -> bulletList
LltNumbered -> let listNumberStyle = toListNumberStyle listItemFormat
listNumberDelim = toListNumberDelim listItemPrefix
listItemSuffix
- in orderedListWith (listItemStart, listNumberStyle, listNumberDelim)
+ in orderedListWith (startNum, listNumberStyle, listNumberDelim)
where
toListNumberStyle LinfNone = DefaultStyle
toListNumberStyle LinfNumber = Decimal
@@ -455,7 +476,6 @@ getListConstructor ListLevelStyle{..} =
toListNumberDelim (Just "(") (Just ")") = TwoParens
toListNumberDelim _ _ = DefaultDelim
-
-- | Determines which style to use for a list, which level to use of that
-- style, and which type of list to create as a result of this information.
-- Then prepares the state for eventual child lists and constructs the list from
@@ -467,42 +487,62 @@ getListConstructor ListLevelStyle{..} =
-- If anything goes wrong, a default ordered-list-constructor is used.
constructList :: ODTReaderSafe x [Blocks] -> ODTReaderSafe x Blocks
constructList reader = proc x -> do
- modifyExtraState (shiftListLevel 1) -< ()
- listLevel <- getCurrentListLevel -< ()
- fStyleName <- findAttr NsText "style-name" -< ()
+ modifyExtraState (shiftListLevel 1) -< ()
+ listLevel <- getCurrentListLevel -< ()
+ listContinuationStartCounter <- getPreviousListStartCounter -< listLevel
+ fStyleName <- findAttr NsText "style-name" -< ()
+ fContNumbering <- findAttr NsText "continue-numbering" -< ()
+ listItemCount <- reader >>^ length -< x
+
+ let continueNumbering = case fContNumbering of
+ Right "true" -> True
+ _ -> False
+
+ let startNumForListLevelStyle = listStartingNumber continueNumbering listContinuationStartCounter
+ let defaultOrderedListConstructor = constructOrderedList (startNumForListLevelStyle Nothing) listLevel listItemCount
+
case fStyleName of
Right styleName -> do
fListStyle <- lookupListStyle -< styleName
case fListStyle of
Right listStyle -> do
- fLLS <- arr (uncurry getListLevelStyle) -< (listLevel,listStyle)
- case fLLS of
+ fListLevelStyle <- arr (uncurry getListLevelStyle) -< (listLevel, listStyle)
+ case fListLevelStyle of
Just listLevelStyle -> do
- oldListStyle <- switchCurrentListStyle -< Just listStyle
- blocks <- constructListWith listLevelStyle -<< x
- switchCurrentListStyle -< oldListStyle
- returnA -< blocks
- Nothing -> constructOrderedList -< x
- Left _ -> constructOrderedList -< x
+ let startNum = startNumForListLevelStyle $ Just listLevelStyle
+ oldListStyle <- switchCurrentListStyle -< Just listStyle
+ blocks <- constructListWith listLevelStyle startNum listLevel listItemCount -<< x
+ switchCurrentListStyle -< oldListStyle
+ returnA -< blocks
+ Nothing -> defaultOrderedListConstructor -<< x
+ Left _ -> defaultOrderedListConstructor -<< x
Left _ -> do
state <- getExtraState -< ()
mListStyle <- arr currentListStyle -< state
case mListStyle of
Just listStyle -> do
- fLLS <- arr (uncurry getListLevelStyle) -< (listLevel,listStyle)
- case fLLS of
- Just listLevelStyle -> constructListWith listLevelStyle -<< x
- Nothing -> constructOrderedList -< x
- Nothing -> constructOrderedList -< x
+ fListLevelStyle <- arr (uncurry getListLevelStyle) -< (listLevel, listStyle)
+ case fListLevelStyle of
+ Just listLevelStyle -> do
+ let startNum = startNumForListLevelStyle $ Just listLevelStyle
+ constructListWith listLevelStyle startNum listLevel listItemCount -<< x
+ Nothing -> defaultOrderedListConstructor -<< x
+ Nothing -> defaultOrderedListConstructor -<< x
where
- constructOrderedList =
+ listStartingNumber continueNumbering listContinuationStartCounter mListLevelStyle
+ | continueNumbering = listContinuationStartCounter
+ | isJust mListLevelStyle = listItemStart (fromJust mListLevelStyle)
+ | otherwise = 1
+ constructOrderedList startNum listLevel listItemCount =
reader
>>> modifyExtraState (shiftListLevel (-1))
- >>^ orderedList
- constructListWith listLevelStyle =
+ >>> modifyExtraState (modifyListContinuationStartCounter listLevel (startNum + listItemCount))
+ >>^ orderedListWith (startNum, DefaultStyle, DefaultDelim)
+ constructListWith listLevelStyle startNum listLevel listItemCount =
reader
- >>> getListConstructor listLevelStyle
+ >>> getListConstructor listLevelStyle startNum
^>> modifyExtraState (shiftListLevel (-1))
+ >>> modifyExtraState (modifyListContinuationStartCounter listLevel (startNum + listItemCount))
--------------------------------------------------------------------------------
-- Readers
@@ -666,9 +706,7 @@ read_header = matchingElement NsText "h"
--
read_list :: BlockMatcher
read_list = matchingElement NsText "list"
--- $ withIncreasedListLevel
$ constructList
--- $ liftA bulletList
$ matchChildContent' [ read_list_item
, read_list_header
]