{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE NamedFieldPuns #-} import Data.Aeson import Data.String (fromString) import GHC.Generics import System.Directory import System.Environment import System.FilePath import Data.Maybe import Data.List (intersperse) import qualified Data.Text.Lazy as T import qualified Data.Text.Lazy.IO as T import qualified Data.Text.Lazy.Encoding as T import qualified Data.ByteString.Lazy as BS data NorwegianWord = NorwegianWord { word :: T.Text , hints :: Maybe [T.Text] } deriving (Generic, Show) instance FromJSON NorwegianWord instance ToJSON NorwegianWord where toEncoding = genericToEncoding defaultOptions data JapaneseWord = JapaneseWord { word :: T.Text , romaji :: Maybe T.Text , hints :: Maybe [T.Text] } deriving (Generic, Show) instance FromJSON JapaneseWord instance ToJSON JapaneseWord where toEncoding = genericToEncoding defaultOptions data Card = Card { norwegian :: [NorwegianWord] , japanese :: [JapaneseWord] } deriving (Generic, Show) data WordBlock = WordBlock { title :: T.Text , cards :: [Card] } deriving (Show) instance FromJSON Card instance ToJSON Card where toEncoding = genericToEncoding defaultOptions readJsonFile :: FilePath -> IO (Either String WordBlock) readJsonFile path = do fileContent <- BS.readFile path return $ cardsToWordblock <$> eitherDecode fileContent where formatPath :: FilePath -> T.Text formatPath = T.append " " . fromMaybe "???" . T.stripPrefix "yokutango_" . fromString . takeBaseName cardsToWordblock cards = WordBlock { title = formatPath path , cards = cards } cardToRow :: Card -> T.Text cardToRow card = mconcat [ japanesePart card, " $\\longleftrightarrow$ ", norwegianPart card ] where jpWordToText :: JapaneseWord -> T.Text jpWordToText JapaneseWord { word, romaji, hints } = case (word, romaji, hints) of (w, Just r, _) -> mconcat [ "\\ruby{", w, "}{", r, "}" ] (w, Nothing, _) -> w noWordToText :: NorwegianWord -> T.Text noWordToText NorwegianWord { word, hints } = word japanesePart (Card { japanese }) = mconcat $ intersperse ("\\\\\n" :: T.Text) $ map jpWordToText japanese norwegianPart (Card { norwegian }) = mconcat $ intersperse ("\\\\\n" :: T.Text) $ map noWordToText norwegian wordblockToTable :: WordBlock -> T.Text wordblockToTable block = mconcat tablePieces where rows = map ((\t -> T.append t "\\\\\n") . cardToRow) (cards block) tablePieces = [ "\\section*{", title block, "}\n" ] ++ rows ++ ["\\newpage"] main :: IO () main = do dir <- head <$> getArgs filePaths <- map (\x -> joinPath [dir, x]) <$> listDirectory dir wordBlocks :: Either str [WordBlock] <- sequence <$> mapM readJsonFile filePaths let output = case wordBlocks of Right blocks -> mconcat $ map wordblockToTable blocks Left err -> fromString err BS.putStr $ T.encodeUtf8 $ output -- case jsonFiles of -- Right cards -> mapM_ print cards -- Left err -> putStr err