svitak/app/Navigation.hs
2026-02-12 11:17:36 +00:00

41 lines
1.4 KiB
Haskell

{-# LANGUAGE OverloadedStrings #-}
module Navigation
( navFinder,
lndmkScraper
)
where
import Text.HTML.Scalpel (Scraper, attr, (@:), (@=), chroot, chroots, text, match)
import Types (NavItem(..), EpubType (..), InternalPath(..))
import Data.Maybe (fromMaybe)
import Control.Applicative (optional)
import Control.Monad (guard)
import qualified Data.Text as T
-- ------------------------------------------------------------
-- EPub 3 navigation
-- ------------------------------------------------------------
-- The epub-metadata library is good for epub 2.x. As there could be a seperate nav.xhtml file in the epub 3.x spec, we need these functions to support it.
navFinder :: Scraper String FilePath
navFinder = attr "href" ("item" @: ["properties" @= "nav"])
itemScraper :: [EpubType] -> Scraper T.Text NavItem
itemScraper allowedTypes = do
label <- text "a"
path <- attr "href" "a"
rawTypes <- fromMaybe "" <$> optional (attr "epub:type" "a")
let foundTypes = map EpubType $ T.words rawTypes
guard $ any (`elem` allowedTypes) foundTypes
pure $ NavItem label (InternalPath $ T.unpack path) foundTypes
lndmkScraper :: [EpubType] -> Scraper T.Text [NavItem]
lndmkScraper labels =
chroot ("nav" @: [match navPredicate]) $ chroots "li" (itemScraper labels)
where
navPredicate "epub:type" xs = EpubType (T.pack xs) `elem` labels
navPredicate _ _ = False