Add image rendering alongside automatic mimetype detection

This commit is contained in:
Marko Andjelic 2026-01-26 02:59:11 +00:00
commit 396a9cdb16
3 changed files with 34 additions and 4 deletions

View file

@ -19,12 +19,13 @@ import qualified Data.Text.Encoding as TE
import Control.Monad.Reader (ReaderT, MonadReader(ask), liftIO)
import Control.Monad.Except (runExceptT)
import Text.HTML.TagSoup (parseTags, Tag(..))
import System.FilePath (takeDirectory, (</>), normalise)
import System.FilePath (takeDirectory, (</>), normalise, takeExtension)
import Data.List (find)
import Codec.Epub.Parse (getManifest , getSpine)
import qualified Codec.Epub.Data.Manifest as DM
import qualified Codec.Epub.Data.Spine as DS
import qualified Data.ByteString.Base64 as B64
type EpubAction a = ReaderT EpubEnv IO a
@ -85,4 +86,32 @@ getChapter filename = do
let full = normalise (baseDir env </> filename)
case findEntryByPath full (archive env) of
Nothing -> pure []
Just e -> pure $ parseTags . TE.decodeUtf8 . B.toStrict $ fromEntry e
Just e -> do
pure $ embedImages (archive env) (baseDir env) (parseTags . TE.decodeUtf8 . B.toStrict $ fromEntry e) -- The base64 img
getMimeType :: FilePath -> T.Text
getMimeType path = T.pack $ "image/" ++ normalizeExt (drop 1 $ takeExtension path)
where
normalizeExt :: String -> String
normalizeExt ext
| ext == "jpg" = "jpeg"
| otherwise = ext
embedImages :: Archive -> FilePath -> [Tag T.Text] -> [Tag T.Text]
embedImages arch bdir = map processTag
where
processTag (TagOpen "img" attrs) = TagOpen "img" (map replaceSrc attrs)
processTag other = other
replaceSrc (name, value)
| name == "src" = ("src", findImage value)
| otherwise = (name, value)
findImage path =
let fullPath = normalise (bdir </> T.unpack path)
in case findEntryByPath fullPath arch of
Nothing -> path
Just entry ->
let rawData = B.toStrict $ fromEntry entry
b64 = TE.decodeUtf8 $ B64.encode rawData
in "data:" <> getMimeType fullPath <> ";base64," <> b64

View file

@ -15,7 +15,7 @@ runWindow htmlContent = do
_ <- Gtk.on app #activate $ do
window <- Gtk.applicationWindowNew app
Gtk.windowSetTitle window (Just "Svitak Reader (GTK 4)")
Gtk.windowSetTitle window (Just "Svitak")
Gtk.windowSetDefaultSize window 800 600