-- |
--
-- Module      : Ronn.Render
-- Copyright   : (c) 2024 Patrick Brisbin
-- License     : AGPL-3
-- Maintainer  : pbrisbin@gmail.com
-- Stability   : experimental
-- Portability : POSIX
module Ronn.Render
  ( ronnToText
  , ronnToDoc
  ) where

import Prelude

import Data.Text (Text)
import Prettyprinter
import Prettyprinter.Render.Text (renderStrict)
import Ronn.AST

ronnToText :: Ronn -> Text
ronnToText :: Ronn -> Text
ronnToText = SimpleDocStream Any -> Text
forall ann. SimpleDocStream ann -> Text
renderStrict (SimpleDocStream Any -> Text)
-> (Ronn -> SimpleDocStream Any) -> Ronn -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LayoutOptions -> Doc Any -> SimpleDocStream Any
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutPretty LayoutOptions
defaultLayoutOptions (Doc Any -> SimpleDocStream Any)
-> (Ronn -> Doc Any) -> Ronn -> SimpleDocStream Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ronn -> Doc Any
forall ann. Ronn -> Doc ann
ronnToDoc

ronnToDoc :: Ronn -> Doc ann
ronnToDoc :: forall ann. Ronn -> Doc ann
ronnToDoc Ronn
ronn =
  (Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Doc ann
forall ann. Doc ann
hardline) -- ensure doc ends in final newline
    (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vsep
    ([Doc ann] -> Doc ann) -> [Doc ann] -> Doc ann
forall a b. (a -> b) -> a -> b
$ Doc ann -> [Doc ann] -> [Doc ann]
forall ann. Doc ann -> [Doc ann] -> [Doc ann]
punctuate Doc ann
forall ann. Doc ann
hardline
    ([Doc ann] -> [Doc ann]) -> [Doc ann] -> [Doc ann]
forall a b. (a -> b) -> a -> b
$ Ronn -> Doc ann
forall ann. Ronn -> Doc ann
prettyTitle Ronn
ronn
      Doc ann -> [Doc ann] -> [Doc ann]
forall a. a -> [a] -> [a]
: (Section -> Doc ann) -> [Section] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map Section -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Section -> Doc ann
pretty Ronn
ronn.sections

prettyTitle :: Ronn -> Doc ann
prettyTitle :: forall ann. Ronn -> Doc ann
prettyTitle Ronn
ronn =
  Char -> Doc ann -> Doc ann
forall ann. Char -> Doc ann -> Doc ann
underline Char
'='
    (Doc ann -> Doc ann) -> Doc ann -> Doc ann
forall a b. (a -> b) -> a -> b
$ ManRef -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. ManRef -> Doc ann
pretty Ronn
ronn.name Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Doc ann
"--" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
hsep ((Part -> Doc ann) -> [Part] -> [Doc ann]
forall a b. (a -> b) -> [a] -> [b]
map Part -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Part -> Doc ann
pretty Ronn
ronn.description)

underline :: Char -> Doc ann -> Doc ann
underline :: forall ann. Char -> Doc ann -> Doc ann
underline Char
c Doc ann
x = Doc ann -> (Int -> Doc ann) -> Doc ann
forall ann. Doc ann -> (Int -> Doc ann) -> Doc ann
width Doc ann
x ((Int -> Doc ann) -> Doc ann) -> (Int -> Doc ann) -> Doc ann
forall a b. (a -> b) -> a -> b
$ \Int
w -> Doc ann
forall ann. Doc ann
hardline Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> [Char] -> Doc ann
forall ann. [Char] -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (Int -> Char -> [Char]
forall a. Int -> a -> [a]
replicate Int
w Char
c)