NestedText — A Human Friendly Data Format

downloadsbuild statuscoveragertd statuspypi versionanaconda versionpython version

Authors: Ken & Kale Kundert
Version: 3.7
Released: 2024-04-27
Documentation:nestedtext.org
Please post all questions, suggestions, and bug reports toGitHub.

NestedText is a file format for holding structured data. It is similar inconcept toJSON, except thatNestedText is designed to make it easy forpeople to enter, edit, or view the data directly. It organizes the data intoa nested collection of name-value pairs, lists, and strings. The syntax isintended to be very simple and intuitive for most people.

A unique feature of this file format is that it only supports one scalar type:strings.  As such, quoting strings is unnecessary, and without quoting there isno need for escaping. While the decision to forego other types (integers,reals, Booleans, etc.) may seem counter productive, it leads to simpler datafiles and applications that are more robust.

NestedText is convenient for configuration files, data journals, addressbooks, account information, and the like. Here is an example of a file thatcontains a few addresses:

# Contact information for our officersKatheryn McDaniel:position:presidentaddress:>138 Almond Street>Topeka, Kansas 20697phone:cell:1-210-555-5297home:1-210-555-8470# Katheryn prefers that we always call her on her cell phone.email:KateMcD@aol.comadditional roles:-board memberMargaret Hodge:position:vice presidentaddress:>2586 Marigold Lane>Topeka, Kansas 20682phone:1-470-555-0398email:margaret.hodge@ku.eduadditional roles:-new membership task force-accounting task force

Typical Applications

Configuration

Configuration files are an attractive application forNestedText.NestedText configuration files tend to be simple, clean and unambiguous.Plus, they handle hierarchy much better than alternatives such asIni andTOML.

Structured Code

One way to build tools to tackle difficult and complex tasks is to provide anapplication specific language. That can be a daunting challenge. However, incertain cases, such as specifying complex configurations,NestedText can helpmake the task much easier.NestedText conveys the structure of data leavingthe end application to interpret the data itself. It can do so witha collection of small parsers that are tailored to the specific piece of data towhich they are applied. This generally results in a simpler specification sinceeach piece of data can be given in its natural format, which might otherwiseconfuse a shared parser. In this way, rather than building one large verygeneral language and parser, a series of much smaller and simpler parsers areneeded. These smaller parsers can be as simple as splitters or partitioners,value checkers, or converters for numbers in special forms (numbers with units,times or dates, GPS coordinates, etc.). Or they could be full-blown expressionevaluators or mini-languages. Structured code provides a nice middle groundbetween data and code and its use is growing in popularity.

An example of structured code is provided by GitHub with its workflowspecification files. They useYAML. Unfortunately, the syntax of the codesnippets held in the various fields can be confused withYAML syntax, whichleads to unnecessary errors, confusion, and complexity (seeYAML issues).JSON suffers from similar problems.NestedText excels for these applicationsas it holds code snippets without any need for quoting or escaping.NestedText provides simple unambiguous rules for defining the structure ofyour data and when these rules are followed there is no way for any syntax orspecial characters in the values of your data to be confused withNestedTextsyntax. In fact, it is possible forNestedText to holdNestedText snippetswithout conflict.

Another example of structured code is provided by the files that contain thetest cases used byParametrize From File, aPyTest plugin.Parametrize From File simplifies the task of specifying test cases forPyTest by separating the test cases from the test code. Here it is beingapplied to test a command line program. Its response is checked using regularexpressions. Each entry includes a shell command to run the program anda regular expression that must match the output for the test to pass:

-    cmd: emborg version    expected: emborg version: \d+\.\d+(\.\d+(\.?\w+\d+)?)?  \(\d\d\d\d-\d\d-\d\d\)    expected type: regex-    cmd: emborg --quiet files -D    expected:        > Archive: home-\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d        > \d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\d\d\d\d configs/subdir/(file|)        > \d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\d\d\d\d configs/subdir/(file|)            # Unfortunately, we cannot check the order as they were both            # created at the same time.    expected type: regex-    cmd: emborg due --backup-days 1 --message "{elapsed} since last {action}"    expected: home: (\d+(\.\d)? (seconds|minutes)) since last backup\.    expected type: regex

Notice that the regular expressions are given clean, without any quoting orescaping.

Composable Utilities

Another attractive use-case forNestedText is command line programs whoseoutput is meant to be consumed by either people or other programs. This isanother growing trend. Many programs do this by supporting a--jsoncommand-line flag that indicates the output should be computer readable ratherthan human readable. But, withNestedText it is not necessary to make peoplechoose. Just output the result inNestedText and it can be read by people orcomputers. For example, consider a program that reads your address list andoutput particular fields on demand:

>address--emailKatherynMcDaniel:KateMcD@aol.comMargaretHodge:margaret.hodge@ku.edu

This output could be fed directly into another program that acceptsNestedTextas input:

>address--email|mail-to-list

Contributing

This package contains a Python reference implementation ofNestedText anda test suite. Implementation in many languages is required forNestedText tocatch on widely. If you like the format, please consider contributingadditional implementations.

Also, please consider usingNestedText for any applications you create.