{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RecordWildCards #-}
import qualified Data.HashMap.Strict as HM
import Data.List (intersperse)
import Data.Text (Text)
import Data.Yaml
import Text.LaTeX
class ToTex a where
toTex :: a -> LaTeX
instance ToTex a => ToTex [a] where
toTex = mconcat . map toTex
data Skill = Skill
{ skName :: Text
, skBasic :: [Knack]
, skAdvanced :: [Knack]
} deriving (Eq,Show)
data Knack = Knack
{ knName :: Text
, knDescription :: Maybe Text
} deriving (Eq,Show)
instance FromJSON [Skill] where
parseJSON (Object os) = mapM getSkill (HM.toList os)
where getSkill :: (Text, Value) -> Parser Skill
getSkill (skName, Object os) = do
basic <- os .:? "basic"
advanced <- os .:? "advanced"
skBasic <- maybe (return []) (mapM getKnack) basic
skAdvanced <- maybe (return []) (mapM getKnack) advanced
return Skill { .. }
getSkill (name, Null) = return (Skill name [] [])
getSkill _ = return (Skill "???" [] [])
getKnack :: Value -> Parser Knack
getKnack (String name) = return (Knack name Nothing)
getKnack (Object os) =
case HM.toList os of
[(name, String desc)] -> return (Knack name (Just desc))
_ -> fail "mal-formatted knack"
getKnack _ = fail "knack neither string nor object"
parseJSON _ = fail "skills not object"
instance ToTex Skill where
toTex Skill { .. } = tabular Nothing [LeftColumn, LeftColumn] table
where table = raw skName & contents
contents = mconcat (intersperse newline (map go skBasic))
<> mconcat (intersperse newline (map go skAdvanced))
go (Knack name Nothing) = raw name
go (Knack name (Just desc)) = raw name <> textit (raw desc)