From 092ef7b8f14be7f6b523a31404be7e69bd0d6f50 Mon Sep 17 00:00:00 2001 From: Marko Andjelic Date: Sat, 24 Jan 2026 00:56:23 +0000 Subject: [PATCH] Implement scalpel --- app/EpubParser.hs | 30 +++++++++--------------------- svitak.cabal | 3 ++- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/app/EpubParser.hs b/app/EpubParser.hs index f9bea9e..7d6e08c 100644 --- a/app/EpubParser.hs +++ b/app/EpubParser.hs @@ -3,7 +3,8 @@ module EpubParser where import Codec.Archive.Zip (toArchive, findEntryByPath, fromEntry, Archive) import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString.Lazy.Char8 as C8 -import Text.HTML.TagSoup (parseTags, fromAttrib, (~==), Tag, innerText, sections) +import Text.HTML.TagSoup (parseTags, Tag) +import Text.HTML.Scalpel (scrape, text, tagSelector, attr) import System.FilePath (takeDirectory) import Control.Monad.Reader import qualified Data.Text as T @@ -36,17 +37,10 @@ openEpub path = toArchive <$> BL.readFile path >>= \archive -> maybe (pure $ Lef getOpfPath :: Archive -> Maybe FilePath getOpfPath archive = do entry <- findEntryByPath "META-INF/container.xml" archive - let content = C8.unpack (fromEntry entry) + let tags = parseTags $ C8.unpack (fromEntry entry) + -- Logic: scrape (the_scraper) (the_tags) + scrape (attr "full-path" (tagSelector "rootfile")) tags - let tags = parseTags content - - let rootfileTags = filter (~== "") tags - - -- If we found at least one, get the "full-path" attribute - case rootfileTags of - (t:_) -> Just (fromAttrib "full-path" t) - [] -> Nothing - getOpfTags :: Archive -> FilePath -> [Tag String] getOpfTags archive opfpath = case findEntryByPath opfpath archive of @@ -56,16 +50,10 @@ getOpfTags archive opfpath = getRootPrefix :: FilePath -> FilePath getRootPrefix path = let dir = takeDirectory path - in if dir == "." - then "" - else dir ++ "/" - -tagify :: String -> String -tagify item = "<" ++ item ++ ">" + in if dir == "." then "" else dir ++ "/" getTagText :: String -> [Tag String] -> T.Text -getTagText tagName tags = - case sections (~== tagify tagName) tags of - (x:_) -> T.pack (innerText x) - [] -> T.empty +getTagText tagName tags = + let scraper = text (tagSelector tagName) + in T.pack $ fromMaybe "" (scrape scraper tags) diff --git a/svitak.cabal b/svitak.cabal index e710b44..578ee42 100644 --- a/svitak.cabal +++ b/svitak.cabal @@ -66,7 +66,8 @@ executable svitak mtl >= 2.3.2, tagsoup, text >= 2.1.2, - zip-archive >= 0.4.3.2 + zip-archive >= 0.4.3.2, + scalpel >= 0.6.2.2 hs-source-dirs: app default-language: Haskell2010