{-|
Module      : Prosidy.Types
Description : A convenience module which reëxports type definitions & helpers. 
Copyright   : ©2020 James Alexander Feldman-Crough
License     : MPL-2.0
Maintainer  : alex@fldcr.com
-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UndecidableInstances #-}
module Prosidy.Types
    ( -- * Documents
      Document(..)
    , documentToRegion
    , regionToDocument
      -- * Tags
    , Tag(..)
    , BlockTag
    , InlineTag
    , LiteralTag
    , tagToRegion
    , regionToTag
      -- * Contextual enumerations
    , Block(..)
    , Inline(..)
      -- * Paragraphs
    , Paragraph(..)
      -- * Common structures
    , Metadata(..)
    , Region(..)
      -- * Textual fragments
    , Fragment(..)
      -- * Utility wrappers
    , module X
    )
where

import           Prosidy.Types.Assoc           as X
                                                ( Assoc(..) )
import           Prosidy.Types.Key             as X
                                                ( Key
                                                , KeyError(..)
                                                , InvalidCharacter
                                                , makeKey
                                                , rawKey
                                                )
import           Prosidy.Types.Series          as X
                                                ( Series(..)
                                                , SeriesNE
                                                )
import           Prosidy.Types.Set             as X
                                                ( Set(..) )
import           Prosidy.Source                 ( Location )

import           Data.Text                      ( Text )
import           GHC.Generics                   ( Generic )
import           Control.DeepSeq                ( NFData )
import           Data.Binary                    ( Binary )
import           Data.Hashable                  ( Hashable )
import           Data.Aeson                     ( ToJSON(..)
                                                , FromJSON(..)
                                                , withObject
                                                , withText
                                                , (.:)
                                                , (.=)
                                                , object
                                                , pairs
                                                )

import qualified Data.Aeson                    as Aeson

-------------------------------------------------------------------------------
-- | A sum type enumerating allowed types inside of a block context.
data Block =
    BlockLiteral LiteralTag
  | BlockParagraph Paragraph
  | BlockTag BlockTag
  deriving stock (Block -> Block -> Bool
(Block -> Block -> Bool) -> (Block -> Block -> Bool) -> Eq Block
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Block -> Block -> Bool
$c/= :: Block -> Block -> Bool
== :: Block -> Block -> Bool
$c== :: Block -> Block -> Bool
Eq, Int -> Block -> ShowS
[Block] -> ShowS
Block -> String
(Int -> Block -> ShowS)
-> (Block -> String) -> ([Block] -> ShowS) -> Show Block
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Block] -> ShowS
$cshowList :: [Block] -> ShowS
show :: Block -> String
$cshow :: Block -> String
showsPrec :: Int -> Block -> ShowS
$cshowsPrec :: Int -> Block -> ShowS
Show, (forall x. Block -> Rep Block x)
-> (forall x. Rep Block x -> Block) -> Generic Block
forall x. Rep Block x -> Block
forall x. Block -> Rep Block x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Block x -> Block
$cfrom :: forall x. Block -> Rep Block x
Generic)
  deriving anyclass (Int -> Block -> Int
Block -> Int
(Int -> Block -> Int) -> (Block -> Int) -> Hashable Block
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Block -> Int
$chash :: Block -> Int
hashWithSalt :: Int -> Block -> Int
$chashWithSalt :: Int -> Block -> Int
Hashable, Get Block
[Block] -> Put
Block -> Put
(Block -> Put) -> Get Block -> ([Block] -> Put) -> Binary Block
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [Block] -> Put
$cputList :: [Block] -> Put
get :: Get Block
$cget :: Get Block
put :: Block -> Put
$cput :: Block -> Put
Binary, Block -> ()
(Block -> ()) -> NFData Block
forall a. (a -> ()) -> NFData a
rnf :: Block -> ()
$crnf :: Block -> ()
NFData)

instance FromJSON Block where
    parseJSON :: Value -> Parser Block
parseJSON = String -> (Object -> Parser Block) -> Value -> Parser Block
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject "block" ((Object -> Parser Block) -> Value -> Parser Block)
-> (Object -> Parser Block) -> Value -> Parser Block
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
        Text
ty <- Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: "type"
        case Text
ty :: Text of
            "tag" -> do
                Text
subtype <- Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: "subtype"
                case Text
subtype :: Text of
                    "block"   -> BlockTag -> Block
BlockTag (BlockTag -> Block) -> Parser BlockTag -> Parser Block
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser BlockTag
forall a. FromJSON a => Object -> Text -> Parser a
.: "value"
                    "literal" -> LiteralTag -> Block
BlockLiteral (LiteralTag -> Block) -> Parser LiteralTag -> Parser Block
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser LiteralTag
forall a. FromJSON a => Object -> Text -> Parser a
.: "value"
                    _         -> String -> Parser Block
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Block) -> String -> Parser Block
forall a b. (a -> b) -> a -> b
$ "unknown tag subtype: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a. Show a => a -> String
show Text
subtype
            "paragraph" -> Paragraph -> Block
BlockParagraph (Paragraph -> Block) -> Parser Paragraph -> Parser Block
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser Paragraph
forall a. FromJSON a => Object -> Text -> Parser a
.: "value"
            _           -> String -> Parser Block
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Block) -> String -> Parser Block
forall a b. (a -> b) -> a -> b
$ "unknown block type: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a. Show a => a -> String
show Text
ty

instance ToJSON Block where
    toEncoding :: Block -> Encoding
toEncoding b :: Block
b = Series -> Encoding
pairs (Series -> Encoding)
-> ([Series] -> Series) -> [Series] -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Series] -> Series
forall a. Monoid a => [a] -> a
mconcat ([Series] -> Encoding) -> [Series] -> Encoding
forall a b. (a -> b) -> a -> b
$ case Block
b of
        BlockLiteral t :: LiteralTag
t ->
            [ "type" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("tag" :: Text)
            , "subtype" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("literal" :: Text)
            , "value" Text -> LiteralTag -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= LiteralTag
t
            ]
        BlockParagraph p :: Paragraph
p -> ["type" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("paragraph" :: Text), "value" Text -> Paragraph -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Paragraph
p]
        BlockTag t :: BlockTag
t ->
            [ "type" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("tag" :: Text)
            , "subtype" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("block" :: Text)
            , "value" Text -> BlockTag -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockTag
t
            ]

    toJSON :: Block -> Value
toJSON b :: Block
b = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ case Block
b of
        BlockLiteral t :: LiteralTag
t ->
            [ "type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("tag" :: Text)
            , "subtype" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("literal" :: Text)
            , "value" Text -> LiteralTag -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= LiteralTag
t
            ]
        BlockParagraph p :: Paragraph
p -> ["type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("paragraph" :: Text), "value" Text -> Paragraph -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Paragraph
p]
        BlockTag t :: BlockTag
t ->
            [ "type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("tag" :: Text)
            , "subtype" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("block" :: Text)
            , "value" Text -> BlockTag -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= BlockTag
t
            ]

-------------------------------------------------------------------------------
-- | A full Prosidy document.
data Document = Document
    { Document -> Metadata
documentMetadata :: Metadata
    , Document -> Series Block
documentContent  :: Series Block
    }
  deriving stock (Document -> Document -> Bool
(Document -> Document -> Bool)
-> (Document -> Document -> Bool) -> Eq Document
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Document -> Document -> Bool
$c/= :: Document -> Document -> Bool
== :: Document -> Document -> Bool
$c== :: Document -> Document -> Bool
Eq, Int -> Document -> ShowS
[Document] -> ShowS
Document -> String
(Int -> Document -> ShowS)
-> (Document -> String) -> ([Document] -> ShowS) -> Show Document
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Document] -> ShowS
$cshowList :: [Document] -> ShowS
show :: Document -> String
$cshow :: Document -> String
showsPrec :: Int -> Document -> ShowS
$cshowsPrec :: Int -> Document -> ShowS
Show, (forall x. Document -> Rep Document x)
-> (forall x. Rep Document x -> Document) -> Generic Document
forall x. Rep Document x -> Document
forall x. Document -> Rep Document x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Document x -> Document
$cfrom :: forall x. Document -> Rep Document x
Generic)
  deriving anyclass (Int -> Document -> Int
Document -> Int
(Int -> Document -> Int) -> (Document -> Int) -> Hashable Document
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Document -> Int
$chash :: Document -> Int
hashWithSalt :: Int -> Document -> Int
$chashWithSalt :: Int -> Document -> Int
Hashable, Document -> ()
(Document -> ()) -> NFData Document
forall a. (a -> ()) -> NFData a
rnf :: Document -> ()
$crnf :: Document -> ()
NFData, Get Document
[Document] -> Put
Document -> Put
(Document -> Put)
-> Get Document -> ([Document] -> Put) -> Binary Document
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [Document] -> Put
$cputList :: [Document] -> Put
get :: Get Document
$cget :: Get Document
put :: Document -> Put
$cput :: Document -> Put
Binary)

instance FromJSON Document where
    parseJSON :: Value -> Parser Document
parseJSON = String -> (Object -> Parser Document) -> Value -> Parser Document
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject "Document"
        ((Object -> Parser Document) -> Value -> Parser Document)
-> (Object -> Parser Document) -> Value -> Parser Document
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> Metadata -> Series Block -> Document
Document (Metadata -> Series Block -> Document)
-> Parser Metadata -> Parser (Series Block -> Document)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser Metadata
forall a. FromJSON a => Object -> Text -> Parser a
.: "metadata" Parser (Series Block -> Document)
-> Parser (Series Block) -> Parser Document
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser (Series Block)
forall a. FromJSON a => Object -> Text -> Parser a
.: "content"

instance ToJSON Document where
    toEncoding :: Document -> Encoding
toEncoding (Document md :: Metadata
md ct :: Series Block
ct) =
        Series -> Encoding
pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$ [Series] -> Series
forall a. Monoid a => [a] -> a
mconcat ["metadata" Text -> Metadata -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Metadata
md, "content" Text -> Series Block -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Series Block
ct]

    toJSON :: Document -> Value
toJSON (Document md :: Metadata
md ct :: Series Block
ct) = [Pair] -> Value
object ["metadata" Text -> Metadata -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Metadata
md, "content" Text -> Series Block -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Series Block
ct]

-- | Convert a 'Document' to a 'Region'. The resulting 'Region' will never have
-- a 'Location' attached. 
documentToRegion :: Document -> Region (Series Block)
documentToRegion :: Document -> Region (Series Block)
documentToRegion (Document md :: Metadata
md ct :: Series Block
ct) = Metadata -> Series Block -> Maybe Location -> Region (Series Block)
forall a. Metadata -> a -> Maybe Location -> Region a
Region Metadata
md Series Block
ct Maybe Location
forall a. Maybe a
Nothing

-- | Convert a 'Region' to a 'Document'. Any 'Location' on the 'Region' will be
-- discarded.
regionToDocument :: Region (Series Block) -> Document
regionToDocument :: Region (Series Block) -> Document
regionToDocument (Region md :: Metadata
md ct :: Series Block
ct _) = Metadata -> Series Block -> Document
Document Metadata
md Series Block
ct

-------------------------------------------------------------------------------
-- | Plain text, possibly annotated with a 'Location'.
data Fragment = Fragment
  { Fragment -> Text
fragmentText     :: Text
    -- ^ Access the underlying 'Text'.
  , Fragment -> Maybe Location
fragmentLocation :: Maybe Location
    -- ^ The location of the 'Text' in the source code.
  }
  deriving stock (Fragment -> Fragment -> Bool
(Fragment -> Fragment -> Bool)
-> (Fragment -> Fragment -> Bool) -> Eq Fragment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Fragment -> Fragment -> Bool
$c/= :: Fragment -> Fragment -> Bool
== :: Fragment -> Fragment -> Bool
$c== :: Fragment -> Fragment -> Bool
Eq, Int -> Fragment -> ShowS
[Fragment] -> ShowS
Fragment -> String
(Int -> Fragment -> ShowS)
-> (Fragment -> String) -> ([Fragment] -> ShowS) -> Show Fragment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Fragment] -> ShowS
$cshowList :: [Fragment] -> ShowS
show :: Fragment -> String
$cshow :: Fragment -> String
showsPrec :: Int -> Fragment -> ShowS
$cshowsPrec :: Int -> Fragment -> ShowS
Show, (forall x. Fragment -> Rep Fragment x)
-> (forall x. Rep Fragment x -> Fragment) -> Generic Fragment
forall x. Rep Fragment x -> Fragment
forall x. Fragment -> Rep Fragment x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Fragment x -> Fragment
$cfrom :: forall x. Fragment -> Rep Fragment x
Generic)
  deriving anyclass (Int -> Fragment -> Int
Fragment -> Int
(Int -> Fragment -> Int) -> (Fragment -> Int) -> Hashable Fragment
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Fragment -> Int
$chash :: Fragment -> Int
hashWithSalt :: Int -> Fragment -> Int
$chashWithSalt :: Int -> Fragment -> Int
Hashable, Get Fragment
[Fragment] -> Put
Fragment -> Put
(Fragment -> Put)
-> Get Fragment -> ([Fragment] -> Put) -> Binary Fragment
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [Fragment] -> Put
$cputList :: [Fragment] -> Put
get :: Get Fragment
$cget :: Get Fragment
put :: Fragment -> Put
$cput :: Fragment -> Put
Binary, Fragment -> ()
(Fragment -> ()) -> NFData Fragment
forall a. (a -> ()) -> NFData a
rnf :: Fragment -> ()
$crnf :: Fragment -> ()
NFData)

instance FromJSON Fragment where
    parseJSON :: Value -> Parser Fragment
parseJSON = String -> (Text -> Parser Fragment) -> Value -> Parser Fragment
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText "Fragment" ((Text -> Parser Fragment) -> Value -> Parser Fragment)
-> (Text -> Parser Fragment) -> Value -> Parser Fragment
forall a b. (a -> b) -> a -> b
$ Fragment -> Parser Fragment
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Fragment -> Parser Fragment)
-> (Text -> Fragment) -> Text -> Parser Fragment
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Maybe Location -> Fragment)
-> Maybe Location -> Text -> Fragment
forall a b c. (a -> b -> c) -> b -> a -> c
flip Text -> Maybe Location -> Fragment
Fragment Maybe Location
forall a. Maybe a
Nothing

instance ToJSON Fragment where
    toEncoding :: Fragment -> Encoding
toEncoding = Text -> Encoding
forall a. ToJSON a => a -> Encoding
toEncoding (Text -> Encoding) -> (Fragment -> Text) -> Fragment -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fragment -> Text
fragmentText
    toJSON :: Fragment -> Value
toJSON     = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value) -> (Fragment -> Text) -> Fragment -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fragment -> Text
fragmentText

-------------------------------------------------------------------------------
-- | A sum type enumerating allowed types inside of an inline context.
data Inline =
    Break
    -- ^ Spacing recorded between lines or on either side of an 'Inline' 'Tag'.
    -- Although we could represent this as 'Text', Prosidy defines a special
    -- node for this case so that authors in CJK languages (or other languages
    -- without explicit spaces between words) may simply ignore these spaces
    -- in their output.
  | InlineTag  InlineTag
    -- ^ A 'Tag' which contains only 'Inline' items. These tags begin with the
    -- @#@ sigil in source.
  | InlineText Fragment
    -- ^ A fragment of plain text.
  deriving stock (Inline -> Inline -> Bool
(Inline -> Inline -> Bool)
-> (Inline -> Inline -> Bool) -> Eq Inline
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Inline -> Inline -> Bool
$c/= :: Inline -> Inline -> Bool
== :: Inline -> Inline -> Bool
$c== :: Inline -> Inline -> Bool
Eq, Int -> Inline -> ShowS
[Inline] -> ShowS
Inline -> String
(Int -> Inline -> ShowS)
-> (Inline -> String) -> ([Inline] -> ShowS) -> Show Inline
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Inline] -> ShowS
$cshowList :: [Inline] -> ShowS
show :: Inline -> String
$cshow :: Inline -> String
showsPrec :: Int -> Inline -> ShowS
$cshowsPrec :: Int -> Inline -> ShowS
Show, (forall x. Inline -> Rep Inline x)
-> (forall x. Rep Inline x -> Inline) -> Generic Inline
forall x. Rep Inline x -> Inline
forall x. Inline -> Rep Inline x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Inline x -> Inline
$cfrom :: forall x. Inline -> Rep Inline x
Generic)
  deriving anyclass (Int -> Inline -> Int
Inline -> Int
(Int -> Inline -> Int) -> (Inline -> Int) -> Hashable Inline
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Inline -> Int
$chash :: Inline -> Int
hashWithSalt :: Int -> Inline -> Int
$chashWithSalt :: Int -> Inline -> Int
Hashable, Get Inline
[Inline] -> Put
Inline -> Put
(Inline -> Put) -> Get Inline -> ([Inline] -> Put) -> Binary Inline
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [Inline] -> Put
$cputList :: [Inline] -> Put
get :: Get Inline
$cget :: Get Inline
put :: Inline -> Put
$cput :: Inline -> Put
Binary, Inline -> ()
(Inline -> ()) -> NFData Inline
forall a. (a -> ()) -> NFData a
rnf :: Inline -> ()
$crnf :: Inline -> ()
NFData)

instance FromJSON Inline where
    parseJSON :: Value -> Parser Inline
parseJSON = String -> (Object -> Parser Inline) -> Value -> Parser Inline
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject "Inline" ((Object -> Parser Inline) -> Value -> Parser Inline)
-> (Object -> Parser Inline) -> Value -> Parser Inline
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> do
        Text
ty <- Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: "type"
        case Text
ty :: Text of
            "break" -> Inline -> Parser Inline
forall (f :: * -> *) a. Applicative f => a -> f a
pure Inline
Break
            "tag"   -> InlineTag -> Inline
InlineTag (InlineTag -> Inline) -> Parser InlineTag -> Parser Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser InlineTag
forall a. FromJSON a => Object -> Text -> Parser a
.: "value"
            "text"  -> Fragment -> Inline
InlineText (Fragment -> Inline) -> Parser Fragment -> Parser Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser Fragment
forall a. FromJSON a => Object -> Text -> Parser a
.: "value"
            _       -> String -> Parser Inline
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Inline) -> String -> Parser Inline
forall a b. (a -> b) -> a -> b
$ "unknown inline type: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a. Show a => a -> String
show Text
ty

instance ToJSON Inline where
    toEncoding :: Inline -> Encoding
toEncoding i :: Inline
i = Series -> Encoding
pairs (Series -> Encoding)
-> ([Series] -> Series) -> [Series] -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Series] -> Series
forall a. Monoid a => [a] -> a
mconcat ([Series] -> Encoding) -> [Series] -> Encoding
forall a b. (a -> b) -> a -> b
$ case Inline
i of
        Break -> ["type" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("break" :: Text), "value" Text -> Value -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Aeson.Null]
        InlineTag t :: InlineTag
t ->
            [ "type" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("tag" :: Text)
            , "subtype" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("inline" :: Text)
            , "value" Text -> InlineTag -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= InlineTag
t
            ]
        InlineText t :: Fragment
t -> ["type" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("text" :: Text), "value" Text -> Fragment -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Fragment
t]

    toJSON :: Inline -> Value
toJSON i :: Inline
i = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ case Inline
i of
        Break -> ["type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("break" :: Text)]
        InlineTag t :: InlineTag
t ->
            [ "type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("tag" :: Text)
            , "subtype" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("inline" :: Text)
            , "value" Text -> InlineTag -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= InlineTag
t
            ]
        InlineText t :: Fragment
t -> ["type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ("text" :: Text), "value" Text -> Fragment -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Fragment
t]

-------------------------------------------------------------------------------
-- | A set of properties and settings, associated with a 'Region'. 
--
-- The namespaces of properties and settings are distinct; a property can share
-- a name with a setting without conflict.
data Metadata = Metadata
    { Metadata -> Set Key
metadataProperties :: Set Key
      -- ^ Properties are a set of 'Key's with no associated value.
    , Metadata -> Assoc Key Text
metadataSettings   :: Assoc Key Text
      -- ^ Settings are 'Key's with an attached value.
    }
  deriving stock (Metadata -> Metadata -> Bool
(Metadata -> Metadata -> Bool)
-> (Metadata -> Metadata -> Bool) -> Eq Metadata
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Metadata -> Metadata -> Bool
$c/= :: Metadata -> Metadata -> Bool
== :: Metadata -> Metadata -> Bool
$c== :: Metadata -> Metadata -> Bool
Eq, Int -> Metadata -> ShowS
[Metadata] -> ShowS
Metadata -> String
(Int -> Metadata -> ShowS)
-> (Metadata -> String) -> ([Metadata] -> ShowS) -> Show Metadata
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Metadata] -> ShowS
$cshowList :: [Metadata] -> ShowS
show :: Metadata -> String
$cshow :: Metadata -> String
showsPrec :: Int -> Metadata -> ShowS
$cshowsPrec :: Int -> Metadata -> ShowS
Show, (forall x. Metadata -> Rep Metadata x)
-> (forall x. Rep Metadata x -> Metadata) -> Generic Metadata
forall x. Rep Metadata x -> Metadata
forall x. Metadata -> Rep Metadata x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Metadata x -> Metadata
$cfrom :: forall x. Metadata -> Rep Metadata x
Generic)
  deriving anyclass (Metadata -> ()
(Metadata -> ()) -> NFData Metadata
forall a. (a -> ()) -> NFData a
rnf :: Metadata -> ()
$crnf :: Metadata -> ()
NFData, Get Metadata
[Metadata] -> Put
Metadata -> Put
(Metadata -> Put)
-> Get Metadata -> ([Metadata] -> Put) -> Binary Metadata
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [Metadata] -> Put
$cputList :: [Metadata] -> Put
get :: Get Metadata
$cget :: Get Metadata
put :: Metadata -> Put
$cput :: Metadata -> Put
Binary, Int -> Metadata -> Int
Metadata -> Int
(Int -> Metadata -> Int) -> (Metadata -> Int) -> Hashable Metadata
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Metadata -> Int
$chash :: Metadata -> Int
hashWithSalt :: Int -> Metadata -> Int
$chashWithSalt :: Int -> Metadata -> Int
Hashable)

instance Monoid Metadata where
    mempty :: Metadata
mempty = Set Key -> Assoc Key Text -> Metadata
Metadata Set Key
forall a. Monoid a => a
mempty Assoc Key Text
forall a. Monoid a => a
mempty

instance Semigroup Metadata where
    Metadata p1 :: Set Key
p1 s1 :: Assoc Key Text
s1 <> :: Metadata -> Metadata -> Metadata
<> Metadata p2 :: Set Key
p2 s2 :: Assoc Key Text
s2 = Set Key -> Assoc Key Text -> Metadata
Metadata (Set Key
p1 Set Key -> Set Key -> Set Key
forall a. Semigroup a => a -> a -> a
<> Set Key
p2) (Assoc Key Text
s1 Assoc Key Text -> Assoc Key Text -> Assoc Key Text
forall a. Semigroup a => a -> a -> a
<> Assoc Key Text
s2)

instance FromJSON Metadata where
    parseJSON :: Value -> Parser Metadata
parseJSON = String -> (Object -> Parser Metadata) -> Value -> Parser Metadata
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject "Metadata"
        ((Object -> Parser Metadata) -> Value -> Parser Metadata)
-> (Object -> Parser Metadata) -> Value -> Parser Metadata
forall a b. (a -> b) -> a -> b
$ \o :: Object
o -> Set Key -> Assoc Key Text -> Metadata
Metadata (Set Key -> Assoc Key Text -> Metadata)
-> Parser (Set Key) -> Parser (Assoc Key Text -> Metadata)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o Object -> Text -> Parser (Set Key)
forall a. FromJSON a => Object -> Text -> Parser a
.: "properties" Parser (Assoc Key Text -> Metadata)
-> Parser (Assoc Key Text) -> Parser Metadata
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o Object -> Text -> Parser (Assoc Key Text)
forall a. FromJSON a => Object -> Text -> Parser a
.: "settings"

instance ToJSON Metadata where
    toEncoding :: Metadata -> Encoding
toEncoding (Metadata ps :: Set Key
ps ss :: Assoc Key Text
ss) =
        Series -> Encoding
pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$ [Series] -> Series
forall a. Monoid a => [a] -> a
mconcat ["properties" Text -> Set Key -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Set Key
ps, "settings" Text -> Assoc Key Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Assoc Key Text
ss]

    toJSON :: Metadata -> Value
toJSON (Metadata ps :: Set Key
ps ss :: Assoc Key Text
ss) = [Pair] -> Value
object ["properties" Text -> Set Key -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Set Key
ps, "settings" Text -> Assoc Key Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Assoc Key Text
ss]

-------------------------------------------------------------------------------
-- | A non-empty collection of 'Inline' items. A 'Paragraph' represents the
-- border between block and inline contexts. All ancestors of a paragraph are
-- block items or a document, and all children are inline items.
data Paragraph = Paragraph
    { Paragraph -> SeriesNE Inline
paragraphContent  :: SeriesNE Inline
    , Paragraph -> Maybe Location
paragraphLocation :: Maybe Location
    }
  deriving stock (Paragraph -> Paragraph -> Bool
(Paragraph -> Paragraph -> Bool)
-> (Paragraph -> Paragraph -> Bool) -> Eq Paragraph
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Paragraph -> Paragraph -> Bool
$c/= :: Paragraph -> Paragraph -> Bool
== :: Paragraph -> Paragraph -> Bool
$c== :: Paragraph -> Paragraph -> Bool
Eq, Int -> Paragraph -> ShowS
[Paragraph] -> ShowS
Paragraph -> String
(Int -> Paragraph -> ShowS)
-> (Paragraph -> String)
-> ([Paragraph] -> ShowS)
-> Show Paragraph
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Paragraph] -> ShowS
$cshowList :: [Paragraph] -> ShowS
show :: Paragraph -> String
$cshow :: Paragraph -> String
showsPrec :: Int -> Paragraph -> ShowS
$cshowsPrec :: Int -> Paragraph -> ShowS
Show, (forall x. Paragraph -> Rep Paragraph x)
-> (forall x. Rep Paragraph x -> Paragraph) -> Generic Paragraph
forall x. Rep Paragraph x -> Paragraph
forall x. Paragraph -> Rep Paragraph x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Paragraph x -> Paragraph
$cfrom :: forall x. Paragraph -> Rep Paragraph x
Generic)
  deriving anyclass (Int -> Paragraph -> Int
Paragraph -> Int
(Int -> Paragraph -> Int)
-> (Paragraph -> Int) -> Hashable Paragraph
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Paragraph -> Int
$chash :: Paragraph -> Int
hashWithSalt :: Int -> Paragraph -> Int
$chashWithSalt :: Int -> Paragraph -> Int
Hashable, Paragraph -> ()
(Paragraph -> ()) -> NFData Paragraph
forall a. (a -> ()) -> NFData a
rnf :: Paragraph -> ()
$crnf :: Paragraph -> ()
NFData, Get Paragraph
[Paragraph] -> Put
Paragraph -> Put
(Paragraph -> Put)
-> Get Paragraph -> ([Paragraph] -> Put) -> Binary Paragraph
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [Paragraph] -> Put
$cputList :: [Paragraph] -> Put
get :: Get Paragraph
$cget :: Get Paragraph
put :: Paragraph -> Put
$cput :: Paragraph -> Put
Binary)

instance FromJSON Paragraph where
    parseJSON :: Value -> Parser Paragraph
parseJSON = (SeriesNE Inline -> Paragraph)
-> Parser (SeriesNE Inline) -> Parser Paragraph
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((SeriesNE Inline -> Maybe Location -> Paragraph)
-> Maybe Location -> SeriesNE Inline -> Paragraph
forall a b c. (a -> b -> c) -> b -> a -> c
flip SeriesNE Inline -> Maybe Location -> Paragraph
Paragraph Maybe Location
forall a. Maybe a
Nothing) (Parser (SeriesNE Inline) -> Parser Paragraph)
-> (Value -> Parser (SeriesNE Inline)) -> Value -> Parser Paragraph
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser (SeriesNE Inline)
forall a. FromJSON a => Value -> Parser a
parseJSON

instance ToJSON Paragraph where
    toEncoding :: Paragraph -> Encoding
toEncoding (Paragraph s :: SeriesNE Inline
s _) = SeriesNE Inline -> Encoding
forall a. ToJSON a => a -> Encoding
toEncoding SeriesNE Inline
s
    toJSON :: Paragraph -> Value
toJSON (Paragraph s :: SeriesNE Inline
s _) = SeriesNE Inline -> Value
forall a. ToJSON a => a -> Value
toJSON SeriesNE Inline
s

-------------------------------------------------------------------------------
-- | An untagged structural grouping of items with type @a@. Regions do not
-- occur in parsing.
data Region a = Region
    { Region a -> Metadata
regionMetadata :: Metadata
    , Region a -> a
regionContent  :: a
    , Region a -> Maybe Location
regionLocation :: Maybe Location
    }
  deriving stock (Region a -> Region a -> Bool
(Region a -> Region a -> Bool)
-> (Region a -> Region a -> Bool) -> Eq (Region a)
forall a. Eq a => Region a -> Region a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Region a -> Region a -> Bool
$c/= :: forall a. Eq a => Region a -> Region a -> Bool
== :: Region a -> Region a -> Bool
$c== :: forall a. Eq a => Region a -> Region a -> Bool
Eq, Region a -> Bool
(a -> m) -> Region a -> m
(a -> b -> b) -> b -> Region a -> b
(forall m. Monoid m => Region m -> m)
-> (forall m a. Monoid m => (a -> m) -> Region a -> m)
-> (forall m a. Monoid m => (a -> m) -> Region a -> m)
-> (forall a b. (a -> b -> b) -> b -> Region a -> b)
-> (forall a b. (a -> b -> b) -> b -> Region a -> b)
-> (forall b a. (b -> a -> b) -> b -> Region a -> b)
-> (forall b a. (b -> a -> b) -> b -> Region a -> b)
-> (forall a. (a -> a -> a) -> Region a -> a)
-> (forall a. (a -> a -> a) -> Region a -> a)
-> (forall a. Region a -> [a])
-> (forall a. Region a -> Bool)
-> (forall a. Region a -> Int)
-> (forall a. Eq a => a -> Region a -> Bool)
-> (forall a. Ord a => Region a -> a)
-> (forall a. Ord a => Region a -> a)
-> (forall a. Num a => Region a -> a)
-> (forall a. Num a => Region a -> a)
-> Foldable Region
forall a. Eq a => a -> Region a -> Bool
forall a. Num a => Region a -> a
forall a. Ord a => Region a -> a
forall m. Monoid m => Region m -> m
forall a. Region a -> Bool
forall a. Region a -> Int
forall a. Region a -> [a]
forall a. (a -> a -> a) -> Region a -> a
forall m a. Monoid m => (a -> m) -> Region a -> m
forall b a. (b -> a -> b) -> b -> Region a -> b
forall a b. (a -> b -> b) -> b -> Region a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Region a -> a
$cproduct :: forall a. Num a => Region a -> a
sum :: Region a -> a
$csum :: forall a. Num a => Region a -> a
minimum :: Region a -> a
$cminimum :: forall a. Ord a => Region a -> a
maximum :: Region a -> a
$cmaximum :: forall a. Ord a => Region a -> a
elem :: a -> Region a -> Bool
$celem :: forall a. Eq a => a -> Region a -> Bool
length :: Region a -> Int
$clength :: forall a. Region a -> Int
null :: Region a -> Bool
$cnull :: forall a. Region a -> Bool
toList :: Region a -> [a]
$ctoList :: forall a. Region a -> [a]
foldl1 :: (a -> a -> a) -> Region a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Region a -> a
foldr1 :: (a -> a -> a) -> Region a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Region a -> a
foldl' :: (b -> a -> b) -> b -> Region a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Region a -> b
foldl :: (b -> a -> b) -> b -> Region a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Region a -> b
foldr' :: (a -> b -> b) -> b -> Region a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Region a -> b
foldr :: (a -> b -> b) -> b -> Region a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Region a -> b
foldMap' :: (a -> m) -> Region a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Region a -> m
foldMap :: (a -> m) -> Region a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Region a -> m
fold :: Region m -> m
$cfold :: forall m. Monoid m => Region m -> m
Foldable, a -> Region b -> Region a
(a -> b) -> Region a -> Region b
(forall a b. (a -> b) -> Region a -> Region b)
-> (forall a b. a -> Region b -> Region a) -> Functor Region
forall a b. a -> Region b -> Region a
forall a b. (a -> b) -> Region a -> Region b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Region b -> Region a
$c<$ :: forall a b. a -> Region b -> Region a
fmap :: (a -> b) -> Region a -> Region b
$cfmap :: forall a b. (a -> b) -> Region a -> Region b
Functor, Int -> Region a -> ShowS
[Region a] -> ShowS
Region a -> String
(Int -> Region a -> ShowS)
-> (Region a -> String) -> ([Region a] -> ShowS) -> Show (Region a)
forall a. Show a => Int -> Region a -> ShowS
forall a. Show a => [Region a] -> ShowS
forall a. Show a => Region a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Region a] -> ShowS
$cshowList :: forall a. Show a => [Region a] -> ShowS
show :: Region a -> String
$cshow :: forall a. Show a => Region a -> String
showsPrec :: Int -> Region a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Region a -> ShowS
Show, Functor Region
Foldable Region
(Functor Region, Foldable Region) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Region a -> f (Region b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Region (f a) -> f (Region a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Region a -> m (Region b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Region (m a) -> m (Region a))
-> Traversable Region
(a -> f b) -> Region a -> f (Region b)
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Region (m a) -> m (Region a)
forall (f :: * -> *) a.
Applicative f =>
Region (f a) -> f (Region a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Region a -> m (Region b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Region a -> f (Region b)
sequence :: Region (m a) -> m (Region a)
$csequence :: forall (m :: * -> *) a. Monad m => Region (m a) -> m (Region a)
mapM :: (a -> m b) -> Region a -> m (Region b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Region a -> m (Region b)
sequenceA :: Region (f a) -> f (Region a)
$csequenceA :: forall (f :: * -> *) a.
Applicative f =>
Region (f a) -> f (Region a)
traverse :: (a -> f b) -> Region a -> f (Region b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Region a -> f (Region b)
$cp2Traversable :: Foldable Region
$cp1Traversable :: Functor Region
Traversable, (forall x. Region a -> Rep (Region a) x)
-> (forall x. Rep (Region a) x -> Region a) -> Generic (Region a)
forall x. Rep (Region a) x -> Region a
forall x. Region a -> Rep (Region a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Region a) x -> Region a
forall a x. Region a -> Rep (Region a) x
$cto :: forall a x. Rep (Region a) x -> Region a
$cfrom :: forall a x. Region a -> Rep (Region a) x
Generic)
  deriving anyclass (Int -> Region a -> Int
Region a -> Int
(Int -> Region a -> Int)
-> (Region a -> Int) -> Hashable (Region a)
forall a. Hashable a => Int -> Region a -> Int
forall a. Hashable a => Region a -> Int
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Region a -> Int
$chash :: forall a. Hashable a => Region a -> Int
hashWithSalt :: Int -> Region a -> Int
$chashWithSalt :: forall a. Hashable a => Int -> Region a -> Int
Hashable, Region a -> ()
(Region a -> ()) -> NFData (Region a)
forall a. NFData a => Region a -> ()
forall a. (a -> ()) -> NFData a
rnf :: Region a -> ()
$crnf :: forall a. NFData a => Region a -> ()
NFData, Get (Region a)
[Region a] -> Put
Region a -> Put
(Region a -> Put)
-> Get (Region a) -> ([Region a] -> Put) -> Binary (Region a)
forall a. Binary a => Get (Region a)
forall a. Binary a => [Region a] -> Put
forall a. Binary a => Region a -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [Region a] -> Put
$cputList :: forall a. Binary a => [Region a] -> Put
get :: Get (Region a)
$cget :: forall a. Binary a => Get (Region a)
put :: Region a -> Put
$cput :: forall a. Binary a => Region a -> Put
Binary)

instance ToJSON a => ToJSON (Region a) where
    toJSON :: Region a -> Value
toJSON (Region md :: Metadata
md ct :: a
ct _) = [Pair] -> Value
Aeson.object ["metadata" Text -> Metadata -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Metadata
md, "content" Text -> a -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= a
ct]

-------------------------------------------------------------------------------
-- | A 'Region', annotated with a tag name.
data Tag a = Tag
    { Tag a -> Key
tagName     :: Key
    , Tag a -> Metadata
tagMetadata :: Metadata
    , Tag a -> a
tagContent  :: a
    , Tag a -> Maybe Location
tagLocation :: Maybe Location
    }
  deriving stock (Tag a -> Tag a -> Bool
(Tag a -> Tag a -> Bool) -> (Tag a -> Tag a -> Bool) -> Eq (Tag a)
forall a. Eq a => Tag a -> Tag a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Tag a -> Tag a -> Bool
$c/= :: forall a. Eq a => Tag a -> Tag a -> Bool
== :: Tag a -> Tag a -> Bool
$c== :: forall a. Eq a => Tag a -> Tag a -> Bool
Eq, Tag a -> Bool
(a -> m) -> Tag a -> m
(a -> b -> b) -> b -> Tag a -> b
(forall m. Monoid m => Tag m -> m)
-> (forall m a. Monoid m => (a -> m) -> Tag a -> m)
-> (forall m a. Monoid m => (a -> m) -> Tag a -> m)
-> (forall a b. (a -> b -> b) -> b -> Tag a -> b)
-> (forall a b. (a -> b -> b) -> b -> Tag a -> b)
-> (forall b a. (b -> a -> b) -> b -> Tag a -> b)
-> (forall b a. (b -> a -> b) -> b -> Tag a -> b)
-> (forall a. (a -> a -> a) -> Tag a -> a)
-> (forall a. (a -> a -> a) -> Tag a -> a)
-> (forall a. Tag a -> [a])
-> (forall a. Tag a -> Bool)
-> (forall a. Tag a -> Int)
-> (forall a. Eq a => a -> Tag a -> Bool)
-> (forall a. Ord a => Tag a -> a)
-> (forall a. Ord a => Tag a -> a)
-> (forall a. Num a => Tag a -> a)
-> (forall a. Num a => Tag a -> a)
-> Foldable Tag
forall a. Eq a => a -> Tag a -> Bool
forall a. Num a => Tag a -> a
forall a. Ord a => Tag a -> a
forall m. Monoid m => Tag m -> m
forall a. Tag a -> Bool
forall a. Tag a -> Int
forall a. Tag a -> [a]
forall a. (a -> a -> a) -> Tag a -> a
forall m a. Monoid m => (a -> m) -> Tag a -> m
forall b a. (b -> a -> b) -> b -> Tag a -> b
forall a b. (a -> b -> b) -> b -> Tag a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Tag a -> a
$cproduct :: forall a. Num a => Tag a -> a
sum :: Tag a -> a
$csum :: forall a. Num a => Tag a -> a
minimum :: Tag a -> a
$cminimum :: forall a. Ord a => Tag a -> a
maximum :: Tag a -> a
$cmaximum :: forall a. Ord a => Tag a -> a
elem :: a -> Tag a -> Bool
$celem :: forall a. Eq a => a -> Tag a -> Bool
length :: Tag a -> Int
$clength :: forall a. Tag a -> Int
null :: Tag a -> Bool
$cnull :: forall a. Tag a -> Bool
toList :: Tag a -> [a]
$ctoList :: forall a. Tag a -> [a]
foldl1 :: (a -> a -> a) -> Tag a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Tag a -> a
foldr1 :: (a -> a -> a) -> Tag a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> Tag a -> a
foldl' :: (b -> a -> b) -> b -> Tag a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Tag a -> b
foldl :: (b -> a -> b) -> b -> Tag a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Tag a -> b
foldr' :: (a -> b -> b) -> b -> Tag a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Tag a -> b
foldr :: (a -> b -> b) -> b -> Tag a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> Tag a -> b
foldMap' :: (a -> m) -> Tag a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Tag a -> m
foldMap :: (a -> m) -> Tag a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Tag a -> m
fold :: Tag m -> m
$cfold :: forall m. Monoid m => Tag m -> m
Foldable, a -> Tag b -> Tag a
(a -> b) -> Tag a -> Tag b
(forall a b. (a -> b) -> Tag a -> Tag b)
-> (forall a b. a -> Tag b -> Tag a) -> Functor Tag
forall a b. a -> Tag b -> Tag a
forall a b. (a -> b) -> Tag a -> Tag b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Tag b -> Tag a
$c<$ :: forall a b. a -> Tag b -> Tag a
fmap :: (a -> b) -> Tag a -> Tag b
$cfmap :: forall a b. (a -> b) -> Tag a -> Tag b
Functor, Int -> Tag a -> ShowS
[Tag a] -> ShowS
Tag a -> String
(Int -> Tag a -> ShowS)
-> (Tag a -> String) -> ([Tag a] -> ShowS) -> Show (Tag a)
forall a. Show a => Int -> Tag a -> ShowS
forall a. Show a => [Tag a] -> ShowS
forall a. Show a => Tag a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Tag a] -> ShowS
$cshowList :: forall a. Show a => [Tag a] -> ShowS
show :: Tag a -> String
$cshow :: forall a. Show a => Tag a -> String
showsPrec :: Int -> Tag a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Tag a -> ShowS
Show, Functor Tag
Foldable Tag
(Functor Tag, Foldable Tag) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Tag a -> f (Tag b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Tag (f a) -> f (Tag a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Tag a -> m (Tag b))
-> (forall (m :: * -> *) a. Monad m => Tag (m a) -> m (Tag a))
-> Traversable Tag
(a -> f b) -> Tag a -> f (Tag b)
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Tag (m a) -> m (Tag a)
forall (f :: * -> *) a. Applicative f => Tag (f a) -> f (Tag a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Tag a -> m (Tag b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Tag a -> f (Tag b)
sequence :: Tag (m a) -> m (Tag a)
$csequence :: forall (m :: * -> *) a. Monad m => Tag (m a) -> m (Tag a)
mapM :: (a -> m b) -> Tag a -> m (Tag b)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Tag a -> m (Tag b)
sequenceA :: Tag (f a) -> f (Tag a)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Tag (f a) -> f (Tag a)
traverse :: (a -> f b) -> Tag a -> f (Tag b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Tag a -> f (Tag b)
$cp2Traversable :: Foldable Tag
$cp1Traversable :: Functor Tag
Traversable, (forall x. Tag a -> Rep (Tag a) x)
-> (forall x. Rep (Tag a) x -> Tag a) -> Generic (Tag a)
forall x. Rep (Tag a) x -> Tag a
forall x. Tag a -> Rep (Tag a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Tag a) x -> Tag a
forall a x. Tag a -> Rep (Tag a) x
$cto :: forall a x. Rep (Tag a) x -> Tag a
$cfrom :: forall a x. Tag a -> Rep (Tag a) x
Generic)
  deriving anyclass (Int -> Tag a -> Int
Tag a -> Int
(Int -> Tag a -> Int) -> (Tag a -> Int) -> Hashable (Tag a)
forall a. Hashable a => Int -> Tag a -> Int
forall a. Hashable a => Tag a -> Int
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Tag a -> Int
$chash :: forall a. Hashable a => Tag a -> Int
hashWithSalt :: Int -> Tag a -> Int
$chashWithSalt :: forall a. Hashable a => Int -> Tag a -> Int
Hashable, Tag a -> ()
(Tag a -> ()) -> NFData (Tag a)
forall a. NFData a => Tag a -> ()
forall a. (a -> ()) -> NFData a
rnf :: Tag a -> ()
$crnf :: forall a. NFData a => Tag a -> ()
NFData, Get (Tag a)
[Tag a] -> Put
Tag a -> Put
(Tag a -> Put) -> Get (Tag a) -> ([Tag a] -> Put) -> Binary (Tag a)
forall a. Binary a => Get (Tag a)
forall a. Binary a => [Tag a] -> Put
forall a. Binary a => Tag a -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [Tag a] -> Put
$cputList :: forall a. Binary a => [Tag a] -> Put
get :: Get (Tag a)
$cget :: forall a. Binary a => Get (Tag a)
put :: Tag a -> Put
$cput :: forall a. Binary a => Tag a -> Put
Binary)

instance FromJSON a => FromJSON (Tag a) where
    parseJSON :: Value -> Parser (Tag a)
parseJSON = String -> (Object -> Parser (Tag a)) -> Value -> Parser (Tag a)
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject "Tag" ((Object -> Parser (Tag a)) -> Value -> Parser (Tag a))
-> (Object -> Parser (Tag a)) -> Value -> Parser (Tag a)
forall a b. (a -> b) -> a -> b
$ \o :: Object
o ->
        Key -> Metadata -> a -> Maybe Location -> Tag a
forall a. Key -> Metadata -> a -> Maybe Location -> Tag a
Tag
            (Key -> Metadata -> a -> Maybe Location -> Tag a)
-> Parser Key -> Parser (Metadata -> a -> Maybe Location -> Tag a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
o
            Object -> Text -> Parser Key
forall a. FromJSON a => Object -> Text -> Parser a
.:  "name"
            Parser (Metadata -> a -> Maybe Location -> Tag a)
-> Parser Metadata -> Parser (a -> Maybe Location -> Tag a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o
            Object -> Text -> Parser Metadata
forall a. FromJSON a => Object -> Text -> Parser a
.:  "metadata"
            Parser (a -> Maybe Location -> Tag a)
-> Parser a -> Parser (Maybe Location -> Tag a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
o
            Object -> Text -> Parser a
forall a. FromJSON a => Object -> Text -> Parser a
.:  "content"
            Parser (Maybe Location -> Tag a)
-> Parser (Maybe Location) -> Parser (Tag a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe Location -> Parser (Maybe Location)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Location
forall a. Maybe a
Nothing

instance ToJSON a => ToJSON (Tag a) where
    toEncoding :: Tag a -> Encoding
toEncoding (Tag nm :: Key
nm md :: Metadata
md ct :: a
ct _) =
        Series -> Encoding
pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$ [Series] -> Series
forall a. Monoid a => [a] -> a
mconcat ["name" Text -> Key -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Key
nm, "metadata" Text -> Metadata -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Metadata
md, "content" Text -> a -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= a
ct]

    toJSON :: Tag a -> Value
toJSON (Tag nm :: Key
nm md :: Metadata
md ct :: a
ct _) =
        [Pair] -> Value
object ["name" Text -> Key -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Key
nm, "metadata" Text -> Metadata -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Metadata
md, "content" Text -> a -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= a
ct]

-- | A 'Tag' containing zero or more 'Block' items. 
-- Specified in Prosidy source with the @#-@ sigil.
type BlockTag = Tag (Series Block)

-- | A 'Tag' containing zero or more 'Inline' items.
-- Specified in Prosidy source with the @#@ sigil.
type InlineTag = Tag (Series Inline)

-- | A 'Tag' containing a single plain-text item.
-- Specified in Prosidy source with the @#=@ sigil.
type LiteralTag = Tag Text

-- | Convert a 'Tag' to a 'Region' by discarding the tag's name.
tagToRegion :: Tag a -> Region a
tagToRegion :: Tag a -> Region a
tagToRegion (Tag _ md :: Metadata
md ct :: a
ct loc :: Maybe Location
loc) = Metadata -> a -> Maybe Location -> Region a
forall a. Metadata -> a -> Maybe Location -> Region a
Region Metadata
md a
ct Maybe Location
loc

-- | Convert a 'Region' to a 'Tag' by providing a tag name.
regionToTag :: Key -> Region a -> Tag a
regionToTag :: Key -> Region a -> Tag a
regionToTag name :: Key
name (Region md :: Metadata
md ct :: a
ct loc :: Maybe Location
loc) = Key -> Metadata -> a -> Maybe Location -> Tag a
forall a. Key -> Metadata -> a -> Maybe Location -> Tag a
Tag Key
name Metadata
md a
ct Maybe Location
loc