SomMeri / less4j

Less language is an extension of css and less4j compiles it into regular css. Less adds several dynamic features into css: variables, expressions, nested rules, and so on. Less was designed to be compatible with css and any correct css file is also correct less file.
145 stars 47 forks source link

Compile with javascript mixin #300

Closed danjee closed 9 years ago

danjee commented 9 years ago

I'm having difficulties compiling a mixin that contains some javascript function. Compiling it from brackets was successful.

/*
 * Scale 3d
 */
.scale3d(...) {
  @process: ~`(function(e){return e=e||"1, 1, 1"})((function(){var e="@{arguments}";return e=e.replace(/^\[|\]$/g,"")})())`;
  -webkit-transform: scale3d(@process);
  -moz-transform: scale3d(@process);
  -ms-transform: scale3d(@process);
  -o-transform: scale3d(@process);
  transform: scale3d(@process);
}

// pentru testare
.btn-test{
    background-color: aqua;
    .scale3d(0,0,0);
}

The java class that I use is something like this:

public class Test {
    public static void main(String[] args) {
        ThreadUnsafeLessCompiler compiler = new ThreadUnsafeLessCompiler();
        try {
            LessCompiler.Configuration configuration = new LessCompiler.Configuration();
            String source = getLessSource();
            LessCompiler.CompilationResult result = compiler.compile(source, configuration);
            List<LessCompiler.Problem> warnings = result.getWarnings();

            for (LessCompiler.Problem warning : warnings) {
                System.err.println(warning.getMessage());
            }

            String cssContent = result.getCss();
            System.out.println(cssContent);
        } catch (Less4jException x) {
            x.printStackTrace();
        }
    }

    private static String getLessSource() {
        return getStringFromInputStream(Test.class.getResourceAsStream("test.less"));
    }

    private static String getStringFromInputStream(InputStream is) {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();

    }
}

This can be fixed ? Thank you

SomMeri commented 9 years ago

@danjee JavaScript support is in separate plugin. Here is plugin readme.

I will close this, but feel free to ask questions or re-open if you have trouble to make it work.

danjee commented 9 years ago

Thank you @SomMeri for your fast response. I've didn't know about the separate plugin. Unfortunately that didn't worked either. My new java code is:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

import com.github.sommeri.less4j.Less4jException;
import com.github.sommeri.less4j.LessCompiler;
import com.github.sommeri.less4j.core.DefaultLessCompiler;
import com.github.sommeri.less4j_javascript.Less4jJavascript;

public class Test {
    public static void main(String[] args) {
        try {
            LessCompiler.Configuration configuration = new LessCompiler.Configuration();
            Less4jJavascript.configure(configuration);
            String source = getLessSource();
            LessCompiler compiler = new DefaultLessCompiler();
            LessCompiler.CompilationResult result = compiler.compile(source, configuration);
            List<LessCompiler.Problem> warnings = result.getWarnings();
            for (LessCompiler.Problem warning : warnings) {
                System.err.println(warning.getMessage());
            }
            String cssContent = result.getCss();
            System.out.println(cssContent);
        } catch (Less4jException x) {
            x.printStackTrace();
        }
    }

    private static String getLessSource() {
        return getStringFromInputStream(Test.class.getResourceAsStream("test.less"));
    }

    private static String getStringFromInputStream(InputStream is) {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();

    }
}

But I still do not have any output, not even an error.

SomMeri commented 9 years ago

@danjee There seem to be an odd problem with the following line:

// pentru testare

When I remove the above line, the test less compiles into:

.btn-test {
  background-color: aqua;
  -webkit-transform: scale3d(0, 0, 0);
  -moz-transform: scale3d(0, 0, 0);
  -ms-transform: scale3d(0, 0, 0);
  -o-transform: scale3d(0, 0, 0);
  transform: scale3d(0, 0, 0);
}

Thank you for reporting the bug, I will fix this.

SomMeri commented 9 years ago

The problem is in how the file is read:

      while ((line = br.readLine()) != null) {
        sb.append(line);
      }

The BufferedReader.readLine method strips all newlines away. Therefore, everything after // becomes part of the comment and is ignored by the compiler.

Quickfix:

      while ((line = br.readLine()) != null) {
        sb.append(line);
        sb.append("\n"); // add newlines back
      }
danjee commented 9 years ago

Thank you