lang/langfilter/lib/LaantasImage.hs

97 lines
2.5 KiB
Haskell
Raw Normal View History

module LaantasImage
2024-11-28 01:32:27 +01:00
(Item (..), splitItem, splitItem', makeItem)
where
import Lang
2024-11-28 01:32:27 +01:00
import Text.Pandoc.Definition
import Data.Bifunctor
import Data.Function
import Data.Maybe
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Text (Text)
import qualified Data.Text as Text
2024-11-28 01:32:27 +01:00
import qualified Data.Text.Lazy as Lazy
import qualified Laantas
2024-11-30 20:03:19 +01:00
import Data.Char (isSpace)
2024-11-28 01:32:27 +01:00
data Item =
Item {
text, title :: Text,
size, stroke :: Double,
2024-11-28 01:32:27 +01:00
width :: Double,
color :: Text,
showText :: Bool
} deriving (Eq, Show)
2024-11-28 01:32:27 +01:00
splitItem :: Vars => Text -> Maybe Item
splitItem (Text.uncons -> Just (c, txt))
| c == '!' = Just $ splitItem' txt
| c == '#' = Just $ (splitItem' txt) {showText = False}
splitItem _ = Nothing
2024-11-28 01:32:27 +01:00
splitItem' :: Vars => Text -> Item
splitItem' txt =
case imageOpts txt of
2024-11-28 01:32:27 +01:00
Just (txt, opts) -> defaultItem txt ?defColor
& withOpt opts "size" (\s i -> i {size = readt s})
& withOpt opts "stroke" (\k i -> i {stroke = readt k})
& withOpt opts "width" (\w i -> i {width = readt w})
& withOpt opts "color" (\c i -> i {color = c})
2024-11-28 01:32:27 +01:00
Nothing -> defaultItem txt ?defColor
where readt x = read $ Text.unpack x
withOpt :: Ord k => Map k v -> k -> (v -> a -> a) -> (a -> a)
withOpt m k f =
case Map.lookup k m of
Just v -> f v
Nothing -> id
2024-11-28 01:32:27 +01:00
defaultItem :: Text -> Text -> Item
defaultItem txt color =
Item {
text = Text.filter notPunc txt,
title = toTitle txt,
2024-11-28 01:32:27 +01:00
size = 2,
stroke = 1.25,
width = 600,
color = color,
showText = True
}
split1 :: Text -> Text -> Maybe (Text, Text)
split1 s txt =
let (a, b) = Text.breakOn s txt in
if Text.null b then
Nothing
else
Just (Text.strip a, Text.strip $ Text.drop (Text.length s) b)
type Opts = Map Text Text
imageOpts :: Text -> Maybe (Text, Opts)
imageOpts = fmap (second splitOpts) . getOpts
getOpts :: Text -> Maybe (Text, Text)
getOpts = split1 "|"
splitOpts :: Text -> Map Text Text
splitOpts = Map.fromList . map splitOpt . Text.splitOn ";" where
splitOpt txt = fromMaybe ("file", txt) $ split1 "=" txt
toTitle :: Text -> Text
toTitle = Text.filter \c -> c /= '\\' && c /= '#'
2024-11-28 01:32:27 +01:00
makeItem :: Item -> Inline
makeItem (Item {..}) =
let env = Laantas.E {..}
words = Laantas.split text in
2024-11-30 20:03:19 +01:00
RawInline "html" $
Lazy.toStrict $ Lazy.dropAround isSpace $ Laantas.prettyText $
Laantas.doGlyphsNoDoctype words env `Laantas.with`
[Laantas.Class_ Laantas.<<- "scr"]
notPunc :: Char -> Bool
notPunc c = c `notElem` ("{}·" :: String)