    {-# LANGUAGE OverloadedStrings #-}
    {- |
       Module      : Text.Pandoc.Readers.Docx.Util
       Copyright   : © 2014-2020 Jesse Rosenthal <jrosenthal@jhu.edu>,
                       2014-2024 John MacFarlane <jgm@berkeley.edu>,
                       2015 Nikolay Yakimov <root@livid.pp.ru>
       License     : GNU GPL, version 2 or above

       Maintainer  : Jesse Rosenthal <jrosenthal@jhu.edu>
       Stability   : alpha
       Portability : portable

    Docx reader utility functions.
    -}
    module Text.Pandoc.Readers.Docx.Util (
                                            NameSpaces
                                          , elemName
                                          , isElem
                                          , elemToNameSpaces
                                          , findChildByName
                                          , findChildrenByName
                                          , findElementByName
                                          , findAttrByName
                                          , extractChildren
                                          ) where

    import Data.List (partition)
    import Text.Pandoc.XML.Light
    import Text.Pandoc.Readers.OOXML.Shared
      (NameSpaces, elemName, isElem, elemToNameSpaces,
       findChildByName, findChildrenByName, findElementByName, findAttrByName)

    -- | Removes child elements that satisfy a given condition.
    -- Returns the modified element and the list of removed children.
    extractChildren :: Element -> (Element -> Bool) -> Maybe (Element, [Element])
    extractChildren :: Element -> (Element -> Bool) -> Maybe (Element, [Element])
    extractChildren Element
    el Element -> Bool
    condition
      | [Element] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Element]
    removedChildren = Maybe (Element, [Element])
    forall a. Maybe a
    Nothing  -- No children removed, return Nothing
      | Bool
    otherwise = (Element, [Element]) -> Maybe (Element, [Element])
    forall a. a -> Maybe a
    Just (Element
    modifiedElement, [Element]
    removedChildren)  -- Children removed, return Just
      where
        -- Separate the children based on the condition
        ([Element]
    removedChildren, [Element]
    keptChildren) = (Element -> Bool) -> [Element] -> ([Element], [Element])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition Element -> Bool
    condition ([Content] -> [Element]
    onlyElems ([Content] -> [Element]) -> [Content] -> [Element]
    forall a b. (a -> b) -> a -> b
    $ Element -> [Content]
    elContent Element
    el)

        -- Reconstruct the element with the kept children
        modifiedElement :: Element
    modifiedElement = Element
    el { elContent = map Elem keptChildren }