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

Import statements does not work with StringSource #285

Closed casph closed 9 years ago

casph commented 9 years ago

Hi, i'm actually using less4j compiler with a StringSource object. My less data is actually coming from a database text field. In my text i've an import statement:

@import 's.less';

So i need to specify where to get the file. Actually i've tried to set the uri argument in StringSource constructor, but it's not working.

Path path = Paths.get("/somepath/db.less");
new LessSource.StringSource(content, name, path.toUri());

Also tried to extend LessSource like this:

public class MySource extends LessSource {

  private String content;
  private Path path;

  public TWTemaSource(String content, Path path) {
    this.content = content;
    this.path = path;
  }

  @Override
  public URI getURI() {
    return path.toUri();
  }

  @Override
  public String getName() {
    return path.getFileName().toString();
  }

  @Override
  public String getContent() {
    return content;
  }

  @Override
  public byte[] getBytes() {
    return content != null ? content.getBytes() : null;
  }

  @Override
  public LessSource relativeSource(String filename) throws StringSourceException {
    return new FileSource(path.resolveSibling(filename).toFile(), Charsets.UTF_8.toString());
  }
}

but i get always the same warning: Attempt to import less file with an unknown compiled file location. Import statement left unchanged

So i'm stuck in this.

martin-g commented 9 years ago

You should override #relativeSource() for this.

  1. https://github.com/SomMeri/less4j/blob/d94b7d010c04f3648960fd1d144792b68f562321/src/main/java/com/github/sommeri/less4j/LessSource.java#L25
casph commented 9 years ago

I've alrady done this if you look at my class MySource. Maybe i've overrided it wrongly?

martin-g commented 9 years ago

Sorry. I didn't notice it. What the debugger says? Put a breakpoint inside this method and see what happens.

casph commented 9 years ago

The problem is that the method itself is never called. i've already put a breakpoint inside it. The only log that i've is the one i've alrady wrote: Attempt to import less file with an unknown compiled file location. Import statement left unchanged

casph commented 9 years ago

If relativeSource method is for this, why stringsource object does not implement it? It's throwing an exception now.

martin-g commented 9 years ago

https://github.com/SomMeri/less4j/blob/d94b7d010c04f3648960fd1d144792b68f562321/src/main/java/com/github/sommeri/less4j/LessSource.java#L406

It cannot provide a default impl because a String has no base directory to calculate relative paths to. It is up to you to override it and decide what could be used as a basedir.

casph commented 9 years ago

i'm passing an uri as third parameter of the constructor so that it can be used for this: https://github.com/SomMeri/less4j/blob/d94b7d010c04f3648960fd1d144792b68f562321/src/main/java/com/github/sommeri/less4j/LessSource.java#L379 maybe i'm wrong?

Apart from that the method in question is not called.

SomMeri commented 9 years ago

@casph The getUri method is used only for error reporting, when building source map and to guess output filename (when used from command line).

StringSource does not implement relativeSource, because uri can link to any protocol: https, ftp, file, etc. It would not be possible to implement them all and would just add a lot of dependencies few people will need.

I wont be able to debug your case for next week and half, but will do so after that (unless you solve the problem in the meantime).

casph commented 9 years ago

@SomMeri Thanks a lot, for now i'm just using a workaround parsing imports in less files manually, so i can wait for you.

SomMeri commented 9 years ago

@casph I tried to reproduce the problem and relativeSource got called for me. This is how I compiled less:

  protected CompilationResult compile(File lessFile, File cssOutput) throws Less4jException {
    LessCompiler compiler = new DefaultLessCompiler();

    MySource source = new MySource("@import 's.less';", new File("c:/data"));
    CompilationResult actual = compiler.compile(source);
    return actual;
  }

Is there something else in your database less file that might cause the error (maybe it calls a function or something like that)?

The only change I did in MySource class is that I replaced Path by File (it was faster for me since less4j is compiled in java 6).

SomMeri commented 9 years ago

I am closing issue. Feel free to reopen If it still does not work or you have more details.