Skip to content

Released version 4.0.0

Latest

Choose a tag to compare

@dg dg released this 26 Oct 00:19
· 2 commits to master since this release

NEON 4 parses a file into a lossless syntax tree in which every comment and every space has its place, so you can edit a configuration and the diff shows only your change. Decoding and encoding stay as they were: Neon::decode() gives the same values as 3.4.

✨ New Features

  • Lossless parsing – Neon::parse($text)->print() === $text holds for any input NEON accepts
  • Format-preserving editing – setValue(), addItem() and removeItem() change only the tokens they edit: 0x0CEA stays hexadecimal, yes becomes no, a new key is indented like its siblings, and a removed item takes its comment along. A refused edit changes nothing at all, so installers, admin panels and AI agents can rewrite config.neon safely
  • A navigable tree – nodes know their parent, their comments and their position (line, column, offset); find(), findAncestor(), siblings, and a public Traverser that can replace and remove nodes on the walk
  • Evaluator – subclass it to turn literals, strings or entities into your own values, such as constants or parameters, the way the Nette DI container reads its configuration
  • Neon::encode() accepts a closure as $blockMode to decide per array whether it is written as a block, e.g. fn($v, $path) => !$path for the first level only, and writes floats in the shortest form that reads back exactly
  • Exception carries the position of the problem as an object and the bare message via getDescription()
  • neon-lint reports one line per finding, --json for tools and --check to verify that a file prints back byte for byte; an AI agent can run it after saving a .neon file
  • Runnable examples with their real output document the whole API
  • The format, the tree and the editing semantics follow a language-neutral specification shared with the JavaScript implementation @nette/neon

💥 Breaking Changes

  • Requires PHP 8.4 or newer and the mbstring extension
  • The tree API is new: Neon::parse() returns a Nodes\DocumentNode, and the classes Decoder, Node\* and the old Traverser are gone. Code that walked the old nodes moves to the new tree, see examples/tree
  • Neon::encode() throws Nette\Neon\Exception for a string that is not valid UTF-8 instead of replacing it with U+FFFD; its errors now name the path to the value
  • Some error messages are more precise; code that matches their text may need an update
  • neon-lint has a new command-line contract: --debug is gone, and a failure of the tool itself exits with 2
  • Neon::BLOCK and Neon::CHAIN are deprecated, use blockMode: true and Neon::Chain