tomledit

package module
v0.0.26 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 17, 2024 License: MIT Imports: 5 Imported by: 14

README

tomledit

GoDoc

This repository defines a Go library to parse and manipulate the syntactic structure of TOML documents. Unlike other TOML libraries, this one does not convert values into Go data structures (for that I recommend github.com/BurntSushi/toml). However, it does preserve the complete structure of its input, including declaration order and comments, allowing a TOML document to be read, manipulated, and written back out without loss.

This library is intended to implement the TOML v1.0.0 specification.

Handle with care: This code is a work-in-progress and should not be considered ready for production use. The package API may still change, and more test coverage is needed.

Documentation

Overview

Package tomledit allows structural edits of a TOML document.

Parsing

To parse a TOML text into a Document, call Parse:

f, err := os.Open("config.toml")
...
defer f.Close()
doc, err := tomledit.Parse(f)
if err != nil {
   log.Fatalf("Parse: %v", err)
}

Once parsed, the structure of the Document is mutable, and changes to the document will be reflected when it is written back out.

Note that the parser does not validate the semantics of the resulting document. Issues such as duplicate keys, incorrect table order, redefinitions, and so forth are not reported by the parser.

Formatting

To write a Document back into TOML format, use a Formatter:

var cfg tomledit.Formatter
if err := cfg.Format(os.Stdout, doc); err != nil {
   log.Fatalf("Format: %v", err)
}

Structure

A Document consists of one or more sections: A "global" section at the beginning of the input, with top-level key-value mappings that are not captured in a named table; followed by zero or more sections denoting named tables.

All sections except the global section have a Heading, which gives the name of the section along with any documentation comments attached to it. The contents of the section are represented as a slice of items, each of which is a block of comments (concrete type parser.Comments) or a key-value mapping (concrete type *parser.KeyValue). Modifying either of these fields updates the structure of the section.

Comments

Each heading or key-value may have a block comment comment attached to it. Block comments are attached to an item if they occur immediately before it (with no intervening blanks); otherwise block comments stand alone as their own items.

Headings and values may also have trailing line comments attached, if they occur on the same line as the value. For example:

# unattached comment
# this block stands alone

# another unattached comment
# this block is separate from the one above

# attached comment, belongs to the following table
[tablename]

foo = 'bar'  # attached comment, belongs to the preceding mapping

The comments attached to an item move with that item, and retain their attachments when the document is formatted. To remove an attached comment, set the corresponding field to a zero value.

Keys and Values

Keys are denoted as slices of strings (parser.Key), representing the dot-separated components of a TOML name (e.g., left.center.right). Use the Equal and IsPrefixOf methods of a key to compare it to another key. It is safe to construct key slices programmatically, or use parser.ParseKey.

Values are denoted as parser.Datum implementations. Primitive values (parser.Token) are stored as uninterpreted text; this package does not convert them into Go values (although you are free to do so). Otherwise, a value is either an array (parser.Array) or an inline table (parser.Inline). Values in key-value mappings are bound with an optional trailing line comment, if one occurs on the same line as the value.

To construct values programmatically, use parser.ParseValue.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Format added in v0.0.2

func Format(w io.Writer, doc *Document) error

Format formats the specified document with default options.

Types

type Document

type Document struct {
	// The global section, containing all keys not in a named table.
	// Setting this field to nil removes the global section.
	Global *Section

	// This slice contains one entry for each named table section.  Modifying
	// the order and content of this slice affects the formatted output.
	Sections []*Section
}

A Document represents the contents of a TOML document. Edits applied to the fields of a document are preserved when the document is written using a Formatter.

func Parse

func Parse(r io.Reader) (*Document, error)

Parse parses a TOML document from r.

Example
package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/creachadair/tomledit"
	"github.com/creachadair/tomledit/parser"
)

func main() {
	doc, err := tomledit.Parse(strings.NewReader(`# Example config

verbose=true

# A commented section
[commented]
  x = 3    # line comment

  # a commented mapping
  y = true
`))
	if err != nil {
		log.Fatalf("Parse: %v", err)
	}

	// Scan through the parsed document printing out all the keys defined in it,
	// in their order of occurrence.
	doc.Scan(func(key parser.Key, _ *tomledit.Entry) bool {
		fmt.Println(key)
		return true
	})
}
Output:


verbose
commented
commented.x
commented.y

func (*Document) Find

func (d *Document) Find(key ...string) []*Entry

Find returns a slice of all entries in d with the given key, or nil.

func (*Document) First

func (d *Document) First(key ...string) *Entry

First returns the first entry in d with the given key, or nil.

Example
package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/creachadair/tomledit"
)

func main() {
	doc, err := tomledit.Parse(strings.NewReader(`[foo]
bar . baz = "frob"
# end
`))
	if err != nil {
		log.Fatalf("Parse: %v", err)
	}

	// Print the first item with the given key. The default string output for an
	// item is for human consumption and is not valid TOML.
	fmt.Println(doc.First("foo", "bar", "baz"))
}
Output:

[foo] :: bar.baz = "frob"

func (*Document) Scan

func (d *Document) Scan(f func(parser.Key, *Entry) bool) bool

Scan calls f for every key-value pair defined in d, in lexical order. The arguments to f are the complete key of the item and the entry. Traversal continues until all items have been visited or f returns false. Scan reports whether the traversal was stopped early.

Editing the contents of existing sections and mappings is safe. It is not safe to remove or reorder sections or mappings during a scan.

type Entry

type Entry struct {
	// The section of the document containing this entry.  For entries matching
	// tables, this is the complete result. Modifying the contents of this field
	// edits the document.
	*Section

	// For an entry representing a key-value mapping, this is its definition.
	// This field is nil for entries matching section headers.  Modifying the
	// contents of this field edits the document.
	*parser.KeyValue
	// contains filtered or unexported fields
}

An Entry represents the result of looking up a key in a document.

func (Entry) IsInline

func (e Entry) IsInline() bool

IsInline reports whether e is inside an inline table.

func (Entry) IsMapping

func (e Entry) IsMapping() bool

IsMapping reports whether e represents a key-value mapping.

func (Entry) IsSection

func (e Entry) IsSection() bool

IsSection reports whether e represents a section head.

func (*Entry) Remove

func (e *Entry) Remove() bool

Remove removes the entry from its location in the document, and reports whether any change was made in doing so.

func (Entry) String

func (e Entry) String() string

type Formatter

type Formatter struct{}

Formatter defines options for formatting a TOML document. The zero value is ready for use with default options (of which there are presently none).

Example
package main

import (
	"log"
	"os"
	"strings"

	"github.com/creachadair/tomledit"
)

func main() {
	doc, err := tomledit.Parse(strings.NewReader(`# A
b='c'
[q."r"]
# D
e.f=true
 g=false
# h
i={j=1,k=2} # L
`))
	if err != nil {
		log.Fatalf("Parse: %v", err)
	}

	if err := tomledit.Format(os.Stdout, doc); err != nil {
		log.Fatalf("Format: %v", err)
	}
}
Output:


# A
b = 'c'

[q.r]

# D
e.f = true
g = false

# h
i = {j = 1, k = 2}  # L

func (Formatter) Format

func (f Formatter) Format(w io.Writer, doc *Document) error

type Section

type Section struct {
	// The heading of the section. For the global section it is nil; otherwise
	// it contains the name of a table. Modifying the contents of this field
	// edits the section within the document.
	*parser.Heading

	// The items comprising the section. Modifying the contents of this slice
	// edits section within its enclosing document.
	Items []parser.Item
}

A Section represents a section of a TOML document. A section represents a table and all the block comments and key-value pairs it contains.

func (*Section) IsGlobal added in v0.0.10

func (s *Section) IsGlobal() bool

IsGlobal reports whether s is a global (top-level) table.

func (*Section) Scan added in v0.0.9

func (s *Section) Scan(f func(parser.Key, *Entry) bool) bool

Scan calls f for every key-value pair defined inside s, not including s itself, in lexical order. The arguments to f are the complete key of the item and the entry. Traversal continues until all items have been visited or f returns false. Scan reports whether the traversal was stopped early.

Editing the contents of existing mappings is safe. It is not safe to remove or reorder items during a scan.

func (*Section) TableName added in v0.0.10

func (s *Section) TableName() parser.Key

TableName returns the name of the table defined by s, which is nil for a global (top-level) table.

Directories

Path Synopsis
cmd
tomldiff
Program tomldiff performs a keyspace diff on two TOML documents.
Program tomldiff performs a keyspace diff on two TOML documents.
tomledit
Program tomledit provides basic command-line support for reading and modifying TOML files.
Program tomledit provides basic command-line support for reading and modifying TOML files.
Package parser implements a parser for TOML, as defined by the TOML v1 specification https://toml.io/en/v1.0.0.
Package parser implements a parser for TOML, as defined by the TOML v1 specification https://toml.io/en/v1.0.0.
Package scanner implements a lexical scanner for TOML, as defined by the TOML v1 specification https://toml.io/en/v1.0.0.
Package scanner implements a lexical scanner for TOML, as defined by the TOML v1 specification https://toml.io/en/v1.0.0.
Package transform defines some useful transformations on TOML documents.
Package transform defines some useful transformations on TOML documents.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL