indents

package module
v0.0.0-...-c9923b4 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2021 License: MIT Imports: 3 Imported by: 0

README

indents

Package indents provides functions for parsing text with indentation.

Documentation

Overview

Package indents provides functions for parsing text with indentation.

Index

Examples

Constants

View Source
const (
	Space = ' '
	Tab   = '\t'
)

Variables

This section is empty.

Functions

This section is empty.

Types

type ExtraIndentationError

type ExtraIndentationError struct {
	Line int // Line number where the error is found.
}

func (*ExtraIndentationError) Error

func (e *ExtraIndentationError) Error() string

type IndentScanner

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

Provides a bufio.Scanner-like interface for reading indented-text. Successive calls to the Scan method will step through the lines of a file. Call the Line method to get the current *Line struct, with the indentation level calculated and set.

The IndentScanner is indentation-"dumb", it merely detects the indentation size of each line and sets it on the *Line struct. It's up to the caller to assert any indentation-aware logic.

See the ParseNodeTree function, where Lines produced by this scanner are parsed in an indentation-aware manner and converted into a tree structure.

Example
text := "line one\n"
text += "  line 2\n"
text += "    line\n"
text += "four"

reader := strings.NewReader(text)
scanner := NewIndentScanner(reader, nil)

for scanner.Scan() {
	line := scanner.Line()
	fmt.Printf(
		"Line %d, level %d: '%s'\n",
		line.Number,
		line.Level,
		line.Text,
	)
}
Output:

Line 1, level 0: 'line one'
Line 2, level 1: 'line 2'
Line 3, level 2: 'line'
Line 4, level 0: 'four'

func NewIndentScanner

func NewIndentScanner(r io.Reader, style *Style) *IndentScanner

Creates a new IndentScanner that reads data from Reader r. The style argument sets the assumed indentation style of the data. If it's nil, the scanner will try to auto-detect the style using the AutoDetect function.

func (*IndentScanner) Err

func (s *IndentScanner) Err() error

Returns the first non-EOF error that was encountered by the Scanner.

func (*IndentScanner) Line

func (s *IndentScanner) Line() *Line

Returns the most recent line generated by a call to Scan as a newly allocated Line struct.

func (*IndentScanner) Lines

func (s *IndentScanner) Lines() int

Returns the number of lines read. Will return 0 if the Scan method was never called before.

func (*IndentScanner) Scan

func (s *IndentScanner) Scan() bool

Advance the scanner to the next line, which will then be available through the Line method. It returns false when the scan stops, either by reaching the end of the input or an error. After Scan returns false, the Err method will return any error that occurred during scanning, except that if it was io.EOF, Err will return nil.

func (*IndentScanner) Style

func (s *IndentScanner) Style() *Style

Returns the autodetected indent style. Will return nil if no indetation detected, or the Line method was never called before.

type Line

type Line struct {
	Text   string // The line text without indentation.
	Number int    // The line number.
	Level  int    // The indentation level.
}

Encapsulates an indented line.

type Node

type Node struct {
	Line     *Line   // The corresponding Line
	Parent   *Node   // This node's parent node
	Children []*Node // This node's child nodes
}

Encapsulates a node in a tree.

func ParseNodeTree

func ParseNodeTree(
	scanner *IndentScanner,
	root *Node,
	options *ParseNodeTreeOptions,
) (*Node, error)

Read lines from an IndentScanner and produce a node tree sructure.

Behaviour of the parser can be customized with the options argument. See ParseNodeTreeOptions.

func (*Node) IsAboveLevel

func (n *Node) IsAboveLevel(o *Node) bool

Tests if this node's indentation level is above o's.

func (*Node) IsBelowLevel

func (n *Node) IsBelowLevel(o *Node) bool

Tests if this node's indentation level is below o's.

func (*Node) IsSameLevel

func (n *Node) IsSameLevel(o *Node) bool

Tests if this node's indentation level is the same as o's.

func (*Node) Level

func (n *Node) Level() int

Gets the indentation level of this node, -1 if this is the root node.

func (*Node) Number

func (n *Node) Number() int

Gets the line number of this node, -1 if this is the root node.

func (*Node) Text

func (n *Node) Text() string

Gets the text of this node.

type NodeProcessor

type NodeProcessor func(node *Node, options *ParseNodeTreeOptions) error

Function to process nodes generated from ParseNodeTree

type ParseNodeTreeOptions

type ParseNodeTreeOptions struct {
	// If true, extra indentations will be ignored.
	IgnoreExtraIndentation bool

	// If set, this function will be called on each Node generated.
	Processor NodeProcessor
}

Options to pass to ParseNodeTree function to customize its behaviour.

type Style

type Style struct {
	Char rune // The indent character.
	Size int  // Number of subsequent Char's considered as 1 indent.
}

Encapsulates an indentation style.

func AutoDetect

func AutoDetect(line string) *Style

Create a new Style by auto-detecting indentation of given line. It is assumed that the given line has (potentially) a first-level indentation. If there are no indentation in the line, this function will return nil.

Example
style := AutoDetect("  two spaces")

fmt.Printf("Style.Char: [%c]\n", style.Char)
fmt.Printf("Style.Size:  %d\n", style.Size)
Output:

Style.Char: [ ]
Style.Size:  2

func Spaces

func Spaces(size int) *Style

Shortcut. Spaces(2) -> &Style{Space, 2}

func Tabs

func Tabs(size int) *Style

Shortcut. Tabs(1) -> &Style{Tab, 1}

func (*Style) Level

func (s *Style) Level(line string) int

Calculate the given line's indentation level based on this indent style.

Example
// Even numbered indents:
style := &Style{Char: '.', Size: 2}
fmt.Println(style.Level("..two spaces in")) // Level=1
fmt.Println(style.Level("....four spaces")) // Levels=2
fmt.Println(style.Level(".....five space")) // Levels=2 (rounds to Size)

// Odd numbered indents are also ok:
oddStyle := &Style{Char: '-', Size: 3}
fmt.Println(oddStyle.Level("---three spaces")) // Level=1
fmt.Println(oddStyle.Level("------six space")) // Levels=2
fmt.Println(oddStyle.Level("-------seven sp")) // Levels=2
Output:

1
2
2
1
2
2

Jump to

Keyboard shortcuts

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