3

Since version 2 of Less you can use plugins. You can also use these plugins to add custom function to Less, examples: https://github.com/less/less-plugin-advanced-color-functions/ and https://github.com/bassjobsen/less-plugin-cubehelix

Inspired on https://github.com/less/less.js/issues/2341 i want to add a custom function twotimesandten to less, so that:

@start: 10;
.test {
result: twotimesandten(@start);
}

compiles into:

.test {
result: 30;
}

After reading http://lesscss.org/usage/#plugins-for-plugin-authors, i wonder how to do this?

Bass Jobsen
  • 48,736
  • 16
  • 143
  • 224

1 Answers1

7

First write the plugin for usage in the browser. You create the plugin using the following code:

var TwoTimesAndTen = {
    install: function(less) {
        less.functions.functionRegistry.add('twotimesandten' ,function(input) { return new(less.tree.Anonymous)(input.value * 2 + 10);} );
    }
};
less = { 
    env: "development",
    plugins: [TwoTimesAndTen]
};
</script>  
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.1.0/less.min.js"></script>

Notice that you should write the name of your function lower-cased always.

To use the above code for the command line compiler you should create a file named less-plugin-twotimesandten/index.js. That file should contain the following code:

var TwoTimesAndTen = {
    install: function(less) {
        less.functions.functionRegistry.add('twotimesandten' ,function(input) { return new(less.tree.Anonymous)(input.value * 2 + 10);} );
    }
};
module.exports = TwoTimesAndTen;

Then you can run the following command in your console:

echo '@start: 10; .test { result:twotimesandten(@start); }' | lessc --plugin=less-plugin-twotimesandten/index.js -

The above will output:

.test {
  result: 30;
}

To install this plugin for global usage you should create a second file named less-plugin-twotimesandten/package.json. The package.json should contain at least the following lines of code:

{
    "name": "less-plugin-twotimesandten",
    "version": "0.0.1",
    "description": "twotimesandten plugin for less.js",
    "main": "index.js"
}

After saving the package.json file you can run the following command in your console:

npm install less-plugin-twotimesandten

Make sure you navigate outside your less-plugin-twotimesandten directory first. In the preceding command less-plugin-twotimesandten is the path to your plugin.

Now you can run the following command:

echo '@start: 10; .test { result:twotimesandten(@start); }' | lessc --twotimesandten -

To write a plugin that runs both client and server side you should read: http://caolanmcmahon.com/posts/writing_for_node_and_the_browser/ (feel free to contribute to https://github.com/less/less-meta/issues/5 too).

Rewrite the content of your less-plugin-twotimesandten/index.js as follows:

(function(exports){
    exports.install= function(less) {
     less.functions.functionRegistry.add('twotimesandten' ,function(input) { return new(less.tree.Anonymous)(input.value * 2 + 10);} );
      };
})(typeof exports === 'undefined'? this['TwoTimesAndTen']={}: exports); 

The above does not change command line usage. For brower usage you can now use the following code:

<script src="less-plugin-twotimesandten/index.js"></script>
<script>
less = { 
    env: "development",
    plugins: [TwoTimesAndTen]
};
</script>  
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.1.0/less.min.js"></script>
Bass Jobsen
  • 48,736
  • 16
  • 143
  • 224
  • Do you have any samples for making a plugin work in the browser mate? I tried the first part of the answer a few different ways but seems like I can't get the hang of it. – Harry Mar 11 '15 at 13:43
  • @harry, to be sure i have test the `TwoTimesAndTen` example above with Less v2.4.0 and i did not found any issues. Possible sometime else in your code won't work, make sure that you write your function name in lowwercase. Also the custom function(s) should accept and return types defined by Less (less.tree.Anonymous) in the above. Otherwise please send me an email with your questions or post a new question. – Bass Jobsen Mar 11 '15 at 19:25
  • Sorry mate. It was my mistake. Didn't realize that the cross origin request error was blocking the processing in Chrome. Hosted it on a server and the code was working perfectly fine. Apologies for troubling you. – Harry Mar 12 '15 at 16:26