{-# LANGUAGE TemplateHaskell, OverloadedStrings, PackageImports #-}
module Hledger.Cli.DocFiles (
Topic
,printHelpForTopic
,runManForTopic
,runInfoForTopic
,runPagerForTopic
) where
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BC
import Data.Maybe (fromMaybe, isNothing)
import Data.String
import System.IO
import System.IO.Temp
import System.Process
import Hledger.Utils (first3, second3, third3, embedFileRelative)
import Text.Printf (printf)
import System.Environment (lookupEnv)
import Hledger.Utils.Debug
type Tool = String
type Topic = String
toolDocs :: [(Tool, (ByteString, ByteString, ByteString))]
toolDocs :: [(Tool, (ByteString, ByteString, ByteString))]
toolDocs = [
(Tool
"hledger",
($(embedFileRelative "embeddedfiles/hledger.1")
,$(embedFileRelative "embeddedfiles/hledger.txt")
,$(embedFileRelative "embeddedfiles/hledger.info")
))
,(Tool
"hledger-ui",
($(embedFileRelative "embeddedfiles/hledger-ui.1")
,$(embedFileRelative "embeddedfiles/hledger-ui.txt")
,$(embedFileRelative "embeddedfiles/hledger-ui.info")
))
,(Tool
"hledger-web",
($(embedFileRelative "embeddedfiles/hledger-web.1")
,$(embedFileRelative "embeddedfiles/hledger-web.txt")
,$(embedFileRelative "embeddedfiles/hledger-web.info")
))
]
toolDocTxt :: Tool -> ByteString
toolDocTxt :: Tool -> ByteString
toolDocTxt Tool
name =
ByteString
-> ((ByteString, ByteString, ByteString) -> ByteString)
-> Maybe (ByteString, ByteString, ByteString)
-> ByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Tool -> ByteString
forall a. IsString a => Tool -> a
fromString (Tool -> ByteString) -> Tool -> ByteString
forall a b. (a -> b) -> a -> b
$ Tool
"No text manual found for tool: "Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++Tool
name) (ByteString, ByteString, ByteString) -> ByteString
forall a b c. (a, b, c) -> b
second3 (Maybe (ByteString, ByteString, ByteString) -> ByteString)
-> Maybe (ByteString, ByteString, ByteString) -> ByteString
forall a b. (a -> b) -> a -> b
$ Tool
-> [(Tool, (ByteString, ByteString, ByteString))]
-> Maybe (ByteString, ByteString, ByteString)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Tool
name [(Tool, (ByteString, ByteString, ByteString))]
toolDocs
toolDocMan :: Tool -> ByteString
toolDocMan :: Tool -> ByteString
toolDocMan Tool
name =
ByteString
-> ((ByteString, ByteString, ByteString) -> ByteString)
-> Maybe (ByteString, ByteString, ByteString)
-> ByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Tool -> ByteString
forall a. IsString a => Tool -> a
fromString (Tool -> ByteString) -> Tool -> ByteString
forall a b. (a -> b) -> a -> b
$ Tool
"No man page found for tool: "Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++Tool
name) (ByteString, ByteString, ByteString) -> ByteString
forall a b c. (a, b, c) -> a
first3 (Maybe (ByteString, ByteString, ByteString) -> ByteString)
-> Maybe (ByteString, ByteString, ByteString) -> ByteString
forall a b. (a -> b) -> a -> b
$ Tool
-> [(Tool, (ByteString, ByteString, ByteString))]
-> Maybe (ByteString, ByteString, ByteString)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Tool
name [(Tool, (ByteString, ByteString, ByteString))]
toolDocs
toolDocInfo :: Tool -> ByteString
toolDocInfo :: Tool -> ByteString
toolDocInfo Tool
name =
ByteString
-> ((ByteString, ByteString, ByteString) -> ByteString)
-> Maybe (ByteString, ByteString, ByteString)
-> ByteString
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Tool -> ByteString
forall a. IsString a => Tool -> a
fromString (Tool -> ByteString) -> Tool -> ByteString
forall a b. (a -> b) -> a -> b
$ Tool
"No info manual found for tool: "Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++Tool
name) (ByteString, ByteString, ByteString) -> ByteString
forall a b c. (a, b, c) -> c
third3 (Maybe (ByteString, ByteString, ByteString) -> ByteString)
-> Maybe (ByteString, ByteString, ByteString) -> ByteString
forall a b. (a -> b) -> a -> b
$ Tool
-> [(Tool, (ByteString, ByteString, ByteString))]
-> Maybe (ByteString, ByteString, ByteString)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Tool
name [(Tool, (ByteString, ByteString, ByteString))]
toolDocs
printHelpForTopic :: Tool -> Maybe Topic -> IO ()
printHelpForTopic :: Tool -> Maybe Tool -> IO ()
printHelpForTopic Tool
tool Maybe Tool
_mtopic =
ByteString -> IO ()
BC.putStr (Tool -> ByteString
toolDocTxt Tool
tool)
runPagerForTopic :: Tool -> Maybe Topic -> IO ()
Tool
tool Maybe Tool
mtopic = do
Tool -> (Tool -> Handle -> IO ()) -> IO ()
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Tool -> (Tool -> Handle -> m a) -> m a
withSystemTempFile (Tool
"hledger-"Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++Tool
toolTool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++Tool
".txt") ((Tool -> Handle -> IO ()) -> IO ())
-> (Tool -> Handle -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Tool
f Handle
h -> do
Handle -> ByteString -> IO ()
BC.hPutStrLn Handle
h (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$ Tool -> ByteString
toolDocTxt Tool
tool
Handle -> IO ()
hClose Handle
h
let defpager :: Tool
defpager = Tool
"less -is"
Tool
envpager <- Tool -> Maybe Tool -> Tool
forall a. a -> Maybe a -> a
fromMaybe Tool
defpager (Maybe Tool -> Tool) -> IO (Maybe Tool) -> IO Tool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tool -> IO (Maybe Tool)
lookupEnv Tool
"PAGER"
let pager :: Tool
pager = if Maybe Tool -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Tool
mtopic then Tool
envpager else Tool
defpager
Tool -> IO ()
callCommand (Tool -> IO ()) -> Tool -> IO ()
forall a b. (a -> b) -> a -> b
$ Tool -> Tool -> Tool
forall a. Show a => Tool -> a -> a
dbg1 Tool
"pager command" (Tool -> Tool) -> Tool -> Tool
forall a b. (a -> b) -> a -> b
$
Tool
pager Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++ Tool -> (Tool -> Tool) -> Maybe Tool -> Tool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Tool
"" (Tool -> Tool -> Tool
forall r. PrintfType r => Tool -> r
printf Tool
" +'/^( )?%s'") Maybe Tool
mtopic Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++ Tool
" " Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++ Tool
f
runManForTopic :: Tool -> Maybe Topic -> IO ()
runManForTopic :: Tool -> Maybe Tool -> IO ()
runManForTopic Tool
tool Maybe Tool
mtopic =
Tool -> (Tool -> Handle -> IO ()) -> IO ()
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Tool -> (Tool -> Handle -> m a) -> m a
withSystemTempFile (Tool
"hledger-"Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++Tool
toolTool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++Tool
".nroff") ((Tool -> Handle -> IO ()) -> IO ())
-> (Tool -> Handle -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Tool
f Handle
h -> do
Handle -> ByteString -> IO ()
BC.hPutStrLn Handle
h (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$ Tool -> ByteString
toolDocMan Tool
tool
Handle -> IO ()
hClose Handle
h
Tool -> IO ()
callCommand (Tool -> IO ()) -> Tool -> IO ()
forall a b. (a -> b) -> a -> b
$ Tool -> Tool -> Tool
forall a. Show a => Tool -> a -> a
dbg1 Tool
"man command" (Tool -> Tool) -> Tool -> Tool
forall a b. (a -> b) -> a -> b
$
Tool
"man " Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++ Tool
f Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++ Tool -> (Tool -> Tool) -> Maybe Tool -> Tool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Tool
"" (Tool -> Tool -> Tool
forall r. PrintfType r => Tool -> r
printf Tool
" -P \"less -is +'/^( )?%s'\"") Maybe Tool
mtopic
runInfoForTopic :: Tool -> Maybe Topic -> IO ()
runInfoForTopic :: Tool -> Maybe Tool -> IO ()
runInfoForTopic Tool
tool Maybe Tool
mtopic =
Tool -> (Tool -> Handle -> IO ()) -> IO ()
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Tool -> (Tool -> Handle -> m a) -> m a
withSystemTempFile (Tool
"hledger-"Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++Tool
toolTool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++Tool
".info") ((Tool -> Handle -> IO ()) -> IO ())
-> (Tool -> Handle -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Tool
f Handle
h -> do
Handle -> ByteString -> IO ()
BC.hPutStrLn Handle
h (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$ Tool -> ByteString
toolDocInfo Tool
tool
Handle -> IO ()
hClose Handle
h
Tool -> IO ()
callCommand (Tool -> IO ()) -> Tool -> IO ()
forall a b. (a -> b) -> a -> b
$ Tool -> Tool -> Tool
forall a. Show a => Tool -> a -> a
dbg1 Tool
"info command" (Tool -> Tool) -> Tool -> Tool
forall a b. (a -> b) -> a -> b
$
Tool
"info -f " Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++ Tool
f Tool -> Tool -> Tool
forall a. [a] -> [a] -> [a]
++ Tool -> (Tool -> Tool) -> Maybe Tool -> Tool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Tool
"" (Tool -> Tool -> Tool
forall r. PrintfType r => Tool -> r
printf Tool
" -n '%s'") Maybe Tool
mtopic