packages feed

nestedtext (empty) → 0.1.2

raw patch · 306 files changed

+5571/−0 lines, 306 filesdep +basedep +binarydep +bytestring

Dependencies added: base, binary, bytestring, containers, directory, filepath, free, generic-data, hedgehog, json, microlens-platform, nestedtext, pipes, pipes-parse, pipes-text, tasty, tasty-hedgehog, tasty-hunit, text, text-short, transformers, vector

Files

+ CHANGELOG.md view
@@ -0,0 +1,17 @@+# Revision history for nestedtext++## 0.1.2 -- 2025/02/16++* fix(test/Official): Disable empty\_1 test+* fix(test/Official): Read/Write with native newline+* fix(vendor): CRLF for windows++## 0.1.1 -- 2025/02/11++* fix(nestedtext.cabal): Remove unused dependency+* fix(Parse): Recognize CR and CRLF as a newline+* fix(Serialize): Do not allow inline key starts with shape symbol++## 0.1.0 -- 2025/02/11++* First version.
+ LICENSE view
@@ -0,0 +1,202 @@++                                 Apache License+                           Version 2.0, January 2004+                        http://www.apache.org/licenses/++   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION++   1. Definitions.++      "License" shall mean the terms and conditions for use, reproduction,+      and distribution as defined by Sections 1 through 9 of this document.++      "Licensor" shall mean the copyright owner or entity authorized by+      the copyright owner that is granting the License.++      "Legal Entity" shall mean the union of the acting entity and all+      other entities that control, are controlled by, or are under common+      control with that entity. For the purposes of this definition,+      "control" means (i) the power, direct or indirect, to cause the+      direction or management of such entity, whether by contract or+      otherwise, or (ii) ownership of fifty percent (50%) or more of the+      outstanding shares, or (iii) beneficial ownership of such entity.++      "You" (or "Your") shall mean an individual or Legal Entity+      exercising permissions granted by this License.++      "Source" form shall mean the preferred form for making modifications,+      including but not limited to software source code, documentation+      source, and configuration files.++      "Object" form shall mean any form resulting from mechanical+      transformation or translation of a Source form, including but+      not limited to compiled object code, generated documentation,+      and conversions to other media types.++      "Work" shall mean the work of authorship, whether in Source or+      Object form, made available under the License, as indicated by a+      copyright notice that is included in or attached to the work+      (an example is provided in the Appendix below).++      "Derivative Works" shall mean any work, whether in Source or Object+      form, that is based on (or derived from) the Work and for which the+      editorial revisions, annotations, elaborations, or other modifications+      represent, as a whole, an original work of authorship. For the purposes+      of this License, Derivative Works shall not include works that remain+      separable from, or merely link (or bind by name) to the interfaces of,+      the Work and Derivative Works thereof.++      "Contribution" shall mean any work of authorship, including+      the original version of the Work and any modifications or additions+      to that Work or Derivative Works thereof, that is intentionally+      submitted to Licensor for inclusion in the Work by the copyright owner+      or by an individual or Legal Entity authorized to submit on behalf of+      the copyright owner. For the purposes of this definition, "submitted"+      means any form of electronic, verbal, or written communication sent+      to the Licensor or its representatives, including but not limited to+      communication on electronic mailing lists, source code control systems,+      and issue tracking systems that are managed by, or on behalf of, the+      Licensor for the purpose of discussing and improving the Work, but+      excluding communication that is conspicuously marked or otherwise+      designated in writing by the copyright owner as "Not a Contribution."++      "Contributor" shall mean Licensor and any individual or Legal Entity+      on behalf of whom a Contribution has been received by Licensor and+      subsequently incorporated within the Work.++   2. Grant of Copyright License. Subject to the terms and conditions of+      this License, each Contributor hereby grants to You a perpetual,+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable+      copyright license to reproduce, prepare Derivative Works of,+      publicly display, publicly perform, sublicense, and distribute the+      Work and such Derivative Works in Source or Object form.++   3. Grant of Patent License. Subject to the terms and conditions of+      this License, each Contributor hereby grants to You a perpetual,+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable+      (except as stated in this section) patent license to make, have made,+      use, offer to sell, sell, import, and otherwise transfer the Work,+      where such license applies only to those patent claims licensable+      by such Contributor that are necessarily infringed by their+      Contribution(s) alone or by combination of their Contribution(s)+      with the Work to which such Contribution(s) was submitted. If You+      institute patent litigation against any entity (including a+      cross-claim or counterclaim in a lawsuit) alleging that the Work+      or a Contribution incorporated within the Work constitutes direct+      or contributory patent infringement, then any patent licenses+      granted to You under this License for that Work shall terminate+      as of the date such litigation is filed.++   4. Redistribution. You may reproduce and distribute copies of the+      Work or Derivative Works thereof in any medium, with or without+      modifications, and in Source or Object form, provided that You+      meet the following conditions:++      (a) You must give any other recipients of the Work or+          Derivative Works a copy of this License; and++      (b) You must cause any modified files to carry prominent notices+          stating that You changed the files; and++      (c) You must retain, in the Source form of any Derivative Works+          that You distribute, all copyright, patent, trademark, and+          attribution notices from the Source form of the Work,+          excluding those notices that do not pertain to any part of+          the Derivative Works; and++      (d) If the Work includes a "NOTICE" text file as part of its+          distribution, then any Derivative Works that You distribute must+          include a readable copy of the attribution notices contained+          within such NOTICE file, excluding those notices that do not+          pertain to any part of the Derivative Works, in at least one+          of the following places: within a NOTICE text file distributed+          as part of the Derivative Works; within the Source form or+          documentation, if provided along with the Derivative Works; or,+          within a display generated by the Derivative Works, if and+          wherever such third-party notices normally appear. The contents+          of the NOTICE file are for informational purposes only and+          do not modify the License. You may add Your own attribution+          notices within Derivative Works that You distribute, alongside+          or as an addendum to the NOTICE text from the Work, provided+          that such additional attribution notices cannot be construed+          as modifying the License.++      You may add Your own copyright statement to Your modifications and+      may provide additional or different license terms and conditions+      for use, reproduction, or distribution of Your modifications, or+      for any such Derivative Works as a whole, provided Your use,+      reproduction, and distribution of the Work otherwise complies with+      the conditions stated in this License.++   5. Submission of Contributions. Unless You explicitly state otherwise,+      any Contribution intentionally submitted for inclusion in the Work+      by You to the Licensor shall be under the terms and conditions of+      this License, without any additional terms or conditions.+      Notwithstanding the above, nothing herein shall supersede or modify+      the terms of any separate license agreement you may have executed+      with Licensor regarding such Contributions.++   6. Trademarks. This License does not grant permission to use the trade+      names, trademarks, service marks, or product names of the Licensor,+      except as required for reasonable and customary use in describing the+      origin of the Work and reproducing the content of the NOTICE file.++   7. Disclaimer of Warranty. Unless required by applicable law or+      agreed to in writing, Licensor provides the Work (and each+      Contributor provides its Contributions) on an "AS IS" BASIS,+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or+      implied, including, without limitation, any warranties or conditions+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A+      PARTICULAR PURPOSE. You are solely responsible for determining the+      appropriateness of using or redistributing the Work and assume any+      risks associated with Your exercise of permissions under this License.++   8. Limitation of Liability. In no event and under no legal theory,+      whether in tort (including negligence), contract, or otherwise,+      unless required by applicable law (such as deliberate and grossly+      negligent acts) or agreed to in writing, shall any Contributor be+      liable to You for damages, including any direct, indirect, special,+      incidental, or consequential damages of any character arising as a+      result of this License or out of the use or inability to use the+      Work (including but not limited to damages for loss of goodwill,+      work stoppage, computer failure or malfunction, or any and all+      other commercial damages or losses), even if such Contributor+      has been advised of the possibility of such damages.++   9. Accepting Warranty or Additional Liability. While redistributing+      the Work or Derivative Works thereof, You may choose to offer,+      and charge a fee for, acceptance of support, warranty, indemnity,+      or other liability obligations and/or rights consistent with this+      License. However, in accepting such obligations, You may act only+      on Your own behalf and on Your sole responsibility, not on behalf+      of any other Contributor, and only if You agree to indemnify,+      defend, and hold each Contributor harmless for any liability+      incurred by, or claims asserted against, such Contributor by reason+      of your accepting any such warranty or additional liability.++   END OF TERMS AND CONDITIONS++   APPENDIX: How to apply the Apache License to your work.++      To apply the Apache License to your work, attach the following+      boilerplate notice, with the fields enclosed by brackets "[]"+      replaced with your own identifying information. (Don't include+      the brackets!)  The text should be enclosed in the appropriate+      comment syntax for the file format. We also recommend that a+      file or class name and description of purpose be included on the+      same "printed page" as the copyright notice for easier+      identification within third-party archives.++   Copyright 2025 0y2k++   Licensed under the Apache License, Version 2.0 (the "License");+   you may not use this file except in compliance with the License.+   You may obtain a copy of the License at++       http://www.apache.org/licenses/LICENSE-2.0++   Unless required by applicable law or agreed to in writing, software+   distributed under the License is distributed on an "AS IS" BASIS,+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+   See the License for the specific language governing permissions and+   limitations under the License.
+ README.md view
@@ -0,0 +1,5 @@+# Haskell implementation of NestedText++## Compatible version of NestedText++3.7
+ nestedtext.cabal view
@@ -0,0 +1,90 @@+cabal-version:      3.8+name:               nestedtext+version:            0.1.2+synopsis:           NestedText: A Human Friendly Data Format+description:+    Haskell implementation of [NestedText](https://nestedtext.org/) 3.7+    parser and serializer.+category:           Data+license:            Apache-2.0+license-file:       LICENSE+homepage:           https://github.com/0y2k/nestedtext-haskell+bug-reports:        https://github.com/0y2k/nestedtext-haskell/issues+author:             0y2k <0x0y2k@gmail.com>+maintainer:         0y2k <0x0y2k@gmail.com>+copyright:          (c) 2025 0y2k+build-type:         Simple+extra-doc-files:+    CHANGELOG.md,+    README.md,+    vendor/github.com/KenKundert/nestedtext_tests/README.md,+extra-source-files:+    vendor/github.com/KenKundert/nestedtext_tests/test_cases/**/load_in.nt,+    vendor/github.com/KenKundert/nestedtext_tests/test_cases/**/load_out.json,+    vendor/github.com/KenKundert/nestedtext_tests/test_cases/**/load_err.json,+    vendor/github.com/KenKundert/nestedtext_tests/test_cases/**/dump_in.json,+    vendor/github.com/KenKundert/nestedtext_tests/test_cases/**/dump_in.py,+    vendor/github.com/KenKundert/nestedtext_tests/test_cases/**/dump_out.nt,+    vendor/github.com/KenKundert/nestedtext_tests/test_cases/**/dump_err.json,++source-repository head+    type:     git+    location: https://github.com/0y2k/nestedtext-haskell++common depends+    build-depends:+        base >= 4.17 && < 4.22,+        bytestring >= 0.11 && < 0.13,+        containers >= 0.6.5 && < 0.8,+        microlens-platform >= 0.4.3.1 && < 0.5,+        pipes >= 4.0 && < 4.4,+        pipes-text >= 1.0 && < 1.1,+        text >= 2.0 && < 2.2,+        text-short >= 0.1 && < 0.2,+        vector >= 0.13 && < 0.14,++common warnings+    ghc-options: -Wall++library+    import:           depends, warnings+    default-language: Haskell2010+    hs-source-dirs:   src+    build-depends:+        binary >= 0.8 && < 0.9,+        free >= 3.2 && < 5.3,+        generic-data >= 1.1 && < 1.2,+        pipes-parse >= 3.0 && < 3.1,+        transformers >= 0.6 && < 0.7,+    exposed-modules:+        Data.NestedText,+        Data.NestedText.Decode,+        Data.NestedText.Encode,+        Data.NestedText.From,+        Data.NestedText.Parse,+        Data.NestedText.Serialize,+        Data.NestedText.To,+        Data.NestedText.Type,+        Data.NestedText.Util,++test-suite nested-text-test+    import:           depends, warnings+    default-language: Haskell2010+    hs-source-dirs:   test+    main-is:          Main.hs+    type:             exitcode-stdio-1.0+    build-tool-depends:+        tasty-discover:tasty-discover+    build-depends:+        nestedtext,+        directory,+        filepath,+        hedgehog,+        json,+        tasty,+        tasty-hedgehog,+        tasty-hunit,+    other-modules:+        Official,+        Property,+        Util,
+ src/Data/NestedText.hs view
@@ -0,0 +1,11 @@+module Data.NestedText+  ( module X+  ) where++import Data.NestedText.Decode as X+import Data.NestedText.Encode as X+import Data.NestedText.From as X+import Data.NestedText.Parse as X+import Data.NestedText.Serialize as X+import Data.NestedText.To as X+import Data.NestedText.Type as X
+ src/Data/NestedText/Decode.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE UndecidableInstances #-}++module Data.NestedText.Decode where++import Data.Bifunctor (first)+import qualified Data.Text.Lazy as TL+import Generic.Data++import Data.NestedText.From+import Data.NestedText.Parse++data DecodeError a+  = DecodeError'ParseError ParseError+  | DecodeError'FromItemError (FromItemError a)+  deriving (Generic)+instance Eq (FromItemError a) => Eq (DecodeError a) where+  (==) = geq+instance Show (FromItemError a) => Show (DecodeError a) where+  showsPrec = gshowsPrec++decode :: FromItem a => TL.Text -> Either (DecodeError a) a+decode ts = do+  item <- first DecodeError'ParseError $ parse ts+  first DecodeError'FromItemError $ fromItem item
+ src/Data/NestedText/Encode.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE UndecidableInstances #-}++module Data.NestedText.Encode where++import Data.Bifunctor (first)+import qualified Data.Text.Lazy as TL+import Generic.Data++import Data.NestedText.To+import Data.NestedText.Serialize++data EncodeError a+  = EncodeError'ToItemError (ToItemError a)+  deriving (Generic)+instance Eq (ToItemError a) => Eq (EncodeError a) where+  (==) = geq+instance Show (ToItemError a) => Show (EncodeError a) where+  showsPrec = gshowsPrec++encode :: ToItem a => a -> Either (EncodeError a) TL.Text+encode = fmap (serialize 2) . first EncodeError'ToItemError . toItem
+ src/Data/NestedText/From.hs view
@@ -0,0 +1,116 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}++module Data.NestedText.From where++import Control.Monad (forM)+import Data.Bifunctor (Bifunctor(first))+import qualified Data.Binary.Builder as BB+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString.Short as SBS+import Data.Kind (Type)+import qualified Data.Map as M+import qualified Data.Text as TS+import qualified Data.Text.Encoding as TE+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Short as ST+import qualified Data.Vector as V+import Data.Void (Void)+import Generic.Data++import Data.NestedText.Type++class FromItem a where+  type FromItemError a :: Type+  fromItem :: Item -> Either (FromItemError a) a+class Ord a => FromKey a where+  type FromKeyError a :: Type+  fromKey :: Key -> Either (FromKeyError a) a++instance FromItem Item where+  type FromItemError Item = Void+  fromItem = Right++data FromItemError'Common+  = FromItemError'Common'InvalidValue+  deriving (Generic, Eq, Show)++instance FromItem BS.ByteString where+  type FromItemError BS.ByteString = FromItemError'Common+  fromItem (Item'String t) = Right $ TE.encodeUtf8 t+  fromItem _ = Left FromItemError'Common'InvalidValue+instance FromItem BL.ByteString where+  type FromItemError BL.ByteString = FromItemError'Common+  fromItem (Item'String t) = Right $ BB.toLazyByteString $ TE.encodeUtf8Builder t+  fromItem _ = Left FromItemError'Common'InvalidValue+instance FromItem TS.Text where+  type FromItemError TS.Text = FromItemError'Common+  fromItem (Item'String t) = Right t+  fromItem _ = Left FromItemError'Common'InvalidValue+instance FromItem TL.Text where+  type FromItemError TL.Text = FromItemError'Common+  fromItem (Item'String t) = Right $ TL.fromStrict t+  fromItem _ = Left FromItemError'Common'InvalidValue++data FromItemError'List a+  = FromItemError'List'InvalidValue+  | FromItemError'List'ElementError (FromItemError a)+  deriving (Generic)+instance Eq (FromItemError a) => Eq (FromItemError'List a) where+  (==) = geq+instance Show (FromItemError a) => Show (FromItemError'List a) where+  showsPrec = gshowsPrec++instance FromItem a => FromItem [a] where+  type FromItemError [a] = FromItemError'List a+  fromItem (Item'List xs) = fmap V.toList $ V.forM xs $ \x ->+    first FromItemError'List'ElementError $ fromItem x+  fromItem _ = Left FromItemError'List'InvalidValue+instance FromItem a => FromItem (V.Vector a) where+  type FromItemError (V.Vector a) = FromItemError'List a+  fromItem (Item'List xs) = V.forM xs $ \x ->+    first FromItemError'List'ElementError $ fromItem x+  fromItem _ = Left FromItemError'List'InvalidValue++instance FromKey BS.ByteString where+  type FromKeyError BS.ByteString = Void+  fromKey st = Right $ ST.toByteString st+instance FromKey BL.ByteString where+  type FromKeyError BL.ByteString = Void+  fromKey st = Right $ BB.toLazyByteString $ ST.toBuilder st+instance FromKey SBS.ShortByteString where+  type FromKeyError SBS.ShortByteString = Void+  fromKey st = Right $ ST.toShortByteString st+instance FromKey TS.Text where+  type FromKeyError TS.Text = Void+  fromKey st = Right $ ST.toText st+instance FromKey TL.Text where+  type FromKeyError TL.Text = Void+  fromKey st = Right $ TL.fromStrict $ ST.toText st+instance FromKey ST.ShortText where+  type FromKeyError ST.ShortText = Void+  fromKey = Right++data FromItemError'Map k v+  = FromItemError'Map'InvalidValue+  | FromItemError'Map'KeyError (FromKeyError k)+  | FromItemError'Map'ValueError (FromItemError v)+  deriving (Generic)+instance (Eq (FromKeyError k), Eq (FromItemError v))+  => Eq (FromItemError'Map k v) where+    (==) = geq+instance (Show (FromKeyError k), Show (FromItemError v))+  => Show (FromItemError'Map k v) where+    showsPrec = gshowsPrec++instance (FromKey k, FromItem v) => FromItem (M.Map k v) where+  type FromItemError (M.Map k v) = FromItemError'Map k v+  fromItem (Item'Dictionary dic) =+    fmap M.fromList $ forM (M.toAscList dic) $ \(ks, vs) -> do+      kd <- first FromItemError'Map'KeyError $ fromKey ks+      vd <- first FromItemError'Map'ValueError $ fromItem vs+      return (kd, vd)+  fromItem _ = Left FromItemError'Map'InvalidValue
+ src/Data/NestedText/Parse.hs view
@@ -0,0 +1,417 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeOperators #-}++module Data.NestedText.Parse+  ( ParseError(..)+  , parse+  , parse'+  , parseDocument+  ) where++import Control.Monad (when)+import Control.Monad.Trans.Class (MonadTrans(..))+import qualified Control.Monad.Trans.State.Strict as StateT+import qualified Data.Char as C+import qualified Data.Map.Strict as M+import qualified Data.Set as S+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Vector as V+import Data.Void+import Generic.Data+import qualified Pipes as P+import qualified Pipes.Parse as PP+import qualified Pipes.Prelude as P+import qualified Pipes.Text as PT+import Prelude hiding (readList)++import Data.NestedText.To (ToItem(..), ToKey(..))+import Data.NestedText.Type+import Data.NestedText.Util++data Line+  = Line'Blank+  | Line'Comment Int T.Text+  | Line'StringItem Int T.Text+  | Line'ListItem Int T.Text+  | Line'DictItem Int T.Text (Maybe T.Text)+  | Line'KeyItem Int T.Text+  | Line'InlineList Int T.Text+  | Line'InlineDict Int T.Text+  deriving (Generic, Eq, Ord, Show)++data ValidLine+  = ValidLine'StringItem Int T.Text+  | ValidLine'ListItem Int T.Text+  | ValidLine'DictItem Int T.Text (Maybe T.Text)+  | ValidLine'KeyItem Int T.Text+  | ValidLine'InlineList Int T.Text+  | ValidLine'InlineDict Int T.Text+  deriving (Generic, Eq, Ord, Show)++data ParseError+  = ParseError'BreakingLinesError+  | ParseError'UnrecognizedLine+  | ParseError'InvalidLine+  | ParseError'InvalidIndent+  | ParseError'InvalidChar+  | ParseError'InvalidEndOfLine+  | ParseError'RemainingInlineContent+  | ParseError'DuplicateKey+  | ParseError'RemainingContent+  | ParseError'Empty+  deriving (Generic, Eq, Ord, Show)++toLine :: T.Text -> Either ParseError Line+toLine ts =+  let ts0 = T.unpack ts+      countPrefixSpaces = go 0+       where+        go !n (' ':xs) = go (succ n) xs+        go !n _ = n+      indentLevel = countPrefixSpaces ts0+      spanByFirstColon = go []+       where+        go _ [] = Nothing+        go revks (':':' ':vs) = Just+          ( reverse $ dropWhile isTabOrSpace revks+          , Just vs+          )+        go revks [':'] = Just+          ( reverse $ dropWhile isTabOrSpace revks+          , Nothing+          )+        go revks (x:xs) = go (x:revks) xs+   in case drop indentLevel ts0 of+        [] -> Right $ Line'Blank+        '#':' ':cs1 -> Right $ Line'Comment indentLevel $ T.pack cs1+        '#':cs1 -> Right $ Line'Comment indentLevel $ T.pack cs1+        ['>'] -> Right $ Line'StringItem indentLevel T.empty+        '>':' ':cs1 -> Right $ Line'StringItem indentLevel $ T.pack cs1+        ['-'] -> Right $ Line'ListItem indentLevel T.empty+        '-':' ':cs1 -> Right $ Line'ListItem indentLevel $ T.pack cs1+        '[':_ -> Right $ Line'InlineList indentLevel ts+        '{':_ -> Right $ Line'InlineDict indentLevel ts+        [':'] -> Right $ Line'KeyItem indentLevel T.empty+        ':':' ':cs1 -> Right $ Line'KeyItem indentLevel $ T.pack cs1+        '\t':_ -> Left ParseError'InvalidIndent+        cs0 -> case spanByFirstColon cs0 of+          Just (k, mv) -> Right $ Line'DictItem indentLevel (T.pack k) (T.pack <$> mv)+          Nothing -> Left ParseError'UnrecognizedLine++toValidLine :: Line -> Maybe ValidLine+toValidLine (Line'StringItem i ts) = Just $ ValidLine'StringItem i ts+toValidLine (Line'ListItem i ts) = Just $ ValidLine'ListItem i ts+toValidLine (Line'DictItem i ts mts) = Just $ ValidLine'DictItem i ts mts+toValidLine (Line'KeyItem i ts) = Just $ ValidLine'KeyItem i ts+toValidLine (Line'InlineList i ts) = Just $ ValidLine'InlineList i ts+toValidLine (Line'InlineDict i ts) = Just $ ValidLine'InlineDict i ts+toValidLine _ = Nothing++validLine'Indent :: ValidLine -> Int+validLine'Indent (ValidLine'StringItem i _) = i+validLine'Indent (ValidLine'ListItem i _) = i+validLine'Indent (ValidLine'DictItem i _ _) = i+validLine'Indent (ValidLine'KeyItem i _) = i+validLine'Indent (ValidLine'InlineList i _) = i+validLine'Indent (ValidLine'InlineDict i _) = i++data WaitingCharList+  = WaitingCharList'ValueOrEnd+  | WaitingCharList'Value+  | WaitingCharList'CommaOrEnd+  deriving (Generic, Eq, Ord, Show)++data WaitingCharDict+  = WaitingCharDict'KeyOrEnd+  | WaitingCharDict'Key+  | WaitingCharDict'Colon Key+  | WaitingCharDict'Value Key+  | WaitingCharDict'CommaOrEnd+  deriving (Generic, Eq, Ord, Show)++parse :: TL.Text -> Either ParseError Item+parse ts0 = StateT.evalStateT parser+  $ PT.folds (<>) T.empty id (splitLines $ PT.fromLazy ts0)+  P.>-> P.mapM toLine+  P.>-> P.mapMaybe toValidLine+ where+  parser = do+    xi <- readItemIndent [EQ] 0+    b <- PP.isEndOfInput+    when (not b) $ lift $ Left ParseError'RemainingContent+    return xi+  toItemWithoutError :: (ToItem a, ToItemError a ~ Void) => a -> Item+  toItemWithoutError x = case toItem x of+    Right y -> y+    Left _ -> error "toItemWithoutError: unreachable Left"+  toKeyWithoutError :: (ToKey a, ToKeyError a ~ Void) => a -> Key+  toKeyWithoutError x = case toKey x of+    Right y -> y+    Left _ -> error "toKeyWithoutError: unreachable Left"+  removeEnclosingSpace = T.dropWhileEnd C.isSpace . T.dropWhile C.isSpace++  readItemIndent cs i = do+    (item, j) <- readItem+    when ((i `compare` j) `notElem` cs) $ lift $ Left ParseError'InvalidIndent+    return item+  readItem = do+    ml <- PP.peek+    case ml of+      Nothing -> lift $ Left ParseError'Empty+      Just l -> case l of+        ValidLine'StringItem i _ts -> do+          ts <- readString i+          return (toItemWithoutError ts, i)+        ValidLine'ListItem i _ts -> do+          vs <- readList i+          return (Item'List vs, i)+        ValidLine'DictItem i _kts _mvts -> do+          dic <- readDict i+          return (Item'Dictionary dic, i)+        ValidLine'KeyItem i _ts -> do+          dic <- readDict i+          return (Item'Dictionary dic, i)+        ValidLine'InlineList i ts -> do+          _ <- PP.draw+          vs <- parseInlineList ts+          return (Item'List vs, i)+        ValidLine'InlineDict i ts -> do+          _ <- PP.draw+          dic <- parseInlineDict ts+          return (Item'Dictionary dic, i)+  readString i = go []+   where+    go ys = do+      ml <- PP.draw+      case ml of+        Nothing -> return $ T.intercalate osNewline $ reverse ys+        Just x -> case i `compare` validLine'Indent x of+          EQ -> case x of+            ValidLine'StringItem _ ts -> go $ ts : ys+            _ -> lift $ Left ParseError'InvalidLine+          LT -> lift $ Left ParseError'InvalidIndent+          GT -> do+            PP.unDraw x+            return $ T.intercalate osNewline $ reverse ys+  readList i = go []+   where+    go ys = do+      ml <- PP.draw+      case ml of+        Nothing -> return $ V.fromList $ reverse ys+        Just x -> case i `compare` validLine'Indent x of+          EQ -> case x of+            ValidLine'ListItem _ ts -> do+              let yys = toItemWithoutError ts : ys+              ml2 <- PP.peek+              case ml2 of+                Nothing -> go yys+                Just x2 -> case i `compare` validLine'Indent x2 of+                  EQ -> go yys+                  LT -> if not $ T.null ts then go yys else do+                    item <- readItemIndent [LT] i+                    go $ item : ys+                  GT -> return $ V.fromList $ reverse yys+            _ -> lift $ Left ParseError'InvalidLine+          LT -> lift $ Left ParseError'InvalidIndent+          GT -> do+            PP.unDraw x+            return $ V.fromList $ reverse ys+  readDict i = go M.empty+   where+    go m0 = do+      ml <- PP.draw+      case ml of+        Nothing -> return m0+        Just x -> case i `compare` validLine'Indent x of+          EQ -> case x of+            ValidLine'DictItem _ k0 mv ->+              let k = toKeyWithoutError k0 in case mv of+                Just v -> do+                  when (M.member k m0) $ lift $ Left ParseError'DuplicateKey+                  go $ M.insert k (toItemWithoutError v) m0+                Nothing -> do+                  ml2 <- PP.peek+                  case ml2 of+                    Nothing -> do+                      when (M.member k m0) $ lift $ Left ParseError'DuplicateKey+                      go $ M.insert k (toItemWithoutError T.empty) m0+                    Just x2 -> case i `compare` validLine'Indent x2 of+                      EQ -> do+                        when (M.member k m0) $ lift $ Left ParseError'DuplicateKey+                        go $ M.insert k (toItemWithoutError T.empty) m0+                      LT -> do+                        vi <- readItemIndent [LT] i+                        when (M.member k m0) $ lift $ Left ParseError'DuplicateKey+                        go $ M.insert k vi m0+                      GT -> do+                        when (M.member k m0) $ lift $ Left ParseError'DuplicateKey+                        return $ M.insert k (toItemWithoutError T.empty) m0+            ValidLine'KeyItem _ _ts -> do+              PP.unDraw x+              k <- readKey i+              vi <- readItemIndent [LT] i+              when (M.member k m0) $ lift $ Left ParseError'DuplicateKey+              go $ M.insert k vi m0+            _ -> lift $ Left ParseError'InvalidLine+          LT -> lift $ Left ParseError'InvalidIndent+          GT -> do+            PP.unDraw x+            return m0+  readKey i = go []+   where+    go ys = do+      ml <- PP.draw+      case ml of+        Nothing -> return+          $ toKeyWithoutError $ T.intercalate osNewline $ reverse ys+        Just x -> case i `compare` validLine'Indent x of+          EQ -> case x of+            ValidLine'KeyItem _ ts -> go $ ts : ys+            _ -> lift $ Left ParseError'InvalidLine+          _ -> do+            PP.unDraw x+            return $ toKeyWithoutError $ T.intercalate osNewline $ reverse ys++  parseInlineList = lift . StateT.evalStateT go . mapM_ P.yield . T.unpack+   where+    go = do+      vs <- readInlineList0+      readInlineSpace+      b <- PP.isEndOfInput+      when (not b) $ lift $ Left ParseError'RemainingInlineContent+      return vs+  parseInlineDict = lift . StateT.evalStateT go . mapM_ P.yield . T.unpack+   where+    go = do+      dic <- readInlineDict0+      readInlineSpace+      b <- PP.isEndOfInput+      when (not b) $ lift $ Left ParseError'RemainingInlineContent+      return dic+  readInlineChar x = do+    mc <- PP.draw+    case mc of+      Nothing -> lift $ Left ParseError'InvalidEndOfLine+      Just c | c == x -> return ()+      Just _ -> lift $ Left ParseError'InvalidChar+  readInlineSpace = do+    mc <- PP.draw+    case mc of+      Nothing -> return ()+      Just c | isTabOrSpace c -> readInlineSpace+      Just c -> do+        PP.unDraw c+        return ()+  readInlineString scs = go []+   where+    go ys = do+      mc <- PP.draw+      case mc of+        Nothing -> return $ removeEnclosingSpace $ T.pack $ reverse ys+        Just c -> if S.notMember c scs then go $ c : ys else do+          PP.unDraw c+          return $ removeEnclosingSpace $ T.pack $ reverse ys+  readInlineList0 = do+    readInlineSpace+    readInlineChar '['+    readInlineList1 WaitingCharList'ValueOrEnd []+  readInlineList1 wcl ys = do+    readInlineSpace+    mc <- PP.draw+    case mc of+      Nothing -> lift $ Left ParseError'InvalidEndOfLine+      Just c -> case wcl of+        WaitingCharList'ValueOrEnd -> case c of+          ']' -> return $ V.fromList $ reverse ys+          '[' -> do+            item <- Item'List <$> readInlineList1 WaitingCharList'ValueOrEnd []+            readInlineList1 WaitingCharList'CommaOrEnd $ item : ys+          '{' -> do+            item <- Item'Dictionary+              <$> readInlineDict1 WaitingCharDict'KeyOrEnd M.empty+            readInlineList1 WaitingCharList'CommaOrEnd $ item : ys+          _ | S.member c specialCharsList ->+            lift $ Left ParseError'InvalidChar+          _ -> do+            PP.unDraw c+            item <- toItemWithoutError <$> readInlineString specialCharsList+            readInlineList1 WaitingCharList'CommaOrEnd $ item : ys+        WaitingCharList'Value -> case c of+          '[' -> do+            item <- Item'List <$> readInlineList1 WaitingCharList'ValueOrEnd []+            readInlineList1 WaitingCharList'CommaOrEnd $ item : ys+          '{' -> do+            item <- Item'Dictionary+              <$> readInlineDict1 WaitingCharDict'KeyOrEnd M.empty+            readInlineList1 WaitingCharList'CommaOrEnd $ item : ys+          _ | S.member c specialCharsList ->+            lift $ Left ParseError'InvalidChar+          _ -> do+            PP.unDraw c+            item <- toItemWithoutError <$> readInlineString specialCharsList+            readInlineList1 WaitingCharList'CommaOrEnd $ item : ys+        WaitingCharList'CommaOrEnd -> case c of+          ',' -> readInlineList1 WaitingCharList'Value ys+          ']' -> return $ V.fromList $ reverse ys+          _ -> lift $ Left ParseError'InvalidChar+  readInlineDict0 = do+    readInlineSpace+    readInlineChar '{'+    readInlineDict1 WaitingCharDict'KeyOrEnd M.empty+  readInlineDict1 wcd m0 = do+    readInlineSpace+    mc <- PP.draw+    case mc of+      Nothing -> lift $ Left ParseError'InvalidEndOfLine+      Just c -> case wcd of+        WaitingCharDict'KeyOrEnd -> case c of+          '}' -> return m0+          _ | S.member c specialCharsDict ->+            lift $ Left ParseError'InvalidChar+          _ -> do+            PP.unDraw c+            key <- toKeyWithoutError <$> readInlineString specialCharsDict+            when (M.member key m0) $ lift $ Left ParseError'DuplicateKey+            readInlineDict1 (WaitingCharDict'Colon key) m0+        WaitingCharDict'Key -> case c of+          _ | S.member c specialCharsDict ->+            lift $ Left ParseError'InvalidChar+          _ -> do+            PP.unDraw c+            key <- toKeyWithoutError <$> readInlineString specialCharsDict+            when (M.member key m0) $ lift $ Left ParseError'DuplicateKey+            readInlineDict1 (WaitingCharDict'Colon key) m0+        WaitingCharDict'Colon k -> case c of+          ':' -> readInlineDict1 (WaitingCharDict'Value k) m0+          _ -> lift $ Left ParseError'InvalidChar+        WaitingCharDict'Value k -> case c of+          '[' -> do+            vi <- Item'List <$> readInlineList1 WaitingCharList'ValueOrEnd []+            readInlineDict1 WaitingCharDict'CommaOrEnd $ M.insert k vi m0+          '{' -> do+            vi <- Item'Dictionary+              <$> readInlineDict1 WaitingCharDict'KeyOrEnd M.empty+            readInlineDict1 WaitingCharDict'CommaOrEnd $ M.insert k vi m0+          _ | S.member c specialCharsDict ->+            lift $ Left ParseError'InvalidChar+          _ -> do+            PP.unDraw c+            vi <- toItemWithoutError <$> readInlineString specialCharsDict+            readInlineDict1 WaitingCharDict'CommaOrEnd $ M.insert k vi m0+        WaitingCharDict'CommaOrEnd -> case c of+          ',' -> readInlineDict1 WaitingCharDict'Key m0+          '}' -> return m0+          _ -> lift $ Left ParseError'InvalidChar++parse' :: T.Text -> Either ParseError Item+parse' = parse . TL.fromStrict++parseDocument :: TL.Text -> Either ParseError Document+parseDocument ts = case parse ts of+  Left ParseError'Empty -> Right Document'Empty+  Right i -> Right $ Document'Item i+  Left err -> Left err
+ src/Data/NestedText/Serialize.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE DeriveGeneric #-}++module Data.NestedText.Serialize+  ( serialize+  , serialize'+  ) where++import qualified Data.Char as C+import Data.Functor.Identity (Identity(..))+import Data.List (intersperse)+import qualified Data.Map.Strict as M+import Data.Maybe (isJust)+import qualified Data.Set as S+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.Builder as TLB+import qualified Data.Text.Short as ST+import qualified Data.Vector as V+import Generic.Data+import Lens.Micro.Platform+import qualified Pipes.Text as PT++import Data.NestedText.Type+import Data.NestedText.Util++data Denote+  = Denote'Null+  | Denote'SingleLine T.Text+  | Denote'MultipleLine Item+  deriving (Generic)++serialize :: Int -> Item -> TL.Text+serialize indentWidth = TLB.toLazyText . write+ where+  indent i = TLB.fromString $ replicate i ' '+  nl = TLB.fromText osNewline+  isMultilineKey ts =+    isJust (ST.findIndex (== '\n') ts)+    || ST.null ts+    || (case ST.uncons ts of+      Nothing -> False+      Just (c, _) -> C.isSpace c || S.member c specialCharsDict || c == '#')+    || (case ST.unsnoc ts of+      Nothing -> False+      Just (_, c) -> C.isSpace c || c == ':')+    || T.isInfixOf (T.pack ": ") (ST.toText ts)+  denoteItem item@(Item'String ts) = case T.findIndex (== '\n') ts of+    Just _ -> Denote'MultipleLine item+    Nothing -> if T.null ts then Denote'Null else Denote'SingleLine ts+  denoteItem item = Denote'MultipleLine item++  write i = writeItem 0 i <> nl+  writeItem i (Item'String ts) = writeString i ts+  writeItem i (Item'List vs) = if V.null vs+    then indent i <> TLB.fromString "[]"+    else mconcat $ intersperse nl+      $ flip map (V.toList vs) $ \vi -> case denoteItem vi of+        Denote'Null -> indent i <> TLB.fromString "-"+        Denote'SingleLine ts -> indent i <> TLB.fromString "- " <> TLB.fromText ts+        Denote'MultipleLine _ -> indent i <> TLB.fromString "-"+          <> nl <> writeItem (i + indentWidth) vi+  writeItem i (Item'Dictionary dic) = if M.null dic+    then indent i <> TLB.fromString "{}"+    else mconcat $ intersperse nl+      $ flip map (M.toAscList dic) $ \(k, vi) -> if isMultilineKey k+        then writeKey i k <> nl <> writeItem (i + indentWidth) vi+        else case denoteItem vi of+          Denote'Null ->+            indent i <> TLB.fromText (ST.toText k) <> TLB.fromString ":"+          Denote'SingleLine ts ->+            indent i <> TLB.fromText (ST.toText k) <> TLB.fromString ": "+            <> TLB.fromText ts+          Denote'MultipleLine _ ->+            indent i <> TLB.fromText (ST.toText k) <> TLB.fromString ":"+            <> nl <> writeItem (i + indentWidth) vi+  writeString i ts =+    freeTToLines (splitLines $ PT.fromLazy $ TL.fromStrict ts)+    & runIdentity+    & map (\l -> if T.null l+      then indent i <> TLB.fromString ">"+      else indent i <> TLB.fromString "> " <> TLB.fromText l)+    & intersperse nl+    & mconcat+  writeKey i ts =+    freeTToLines (splitLines $ PT.fromLazy $ TL.fromStrict $ ST.toText ts)+    & runIdentity+    & map (\l -> if T.null l+      then indent i <> TLB.fromString ":"+      else indent i <> TLB.fromString ": " <> TLB.fromText l)+    & intersperse nl+    & mconcat++serialize' :: Int -> Item -> T.Text+serialize' i = TL.toStrict . serialize i
+ src/Data/NestedText/To.hs view
@@ -0,0 +1,115 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}++module Data.NestedText.To where++import Control.Monad (forM)+import Data.Bifunctor (Bifunctor(first))+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString.Short as SBS+import Data.Kind (Type)+import qualified Data.Map as M+import qualified Data.Text as TS+import qualified Data.Text.Encoding as TE+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Short as ST+import qualified Data.Vector as V+import Data.Void (Void)+import Generic.Data++import Data.NestedText.Type++class ToItem a where+  type ToItemError a :: Type+  toItem :: a -> Either (ToItemError a) Item+class ToKey a where+  type ToKeyError a :: Type+  toKey :: a -> Either (ToKeyError a) Key++instance ToItem Item where+  type ToItemError Item = Void+  toItem = Right++data ToItemError'Text+  = ToItemError'Text'Utf8Error+  deriving (Generic, Eq, Show)++instance ToItem BS.ByteString where+  type ToItemError BS.ByteString = ToItemError'Text+  toItem bs = fmap Item'String+    $ first (const ToItemError'Text'Utf8Error) $ TE.decodeUtf8' bs+instance ToItem BL.ByteString where+  type ToItemError BL.ByteString = ToItemError'Text+  toItem bs = fmap Item'String+    $ first (const ToItemError'Text'Utf8Error) $ TE.decodeUtf8' $ BL.toStrict bs+instance ToItem TS.Text where+  type ToItemError TS.Text = Void+  toItem = Right . Item'String+instance ToItem TL.Text where+  type ToItemError TL.Text = Void+  toItem = Right . Item'String . TL.toStrict++data ToItemError'List a+  = ToItemError'List'ElementError (ToItemError a)+  deriving (Generic)+instance Eq (ToItemError a) => Eq (ToItemError'List a) where+  (==) = geq+instance Show (ToItemError a) => Show (ToItemError'List a) where+  showsPrec = gshowsPrec++instance ToItem a => ToItem [a] where+  type ToItemError [a] = ToItemError'List a+  toItem xs = Item'List <$> V.forM (V.fromList xs)+   (first ToItemError'List'ElementError . toItem)+instance ToItem a => ToItem (V.Vector a) where+  type ToItemError (V.Vector a) = ToItemError'List a+  toItem xs = Item'List <$> V.forM xs+   (first ToItemError'List'ElementError . toItem)++data ToKeyError'Text+  = ToKeyError'Text'Utf8Error+  deriving (Generic, Eq, Show)++instance ToKey BS.ByteString where+  type ToKeyError BS.ByteString = ToKeyError'Text+  toKey bs = fmap ST.fromText+    $ first (const ToKeyError'Text'Utf8Error) $ TE.decodeUtf8' bs+instance ToKey BL.ByteString where+  type ToKeyError BL.ByteString = ToKeyError'Text+  toKey bs = fmap ST.fromText+    $ first (const ToKeyError'Text'Utf8Error) $ TE.decodeUtf8' $ BL.toStrict bs+instance ToKey SBS.ShortByteString where+  type ToKeyError SBS.ShortByteString = ToKeyError'Text+  toKey sbs = maybe (Left ToKeyError'Text'Utf8Error) Right+    $ ST.fromShortByteString sbs+instance ToKey TS.Text where+  type ToKeyError TS.Text = Void+  toKey = Right . ST.fromText+instance ToKey TL.Text where+  type ToKeyError TL.Text = Void+  toKey = Right . ST.fromText . TL.toStrict+instance ToKey ST.ShortText where+  type ToKeyError ST.ShortText = Void+  toKey = Right++data ToItemError'Map k v+  = ToItemError'Map'KeyError (ToKeyError k)+  | ToItemError'Map'ValueError (ToItemError v)+  deriving (Generic)+instance (Eq (ToKeyError k), Eq (ToItemError v))+  => Eq (ToItemError'Map k v) where+    (==) = geq+instance (Show (ToKeyError k), Show (ToItemError v))+  => Show (ToItemError'Map k v) where+    showsPrec = gshowsPrec++instance (ToKey k, ToItem v) => ToItem (M.Map k v) where+  type ToItemError (M.Map k v) = ToItemError'Map k v+  toItem dic = fmap (Item'Dictionary . M.fromList)+    $ forM (M.toAscList dic) $ \(ks, vs) -> do+      kd <- first ToItemError'Map'KeyError $ toKey ks+      vd <- first ToItemError'Map'ValueError $ toItem vs+      return (kd, vd)
+ src/Data/NestedText/Type.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE DeriveGeneric #-}++module Data.NestedText.Type where++import qualified Data.Map.Strict as M+import qualified Data.Text as T+import qualified Data.Text.Short as ST+import qualified Data.Vector as V+import Generic.Data (Generic)++type Key = ST.ShortText++data Item+  = Item'String T.Text+  | Item'List (V.Vector Item)+  | Item'Dictionary (M.Map Key Item)+  deriving (Generic, Eq, Show)++data Document+  = Document'Empty+  | Document'Item Item+  deriving (Generic, Eq, Show)
+ src/Data/NestedText/Util.hs view
@@ -0,0 +1,62 @@+module Data.NestedText.Util where++import qualified Control.Monad.Trans.Free as F+import Data.Functor (($>))+import qualified Data.Set as S+import qualified Data.Text as T+import Lens.Micro.Platform+import qualified Pipes as P+import qualified Pipes.Prelude as P+import qualified Pipes.Text as PT+import System.IO (Newline(..), nativeNewline)++specialCharsList :: S.Set Char+specialCharsList = S.fromAscList ",[]{}"+specialCharsDict :: S.Set Char+specialCharsDict = S.fromAscList ",:[]{}"++isTabOrSpace :: Char -> Bool+isTabOrSpace c = c == ' ' || c == '\t'++osNewline :: T.Text+osNewline = case nativeNewline of+  LF -> T.pack "\n"+  CRLF -> T.pack "\r\n"++splitLines :: Monad m => P.Producer T.Text m r -> F.FreeT (P.Producer T.Text m) m r+splitLines p0 = F.FreeT $ go1 p0+ where+  go0 r = return $ F.Free $ P.yield T.empty $> F.FreeT (return $ F.Pure r)+  go1 p1 = do+    ec <- P.next p1+    case ec of+      Left r -> go0 r+      Right (txt, p2) -> if T.null txt+        then go1 p2+        else return $ F.Free $ go2 $ P.yield txt >> p2+  go2 p1 = do+    p2 <- p1 ^. PT.break (\c -> c == '\n' || c == '\r')+    return $ F.FreeT $ do+      ec1 <- PT.nextChar p2+      case ec1 of+        Left r -> return $ F.Pure r+        Right ('\n', p3) -> go1 p3+        Right ('\r', p3) -> do+          ec2 <- PT.nextChar p3+          case ec2 of+            Left r -> go0 r+            Right ('\n', p4) -> go1 p4+            Right (c, p4) -> go1 $ P.yield (T.singleton c) >> p4+        Right _ -> error "splitLines: unreachable"++freeTToLines :: Monad m => F.FreeT (P.Producer T.Text m) m r -> m [T.Text]+freeTToLines free = go free+  where+    go ft = do+      step <- F.runFreeT ft+      case step of+        F.Pure _ -> return []+        F.Free p0 -> do+          (line, p1) <- P.fold' (<>) T.empty id p0+          rest <- go p1+          return $ line : rest
+ test/Main.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF tasty-discover #-}
+ test/Official.hs view
@@ -0,0 +1,178 @@+module Official where++import Control.Monad (forM)+import Data.Functor.Identity (Identity(..))+import Data.List (singleton)+import qualified Data.Map as M+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import qualified Data.Text.Lazy.IO as TLIO+import qualified Data.Text.Short as ST+import qualified Data.Vector as V+import qualified Pipes.Text as PT+import System.Directory (doesFileExist, listDirectory)+import System.FilePath ((</>))+import System.IO+  ( IOMode(..), Newline(..)+  , hSetEncoding, hSetNewlineMode+  , nativeNewline, nativeNewlineMode, noNewlineTranslation+  , openFile, utf8+  )+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.HUnit (assertFailure, testCase, (@?=))+import qualified Text.JSON as J++import Data.NestedText.Parse+import Data.NestedText.Serialize+import Data.NestedText.Type+import Data.NestedText.Util++data TestLoad+  = TestLoad'Nothing+  | TestLoad'ShouldSuccess FilePath FilePath+  | TestLoad'ShouldFailure FilePath+  deriving (Eq, Show)++data TestDump+  = TestDump'Nothing+  | TestDump'ShouldSuccess FilePath FilePath+  | TestDump'ShouldFailure FilePath+  deriving (Eq, Show)++newtype I = I { unI :: Item }++instance J.JSON I where+  readJSON (J.JSString jsstr) =+    J.Ok $ I $ Item'String $ T.pack $ J.fromJSString jsstr+  readJSON (J.JSArray vs) =+    fmap (I . Item'List . V.fromList) $ forM vs $ \vi -> unI <$> J.readJSON vi+  readJSON (J.JSObject jsobj) =+    fmap (I . Item'Dictionary . M.fromList)+    $ forM (J.fromJSObject jsobj) $ \(k, v) -> do+      i <- J.readJSON v+      return (ST.pack k, unI i)+  readJSON _ = J.Error "cannot convert json to nestedtext item"+  showJSON _ = error "unimplemented"++readPlaintext :: FilePath -> IO TL.Text+readPlaintext file = do+  h <- openFile file ReadMode+  hSetEncoding h utf8+  hSetNewlineMode h noNewlineTranslation+  TLIO.hGetContents h++readJSON :: FilePath -> IO (Maybe Item)+readJSON file = do+  h <- openFile file ReadMode+  hSetEncoding h utf8+  hSetNewlineMode h nativeNewlineMode+  ts <- TLIO.hGetContents h+  -- workaround for json-0.11; not supported trailing whitespaces+  return $ case J.decode $ TL.unpack $ TL.dropWhileEnd (== '\n') ts of+    J.Ok (I i) -> Just $ f i+    J.Error _err -> Nothing+ where+  f = case nativeNewline of+    LF -> id+    CRLF -> bimap (ST.fromText . r . ST.toText) r+  r = T.intercalate osNewline+    . runIdentity . freeTToLines . splitLines . PT.fromLazy . TL.fromStrict+  bimap _fk fv (Item'String ts) = Item'String $ fv ts+  bimap fk fv (Item'List vs) = Item'List $ V.map (bimap fk fv) vs+  bimap fk fv (Item'Dictionary dic) =+    Item'Dictionary $ bimap fk fv <$> M.mapKeys fk dic++test_official :: IO [TestTree]+test_official = do+  let dir = "vendor"+        </> "github.com"+        </> "KenKundert"+        </> "nestedtext_tests"+        </> "test_cases"+      skipLoad =+        -- because invalid value+        [ "empty_1"+        ]+      skipDump =+        -- because disordered keys of dict+        [ "dict_17"+        , "dict_20"+        , "dict_23"+        , "dict_25"+        , "dict_28"+        , "dict_29"+        , "holistic_1"+        , "holistic_2"+        , "holistic_3"+        , "holistic_4"+        , "holistic_5"+        , "holistic_6"+        , "holistic_7"+        -- because trailing colon for inline key+        , "dict_16"+        , "dict_26"+        , "dict_30"+        ]+  ds <- listDirectory dir+  ts <- forM ds $ \d0 -> do+    let d = dir </> d0+        fileLoadIn = d </> "load_in.nt"+        fileLoadOut = d </> "load_out.json"+        fileLoadErr = d </> "load_err.json"+        fileDumpIn = d </> "dump_in.json"+        fileDumpOut = d </> "dump_out.nt"+        fileDumpErr = d </> "dump_err.json"+    fli <- doesFileExist fileLoadIn+    tl <- if not fli then return TestLoad'Nothing else do+      flo <- doesFileExist fileLoadOut+      fle <- doesFileExist fileLoadErr+      return $ case (flo, fle) of+        (True, False) -> TestLoad'ShouldSuccess fileLoadIn fileLoadOut+        (False, True) -> TestLoad'ShouldFailure fileLoadIn+        (True, True) -> error $ d0 ++ ": ambiguous expected result"+        (False, False) -> error $ d0 ++ ": no expected result"+    fdi <- doesFileExist fileDumpIn+    td <- if not fdi then return TestDump'Nothing else do+      fdo <- doesFileExist fileDumpOut+      fde <- doesFileExist fileDumpErr+      return $ case (fdo, fde) of+        (True, False) -> TestDump'ShouldSuccess fileDumpIn fileDumpOut+        (False, True) -> TestDump'ShouldFailure fileDumpIn+        (True, True) -> error $ d0 ++ ": ambiguous expected result"+        (False, False) -> error $ d0 ++ ": no expected result"+    return (d0, tl, td)+  forM ts $ \(d, tl, td) -> do+    tls <- if elem d skipLoad then return [] else case tl of+      TestLoad'Nothing -> return []+      TestLoad'ShouldSuccess fin fout -> do+        mjout <- readJSON fout+        case mjout of+          Just iout -> do+            nin <- readPlaintext fin+            return $ singleton $ testCase "load" $ case parse nin of+              Right iin -> iin @?= iout+              Left err -> assertFailure $ show err+          Nothing -> return []+      TestLoad'ShouldFailure fin -> do+        nin <- readPlaintext fin+        return $ singleton $ testCase "load" $ case parse nin of+          Right iin ->+            assertFailure $ "load succeed! it should fail. " ++ show iin+          Left _err -> return ()+    tds <- if elem d skipDump then return [] else case td of+      TestDump'Nothing -> return []+      TestDump'ShouldSuccess fin fout -> do+        mjin <- readJSON fin+        case mjin of+          Just iin -> do+            nout <- readPlaintext fout+            return $ singleton $ testCase "dump" $ serialize 4 iin @?= nout+          Nothing -> return []+      TestDump'ShouldFailure fin -> return $ singleton $ testCase "dump" $ do+        mjin <- readJSON fin+        case mjin of+          Just iin -> do+            let _ = iin :: Item+            assertFailure $ "dump succeed! it should fail. " ++ show iin+          Nothing -> return ()+    return $ testGroup d $ tls ++ tds
+ test/Property.hs view
@@ -0,0 +1,44 @@+module Property where++import qualified Data.Char as C+import qualified Data.Map.Strict as M+import qualified Data.Text as T+import qualified Data.Text.Short as ST+import qualified Data.Vector as V+import qualified Hedgehog as H+import qualified Hedgehog.Gen as HG+import qualified Hedgehog.Range as HR+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.Hedgehog (testProperty)++import Data.NestedText.Parse+import Data.NestedText.Serialize+import Data.NestedText.Type++genItem :: H.MonadGen m => H.Range Int -> H.Range Int -> H.Range Int -> m Item+genItem rs rk rn = go+ where+  go = HG.recursive HG.choice+    [ Item'String . T.pack <$> HG.string rs char+    ]+    [ Item'List . V.fromList <$> HG.list rn go+    , Item'Dictionary . M.fromList <$> HG.list rn entry+    ]+  entry = do+    k <- ST.pack <$> HG.string rk char+    v <- go+    return (k, v)+  char = HG.filterT C.isPrint HG.unicode++test_property :: TestTree+test_property = testGroup "property"+  [ testProperty "parse . serialize === Right" $ H.property $ do+    n <- H.forAll $ HG.integral $ HR.linear 1 8+    item <- H.forAll $ genItem (HR.linear 0 64) (HR.linear 0 16) (HR.linear 0 32)+    parse (serialize n item) H.=== Right item+  , testProperty "fmap serialize . parse . serialize === Right . serialize" $ H.property $ do+    n <- H.forAll $ HG.integral $ HR.linear 1 8+    item <- H.forAll $ genItem (HR.linear 0 64) (HR.linear 0 16) (HR.linear 0 32)+    (fmap (serialize n) . parse . serialize n) item+      H.=== (Right . serialize n) item+  ]
+ test/Util.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE OverloadedStrings #-}++module Util where++import qualified Pipes as P+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.HUnit (testCase, (@?=))++import Data.NestedText.Util++test_lines :: TestTree+test_lines = testGroup "splitLines" $+  let go name textsIn textsOut = testCase name $ do+        linesList <- freeTToLines $ splitLines $ mapM_ P.yield textsIn+        linesList @?= textsOut+   in [ go "LF only in one chunk"+        ["line1\nline2\nline3"]+        ["line1", "line2", "line3"]+      , go "CR only in one chunk"+        ["line1\rline2\rline3"]+        ["line1", "line2", "line3"]+      , go "CRLF only in one chunk"+        ["line1\r\nline2\r\nline3"]+        ["line1", "line2", "line3"]+      , go "CRLF spanning chunk boundary"+        ["line1\r", "\nline2\r", "\nline3"]+        ["line1", "line2", "line3"]+      , go "Mixed newlines and spanning boundaries"+        ["line1", "\r", "\nline2\nli", "ne3\r", "\nline4\rline5"]+        ["line1", "line2", "line3", "line4", "line5"]+      , go "More spanning boundaries"+        ["line1", "\nline2", "\rline3", "\r\nline4\r", "\nline5\r\n", "line6"]+        ["line1", "line2", "line3", "line4", "line5", "line6"]+      , go "Contains empty chunks"+        ["line1", "", "\nline2\n", "", "\nline4"]+        ["line1", "line2", "", "line4"]+      , go "Enclosing blank lines"+        ["\nline2\n"]+        ["", "line2", ""]+      , go "No newline"+        ["single line without newline"]+        ["single line without newline"]+      ]
+ vendor/github.com/KenKundert/nestedtext_tests/README.md view
@@ -0,0 +1,101 @@+Official NestedText Test Suite+==============================++Version: 3.7++Test cases for NestedText are written in JSON, for the purpose of allowing +NestedText implementations in any language to use the same tests.++Understanding the tests+-----------------------+Each test case consists of a directory with some number of the following files:++- `load_in.nt`: A NestedText file that is meant to be loaded.  The presence +  of this file indicates that this case is meant to test the `load()` function, +  and that one of (but not both of) `load_out.json` or `load_err.json` must +  also be present.++- `load_out.json`: A JSON file encoding the data structure that should be +  loaded from `load_in.nt`.  The presence of this file indicates that the data +  structure should be loaded without errors.++- `load_err.json`: A JSON file describing the parameters of the error that +  should be triggered when attempting to load `load_in.nt`.  Specifically, +  these parameters include:++  - `lineno`: The line number (counting from 1) where the error occurs.+  - `colno`: The column number (counting from 0) where the error occurs.+  - `message`: The error message that should be produced.++- `dump_in.json`: A JSON data structure that is meant to be dumped to +  NestedText.  The presence of this file indicates that this case is meant to +  test the `dump()` function, and that one of (but not both of) `dump_out.nt` +  or `dump_err.json` must also be present.  This file may have a different file +  type (e.g. `*.py`) for tests involving data structures that cannot be +  represented in JSON (e.g. dictionary keys with newlines).++- `dump_out.nt`: A NestedText file that should be dumped from the data +  structure in `dump_in.json`.  The presence of this file indicates that the +  data structure should be dumped without error.++- `dump_err.json`: A JSON file describing the parameters of the error that +  should be triggered when attempting to dump the data structure in +  `dump_in.json`.  Specifically, these parameters include:++  - `culprit`: The specific object responsible for the error.+  - `message`: The error message that should be produced.++It's very possible for a single test case to test both the `load()` and +`dump()` functions.  For such tests, it's common to symlink `load_in.nt` to +`dump_out.nt` and/or `load_out.json` to `dump_in.json`.++Using the tests+---------------++### Installation+This repository is meant to be included as a submodule of any repository that +implements the NestedText standard.  This approach makes it easy to share tests +between implementations (e.g. corner cases found in one implementation could be +added to this repository and made available to every implementation) and easy +to control which version of the tests are being used (e.g. ).++It would be good to familiarize yourself with the `git submodule` command +before attempting to incorporate these tests into a project, but the basic +command to do so is shown below.  Note that it's conventional to name the +submodule `official_tests`:++    $ git init «new-project»+    $ cd «new-project»+    $ git submodule add git@github.com:KenKundert/nestedtext_tests.git tests/official_tests++To incorporate new tests from the upstream repository:++    $ cd tests/official_tests+    $ git pull++### APIs+The `api/` directory contains code that parses the test cases into native data +structures for different languages.  If you're writing an implementation for a +language that isn't represented in the `api/` directory yet, it would be much +appreciated if you could submit an API (via pull request) and make it easier +for others to create implementations.++There are also APIs maintained outside of this source tree:+* Ruby - [official_tests_api.rb](https://github.com/erikw/nestedtext-ruby/blob/main/test/official_tests_api.rb)++### Helper scripts+In addition to the tests themselves, this repository contains a number of +helper scripts to make it easier to work with the tests.  These scripts +include:++- `show_test_cases.py`: Print the actual test inputs and outputs.  This can be +  a good way to make sure that a certain feature is being adequately exercised.++- `make_test_case.py`: Create a new test case.  You will be automatically +  prompted to fill out the relevant files.++- `renumber_test_cases.py`: Renumber the test cases.  This provides an easy way +  to keep the numbering logical after adding or removing tests.++For more detailed usage information, run any of these scripts with the `-h` +flag.
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_01/dump_in.json view
@@ -0,0 +1,1 @@+{"key1": "", "key2": ""}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_01/dump_out.nt view
@@ -0,0 +1,2 @@+key1:+key2:
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_01/load_in.nt view
@@ -0,0 +1,2 @@+key1:+key2:
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_01/load_out.json view
@@ -0,0 +1,1 @@+{"key1": "", "key2": ""}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_02/dump_in.json view
@@ -0,0 +1,1 @@+{"apricot\n": "8"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_02/dump_out.nt view
@@ -0,0 +1,3 @@+: apricot+:+    > 8
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_03/dump_in.json view
@@ -0,0 +1,1 @@+{" key-a\" : key-b' : key-c ": "value"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_03/dump_out.nt view
@@ -0,0 +1,2 @@+:  key-a" : key-b' : key-c +    > value
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_04/dump_in.json view
@@ -0,0 +1,1 @@+{}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_04/dump_out.nt view
@@ -0,0 +1,1 @@+{}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_05/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 0,+  "colno": 0,+  "message": "top-level content must start in column 1."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_05/load_in.nt view
@@ -0,0 +1,1 @@+    key: value
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_06/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 4,+  "colno": 0,+  "message": "invalid indentation."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_06/load_in.nt view
@@ -0,0 +1,5 @@+key 1:  +        # notice the extra space at the end of the above line++        # that, combined with the indent in the line below is an error+        key2: value 1.1
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_07/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 4,+  "message": "invalid character in indentation: '\\t'."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_07/load_in.nt view
@@ -0,0 +1,4 @@+# invalid indentation, tab in indentation+key 1:+    	    key 1.1: value 1.1+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_08/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 0,+  "message": "expected dictionary item."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_08/load_in.nt view
@@ -0,0 +1,3 @@+ingredients:+- green chilies+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_09/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 2,+  "message": "invalid indentation."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_09/load_in.nt view
@@ -0,0 +1,4 @@+ingredients:+  - green chilies+    - red chilies+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_10/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 0,+  "message": "invalid indentation, partial dedent."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_10/load_in.nt view
@@ -0,0 +1,4 @@+candidates:+    name:+  phone:+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_11/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 0,+  "message": "invalid indentation, partial dedent."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_11/load_in.nt view
@@ -0,0 +1,4 @@+ingredients:+    - green chilies+  - red chilies+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_12/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 0,+  "message": "expected dictionary item."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_12/load_in.nt view
@@ -0,0 +1,4 @@+# differing types at same level of indentation+ingredients: red chilies+- green chilies+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_13/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 4,+  "message": "unrecognized line."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_13/load_in.nt view
@@ -0,0 +1,3 @@+ingredients:+    green chilies+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_14/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 0,+  "message": "duplicate key: key."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_14/load_in.nt view
@@ -0,0 +1,2 @@+key: value 1+key: value 2
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_15/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 4,+  "message": "invalid character in indentation: '\\t'."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_15/load_in.nt view
@@ -0,0 +1,3 @@+key:+    	    > first line+    	    > second line
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_16/dump_in.json view
@@ -0,0 +1,4 @@+{+    "key:": ""+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_16/dump_out.nt view
@@ -0,0 +1,1 @@+key::
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_16/load_in.nt view
@@ -0,0 +1,1 @@+key::
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_16/load_out.json view
@@ -0,0 +1,4 @@+{+    "key:": ""+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_17/dump_in.json view
@@ -0,0 +1,18 @@+{+    "": "",+    "~!@#$%^&*()_+-1234567890{}[]|\\;<>?,./": "~!@#$%^&*()_+-1234567890{}[]|\\:;<>?,./",+    "- key 3": "- value 3",+    "key 4: ": "value 4: ",+    "> key 5": "> value 5",+    "# key 6": "#value 6",+    ": key 7": ": value 7",+    "\" key 8 \"": "\" value 8 \"",+    "' key 9 '": "' value 9 '",+    "key 10": "value '\" 10",+    "key 11": "And Fred said 'yabba dabba doo!' to Barney.",+    "key \" 12": "value ' 12",+    "$€¥£₩₺₽₹ɃΞȄ": "$€¥£₩₺₽₹ɃΞȄ",+    "YZEPTGMKk_cmuµμnpfazy": "YZEPTGMKk_cmuµμnpfazy",+    "a-zA-Z%√{us}{cur}][-^/()\\w·⁻⁰¹²³⁴⁵⁶⁷⁸⁹°ÅΩƱΩ℧": "a-zA-Z%√{us}{cur}][-^/()\\w·⁻⁰¹²³⁴⁵⁶⁷⁸⁹°ÅΩƱΩ℧"+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_17/dump_out.nt view
@@ -0,0 +1,21 @@+:+    >+~!@#$%^&*()_+-1234567890{}[]|\;<>?,./: ~!@#$%^&*()_+-1234567890{}[]|\:;<>?,./+: - key 3+    > - value 3+: key 4: +    > value 4: +: > key 5+    > > value 5+: # key 6+    > #value 6+: : key 7+    > : value 7+" key 8 ": " value 8 "+' key 9 ': ' value 9 '+key 10: value '" 10+key 11: And Fred said 'yabba dabba doo!' to Barney.+key " 12: value ' 12+$€¥£₩₺₽₹ɃΞȄ: $€¥£₩₺₽₹ɃΞȄ+YZEPTGMKk_cmuµμnpfazy: YZEPTGMKk_cmuµμnpfazy+a-zA-Z%√{us}{cur}][-^/()\w·⁻⁰¹²³⁴⁵⁶⁷⁸⁹°ÅΩƱΩ℧: a-zA-Z%√{us}{cur}][-^/()\w·⁻⁰¹²³⁴⁵⁶⁷⁸⁹°ÅΩƱΩ℧
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_17/load_in.nt view
@@ -0,0 +1,21 @@+:+    >+~!@#$%^&*()_+-1234567890{}[]|\;<>?,./: ~!@#$%^&*()_+-1234567890{}[]|\:;<>?,./+: - key 3+    > - value 3+: key 4: +    > value 4: +: > key 5+    > > value 5+: # key 6+    > #value 6+: : key 7+    > : value 7+" key 8 ": " value 8 "+' key 9 ': ' value 9 '+key 10: value '" 10+key 11: And Fred said 'yabba dabba doo!' to Barney.+key " 12: value ' 12+$€¥£₩₺₽₹ɃΞȄ: $€¥£₩₺₽₹ɃΞȄ+YZEPTGMKk_cmuµμnpfazy: YZEPTGMKk_cmuµμnpfazy+a-zA-Z%√{us}{cur}][-^/()\w·⁻⁰¹²³⁴⁵⁶⁷⁸⁹°ÅΩƱΩ℧: a-zA-Z%√{us}{cur}][-^/()\w·⁻⁰¹²³⁴⁵⁶⁷⁸⁹°ÅΩƱΩ℧
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_17/load_out.json view
@@ -0,0 +1,18 @@+{+    "": "",+    "~!@#$%^&*()_+-1234567890{}[]|\\;<>?,./": "~!@#$%^&*()_+-1234567890{}[]|\\:;<>?,./",+    "- key 3": "- value 3",+    "key 4: ": "value 4: ",+    "> key 5": "> value 5",+    "# key 6": "#value 6",+    ": key 7": ": value 7",+    "\" key 8 \"": "\" value 8 \"",+    "' key 9 '": "' value 9 '",+    "key 10": "value '\" 10",+    "key 11": "And Fred said 'yabba dabba doo!' to Barney.",+    "key \" 12": "value ' 12",+    "$€¥£₩₺₽₹ɃΞȄ": "$€¥£₩₺₽₹ɃΞȄ",+    "YZEPTGMKk_cmuµμnpfazy": "YZEPTGMKk_cmuµμnpfazy",+    "a-zA-Z%√{us}{cur}][-^/()\\w·⁻⁰¹²³⁴⁵⁶⁷⁸⁹°ÅΩƱΩ℧": "a-zA-Z%√{us}{cur}][-^/()\\w·⁻⁰¹²³⁴⁵⁶⁷⁸⁹°ÅΩƱΩ℧"+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_18/dump_in.json view
@@ -0,0 +1,4 @@+{+    "key 1": "value 1",+    "key'\"2": "value 2"+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_18/dump_out.nt view
@@ -0,0 +1,2 @@+key 1: value 1+key'"2: value 2
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_18/load_in.nt view
@@ -0,0 +1,2 @@+key 1: value 1+key'"2: value 2
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_18/load_out.json view
@@ -0,0 +1,4 @@+{+    "key 1": "value 1",+    "key'\"2": "value 2"+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_19/load_in.nt view
@@ -0,0 +1,4 @@+# Trailing whitespace in keys is insignficant.+k1: v1+k2 : v2+k3  : v3
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_19/load_out.json view
@@ -0,0 +1,1 @@+{"k1": "v1", "k2": "v2", "k3": "v3"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_20/dump_in.json view
@@ -0,0 +1,15 @@+{+  "-#:'>": "-#:\">:",+  "-#:\">": "-#:'>:",+  "-#'\\'>:": "-#\"\\\">::",+  "-#\"\\\">:": "-#'\\'>::",+  ":-#:'>": ":-#:\">:",+  ":-#:\">": ":-#:'>:",+  ":-#'\\'>:": ":-#\"\\\">::",+  ":-#\"\\\">:": ":-#'\\'>::",+  ">:-#:'>": ">:-#:\">:",+  ">:-#:\">": ">:-#:'>:",+  ">:-#'\\'>:": ">:-#\"\\\">::",+  ">:-#\"\\\">:": ">:-#'\\'>::"+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_20/dump_out.nt view
@@ -0,0 +1,12 @@+-#:'>: -#:">:+-#:">: -#:'>:+-#'\'>:: -#"\">::+-#"\">:: -#'\'>::+:-#:'>: :-#:">:+:-#:">: :-#:'>:+:-#'\'>:: :-#"\">::+:-#"\">:: :-#'\'>::+>:-#:'>: >:-#:">:+>:-#:">: >:-#:'>:+>:-#'\'>:: >:-#"\">::+>:-#"\">:: >:-#'\'>::
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_20/load_in.nt view
@@ -0,0 +1,15 @@+# various valid dictionary items with unusual unquoted keys+-#:'>: -#:">:+-#:">: -#:'>:+-#'\'>:: -#"\">::+-#"\">:: -#'\'>::+    # indented comment+:-#:'>: :-#:">:+:-#:">: :-#:'>:+:-#'\'>:: :-#"\">::+:-#"\">:: :-#'\'>::+        # indented comment+>:-#:'>: >:-#:">:+>:-#:">: >:-#:'>:+>:-#'\'>:: >:-#"\">::+>:-#"\">:: >:-#'\'>::
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_20/load_out.json view
@@ -0,0 +1,15 @@+{+  "-#:'>": "-#:\">:",+  "-#:\">": "-#:'>:",+  "-#'\\'>:": "-#\"\\\">::",+  "-#\"\\\">:": "-#'\\'>::",+  ":-#:'>": ":-#:\">:",+  ":-#:\">": ":-#:'>:",+  ":-#'\\'>:": ":-#\"\\\">::",+  ":-#\"\\\">:": ":-#'\\'>::",+  ">:-#:'>": ">:-#:\">:",+  ">:-#:\">": ">:-#:'>:",+  ">:-#'\\'>:": ">:-#\"\\\">::",+  ">:-#\"\\\">:": ">:-#'\\'>::"+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_21/dump_err.json view
@@ -0,0 +1,4 @@+{+  "culprit": "peach",+  "message": "unsupported type (int)."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_21/dump_in.json view
@@ -0,0 +1,1 @@+{"peach": 3, "apricot": 8, "blueberry": "1 lb", "orange": 4}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_22/dump_err.json view
@@ -0,0 +1,4 @@+{+  "culprit": 8,+  "message": "keys must be strings."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_22/dump_in.py view
@@ -0,0 +1,1 @@+data = {8: '8'}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_23/dump_in.json view
@@ -0,0 +1,22 @@+{+    "key1": "value 1",+    "key2": "value 2",+    "key 3": "value 3",+    "key 4": "value 4",+    "key5": "",+    "key6": "",+    " key7 ": "value 7",+    " key8 ": "value 8",+    " ' key9 ' ": "value 9",+    " \" key10 \" ": "value 10",+    " \" key11: \" ": "value 11",+    " \" key12 : \" ": "value 12",+    " \" key13: ": "value 13",+    " \" key14 : ": "value 14",+    " ' key15': ": "value 15",+    " ' key16' : ": "value 16",+    "": "value 17",+    " ' key18\"' : ": "value 18",+    " \" key19'\" : " : "value 19"++}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_23/dump_out.nt view
@@ -0,0 +1,32 @@+key1: value 1+key2: value 2+key 3: value 3+key 4: value 4+key5:+key6:+:  key7 +    > value 7+:  key8 +    > value 8+:  ' key9 ' +    > value 9+:  " key10 " +    > value 10+:  " key11: " +    > value 11+:  " key12 : " +    > value 12+:  " key13: +    > value 13+:  " key14 : +    > value 14+:  ' key15': +    > value 15+:  ' key16' : +    > value 16+:+    > value 17+:  ' key18"' : +    > value 18+:  " key19'" : +    > value 19
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_23/load_in.nt view
@@ -0,0 +1,32 @@+key1: value 1+key2: value 2+key 3: value 3+key 4: value 4+key5:+key6:+:  key7 +    > value 7+:  key8 +    > value 8+:  ' key9 ' +    > value 9+:  " key10 " +    > value 10+:  " key11: " +    > value 11+:  " key12 : " +    > value 12+:  " key13: +    > value 13+:  " key14 : +    > value 14+:  ' key15': +    > value 15+:  ' key16' : +    > value 16+:+    > value 17+:  ' key18"' : +    > value 18+:  " key19'" : +    > value 19
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_23/load_out.json view
@@ -0,0 +1,22 @@+{+    "key1": "value 1",+    "key2": "value 2",+    "key 3": "value 3",+    "key 4": "value 4",+    "key5": "",+    "key6": "",+    " key7 ": "value 7",+    " key8 ": "value 8",+    " ' key9 ' ": "value 9",+    " \" key10 \" ": "value 10",+    " \" key11: \" ": "value 11",+    " \" key12 : \" ": "value 12",+    " \" key13: ": "value 13",+    " \" key14 : ": "value 14",+    " ' key15': ": "value 15",+    " ' key16' : ": "value 16",+    "": "value 17",+    " ' key18\"' : ": "value 18",+    " \" key19'\" : " : "value 19"++}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_24/dump_in.json view
@@ -0,0 +1,1 @@+{"'a": "': a", "'b: ": "': b"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_24/dump_out.nt view
@@ -0,0 +1,3 @@+'a: ': a+: 'b: +    > ': b
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_25/dump_in.json view
@@ -0,0 +1,20 @@+{+    "This is a key that is\nspread over multiple lines.\nLike normal multiline strings,\nit can contain any character\nwithout restriction.": "This is its value",+    "Here is another multiline key.\nBut in this case it has an empty value.": "",+    "This is another multiline key,\nthis one with a multiline value.": "Here is the multiline value.\nIt is paired with a multiline key.",+    "here is a simple key": "with a simple value",+    "Here is a multiline key\nwith a list value.": [+        "0",+        "1"+    ],+    "Here is a multiline key\nwith a dictionary value.": {+        "a": "a",+        "b": "b"+    },+    "here is another simple key": "with another simple value",+    "here is a multiline key: that kind of looks a dict item": "a multiline value",+    "This is another multiline key,\nthis one with a dictionary as a value that has a multiline key.": {+        "This is another multiline key,\nthis one with a multiline value.": "Here is the multiline value.\nIt is paired with a multiline key."+    },+    "This a multiline key with a blank second line.\n": "yabba dabba doo"+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_25/dump_out.nt view
@@ -0,0 +1,34 @@+: This is a key that is+: spread over multiple lines.+: Like normal multiline strings,+: it can contain any character+: without restriction.+    > This is its value+: Here is another multiline key.+: But in this case it has an empty value.+    >+: This is another multiline key,+: this one with a multiline value.+    > Here is the multiline value.+    > It is paired with a multiline key.+here is a simple key: with a simple value+: Here is a multiline key+: with a list value.+    - 0+    - 1+: Here is a multiline key+: with a dictionary value.+    a: a+    b: b+here is another simple key: with another simple value+: here is a multiline key: that kind of looks a dict item+    > a multiline value+: This is another multiline key,+: this one with a dictionary as a value that has a multiline key.+    : This is another multiline key,+    : this one with a multiline value.+        > Here is the multiline value.+        > It is paired with a multiline key.+: This a multiline key with a blank second line.+:+    > yabba dabba doo
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_25/load_in.nt view
@@ -0,0 +1,44 @@+: This is a key that is+: spread over multiple lines.+: Like normal multiline strings,+: it can contain any character+: without restriction.+    > This is its value++: Here is another multiline key.+: But in this case it has an empty value.+    >++: This is another multiline key,+: this one with a multiline value.+    > Here is the multiline value.+    > It is paired with a multiline key.++here is a simple key: with a simple value++: Here is a multiline key+: with a list value.+    - 0+    - 1++: Here is a multiline key+: with a dictionary value.+    a: a+    b: b++here is another simple key: with another simple value++: here is a multiline key: that kind of looks a dict item+    > a multiline value++: This is another multiline key,+: this one with a dictionary as a value that has a multiline key.+    : This is another multiline key,+    : this one with a multiline value.+        > Here is the multiline value.+        > It is paired with a multiline key.++: This a multiline key with a blank second line.+:+    > yabba dabba doo+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_25/load_out.json view
@@ -0,0 +1,20 @@+{+    "This is a key that is\nspread over multiple lines.\nLike normal multiline strings,\nit can contain any character\nwithout restriction.": "This is its value",+    "Here is another multiline key.\nBut in this case it has an empty value.": "",+    "This is another multiline key,\nthis one with a multiline value.": "Here is the multiline value.\nIt is paired with a multiline key.",+    "here is a simple key": "with a simple value",+    "Here is a multiline key\nwith a list value.": [+        "0",+        "1"+    ],+    "Here is a multiline key\nwith a dictionary value.": {+        "a": "a",+        "b": "b"+    },+    "here is another simple key": "with another simple value",+    "here is a multiline key: that kind of looks a dict item": "a multiline value",+    "This is another multiline key,\nthis one with a dictionary as a value that has a multiline key.": {+        "This is another multiline key,\nthis one with a multiline value.": "Here is the multiline value.\nIt is paired with a multiline key."+    },+    "This a multiline key with a blank second line.\n": "yabba dabba doo"+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_26/dump_in.json view
@@ -0,0 +1,9 @@+{+    "A": {+        "B:": ""+    },+    "C :": "",+    "D": "",+    "E": "",+    "F1\nF2": ""+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_26/dump_out.nt view
@@ -0,0 +1,8 @@+A:+    B::+C ::+D:+E:+: F1+: F2+    >
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_26/load_in.nt view
@@ -0,0 +1,11 @@+A :+ : B:+  >+: C :+ >+D :+: E+ >+: F1+: F2+ >
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_26/load_out.json view
@@ -0,0 +1,9 @@+{+    "A": {+        "B:": ""+    },+    "C :": "",+    "D": "",+    "E": "",+    "F1\nF2": ""+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_27/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 1,+  "message": "multiline key requires a value."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_27/load_in.nt view
@@ -0,0 +1,5 @@+A :+ : B:+: C :+D :+: E
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_28/dump_in.json view
@@ -0,0 +1,179 @@+{+    "tether": {+        "disclose": "paranoid clunk gaggle",+        "prolong": "stove banish",+        "navel": "-clipboard organist signify",+        "crane": "-washout honey guarantor=aircrew",+        "inure": "fondle = 10kΩ*dissect"+    },+    "majesty": {+        "fatten": "washbowl flagon gentile hairstyle",+        "static": "lender busby",+        "niece": "-humpback adduce ferryboat",+        "reservoir": "-dally idiot enlarge=avalanche",+        "wally": "divorcee = 10kΩ*fugue"+    },+    "banner": {+        "scepter": "trollop living giddy",+        "lager": "piper glacier",+        "debunk": "-trapeze person matron",+        "pecan": "-uncanny perform megaton=profiteer",+        "register": "answer = 10kΩ*trend"+    },+    "monolith": {+        "partitive": "bookie outcome buckskin",+        "roller": "pixie fraud",+        "change": "scullery-roach rubber reveal+payoff",+        "simulator": "smock fritter consign=chateau",+        "narrow": "betrothal = 10kΩ*trooper - landau"+    },+    "reinstate": {+        "dramatist": "pasture glade enslave upright",+        "kinky": "deuce birdie",+        "bathroom": "people-layoff fluke flood+sonata",+        "heart": "loiter feature scamper=drivel",+        "vendetta": "nauseate = 10kΩ*hoodlum - signboard"+    },+    "overstate": {+        "deter": "clitoris treachery reading",+        "saddlebag": "doodle enunciate",+        "cherub": "cupboard-shingle refuge reefer+animate",+        "overcome": "gasometer crease bazooka=thriller",+        "poplar": "centipede = 10kΩ*headman - dewlap"+    },+    "[testament:blight] spangle": {+        "otter": "adherent disguise electrode biplane",+        "stormy": "curfew neuter",+        "spaceman": "addict = snowman*(anxiety+embitter)*bayonet kestrel liken",+        "hardy thinner": "'pretend",+        "belief": "sphere",+        "sachet": "fortnight: twitch(hopper) rebut duodenum=bottom; pleat=onward.\nfrizz: galley(genealogy) advantage whelk=-sprawl; waist=-immigrant."+    },+    "[mongrel:sequester] prism": {+        "bairn": "easterner racketeer shortfall bootlace amoeba",+        "canopy": "refuse profit",+        "snuggle": "baritone = scrounger*(supplier+clobber)*flutter agate simplify",+        "edition industry": "'castle",+        "tenth": "rhyme",+        "scrunch": "ledge: exporter(wrongdoer) levitate daiquiri=subsidize; bulletin=reason.\njackpot: butcher(frequent) medicine memento=-diaphragm; ointment=-raving."+    },+    "[frogman:alleyway] fatigue": {+        "hyena": "believer timepiece infuriate sixty",+        "cache": "bootee scoopful",+        "laborer": "egoist = lunatic*(obeisance+voice)*gambit nickel queer",+        "scraggy doggie": "'cedar",+        "requisite": "pastor",+        "teacher": "toboggan: champion(dominion) adieu golfer=linen; divorce=stake.\nfireguard: vineyard(confide) seashore diddle=-dartboard; genuflect=-fidget."+    },+    "install": {+        "abide": "waistline",+        "skunk": "coarsen nuisance",+        "briar": "eviction = glide && !reliquary overfeed resent",+        "magnum accident": "'quince",+        "nightmare": "cheapen"+    },+    "withdraw": {+        "chalice": "noble canard",+        "siphon": "utility overhead",+        "butler": "aspirin.starlet < heater < brace.blockade",+        "juggler": "crumpet = sunny + slattern + persuade. cataclysm = scolding.",+        "betake": "projector.insulator",+        "hearth": "convector"+    },+    "surgery": {+        "sunbathe": "decathlon",+        "fixation": "heighten watcher",+        "stretchy": "-washday < burnish < debrief",+        "scabbard": "reward"+    },+    "intercede barony": {+        "busker": "yachtsman-fleshpot sandbag flummox",+        "vestry": "panorama",+        "sanction": "drench=\"%keyboard\""+    },+    "harmony creaky": {+        "physicist": "gauge-doublet bungalow clink",+        "swerve": "cleanser",+        "royalty": "essay=\"%honeymoon\";\nextol = \"swampy\";\nalmshouse = \"\"."+    },+    "caterwaul imitation": {+        "dunce": "bodice sitcom chipmunk",+        "profane": "monocle",+        "sortie": "impute=\"%covert\""+    },+    "menace": {+        "dredge": "miasma litigant broil",+        "bishop": "medley",+        "inquest": "scourer=\"%gamma\"; mesmerize='ballcock"+    },+    "mattock": {+        "taint": "buttery combatant stalwart",+        "oculist": "implicate",+        "support": "closure='snake; phoenix=\"%smoothie\""+    },+    "chance": {+        "riposte": "crusade",+        "scripture": "cathode",+        "doorstep": "dukedom=screening; lifebuoy=\"%crackle\"",+        "salesman": "shimmer cobweb spool=butter."+    },+    "asset": {+        "overthrow": "dainty",+        "chancy": "bough psychotic",+        "sultana": "father hormone caliber=mayday."+    },+    "pollinate": {+        "doctor": "masochist",+        "strangler": "saloon ensemble shower",+        "tuxedo": "inject='strategy;\npurport={toffee,ripper}.",+        "citadel": "shrew repellent dairymaid=laser; elevator=biped.\nresound garage mistreat=rebuild; scree=choke.\nanchor begrudge slalom=reassert; molester=chopper.\ndizzy outbreak snifter=tussle; remove=survive.\nnoodle panegyric importune=native; accredit=loser."+    },+    "acquit invest gravity": {+        "remain": "beetroot maroon cliche ninety",+        "bookmark": "munch",+        "commodore": "plank=sundry;\nprick=rehear;\nbonnet=\"banana\"",+        "transfer": "blister project adjective=slinky; uncover=salty.\nbowler acquiesce nobody=syllabus; bushy=fossilize."+    },+    "horror megalith": {+        "spurt": "flower towpath rejoicing dowry rupture",+        "recur": "capacity",+        "tract": "goatee='graze;\nliqueur=\"scream\";\ndetain=prefigure;\nspill={eggplant,poach}",+        "plunger": "cutting dislocate prince=spongy; flirt=debut.\nneurone cricketer shredder=property; break=octagon; plutocrat=lapwing.\nsofty expert tycoon=qualify; coachman=heretic.\nredwood notebook heath=blackjack; frump=washstand.\nloose keeper applaud=destroyer; intention=hymnal.\npotentate brasserie souvenir=tumor; masseur=hasten.\nsanctify report touchdown=afford; combat=impart.\nbrute elder bisexual=penknife; treadmill=thesaurus.\ntissue sickly dimmer=dowdy; cylinder=actor.\nawakening robotic fascia=paperboy; scalp=length; seashell=50μA.\nlarch fashion crack=scorpion; explicate=retire.\nmature lapel incline=dressing; thwack=rivet.\nneologism phonetic zebra=upstage; realtor=showpiece.\nevacuee stride softener=ditty; earth=bookcase.\nuproot cross titter=constrict; specific=wayside.\noverwrite overshoot quandary=panther; cartwheel=ratio."+    },+    "informer payroll": {+        "sequin": "armadillo exclaim foray cuckoo",+        "lynch": "punchbowl",+        "trump": "bedeck=quota;\nmachete=croupier;\nalpine=\"response\";\nvegetable=slowdown.",+        "whisker": "lottery sheath moonlight=chamber.\nfantasize pullover stool=eject."+    },+    "barbarity, allude, whittle": {+        "militant": "garret dictate sweeper",+        "extension": "senator",+        "justify": "taxicab=ferry;\nparagraph=spokesman;\npolitic=codpiece;\ngrizzle=clerk;\nperturb=mudguard;\ndecade=\"sickness\"",+        "broad": "ceramic morsel sahib=gelding.\ngravy shoddy fixative=scramble.\nsmelt beatnik describe=duckling.\nbourbon crusader tabloid=wordy."+    },+    "extenuate, promoter": {+        "store": "treasury dumpling emotion skirmish",+        "epitaph": "incumbent",+        "yearning": "adjudge='yearbook;\nmaneuver=\"infer\";\ncabaret=deception;\nhostel={fossil,diagnose}",+        "sporran": "alphabet counter haughty=ceiling; treadle=reedy.\nhierarchy hardship troll=detractor; holocaust=deafen; gangway=translate.\nthought termite limousine=hustle; tweed=majorette.\nbatten swindler parkland=outsider; crawl=prevail.\nprovision fabric indict=amaze; weight=commando.\nextend cabal charge=admit; umlaut=steel.\nstrength councilor entity=address; encamp=slake.\ntrespass soapbox knoll=befriend; aggregate=allusion.\nsequel fingertip billfold=staunch; particle=combine.\nsediment intellect organizer=blurry; fatty=beard; revel=50μA.\ntoxin steak panacea=elite; scavenge=acoustic.\nfarmyard resign presage=peasant; jumble=regret.\nberry valet alchemist=greasy; clonk=eyesore.\ntreat temper antenatal=interlink; hurtle=catchy.\nobtain seaweed offender=cameo; jostle=reprove.\nrigidity radish braise=scoot; petty=marquee."+    },+    "menage, quail": {+        "outspread": "share pinion fruitcake portend",+        "reference": "appendix",+        "daily": "scrapbook=rejoin;\ndrier=agonize;\nsewer=\"dollop\";\nbistro=ratepayer.",+        "flabby": "pentagon rotor science=besiege.\nspider distance shaggy=mayor.\nstatement venture priory=seance.\nsextet riddle shabby=stationer."+    },+    "jelly, exude": {+        "naught": "misread sandbank speculate",+        "espresso": "dispel",+        "oilman": "amalgam=additive;\ntatty=unsettle;\nlousy=\"clamber\";\nradiator = \"paring, anatomist\";\nsidle=thatch.",+        "episode": "council whiplash muscle=carriage.\nbaseline nymph tantrum=spoof; prognosis=trundle; friend=plump.comedy.\ninduct tubby compost=crank.\nfamily stately expunge=echelon."+    },+    "holding, scruple": {+        "ramrod": "tableau beret",+        "flatten": "tributary",+        "cobra": "hunchback=bumpy;\nlorry=\"inkling\";\nholler = \"pedant, lifeboat\";\nbutchery=antique.",+        "decree": "embroil numskull stigma=explosion.\ngrand bonus accord=scarf.\namplifier prattle submerge=justice.\ngrace arrowhead athlete=shaver."+    }+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_28/dump_out.nt view
@@ -0,0 +1,251 @@+tether:+    disclose: paranoid clunk gaggle+    prolong: stove banish+    navel: -clipboard organist signify+    crane: -washout honey guarantor=aircrew+    inure: fondle = 10kΩ*dissect+majesty:+    fatten: washbowl flagon gentile hairstyle+    static: lender busby+    niece: -humpback adduce ferryboat+    reservoir: -dally idiot enlarge=avalanche+    wally: divorcee = 10kΩ*fugue+banner:+    scepter: trollop living giddy+    lager: piper glacier+    debunk: -trapeze person matron+    pecan: -uncanny perform megaton=profiteer+    register: answer = 10kΩ*trend+monolith:+    partitive: bookie outcome buckskin+    roller: pixie fraud+    change: scullery-roach rubber reveal+payoff+    simulator: smock fritter consign=chateau+    narrow: betrothal = 10kΩ*trooper - landau+reinstate:+    dramatist: pasture glade enslave upright+    kinky: deuce birdie+    bathroom: people-layoff fluke flood+sonata+    heart: loiter feature scamper=drivel+    vendetta: nauseate = 10kΩ*hoodlum - signboard+overstate:+    deter: clitoris treachery reading+    saddlebag: doodle enunciate+    cherub: cupboard-shingle refuge reefer+animate+    overcome: gasometer crease bazooka=thriller+    poplar: centipede = 10kΩ*headman - dewlap+: [testament:blight] spangle+    otter: adherent disguise electrode biplane+    stormy: curfew neuter+    spaceman: addict = snowman*(anxiety+embitter)*bayonet kestrel liken+    hardy thinner: 'pretend+    belief: sphere+    sachet:+        > fortnight: twitch(hopper) rebut duodenum=bottom; pleat=onward.+        > frizz: galley(genealogy) advantage whelk=-sprawl; waist=-immigrant.+: [mongrel:sequester] prism+    bairn: easterner racketeer shortfall bootlace amoeba+    canopy: refuse profit+    snuggle: baritone = scrounger*(supplier+clobber)*flutter agate simplify+    edition industry: 'castle+    tenth: rhyme+    scrunch:+        > ledge: exporter(wrongdoer) levitate daiquiri=subsidize; bulletin=reason.+        > jackpot: butcher(frequent) medicine memento=-diaphragm; ointment=-raving.+: [frogman:alleyway] fatigue+    hyena: believer timepiece infuriate sixty+    cache: bootee scoopful+    laborer: egoist = lunatic*(obeisance+voice)*gambit nickel queer+    scraggy doggie: 'cedar+    requisite: pastor+    teacher:+        > toboggan: champion(dominion) adieu golfer=linen; divorce=stake.+        > fireguard: vineyard(confide) seashore diddle=-dartboard; genuflect=-fidget.+install:+    abide: waistline+    skunk: coarsen nuisance+    briar: eviction = glide && !reliquary overfeed resent+    magnum accident: 'quince+    nightmare: cheapen+withdraw:+    chalice: noble canard+    siphon: utility overhead+    butler: aspirin.starlet < heater < brace.blockade+    juggler: crumpet = sunny + slattern + persuade. cataclysm = scolding.+    betake: projector.insulator+    hearth: convector+surgery:+    sunbathe: decathlon+    fixation: heighten watcher+    stretchy: -washday < burnish < debrief+    scabbard: reward+intercede barony:+    busker: yachtsman-fleshpot sandbag flummox+    vestry: panorama+    sanction: drench="%keyboard"+harmony creaky:+    physicist: gauge-doublet bungalow clink+    swerve: cleanser+    royalty:+        > essay="%honeymoon";+        > extol = "swampy";+        > almshouse = "".+caterwaul imitation:+    dunce: bodice sitcom chipmunk+    profane: monocle+    sortie: impute="%covert"+menace:+    dredge: miasma litigant broil+    bishop: medley+    inquest: scourer="%gamma"; mesmerize='ballcock+mattock:+    taint: buttery combatant stalwart+    oculist: implicate+    support: closure='snake; phoenix="%smoothie"+chance:+    riposte: crusade+    scripture: cathode+    doorstep: dukedom=screening; lifebuoy="%crackle"+    salesman: shimmer cobweb spool=butter.+asset:+    overthrow: dainty+    chancy: bough psychotic+    sultana: father hormone caliber=mayday.+pollinate:+    doctor: masochist+    strangler: saloon ensemble shower+    tuxedo:+        > inject='strategy;+        > purport={toffee,ripper}.+    citadel:+        > shrew repellent dairymaid=laser; elevator=biped.+        > resound garage mistreat=rebuild; scree=choke.+        > anchor begrudge slalom=reassert; molester=chopper.+        > dizzy outbreak snifter=tussle; remove=survive.+        > noodle panegyric importune=native; accredit=loser.+acquit invest gravity:+    remain: beetroot maroon cliche ninety+    bookmark: munch+    commodore:+        > plank=sundry;+        > prick=rehear;+        > bonnet="banana"+    transfer:+        > blister project adjective=slinky; uncover=salty.+        > bowler acquiesce nobody=syllabus; bushy=fossilize.+horror megalith:+    spurt: flower towpath rejoicing dowry rupture+    recur: capacity+    tract:+        > goatee='graze;+        > liqueur="scream";+        > detain=prefigure;+        > spill={eggplant,poach}+    plunger:+        > cutting dislocate prince=spongy; flirt=debut.+        > neurone cricketer shredder=property; break=octagon; plutocrat=lapwing.+        > softy expert tycoon=qualify; coachman=heretic.+        > redwood notebook heath=blackjack; frump=washstand.+        > loose keeper applaud=destroyer; intention=hymnal.+        > potentate brasserie souvenir=tumor; masseur=hasten.+        > sanctify report touchdown=afford; combat=impart.+        > brute elder bisexual=penknife; treadmill=thesaurus.+        > tissue sickly dimmer=dowdy; cylinder=actor.+        > awakening robotic fascia=paperboy; scalp=length; seashell=50μA.+        > larch fashion crack=scorpion; explicate=retire.+        > mature lapel incline=dressing; thwack=rivet.+        > neologism phonetic zebra=upstage; realtor=showpiece.+        > evacuee stride softener=ditty; earth=bookcase.+        > uproot cross titter=constrict; specific=wayside.+        > overwrite overshoot quandary=panther; cartwheel=ratio.+informer payroll:+    sequin: armadillo exclaim foray cuckoo+    lynch: punchbowl+    trump:+        > bedeck=quota;+        > machete=croupier;+        > alpine="response";+        > vegetable=slowdown.+    whisker:+        > lottery sheath moonlight=chamber.+        > fantasize pullover stool=eject.+barbarity, allude, whittle:+    militant: garret dictate sweeper+    extension: senator+    justify:+        > taxicab=ferry;+        > paragraph=spokesman;+        > politic=codpiece;+        > grizzle=clerk;+        > perturb=mudguard;+        > decade="sickness"+    broad:+        > ceramic morsel sahib=gelding.+        > gravy shoddy fixative=scramble.+        > smelt beatnik describe=duckling.+        > bourbon crusader tabloid=wordy.+extenuate, promoter:+    store: treasury dumpling emotion skirmish+    epitaph: incumbent+    yearning:+        > adjudge='yearbook;+        > maneuver="infer";+        > cabaret=deception;+        > hostel={fossil,diagnose}+    sporran:+        > alphabet counter haughty=ceiling; treadle=reedy.+        > hierarchy hardship troll=detractor; holocaust=deafen; gangway=translate.+        > thought termite limousine=hustle; tweed=majorette.+        > batten swindler parkland=outsider; crawl=prevail.+        > provision fabric indict=amaze; weight=commando.+        > extend cabal charge=admit; umlaut=steel.+        > strength councilor entity=address; encamp=slake.+        > trespass soapbox knoll=befriend; aggregate=allusion.+        > sequel fingertip billfold=staunch; particle=combine.+        > sediment intellect organizer=blurry; fatty=beard; revel=50μA.+        > toxin steak panacea=elite; scavenge=acoustic.+        > farmyard resign presage=peasant; jumble=regret.+        > berry valet alchemist=greasy; clonk=eyesore.+        > treat temper antenatal=interlink; hurtle=catchy.+        > obtain seaweed offender=cameo; jostle=reprove.+        > rigidity radish braise=scoot; petty=marquee.+menage, quail:+    outspread: share pinion fruitcake portend+    reference: appendix+    daily:+        > scrapbook=rejoin;+        > drier=agonize;+        > sewer="dollop";+        > bistro=ratepayer.+    flabby:+        > pentagon rotor science=besiege.+        > spider distance shaggy=mayor.+        > statement venture priory=seance.+        > sextet riddle shabby=stationer.+jelly, exude:+    naught: misread sandbank speculate+    espresso: dispel+    oilman:+        > amalgam=additive;+        > tatty=unsettle;+        > lousy="clamber";+        > radiator = "paring, anatomist";+        > sidle=thatch.+    episode:+        > council whiplash muscle=carriage.+        > baseline nymph tantrum=spoof; prognosis=trundle; friend=plump.comedy.+        > induct tubby compost=crank.+        > family stately expunge=echelon.+holding, scruple:+    ramrod: tableau beret+    flatten: tributary+    cobra:+        > hunchback=bumpy;+        > lorry="inkling";+        > holler = "pedant, lifeboat";+        > butchery=antique.+    decree:+        > embroil numskull stigma=explosion.+        > grand bonus accord=scarf.+        > amplifier prattle submerge=justice.+        > grace arrowhead athlete=shaver.
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_28/load_in.nt view
@@ -0,0 +1,279 @@+tether:+    disclose: paranoid clunk gaggle+    prolong: stove banish+    navel: -clipboard organist signify+    crane: -washout honey guarantor=aircrew+    inure: fondle = 10kΩ*dissect++majesty:+    fatten: washbowl flagon gentile hairstyle+    static: lender busby+    niece: -humpback adduce ferryboat+    reservoir: -dally idiot enlarge=avalanche+    wally: divorcee = 10kΩ*fugue++banner:+    scepter: trollop living giddy+    lager: piper glacier+    debunk: -trapeze person matron+    pecan: -uncanny perform megaton=profiteer+    register: answer = 10kΩ*trend++monolith:+    partitive: bookie outcome buckskin+    roller: pixie fraud+    change: scullery-roach rubber reveal+payoff+    simulator: smock fritter consign=chateau+    narrow: betrothal = 10kΩ*trooper - landau++reinstate:+    dramatist: pasture glade enslave upright+    kinky: deuce birdie+    bathroom: people-layoff fluke flood+sonata+    heart: loiter feature scamper=drivel+    vendetta: nauseate = 10kΩ*hoodlum - signboard++overstate:+    deter: clitoris treachery reading+    saddlebag: doodle enunciate+    cherub: cupboard-shingle refuge reefer+animate+    overcome: gasometer crease bazooka=thriller+    poplar: centipede = 10kΩ*headman - dewlap++: [testament:blight] spangle+    otter: adherent disguise electrode biplane+    stormy: curfew neuter+    spaceman: addict = snowman*(anxiety+embitter)*bayonet kestrel liken+    hardy thinner: 'pretend+    belief: sphere+    sachet:+        > fortnight: twitch(hopper) rebut duodenum=bottom; pleat=onward.+        > frizz: galley(genealogy) advantage whelk=-sprawl; waist=-immigrant.++: [mongrel:sequester] prism+    bairn: easterner racketeer shortfall bootlace amoeba+    canopy: refuse profit+    snuggle: baritone = scrounger*(supplier+clobber)*flutter agate simplify+    edition industry: 'castle+    tenth: rhyme+    scrunch:+        > ledge: exporter(wrongdoer) levitate daiquiri=subsidize; bulletin=reason.+        > jackpot: butcher(frequent) medicine memento=-diaphragm; ointment=-raving.++: [frogman:alleyway] fatigue+    hyena: believer timepiece infuriate sixty+    cache: bootee scoopful+    laborer: egoist = lunatic*(obeisance+voice)*gambit nickel queer+    scraggy doggie: 'cedar+    requisite: pastor+    teacher:+        > toboggan: champion(dominion) adieu golfer=linen; divorce=stake.+        > fireguard: vineyard(confide) seashore diddle=-dartboard; genuflect=-fidget.++install:+    abide: waistline+    skunk: coarsen nuisance+    briar: eviction = glide && !reliquary overfeed resent+    magnum accident: 'quince+    nightmare: cheapen++withdraw:+    chalice: noble canard+    siphon: utility overhead+    butler: aspirin.starlet < heater < brace.blockade+    juggler: crumpet = sunny + slattern + persuade. cataclysm = scolding.+    betake: projector.insulator+    hearth: convector++surgery:+    sunbathe: decathlon+    fixation: heighten watcher+    stretchy: -washday < burnish < debrief+    scabbard: reward++intercede barony:+    busker: yachtsman-fleshpot sandbag flummox+    vestry: panorama+    sanction: drench="%keyboard"++harmony creaky:+    physicist: gauge-doublet bungalow clink+    swerve: cleanser+    royalty:+        > essay="%honeymoon";+        > extol = "swampy";+        > almshouse = "".++caterwaul imitation:+    dunce: bodice sitcom chipmunk+    profane: monocle+    sortie: impute="%covert"++menace:+    dredge: miasma litigant broil+    bishop: medley+    inquest: scourer="%gamma"; mesmerize='ballcock++mattock:+    taint: buttery combatant stalwart+    oculist: implicate+    support: closure='snake; phoenix="%smoothie"++chance:+    riposte: crusade+    scripture: cathode+    doorstep: dukedom=screening; lifebuoy="%crackle"+    salesman: shimmer cobweb spool=butter.++asset:+    overthrow: dainty+    chancy: bough psychotic+    sultana: father hormone caliber=mayday.++pollinate:+    doctor: masochist+    strangler: saloon ensemble shower+    tuxedo:+        > inject='strategy;+        > purport={toffee,ripper}.+    citadel:+        > shrew repellent dairymaid=laser; elevator=biped.+        > resound garage mistreat=rebuild; scree=choke.+        > anchor begrudge slalom=reassert; molester=chopper.+        > dizzy outbreak snifter=tussle; remove=survive.+        > noodle panegyric importune=native; accredit=loser.++acquit invest gravity:+    remain: beetroot maroon cliche ninety+    bookmark: munch+    commodore:+        > plank=sundry;+        > prick=rehear;+        > bonnet="banana"+    transfer:+        > blister project adjective=slinky; uncover=salty.+        > bowler acquiesce nobody=syllabus; bushy=fossilize.++horror megalith:+    spurt: flower towpath rejoicing dowry rupture+    recur: capacity+    tract:+        > goatee='graze;+        > liqueur="scream";+        > detain=prefigure;+        > spill={eggplant,poach}+    plunger:+        > cutting dislocate prince=spongy; flirt=debut.+        > neurone cricketer shredder=property; break=octagon; plutocrat=lapwing.+        > softy expert tycoon=qualify; coachman=heretic.+        > redwood notebook heath=blackjack; frump=washstand.+        > loose keeper applaud=destroyer; intention=hymnal.+        > potentate brasserie souvenir=tumor; masseur=hasten.+        > sanctify report touchdown=afford; combat=impart.+        > brute elder bisexual=penknife; treadmill=thesaurus.+        > tissue sickly dimmer=dowdy; cylinder=actor.+        > awakening robotic fascia=paperboy; scalp=length; seashell=50μA.+        > larch fashion crack=scorpion; explicate=retire.+        > mature lapel incline=dressing; thwack=rivet.+        > neologism phonetic zebra=upstage; realtor=showpiece.+        > evacuee stride softener=ditty; earth=bookcase.+        > uproot cross titter=constrict; specific=wayside.+        > overwrite overshoot quandary=panther; cartwheel=ratio.++informer payroll:+    sequin: armadillo exclaim foray cuckoo+    lynch: punchbowl+    trump:+        > bedeck=quota;+        > machete=croupier;+        > alpine="response";+        > vegetable=slowdown.+    whisker:+        > lottery sheath moonlight=chamber.+        > fantasize pullover stool=eject.++barbarity, allude, whittle:+    militant: garret dictate sweeper+    extension: senator+    justify:+        > taxicab=ferry;+        > paragraph=spokesman;+        > politic=codpiece;+        > grizzle=clerk;+        > perturb=mudguard;+        > decade="sickness"+    broad:+        > ceramic morsel sahib=gelding.+        > gravy shoddy fixative=scramble.+        > smelt beatnik describe=duckling.+        > bourbon crusader tabloid=wordy.++extenuate, promoter:+    store: treasury dumpling emotion skirmish+    epitaph: incumbent+    yearning:+        > adjudge='yearbook;+        > maneuver="infer";+        > cabaret=deception;+        > hostel={fossil,diagnose}+    sporran:+        > alphabet counter haughty=ceiling; treadle=reedy.+        > hierarchy hardship troll=detractor; holocaust=deafen; gangway=translate.+        > thought termite limousine=hustle; tweed=majorette.+        > batten swindler parkland=outsider; crawl=prevail.+        > provision fabric indict=amaze; weight=commando.+        > extend cabal charge=admit; umlaut=steel.+        > strength councilor entity=address; encamp=slake.+        > trespass soapbox knoll=befriend; aggregate=allusion.+        > sequel fingertip billfold=staunch; particle=combine.+        > sediment intellect organizer=blurry; fatty=beard; revel=50μA.+        > toxin steak panacea=elite; scavenge=acoustic.+        > farmyard resign presage=peasant; jumble=regret.+        > berry valet alchemist=greasy; clonk=eyesore.+        > treat temper antenatal=interlink; hurtle=catchy.+        > obtain seaweed offender=cameo; jostle=reprove.+        > rigidity radish braise=scoot; petty=marquee.++menage, quail:+    outspread: share pinion fruitcake portend+    reference: appendix+    daily:+        > scrapbook=rejoin;+        > drier=agonize;+        > sewer="dollop";+        > bistro=ratepayer.+    flabby:+        > pentagon rotor science=besiege.+        > spider distance shaggy=mayor.+        > statement venture priory=seance.+        > sextet riddle shabby=stationer.++jelly, exude:+    naught: misread sandbank speculate+    espresso: dispel+    oilman:+        > amalgam=additive;+        > tatty=unsettle;+        > lousy="clamber";+        > radiator = "paring, anatomist";+        > sidle=thatch.+    episode:+        > council whiplash muscle=carriage.+        > baseline nymph tantrum=spoof; prognosis=trundle; friend=plump.comedy.+        > induct tubby compost=crank.+        > family stately expunge=echelon.++holding, scruple:+    ramrod: tableau beret+    flatten: tributary+    cobra:+        > hunchback=bumpy;+        > lorry="inkling";+        > holler = "pedant, lifeboat";+        > butchery=antique.+    decree:+        > embroil numskull stigma=explosion.+        > grand bonus accord=scarf.+        > amplifier prattle submerge=justice.+        > grace arrowhead athlete=shaver.+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_28/load_out.json view
@@ -0,0 +1,179 @@+{+    "tether": {+        "disclose": "paranoid clunk gaggle",+        "prolong": "stove banish",+        "navel": "-clipboard organist signify",+        "crane": "-washout honey guarantor=aircrew",+        "inure": "fondle = 10kΩ*dissect"+    },+    "majesty": {+        "fatten": "washbowl flagon gentile hairstyle",+        "static": "lender busby",+        "niece": "-humpback adduce ferryboat",+        "reservoir": "-dally idiot enlarge=avalanche",+        "wally": "divorcee = 10kΩ*fugue"+    },+    "banner": {+        "scepter": "trollop living giddy",+        "lager": "piper glacier",+        "debunk": "-trapeze person matron",+        "pecan": "-uncanny perform megaton=profiteer",+        "register": "answer = 10kΩ*trend"+    },+    "monolith": {+        "partitive": "bookie outcome buckskin",+        "roller": "pixie fraud",+        "change": "scullery-roach rubber reveal+payoff",+        "simulator": "smock fritter consign=chateau",+        "narrow": "betrothal = 10kΩ*trooper - landau"+    },+    "reinstate": {+        "dramatist": "pasture glade enslave upright",+        "kinky": "deuce birdie",+        "bathroom": "people-layoff fluke flood+sonata",+        "heart": "loiter feature scamper=drivel",+        "vendetta": "nauseate = 10kΩ*hoodlum - signboard"+    },+    "overstate": {+        "deter": "clitoris treachery reading",+        "saddlebag": "doodle enunciate",+        "cherub": "cupboard-shingle refuge reefer+animate",+        "overcome": "gasometer crease bazooka=thriller",+        "poplar": "centipede = 10kΩ*headman - dewlap"+    },+    "[testament:blight] spangle": {+        "otter": "adherent disguise electrode biplane",+        "stormy": "curfew neuter",+        "spaceman": "addict = snowman*(anxiety+embitter)*bayonet kestrel liken",+        "hardy thinner": "'pretend",+        "belief": "sphere",+        "sachet": "fortnight: twitch(hopper) rebut duodenum=bottom; pleat=onward.\nfrizz: galley(genealogy) advantage whelk=-sprawl; waist=-immigrant."+    },+    "[mongrel:sequester] prism": {+        "bairn": "easterner racketeer shortfall bootlace amoeba",+        "canopy": "refuse profit",+        "snuggle": "baritone = scrounger*(supplier+clobber)*flutter agate simplify",+        "edition industry": "'castle",+        "tenth": "rhyme",+        "scrunch": "ledge: exporter(wrongdoer) levitate daiquiri=subsidize; bulletin=reason.\njackpot: butcher(frequent) medicine memento=-diaphragm; ointment=-raving."+    },+    "[frogman:alleyway] fatigue": {+        "hyena": "believer timepiece infuriate sixty",+        "cache": "bootee scoopful",+        "laborer": "egoist = lunatic*(obeisance+voice)*gambit nickel queer",+        "scraggy doggie": "'cedar",+        "requisite": "pastor",+        "teacher": "toboggan: champion(dominion) adieu golfer=linen; divorce=stake.\nfireguard: vineyard(confide) seashore diddle=-dartboard; genuflect=-fidget."+    },+    "install": {+        "abide": "waistline",+        "skunk": "coarsen nuisance",+        "briar": "eviction = glide && !reliquary overfeed resent",+        "magnum accident": "'quince",+        "nightmare": "cheapen"+    },+    "withdraw": {+        "chalice": "noble canard",+        "siphon": "utility overhead",+        "butler": "aspirin.starlet < heater < brace.blockade",+        "juggler": "crumpet = sunny + slattern + persuade. cataclysm = scolding.",+        "betake": "projector.insulator",+        "hearth": "convector"+    },+    "surgery": {+        "sunbathe": "decathlon",+        "fixation": "heighten watcher",+        "stretchy": "-washday < burnish < debrief",+        "scabbard": "reward"+    },+    "intercede barony": {+        "busker": "yachtsman-fleshpot sandbag flummox",+        "vestry": "panorama",+        "sanction": "drench=\"%keyboard\""+    },+    "harmony creaky": {+        "physicist": "gauge-doublet bungalow clink",+        "swerve": "cleanser",+        "royalty": "essay=\"%honeymoon\";\nextol = \"swampy\";\nalmshouse = \"\"."+    },+    "caterwaul imitation": {+        "dunce": "bodice sitcom chipmunk",+        "profane": "monocle",+        "sortie": "impute=\"%covert\""+    },+    "menace": {+        "dredge": "miasma litigant broil",+        "bishop": "medley",+        "inquest": "scourer=\"%gamma\"; mesmerize='ballcock"+    },+    "mattock": {+        "taint": "buttery combatant stalwart",+        "oculist": "implicate",+        "support": "closure='snake; phoenix=\"%smoothie\""+    },+    "chance": {+        "riposte": "crusade",+        "scripture": "cathode",+        "doorstep": "dukedom=screening; lifebuoy=\"%crackle\"",+        "salesman": "shimmer cobweb spool=butter."+    },+    "asset": {+        "overthrow": "dainty",+        "chancy": "bough psychotic",+        "sultana": "father hormone caliber=mayday."+    },+    "pollinate": {+        "doctor": "masochist",+        "strangler": "saloon ensemble shower",+        "tuxedo": "inject='strategy;\npurport={toffee,ripper}.",+        "citadel": "shrew repellent dairymaid=laser; elevator=biped.\nresound garage mistreat=rebuild; scree=choke.\nanchor begrudge slalom=reassert; molester=chopper.\ndizzy outbreak snifter=tussle; remove=survive.\nnoodle panegyric importune=native; accredit=loser."+    },+    "acquit invest gravity": {+        "remain": "beetroot maroon cliche ninety",+        "bookmark": "munch",+        "commodore": "plank=sundry;\nprick=rehear;\nbonnet=\"banana\"",+        "transfer": "blister project adjective=slinky; uncover=salty.\nbowler acquiesce nobody=syllabus; bushy=fossilize."+    },+    "horror megalith": {+        "spurt": "flower towpath rejoicing dowry rupture",+        "recur": "capacity",+        "tract": "goatee='graze;\nliqueur=\"scream\";\ndetain=prefigure;\nspill={eggplant,poach}",+        "plunger": "cutting dislocate prince=spongy; flirt=debut.\nneurone cricketer shredder=property; break=octagon; plutocrat=lapwing.\nsofty expert tycoon=qualify; coachman=heretic.\nredwood notebook heath=blackjack; frump=washstand.\nloose keeper applaud=destroyer; intention=hymnal.\npotentate brasserie souvenir=tumor; masseur=hasten.\nsanctify report touchdown=afford; combat=impart.\nbrute elder bisexual=penknife; treadmill=thesaurus.\ntissue sickly dimmer=dowdy; cylinder=actor.\nawakening robotic fascia=paperboy; scalp=length; seashell=50μA.\nlarch fashion crack=scorpion; explicate=retire.\nmature lapel incline=dressing; thwack=rivet.\nneologism phonetic zebra=upstage; realtor=showpiece.\nevacuee stride softener=ditty; earth=bookcase.\nuproot cross titter=constrict; specific=wayside.\noverwrite overshoot quandary=panther; cartwheel=ratio."+    },+    "informer payroll": {+        "sequin": "armadillo exclaim foray cuckoo",+        "lynch": "punchbowl",+        "trump": "bedeck=quota;\nmachete=croupier;\nalpine=\"response\";\nvegetable=slowdown.",+        "whisker": "lottery sheath moonlight=chamber.\nfantasize pullover stool=eject."+    },+    "barbarity, allude, whittle": {+        "militant": "garret dictate sweeper",+        "extension": "senator",+        "justify": "taxicab=ferry;\nparagraph=spokesman;\npolitic=codpiece;\ngrizzle=clerk;\nperturb=mudguard;\ndecade=\"sickness\"",+        "broad": "ceramic morsel sahib=gelding.\ngravy shoddy fixative=scramble.\nsmelt beatnik describe=duckling.\nbourbon crusader tabloid=wordy."+    },+    "extenuate, promoter": {+        "store": "treasury dumpling emotion skirmish",+        "epitaph": "incumbent",+        "yearning": "adjudge='yearbook;\nmaneuver=\"infer\";\ncabaret=deception;\nhostel={fossil,diagnose}",+        "sporran": "alphabet counter haughty=ceiling; treadle=reedy.\nhierarchy hardship troll=detractor; holocaust=deafen; gangway=translate.\nthought termite limousine=hustle; tweed=majorette.\nbatten swindler parkland=outsider; crawl=prevail.\nprovision fabric indict=amaze; weight=commando.\nextend cabal charge=admit; umlaut=steel.\nstrength councilor entity=address; encamp=slake.\ntrespass soapbox knoll=befriend; aggregate=allusion.\nsequel fingertip billfold=staunch; particle=combine.\nsediment intellect organizer=blurry; fatty=beard; revel=50μA.\ntoxin steak panacea=elite; scavenge=acoustic.\nfarmyard resign presage=peasant; jumble=regret.\nberry valet alchemist=greasy; clonk=eyesore.\ntreat temper antenatal=interlink; hurtle=catchy.\nobtain seaweed offender=cameo; jostle=reprove.\nrigidity radish braise=scoot; petty=marquee."+    },+    "menage, quail": {+        "outspread": "share pinion fruitcake portend",+        "reference": "appendix",+        "daily": "scrapbook=rejoin;\ndrier=agonize;\nsewer=\"dollop\";\nbistro=ratepayer.",+        "flabby": "pentagon rotor science=besiege.\nspider distance shaggy=mayor.\nstatement venture priory=seance.\nsextet riddle shabby=stationer."+    },+    "jelly, exude": {+        "naught": "misread sandbank speculate",+        "espresso": "dispel",+        "oilman": "amalgam=additive;\ntatty=unsettle;\nlousy=\"clamber\";\nradiator = \"paring, anatomist\";\nsidle=thatch.",+        "episode": "council whiplash muscle=carriage.\nbaseline nymph tantrum=spoof; prognosis=trundle; friend=plump.comedy.\ninduct tubby compost=crank.\nfamily stately expunge=echelon."+    },+    "holding, scruple": {+        "ramrod": "tableau beret",+        "flatten": "tributary",+        "cobra": "hunchback=bumpy;\nlorry=\"inkling\";\nholler = \"pedant, lifeboat\";\nbutchery=antique.",+        "decree": "embroil numskull stigma=explosion.\ngrand bonus accord=scarf.\namplifier prattle submerge=justice.\ngrace arrowhead athlete=shaver."+    }+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_29/dump_in.json view
@@ -0,0 +1,9 @@+{+    "{http://www.kde.org/standards/kcfg/1.0}kcfgfile": "",+    "{http://www.kde.org/standards/kcfg/1.0}group": {+        "{http://www.kde.org/standards/kcfg/1.0}entry": [+            {"{http://www.kde.org/standards/kcfg/1.0}default": "250"},+            {"{http://www.kde.org/standards/kcfg/1.0}default": "krunner,yakuake"}+        ]+    }+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_29/dump_out.nt view
@@ -0,0 +1,10 @@+: {http://www.kde.org/standards/kcfg/1.0}kcfgfile+    >+: {http://www.kde.org/standards/kcfg/1.0}group+    : {http://www.kde.org/standards/kcfg/1.0}entry+        -+            : {http://www.kde.org/standards/kcfg/1.0}default+                > 250+        -+            : {http://www.kde.org/standards/kcfg/1.0}default+                > krunner,yakuake
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_29/load_in.nt view
@@ -0,0 +1,10 @@+: {http://www.kde.org/standards/kcfg/1.0}kcfgfile+    >+: {http://www.kde.org/standards/kcfg/1.0}group+    : {http://www.kde.org/standards/kcfg/1.0}entry+        -+            : {http://www.kde.org/standards/kcfg/1.0}default+                > 250+        -+            : {http://www.kde.org/standards/kcfg/1.0}default+                > krunner,yakuake
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_29/load_out.json view
@@ -0,0 +1,9 @@+{+    "{http://www.kde.org/standards/kcfg/1.0}kcfgfile": "",+    "{http://www.kde.org/standards/kcfg/1.0}group": {+        "{http://www.kde.org/standards/kcfg/1.0}entry": [+            {"{http://www.kde.org/standards/kcfg/1.0}default": "250"},+            {"{http://www.kde.org/standards/kcfg/1.0}default": "krunner,yakuake"}+        ]+    }+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_30/dump_in.json view
@@ -0,0 +1,1 @@+{"key1: key2": "value1: value2", "key:": " "}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_30/dump_out.nt view
@@ -0,0 +1,3 @@+: key1: key2+    > value1: value2+key::  
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_30/load_in.nt view
@@ -0,0 +1,3 @@+: key1: key2+    > value1: value2+key::  
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/dict_30/load_out.json view
@@ -0,0 +1,1 @@+{"key1: key2": "value1: value2", "key:": " "}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/empty_1/load_in.nt view
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/empty_1/load_out.json view
@@ -0,0 +1,1 @@+null
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_1/dump_in.json view
@@ -0,0 +1,28 @@+{+  "key 1": "value 1",+  "- key2:": "value2:",+  "  #key3  ": "  #value3  ",+  "key 4": {+      "key 4.1": "value 4.1",+      "key 4.2": "value 4.2",+      "key 4.3": {+          "key 4.3.1": "value 4.3.1",+          "key 4.3.2": "value 4.3.2"+      },+      "key 4.4": [+          "value 4.4.1",+          "value 4.4.2",+          ["value 4.4.3.1", "value 4.4.3.2"]+      ]+  },+  "key 5": "value 5 part 1",+  "key 6": "value 6 part 1\nvalue 6 part 2",+  "key 7": "value 7 part 1\n\nvalue 7 part 3\n",+  "key 8": ["value 8.1", "value 8.2"],+  "key 9": ["value 9.1", "value 9.2"],+  "key 10": "This is a multiline string.  It should end without a newline.",+  "key 11": "This is a multiline string.  It should end with a newline.\n",+  "key 12": "\nThis is another\nmultiline string.\n\nThis continues the same string.\n\n",+  "key 13": ""+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_1/dump_out.nt view
@@ -0,0 +1,45 @@+key 1: value 1+: - key2:+    > value2:+:   #key3  +    >   #value3  +key 4:+    key 4.1: value 4.1+    key 4.2: value 4.2+    key 4.3:+        key 4.3.1: value 4.3.1+        key 4.3.2: value 4.3.2+    key 4.4:+        - value 4.4.1+        - value 4.4.2+        -+            - value 4.4.3.1+            - value 4.4.3.2+key 5: value 5 part 1+key 6:+    > value 6 part 1+    > value 6 part 2+key 7:+    > value 7 part 1+    >+    > value 7 part 3+    >+key 8:+    - value 8.1+    - value 8.2+key 9:+    - value 9.1+    - value 9.2+key 10: This is a multiline string.  It should end without a newline.+key 11:+    > This is a multiline string.  It should end with a newline.+    >+key 12:+    >+    > This is another+    > multiline string.+    >+    > This continues the same string.+    >+    >+key 13:
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_1/load_in.nt view
@@ -0,0 +1,56 @@+# this is a comment, it is ignored+key 1: value 1+                                                                    +: - key2:+    > value2:+                                                                    +:   #key3  +    >   #value3  +                                                                    +key 4:+    key 4.1: value 4.1+    key 4.2: value 4.2+    key 4.3:+        key 4.3.1: value 4.3.1+        key 4.3.2: value 4.3.2+    key 4.4:+        - value 4.4.1+                                                                    +        - value 4.4.2+        -+            - value 4.4.3.1+            - value 4.4.3.2+key 5:+    > value 5 part 1+key 6:+    > value 6 part 1+    > value 6 part 2+key 7:+    > value 7 part 1+    >+    > value 7 part 3+    >+                                                                    +key 8:+    - value 8.1+                                                                    +    - value 8.2+                                                                    +key 9:+    - value 9.1+    - value 9.2+key 10:+    > This is a multiline string.  It should end without a newline.+key 11:+    > This is a multiline string.  It should end with a newline.+    >+key 12:+    >+    > This is another+    > multiline string.+    >+    > This continues the same string.+    >+    >+key 13:+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_1/load_out.json view
@@ -0,0 +1,28 @@+{+  "key 1": "value 1",+  "- key2:": "value2:",+  "  #key3  ": "  #value3  ",+  "key 4": {+      "key 4.1": "value 4.1",+      "key 4.2": "value 4.2",+      "key 4.3": {+          "key 4.3.1": "value 4.3.1",+          "key 4.3.2": "value 4.3.2"+      },+      "key 4.4": [+          "value 4.4.1",+          "value 4.4.2",+          ["value 4.4.3.1", "value 4.4.3.2"]+      ]+  },+  "key 5": "value 5 part 1",+  "key 6": "value 6 part 1\nvalue 6 part 2",+  "key 7": "value 7 part 1\n\nvalue 7 part 3\n",+  "key 8": ["value 8.1", "value 8.2"],+  "key 9": ["value 9.1", "value 9.2"],+  "key 10": "This is a multiline string.  It should end without a newline.",+  "key 11": "This is a multiline string.  It should end with a newline.\n",+  "key 12": "\nThis is another\nmultiline string.\n\nThis continues the same string.\n\n",+  "key 13": ""+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_2/dump_in.json view
@@ -0,0 +1,23 @@+{+  "src_dir": "/",+  "excludes": [+      "/dev",+      "/home/*/.cache",+      "/root/*/.cache",+      "/proc",+      "/sys",+      "/tmp",+      "/var/cache",+      "/var/lock",+      "/var/run",+      "/var/tmp"+  ],+  "keep": {+      "hourly": "24",+      "daily": "7",+      "weekly": "4",+      "monthly": "12",+      "yearly": "5"+  },+  "passphrase": "trouper segregate militia airway pricey sweetmeat tartan bookstall\nobsession charlady twosome silky puffball grubby ranger notation\nrosebud replicate freshen javelin abbot autocue beater byway\n"+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_2/dump_out.nt view
@@ -0,0 +1,23 @@+src_dir: /+excludes:+    - /dev+    - /home/*/.cache+    - /root/*/.cache+    - /proc+    - /sys+    - /tmp+    - /var/cache+    - /var/lock+    - /var/run+    - /var/tmp+keep:+    hourly: 24+    daily: 7+    weekly: 4+    monthly: 12+    yearly: 5+passphrase:+    > trouper segregate militia airway pricey sweetmeat tartan bookstall+    > obsession charlady twosome silky puffball grubby ranger notation+    > rosebud replicate freshen javelin abbot autocue beater byway+    >
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_2/load_in.nt view
@@ -0,0 +1,24 @@+# backup settings for root+src_dir: /+excludes:+    - /dev+    - /home/*/.cache+    - /root/*/.cache+    - /proc+    - /sys+    - /tmp+    - /var/cache+    - /var/lock+    - /var/run+    - /var/tmp+keep:+    hourly: 24+    daily: 7+    weekly: 4+    monthly: 12+    yearly: 5+passphrase:+    > trouper segregate militia airway pricey sweetmeat tartan bookstall+    > obsession charlady twosome silky puffball grubby ranger notation+    > rosebud replicate freshen javelin abbot autocue beater byway+    >
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_2/load_out.json view
@@ -0,0 +1,23 @@+{+  "src_dir": "/",+  "excludes": [+      "/dev",+      "/home/*/.cache",+      "/root/*/.cache",+      "/proc",+      "/sys",+      "/tmp",+      "/var/cache",+      "/var/lock",+      "/var/run",+      "/var/tmp"+  ],+  "keep": {+      "hourly": "24",+      "daily": "7",+      "weekly": "4",+      "monthly": "12",+      "yearly": "5"+  },+  "passphrase": "trouper segregate militia airway pricey sweetmeat tartan bookstall\nobsession charlady twosome silky puffball grubby ranger notation\nrosebud replicate freshen javelin abbot autocue beater byway\n"+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_3/dump_in.json view
@@ -0,0 +1,5 @@+{+  "tux": "",+  "jux": "lux",+  "dux": ["bux", "", "\n", "crux", "", " — "]+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_3/dump_out.nt view
@@ -0,0 +1,11 @@+tux:+jux: lux+dux:+    - bux+    -+    -+        >+        >+    - crux+    -+    -  — 
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_3/load_in.nt view
@@ -0,0 +1,15 @@+# backup settings for root+tux:+jux: lux+dux:+    - bux+    -+    -+        >+        >+                           +    - crux+    -+                           +    -  — +
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_3/load_out.json view
@@ -0,0 +1,5 @@+{+  "tux": "",+  "jux": "lux",+  "dux": ["bux", "", "\n", "crux", "", " — "]+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_4/dump_in.json view
@@ -0,0 +1,8 @@+{+    "output current": "out",+    "description": "Output current",+    "range": "V(gnda) + 0.5V < V < V(vdda) - 0.5V; -500μA <= I <= 500μA",+    "behavior": "current:\n    I = On*Iout;\n    Vout=V;\n    IoutMeas=I with prail=vdda; nrail=gnda",+    "nominal": "V=1.25V+1Ω*I"+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_4/dump_out.nt view
@@ -0,0 +1,9 @@+output current: out+description: Output current+range: V(gnda) + 0.5V < V < V(vdda) - 0.5V; -500μA <= I <= 500μA+behavior:+    > current:+    >     I = On*Iout;+    >     Vout=V;+    >     IoutMeas=I with prail=vdda; nrail=gnda+nominal: V=1.25V+1Ω*I
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_4/load_in.nt view
@@ -0,0 +1,16 @@+# this is a comment+output current: out+description: Output current+range: V(gnda) + 0.5V < V < V(vdda) - 0.5V; -500μA <= I <= 500μA+    # this is another comment+behavior:+    > current:+    >     I = On*Iout;+    # this is mid-string comment+    >     Vout=V;+                                                                 +    >     IoutMeas=I with prail=vdda; nrail=gnda+                                                                 +nominal: V=1.25V+1Ω*I+                                                                 +    # this is the final comment
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_4/load_out.json view
@@ -0,0 +1,8 @@+{+    "output current": "out",+    "description": "Output current",+    "range": "V(gnda) + 0.5V < V < V(vdda) - 0.5V; -500μA <= I <= 500μA",+    "behavior": "current:\n    I = On*Iout;\n    Vout=V;\n    IoutMeas=I with prail=vdda; nrail=gnda",+    "nominal": "V=1.25V+1Ω*I"+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_5/dump_in.json view
@@ -0,0 +1,16 @@+{+    "president": {+        "name": "Katheryn McDaniel",+        "address": "138 Almond Street\nTopeka, Kansas 20697",+        "phone": {+            "cell": "1-210-835-5297",+            "home": "1-210-478-8470"+        },+        "email": "KateMcD@aol.com",+        "kids": [+            "Joanie",+            "Terrance"+        ]+    }+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_5/dump_out.nt view
@@ -0,0 +1,12 @@+president:+    name: Katheryn McDaniel+    address:+        > 138 Almond Street+        > Topeka, Kansas 20697+    phone:+        cell: 1-210-835-5297+        home: 1-210-478-8470+    email: KateMcD@aol.com+    kids:+        - Joanie+        - Terrance
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_5/load_in.nt view
@@ -0,0 +1,12 @@+president:+    name: Katheryn McDaniel+    address:+        > 138 Almond Street+        > Topeka, Kansas 20697+    phone:+        cell: 1-210-835-5297+        home: 1-210-478-8470+    email: KateMcD@aol.com+    kids:+        - Joanie+        - Terrance
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_5/load_out.json view
@@ -0,0 +1,16 @@+{+    "president": {+        "name": "Katheryn McDaniel",+        "address": "138 Almond Street\nTopeka, Kansas 20697",+        "phone": {+            "cell": "1-210-835-5297",+            "home": "1-210-478-8470"+        },+        "email": "KateMcD@aol.com",+        "kids": [+            "Joanie",+            "Terrance"+        ]+    }+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_6/dump_in.json view
@@ -0,0 +1,13 @@+{+    "vice president": {+        "name": "Margaret Hodge",+        "address": "2586 Marigold Lane\nTopeka, Kansas 20682",+        "phone": "1-470-974-0398",+        "email": "margarett.hodge@ku.edu",+        "kids": [+            "Arnie",+            "Zach",+            "Maggie"+        ]+    }+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_6/dump_out.nt view
@@ -0,0 +1,11 @@+vice president:+    name: Margaret Hodge+    address:+        > 2586 Marigold Lane+        > Topeka, Kansas 20682+    phone: 1-470-974-0398+    email: margarett.hodge@ku.edu+    kids:+        - Arnie+        - Zach+        - Maggie
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_6/load_in.nt view
@@ -0,0 +1,12 @@+vice president:+  name: Margaret Hodge+  address:+            > 2586 Marigold Lane+            > Topeka, Kansas 20682+  phone: 1-470-974-0398+  email: margarett.hodge@ku.edu+  kids:+        - Arnie+        - Zach+        - Maggie+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_6/load_out.json view
@@ -0,0 +1,13 @@+{+    "vice president": {+        "name": "Margaret Hodge",+        "address": "2586 Marigold Lane\nTopeka, Kansas 20682",+        "phone": "1-470-974-0398",+        "email": "margarett.hodge@ku.edu",+        "kids": [+            "Arnie",+            "Zach",+            "Maggie"+        ]+    }+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_7/dump_in.json view
@@ -0,0 +1,7 @@+{+  "treasurer": {+      "name": "\t       Fumiko\tPurvis    \t",+      "address": "\t 3636 Buffalo Ave \t\n\t Topeka, Kansas 20692\t "+  }+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_7/dump_out.nt view
@@ -0,0 +1,5 @@+treasurer:+    name: 	       Fumiko	Purvis    	+    address:+        > 	 3636 Buffalo Ave 	+        > 	 Topeka, Kansas 20692	 
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_7/load_in.nt view
@@ -0,0 +1,9 @@+# This example focuses on legal tabs and significant trailing whitespace.  If +# you want to understand what's going on, make sure your editor is configureed +# to show spaces and tabs.+treasurer:+    name	 : 	       Fumiko	Purvis    	+    address:+        > 	 3636 Buffalo Ave 	+        > 	 Topeka, Kansas 20692	 +
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/holistic_7/load_out.json view
@@ -0,0 +1,7 @@+{+  "treasurer": {+      "name": "\t       Fumiko\tPurvis    \t",+      "address": "\t 3636 Buffalo Ave \t\n\t Topeka, Kansas 20692\t "+  }+}+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_01/dump_in.json view
@@ -0,0 +1,132 @@+[+    {},+    {+        "a": "0"+    },+    {+        "a": "k"+    },+    {+        "a": []+    },+    {+        "a": [+            "b"+        ]+    },+    {+        "a": {}+    },+    {+        "a": {+            "b": "1"+        }+    },+    {+        "a": "0",+        "b": "1"+    },+    {+        "a": {+            "A": "0"+        },+        "b": {+            "B": "1"+        }+    },+    {+        "a": {+            "A": "0"+        },+        "b": {+            "B": "1"+        }+    },+    {+        "a": [+            "1",+            "2",+            "3"+        ],+        "b": [+            "4",+            "5",+            "6"+        ]+    },+    {+        "a": "0",+        "b": "1"+    },+    {+        "a": [],+        "b": []+    },+    {+        "a": [+            "0",+            "1"+        ],+        "b": [+            "2",+            "3"+        ]+    },+    {+        "a": {},+        "b": {}+    },+    {+        "a": {+            "b": "0",+            "c": "1"+        },+        "d": {+            "e": "2",+            "f": "3"+        }+    },+    {+        "a": "0",+        "b": []+    },+    {+        "a": [],+        "b": {}+    },+    {+        "a": {},+        "b": "0"+    },+    {+        "a": "0"+    },+    {+        "a": "0"+    },+    {+        "a": "0"+    },+    {+        "a": "0"+    },+    {+        "a": "0"+    },+    {+        "a": "0",+        "b": "1"+    },+    {+        "a": "0",+        "b": "1"+    },+    {+        "a": "0",+        "b": "1"+    },+    {+        "key 1": "value 1",+        "key 2": "value 2"+    }+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_01/dump_out.nt view
@@ -0,0 +1,102 @@+-+    {}+-+    a: 0+-+    a: k+-+    a:+        []+-+    a:+        - b+-+    a:+        {}+-+    a:+        b: 1+-+    a: 0+    b: 1+-+    a:+        A: 0+    b:+        B: 1+-+    a:+        A: 0+    b:+        B: 1+-+    a:+        - 1+        - 2+        - 3+    b:+        - 4+        - 5+        - 6+-+    a: 0+    b: 1+-+    a:+        []+    b:+        []+-+    a:+        - 0+        - 1+    b:+        - 2+        - 3+-+    a:+        {}+    b:+        {}+-+    a:+        b: 0+        c: 1+    d:+        e: 2+        f: 3+-+    a: 0+    b:+        []+-+    a:+        []+    b:+        {}+-+    a:+        {}+    b: 0+-+    a: 0+-+    a: 0+-+    a: 0+-+    a: 0+-+    a: 0+-+    a: 0+    b: 1+-+    a: 0+    b: 1+-+    a: 0+    b: 1+-+    key 1: value 1+    key 2: value 2
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_01/load_in.nt view
@@ -0,0 +1,57 @@++-+    {}+-+    {a:0}+-+    {a: k}+-+    {a:[]}+-+    {a: [b]}+-+    {a:{}}+-+    {a: {b:1}}+-+    {a:0, b:1}+-+    {a:{A:0}, b:{B:1}}+-+    { a : { A : 0 } , b : { B : 1 } }   +-+    {a:[1,2,3], b:[4,5,6]}+-+    {a:0,b:1}+-+    {a:[],b:[]}+-+    {a:[0,1],b:[2,3]}+-+    {a:{},b:{}}+-+    {a:{b:0,c:1},d:{e:2,f:3}}+-+    {a:0,b:[]}+-+    {a:[],b:{}}+-+    {a:{},b:0}+-+    { a:0}+-+    {a :0}+-+    {a: 0}+-+    {a:0 }+-+    { a : 0 }+-+    {a:0, b:1}+-+    {a:0 ,b:1}+-+    {a:0 , b:1}+-+    {key 1:value 1, key 2 : value 2 }
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_01/load_out.json view
@@ -0,0 +1,132 @@+[+    {},+    {+        "a": "0"+    },+    {+        "a": "k"+    },+    {+        "a": []+    },+    {+        "a": [+            "b"+        ]+    },+    {+        "a": {}+    },+    {+        "a": {+            "b": "1"+        }+    },+    {+        "a": "0",+        "b": "1"+    },+    {+        "a": {+            "A": "0"+        },+        "b": {+            "B": "1"+        }+    },+    {+        "a": {+            "A": "0"+        },+        "b": {+            "B": "1"+        }+    },+    {+        "a": [+            "1",+            "2",+            "3"+        ],+        "b": [+            "4",+            "5",+            "6"+        ]+    },+    {+        "a": "0",+        "b": "1"+    },+    {+        "a": [],+        "b": []+    },+    {+        "a": [+            "0",+            "1"+        ],+        "b": [+            "2",+            "3"+        ]+    },+    {+        "a": {},+        "b": {}+    },+    {+        "a": {+            "b": "0",+            "c": "1"+        },+        "d": {+            "e": "2",+            "f": "3"+        }+    },+    {+        "a": "0",+        "b": []+    },+    {+        "a": [],+        "b": {}+    },+    {+        "a": {},+        "b": "0"+    },+    {+        "a": "0"+    },+    {+        "a": "0"+    },+    {+        "a": "0"+    },+    {+        "a": "0"+    },+    {+        "a": "0"+    },+    {+        "a": "0",+        "b": "1"+    },+    {+        "a": "0",+        "b": "1"+    },+    {+        "a": "0",+        "b": "1"+    },+    {+        "key 1": "value 1",+        "key 2": "value 2"+    }+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_02/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "expected ‘:’, found ‘}’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_02/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_03/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 5,+  "message": "line ended without closing delimiter."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_03/load_in.nt view
@@ -0,0 +1,2 @@+-+    {
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_04/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 5,+  "message": "expected ‘:’, found ‘{’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_04/load_in.nt view
@@ -0,0 +1,2 @@+-+    {{}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_05/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "extra character after closing delimiter: ‘}’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_05/load_in.nt view
@@ -0,0 +1,2 @@+-+    {}}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_06/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "expected ‘:’, found ‘,’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_06/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a,:b}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_07/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "expected ‘:’, found ‘{’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_07/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a{:b}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_08/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "expected ‘:’, found ‘}’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_08/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a}:b}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_09/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "expected ‘:’, found ‘[’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_09/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a[:b}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_10/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "expected ‘:’, found ‘]’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_10/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a]:b}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_11/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 8,+  "message": "expected ‘,’ or ‘}’, found ‘{’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_11/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a:b{}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_12/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 9,+  "message": "extra character after closing delimiter: ‘}’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_12/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a:b}}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_13/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 8,+  "message": "expected ‘,’ or ‘}’, found ‘[’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_13/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a:b[}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_14/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 8,+  "message": "expected ‘,’ or ‘}’, found ‘]’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_14/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a:b]}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_15/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 10,+  "message": "expected ‘:’, found ‘,’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_15/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a:0, , }
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_16/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 15,+  "message": "expected ‘:’, found ‘{’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_16/load_in.nt view
@@ -0,0 +1,2 @@+-+    {a:{A:0}, b{B:1}}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_17/dump_in.json view
@@ -0,0 +1,10 @@+{+    "a": {+        "b": "0",+        "c": "1"+    },+    "d": {+        "e": "2",+        "f": "3"+    }+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_17/dump_out.nt view
@@ -0,0 +1,6 @@+a:+    b: 0+    c: 1+d:+    e: 2+    f: 3
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_17/load_in.nt view
@@ -0,0 +1,1 @@+{a: {b:0, c:1}, d: {e:2, f:3}}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_17/load_out.json view
@@ -0,0 +1,10 @@+{+    "a": {+        "b": "0",+        "c": "1"+    },+    "d": {+        "e": "2",+        "f": "3"+    }+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_18/dump_in.json view
@@ -0,0 +1,22 @@+{+    "key 1": {+        "k1.1": "v1.1",+        "k1.2": "v1.2",+        "k1.3": "v1.3"+    },+    "key 2": {+        "k2.1": "v2.1",+        "k2.2": "v2.2",+        "k2.3": "v2.3"+    },+    "key 3": {+        "k3.1": "v3.1",+        "k3.2": "v3.2",+        "k3.3": "v3.3"+    },+    "key 4": {+        "k4.1": "v4.1",+        "k4.2": "v4.2",+        "k4.3": "v4.3"+    }+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_18/dump_out.nt view
@@ -0,0 +1,16 @@+key 1:+    k1.1: v1.1+    k1.2: v1.2+    k1.3: v1.3+key 2:+    k2.1: v2.1+    k2.2: v2.2+    k2.3: v2.3+key 3:+    k3.1: v3.1+    k3.2: v3.2+    k3.3: v3.3+key 4:+    k4.1: v4.1+    k4.2: v4.2+    k4.3: v4.3
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_18/load_in.nt view
@@ -0,0 +1,8 @@+key 1:+        {k1.1:v1.1,	  k1.2:v1.2,      	k1.3:v1.3	}	+key 2:+        {k2.1	:v2.1,	  k2.2	:v2.2,      	k2.3	:v2.3	}	+key 3:+        {k3.1:	v3.1,	  k3.2:	v3.2,      	k3.3:	v3.3	}	+key 4:+        {k4.1	:	v4.1,	  k4.2	:	v4.2,      	k4.3	:	v4.3	}	
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_18/load_out.json view
@@ -0,0 +1,22 @@+{+    "key 1": {+        "k1.1": "v1.1",+        "k1.2": "v1.2",+        "k1.3": "v1.3"+    },+    "key 2": {+        "k2.1": "v2.1",+        "k2.2": "v2.2",+        "k2.3": "v2.3"+    },+    "key 3": {+        "k3.1": "v3.1",+        "k3.2": "v3.2",+        "k3.3": "v3.3"+    },+    "key 4": {+        "k4.1": "v4.1",+        "k4.2": "v4.2",+        "k4.3": "v4.3"+    }+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_19/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 49,+  "message": "expected ‘:’, found ‘}’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_19/load_in.nt view
@@ -0,0 +1,8 @@+key 1:+       {k1.1:v1.1,	  k1.2:v1.2,      	k1.3:v1.3,	}	+key 2:+        {k2.1	:v2.1,	  k2.2	:v2.2,      	k2.3	:v2.3,	}	+key 3:+        {k3.1:	v3.1,	  k3.2:	v3.2,      	k3.3:	v3.3,	}	+key 4:+        {k4.1	:	v4.1,	  k4.2	:	v4.2,      	k4.3	:	v4.3,	}	
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_20/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 0,+  "colno": 5,+  "message": "expected value."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_20/load_in.nt view
@@ -0,0 +1,1 @@+{a:0,}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_21/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 0,+  "colno": 6,+  "message": "expected ‘:’, found ‘}’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_21/load_in.nt view
@@ -0,0 +1,1 @@+{a:0, }
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_22/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 0,+  "colno": 7,+  "message": "expected value."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_22/load_in.nt view
@@ -0,0 +1,1 @@+{a:0,:,}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_23/load_err.json view
@@ -0,0 +1,5 @@+{+    "lineno": 1,+    "colno": null,+    "message": "extra content."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_dict_23/load_in.nt view
@@ -0,0 +1,2 @@+{cases: {*: {*: {*:*}}}}+checks: *.sv
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_01/dump_in.json view
@@ -0,0 +1,117 @@+[+    [],+    [+        "a"+    ],+    [+        ":"+    ],+    [+        []+    ],+    [+        [+            "a"+        ]+    ],+    [+        {}+    ],+    [+        {+            "a": "0"+        }+    ],+    [+        "a",+        "b"+    ],+    [+        [],+        []+    ],+    [+        [+            "a",+            "b"+        ],+        [+            "c",+            "d"+        ]+    ],+    [+        [+            "a",+            "b"+        ],+        [+            "c",+            "d"+        ]+    ],+    [+        {},+        {}+    ],+    [+        {+            "a": "0",+            "b": "1"+        },+        {+            "c": "2",+            "d": "3"+        }+    ],+    [+        "a",+        []+    ],+    [+        [],+        {}+    ],+    [+        {},+        "b"+    ],+    [+        "a"+    ],+    [+        "a"+    ],+    [+        "a"+    ],+    [+        "a",+        "b"+    ],+    [+        "a",+        "b"+    ],+    [+        "a",+        "b"+    ],+    [+        [+            "11",+            "12",+            "13"+        ],+        [+            "21",+            "22",+            "23"+        ],+        [+            "31",+            "32",+            "33"+        ]+    ]+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_01/dump_out.nt view
@@ -0,0 +1,93 @@+-+    []+-+    - a+-+    - :+-+    -+        []+-+    -+        - a+-+    -+        {}+-+    -+        a: 0+-+    - a+    - b+-+    -+        []+    -+        []+-+    -+        - a+        - b+    -+        - c+        - d+-+    -+        - a+        - b+    -+        - c+        - d+-+    -+        {}+    -+        {}+-+    -+        a: 0+        b: 1+    -+        c: 2+        d: 3+-+    - a+    -+        []+-+    -+        []+    -+        {}+-+    -+        {}+    - b+-+    - a+-+    - a+-+    - a+-+    - a+    - b+-+    - a+    - b+-+    - a+    - b+-+    -+        - 11+        - 12+        - 13+    -+        - 21+        - 22+        - 23+    -+        - 31+        - 32+        - 33
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_01/load_in.nt view
@@ -0,0 +1,46 @@+-+    []+-+    [a]+-+    [:]+-+    [[]]+-+    [[a]]+-+    [{}]+-+    [{a:0}]+-+    [a,b]+-+    [[],[]]+-+    [[a,b],[c,d]]+-+    [ [ a , b ] , [ c , d ] ]   +-+    [{},{}]+-+    [{a:0,b:1},{c:2,d:3}]+-+    [a,[]]+-+    [[],{}]+-+    [{},b]+-+    [ a]+-+    [a ]+-+    [ a ]+-+    [a, b]+-+    [a ,b]+-+    [a , b]+-+    [[11,12,13],[21,22,23],[31,32,33]]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_01/load_out.json view
@@ -0,0 +1,117 @@+[+    [],+    [+        "a"+    ],+    [+        ":"+    ],+    [+        []+    ],+    [+        [+            "a"+        ]+    ],+    [+        {}+    ],+    [+        {+            "a": "0"+        }+    ],+    [+        "a",+        "b"+    ],+    [+        [],+        []+    ],+    [+        [+            "a",+            "b"+        ],+        [+            "c",+            "d"+        ]+    ],+    [+        [+            "a",+            "b"+        ],+        [+            "c",+            "d"+        ]+    ],+    [+        {},+        {}+    ],+    [+        {+            "a": "0",+            "b": "1"+        },+        {+            "c": "2",+            "d": "3"+        }+    ],+    [+        "a",+        []+    ],+    [+        [],+        {}+    ],+    [+        {},+        "b"+    ],+    [+        "a"+    ],+    [+        "a"+    ],+    [+        "a"+    ],+    [+        "a",+        "b"+    ],+    [+        "a",+        "b"+    ],+    [+        "a",+        "b"+    ],+    [+        [+            "11",+            "12",+            "13"+        ],+        [+            "21",+            "22",+            "23"+        ],+        [+            "31",+            "32",+            "33"+        ]+    ]+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_02/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 5,+  "message": "line ended without closing delimiter."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_02/load_in.nt view
@@ -0,0 +1,2 @@+-+    [
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_03/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "line ended without closing delimiter."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_03/load_in.nt view
@@ -0,0 +1,2 @@+-+    [,
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_04/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 7,+  "message": "line ended without closing delimiter."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_04/load_in.nt view
@@ -0,0 +1,2 @@+-+    [[]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_05/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "extra characters after closing delimiter: ‘{a:0}’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_05/load_in.nt view
@@ -0,0 +1,2 @@+-+    []{a:0}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_06/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "expected ‘,’ or ‘]’, found ‘[’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_06/load_in.nt view
@@ -0,0 +1,2 @@+-+    [a[b]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_07/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 7,+  "message": "extra characters after closing delimiter: ‘b]’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_07/load_in.nt view
@@ -0,0 +1,2 @@+-+    [a]b]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_08/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "expected ‘:’, found ‘]’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_08/load_in.nt view
@@ -0,0 +1,2 @@+-+    [{]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_09/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 5,+  "message": "expected value."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_09/load_in.nt view
@@ -0,0 +1,2 @@+-+    [}]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_10/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "expected ‘,’ or ‘]’, found ‘{’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_10/load_in.nt view
@@ -0,0 +1,2 @@+-+    [a{b]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_11/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 6,+  "message": "expected ‘,’ or ‘]’, found ‘}’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_11/load_in.nt view
@@ -0,0 +1,2 @@+-+    [a}b]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_12/dump_in.json view
@@ -0,0 +1,17 @@+[+    [+        "11",+        "12",+        "13"+    ],+    [+        "21",+        "22",+        "23"+    ],+    [+        "31",+        "32",+        "33"+    ]+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_12/dump_out.nt view
@@ -0,0 +1,12 @@+-+    - 11+    - 12+    - 13+-+    - 21+    - 22+    - 23+-+    - 31+    - 32+    - 33
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_12/load_in.nt view
@@ -0,0 +1,1 @@+[[11, 12, 13], [21, 22, 23], [31, 32, 33]]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_12/load_out.json view
@@ -0,0 +1,17 @@+[+    [+        "11",+        "12",+        "13"+    ],+    [+        "21",+        "22",+        "23"+    ],+    [+        "31",+        "32",+        "33"+    ]+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_13/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 0,+  "colno": 6,+  "message": "extra characters after closing delimiter: ‘gain:’."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/inline_list_13/load_in.nt view
@@ -0,0 +1,3 @@+[7:0] gain:+    desc: the gain+    type: input signed
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_1/dump_in.json view
@@ -0,0 +1,1 @@+["",""]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_1/dump_out.nt view
@@ -0,0 +1,2 @@+-+-
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_1/load_in.nt view
@@ -0,0 +1,2 @@+-+-
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_1/load_out.json view
@@ -0,0 +1,1 @@+["",""]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_2/dump_in.json view
@@ -0,0 +1,1 @@+["A", "B", "C", ["D1", "D2"], "E"]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_2/dump_out.nt view
@@ -0,0 +1,7 @@+- A+- B+- C+-+    - D1+    - D2+- E
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_2/load_in.nt view
@@ -0,0 +1,7 @@+- A+- B+- C+-+    - D1+    - D2+- E
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_2/load_out.json view
@@ -0,0 +1,1 @@+["A", "B", "C", ["D1", "D2"], "E"]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_3/dump_in.json view
@@ -0,0 +1,1 @@+[]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_3/dump_out.nt view
@@ -0,0 +1,1 @@+[]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_4/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 2,+  "message": "expected list item."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_4/load_in.nt view
@@ -0,0 +1,4 @@+ingredients:+  - green chilies+  cannot mix list with: dictionary+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_5/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 0,+  "message": "top-level content must start in column 1."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_5/load_in.nt view
@@ -0,0 +1,5 @@++    - green chilies++- red chilies+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_6/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 0,+  "message": "invalid indentation."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_6/load_in.nt view
@@ -0,0 +1,3 @@+- green chilies+    - red chilies+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_7/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 0,+  "message": "invalid character in indentation: '\\t'."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_7/load_in.nt view
@@ -0,0 +1,3 @@+# this is an error because indentation is a tab+- +	- red chilies
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_8/dump_in.json view
@@ -0,0 +1,13 @@+[+    ":",+    "~!@#$%^&*()_+-1234567890{}[]|\\:;<>?,./",+    "- value 3",+    "' : value 4:'",+    "> value 5",+    "#value 6",+    "key 7' : : value 7",+    "\" value 8 \"",+    "' value 9 '",+    "value '\" 10",+    "And Fred said 'yabba dabba doo!' to Barney."+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_8/dump_out.nt view
@@ -0,0 +1,11 @@+- :+- ~!@#$%^&*()_+-1234567890{}[]|\:;<>?,./+- - value 3+- ' : value 4:'+- > value 5+- #value 6+- key 7' : : value 7+- " value 8 "+- ' value 9 '+- value '" 10+- And Fred said 'yabba dabba doo!' to Barney.
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_8/load_in.nt view
@@ -0,0 +1,12 @@+- :+- ~!@#$%^&*()_+-1234567890{}[]|\:;<>?,./+- - value 3+- ' : value 4:'+- > value 5+- #value 6+- key 7' : : value 7+- " value 8 "+- ' value 9 '+-+  > value '" 10+- And Fred said 'yabba dabba doo!' to Barney.
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/list_8/load_out.json view
@@ -0,0 +1,13 @@+[+    ":",+    "~!@#$%^&*()_+-1234567890{}[]|\\:;<>?,./",+    "- value 3",+    "' : value 4:'",+    "> value 5",+    "#value 6",+    "key 7' : : value 7",+    "\" value 8 \"",+    "' value 9 '",+    "value '\" 10",+    "And Fred said 'yabba dabba doo!' to Barney."+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_1/dump_in.json view
@@ -0,0 +1,1 @@+{"what makes it green": "\tgreen\tchilies\t"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_1/dump_out.nt view
@@ -0,0 +1,1 @@+what makes it green: 	green	chilies	
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_1/load_in.nt view
@@ -0,0 +1,1 @@+what makes it green	: 	green	chilies	
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_1/load_out.json view
@@ -0,0 +1,1 @@+{"what makes it green": "\tgreen\tchilies\t"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_2/dump_in.json view
@@ -0,0 +1,1 @@+{"key": "value \" value"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_2/dump_out.nt view
@@ -0,0 +1,1 @@+key: value " value
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_2/load_in.nt view
@@ -0,0 +1,1 @@+key: value " value
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_2/load_out.json view
@@ -0,0 +1,1 @@+{"key": "value \" value"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_3/dump_in.json view
@@ -0,0 +1,1 @@+{"key": "value ' value"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_3/dump_out.nt view
@@ -0,0 +1,1 @@+key: value ' value
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_3/load_in.nt view
@@ -0,0 +1,1 @@+key: value ' value
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_3/load_out.json view
@@ -0,0 +1,1 @@+{"key": "value ' value"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_4/dump_in.json view
@@ -0,0 +1,8 @@+{+  "key1": "'And Fred said \"yabba dabba doo!\" to Barney.'",+  "key2": "\"And Fred said 'yabba dabba doo!' to Barney.\"",+  "key3": "\"And Fred said \"yabba dabba doo!\" to Barney.\"",+  "key4": "'And Fred said 'yabba dabba doo!' to Barney.'",+  "key5": "And Fred said \"yabba dabba doo!\" to Barney.",+  "key6": "And Fred said 'yabba dabba doo!' to Barney."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_4/dump_out.nt view
@@ -0,0 +1,6 @@+key1: 'And Fred said "yabba dabba doo!" to Barney.'+key2: "And Fred said 'yabba dabba doo!' to Barney."+key3: "And Fred said "yabba dabba doo!" to Barney."+key4: 'And Fred said 'yabba dabba doo!' to Barney.'+key5: And Fred said "yabba dabba doo!" to Barney.+key6: And Fred said 'yabba dabba doo!' to Barney.
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_4/load_in.nt view
@@ -0,0 +1,6 @@+key1: 'And Fred said "yabba dabba doo!" to Barney.'+key2: "And Fred said 'yabba dabba doo!' to Barney."+key3: "And Fred said "yabba dabba doo!" to Barney."+key4: 'And Fred said 'yabba dabba doo!' to Barney.'+key5: And Fred said "yabba dabba doo!" to Barney.+key6: And Fred said 'yabba dabba doo!' to Barney.
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_4/load_out.json view
@@ -0,0 +1,8 @@+{+  "key1": "'And Fred said \"yabba dabba doo!\" to Barney.'",+  "key2": "\"And Fred said 'yabba dabba doo!' to Barney.\"",+  "key3": "\"And Fred said \"yabba dabba doo!\" to Barney.\"",+  "key4": "'And Fred said 'yabba dabba doo!' to Barney.'",+  "key5": "And Fred said \"yabba dabba doo!\" to Barney.",+  "key6": "And Fred said 'yabba dabba doo!' to Barney."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_5/dump_in.json view
@@ -0,0 +1,1 @@+""
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_5/dump_out.nt view
@@ -0,0 +1,1 @@+>
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_6/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 4,+  "message": "unrecognized line."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_6/load_in.nt view
@@ -0,0 +1,3 @@+ingredients:+    green chilies+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_7/dump_in.json view
@@ -0,0 +1,1 @@+"what makes it green?"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_7/dump_out.nt view
@@ -0,0 +1,1 @@+> what makes it green?
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_7/load_in.nt view
@@ -0,0 +1,2 @@+# This tests a top-level single line string and Unix line endings (LF)+> what makes it green?
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_7/load_out.json view
@@ -0,0 +1,1 @@+"what makes it green?"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_8/dump_in.json view
@@ -0,0 +1,1 @@+"what makes it green?\r\n"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_8/dump_out.nt view
@@ -0,0 +1,2 @@+> what makes it green?+>
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_8/load_in.nt view
@@ -0,0 +1,3 @@+# this is a dos file, and so uses <CR><LF> as an <EOL> mark.
+> what makes it green?
+>
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_8/load_out.json view
@@ -0,0 +1,1 @@+"what makes it green?\n"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_9/dump_in.json view
@@ -0,0 +1,1 @@+"what makes it green?"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_9/dump_out.nt view
@@ -0,0 +1,1 @@+> what makes it green?
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_9/load_in.nt view
@@ -0,0 +1,1 @@+# This tests Mac line endings (CR)
> what makes it green?
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_9/load_out.json view
@@ -0,0 +1,1 @@+"what makes it green?"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_inline_01/dump_in.json view
@@ -0,0 +1,57 @@+[+    [],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’\t\t‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "
‘a’

‘a’
"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ]+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_inline_01/dump_out.nt view
@@ -0,0 +1,38 @@+-+    []+-+    - ‘a’  ‘a’+-+    - ‘a’		‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - 
‘a’

‘a’
+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’+-+    - ‘a’  ‘a’
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_inline_01/load_in.nt view
@@ -0,0 +1,80 @@+# All non-line-break white space before or after a value in an inline list is +# discarded.+# This test checks that this is true with all known white space characters.+-+    []++# ASCII spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# tabs surround ‘a’+-+    [	‘a’		‘a’	]++# no-breck spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# en-quad spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# em-quad spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# en-space spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# em-space spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# three-per-em-space spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# four-per-em-space spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# six-per-em-space spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# figure spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# punctuation spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# thin spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# hair spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# line separators surround ‘a’+-+    [
‘a’

‘a’
]++# mathematical spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# ideographic spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]++# narrow-non-breaking spaces surround ‘a’+-+    [ ‘a’  ‘a’ ]+++# vim: set noexpandtab
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_inline_01/load_out.json view
@@ -0,0 +1,57 @@+[+    [],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’\t\t‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "
‘a’

‘a’
"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ],+    [+        "‘a’  ‘a’"+    ]+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_inline_02/dump_in.json view
@@ -0,0 +1,57 @@+[+    {},+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’\t\t‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "
‘a’

‘a’
"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    }+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_inline_02/dump_out.nt view
@@ -0,0 +1,38 @@+-+    {}+-+    a: ‘a’  ‘a’+-+    a: ‘a’		‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: 
‘a’

‘a’
+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’+-+    a: ‘a’  ‘a’
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_inline_02/load_in.nt view
@@ -0,0 +1,80 @@+# All non-line-break white space before or after a value in an inline list is +# discarded.+# This test checks that this is true with all known white space characters.+-+    {}++# ASCII spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# tabs surround ‘a’+-+    {a:	‘a’		‘a’	}++# no-breck spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# en-quad spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# em-quad spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# en-space spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# em-space spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# three-per-em-space spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# four-per-em-space spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# six-per-em-space spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# figure spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# punctuation spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# thin spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# hair spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# line separators surround ‘a’+-+    {a:
‘a’

‘a’
}++# mathematical spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# ideographic spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }++# narrow-non-breaking spaces surround ‘a’+-+    {a: ‘a’  ‘a’ }+++# vim: set noexpandtab
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_inline_02/load_out.json view
@@ -0,0 +1,57 @@+[+    {},+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’\t\t‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "
‘a’

‘a’
"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    },+    {+        "a": "‘a’  ‘a’"+    }+]
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_01/dump_in.json view
@@ -0,0 +1,1 @@+"\n"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_01/dump_out.nt view
@@ -0,0 +1,2 @@+>+>
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_01/load_in.nt view
@@ -0,0 +1,2 @@+>+>
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_01/load_out.json view
@@ -0,0 +1,1 @@+"\n"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_02/dump_in.json view
@@ -0,0 +1,1 @@+"\nLorem Ipsum\n\n    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, \nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo \nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse \ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat \nnon proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n\n    Sed ut perspiciatis unde omnis iste natus error sit voluptatem\naccusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab \nillo inventore veritatis et quasi architecto beatae vitae dicta sunt \nexplicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit \naut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem \nsequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit \namet, consectetur, adipisci velit, sed quia non numquam eius modi tempora \nincidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad \nminima veniam, quis nostrum exercitationem ullam corporis suscipit \nlaboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum \niure reprehenderit qui in ea voluptate velit esse quam nihil molestiae \nconsequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?\"\n"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_02/dump_out.nt view
@@ -0,0 +1,24 @@+>+> Lorem Ipsum+>+>     Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod+> tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, +> quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo +> consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse +> cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat +> non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.+>+>+>     Sed ut perspiciatis unde omnis iste natus error sit voluptatem+> accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab +> illo inventore veritatis et quasi architecto beatae vitae dicta sunt +> explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit +> aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem +> sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit +> amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora +> incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad +> minima veniam, quis nostrum exercitationem ullam corporis suscipit +> laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum +> iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae +> consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"+>
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_02/load_in.nt view
@@ -0,0 +1,30 @@+>+> Lorem Ipsum+>+>     Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod+> tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, +> quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo +> consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse +> cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat +> non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.+>++# Here is a bit more that one rarely sees ...++>+>     Sed ut perspiciatis unde omnis iste natus error sit voluptatem+> accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab +> illo inventore veritatis et quasi architecto beatae vitae dicta sunt +> explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit +> aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem +> sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit +> amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora +> incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad +> minima veniam, quis nostrum exercitationem ullam corporis suscipit +> laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum +> iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae +> consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"+>++# There is more, but let's stop here.+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_02/load_out.json view
@@ -0,0 +1,1 @@+"\nLorem Ipsum\n\n    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, \nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo \nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse \ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat \nnon proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n\n    Sed ut perspiciatis unde omnis iste natus error sit voluptatem\naccusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab \nillo inventore veritatis et quasi architecto beatae vitae dicta sunt \nexplicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit \naut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem \nsequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit \namet, consectetur, adipisci velit, sed quia non numquam eius modi tempora \nincidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad \nminima veniam, quis nostrum exercitationem ullam corporis suscipit \nlaboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum \niure reprehenderit qui in ea voluptate velit esse quam nihil molestiae \nconsequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?\"\n"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_03/load_in.nt view
@@ -0,0 +1,2 @@+ingredients:+  > green chilies
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_03/load_out.json view
@@ -0,0 +1,1 @@+{"ingredients": "green chilies"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_04/load_in.nt view
@@ -0,0 +1,3 @@+key "' key:+  > value '" value+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_04/load_out.json view
@@ -0,0 +1,1 @@+{"key \"' key": "value '\" value"}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_05/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 0,+  "message": "invalid indentation, partial dedent."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_05/load_in.nt view
@@ -0,0 +1,4 @@+ingredients:+    > green chilies+  > red chilies+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_06/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 2,+  "message": "invalid indentation."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_06/load_in.nt view
@@ -0,0 +1,4 @@+ingredients:+  > green chilies+    > red chilies+
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_07/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 1,+  "colno": 0,+  "message": "top-level content must start in column 1."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_07/load_in.nt view
@@ -0,0 +1,3 @@+# this is an error because content does not start in column 1+    > green chilies+    > red chilies
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_08/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 0,+  "message": "invalid character in indentation: '\\t'."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_08/load_in.nt view
@@ -0,0 +1,4 @@+# this is an error because the indentation is a tab+ingredients:+	> green chilies+	> red chilies
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_09/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 2,+  "colno": 4,+  "message": "invalid character in indentation: '\\t'."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_09/load_in.nt view
@@ -0,0 +1,4 @@+# this is an error because the indentation contains a tab+ingredients:+    	> green chilies+    	> red chilies
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_10/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 3,+  "colno": 4,+  "message": "invalid character in indentation: '\\xa0' (NO-BREAK SPACE)."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_10/load_in.nt view
@@ -0,0 +1,5 @@+# this is an error because the indentation contains a unicode space+ingredients:+        > green chilies+        > red chilies+#   ↑ this is a non-breaking space
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_11/load_in.nt view
@@ -0,0 +1,73 @@+no newlines:+    > line 1+    > line 2+leading newline:+    >+    > line 1+    > line 2+internal newline:+    > line 1+    >+    > line 2+trailing newline:+    > line 1+    > line 2+    >+leading, internal, and trailing newline:+    >+    > line 1+    >+    > line 2+    >+leading newlines:+    >+    >+    > line 1+    > line 2+internal newlines:+    > line 1+    >+    >+    > line 2+trailing newlines:+    > line 1+    > line 2+    >+    >+leading, internal, and trailing newlines:+    >+    >+    > line 1+    >+    >+    > line 2+    >+    >+leading blank line:++    > line 1+    > line 2+internal blank line:+    > line 1++    > line 2+trailing blank line:+    > line 1+    > line 2++leading comment:+  # ignore me+    > line 1+    > line 2+internal comment:+    > line 1+        # ignore me+    > line 2+trailing comment:+    > line 1+    > line 2+  # ignore me++            # ignore me++                       
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_11/load_out.json view
@@ -0,0 +1,17 @@+{+    "no newlines": "line 1\nline 2",+    "leading newline": "\nline 1\nline 2",+    "internal newline": "line 1\n\nline 2",+    "trailing newline": "line 1\nline 2\n",+    "leading, internal, and trailing newline": "\nline 1\n\nline 2\n",+    "leading newlines": "\n\nline 1\nline 2",+    "internal newlines": "line 1\n\n\nline 2",+    "trailing newlines": "line 1\nline 2\n\n",+    "leading, internal, and trailing newlines": "\n\nline 1\n\n\nline 2\n\n",+    "leading blank line": "line 1\nline 2",+    "internal blank line": "line 1\nline 2",+    "trailing blank line": "line 1\nline 2",+    "leading comment": "line 1\nline 2",+    "internal comment": "line 1\nline 2",+    "trailing comment": "line 1\nline 2"+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_12/dump_in.json view
@@ -0,0 +1,1 @@+"\nthe BS character \\\tBackslash (\\)\nthe SQ character '\tSingle quote (')\nthe DQ character \"\tDouble quote (\")\nthe AB character \u0007\tASCII Bell (BEL)\nthe BS character \b\tASCII Backspace (BS)\nthe FF character \f\tASCII Formfeed (FF)\nthe LF character \n\tASCII Linefeed (LF)\nthe CR character \r\tASCII Carriage Return (CR)\nthe HT character \t\tASCII Horizontal Tab (TAB)\nthe VT character \u000b\tASCII Vertical Tab (VT)\nthe ES character \u001b\tASCII escape character as octal value\nthe ES character \u001b\tASCII escape character as hex value\n"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_12/dump_out.nt view
@@ -0,0 +1,16 @@+>+> the BS character \	Backslash (\)+> the SQ character '	Single quote (')+> the DQ character "	Double quote (")+> the AB character 	ASCII Bell (BEL)+> the BS character 	ASCII Backspace (BS)+> the FF character 	ASCII Formfeed (FF)+> the LF character +> 	ASCII Linefeed (LF)+> the CR character +> 	ASCII Carriage Return (CR)+> the HT character 		ASCII Horizontal Tab (TAB)+> the VT character 	ASCII Vertical Tab (VT)+> the ES character 	ASCII escape character as octal value+> the ES character 	ASCII escape character as hex value+>
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_12/load_in.nt view
@@ -0,0 +1,16 @@+>+> the BS character \	Backslash (\)+> the SQ character '	Single quote (')+> the DQ character "	Double quote (")+> the AB character 	ASCII Bell (BEL)+> the BS character 	ASCII Backspace (BS)+> the FF character 	ASCII Formfeed (FF)+> the LF character +> 	ASCII Linefeed (LF)+> the CR character +> 	ASCII Carriage Return (CR)+> the HT character 		ASCII Horizontal Tab (TAB)+> the VT character 	ASCII Vertical Tab (VT)+> the ES character 	ASCII escape character as octal value+> the ES character 	ASCII escape character as hex value+>
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_12/load_out.json view
@@ -0,0 +1,1 @@+"\nthe BS character \\\tBackslash (\\)\nthe SQ character '\tSingle quote (')\nthe DQ character \"\tDouble quote (\")\nthe AB character \u0007\tASCII Bell (BEL)\nthe BS character \b\tASCII Backspace (BS)\nthe FF character \f\tASCII Formfeed (FF)\nthe LF character \n\tASCII Linefeed (LF)\nthe CR character \n\tASCII Carriage Return (CR)\nthe HT character \t\tASCII Horizontal Tab (TAB)\nthe VT character \u000b\tASCII Vertical Tab (VT)\nthe ES character \u001b\tASCII escape character as octal value\nthe ES character \u001b\tASCII escape character as hex value\n"
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_13/load_err.json view
@@ -0,0 +1,5 @@+{+  "lineno": 3,+  "colno": 0,+  "message": "invalid character in indentation: '\\t'."+}
+ vendor/github.com/KenKundert/nestedtext_tests/test_cases/string_multiline_13/load_in.nt view
@@ -0,0 +1,4 @@+# this is an error because tab is used as indentation character+ingredients:+        > green chilies+	> red chilies