Skip to content

Commit 4e08eca

Browse files
committed
Wrote the buggy CSS parser
1 parent 21da5a1 commit 4e08eca

File tree

2 files changed

+137
-13
lines changed

2 files changed

+137
-13
lines changed

Block.go

Lines changed: 135 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,157 @@
11
package cssminify
22

33
import (
4+
"bytes"
5+
"fmt"
46
"io/ioutil"
7+
"strings"
58
)
69

710
type Block struct {
8-
selector string
9-
pair Pair
11+
selector []byte
12+
pairs []Pair
1013
}
1114

15+
// Error constants
16+
const (
17+
NOT_IN_SELECTOR = "Met { while not being in selector"
18+
NOT_AFTER_VALUE = "Met } after a non-value"
19+
NOT_IN_PROPERTY = "Met : after a non-property"
20+
NOT_IN_VALUE = "Met ; after a non-value"
21+
)
22+
23+
// Parser constants
24+
const (
25+
STARTING_COMMENT = 0
26+
IN_COMMENT = 1
27+
CLOSING_COMMENT = 2
28+
IN_SELECTOR = 3
29+
IN_PROPERTY = 4
30+
IN_VALUE = 5
31+
)
32+
1233
func Blocks(file string) []Block {
1334
var (
14-
block Block
15-
blocks = make([]Block, 0)
35+
blocks []Block
36+
letter byte
37+
current []byte
38+
beforeState byte
39+
state byte
40+
currentBlock Block
41+
currentPair Pair
1642
)
1743

18-
content := readFile(file)
44+
content := []byte(readFile(file))
45+
46+
for letter, content = stripLetter(content); letter != 0; letter, content = stripLetter(content) {
47+
if state == STARTING_COMMENT && letter != '*' {
48+
state = beforeState
49+
}
50+
if state == CLOSING_COMMENT && letter != '/' {
51+
state = beforeState
52+
}
53+
switch letter {
54+
case '/':
55+
switch state {
56+
case CLOSING_COMMENT:
57+
state = beforeState
58+
59+
// Since we don't keep comments
60+
current = []byte{}
61+
default:
62+
if state != IN_COMMENT {
63+
beforeState = state
64+
state = STARTING_COMMENT
65+
current = append(current, letter)
66+
}
67+
}
68+
case '*':
69+
switch state {
70+
case STARTING_COMMENT:
71+
beforeState = state
72+
state = IN_COMMENT
73+
current = append(current, letter)
74+
case IN_COMMENT:
75+
state = CLOSING_COMMENT
76+
current = append(current, letter)
77+
}
78+
case '{':
79+
if state != IN_COMMENT {
80+
if state == IN_SELECTOR {
81+
state = IN_PROPERTY
82+
currentBlock.selector = current
83+
current = []byte{}
84+
} else {
85+
panic(NOT_IN_SELECTOR)
86+
}
87+
}
88+
case '}':
89+
if state != IN_COMMENT {
90+
if state == IN_VALUE && !bytes.Equal(nil, current) {
91+
state = IN_PROPERTY
92+
currentPair.value = current
93+
currentBlock.pairs = append(currentBlock.pairs, currentPair)
94+
}
95+
if state == IN_PROPERTY && strings.Trim(string(current), " ") != "" {
96+
current = []byte{}
97+
blocks = append(blocks, currentBlock)
98+
currentBlock = Block{}
99+
state = IN_SELECTOR
100+
} else {
101+
panic(NOT_AFTER_VALUE)
102+
}
103+
}
104+
case ':':
105+
if state != IN_COMMENT {
106+
if state == IN_PROPERTY && !bytes.Equal(nil, current) {
107+
state = IN_VALUE
108+
currentPair.property = current
109+
110+
// Cleanup
111+
current = []byte{}
112+
} else {
113+
if state != IN_VALUE && state != IN_SELECTOR {
114+
panic(NOT_IN_PROPERTY)
115+
}
116+
}
117+
}
118+
case ';':
119+
if state != IN_COMMENT {
120+
if state == IN_VALUE {
121+
state = IN_PROPERTY
122+
currentPair.value = current
123+
currentBlock.pairs = append(currentBlock.pairs, currentPair)
124+
125+
// Cleanup
126+
currentPair = Pair{}
127+
current = []byte{}
128+
} else {
129+
panic(NOT_IN_VALUE)
130+
}
131+
}
132+
default:
133+
if state != IN_COMMENT {
134+
if state == 0 {
135+
state = IN_SELECTOR
136+
}
137+
current = append(current, letter)
138+
}
139+
}
19140

20-
block = createBlockFromFile(&content)
21-
for block.selector != "" {
22-
blocks = append(blocks, block)
23-
block = createBlockFromFile(&content)
24141
}
25142

26143
return blocks
27144
}
28145

29-
func createBlockFromFile(content *string) Block {
30-
return Block{}
146+
func stripLetter(content []byte) (byte, []byte) {
147+
var letter byte
148+
if len(content) != 0 {
149+
letter = content[0]
150+
content = content[1:]
151+
} else {
152+
content = []byte{}
153+
}
154+
return letter, content
31155
}
32156

33157
func readFile(root string) string {

Pair.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package cssminify
22

33
type Pair struct {
4-
property string
5-
value string
4+
property []byte
5+
value []byte
66
}

0 commit comments

Comments
 (0)