module Language.Ltml.Parser.SimpleSection
    ( simpleSectionP
    , simpleSectionSequenceP
    )
where

import Control.Applicative.Utils ((<:>))
import Control.Monad (void)
import Control.Monad.Trans.Class (lift)
import Language.Lsd.AST.SimpleRegex (Sequence (Sequence), Star (Star))
import Language.Lsd.AST.Type (unwrapNT)
import Language.Lsd.AST.Type.SimpleSection
    ( SimpleSectionType (SimpleSectionType)
    )
import Language.Ltml.AST.SimpleSection (SimpleSection (SimpleSection))
import Language.Ltml.Parser (Parser)
import Language.Ltml.Parser.Common.Lexeme (nLexeme1)
import Language.Ltml.Parser.Footnote (FootnoteParser)
import Language.Ltml.Parser.Footnote.Combinators (manyWithFootnotesTillSucc)
import Language.Ltml.Parser.Keyword (keywordP)
import Language.Ltml.Parser.SimpleParagraph (simpleParagraphP)

simpleSectionP
    :: SimpleSectionType
    -> Parser ()
    -> FootnoteParser SimpleSection
simpleSectionP :: SimpleSectionType -> Parser () -> FootnoteParser SimpleSection
simpleSectionP (SimpleSectionType Keyword
kw SimpleSectionFormat
fmt (Star NamedType SimpleParagraphType
childrenT)) Parser ()
succStartP = do
    Parser () -> FootnoteWriterT (ParsecT Void Text Identity) ()
forall (m :: * -> *) a. Monad m => m a -> FootnoteWriterT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Parser () -> FootnoteWriterT (ParsecT Void Text Identity) ())
-> Parser () -> FootnoteWriterT (ParsecT Void Text Identity) ()
forall a b. (a -> b) -> a -> b
$ Parser () -> Parser ()
forall (m :: * -> *) a. MonadParser m => m a -> m a
nLexeme1 (Parser () -> Parser ()) -> Parser () -> Parser ()
forall a b. (a -> b) -> a -> b
$ Keyword -> Parser ()
forall (m :: * -> *). MonadParser m => Keyword -> m ()
keywordP Keyword
kw
    SimpleSectionFormat -> [SimpleParagraph] -> SimpleSection
SimpleSection SimpleSectionFormat
fmt
        ([SimpleParagraph] -> SimpleSection)
-> FootnoteWriterT (ParsecT Void Text Identity) [SimpleParagraph]
-> FootnoteParser SimpleSection
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser SimpleParagraph
-> Parser ()
-> FootnoteWriterT (ParsecT Void Text Identity) [SimpleParagraph]
forall a. Parser a -> Parser () -> FootnoteParser [a]
manyWithFootnotesTillSucc
            (SimpleParagraphType -> Parser SimpleParagraph
simpleParagraphP (SimpleParagraphType -> Parser SimpleParagraph)
-> SimpleParagraphType -> Parser SimpleParagraph
forall a b. (a -> b) -> a -> b
$ NamedType SimpleParagraphType -> SimpleParagraphType
forall t. NamedType t -> t
unwrapNT NamedType SimpleParagraphType
childrenT)
            Parser ()
succStartP

simpleSectionSequenceP
    :: Sequence SimpleSectionType
    -> Parser ()
    -> FootnoteParser [SimpleSection]
simpleSectionSequenceP :: Sequence SimpleSectionType
-> Parser () -> FootnoteParser [SimpleSection]
simpleSectionSequenceP (Sequence [SimpleSectionType]
ts') Parser ()
succStartP = [SimpleSectionType] -> FootnoteParser [SimpleSection]
aux [SimpleSectionType]
ts'
  where
    aux :: [SimpleSectionType] -> FootnoteParser [SimpleSection]
aux [] = ParsecT Void Text Identity [SimpleSection]
-> FootnoteParser [SimpleSection]
forall (m :: * -> *) a. Monad m => m a -> FootnoteWriterT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ParsecT Void Text Identity [SimpleSection]
 -> FootnoteParser [SimpleSection])
-> ParsecT Void Text Identity [SimpleSection]
-> FootnoteParser [SimpleSection]
forall a b. (a -> b) -> a -> b
$ [] [SimpleSection]
-> Parser () -> ParsecT Void Text Identity [SimpleSection]
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser ()
succStartP
    aux [SimpleSectionType
t] = SimpleSectionType -> Parser () -> FootnoteParser SimpleSection
simpleSectionP SimpleSectionType
t Parser ()
succStartP FootnoteParser SimpleSection
-> FootnoteParser [SimpleSection] -> FootnoteParser [SimpleSection]
forall (f :: * -> *) a. Applicative f => f a -> f [a] -> f [a]
<:> [SimpleSectionType] -> FootnoteParser [SimpleSection]
aux []
    aux (SimpleSectionType
t : ts :: [SimpleSectionType]
ts@(SimpleSectionType
t' : [SimpleSectionType]
_)) = SimpleSectionType -> Parser () -> FootnoteParser SimpleSection
simpleSectionP SimpleSectionType
t (SimpleSectionType -> Parser ()
toStartP SimpleSectionType
t') FootnoteParser SimpleSection
-> FootnoteParser [SimpleSection] -> FootnoteParser [SimpleSection]
forall (f :: * -> *) a. Applicative f => f a -> f [a] -> f [a]
<:> [SimpleSectionType] -> FootnoteParser [SimpleSection]
aux [SimpleSectionType]
ts

toStartP :: SimpleSectionType -> Parser ()
toStartP :: SimpleSectionType -> Parser ()
toStartP (SimpleSectionType Keyword
kw SimpleSectionFormat
_ Star (NamedType SimpleParagraphType)
_) = Parser () -> Parser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parser () -> Parser ()) -> Parser () -> Parser ()
forall a b. (a -> b) -> a -> b
$ Keyword -> Parser ()
forall (m :: * -> *). MonadParser m => Keyword -> m ()
keywordP Keyword
kw