ansiform-0.7.8.5: src/Ansiform/Internal/Render.hs
-- | Capture page, section and printer output as a string.
module Ansiform.Internal.Render (renderPage, renderSection, renderPrinter) where
--------------------------------------------------------------------------------
import Control.Exception (bracket)
import System.Directory (getTemporaryDirectory, removeFile)
import System.IO (Handle, hClose, hFlush, openTempFile)
import Ansiform.Internal.Page
import Ansiform.Internal.Printer
import Ansiform.Internal.Section
import Ansiform.Internal.Settings
-- Rendering
--------------------------------------------------------------------------------
-- | Renders a page and returns the captured output.
renderPage :: Page -> Settings -> IO String
renderPage p s = snd <$> captureOutput (\h -> renderWithConfig h)
where
renderWithConfig h = do
cfg <- runSettingsOn h s
runPageIOOn h (return cfg) p
-- | Renders a section and returns the captured output.
renderSection :: Section -> Settings -> IO String
renderSection sec s = snd <$> captureOutput (\h -> renderWithConfig h)
where
renderWithConfig h = do
cfg <- runSettingsOn h s
runSectionIOOn h (return cfg) sec
-- | Renders a single printer and returns the captured output.
renderPrinter :: Printer -> Settings -> IO String
renderPrinter pr s = snd <$> captureOutput (\h -> renderWithConfig h)
where
renderWithConfig h = do
cfg <- runSettingsOn h s
runPrinterIOOn h (return cfg) pr
-- Support Functions
--------------------------------------------------------------------------------
-- Runs an action against a temporary output handle and returns its content.
captureOutput :: (Handle -> IO a) -> IO (a, String)
captureOutput action = do
tmp <- getTemporaryDirectory
bracket (openTempFile tmp "ansiform-render") cleanup $ \(path, h) -> do
result <- action h
hFlush h
hClose h
output <- readFile path
length output `seq` return (result, output)
where
cleanup (path, h) = do
hClose h
removeFile path