/src/Text/Pandoc/Lua/Marshal/ReaderOptions.hs

https://github.com/jgm/pandoc · Haskell · 137 lines · 93 code · 10 blank · 34 comment · 0 complexity · dc1961f3b4e907b880a1696b35404042 MD5 · raw file

  1. {-# LANGUAGE CPP #-}
  2. {-# LANGUAGE LambdaCase #-}
  3. {-# LANGUAGE OverloadedStrings #-}
  4. {-# LANGUAGE ScopedTypeVariables #-}
  5. {-# OPTIONS_GHC -fno-warn-orphans #-}
  6. {- |
  7. Module : Text.Pandoc.Lua.Marshaling.ReaderOptions
  8. Copyright : © 2012-2022 John MacFarlane
  9. © 2017-2022 Albert Krewinkel
  10. License : GNU GPL, version 2 or above
  11. Maintainer : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
  12. Stability : alpha
  13. Marshaling instance for ReaderOptions and its components.
  14. -}
  15. module Text.Pandoc.Lua.Marshal.ReaderOptions
  16. ( peekReaderOptions
  17. , pushReaderOptions
  18. , pushReaderOptionsReadonly
  19. ) where
  20. import Data.Default (def)
  21. import HsLua as Lua
  22. #if !MIN_VERSION_hslua(2,2,0)
  23. import HsLua.Aeson (peekViaJSON, pushViaJSON)
  24. #endif
  25. import Text.Pandoc.Lua.Marshal.List (pushPandocList)
  26. import Text.Pandoc.Options (ReaderOptions (..))
  27. --
  28. -- Reader Options
  29. --
  30. -- | Retrieve a ReaderOptions value, either from a normal ReaderOptions
  31. -- value, from a read-only object, or from a table with the same
  32. -- keys as a ReaderOptions object.
  33. peekReaderOptions :: LuaError e => Peeker e ReaderOptions
  34. peekReaderOptions = retrieving "ReaderOptions" . \idx ->
  35. liftLua (ltype idx) >>= \case
  36. TypeUserdata -> choice [ peekUD typeReaderOptions
  37. , peekUD typeReaderOptionsReadonly
  38. ]
  39. idx
  40. TypeTable -> peekReaderOptionsTable idx
  41. _ -> failPeek =<<
  42. typeMismatchMessage "ReaderOptions userdata or table" idx
  43. -- | Pushes a ReaderOptions value as userdata object.
  44. pushReaderOptions :: LuaError e => Pusher e ReaderOptions
  45. pushReaderOptions = pushUD typeReaderOptions
  46. -- | Pushes a ReaderOptions object, but makes it read-only.
  47. pushReaderOptionsReadonly :: LuaError e => Pusher e ReaderOptions
  48. pushReaderOptionsReadonly = pushUD typeReaderOptionsReadonly
  49. -- | ReaderOptions object type for read-only values.
  50. typeReaderOptionsReadonly :: LuaError e => DocumentedType e ReaderOptions
  51. typeReaderOptionsReadonly = deftype "ReaderOptions (read-only)"
  52. [ operation Tostring $ lambda
  53. ### liftPure show
  54. <#> udparam typeReaderOptions "opts" "options to print in native format"
  55. =#> functionResult pushString "string" "Haskell representation"
  56. , operation Newindex $ lambda
  57. ### (failLua "This ReaderOptions value is read-only.")
  58. =?> "Throws an error when called, i.e., an assignment is made."
  59. ]
  60. readerOptionsMembers
  61. -- | 'ReaderOptions' object type.
  62. typeReaderOptions :: LuaError e => DocumentedType e ReaderOptions
  63. typeReaderOptions = deftype "ReaderOptions"
  64. [ operation Tostring $ lambda
  65. ### liftPure show
  66. <#> udparam typeReaderOptions "opts" "options to print in native format"
  67. =#> functionResult pushString "string" "Haskell representation"
  68. ]
  69. readerOptionsMembers
  70. -- | Member properties of 'ReaderOptions' Lua values.
  71. readerOptionsMembers :: LuaError e
  72. => [Member e (DocumentedFunction e) ReaderOptions]
  73. readerOptionsMembers =
  74. [ property "abbreviations" ""
  75. (pushSet pushText, readerAbbreviations)
  76. (peekSet peekText, \opts x -> opts{ readerAbbreviations = x })
  77. , property "columns" ""
  78. (pushIntegral, readerColumns)
  79. (peekIntegral, \opts x -> opts{ readerColumns = x })
  80. , property "default_image_extension" ""
  81. (pushText, readerDefaultImageExtension)
  82. (peekText, \opts x -> opts{ readerDefaultImageExtension = x })
  83. , property "extensions" ""
  84. (pushViaJSON, readerExtensions)
  85. (peekViaJSON, \opts x -> opts{ readerExtensions = x })
  86. , property "indented_code_classes" ""
  87. (pushPandocList pushText, readerIndentedCodeClasses)
  88. (peekList peekText, \opts x -> opts{ readerIndentedCodeClasses = x })
  89. , property "standalone" ""
  90. (pushBool, readerStandalone)
  91. (peekBool, \opts x -> opts{ readerStandalone = x })
  92. , property "strip_comments" ""
  93. (pushBool, readerStripComments)
  94. (peekBool, \opts x -> opts{ readerStripComments = x })
  95. , property "tab_stop" ""
  96. (pushIntegral, readerTabStop)
  97. (peekIntegral, \opts x -> opts{ readerTabStop = x })
  98. , property "track_changes" ""
  99. (pushViaJSON, readerTrackChanges)
  100. (choice [peekRead, peekViaJSON], \opts x -> opts{ readerTrackChanges = x })
  101. ]
  102. -- | Retrieves a 'ReaderOptions' object from a table on the stack, using
  103. -- the default values for all missing fields.
  104. --
  105. -- Internally, this pushes the default reader options, sets each
  106. -- key/value pair of the table in the userdata value, then retrieves the
  107. -- object again. This will update all fields and complain about unknown
  108. -- keys.
  109. peekReaderOptionsTable :: LuaError e => Peeker e ReaderOptions
  110. peekReaderOptionsTable idx = retrieving "ReaderOptions (table)" $ do
  111. liftLua $ do
  112. absidx <- absindex idx
  113. pushUD typeReaderOptions def
  114. let setFields = do
  115. next absidx >>= \case
  116. False -> return () -- all fields were copied
  117. True -> do
  118. pushvalue (nth 2) *> insert (nth 2)
  119. settable (nth 4) -- set in userdata object
  120. setFields
  121. pushnil -- first key
  122. setFields
  123. peekUD typeReaderOptions top `lastly` pop 1
  124. instance Pushable ReaderOptions where
  125. push = pushReaderOptions