61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package terrace
|
|
|
|
import (
|
|
"errors"
|
|
)
|
|
|
|
// LineData holds the parsed information from each line.
|
|
type LineData struct {
|
|
// Which character is being used for indentation.
|
|
Indent rune
|
|
// How many indent characters are present in the current line.
|
|
Level int
|
|
// The number of characters before the start of the line's "head" section.
|
|
OffsetHead int
|
|
// The number of characters before the start of the line's "tail" section.
|
|
OffsetTail int
|
|
}
|
|
|
|
// NewLineData initializes a LineData instance with default values.
|
|
func NewLineData(indent rune) *LineData {
|
|
return &LineData{
|
|
Indent: indent,
|
|
Level: 0,
|
|
OffsetHead: 0,
|
|
OffsetTail: 0,
|
|
}
|
|
}
|
|
|
|
// ParseLine is the core Terrace parser function, sets level, offsetHead, and offsetTail in a LineData object based on the passed line.
|
|
func ParseLine(line string, lineData *LineData) error {
|
|
if lineData == nil {
|
|
return errors.New("'lineData' must be a non-nil pointer to a LineData struct")
|
|
}
|
|
if lineData.Indent == 0 {
|
|
return errors.New("'lineData.Indent' must be a single character")
|
|
}
|
|
|
|
if len(line) == 0 {
|
|
lineData.OffsetHead = 0
|
|
lineData.OffsetTail = 0
|
|
} else {
|
|
level := 0
|
|
for _, char := range line {
|
|
if char == lineData.Indent {
|
|
level++
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
lineData.Level = level
|
|
lineData.OffsetHead = level
|
|
lineData.OffsetTail = level
|
|
|
|
for lineData.OffsetTail < len(line) && line[lineData.OffsetTail] != ' ' {
|
|
lineData.OffsetTail++
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|