splice

package
v0.0.0-...-85302ad Latest Latest
Warning

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

Go to latest
Published: Nov 15, 2023 License: BSD-2-Clause Imports: 6 Imported by: 1

Documentation

Overview

Package splice allows to perform simple edits on a string, byte buffer or a file.

It allows to delete, insert or replace strings in a text buffer.

The core operation is: replace the current content of a given selection with a new string. Deletion is just replacement with an empty string. Insertion is just replacement at a zero length selection.

Selections are addressed by unicode character offsets, not byte offsets!.

The edit operation involves one single pass through the input.

Example

In order to splice a string you must provide one or more spans (character ranges) and the replacement string for each span. The resulting Transformer instance can then be passed to a collection of functions that can apply transformers to their inputs. See the documentation for the golang.org/x/text/transform for a full list.

This example shows the simplest case where the input and output are plain Go strings.

package main

import (
	"fmt"
	"log"

	"github.com/lonegunmanb/go-yaml-edit/splice"
	"golang.org/x/text/transform"
)

func main() {
	src := "abcd"

	res, _, err := transform.String(splice.T(splice.Span(1, 2).With("XYZ")), src)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res)

}
Output:

aXYZcd
Example (Delete)

Deletion is modeled by using an empty replacement string.

package main

import (
	"fmt"
	"log"

	"github.com/lonegunmanb/go-yaml-edit/splice"
	"golang.org/x/text/transform"
)

func main() {
	src := "abcd"

	t := splice.T(splice.Span(2, 3).With(""))
	res, _, err := transform.String(t, src)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res)

}
Output:

abd
Example (File)

If you want to edit a file in-place, just use any library that can apply a Transformer to a file, like for example the github.com/mkmik/filetransformer package.

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"github.com/lonegunmanb/go-yaml-edit/splice"
	"github.com/mkmik/filetransformer"
)

func main() {
	tmp, err := ioutil.TempFile("", "")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(tmp.Name())

	fmt.Fprintf(tmp, "abcd")
	tmp.Close()

	t := splice.T(splice.Span(1, 3).With("X"))
	if err := filetransformer.Transform(t, tmp.Name()); err != nil {
		log.Fatal(err)
	}

	b, err := ioutil.ReadFile(tmp.Name())
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(b))

}
Output:

aXd
Example (Insert)

Inserting text is achieved by selecting a zero-width span, effectively acting as a cursor inside the input stream.

package main

import (
	"fmt"
	"log"

	"github.com/lonegunmanb/go-yaml-edit/splice"
	"golang.org/x/text/transform"
)

func main() {
	src := "abcd"

	t := splice.T(splice.Span(2, 2).With("X"))
	res, _, err := transform.String(t, src)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res)

}
Output:

abXcd
Example (Multiple)

Multiple substitutions are possible. All positions are interpreted as positions in the source stream. The library deals with the fact that replacement strings can have different lengths than the strings they replace and will behave accordingly.

package main

import (
	"fmt"
	"log"

	"github.com/lonegunmanb/go-yaml-edit/splice"
	"golang.org/x/text/transform"
)

func main() {
	src := "abcd"

	t := splice.T(
		splice.Span(1, 2).With("B"),
		splice.Span(3, 4).With("D"),
	)
	aBcD, _, err := transform.String(t, src)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(aBcD)

	t = splice.T(
		splice.Span(1, 2).With("Ba"),
		splice.Span(2, 3).With(""),
		splice.Span(3, 4).With("Da"),
	)
	aBaDa, _, err := transform.String(t, src)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(aBaDa)

}
Output:

aBcD
aBaDa
Example (Unicode)

All positions are character (rune) position, not bytes. This is an important distinction when the input contains non-ASCII characters.

package main

import (
	"fmt"
	"log"

	"github.com/lonegunmanb/go-yaml-edit/splice"
	"golang.org/x/text/transform"
)

func main() {
	src := "ábcd"

	res, _, err := transform.String(splice.T(splice.Span(1, 2).With("B")), src)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(res)

}
Output:

áBcd

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Peek

func Peek(r io.Reader, sels ...Selection) ([]string, error)

Peek returns a slice of strings for each extent of the input reader. The order of the resulting slice matches the order of the provided selection slice (which can be in any order; slice provides the necessary sorting to guarantee a single scan pass on the reader).

Types

type Op

type Op struct {
	Selection
	Replace func(prev string) (string, error)
}

A Op captures a request to replace a selection with a replacement string. An idiomatic way to construct an Op instance is to call With or WithFunc on a Selection.

Example
package main

import (
	"fmt"

	"github.com/lonegunmanb/go-yaml-edit/splice"
)

func main() {
	fmt.Printf("%T", splice.Span(3, 4).With("foo"))
}
Output:

splice.Op

type Selection

type Selection struct {
	Start int
	End   int
}

A Selection selects a range of characters in the input string buffer. It's defined to be the range that starts at Start end ends before the End position. Positions are unicode codepoint offsets, not byte offsets.

func Span

func Span(start, end int) Selection

Span constructs a Selection.

func (Selection) With

func (s Selection) With(r string) Op

With returns an operation that captures a replacement of the current selection with a desired replacement string.

func (Selection) WithFunc

func (s Selection) WithFunc(f func(prev string) (string, error)) Op

WithFunc returns an operation that will call the f callback on the previous value of the selection and replace the selection with the return value of the callback.

type Transformer

type Transformer struct {
	// contains filtered or unexported fields
}

A Transformer transforms some text applying Ops (Replacements on Selections).

func T

func T(ops ...Op) *Transformer

T constructs a splice transformer given one or more operations. A splice transformer implements golang.org/x/text/transform.Transformer; that package contains many useful functions to apply the transformation.

func (*Transformer) Reset

func (t *Transformer) Reset()

Reset implements the golang.org/x/text/transform.Transformer interface.

func (*Transformer) Transform

func (t *Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error)

Transform implements the golang.org/x/text/transform.Transformer interface.

Jump to

Keyboard shortcuts

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