{-# LANGUAGE LambdaCase           #-}
{-# LANGUAGE OverloadedStrings    #-}
{-# LANGUAGE ScopedTypeVariables  #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{- |
   Module      : Text.Pandoc.Lua.Marshaling.ReaderOptions
   Copyright   : © 2012-2020 John MacFarlane
                 © 2017-2020 Albert Krewinkel
   License     : GNU GPL, version 2 or above

   Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
   Stability   : alpha

Marshaling instance for ReaderOptions and its components.
-}
module Text.Pandoc.Lua.Marshaling.ReaderOptions () where

import Data.Data (showConstr, toConstr)
import Foreign.Lua (Lua, Pushable)
import Text.Pandoc.Extensions (Extensions)
import Text.Pandoc.Lua.Marshaling.AnyValue (AnyValue (..))
import Text.Pandoc.Lua.Marshaling.CommonState ()
import Text.Pandoc.Options (ReaderOptions (..), TrackChanges)

import qualified Data.Set as Set
import qualified Data.Text as Text
import qualified Foreign.Lua as Lua
import qualified Text.Pandoc.Lua.Util as LuaUtil

--
-- Reader Options
--
instance Pushable Extensions where
  push :: Extensions -> Lua ()
push exts :: Extensions
exts = String -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push (Extensions -> String
forall a. Show a => a -> String
show Extensions
exts)

instance Pushable TrackChanges where
  push :: TrackChanges -> Lua ()
push = String -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push (String -> Lua ())
-> (TrackChanges -> String) -> TrackChanges -> Lua ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constr -> String
showConstr (Constr -> String)
-> (TrackChanges -> Constr) -> TrackChanges -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TrackChanges -> Constr
forall a. Data a => a -> Constr
toConstr

instance Pushable ReaderOptions where
  push :: ReaderOptions -> Lua ()
push ro :: ReaderOptions
ro = do
    let ReaderOptions
          (Extensions
extensions            :: Extensions)
          (Bool
standalone            :: Bool)
          (Int
columns               :: Int)
          (Int
tabStop               :: Int)
          ([Text]
indentedCodeClasses   :: [Text.Text])
          (Set Text
abbreviations         :: Set.Set Text.Text)
          (Text
defaultImageExtension :: Text.Text)
          (TrackChanges
trackChanges          :: TrackChanges)
          (Bool
stripComments         :: Bool)
          = ReaderOptions
ro
    Lua ()
Lua.newtable
    String -> Extensions -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField "extensions" Extensions
extensions
    String -> Bool -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField "standalone" Bool
standalone
    String -> Int -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField "columns" Int
columns
    String -> Int -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField "tab_stop" Int
tabStop
    String -> [Text] -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField "indented_code_classes" [Text]
indentedCodeClasses
    String -> Set Text -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField "abbreviations" Set Text
abbreviations
    String -> Text -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField "default_image_extension" Text
defaultImageExtension
    String -> TrackChanges -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField "track_changes" TrackChanges
trackChanges
    String -> Bool -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField "strip_comments" Bool
stripComments

    -- add metatable
    let indexReaderOptions :: AnyValue -> AnyValue -> Lua Lua.NumResults
        indexReaderOptions :: AnyValue -> AnyValue -> Lua NumResults
indexReaderOptions _tbl :: AnyValue
_tbl (AnyValue key :: StackIndex
key) = do
          StackIndex -> Lua Type
Lua.ltype StackIndex
key Lua Type -> (Type -> Lua ()) -> Lua ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
            Lua.TypeString -> StackIndex -> Lua Text
forall a. Peekable a => StackIndex -> Lua a
Lua.peek StackIndex
key Lua Text -> (Text -> Lua ()) -> Lua ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
              (Text
"defaultImageExtension" :: Text.Text)
                                    -> Text -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push Text
defaultImageExtension
              "indentedCodeClasses" -> [Text] -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push [Text]
indentedCodeClasses
              "stripComments" -> Bool -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push Bool
stripComments
              "tabStop" -> Int -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push Int
tabStop
              "trackChanges" -> TrackChanges -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push TrackChanges
trackChanges
              _ -> Lua ()
Lua.pushnil
            _ -> Lua ()
Lua.pushnil
          NumResults -> Lua NumResults
forall (m :: * -> *) a. Monad m => a -> m a
return 1
    Lua ()
Lua.newtable
    String -> (AnyValue -> AnyValue -> Lua NumResults) -> Lua ()
forall a. ToHaskellFunction a => String -> a -> Lua ()
LuaUtil.addFunction "__index" AnyValue -> AnyValue -> Lua NumResults
indexReaderOptions
    StackIndex -> Lua ()
Lua.setmetatable (CInt -> StackIndex
Lua.nthFromTop 2)