{-# LANGUAGE OverloadedStrings #-} module MdBlocks.CLI where import qualified Data.Aeson.Encode.Pretty as JSON import qualified Data.ByteString.Lazy.Char8 as BL import qualified Data.Text.IO as T import System.Directory (doesFileExist) import System.Exit (die) import Options.Applicative import MdBlocks.Address import MdBlocks.Parser import MdBlocks.Resolver import MdBlocks.Types data Command = List FilePath | Extract String | ShowMeta String runCLI :: IO () runCLI = execParser opts >>= run where opts = info (parser <**> helper) (fullDesc <> progDesc "Parse and extract Markdown blocks") parser :: Parser Command parser = listP <|> extractP <|> showP listP :: Parser Command listP = List <$> strOption ( long "list" <> metavar "FILE" <> help "List blocks in a Markdown file" ) extractP :: Parser Command extractP = Extract <$> strOption ( long "extract" <> metavar "FILE#ID" <> help "Extract a block by its address" ) showP :: Parser Command showP = ShowMeta <$> strOption ( long "show" <> metavar "FILE#ID" <> help "Show block metadata" ) run :: Command -> IO () run (List fp) = do bs <- loadBlocks fp BL.putStrLn $ JSON.encodePretty bs run (Extract rawAddress) = case parseAddress rawAddress of Left err -> die ("mdblocks: " ++ err) Right address -> do isFile <- doesFileExist (addressFile address) if not isFile then die ("mdblocks: not a file: " ++ addressFile address) else do blocks <- loadBlocks (addressFile address) case resolveBlock address blocks of Left err -> die ("mdblocks: " ++ formatResolveError address err) Right block -> T.putStr (blockContent block) run (ShowMeta addr) = putStrLn ("show not implemented yet: " ++ addr) loadBlocks :: FilePath -> IO [Block] loadBlocks fp = do txt <- T.readFile fp pure (parseFile fp txt)