{-# LANGUAGE OverloadedStrings #-}

-- | This module provides utilities for building Pandoc documents.
module Study.Framework.DocumentBuilders
( buildDocumentFromMarkdownCode
, buildGlossaryDocument
) where

import Core
import Language.Lojban.Core
import qualified Data.Text as T
import qualified Text.Pandoc as P

-- | Given Markdown code, produces a Pandoc document.
buildDocumentFromMarkdownCode :: T.Text -> Either P.PandocError P.Pandoc
buildDocumentFromMarkdownCode :: Text -> Either PandocError Pandoc
buildDocumentFromMarkdownCode Text
code = PandocPure Pandoc -> Either PandocError Pandoc
forall a. PandocPure a -> Either PandocError a
P.runPure (PandocPure Pandoc -> Either PandocError Pandoc)
-> PandocPure Pandoc -> Either PandocError Pandoc
forall a b. (a -> b) -> a -> b
$ ReaderOptions -> Text -> PandocPure Pandoc
forall (m :: * -> *) a.
(PandocMonad m, ToSources a) =>
ReaderOptions -> a -> m Pandoc
P.readMarkdown ReaderOptions
forall a. Default a => a
P.def
    { readerStripComments :: Bool
P.readerStripComments = Bool
True
    , readerExtensions :: Extensions
P.readerExtensions = [Extension] -> Extensions
P.extensionsFromList [ Extension
P.Ext_raw_html, Extension
P.Ext_markdown_in_html_blocks, Extension
P.Ext_subscript, Extension
P.Ext_simple_tables, Extension
P.Ext_multiline_tables, Extension
P.Ext_pipe_tables ]
    } (Text -> PandocPure Pandoc) -> Text -> PandocPure Pandoc
forall a b. (a -> b) -> a -> b
$ Text -> Text
preprocessMarkdownCode Text
code

-- | Proprocess Markdown code to handle subscripts.
preprocessMarkdownCode :: T.Text -> T.Text
preprocessMarkdownCode :: Text -> Text
preprocessMarkdownCode = (HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"x_1" Text
"x~1~") (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"x_2" Text
"x~2~") (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"x_3" Text
"x~3~") (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"x_4" Text
"x~4~") (Text -> Text) -> (Text -> Text) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"x_5" Text
"x~5~")

-- | Given a dictionary and a vocabulary, produces a glossary in the form of a Pandoc document.
buildGlossaryDocument :: Dictionary -> Vocabulary -> P.Pandoc
buildGlossaryDocument :: Dictionary -> Vocabulary -> Pandoc
buildGlossaryDocument Dictionary
dictionary Vocabulary
vocabulary = Pandoc
document where
    Right Pandoc
document = Text -> Either PandocError Pandoc
buildDocumentFromMarkdownCode Text
code
    -- Code
    code :: Text
code = [Text] -> Text
T.concat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ [] [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++
        if [Text] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
brivlaList then [] else [Text
"### Brivla\n", Text
brivlaCode, Text
"\n\n"] [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++
        if [Text] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
cmavoList then [] else [Text
"### Cmavo\n", Text
cmavoCode, Text
"\n\n"]
    cmavoCode :: Text
cmavoCode = [Text] -> Text
handleWordList [Text]
cmavoList
    brivlaCode :: Text
brivlaCode = [Text] -> Text
handleWordList [Text]
brivlaList
    -- Word lists
    cmavoList :: [Text]
cmavoList = Vocabulary -> [Text]
vocabularyCmavoList Vocabulary
vocabulary
    brivlaList :: [Text]
brivlaList = Vocabulary -> [Text]
vocabularyBrivlaList Vocabulary
vocabulary
    -- Hanndle word list
    handleWordList :: [T.Text] -> T.Text
    handleWordList :: [Text] -> Text
handleWordList = Text -> [Text] -> Text
T.intercalate Text
"\n\n" ([Text] -> Text) -> ([Text] -> [Text]) -> [Text] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
handleWord
    -- Handle word
    handleWord :: T.Text -> T.Text
    handleWord :: Text -> Text
handleWord Text
word = [Text] -> Text
T.concat [Text
"<span class=\"definition-head\">", Text
word, Text
"</span> ", Dictionary -> Text -> Text
dictLookupValsiDefinition Dictionary
dictionary Text
word]