Skip to content

Commit

Permalink
When the first letter of a comment is !, the comment will be interp…
Browse files Browse the repository at this point in the history
…olated

and always rendered into css output even in compressed output modes.
This is useful for adding Copyright notices to your generated CSS.
  • Loading branch information
chriseppstein committed Mar 9, 2011
1 parent 39fffd0 commit 0a4d754
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 5 deletions.
6 changes: 6 additions & 0 deletions doc-src/SASS_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
The imported file will be treated as though it were nested within the rule.
Files with mixins may not be imported in nested contexts.

* If a comment starts with `!`, that comment will now be interpolated
(`#{...}` will be replaced with the resulting value of the expression
inside) and the comment will always be printed out in the generated CSS
file -- even with compressed output. This is useful for adding copyright
notices to your stylesheets.

### Keyword Arguments

Both mixins and Sass functions now support the ability to pass in keyword arguments.
Expand Down
3 changes: 3 additions & 0 deletions doc-src/SASS_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,9 @@ is compiled to:
a {
color: green; }

When the first letter of a comment is `!`, the comment will be interpolated
and always rendered into css output even in compressed output modes. This is useful for adding Copyright notices to your generated CSS.

## SassScript {#sassscript}

In addition to the plain CSS property syntax,
Expand Down
25 changes: 23 additions & 2 deletions lib/sass/tree/comment_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ class CommentNode < Node
# @return [String]
attr_accessor :value

# Whether the comment is loud.
#
# Loud comments start with ! and force the comment to be generated
# irrespective of compilation settings or the comment syntax used.
#
# @return [Boolean]
attr_accessor :loud

# Whether or not the comment is silent (that is, doesn't output to CSS).
#
# @return [Boolean]
Expand All @@ -19,8 +27,10 @@ class CommentNode < Node
# @param silent [Boolean] See \{#silent}
def initialize(value, silent)
@lines = []
@value = normalize_indentation value
@silent = silent
@value = normalize_indentation value
@loud = @value =~ %r{^(/[\/\*])?!}
@value.sub!("#{$1}!", $1.to_s) if @loud
super()
end

Expand All @@ -36,9 +46,20 @@ def ==(other)
# Returns `true` if this is a silent comment
# or the current style doesn't render comments.
#
# Comments starting with ! are never invisible (and the ! is removed from the output.)
#
# @return [Boolean]
def invisible?
style == :compressed || @silent
if @loud
return false
else
@silent || (style == :compressed)
end
end

# Returns whether this comment should be interpolated for dynamic comment generation.
def evaluated?
@loud
end

private
Expand Down
9 changes: 8 additions & 1 deletion lib/sass/tree/visitors/perform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ def visit_root(node)

# Removes this node from the tree if it's a silent comment.
def visit_comment(node)
node.silent ? [] : node
return [] if node.invisible?
if node.evaluated?
node.value.gsub!(/(^|[^\\])\#{([^}]*)}/) do |md|
$1+Sass::Script.parse($2, node.line, 0, node.options).perform(@environment).to_s
end
node.value = run_interp([Sass::Script::String.new(node.value)])
end
node
end

# Prints the expression to STDERR.
Expand Down
6 changes: 4 additions & 2 deletions lib/sass/tree/visitors/to_css.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ def visit_comment(node)
return if node.invisible?
spaces = (' ' * [@tabs - node.value[/^ */].size, 0].max)

content = node.value.gsub(/^/, spaces)
content.gsub!(/\n +(\* *(?!\/))?/, ' ') if node.style == :compact
content = node.value.gsub(/^/, spaces).gsub(%r{^(\s*)//(.*)$}) do |md|
"#{$1}/*#{$2} */"
end
content.gsub!(/\n +(\* *(?!\/))?/, ' ') if (node.style == :compact || node.style == :compressed) && !node.loud
content
end

Expand Down
41 changes: 41 additions & 0 deletions test/sass/engine_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,47 @@ def test_loud_comment_with_separate_line_close
SASS
end

def test_loud_comment_in_compressed_mode
assert_equal <<CSS, render(<<SASS, :style => :compressed)
foo{color:blue;/* foo
* bar
*/}
CSS
foo
color: blue
/*! foo
* bar
*/
SASS
end
def test_loud_comment_in_silent_comment
assert_equal <<CSS, render(<<SASS, :style => :compressed)
foo{color:blue;/* foo */
/* bar */
/* */
/* bip */
/* baz */}
CSS
foo
color: blue
//! foo
//! bar
//!
bip
baz
SASS
end

def test_loud_comment_is_evaluated
assert_equal <<CSS, render(<<SASS)
/*
* Hue: 327.216deg */
CSS
/*!
Hue: \#{hue(#f836a0)}
SASS
end

def test_attribute_selector_with_spaces
assert_equal(<<CSS, render(<<SASS))
a b[foo=bar] {
Expand Down

0 comments on commit 0a4d754

Please sign in to comment.