packages feed

pandoc-pyplot-2.2.0.0: executable/Main.hs

{-# LANGUAGE ApplicativeDo   #-}
{-# LANGUAGE LambdaCase      #-}
{-# LANGUAGE TemplateHaskell #-}

module Main where

import           Control.Applicative                ((<|>))
import           Control.Monad                      (join)

import           Data.Default.Class                 (def)
import           Data.List                          (intersperse)
import           Data.Monoid                        ((<>))
import qualified Data.Text                          as T

import           Options.Applicative
import qualified Options.Applicative.Help.Pretty    as P

import           System.Directory                   (doesFileExist)
import           System.IO.Temp                     (writeSystemTempFile)

import           Text.Pandoc.Filter.Pyplot          (SaveFormat (..),
                                                     configuration,
                                                     plotTransformWithConfig)
import           Text.Pandoc.Filter.Pyplot.Internal (writeConfig)
import           Text.Pandoc.JSON                   (toJSONFilter)

import           Web.Browser                        (openBrowser)

import qualified Data.Version                       as V
import           Paths_pandoc_pyplot                (version)

import           ManPage                            (embedManualHtml)

main :: IO ()
main = join $ execParser opts
    where
        opts = info (run <**> helper)
            (fullDesc
            <> progDesc "This pandoc filter generates plots from Python code blocks using Matplotlib. This allows to keep documentation and figures in perfect synchronicity."
            <> header "pandoc-pyplot - generate Matplotlib figures directly in documents."
            <> footerDoc (Just footer')
            )


toJSONFilterWithConfig :: IO ()
toJSONFilterWithConfig = do
    configExists <- doesFileExist ".pandoc-pyplot.yml"
    config <- if configExists
                then configuration ".pandoc-pyplot.yml"
                else def
    toJSONFilter (plotTransformWithConfig config)


data Flag = Version
          | Formats
          | Manual
          | Config
    deriving (Eq)


run :: Parser (IO ())
run = do
    versionP <- flag Nothing (Just Version) (long "version" <> short 'v'
                    <> help "Show version number and exit.")

    formatsP <- flag Nothing (Just Formats) (long "formats" <> short 'f'
                    <> help "Show supported output figure formats and exit.")

    manualP  <- flag Nothing (Just Manual)  (long "manual"  <> short 'm'
                    <> help "Open the manual page in the default web browser and exit.")

    configP  <- flag Nothing (Just Config)  (long "write-example-config"
                    <> help "Write the default configuration in '.pandoc-pyplot.yml', \
                            \which you can subsequently customize, and exit. If '.pandoc-pyplot.yml' \
                            \already exists, an error will be thrown. ")

    input    <- optional $ strArgument (metavar "AST")
    return $ go (versionP <|> formatsP <|> manualP <|> configP) input
    where
        go :: Maybe Flag -> Maybe String -> IO ()
        go (Just Version) _ = putStrLn (V.showVersion version)
        go (Just Formats) _ = putStrLn . mconcat . intersperse ", " . fmap show $ supportedSaveFormats
        go (Just Manual)  _ = writeSystemTempFile "pandoc-pyplot-manual.html" (T.unpack manualHtml)
                                >>= \fp -> openBrowser ("file:///" <> fp)
                                >> return ()
        go (Just Config) _  = writeConfig ".pandoc-pyplot.yml" def
        go Nothing _ = toJSONFilterWithConfig


supportedSaveFormats :: [SaveFormat]
supportedSaveFormats = enumFromTo minBound maxBound


manualHtml :: T.Text
manualHtml = T.pack $(embedManualHtml)


-- | Use Doc type directly because of newline formatting
footer' :: P.Doc
footer' = mconcat [
        P.text "Example usage with pandoc:"
    , P.line, P.line
    , P.indent 4 $ P.string "> pandoc --filter pandoc-pyplot input.md --output output.html"
    , P.line, P.line
    , P.text "If you use pandoc-pyplot in combination with other filters, you probably want to run pandoc-pyplot first. Here is an example with pandoc-crossref:"
    , P.line, P.line
    , P.indent 4 $ P.string "> pandoc --filter pandoc-pyplot --filter pandoc-crossref -i input.md -o output.pdf"
    , P.line, P.line
    , P.text "More information can be found via the manual (pandoc-pyplot --manual) or the repository README, located at"
    , P.line
    , P.indent 4 $ P.text "https://github.com/LaurentRDC/pandoc-pyplot"
    , P.line
    ]