-- Copyright 2017 Evan Laforge
-- This program is distributed under the terms of the GNU General Public
-- License 3.0, see COPYING or http://www.gnu.org/licenses/gpl-3.0.txt

-- | Utilities for the 'Doc' type.
module Util.Doc (
    Doc(..), pretty, literal, commas
) where
import qualified Data.String as String
import           Data.Text (Text)

import qualified Util.Pretty as Pretty
import qualified Util.Serialize as Serialize
import qualified Util.Texts as Texts


-- | This is for documentation text.  It can contain some simple markdown-like
-- formatting, which may be either be printed directly, or formatted via
-- 'html_doc'.
newtype Doc = Doc Text
    deriving (Doc -> Doc -> Bool
(Doc -> Doc -> Bool) -> (Doc -> Doc -> Bool) -> Eq Doc
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Doc -> Doc -> Bool
$c/= :: Doc -> Doc -> Bool
== :: Doc -> Doc -> Bool
$c== :: Doc -> Doc -> Bool
Eq, Eq Doc
Eq Doc
-> (Doc -> Doc -> Ordering)
-> (Doc -> Doc -> Bool)
-> (Doc -> Doc -> Bool)
-> (Doc -> Doc -> Bool)
-> (Doc -> Doc -> Bool)
-> (Doc -> Doc -> Doc)
-> (Doc -> Doc -> Doc)
-> Ord Doc
Doc -> Doc -> Bool
Doc -> Doc -> Ordering
Doc -> Doc -> Doc
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Doc -> Doc -> Doc
$cmin :: Doc -> Doc -> Doc
max :: Doc -> Doc -> Doc
$cmax :: Doc -> Doc -> Doc
>= :: Doc -> Doc -> Bool
$c>= :: Doc -> Doc -> Bool
> :: Doc -> Doc -> Bool
$c> :: Doc -> Doc -> Bool
<= :: Doc -> Doc -> Bool
$c<= :: Doc -> Doc -> Bool
< :: Doc -> Doc -> Bool
$c< :: Doc -> Doc -> Bool
compare :: Doc -> Doc -> Ordering
$ccompare :: Doc -> Doc -> Ordering
Ord, Int -> Doc -> ShowS
[Doc] -> ShowS
Doc -> String
(Int -> Doc -> ShowS)
-> (Doc -> String) -> ([Doc] -> ShowS) -> Show Doc
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Doc] -> ShowS
$cshowList :: [Doc] -> ShowS
show :: Doc -> String
$cshow :: Doc -> String
showsPrec :: Int -> Doc -> ShowS
$cshowsPrec :: Int -> Doc -> ShowS
Show, [Doc] -> Doc
Doc -> Text
Doc -> Doc
(Doc -> Text) -> (Doc -> Doc) -> ([Doc] -> Doc) -> Pretty Doc
forall a. (a -> Text) -> (a -> Doc) -> ([a] -> Doc) -> Pretty a
formatList :: [Doc] -> Doc
$cformatList :: [Doc] -> Doc
format :: Doc -> Doc
$cformat :: Doc -> Doc
pretty :: Doc -> Text
$cpretty :: Doc -> Text
Pretty.Pretty, NonEmpty Doc -> Doc
Doc -> Doc -> Doc
(Doc -> Doc -> Doc)
-> (NonEmpty Doc -> Doc)
-> (forall b. Integral b => b -> Doc -> Doc)
-> Semigroup Doc
forall b. Integral b => b -> Doc -> Doc
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> Doc -> Doc
$cstimes :: forall b. Integral b => b -> Doc -> Doc
sconcat :: NonEmpty Doc -> Doc
$csconcat :: NonEmpty Doc -> Doc
<> :: Doc -> Doc -> Doc
$c<> :: Doc -> Doc -> Doc
Semigroup, Semigroup Doc
Doc
Semigroup Doc
-> Doc -> (Doc -> Doc -> Doc) -> ([Doc] -> Doc) -> Monoid Doc
[Doc] -> Doc
Doc -> Doc -> Doc
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [Doc] -> Doc
$cmconcat :: [Doc] -> Doc
mappend :: Doc -> Doc -> Doc
$cmappend :: Doc -> Doc -> Doc
mempty :: Doc
$cmempty :: Doc
Monoid, String -> Doc
(String -> Doc) -> IsString Doc
forall a. (String -> a) -> IsString a
fromString :: String -> Doc
$cfromString :: String -> Doc
String.IsString,
        Get Doc
Putter Doc
Putter Doc -> Get Doc -> Serialize Doc
forall a. Putter a -> Get a -> Serialize a
get :: Get Doc
$cget :: Get Doc
put :: Putter Doc
$cput :: Putter Doc
Serialize.Serialize)

instance Texts.Textlike Doc where
    toText :: Doc -> Text
toText (Doc Text
t) = Text
t
    fromText :: Text -> Doc
fromText = Text -> Doc
Doc

-- | This probably doesn't belong here, but it's useful in the same contexts as
-- 'Doc'.
pretty :: Pretty.Pretty a => a -> Doc
pretty :: forall a. Pretty a => a -> Doc
pretty = Text -> Doc
literal (Text -> Doc) -> (a -> Text) -> a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
forall a. Pretty a => a -> Text
Pretty.pretty

literal :: Text -> Doc
literal :: Text -> Doc
literal Text
text = Text -> Doc
Doc (Text -> Doc) -> Text -> Doc
forall a b. (a -> b) -> a -> b
$ Text
"`" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
text Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"`"

commas :: [Doc] -> Doc
commas :: [Doc] -> Doc
commas = Doc -> [Doc] -> Doc
forall a. Textlike a => a -> [a] -> a
Texts.join Doc
", "