{-# 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 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 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 String
"extensions" Extensions
extensions
    String -> Bool -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField String
"standalone" Bool
standalone
    String -> Int -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField String
"columns" Int
columns
    String -> Int -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField String
"tab_stop" Int
tabStop
    String -> [Text] -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField String
"indented_code_classes" [Text]
indentedCodeClasses
    String -> Set Text -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField String
"abbreviations" Set Text
abbreviations
    String -> Text -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField String
"default_image_extension" Text
defaultImageExtension
    String -> TrackChanges -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField String
"track_changes" TrackChanges
trackChanges
    String -> Bool -> Lua ()
forall a. Pushable a => String -> a -> Lua ()
LuaUtil.addField String
"strip_comments" Bool
stripComments

    -- add metatable
    let indexReaderOptions :: AnyValue -> AnyValue -> Lua Lua.NumResults
        indexReaderOptions :: AnyValue -> AnyValue -> Lua NumResults
indexReaderOptions AnyValue
_tbl (AnyValue 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
            Type
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
              Text
"indentedCodeClasses" -> [Text] -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push [Text]
indentedCodeClasses
              Text
"stripComments" -> Bool -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push Bool
stripComments
              Text
"tabStop" -> Int -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push Int
tabStop
              Text
"trackChanges" -> TrackChanges -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push TrackChanges
trackChanges
              Text
_ -> Lua ()
Lua.pushnil
            Type
_ -> Lua ()
Lua.pushnil
          NumResults -> Lua NumResults
forall (m :: * -> *) a. Monad m => a -> m a
return NumResults
1
    Lua ()
Lua.newtable
    String -> (AnyValue -> AnyValue -> Lua NumResults) -> Lua ()
forall a. ToHaskellFunction a => String -> a -> Lua ()
LuaUtil.addFunction String
"__index" AnyValue -> AnyValue -> Lua NumResults
indexReaderOptions
    StackIndex -> Lua ()
Lua.setmetatable (CInt -> StackIndex
Lua.nthFromTop CInt
2)