module DataFlow.PrettyRenderer where
import Control.Monad.State
import Control.Monad.Writer
type Indent = Int
type IndentNext = Bool
data RendererState = RendererState Indent IndentNext
type Renderer t = WriterT [String] (State RendererState) t
write :: String -> Renderer ()
write s = do
(RendererState n indentNext) <- lift get
if indentNext
then tell [replicate n ' ' ++ s]
else tell [s]
put $ RendererState n False
writeln :: String -> Renderer ()
writeln s = do
write s
write "\n"
modify $ \(RendererState n _) -> RendererState n True
indent :: Renderer ()
indent = modify $ \(RendererState n indentNext) -> RendererState (n + 2) indentNext
dedent :: Renderer ()
dedent = modify $ \(RendererState n indentNext) -> RendererState (n 2) indentNext
withIndent :: Renderer () -> Renderer ()
withIndent gen = do
indent
gen
dedent
renderWithIndent :: Renderer () -> String
renderWithIndent r =
concat $ evalState (execWriterT r) (RendererState 0 False)