module SinglePage (make) where import Depend (pageFile) import Info hiding (Text) import BuilderQQ import Records () import Control.Exception import qualified Data.Text as Strict import qualified Data.Text.Lazy as Lazy import Data.Time (formatTime, defaultTimeLocale) import Data.Maybe (fromMaybe) import qualified Data.Char as Char import qualified Data.List as List -- | e.g. only nsfw images are present for a non-nsfw page data NoEligibleImages = NoEligibleImages {title :: !Strict.Text} deriving stock Eq deriving anyclass Exception instance Show NoEligibleImages where show (NoEligibleImages {title}) = Strict.unpack title <> ": no images selected\n" <> " (probably a nsfw-only work without --nsfw set)" make :: Bool -> Info -> Lazy.Text make nsfw = toLazyText . make' nsfw make' :: Bool -> Info -> Builder make' nsfw (Info {date, title, artist, tags, nsfwTags, description, images, background, links}) = [b|@0 $titleTag
$titleHeader $artistTag

$formattedDate

$buttonBar
$warning'
$descSection $tagsList $linksList
|] where titleTag = ifJust title \t -> [b|$*t|] titleHeader = ifJust title \t -> [b|

$*t

|] artistTag = ifJust artist makeArtist formattedDate = formatDate date buttonBar = makeButtonBar (fromMaybe (Strict.pack path0) title) nsfw images image0 = head images path0 = #path image0 path0' = pageFile path0 descSection = ifJust description makeDesc tagsList = makeTags nsfw tags nsfwTags linksList = extLinks nsfw links dataBg = ifJust background \bg -> [b| data-bg="$*bg"|] warning' = ifJust (#warning image0) \w -> [b|@4
cw: $*w
|] makeArtist :: Artist -> Builder makeArtist (Artist {name, url}) = [b|

by $artistLink

|] where artistLink = case url of Just u -> [b|$*name|] Nothing -> [b|$*name|] makeDesc :: Strict.Text -> Builder makeDesc desc = [b|@4

about

$8*desc
|] ifJust :: Monoid b => Maybe a -> (a -> b) -> b ifJust x f = maybe mempty f x formatDate :: Day -> Builder formatDate d = let str = formatTime defaultTimeLocale "%e %#B %Y" d in [b|$@str|] makeButtonBar :: Strict.Text -> Bool -> [Image] -> Builder makeButtonBar title nsfw allImages = case length images of 0 -> throw $ NoEligibleImages title 1 -> "" _ -> [b|@2 |] where images | nsfw = allImages | otherwise = filter #sfw allImages alts = map (uncurry altButton) $ zip [0..] images altButton :: Int -> Image -> Builder altButton i (Image {label, path, nsfw, warning}) = [b|@6 |] where nsfwClass = if nsfw then " class=nsfw" else "" checked = if i == 0 then " checked" else "" idLabel = escId label path' = pageFile path warning' = ifJust warning \w -> [b| data-warning="$*w"|] escId :: Strict.Text -> Builder escId = foldMap esc1 . Strict.unpack where esc1 c | Char.isSpace c = "" | c < 'ΓΏ' && not (Char.isAlphaNum c || c == '-') = "_" | otherwise = [b|$'c|] makeTags :: Bool -> [Strict.Text] -> [Strict.Text] -> Builder makeTags nsfw sfwTags nsfwTags = if null tags then "" else [b|@4

tags

|] where tagList = map makeTag tags makeTag t = [b|
  • $*t|] tags = List.nub $ if nsfw then sfwTags <> nsfwTags else sfwTags extLinks :: Bool -> [Link] -> Builder extLinks nsfw allLinks = if null links then "" else [b|@4 |] where links = if nsfw then allLinks else filter #sfw allLinks linkList = map extLink links extLink :: Link -> Builder extLink (Link {title, url}) = [b|@6
  • $*title |]