pick

package
v0.1.6 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package pick evaluates `pick=` expressions: how a single value or a single contiguous range is taken out of a bound block (docs/SPEC.md §10).

The rule that keeps this from becoming a scripting language: a pick returns exactly one line (a Value) or one contiguous range (a Range). No transforms, no arithmetic, no joins. Display formatting belongs to the cite side.

Tiers implemented here, all stdlib: the text vocabulary (`line`, `regex`, `url`, `after`, `between`), the document vocabulary over markdown (`heading`, `section`, `paragraph`, `link`), the structured vocabulary for formats that need no dependency (`json`, `env`, `ini`, `csv`, and line-mode `yaml` and `toml` for the common flat and nested-map cases), and `file`. `symbol:` needs a grammar, so this package answers it with ErrUnsupported: on a remote def the scanner hands it to the host's resolver (scan.Options.Symbol), which asks the target file's own tier, as `ds def file#Name` does. A picker plugin (Picker interface in the root package) may add schemes.

Index

Constants

View Source
const (
	SchemeLine      = "line"
	SchemeRegex     = "regex"
	SchemeURL       = "url"
	SchemeAfter     = "after"
	SchemeBetween   = "between"
	SchemeHeading   = "heading"
	SchemeSection   = "section"
	SchemeParagraph = "paragraph"
	SchemeLink      = "link"
	SchemeJSON      = "json"
	SchemeEnv       = "env"
	SchemeINI       = "ini"
	SchemeCSV       = "csv"
	SchemeYAML      = "yaml"
	SchemeTOML      = "toml"
	SchemeFile      = "file"
	SchemeSymbol    = "symbol"
)

Scheme names. Kept as constants so the dispatcher, the docs, and the conformance fixtures agree on spelling.

Variables

View Source
var (
	// ErrBadExpr is a malformed expression: unknown scheme, missing argument,
	// bad number, invalid regex.
	ErrBadExpr = errors.New("pick: bad expression")
	// ErrNotFound means the expression is valid but nothing in the content
	// matched. `check` reports this as `pick failed`.
	ErrNotFound = errors.New("pick: nothing matched")
	// ErrMultiLine means a value-producing pick (line, regex, a scalar key)
	// yielded more than one line, which the one-line rule forbids. The way out
	// is a pick that names a block -- a key or table holding the lines, a
	// section, a symbol -- cited with ds:block. The message used to say only
	// "use ds:block", which read as a fault in the citation even when the
	// citation already was ds:block (bug 134).
	ErrMultiLine = errors.New("pick: the picked value spans more than one line; pick the key, table, section or symbol that holds those lines to bind them as a block")
	// ErrUnsupported means the scheme needs an extractor this package does not
	// have (a grammar). Plugins answer it; the root reports it honestly.
	ErrUnsupported = errors.New("pick: scheme not supported without a plugin")
)

Sentinel errors.

Schemes is the canonical list, in the order the spec table presents them.

Functions

func KeyValue

func KeyValue(line string) (string, bool)

KeyValue returns the value part of a `key: value` or `key = value` line with any inline comment and one layer of quotes removed. It is the default pick for config hosts (§10): the visible value, not the key line, is what a fact means. ok is false when the line has no separator.

func SplitScheme

func SplitScheme(expr string) (scheme, arg string)

SplitScheme separates `scheme:arg`; a bare word is a scheme with no arg.

Types

type Expr

type Expr struct {
	Scheme string
	Arg    string
}

Expr is a parsed expression: scheme plus its raw argument, quotes removed.

func Parse

func Parse(expr string) (Expr, error)

Parse splits `scheme:arg` and strips optional single or double quotes from the argument. `heading`, `url`, and `file` take no argument.

func (Expr) Apply

func (e Expr) Apply(content string) (Result, error)

Apply evaluates a parsed expression.

CRLF is read as LF. The scanner hands over a file's raw bytes, and a Windows checkout with core.autocrlf has \r on every line: `line:2` then failed as spanning two lines and a `$`-anchored regex matched nothing, so one repository resolved differently depending on who checked it out.

type Kind

type Kind string

Kind says whether a Result is a one-line value or a line range.

const (
	// KindValue is a single line, what `ds:cfg` inlines.
	KindValue Kind = "value"
	// KindRange is one or more contiguous lines, what `ds:block` renders.
	KindRange Kind = "range"
)

type Picker

type Picker func(arg, content string) (Result, error)

Picker is a plugin scheme (§37.3): given the argument after the colon and the block content, it returns a value or a range.

type Result

type Result struct {
	Kind  Kind
	Value string
	Text  string
	Start int
	End   int
}

Result is what a pick produced. For KindValue, Value is set and Start==End. For KindRange, Text is the joined lines. Start and End are 1-based line numbers within the content handed to Pick, inclusive, so a caller that knows where the content began in its file can add the offset.

func Pick

func Pick(expr, content string) (Result, error)

Pick evaluates expr against content and applies the one-line rule for value schemes. Line numbers in the Result are relative to content.

func PickWith

func PickWith(pickers map[string]Picker, expr, content string) (Result, error)

PickWith applies a registered Picker when the scheme names one, otherwise the built-in schemes. Plugins never shadow built-ins: a registered scheme with a built-in name is ignored, so `json:` always means the same thing.

Jump to

Keyboard shortcuts

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