ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/aya/vendor/github.com/yosssi/gcss/compile.go
Revision: 1.1
Committed: Mon Sep 30 00:42:06 2024 UTC (6 weeks, 4 days ago) by yakumo_izuru
Branch: MAIN
CVS Tags: HEAD
Log Message:
Mirrored from https://git.chaotic.ninja/git/yakumo_izuru/aya

File Contents

# Content
1 package gcss
2
3 import (
4 "bytes"
5 "io"
6 "io/ioutil"
7 "path/filepath"
8 "strings"
9 )
10
11 // extensions
12 const (
13 extCSS = ".css"
14 extGCSS = ".gcss"
15 )
16
17 // cssFilePath converts path's extenstion into a CSS file extension.
18 var cssFilePath = func(path string) string {
19 return convertExt(path, extCSS)
20 }
21
22 // Compile compiles GCSS data which is read from src and
23 // Writes the result CSS data to the dst.
24 func Compile(dst io.Writer, src io.Reader) (int, error) {
25 data, err := ioutil.ReadAll(src)
26
27 if err != nil {
28 return 0, err
29 }
30
31 bc, berrc := compileBytes(data)
32
33 bf := new(bytes.Buffer)
34
35 BufWriteLoop:
36 for {
37 select {
38 case b, ok := <-bc:
39 if !ok {
40 break BufWriteLoop
41 }
42
43 bf.Write(b)
44 case err := <-berrc:
45 return 0, err
46 }
47 }
48
49 return dst.Write(bf.Bytes())
50 }
51
52 // CompileFile parses the GCSS file specified by the path parameter,
53 // generates a CSS file and returns the path of the generated CSS file
54 // and an error when it occurs.
55 func CompileFile(path string) (string, error) {
56 data, err := ioutil.ReadFile(path)
57
58 if err != nil {
59 return "", err
60 }
61
62 cssPath := cssFilePath(path)
63
64 bc, berrc := compileBytes(data)
65
66 done, werrc := write(cssPath, bc, berrc)
67
68 select {
69 case <-done:
70 case err := <-werrc:
71 return "", err
72 }
73
74 return cssPath, nil
75 }
76
77 // compileBytes parses the GCSS byte array passed as the s parameter,
78 // generates a CSS byte array and returns the two channels: the first
79 // one returns the CSS byte array and the last one returns an error
80 // when it occurs.
81 func compileBytes(b []byte) (<-chan []byte, <-chan error) {
82 lines := strings.Split(formatLF(string(b)), lf)
83
84 bc := make(chan []byte, len(lines))
85 errc := make(chan error)
86
87 go func() {
88 ctx := newContext()
89
90 elemc, pErrc := parse(lines)
91
92 for {
93 select {
94 case elem, ok := <-elemc:
95 if !ok {
96 close(bc)
97 return
98 }
99
100 elem.SetContext(ctx)
101
102 switch v := elem.(type) {
103 case *mixinDeclaration:
104 ctx.mixins[v.name] = v
105 case *variable:
106 ctx.vars[v.name] = v
107 case *atRule, *declaration, *selector:
108 bf := new(bytes.Buffer)
109 elem.WriteTo(bf)
110 bc <- bf.Bytes()
111 }
112 case err := <-pErrc:
113 errc <- err
114 return
115 }
116 }
117 }()
118
119 return bc, errc
120 }
121
122 // Path converts path's extenstion into a GCSS file extension.
123 func Path(path string) string {
124 return convertExt(path, extGCSS)
125 }
126
127 // convertExt converts path's extension into ext.
128 func convertExt(path string, ext string) string {
129 return strings.TrimSuffix(path, filepath.Ext(path)) + ext
130 }