1#| 2Copyright 2017 Dmitry Arkhipov 3Distributed under the Boost Software License, Version 1.0. (See 4accompanying file LICENSE_1_0.txt or copy at 5http://www.boost.org/LICENSE_1_0.txt) 6|# 7 8import common ; 9import feature ; 10import generators ; 11import modules ; 12import sequence ; 13import toolset ; 14import "class" : new ; 15 16#| tag::doc[] 17 18= Sass 19 20This tool converts SASS and SCSS files into CSS. This tool explicitly supports 21both the version written in C (sassc) and the original Ruby implementation 22(scss) but other variants might also work. In addition to tool-specific 23features, described in this section, the tool recognizes features `<flags>` 24and `<include>`. 25 26|# # end::doc[] 27 28feature.feature sass : : implicit propagated symmetric ; 29 30#| tag::doc[] 31 32== Feature: `sass-style` 33 34Sets the output style. Available values are 35 36* `nested`: each property is put on its own line, rules are indented based on 37 how deeply they are nested; 38* `expanded`: each property is put on its own line, rules are not indented; 39* `compact`: each rule is put on a single line, nested rules occupy adjacent 40 lines, while groups of unrelated rules are separated by newlines; 41* `compressed`: takes minimum amount of space: all unnecessary whitespace is 42 removed, property values are compressed to have minimal representation. 43 44The feature is `optional` and is not `propagated` to dependent targets. If no 45style is specified, then, if property set contains property `<optimization>on`, 46`compressed` style is selected. Otherwise, `nested` style is selected. 47 48|# # end::doc[] 49 50feature.subfeature sass 51 : style 52 : nested expanded compact compressed 53 : optional 54 ; 55 56#| tag::doc[] 57 58== Feature: `sass-line-numbers` 59 60Enables emitting comments showing original line numbers for rules. This can be 61useful for debugging a stylesheet. Available values are `on` and `off`. The 62feature is `optional` and is not `propagated` to dependent targets. If no value 63for this feature is specified, then one is copied from the feature 64`debug-symbols`. 65 66|# # end::doc[] 67 68feature.subfeature sass : line-numbers : on off : optional ; 69 70#| tag::doc[] 71 72== Initialization 73 74To use the `sass` tool you need to declare it in a configuration file with the 75`using` rule. The initialization takes the following arguments: 76 77* `command`: the command, with any extra arguments, to execute. 78 79For example you could insert the following in your `user-config.jam`: 80 81``` 82using sass : /usr/local/bin/psass -p2 ; # Perl libsass-based version 83``` 84 85If no `command` is given, `sassc` is tried, after which `scss` is tried. 86 87|# # end::doc[] 88 89rule init ( command * ) 90{ 91 if ! $(.initialized) 92 { 93 # Setup only if we were called via "using .. ;" 94 .initialized = true ; 95 96 # Register generators 97 generators.register [ new sass-generator sass.convert : SASS : CSS ] ; 98 } 99 100 # Setting up command 101 if ! $(command) 102 { 103 # If none was specified by the user, first try sassc, then scss 104 SASS = [ common.find-tool sassc ] ; 105 SASS ?= [ common.find-tool scss ] ; 106 } 107 else 108 { 109 # Otherwise we attempt to resolve each component of the command to 110 # account for script interpreter wrappers. 111 SASS = [ sequence.transform maybe-find-tool : $(command) ] ; 112 } 113} 114 115class sass-generator : generator 116{ 117 import property-set ; 118 119 rule run ( project name ? : property-set : sources + ) 120 { 121 local style = [ $(property-set).get <sass-style> ] ; 122 local line-numbers = [ $(property-set).get <sass-line-numbers> ] ; 123 124 # Only one source file is sensible; we accept only sass and scss files 125 if ( ! $(sources[2]) ) && ( [ $(sources[1]).type ] in SASS ) 126 { 127 # If no output name was given, guess it from sources 128 if ! $(name) 129 { 130 name = [ generator.determine-output-name $(sources) ] ; 131 } 132 133 # If output style was not given, then it is determined by 134 # <optimization> feature 135 if ! $(style) 136 { 137 switch [ $(property-set).get <optimization> ] 138 { 139 case "off" : style = nested ; 140 case * : style = compressed ; 141 } 142 } 143 144 # If line-numbers feature wasn't specified, copy it from 145 # <debug-symbols> 146 line-numbers ?= [ $(property-set).get <debug-symbols> ] ; 147 } 148 149 # We build a reduced property set so that we are not toolset dependent. 150 local raw-set 151 = <sass-style>$(style) 152 <sass-line-numbers>$(line-numbers) 153 ; 154 raw-set += 155 [ sequence.filter recognized-feature : [ $(property-set).raw ] ] ; 156 raw-set = [ feature.expand-composites $(raw-set) ] ; 157 raw-set += [ $(property-set).incidental ] ; 158 property-set = [ property-set.create $(raw-set) ] ; 159 return 160 [ generator.run $(project) $(name) 161 : $(property-set) 162 : $(sources) 163 ] ; 164 } 165 166 local rule recognized-feature ( feature ) 167 { 168 local result ; 169 if $(feature:G) in <include> <flags> 170 { 171 result = true ; 172 } 173 return $(result) ; 174 } 175} 176 177_ = " " ; 178toolset.flags sass STYLE : <sass-style> ; 179toolset.flags sass LINE_NUMBERS <sass-line-numbers>on : --line-numbers ; 180toolset.flags sass INCLUDES : <include> ; 181toolset.flags sass FLAGS : <flags> ; 182 183actions convert 184{ 185 "$(SASS)" -t$(_)"$(STYLE)" $(LINE_NUMBERS) -I$(_)"$(INCLUDES)" $(FLAGS) "$(>)" $(_)"$(<)" 186} 187 188local rule maybe-find-tool ( command ) 189{ 190 local tool = [ common.find-tool $(command) ] ; 191 tool ?= $(command) ; 192 return $(tool) ; 193} 194