Parse error of conditionals inside mixin #53

mingodad opened this Issue Oct 22, 2012 · 7 comments


None yet
2 participants

The example bellow is extracted and adapted from "compass/typography/text/_replacement.scss" and do not compile with libsass :
ERROR -- test.scss:7: invalid property name

if the conditionals are commented it does work // @if is-url($img) { // } @else { //} , it seems that the parser doesn't recognize the @if conditional inside the mixin.

@function is-url($n) {
@return $n != '';

@mixin replace-text($img, $x: 50%, $y: 50%) {
//@include hide-text;
background: {
@if is-url($img) {
image: $img;
} @else {
image: image-url($img);
repeat: no-repeat;
position: $x $y;

@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
color: #ff0000;

.dad {
@include replace-text('dad');
@include large-text;

Good catch! The problem is specifically that conditionals aren't allowed inside namespaced properties. I'll fix this soon. Thanks!

Oh, I should also point out that replacing the background { ... } block with the following should work (assuming that the is-url function is implemented in SassScript, of course):

background-image: if(is-url($img), $img, image-url($img));
background: {
  repeat: no-repeat;
  position: $x $y;

After playing a bit with the code I tried this modification but it now gives another error:

It seems that this parser is generated by hand. How it works ?
If some explanation about of the logic of this parser is provided it can allow other people to help improve it, I plan to integrate a lua interpreter on it and knowing a bit how it is supposed to work will make things easier.

Node Document::parse_propset()
lex< identifier >();
Node property_segment(context.new_Node(Node::identifier, path, line, lexed));
lex< exactly<':'> >();
lex< exactly<'{'> >();
Node block(context.new_Node(Node::block, path, line, 1));
while (!lex< exactly<'}'> >()) {
if (peek< sequence< identifier, optional_spaces, exactly<':'>, optional_spaces, exactly<'{'> > >(position)) {
block << parse_propset();
///////new code start
else if(peek< exactly<'@'> >()) {
block << parse_block(block);
//////new code end
else {
block << parse_rule();
lex< exactly<';'> >();
if (block.empty()) throw_syntax_error("namespaced property cannot be empty");
Node propset(context.new_Node(Node::propset, path, line, 2));
propset << property_segment;
propset << block;
return propset;

Yeah, the parser is hand-written and somewhat complex, and the formal syntax of Sass itself is fairly complicated too. Documenting the whole thing isn't really feasible for me at the moment, but if you can tell me how you want to integrate Lua and what you want to do with it, I may be able to explain some of the relevant LibSass components.

(Incidentally, Lua is one of my favorite langauges, so I appreciate your interest in integrating it with LibSass!)

My idea is to be able to also create functions with lua to be used inside scss probably something like:

@-lua {
--any lua code here
--maybe having a global object sass where we can create new functions on it
--that will be searched when an identifier is not found elsewhere
function sass:resize_image(img_name, new_size)
os.execute("imagemagick ...")

.menu {
background-image : @include resize_image('some_image', 30px);

Hmm, rather than introduce special syntax, a better way might be to introduce a new built-in Sass function that takes a Lua source string as an argument. Check out functions.cpp for the set of built-in Sass functions. They're also declared in functions.hpp and registered in context.cpp.

You could define the function to be used as follows:

$x: something();
$y: something-else();
div {
  foo: lua("some_lua_function(#{$x}, #{$y})");

Unfortunately, defining functions in Lua and making them accessible in Sass will require a foreign function interface, which is still in development. But once this is done, you'd be able to add Lua support without needing to fork LibSass.

All right, directives and whatnot are allowed in namespaced properties now.

@akhleung akhleung closed this Nov 28, 2012

anlutro pushed a commit to alprs/libsass that referenced this issue Feb 2, 2015

Merge pull request #53 from mgreter/passing-tests
More passing tests recovered
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment