Advertisement
AmourSpirit

lessc Modified for eclipse

Dec 22nd, 2015
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env node
  2.  
  3. var path = require('path'),
  4.     fs = require('../lib/less-node/fs'),
  5.     os = require("os"),
  6.     errno,
  7.     mkdirp;
  8.  
  9. try {
  10.     errno = require('errno');
  11. } catch (err) {
  12.     errno = null;
  13. }
  14.  
  15. var less = require('../lib/less-node'),
  16.     pluginLoader = new less.PluginLoader(less),
  17.     plugin,
  18.     plugins = [];
  19.  
  20. var args = process.argv.slice(1);
  21. var silent = false,
  22.     verbose = false,
  23.     options = {
  24.     depends: false,
  25.     compress: false,
  26.     max_line_len: -1,
  27.     lint: false,
  28.     paths: [],
  29.     color: true,
  30.     strictImports: false,
  31.     insecure: false,
  32.     rootpath: '',
  33.     relativeUrls: false,
  34.     ieCompat: true,
  35.     strictMath: false,
  36.     strictUnits: false,
  37.     globalVars: null,
  38.     modifyVars: null,
  39.     urlArgs: '',
  40.     plugins: plugins
  41. };
  42. var sourceMapOptions = {};
  43. var continueProcessing = true,
  44.     currentErrorcode;
  45.  
  46. // calling process.exit does not flush stdout always
  47. // so use this to set the exit code
  48. process.on('exit', function() { process.reallyExit(currentErrorcode); });
  49.  
  50. var checkArgFunc = function(arg, option) {
  51.     if (!option) {
  52.         console.error(arg + " option requires a parameter");
  53.         continueProcessing = false;
  54.         currentErrorcode = 1;
  55.         return false;
  56.     }
  57.     return true;
  58. };
  59.  
  60. var checkBooleanArg = function(arg) {
  61.     var onOff = /^((on|t|true|y|yes)|(off|f|false|n|no))$/i.exec(arg);
  62.     if (!onOff) {
  63.         console.error(" unable to parse " + arg + " as a boolean. use one of on/t/true/y/yes/off/f/false/n/no");
  64.         continueProcessing = false;
  65.         currentErrorcode = 1;
  66.         return false;
  67.     }
  68.     return Boolean(onOff[2]);
  69. };
  70.  
  71. var parseVariableOption = function(option, variables) {
  72.     var parts = option.split('=', 2);
  73.     variables[parts[0]] = parts[1];
  74. };
  75.  
  76. var sourceMapFileInline = false;
  77.  
  78. function printUsage() {
  79.     less.lesscHelper.printUsage();
  80.     pluginLoader.printUsage(plugins);
  81.     continueProcessing = false;
  82. }
  83.  
  84. // self executing function so we can return
  85. (function() {
  86.     args = args.filter(function (arg) {
  87.         var match;
  88.  
  89.         match = arg.match(/^-I(.+)$/);
  90.         if (match) {
  91.             options.paths.push(match[1]);
  92.             return false;
  93.         }
  94.  
  95.         match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=(.*))?$/i);
  96.         if (match) {
  97.             arg = match[1];
  98.         } else {
  99.             return arg;
  100.         }
  101.  
  102.         switch (arg) {
  103.             case 'O0':
  104.             case '01':
  105.             case 'O1':
  106.                 // case O0 01 o1 are fixes for eclipse less plugin
  107.                 break;
  108.             case 'v':
  109.             case 'version':
  110.                 console.log("lessc " + less.version.join('.') + " (Less Compiler) [JavaScript]");
  111.                 continueProcessing = false;
  112.                 break;
  113.             case 'verbose':
  114.                 verbose = true;
  115.                 break;
  116.             case 's':
  117.             case 'silent':
  118.                 silent = true;
  119.                 break;
  120.             case 'l':
  121.             case 'lint':
  122.                 options.lint = true;
  123.                 break;
  124.             case 'strict-imports':
  125.                 options.strictImports = true;
  126.                 break;
  127.             case 'h':
  128.             case 'help':
  129.                 printUsage();
  130.                 break;
  131.             case 'x':
  132.             case 'compress':
  133.                 options.compress = true;
  134.                 break;
  135.             case 'insecure':
  136.                 options.insecure = true;
  137.                 break;
  138.             case 'M':
  139.             case 'depends':
  140.                 options.depends = true;
  141.                 break;
  142.             case 'max-line-len':
  143.                 if (checkArgFunc(arg, match[2])) {
  144.                     options.maxLineLen = parseInt(match[2], 10);
  145.                     if (options.maxLineLen <= 0) {
  146.                         options.maxLineLen = -1;
  147.                     }
  148.                 }
  149.                 break;
  150.             case 'no-color':
  151.                 options.color = false;
  152.                 break;
  153.             case 'no-ie-compat':
  154.                 options.ieCompat = false;
  155.                 break;
  156.             case 'no-js':
  157.                 options.javascriptEnabled = false;
  158.                 break;
  159.             case 'include-path':
  160.                 if (checkArgFunc(arg, match[2])) {
  161.                     // ; supported on windows.
  162.                     // : supported on windows and linux, excluding a drive letter like C:\ so C:\file:D:\file parses to 2
  163.                     options.paths = match[2]
  164.                         .split(os.type().match(/Windows/) ? /:(?!\\)|;/ : ':')
  165.                         .map(function(p) {
  166.                             if (p) {
  167.                                 return path.resolve(process.cwd(), p);
  168.                             }
  169.                         });
  170.                 }
  171.                 break;
  172.             case 'line-numbers':
  173.                 if (checkArgFunc(arg, match[2])) {
  174.                     options.dumpLineNumbers = match[2];
  175.                 }
  176.                 break;
  177.             case 'source-map':
  178.                 options.sourceMap = true;
  179.                 if (match[2]) {
  180.                     sourceMapOptions.sourceMapFullFilename = match[2];
  181.                 }
  182.                 break;
  183.             case 'source-map-rootpath':
  184.                 if (checkArgFunc(arg, match[2])) {
  185.                     sourceMapOptions.sourceMapRootpath = match[2];
  186.                 }
  187.                 break;
  188.             case 'source-map-basepath':
  189.                 if (checkArgFunc(arg, match[2])) {
  190.                     sourceMapOptions.sourceMapBasepath = match[2];
  191.                 }
  192.                 break;
  193.             case 'source-map-map-inline':
  194.                 sourceMapFileInline = true;
  195.                 options.sourceMap = true;
  196.                 break;
  197.             case 'source-map-less-inline':
  198.                 sourceMapOptions.outputSourceFiles = true;
  199.                 break;
  200.             case 'source-map-url':
  201.                 if (checkArgFunc(arg, match[2])) {
  202.                     sourceMapOptions.sourceMapURL = match[2];
  203.                 }
  204.                 break;
  205.             case 'rp':
  206.             case 'rootpath':
  207.                 if (checkArgFunc(arg, match[2])) {
  208.                     options.rootpath = match[2].replace(/\\/g, '/');
  209.                 }
  210.                 break;
  211.             case "ru":
  212.             case "relative-urls":
  213.                 options.relativeUrls = true;
  214.                 break;
  215.             case "sm":
  216.             case "strict-math":
  217.                 if (checkArgFunc(arg, match[2])) {
  218.                     options.strictMath = checkBooleanArg(match[2]);
  219.                 }
  220.                 break;
  221.             case "su":
  222.             case "strict-units":
  223.                 if (checkArgFunc(arg, match[2])) {
  224.                     options.strictUnits = checkBooleanArg(match[2]);
  225.                 }
  226.                 break;
  227.             case "global-var":
  228.                 if (checkArgFunc(arg, match[2])) {
  229.                     if (!options.globalVars) {
  230.                         options.globalVars = {};
  231.                     }
  232.                     parseVariableOption(match[2], options.globalVars);
  233.                 }
  234.                 break;
  235.             case "modify-var":
  236.                 if (checkArgFunc(arg, match[2])) {
  237.                     if (!options.modifyVars) {
  238.                         options.modifyVars = {};
  239.                     }
  240.  
  241.                     parseVariableOption(match[2], options.modifyVars);
  242.                 }
  243.                 break;
  244.             case 'url-args':
  245.                 if (checkArgFunc(arg, match[2])) {
  246.                     options.urlArgs = match[2];
  247.                 }
  248.                 break;
  249.             case 'plugin':
  250.                 var splitupArg = match[2].match(/^([^=]+)(=(.*))?/),
  251.                     name = splitupArg[1],
  252.                     pluginOptions = splitupArg[3];
  253.  
  254.                 plugin = pluginLoader.tryLoadPlugin(name, pluginOptions);
  255.                 if (plugin) {
  256.                     plugins.push(plugin);
  257.                 } else {
  258.                     console.error("Unable to load plugin " + name +
  259.                         " please make sure that it is installed under or at the same level as less");
  260.                     currentErrorcode = 1;
  261.                 }
  262.                 break;
  263.             default:
  264.                 plugin = pluginLoader.tryLoadPlugin("less-plugin-" + arg, match[2]);
  265.                 if (plugin) {
  266.                     plugins.push(plugin);
  267.                 } else {
  268.                     console.error("Unable to interpret argument " + arg +
  269.                         " - if it is a plugin (less-plugin-" + arg + "), make sure that it is installed under or at" +
  270.                         " the same level as less");
  271.                     currentErrorcode = 1;
  272.                 }
  273.                 break;
  274.         }
  275.     });
  276.  
  277.     if (!continueProcessing) {
  278.         return;
  279.     }
  280.  
  281.     var input = args[1];
  282.     if (input && input != '-') {
  283.         input = path.resolve(process.cwd(), input);
  284.     }
  285.     var output = args[2];
  286.     var outputbase = args[2];
  287.     if (output) {
  288.         output = path.resolve(process.cwd(), output);
  289.     }
  290.  
  291.     if (options.sourceMap) {
  292.  
  293.         sourceMapOptions.sourceMapInputFilename = input;
  294.         if (!sourceMapOptions.sourceMapFullFilename) {
  295.             if (!output && !sourceMapFileInline) {
  296.                 console.log("the sourcemap option only has an optional filename if the css filename is given");
  297.                 console.log("consider adding --source-map-map-inline which embeds the sourcemap into the css");
  298.                 return;
  299.             }
  300.             // its in the same directory, so always just the basename
  301.             sourceMapOptions.sourceMapOutputFilename = path.basename(output);
  302.             sourceMapOptions.sourceMapFullFilename = output + ".map";
  303.             // its in the same directory, so always just the basename
  304.             sourceMapOptions.sourceMapFilename = path.basename(sourceMapOptions.sourceMapFullFilename);
  305.         } else if (options.sourceMap && !sourceMapFileInline) {
  306.             var mapFilename = path.resolve(process.cwd(), sourceMapOptions.sourceMapFullFilename),
  307.                 mapDir = path.dirname(mapFilename),
  308.                 outputDir = path.dirname(output);
  309.             // find the path from the map to the output file
  310.             sourceMapOptions.sourceMapOutputFilename = path.join(
  311.                 path.relative(mapDir, outputDir), path.basename(output));
  312.  
  313.             // make the sourcemap filename point to the sourcemap relative to the css file output directory
  314.             sourceMapOptions.sourceMapFilename = path.join(
  315.                 path.relative(outputDir, mapDir), path.basename(sourceMapOptions.sourceMapFullFilename));
  316.         }
  317.     }
  318.  
  319.     if (sourceMapOptions.sourceMapBasepath === undefined) {
  320.         sourceMapOptions.sourceMapBasepath = input ? path.dirname(input) : process.cwd();
  321.     }
  322.  
  323.     if (sourceMapOptions.sourceMapRootpath === undefined) {
  324.         var pathToMap = path.dirname(sourceMapFileInline ? output : sourceMapOptions.sourceMapFullFilename),
  325.             pathToInput = path.dirname(sourceMapOptions.sourceMapInputFilename);
  326.         sourceMapOptions.sourceMapRootpath = path.relative(pathToMap, pathToInput);
  327.     }
  328.  
  329.     if (! input) {
  330.         console.error("lessc: no input files");
  331.         console.error("");
  332.         printUsage();
  333.         currentErrorcode = 1;
  334.         return;
  335.     }
  336.  
  337.     var ensureDirectory = function (filepath) {
  338.         var dir = path.dirname(filepath),
  339.             cmd,
  340.             existsSync = fs.existsSync || path.existsSync;
  341.         if (!existsSync(dir)) {
  342.             if (mkdirp === undefined) {
  343.                 try {mkdirp = require('mkdirp');}
  344.                 catch(e) { mkdirp = null; }
  345.             }
  346.             cmd = mkdirp && mkdirp.sync || fs.mkdirSync;
  347.             cmd(dir);
  348.         }
  349.     };
  350.  
  351.     if (options.depends) {
  352.         if (!outputbase) {
  353.             console.log("option --depends requires an output path to be specified");
  354.             return;
  355.         }
  356.         process.stdout.write(outputbase + ": ");
  357.     }
  358.  
  359.     if (!sourceMapFileInline) {
  360.         var writeSourceMap = function(output, onDone) {
  361.             output = output || "";
  362.             var filename = sourceMapOptions.sourceMapFullFilename;
  363.             ensureDirectory(filename);
  364.             fs.writeFile(filename, output, 'utf8', function (err) {
  365.                 if (err) {
  366.                     var description = "Error: ";
  367.                     if (errno && errno.errno[err.errno]) {
  368.                         description += errno.errno[err.errno].description;
  369.                     } else {
  370.                         description += err.code + " " + err.message;
  371.                     }
  372.                     console.error('lessc: failed to create file ' + filename);
  373.                     console.error(description);
  374.                 } else {
  375.                     less.logger.info('lessc: wrote ' + filename);
  376.                 }
  377.                 onDone();
  378.             });
  379.         };
  380.     }
  381.  
  382.     var writeSourceMapIfNeeded = function(output, onDone) {
  383.         if (options.sourceMap && !sourceMapFileInline) {
  384.             writeSourceMap(output, onDone);
  385.         } else {
  386.             onDone();
  387.         }
  388.     };
  389.  
  390.     var writeOutput = function(output, result, onSuccess) {
  391.         if (output) {
  392.             ensureDirectory(output);
  393.             fs.writeFile(output, result.css, {encoding: 'utf8'}, function (err) {
  394.                 if (err) {
  395.                     var description = "Error: ";
  396.                     if (errno && errno.errno[err.errno]) {
  397.                         description += errno.errno[err.errno].description;
  398.                     } else {
  399.                         description += err.code + " " + err.message;
  400.                     }
  401.                     console.error('lessc: failed to create file ' + output);
  402.                     console.error(description);
  403.                 } else {
  404.                     less.logger.info('lessc: wrote ' + output);
  405.                     onSuccess();
  406.                 }
  407.             });
  408.         } else if (!options.depends) {
  409.             process.stdout.write(result.css);
  410.             onSuccess();
  411.         }
  412.     };
  413.  
  414.     var logDependencies = function(options, result) {
  415.         if (options.depends) {
  416.             var depends = "";
  417.             for (var i = 0; i < result.imports.length; i++) {
  418.                 depends += result.imports[i] + " ";
  419.             }
  420.             console.log(depends);
  421.         }
  422.     };
  423.  
  424.     var parseLessFile = function (e, data) {
  425.         if (e) {
  426.             console.error("lessc: " + e.message);
  427.             currentErrorcode = 1;
  428.             return;
  429.         }
  430.  
  431.         data = data.replace(/^\uFEFF/, '');
  432.  
  433.         options.paths = [path.dirname(input)].concat(options.paths);
  434.         options.filename = input;
  435.  
  436.         if (options.lint) {
  437.             options.sourceMap = false;
  438.         }
  439.         sourceMapOptions.sourceMapFileInline = sourceMapFileInline;
  440.  
  441.         if (options.sourceMap) {
  442.             options.sourceMap = sourceMapOptions;
  443.         }
  444.  
  445.         less.logger.addListener({
  446.             info: function(msg) {
  447.                 if (verbose) {
  448.                     console.log(msg);
  449.                 }
  450.             },
  451.             warn: function(msg) {
  452.                 // do not show warning if the silent option is used
  453.                 if (!silent) {
  454.                     console.warn(msg);
  455.                 }
  456.             },
  457.             error: function(msg) {
  458.                 console.error(msg);
  459.             }
  460.         });
  461.  
  462.         less.render(data, options)
  463.             .then(function(result) {
  464.                 if (!options.lint) {
  465.                     writeOutput(output, result, function() {
  466.                         writeSourceMapIfNeeded(result.map, function() {
  467.                             logDependencies(options, result);
  468.                         });
  469.                     });
  470.                 }
  471.             },
  472.             function(err) {
  473.                 less.writeError(err, options);
  474.                 currentErrorcode = 1;
  475.             });
  476.     };
  477.  
  478.     if (input != '-') {
  479.         fs.readFile(input, 'utf8', parseLessFile);
  480.     } else {
  481.         process.stdin.resume();
  482.         process.stdin.setEncoding('utf8');
  483.  
  484.         var buffer = '';
  485.         process.stdin.on('data', function(data) {
  486.             buffer += data;
  487.         });
  488.  
  489.         process.stdin.on('end', function() {
  490.             parseLessFile(false, buffer);
  491.         });
  492.     }
  493. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement