{-# LANGUAGE OverloadedStrings #-}

module Language.Ltml.Tree.Example.Fpo
    ( fpoTree
    )
where

import Data.Text (Text, unlines)
import Language.Ltml.Common (Flagged (Flagged))
import Language.Ltml.Tree
    ( FlaggedInputTree'
    , Tree (Leaf, Tree)
    , TypedInputTree'
    , TypedTree (TypedTree)
    )
import Prelude hiding (unlines)

fpoTree :: FlaggedInputTree'
fpoTree :: FlaggedInputTree'
fpoTree =
    Bool -> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
False (TypedTree Bool (Maybe Text) Text -> FlaggedInputTree')
-> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall a b. (a -> b) -> a -> b
$
        KindName
-> TypeName
-> Tree Bool (Maybe Text) Text
-> TypedTree Bool (Maybe Text) Text
forall flag a b.
KindName -> TypeName -> Tree flag a b -> TypedTree flag a b
TypedTree KindName
"document-container" TypeName
"fpo-container" (Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text)
-> Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text
forall a b. (a -> b) -> a -> b
$
            Maybe Text -> [FlaggedInputTree'] -> Tree Bool (Maybe Text) Text
forall flag a b. a -> [FlaggedTree flag a b] -> Tree flag a b
Tree (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
header) (FlaggedInputTree'
mainDocTree FlaggedInputTree' -> [FlaggedInputTree'] -> [FlaggedInputTree']
forall a. a -> [a] -> [a]
: [FlaggedInputTree']
appTrees)
  where
    header :: Text
    header :: Text
header =
        [Text] -> Text
unlines
            [ Text
"// Document container header."
            , Text
"// The order of entries is fixed (TODO)."
            , Text
""
            , Text
"pdf-title: Beispieltitel"
            , Text
""
            , Text
"// Name of the institution here."
            , Text
"header-footer-supertitle: Universität BeispielStadt"
            , Text
""
            , Text
"header-footer-title: FPO Beispiel 2025"
            , Text
""
            , Text
"header-footer-date: 2025-08-26"
            ]

mainDocTree :: FlaggedInputTree'
mainDocTree :: FlaggedInputTree'
mainDocTree =
    Bool -> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
False (TypedTree Bool (Maybe Text) Text -> FlaggedInputTree')
-> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall a b. (a -> b) -> a -> b
$
        KindName
-> TypeName
-> Tree Bool (Maybe Text) Text
-> TypedTree Bool (Maybe Text) Text
forall flag a b.
KindName -> TypeName -> Tree flag a b -> TypedTree flag a b
TypedTree KindName
"document" TypeName
"fpo-maindoc" (Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text)
-> Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text
forall a b. (a -> b) -> a -> b
$
            Maybe Text -> [FlaggedInputTree'] -> Tree Bool (Maybe Text) Text
forall flag a b. a -> [FlaggedTree flag a b] -> Tree flag a b
Tree
                (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
heading)
                [FlaggedInputTree'
forall {flag} {a}. Flagged Bool (TypedTree flag a Text)
introTree, FlaggedInputTree'
mainBodyTree, FlaggedInputTree'
forall {flag} {a}. Flagged Bool (TypedTree flag a Text)
extroTree]
  where
    heading :: Text
heading =
        [Text] -> Text
unlines
            [ Text
"// Only the document's heading is permitted here."
            , Text
"! Beispiel-Überschrift"
            ]

    introTree :: Flagged Bool (TypedTree flag a Text)
introTree =
        Bool
-> TypedTree flag a Text -> Flagged Bool (TypedTree flag a Text)
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
False (TypedTree flag a Text -> Flagged Bool (TypedTree flag a Text))
-> TypedTree flag a Text -> Flagged Bool (TypedTree flag a Text)
forall a b. (a -> b) -> a -> b
$
            KindName -> TypeName -> Tree flag a Text -> TypedTree flag a Text
forall flag a b.
KindName -> TypeName -> Tree flag a b -> TypedTree flag a b
TypedTree KindName
"document-intro" TypeName
"" (Tree flag a Text -> TypedTree flag a Text)
-> Tree flag a Text -> TypedTree flag a Text
forall a b. (a -> b) -> a -> b
$
                Text -> Tree flag a Text
forall flag a b. b -> Tree flag a b
Leaf Text
introText

    mainBodyTree :: FlaggedInputTree'
mainBodyTree =
        Bool -> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
False (TypedTree Bool (Maybe Text) Text -> FlaggedInputTree')
-> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall a b. (a -> b) -> a -> b
$
            KindName
-> TypeName
-> Tree Bool (Maybe Text) Text
-> TypedTree Bool (Maybe Text) Text
forall flag a b.
KindName -> TypeName -> Tree flag a b -> TypedTree flag a b
TypedTree KindName
"document-mainbody" TypeName
"fpo-mainbody-simple" (Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text)
-> Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text
forall a b. (a -> b) -> a -> b
$
                Maybe Text -> [FlaggedInputTree'] -> Tree Bool (Maybe Text) Text
forall flag a b. a -> [FlaggedTree flag a b] -> Tree flag a b
Tree Maybe Text
forall a. Maybe a
Nothing [Bool -> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
True TypedTree Bool (Maybe Text) Text
sampleSectionTree]

    extroTree :: Flagged Bool (TypedTree flag a Text)
extroTree =
        Bool
-> TypedTree flag a Text -> Flagged Bool (TypedTree flag a Text)
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
False (TypedTree flag a Text -> Flagged Bool (TypedTree flag a Text))
-> TypedTree flag a Text -> Flagged Bool (TypedTree flag a Text)
forall a b. (a -> b) -> a -> b
$
            KindName -> TypeName -> Tree flag a Text -> TypedTree flag a Text
forall flag a b.
KindName -> TypeName -> Tree flag a b -> TypedTree flag a b
TypedTree KindName
"document-extro" TypeName
"" (Tree flag a Text -> TypedTree flag a Text)
-> Tree flag a Text -> TypedTree flag a Text
forall a b. (a -> b) -> a -> b
$
                Text -> Tree flag a Text
forall flag a b. b -> Tree flag a b
Leaf Text
extroText

appTrees :: [FlaggedInputTree']
appTrees :: [FlaggedInputTree']
appTrees = [FlaggedInputTree'
appendixTree, FlaggedInputTree'
attachmentsTree]

appendixTree :: FlaggedInputTree'
appendixTree :: FlaggedInputTree'
appendixTree =
    Bool -> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
False (TypedTree Bool (Maybe Text) Text -> FlaggedInputTree')
-> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall a b. (a -> b) -> a -> b
$
        KindName
-> TypeName
-> Tree Bool (Maybe Text) Text
-> TypedTree Bool (Maybe Text) Text
forall flag a b.
KindName -> TypeName -> Tree flag a b -> TypedTree flag a b
TypedTree KindName
"appendix-section" TypeName
"appendix" (Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text)
-> Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text
forall a b. (a -> b) -> a -> b
$
            Maybe Text -> [FlaggedInputTree'] -> Tree Bool (Maybe Text) Text
forall flag a b. a -> [FlaggedTree flag a b] -> Tree flag a b
Tree Maybe Text
forall a. Maybe a
Nothing [Bool -> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
False TypedTree Bool (Maybe Text) Text
appendixDocument]
  where
    appendixDocument :: TypedInputTree'
    appendixDocument :: TypedTree Bool (Maybe Text) Text
appendixDocument =
        KindName
-> TypeName
-> Tree Bool (Maybe Text) Text
-> TypedTree Bool (Maybe Text) Text
forall flag a b.
KindName -> TypeName -> Tree flag a b -> TypedTree flag a b
TypedTree KindName
"document" TypeName
"simpledoc" (Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text)
-> Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text
forall a b. (a -> b) -> a -> b
$
            Maybe Text -> [FlaggedInputTree'] -> Tree Bool (Maybe Text) Text
forall flag a b. a -> [FlaggedTree flag a b] -> Tree flag a b
Tree
                (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
appendixHeading)
                [Bool -> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
False TypedTree Bool (Maybe Text) Text
appendixDocumentBody]

    appendixDocumentBody :: TypedInputTree'
    appendixDocumentBody :: TypedTree Bool (Maybe Text) Text
appendixDocumentBody =
        KindName
-> TypeName
-> Tree Bool (Maybe Text) Text
-> TypedTree Bool (Maybe Text) Text
forall flag a b.
KindName -> TypeName -> Tree flag a b -> TypedTree flag a b
TypedTree KindName
"document-mainbody" TypeName
"simpledoc-mainbody" (Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text)
-> Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text
forall a b. (a -> b) -> a -> b
$
            Text -> Tree Bool (Maybe Text) Text
forall flag a b. b -> Tree flag a b
Leaf Text
simpleBlockText

    appendixHeading :: Text
    appendixHeading :: Text
appendixHeading =
        [Text] -> Text
unlines
            [ Text
"// Only the appendix document's heading is permitted here."
            , Text
"! Beispiel Anhang"
            ]

attachmentsTree :: FlaggedInputTree'
attachmentsTree :: FlaggedInputTree'
attachmentsTree =
    Bool -> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall flag a. flag -> a -> Flagged flag a
Flagged Bool
False (TypedTree Bool (Maybe Text) Text -> FlaggedInputTree')
-> TypedTree Bool (Maybe Text) Text -> FlaggedInputTree'
forall a b. (a -> b) -> a -> b
$
        KindName
-> TypeName
-> Tree Bool (Maybe Text) Text
-> TypedTree Bool (Maybe Text) Text
forall flag a b.
KindName -> TypeName -> Tree flag a b -> TypedTree flag a b
TypedTree KindName
"appendix-section" TypeName
"attachments" (Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text)
-> Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text
forall a b. (a -> b) -> a -> b
$
            Maybe Text -> [FlaggedInputTree'] -> Tree Bool (Maybe Text) Text
forall flag a b. a -> [FlaggedTree flag a b] -> Tree flag a b
Tree Maybe Text
forall a. Maybe a
Nothing []

introText :: Text
introText :: Text
introText =
    [Text] -> Text
unlines
        [ Text
"[date]"
        , Text
""
        , Text
"// Insert correct date here; displayed at the very top."
        , Text
"Vom 19. Januar 2038"
        , Text
""
        , Text
""
        , Text
"[publ_log]"
        , Text
""
        , Text
"// Publication log; typically one paragraph (i.e., no empty lines)"
        , Text
"// with many comma-separated \"Veröffentlichung vom ...\""
        , Text
""
        , Text
""
        , Text
"[intro]"
        , Text
""
        , Text
"// Intro; typically one paragraph à la:"
        , Text
"// \"Aufgrund ... wird ... erlassen:\""
        ]

sampleSectionTree :: TypedInputTree'
sampleSectionTree :: TypedTree Bool (Maybe Text) Text
sampleSectionTree =
    KindName
-> TypeName
-> Tree Bool (Maybe Text) Text
-> TypedTree Bool (Maybe Text) Text
forall flag a b.
KindName -> TypeName -> Tree flag a b -> TypedTree flag a b
TypedTree KindName
"section" TypeName
"section" (Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text)
-> Tree Bool (Maybe Text) Text -> TypedTree Bool (Maybe Text) Text
forall a b. (a -> b) -> a -> b
$
        Text -> Tree Bool (Maybe Text) Text
forall flag a b. b -> Tree flag a b
Leaf Text
sampleSectionText

sampleSectionText :: Text
sampleSectionText :: Text
sampleSectionText =
    [Text] -> Text
unlines
        [ Text
"// document heading; mandatory, with the § sign."
        , Text
"§ section title"
        , Text
""
        , Text
"// Section body -- a sequence of paragraphs, separated by empty"
        , Text
"// lines."
        , Text
""
        , Text
"This is a simple paragraph."
        , Text
""
        , Text
"This is another paragraph, with an enumeration:"
        , Text
"  # first item"
        , Text
"  # second item"
        , Text
"      # sub-item"
        , Text
"  # third item, which"
        , Text
"    spans several lines"
        , Text
""
        , Text
"{some_paragraph:}"
        , Text
"A labeled paragraph, referencing itself: {:some_paragraph}."
        , Text
"It also has a footnote{^:a_footnote}."
        , Text
"{a_sentence:} It also has a self-referencing sentence:"
        , Text
"{:a_sentence}."
        , Text
""
        , Text
"// A footnote is defined as follows:"
        , Text
"^{a_footnote:}"
        , Text
"  The footnote."
        ]

extroText :: Text
extroText :: Text
extroText =
    [Text] -> Text
unlines
        [ Text
"[extro]"
        , Text
""
        , Text
"// Here goes some text that goes at the end of the document."
        , Text
""
        , Text
"// In particular, there should be the date and name of the"
        , Text
"// signatory, with space for the actual signature."
        , Text
"//  - Vertical space can be inserted as {nl}."
        , Text
""
        , Text
""
        , Text
"[legal_log]"
        , Text
""
        , Text
"// Here, a sequence of paragraphs like the following should go."
        , Text
""
        , Text
"<*Artikel 42 der Änderungssatzung vom 19. Januar 2038:>"
        , Text
"Diese Satzung tritt am Tag nach ihrer Bekanntmachung in Kraft."
        ]

simpleBlockText :: Text
simpleBlockText :: Text
simpleBlockText =
    [Text] -> Text
unlines
        [ Text
"// Here goes all text regarding this appendix section."
        , Text
"// An appendix section consists of regular paragraphs and tables."
        , -- , "// For better readability, an appendix section"
          -- , "// should contain only a single table."
          Text
""
        , Text
"This an appendix section. Here, many useful pieces of information are specified."
        , Text
""
        , Text
"// A simple table could look like this:"
        , Text
""
        , Text
"| A | B |&"
        , Text
"| C | D |&"
        , Text
""
        , Text
"// The '&' symbol is used to mark the end of a row."
        , Text
""
        , Text
"// Cells can also be merged across rows and columns"
        , Text
"// using the arrow symbols '<' and '^':"
        , Text
""
        , Text
"Vertically merged cells look like this: "
        , Text
""
        , Text
"| A | < |&"
        , Text
"| C | D |&"
        , Text
""
        , Text
"Horizontally merged cells look like this:"
        , Text
""
        , Text
"| A | B |&"
        , Text
"| ^ | D |&"
        , Text
""
        , Text
""
        , Text
"// There is also a special syntax for module definitions and studyplans:"
        , Text
"The following is a simple list of module definitions."
        , Text
""
        , Text
"// First, a schema is defined:"
        , Text
"schema: Name | ECTS | Score"
        , Text
"// A list of modules follows:"
        , Text
"module: ABC | 8 | A"
        , Text
"module: DEFG | 4 | B"
        , Text
""
        , Text
"Furthermore, a studyplan is defined."
        , Text
""
        , Text
"// Additionally modules can be grouped into categories:"
        , Text
"schema: Name | ECTS | Score"
        , Text
"category: 1. Semester"
        , Text
"module: ABC | 8 | A"
        , Text
"module: DEFG | 4 | B"
        , Text
""
        , Text
"category: 2. Semester"
        , Text
"module: ABC II | 5-8 | "
        , Text
"module: D I | | C{^:c_grade}"
        , Text
""
        , Text
"^{c_grade:} A footnote!"
        ]