Mercurial > yakumo_izuru > aya
comparison vendor/github.com/yosssi/gcss/compile.go @ 66:787b5ee0289d draft
Use vendored modules
Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
| author | yakumo.izuru |
|---|---|
| date | Sun, 23 Jul 2023 13:18:53 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 65:6d985efa0f7a | 66:787b5ee0289d |
|---|---|
| 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 } |
