indieweb-algorithms-0.1.0: library/Data/IndieWeb/MicroformatsUtil.hs
{-# 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