-
Notifications
You must be signed in to change notification settings - Fork 39
/
line.go
114 lines (89 loc) · 2.12 KB
/
line.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package gcss
import (
"fmt"
"strings"
)
const unicodeSpace = 32
const indentTop = 0
// line represents a line of codes.
type line struct {
no int
s string
indent int
}
// isEmpty returns true if the line's s is zero value.
func (ln *line) isEmpty() bool {
return strings.TrimSpace(ln.s) == ""
}
// isTopIndent returns true if the line's indent is the top level.
func (ln *line) isTopIndent() bool {
return ln.indent == indentTop
}
// childOf returns true if the line is a child of the parent.
func (ln *line) childOf(parent element) (bool, error) {
var ok bool
var err error
switch pIndent := parent.Base().ln.indent; {
case ln.indent == pIndent+1:
ok = true
case ln.indent > pIndent+1:
err = fmt.Errorf("indent is invalid [line: %d]", ln.no)
}
return ok, err
}
// isDeclaration returns true if the line is a declaration.
func (ln *line) isDeclaration() bool {
_, _, err := declarationPV(ln)
return err == nil
}
// isAtRule returns true if the line is an at-rule.
func (ln *line) isAtRule() bool {
return strings.HasPrefix(strings.TrimSpace(ln.s), atMark)
}
// isVariable returns true if the line is a variable.
func (ln *line) isVariable() bool {
if !ln.isTopIndent() {
return false
}
_, _, err := variableNV(ln)
return err == nil
}
// isMixinDeclaration returns true if the line is a mixin declaration.
func (ln *line) isMixinDeclaration() bool {
if !ln.isTopIndent() {
return false
}
_, _, err := mixinNP(ln, true)
return err == nil
}
// isMixinInvocation returns true if the line is a mixin invocation.
func (ln *line) isMixinInvocation() bool {
if ln.isTopIndent() {
return false
}
_, _, err := mixinNP(ln, false)
return err == nil
}
// isComment returns true if the line is a comment.
func (ln *line) isComment() bool {
return strings.HasPrefix(strings.TrimSpace(ln.s), doubleSlash)
}
// newLine creates and returns a line.
func newLine(no int, s string) *line {
return &line{
no: no,
s: s,
indent: indent(s),
}
}
// indent returns the string's indent.
func indent(s string) int {
var i int
for _, b := range s {
if b != unicodeSpace {
break
}
i++
}
return i / 2
}