{-# LANGUAGE OverloadedStrings, UnicodeSyntax #-} module Data.IndieWeb.MicroformatsUtil where import Control.Lens import Data.Maybe import Data.Aeson import Data.Aeson.Lens import qualified Data.Vector as V import qualified Data.HashMap.Strict as HMS import qualified Data.Text as T -- | Recursively finds microformats of a given type, also keeping the path (in reverse order) that led to them. -- Returns Nothing when the given Value isn't an object with an 'items' key, ie. is not a result of Microformats 2 parsing. allMicroformatsOfType ∷ T.Text → Value → Maybe [(Value, [Value])] allMicroformatsOfType typeName mf = do items ← mf ^? key "items" . _Array let findOfType acc path v = let valToList (Array vec) = V.toList vec valToList _ = [] childMfs = V.toList $ fromMaybe V.empty $ v ^? key "children" . _Array propMfs = concatMap valToList $ HMS.elems $ fromMaybe HMS.empty $ v ^? key "properties" . _Object acc' = acc ++ concatMap (findOfType acc $ v : path) (childMfs ++ propMfs) in if String typeName `V.elem` fromMaybe V.empty (v ^? key "type" . _Array) then (v, path) : acc' else acc' Just $ concatMap (findOfType [] []) items