client.go (2728B)
1 // Copyright 2018 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package scss
15
16 import (
17 "regexp"
18
19 "github.com/gohugoio/hugo/helpers"
20 "github.com/gohugoio/hugo/hugolib/filesystems"
21 "github.com/gohugoio/hugo/resources"
22 "github.com/spf13/afero"
23
24 "github.com/mitchellh/mapstructure"
25 )
26
27 const transformationName = "tocss"
28
29 type Client struct {
30 rs *resources.Spec
31 sfs *filesystems.SourceFilesystem
32 workFs afero.Fs
33 }
34
35 func New(fs *filesystems.SourceFilesystem, rs *resources.Spec) (*Client, error) {
36 return &Client{sfs: fs, workFs: rs.BaseFs.Work, rs: rs}, nil
37 }
38
39 type Options struct {
40
41 // Hugo, will by default, just replace the extension of the source
42 // to .css, e.g. "scss/main.scss" becomes "scss/main.css". You can
43 // control this by setting this, e.g. "styles/main.css" will create
44 // a Resource with that as a base for RelPermalink etc.
45 TargetPath string
46
47 // Hugo automatically adds the entry directories (where the main.scss lives)
48 // for project and themes to the list of include paths sent to LibSASS.
49 // Any paths set in this setting will be appended. Note that these will be
50 // treated as relative to the working dir, i.e. no include paths outside the
51 // project/themes.
52 IncludePaths []string
53
54 // Default is nested.
55 // One of nested, expanded, compact, compressed.
56 OutputStyle string
57
58 // Precision of floating point math.
59 Precision int
60
61 // When enabled, Hugo will generate a source map.
62 EnableSourceMap bool
63 }
64
65 func DecodeOptions(m map[string]any) (opts Options, err error) {
66 if m == nil {
67 return
68 }
69 err = mapstructure.WeakDecode(m, &opts)
70
71 if opts.TargetPath != "" {
72 opts.TargetPath = helpers.ToSlashTrimLeading(opts.TargetPath)
73 }
74
75 return
76 }
77
78 var (
79 regularCSSImportTo = regexp.MustCompile(`.*(@import "(.*\.css)";).*`)
80 regularCSSImportFrom = regexp.MustCompile(`.*(\/\* HUGO_IMPORT_START (.*) HUGO_IMPORT_END \*\/).*`)
81 )
82
83 func replaceRegularImportsIn(s string) (string, bool) {
84 replaced := regularCSSImportTo.ReplaceAllString(s, "/* HUGO_IMPORT_START $2 HUGO_IMPORT_END */")
85 return replaced, s != replaced
86 }
87
88 func replaceRegularImportsOut(s string) string {
89 return regularCSSImportFrom.ReplaceAllString(s, "@import \"$2\";")
90 }