{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE StandaloneDeriving #-}

module Language.Lsd.AST.Format
    ( FormatString (..)
    , FormatAtom (..)
    , IdentifierFormat
    , EnumStyle (..)
    , HeadingFormat (..)
    , HeadingPlaceholderAtom (..)
    , MainHeadingFormat
    , InnerHeadingFormat
    , KeyFormat
    , KeyPlaceholderAtom (..)
    , TocKeyFormat (..)
    , EnumItemKeyFormat (..)
    , ParagraphKeyFormat (..)
    )
where

import Data.Typography (Typography)

newtype FormatString a = FormatString [FormatAtom a]
    deriving (Int -> FormatString a -> ShowS
[FormatString a] -> ShowS
FormatString a -> String
(Int -> FormatString a -> ShowS)
-> (FormatString a -> String)
-> ([FormatString a] -> ShowS)
-> Show (FormatString a)
forall a. Show a => Int -> FormatString a -> ShowS
forall a. Show a => [FormatString a] -> ShowS
forall a. Show a => FormatString a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> FormatString a -> ShowS
showsPrec :: Int -> FormatString a -> ShowS
$cshow :: forall a. Show a => FormatString a -> String
show :: FormatString a -> String
$cshowList :: forall a. Show a => [FormatString a] -> ShowS
showList :: [FormatString a] -> ShowS
Show, FormatString a -> FormatString a -> Bool
(FormatString a -> FormatString a -> Bool)
-> (FormatString a -> FormatString a -> Bool)
-> Eq (FormatString a)
forall a. Eq a => FormatString a -> FormatString a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => FormatString a -> FormatString a -> Bool
== :: FormatString a -> FormatString a -> Bool
$c/= :: forall a. Eq a => FormatString a -> FormatString a -> Bool
/= :: FormatString a -> FormatString a -> Bool
Eq)

data FormatAtom a
    = StringAtom String
    | PlaceholderAtom a
    | InsertedPlaceholderAtom a
    deriving (Int -> FormatAtom a -> ShowS
[FormatAtom a] -> ShowS
FormatAtom a -> String
(Int -> FormatAtom a -> ShowS)
-> (FormatAtom a -> String)
-> ([FormatAtom a] -> ShowS)
-> Show (FormatAtom a)
forall a. Show a => Int -> FormatAtom a -> ShowS
forall a. Show a => [FormatAtom a] -> ShowS
forall a. Show a => FormatAtom a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> FormatAtom a -> ShowS
showsPrec :: Int -> FormatAtom a -> ShowS
$cshow :: forall a. Show a => FormatAtom a -> String
show :: FormatAtom a -> String
$cshowList :: forall a. Show a => [FormatAtom a] -> ShowS
showList :: [FormatAtom a] -> ShowS
Show, FormatAtom a -> FormatAtom a -> Bool
(FormatAtom a -> FormatAtom a -> Bool)
-> (FormatAtom a -> FormatAtom a -> Bool) -> Eq (FormatAtom a)
forall a. Eq a => FormatAtom a -> FormatAtom a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => FormatAtom a -> FormatAtom a -> Bool
== :: FormatAtom a -> FormatAtom a -> Bool
$c/= :: forall a. Eq a => FormatAtom a -> FormatAtom a -> Bool
/= :: FormatAtom a -> FormatAtom a -> Bool
Eq)

type IdentifierFormat = FormatString EnumStyle

data EnumStyle
    = Arabic
    | AlphabeticLower
    | AlphabeticUpper
    deriving (Int -> EnumStyle -> ShowS
[EnumStyle] -> ShowS
EnumStyle -> String
(Int -> EnumStyle -> ShowS)
-> (EnumStyle -> String)
-> ([EnumStyle] -> ShowS)
-> Show EnumStyle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EnumStyle -> ShowS
showsPrec :: Int -> EnumStyle -> ShowS
$cshow :: EnumStyle -> String
show :: EnumStyle -> String
$cshowList :: [EnumStyle] -> ShowS
showList :: [EnumStyle] -> ShowS
Show, EnumStyle -> EnumStyle -> Bool
(EnumStyle -> EnumStyle -> Bool)
-> (EnumStyle -> EnumStyle -> Bool) -> Eq EnumStyle
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EnumStyle -> EnumStyle -> Bool
== :: EnumStyle -> EnumStyle -> Bool
$c/= :: EnumStyle -> EnumStyle -> Bool
/= :: EnumStyle -> EnumStyle -> Bool
Eq)

-- | The format of a heading.  The boolean type parameter determines whether
--   an identifier (placeholder) is permitted in the heading (format).
data HeadingFormat (permitIdentifier :: Bool)
    = HeadingFormat
        Typography
        (FormatString (HeadingPlaceholderAtom permitIdentifier))
    deriving (Int -> HeadingFormat permitIdentifier -> ShowS
[HeadingFormat permitIdentifier] -> ShowS
HeadingFormat permitIdentifier -> String
(Int -> HeadingFormat permitIdentifier -> ShowS)
-> (HeadingFormat permitIdentifier -> String)
-> ([HeadingFormat permitIdentifier] -> ShowS)
-> Show (HeadingFormat permitIdentifier)
forall (permitIdentifier :: Bool).
Int -> HeadingFormat permitIdentifier -> ShowS
forall (permitIdentifier :: Bool).
[HeadingFormat permitIdentifier] -> ShowS
forall (permitIdentifier :: Bool).
HeadingFormat permitIdentifier -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall (permitIdentifier :: Bool).
Int -> HeadingFormat permitIdentifier -> ShowS
showsPrec :: Int -> HeadingFormat permitIdentifier -> ShowS
$cshow :: forall (permitIdentifier :: Bool).
HeadingFormat permitIdentifier -> String
show :: HeadingFormat permitIdentifier -> String
$cshowList :: forall (permitIdentifier :: Bool).
[HeadingFormat permitIdentifier] -> ShowS
showList :: [HeadingFormat permitIdentifier] -> ShowS
Show)

data HeadingPlaceholderAtom (permitIdentifier :: Bool) where
    IdentifierPlaceholder :: HeadingPlaceholderAtom 'True
    HeadingTextPlaceholder :: HeadingPlaceholderAtom permitIdentifier

deriving instance Show (HeadingPlaceholderAtom a)

-- | Heading format without identifier placeholders.
type MainHeadingFormat = HeadingFormat 'False

-- | Heading format with identifier placeholders.
type InnerHeadingFormat = HeadingFormat 'True

type KeyFormat = FormatString KeyPlaceholderAtom

data KeyPlaceholderAtom = KeyIdentifierPlaceholder
    deriving (Int -> KeyPlaceholderAtom -> ShowS
[KeyPlaceholderAtom] -> ShowS
KeyPlaceholderAtom -> String
(Int -> KeyPlaceholderAtom -> ShowS)
-> (KeyPlaceholderAtom -> String)
-> ([KeyPlaceholderAtom] -> ShowS)
-> Show KeyPlaceholderAtom
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyPlaceholderAtom -> ShowS
showsPrec :: Int -> KeyPlaceholderAtom -> ShowS
$cshow :: KeyPlaceholderAtom -> String
show :: KeyPlaceholderAtom -> String
$cshowList :: [KeyPlaceholderAtom] -> ShowS
showList :: [KeyPlaceholderAtom] -> ShowS
Show, KeyPlaceholderAtom -> KeyPlaceholderAtom -> Bool
(KeyPlaceholderAtom -> KeyPlaceholderAtom -> Bool)
-> (KeyPlaceholderAtom -> KeyPlaceholderAtom -> Bool)
-> Eq KeyPlaceholderAtom
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: KeyPlaceholderAtom -> KeyPlaceholderAtom -> Bool
== :: KeyPlaceholderAtom -> KeyPlaceholderAtom -> Bool
$c/= :: KeyPlaceholderAtom -> KeyPlaceholderAtom -> Bool
/= :: KeyPlaceholderAtom -> KeyPlaceholderAtom -> Bool
Eq)

newtype TocKeyFormat = TocKeyFormat KeyFormat
    deriving (Int -> TocKeyFormat -> ShowS
[TocKeyFormat] -> ShowS
TocKeyFormat -> String
(Int -> TocKeyFormat -> ShowS)
-> (TocKeyFormat -> String)
-> ([TocKeyFormat] -> ShowS)
-> Show TocKeyFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TocKeyFormat -> ShowS
showsPrec :: Int -> TocKeyFormat -> ShowS
$cshow :: TocKeyFormat -> String
show :: TocKeyFormat -> String
$cshowList :: [TocKeyFormat] -> ShowS
showList :: [TocKeyFormat] -> ShowS
Show)

newtype EnumItemKeyFormat = EnumItemKeyFormat KeyFormat
    deriving (Int -> EnumItemKeyFormat -> ShowS
[EnumItemKeyFormat] -> ShowS
EnumItemKeyFormat -> String
(Int -> EnumItemKeyFormat -> ShowS)
-> (EnumItemKeyFormat -> String)
-> ([EnumItemKeyFormat] -> ShowS)
-> Show EnumItemKeyFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EnumItemKeyFormat -> ShowS
showsPrec :: Int -> EnumItemKeyFormat -> ShowS
$cshow :: EnumItemKeyFormat -> String
show :: EnumItemKeyFormat -> String
$cshowList :: [EnumItemKeyFormat] -> ShowS
showList :: [EnumItemKeyFormat] -> ShowS
Show, EnumItemKeyFormat -> EnumItemKeyFormat -> Bool
(EnumItemKeyFormat -> EnumItemKeyFormat -> Bool)
-> (EnumItemKeyFormat -> EnumItemKeyFormat -> Bool)
-> Eq EnumItemKeyFormat
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EnumItemKeyFormat -> EnumItemKeyFormat -> Bool
== :: EnumItemKeyFormat -> EnumItemKeyFormat -> Bool
$c/= :: EnumItemKeyFormat -> EnumItemKeyFormat -> Bool
/= :: EnumItemKeyFormat -> EnumItemKeyFormat -> Bool
Eq)

newtype ParagraphKeyFormat = ParagraphKeyFormat KeyFormat
    deriving (Int -> ParagraphKeyFormat -> ShowS
[ParagraphKeyFormat] -> ShowS
ParagraphKeyFormat -> String
(Int -> ParagraphKeyFormat -> ShowS)
-> (ParagraphKeyFormat -> String)
-> ([ParagraphKeyFormat] -> ShowS)
-> Show ParagraphKeyFormat
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ParagraphKeyFormat -> ShowS
showsPrec :: Int -> ParagraphKeyFormat -> ShowS
$cshow :: ParagraphKeyFormat -> String
show :: ParagraphKeyFormat -> String
$cshowList :: [ParagraphKeyFormat] -> ShowS
showList :: [ParagraphKeyFormat] -> ShowS
Show)