forked from marko/svitak
41 lines
1.4 KiB
Haskell
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
|