From e8ed40ef01efdba315ec995c99da31a55bf55c57 Mon Sep 17 00:00:00 2001 From: Tuong Nguyen Manh Date: Sat, 13 Dec 2025 22:28:59 +0100 Subject: DocBook reader: Fix adding wrong metadata (#11347) Now keep track of the current element stack to only add metadata if inside an appropriate parent element. Closes #11300. --- src/Text/Pandoc/Readers/DocBook.hs | 21 ++++++++---- test/command/11300.md | 67 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 test/command/11300.md diff --git a/src/Text/Pandoc/Readers/DocBook.hs b/src/Text/Pandoc/Readers/DocBook.hs index 38e67e87e..66128b12e 100644 --- a/src/Text/Pandoc/Readers/DocBook.hs +++ b/src/Text/Pandoc/Readers/DocBook.hs @@ -548,6 +548,7 @@ data DBState = DBState{ dbSectionLevel :: Int , dbBook :: Bool , dbContent :: [Content] , dbLiteralLayout :: Bool + , dbElementStack :: [Text] } deriving Show instance Default DBState where @@ -556,7 +557,9 @@ instance Default DBState where , dbMeta = mempty , dbBook = False , dbContent = [] - , dbLiteralLayout = False } + , dbLiteralLayout = False + , dbElementStack = [] + } readDocBook :: (PandocMonad m, ToSources a) @@ -621,9 +624,13 @@ named s e = qName (elName e) == s -- addMetadataFromElement :: PandocMonad m => Element -> DB m Blocks -addMetadataFromElement e = - mempty <$ mapM_ handleMetadataElement +addMetadataFromElement e = do + -- Add metadata if at root or appropriate parent element + elementStack <- gets dbElementStack + if take 1 elementStack `elem` [[], ["book"], ["article"]] + then mempty <$ mapM_ handleMetadataElement (filterChildren ((isMetadataField . qName . elName)) e) + else return mempty where handleMetadataElement elt = case qName (elName elt) of @@ -853,9 +860,11 @@ getMediaobject e = do fmap (imageWith attr imageUrl tit) capt getBlocks :: PandocMonad m => Element -> DB m Blocks -getBlocks e = mconcat <$> - mapM parseBlock (elContent e) - +getBlocks e = do + modify (\st -> st{ dbElementStack = qName (elName e) : dbElementStack st }) + blocks <- mconcat <$> mapM parseBlock (elContent e) + modify (\st -> st{ dbElementStack = drop 1 $ dbElementStack st }) + return blocks parseBlock :: PandocMonad m => Content -> DB m Blocks parseBlock (Text (CData CDataRaw _ _)) = return mempty -- DOCTYPE diff --git a/test/command/11300.md b/test/command/11300.md new file mode 100644 index 000000000..141d46248 --- /dev/null +++ b/test/command/11300.md @@ -0,0 +1,67 @@ +``` +% pandoc -f docbook -t native -s + + + + Book title + Book subtitle + + + + Chapter title + + My sentence + + +^D +Pandoc + Meta + { unMeta = + fromList + [ ( "subtitle" + , MetaInlines [ Str "Book" , Space , Str "subtitle" ] + ) + , ( "title" + , MetaInlines [ Str "Book" , Space , Str "title" ] + ) + ] + } + [ Header + 1 ( "" , [] , [] ) [ Str "Chapter" , Space , Str "title" ] + , Para [ Str "My" , Space , Str "sentence" ] + ] +``` + +``` +% pandoc -f docbook -t native -s + + + + + Chapter title + + My sentence + + + Book title + Book subtitle + + +^D +Pandoc + Meta + { unMeta = + fromList + [ ( "subtitle" + , MetaInlines [ Str "Book" , Space , Str "subtitle" ] + ) + , ( "title" + , MetaInlines [ Str "Book" , Space , Str "title" ] + ) + ] + } + [ Header + 1 ( "" , [] , [] ) [ Str "Chapter" , Space , Str "title" ] + , Para [ Str "My" , Space , Str "sentence" ] + ] +``` -- cgit v1.2.3