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

# User Rev Content
1 yakumo_izuru 1.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     }