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 }