aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aeson-pretty/Data/Aeson/Encode/Pretty.hs208
-rw-r--r--pandoc.cabal10
-rw-r--r--stack.yaml2
3 files changed, 5 insertions, 215 deletions
diff --git a/aeson-pretty/Data/Aeson/Encode/Pretty.hs b/aeson-pretty/Data/Aeson/Encode/Pretty.hs
deleted file mode 100644
index 5cef52295..000000000
--- a/aeson-pretty/Data/Aeson/Encode/Pretty.hs
+++ /dev/null
@@ -1,208 +0,0 @@
-{-# LANGUAGE OverloadedStrings, RecordWildCards #-}
-
--- |Aeson-compatible pretty-printing of JSON 'Value's.
-module Data.Aeson.Encode.Pretty (
- -- * Simple Pretty-Printing
- encodePretty, encodePrettyToTextBuilder,
-
- -- * Pretty-Printing with Configuration Options
- encodePretty', encodePrettyToTextBuilder',
- Config (..), defConfig,
- Indent(..), NumberFormat(..),
- -- ** Sorting Keys in Objects
- -- |With the Aeson library, the order of keys in objects is undefined due to
- -- objects being implemented as HashMaps. To allow user-specified key
- -- orders in the pretty-printed JSON, 'encodePretty'' can be configured
- -- with a comparison function. These comparison functions can be composed
- -- using the 'Monoid' interface. Some other useful helper functions to keep
- -- in mind are 'comparing' and 'on'.
- --
- -- Consider the following deliberately convoluted example, demonstrating
- -- the use of comparison functions:
- --
- -- An object might pretty-print as follows
- --
- -- > {
- -- > "baz": ...,
- -- > "bar": ...,
- -- > "foo": ...,
- -- > "quux": ...,
- -- > }
- --
- -- which is clearly a confusing order of keys. By using a comparison
- -- function such as
- --
- -- > comp :: Text -> Text -> Ordering
- -- > comp = keyOrder ["foo","bar"] `mappend` comparing length
- --
- -- we can achieve the desired neat result:
- --
- -- > {
- -- > "foo": ...,
- -- > "bar": ...,
- -- > "baz": ...,
- -- > "quux": ...,
- -- > }
- --
-
- mempty,
- -- |Serves as an order-preserving (non-)sort function. Re-exported from
- -- "Data.Monoid".
- compare,
- -- |Sort keys in their natural order, i.e. by comparing character codes.
- -- Re-exported from the Prelude and "Data.Ord"
- keyOrder
-) where
-
-import Data.Aeson (Value(..), ToJSON(..))
-import qualified Data.Aeson.Text as Aeson
-import Data.ByteString.Lazy (ByteString)
-import Data.Function (on)
-import qualified Data.HashMap.Strict as H (toList)
-import Data.List (intersperse, sortBy, elemIndex)
-import Data.Maybe (fromMaybe)
-import Data.Semigroup ((<>))
-import qualified Data.Scientific as S (Scientific, FPFormat(..))
-import Data.Ord (comparing)
-import Data.Text (Text)
-import Data.Text.Lazy.Builder (Builder, toLazyText)
-import Data.Text.Lazy.Builder.Scientific (formatScientificBuilder)
-import Data.Text.Lazy.Encoding (encodeUtf8)
-import qualified Data.Vector as V (toList)
-import Prelude ()
-import Prelude.Compat
-
-
-data PState = PState { pLevel :: Int
- , pIndent :: Builder
- , pNewline :: Builder
- , pItemSep :: Builder
- , pKeyValSep :: Builder
- , pNumFormat :: NumberFormat
- , pSort :: [(Text, Value)] -> [(Text, Value)]
- }
-
--- | Indentation per level of nesting. @'Spaces' 0@ removes __all__ whitespace
--- from the output.
-data Indent = Spaces Int | Tab
-
-data NumberFormat
- -- | The standard behaviour of the 'Aeson.encode' function. Uses
- -- integer literals for integers (1, 2, 3...), simple decimals
- -- for fractional values between 0.1 and 9,999,999, and scientific
- -- notation otherwise.
- = Generic
- -- | Scientific notation (e.g. 2.3e123).
- | Scientific
- -- | Standard decimal notation
- | Decimal
- -- | Custom formatting function
- | Custom (S.Scientific -> Builder)
-
-data Config = Config
- { confIndent :: Indent
- -- ^ Indentation per level of nesting
- , confCompare :: Text -> Text -> Ordering
- -- ^ Function used to sort keys in objects
- , confNumFormat :: NumberFormat
- , confTrailingNewline :: Bool
- -- ^ Whether to add a trailing newline to the output
- }
-
--- |Sort keys by their order of appearance in the argument list.
---
--- Keys that are not present in the argument list are considered to be greater
--- than any key in the list and equal to all keys not in the list. I.e. keys
--- not in the argument list are moved to the end, while their order is
--- preserved.
-keyOrder :: [Text] -> Text -> Text -> Ordering
-keyOrder ks = comparing $ \k -> fromMaybe maxBound (elemIndex k ks)
-
-
--- |The default configuration: indent by four spaces per level of nesting, do
--- not sort objects by key, do not add trailing newline.
---
--- > defConfig = Config { confIndent = Spaces 4, confCompare = mempty, confNumFormat = Generic, confTrailingNewline = False }
-defConfig :: Config
-defConfig =
- Config {confIndent = Spaces 4, confCompare = mempty, confNumFormat = Generic, confTrailingNewline = False}
-
--- |A drop-in replacement for aeson's 'Aeson.encode' function, producing
--- JSON-ByteStrings for human readers.
---
--- Follows the default configuration in 'defConfig'.
-encodePretty :: ToJSON a => a -> ByteString
-encodePretty = encodePretty' defConfig
-
--- |A variant of 'encodePretty' that takes an additional configuration
--- parameter.
-encodePretty' :: ToJSON a => Config -> a -> ByteString
-encodePretty' conf = encodeUtf8 . toLazyText . encodePrettyToTextBuilder' conf
-
--- |A drop-in replacement for aeson's 'Aeson.encodeToTextBuilder' function,
--- producing JSON-ByteStrings for human readers.
---
--- Follows the default configuration in 'defConfig'.
-encodePrettyToTextBuilder :: ToJSON a => a -> Builder
-encodePrettyToTextBuilder = encodePrettyToTextBuilder' defConfig
-
--- |A variant of 'encodeToTextBuilder' that takes an additional configuration
--- parameter.
-encodePrettyToTextBuilder' :: ToJSON a => Config -> a -> Builder
-encodePrettyToTextBuilder' Config{..} x = fromValue st (toJSON x) <> trail
- where
- st = PState 0 indent newline itemSep kvSep confNumFormat sortFn
- indent = case confIndent of
- Spaces n -> mconcat (replicate n " ")
- Tab -> "\t"
- newline = case confIndent of
- Spaces 0 -> ""
- _ -> "\n"
- itemSep = ","
- kvSep = case confIndent of
- Spaces 0 -> ":"
- _ -> ": "
- sortFn = sortBy (confCompare `on` fst)
- trail = if confTrailingNewline then "\n" else ""
-
-
-fromValue :: PState -> Value -> Builder
-fromValue st@PState{..} val = go val
- where
- go (Array v) = fromCompound st ("[","]") fromValue (V.toList v)
- go (Object m) = fromCompound st ("{","}") fromPair (pSort (H.toList m))
- go (Number x) = fromNumber st x
- go v = Aeson.encodeToTextBuilder v
-
-fromCompound :: PState
- -> (Builder, Builder)
- -> (PState -> a -> Builder)
- -> [a]
- -> Builder
-fromCompound st@PState{..} (delimL,delimR) fromItem items = mconcat
- [ delimL
- , if null items then mempty
- else pNewline <> items' <> pNewline <> fromIndent st
- , delimR
- ]
- where
- items' = mconcat . intersperse (pItemSep <> pNewline) $
- map (\item -> fromIndent st' <> fromItem st' item)
- items
- st' = st { pLevel = pLevel + 1}
-
-fromPair :: PState -> (Text, Value) -> Builder
-fromPair st (k,v) =
- Aeson.encodeToTextBuilder (toJSON k) <> pKeyValSep st <> fromValue st v
-
-fromIndent :: PState -> Builder
-fromIndent PState{..} = mconcat (replicate pLevel pIndent)
-
-fromNumber :: PState -> S.Scientific -> Builder
-fromNumber st x = case pNumFormat st of
- Generic
- | (x > 1.0e19 || x < -1.0e19) -> formatScientificBuilder S.Exponent Nothing x
- | otherwise -> Aeson.encodeToTextBuilder $ Number x
- Scientific -> formatScientificBuilder S.Exponent Nothing x
- Decimal -> formatScientificBuilder S.Fixed Nothing x
- Custom f -> f x
diff --git a/pandoc.cabal b/pandoc.cabal
index 499019106..538020eb4 100644
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -340,8 +340,6 @@ custom-setup
library
build-depends: base >= 4.7 && < 5,
- base-compat,
- scientific,
syb >= 0.1 && < 0.8,
containers >= 0.4.2.1 && < 0.6,
unordered-containers >= 0.2 && < 0.3,
@@ -388,7 +386,8 @@ library
http-client-tls >= 0.2.4 && < 0.4,
http-types >= 0.8 && < 0.13,
case-insensitive >= 1.2 && < 1.3,
- HsYAML >= 0.1.1.1 && < 0.2
+ HsYAML >= 0.1.1.1 && < 0.2,
+ aeson-pretty >= 0.8.5 && < 0.9
if impl(ghc < 8.0)
build-depends: semigroups == 0.18.*,
-- basement 0.0.8 and foundation 0.0.21, transitive
@@ -412,7 +411,7 @@ library
ghc-options: -Wall -fno-warn-unused-do-bind
default-language: Haskell2010
other-extensions: NoImplicitPrelude
- hs-source-dirs: src, aeson-pretty
+ hs-source-dirs: src
exposed-modules: Text.Pandoc,
Text.Pandoc.App,
@@ -543,8 +542,7 @@ library
Text.Pandoc.UUID,
Text.Pandoc.Translations,
Text.Pandoc.Slides,
- Paths_pandoc,
- Data.Aeson.Encode.Pretty
+ Paths_pandoc
autogen-modules: Paths_pandoc
buildable: True
diff --git a/stack.yaml b/stack.yaml
index 5b973ef6d..ba6ffd7c5 100644
--- a/stack.yaml
+++ b/stack.yaml
@@ -20,7 +20,7 @@ packages:
extra-dep: true
extra-deps:
- github: jgm/pandoc-citeproc
- commit: 626b16ef8cfc71f54f5fdccf680f41e51d356f80
+ commit: 596872a5a5dec15f4c8848cf87dd72e0ef2f160d
- haddock-library-1.6.0
- HsYAML-0.1.1.1
- yaml-0.9.0