You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							847 lines
						
					
					
						
							19 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							847 lines
						
					
					
						
							19 KiB
						
					
					
				
								#!/usr/bin/env node
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Module dependencies.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var fs = require('fs')
							 | 
						|
								  , stylus = require('../lib/stylus')
							 | 
						|
								  , basename = require('path').basename
							 | 
						|
								  , dirname = require('path').dirname
							 | 
						|
								  , extname = require('path').extname
							 | 
						|
								  , resolve = require('path').resolve
							 | 
						|
								  , join = require('path').join
							 | 
						|
								  , isWindows = process.platform === 'win32'
							 | 
						|
								  , semver = require('semver')
							 | 
						|
								  , mkdirSync = semver.satisfies(process.version, '>=10.12.0') ? fs.mkdirSync : require('mkdirp').sync;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Arguments.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var args = process.argv.slice(2);
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Compare flag.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var compare = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Compress flag.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var compress = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * CSS conversion flag.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var convertCSS = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Line numbers flag.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var linenos = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * CSS class prefix.
							 | 
						|
								 */
							 | 
						|
								var prefix = '';
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Print to stdout flag.
							 | 
						|
								 */
							 | 
						|
								var print = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Firebug flag
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var firebug = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Quiet flag
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var quiet = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Sourcemap flag
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var sourcemap = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Files to processes.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var files = [];
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Import paths.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var paths = [];
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Destination directory.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var dest;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Watcher hash.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var watchers;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Enable REPL.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var interactive;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Plugins.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var plugins = [];
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Optional url() function.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var urlFunction = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Include CSS on import.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var includeCSS = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Set file imports.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var imports = [];
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Resolve relative urls
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var resolveURL = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Disable cache.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var disableCache = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Display dependencies flag.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var deps = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Hoist at-rules.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var hoist = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Specify custom file extension.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var ext = '.css';
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Usage docs.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var usage = [
							 | 
						|
								    ''
							 | 
						|
								  , '  Usage: stylus [options] [command] [< in [> out]]'
							 | 
						|
								  , '                [file|dir ...]'
							 | 
						|
								  , ''
							 | 
						|
								  , '  Commands:'
							 | 
						|
								  , ''
							 | 
						|
								  , '    help [<type>:]<prop> Opens help info at MDN for <prop> in'
							 | 
						|
								  , '                         your default browser. Optionally'
							 | 
						|
								  , '                         searches other resources of <type>:'
							 | 
						|
								  , '                         safari opera w3c ms caniuse quirksmode'
							 | 
						|
								  , ''
							 | 
						|
								  , '  Options:'
							 | 
						|
								  , ''
							 | 
						|
								  , '    -i, --interactive       Start interactive REPL'
							 | 
						|
								  , '    -u, --use <path>        Utilize the Stylus plugin at <path>'
							 | 
						|
								  , '    -U, --inline            Utilize image inlining via data URI support'
							 | 
						|
								  , '    -w, --watch             Watch file(s) for changes and re-compile'
							 | 
						|
								  , '    -o, --out <dir>         Output to <dir> when passing files'
							 | 
						|
								  , '    -C, --css <src> [dest]  Convert CSS input to Stylus'
							 | 
						|
								  , '    -I, --include <path>    Add <path> to lookup paths'
							 | 
						|
								  , '    -c, --compress          Compress CSS output'
							 | 
						|
								  , '    -d, --compare           Display input along with output'
							 | 
						|
								  , '    -f, --firebug           Emits debug infos in the generated CSS that'
							 | 
						|
								  , '                            can be used by the FireStylus Firebug plugin'
							 | 
						|
									, '    -l, --line-numbers      Emits comments in the generated CSS'
							 | 
						|
								  , '                            indicating the corresponding Stylus line'
							 | 
						|
								  , '    -m, --sourcemap         Generates a sourcemap in sourcemaps v3 format'
							 | 
						|
									, '    -q, --quiet     				 Less noisy output'
							 | 
						|
								  , '    --sourcemap-inline      Inlines sourcemap with full source text in base64 format'
							 | 
						|
								  , '    --sourcemap-root <url>  "sourceRoot" property of the generated sourcemap'
							 | 
						|
								  , '    --sourcemap-base <path> Base <path> from which sourcemap and all sources are relative'
							 | 
						|
								  , '    -P, --prefix [prefix]   prefix all css classes'
							 | 
						|
								  , '    -p, --print             Print out the compiled CSS'
							 | 
						|
								  , '    --import <file>         Import stylus <file>'
							 | 
						|
								  , '    --include-css           Include regular CSS on @import'
							 | 
						|
								  , '	 --ext			 Specify custom file extension for compiled file, default .css'	
							 | 
						|
								  , '    -D, --deps              Display dependencies of the compiled file'
							 | 
						|
								  , '    --disable-cache         Disable caching'
							 | 
						|
								  , '    --hoist-atrules         Move @import and @charset to the top'
							 | 
						|
								  , '    -r, --resolve-url       Resolve relative urls inside imports'
							 | 
						|
								  , '    --resolve-url-nocheck   Like --resolve-url but without file existence check'
							 | 
						|
								  , '    -V, --version           Display the version of Stylus'
							 | 
						|
								  , '    -h, --help              Display help information'
							 | 
						|
								  , ''
							 | 
						|
								].join('\n');
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Handle arguments.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var arg;
							 | 
						|
								while (args.length) {
							 | 
						|
								  arg = args.shift();
							 | 
						|
								  switch (arg) {
							 | 
						|
								    case '-h':
							 | 
						|
								    case '--help':
							 | 
						|
								      console.error(usage);
							 | 
						|
								      return;
							 | 
						|
								    case '-d':
							 | 
						|
								    case '--compare':
							 | 
						|
								      compare = true;
							 | 
						|
								      break;
							 | 
						|
								    case '-c':
							 | 
						|
								    case '--compress':
							 | 
						|
								      compress = true;
							 | 
						|
								      break;
							 | 
						|
								    case '-C':
							 | 
						|
								    case '--css':
							 | 
						|
								      convertCSS = true;
							 | 
						|
								      break;
							 | 
						|
								    case '-f':
							 | 
						|
								    case '--firebug':
							 | 
						|
								      firebug = true;
							 | 
						|
								      break;
							 | 
						|
								    case '-l':
							 | 
						|
								    case '--line-numbers':
							 | 
						|
								      linenos = true;
							 | 
						|
								      break;
							 | 
						|
								    case '-m':
							 | 
						|
								    case '--sourcemap':
							 | 
						|
								      sourcemap = {};
							 | 
						|
								      break;
							 | 
						|
										case '-q':
							 | 
						|
										case '--quiet':
							 | 
						|
											quiet = true;
							 | 
						|
											break;
							 | 
						|
								    case '--sourcemap-inline':
							 | 
						|
								      sourcemap = sourcemap || {};
							 | 
						|
								      sourcemap.inline = true;
							 | 
						|
								      break;
							 | 
						|
								    case '--sourcemap-root':
							 | 
						|
								      var url = args.shift();
							 | 
						|
								      if (!url) throw new Error('--sourcemap-root <url> required');
							 | 
						|
								      sourcemap = sourcemap || {};
							 | 
						|
								      sourcemap.sourceRoot = url;
							 | 
						|
								      break;
							 | 
						|
								    case '--sourcemap-base':
							 | 
						|
								      var path = args.shift();
							 | 
						|
								      if (!path) throw new Error('--sourcemap-base <path> required');
							 | 
						|
								      sourcemap = sourcemap || {};
							 | 
						|
								      sourcemap.basePath = path;
							 | 
						|
								      break;
							 | 
						|
								    case '-P':
							 | 
						|
								    case '--prefix':
							 | 
						|
								      prefix = args.shift();
							 | 
						|
								      if (!prefix) throw new Error('--prefix <prefix> required');
							 | 
						|
								      break;
							 | 
						|
								    case '-p':
							 | 
						|
								    case '--print':
							 | 
						|
								      print = true;
							 | 
						|
								      break;
							 | 
						|
								    case '-V':
							 | 
						|
								    case '--version':
							 | 
						|
								      console.log(stylus.version);
							 | 
						|
								      return;
							 | 
						|
								    case '-o':
							 | 
						|
								    case '--out':
							 | 
						|
								      dest = args.shift();
							 | 
						|
								      if (!dest) throw new Error('--out <dir> required');
							 | 
						|
								      break;
							 | 
						|
								    case 'help':
							 | 
						|
								      var name = args.shift()
							 | 
						|
								        , browser = name.split(':');
							 | 
						|
								      if (browser.length > 1) {
							 | 
						|
								        name = [].slice.call(browser, 1).join(':');
							 | 
						|
								        browser = browser[0];
							 | 
						|
								      } else {
							 | 
						|
								        name = browser[0];
							 | 
						|
								        browser = '';
							 | 
						|
								      }
							 | 
						|
								      if (!name) throw new Error('help <property> required');
							 | 
						|
								      help(name);
							 | 
						|
								      break;
							 | 
						|
								    case '--include-css':
							 | 
						|
								      includeCSS = true;
							 | 
						|
								      break;
							 | 
						|
								    case '--ext':
							 | 
						|
								      ext = args.shift();
							 | 
						|
								      if (!ext) throw new Error('--ext <ext> required');
							 | 
						|
								      break;
							 | 
						|
								    case '--disable-cache':
							 | 
						|
								      disableCache = true;
							 | 
						|
								      break;
							 | 
						|
								    case '--hoist-atrules':
							 | 
						|
								      hoist = true;
							 | 
						|
								      break;
							 | 
						|
								    case '-i':
							 | 
						|
								    case '--repl':
							 | 
						|
								    case '--interactive':
							 | 
						|
								      interactive = true;
							 | 
						|
								      break;
							 | 
						|
								    case '-I':
							 | 
						|
								    case '--include':
							 | 
						|
								      var path = args.shift();
							 | 
						|
								      if (!path) throw new Error('--include <path> required');
							 | 
						|
								      paths.push(path);
							 | 
						|
								      break;
							 | 
						|
								    case '-w':
							 | 
						|
								    case '--watch':
							 | 
						|
								      watchers = {};
							 | 
						|
								      break;
							 | 
						|
								    case '-U':
							 | 
						|
								    case '--inline':
							 | 
						|
								      args.unshift('--use', 'url');
							 | 
						|
								      break;
							 | 
						|
								    case '-u':
							 | 
						|
								    case '--use':
							 | 
						|
								      var options;
							 | 
						|
								      var path = args.shift();
							 | 
						|
								      if (!path) throw new Error('--use <path> required');
							 | 
						|
								
							 | 
						|
								      // options
							 | 
						|
								      if ('--with' == args[0]) {
							 | 
						|
								        args.shift();
							 | 
						|
								        options = args.shift();
							 | 
						|
								        if (!options) throw new Error('--with <options> required');
							 | 
						|
								        options = eval('(' + options + ')');
							 | 
						|
								      }
							 | 
						|
								
							 | 
						|
								      // url support
							 | 
						|
								      if ('url' == path) {
							 | 
						|
								        urlFunction = options || {};
							 | 
						|
								      } else {
							 | 
						|
								        paths.push(dirname(path));
							 | 
						|
								        plugins.push({ path: path, options: options });
							 | 
						|
								      }
							 | 
						|
								      break;
							 | 
						|
								    case '--import':
							 | 
						|
								      var file = args.shift();
							 | 
						|
								      if (!file) throw new Error('--import <file> required');
							 | 
						|
								      imports.push(file);
							 | 
						|
								      break;
							 | 
						|
								    case '-r':
							 | 
						|
								    case '--resolve-url':
							 | 
						|
								      resolveURL = {};
							 | 
						|
								      break;
							 | 
						|
								    case '--resolve-url-nocheck':
							 | 
						|
								      resolveURL = { nocheck: true };
							 | 
						|
								      break;
							 | 
						|
								    case '-D':
							 | 
						|
								    case '--deps':
							 | 
						|
								      deps = true;
							 | 
						|
								      break;
							 | 
						|
								    default:
							 | 
						|
								      files.push(arg);
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// if --watch is used, assume we are
							 | 
						|
								// not working with stdio
							 | 
						|
								
							 | 
						|
								if (watchers && !files.length) {
							 | 
						|
								  files = fs.readdirSync(process.cwd())
							 | 
						|
								    .filter(function(file){
							 | 
						|
								    return file.match(/\.styl$/);
							 | 
						|
								  });
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// --sourcemap flag is not working with stdio
							 | 
						|
								if (sourcemap && !files.length) sourcemap = false;
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Open the default browser to the CSS property `name`.
							 | 
						|
								 *
							 | 
						|
								 * @param {String} name
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function help(name) {
							 | 
						|
								  var url
							 | 
						|
								    , exec = require('child_process').exec
							 | 
						|
								    , command;
							 | 
						|
								
							 | 
						|
								  name = encodeURIComponent(name);
							 | 
						|
								
							 | 
						|
								  switch (browser) {
							 | 
						|
								    case 'safari':
							 | 
						|
								    case 'webkit':
							 | 
						|
								      url = 'https://developer.apple.com/library/safari/search/?q=' + name;
							 | 
						|
								      break;
							 | 
						|
								    case 'opera':
							 | 
						|
								      url = 'http://dev.opera.com/search/?term=' + name;
							 | 
						|
								      break;
							 | 
						|
								    case 'w3c':
							 | 
						|
								      url = 'http://www.google.com/search?q=site%3Awww.w3.org%2FTR+' + name;
							 | 
						|
								      break;
							 | 
						|
								    case 'ms':
							 | 
						|
								      url = 'http://social.msdn.microsoft.com/search/en-US/ie?query=' + name + '&refinement=59%2c61';
							 | 
						|
								      break;
							 | 
						|
								    case 'caniuse':
							 | 
						|
								      url = 'http://caniuse.com/#search=' + name;
							 | 
						|
								      break;
							 | 
						|
								    case 'quirksmode':
							 | 
						|
								      url = 'http://www.google.com/search?q=site%3Awww.quirksmode.org+' + name;
							 | 
						|
								      break;
							 | 
						|
								    default:
							 | 
						|
								      url = 'https://developer.mozilla.org/en/CSS/' + name;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  switch (process.platform) {
							 | 
						|
								    case 'linux': command = 'x-www-browser'; break;
							 | 
						|
								    default: command = 'open';
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  exec(command + ' "' + url + '"', function(){
							 | 
						|
								    process.exit(0);
							 | 
						|
								  });
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								// Compilation options
							 | 
						|
								
							 | 
						|
								if (files.length > 1 && isCSS(dest)) {
							 | 
						|
								  dest = dirname(dest);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								var options = {
							 | 
						|
								    filename: 'stdin'
							 | 
						|
								  , compress: compress
							 | 
						|
								  , firebug: firebug
							 | 
						|
								  , linenos: linenos
							 | 
						|
								  , sourcemap: sourcemap
							 | 
						|
								  , paths: [process.cwd()].concat(paths)
							 | 
						|
								  , prefix: prefix
							 | 
						|
								  , dest: dest
							 | 
						|
								  , 'hoist atrules': hoist
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								// Buffer stdin
							 | 
						|
								
							 | 
						|
								var str = '';
							 | 
						|
								
							 | 
						|
								// Convert CSS to Stylus
							 | 
						|
								
							 | 
						|
								if (convertCSS) {
							 | 
						|
								    switch (files.length) {
							 | 
						|
								    case 2:
							 | 
						|
								      compileCSSFile(files[0], files[1]);
							 | 
						|
								      break;
							 | 
						|
								    case 1:
							 | 
						|
								      var file = files[0];
							 | 
						|
								      compileCSSFile(file, join(dirname(file), basename(file, extname(file))) + '.styl');
							 | 
						|
								      break;
							 | 
						|
								    default:
							 | 
						|
								      var stdin = process.openStdin();
							 | 
						|
								      stdin.setEncoding('utf8');
							 | 
						|
								      stdin.on('data', function(chunk){ str += chunk; });
							 | 
						|
								      stdin.on('end', function(){
							 | 
						|
								        var out = stylus.convertCSS(str);
							 | 
						|
								        console.log(out);
							 | 
						|
								      });
							 | 
						|
								  }
							 | 
						|
								} else if (interactive) {
							 | 
						|
								  repl();
							 | 
						|
								} else if (deps) {
							 | 
						|
								  // if --deps is used, just display list of the dependencies
							 | 
						|
								  // not working with stdio and dirs
							 | 
						|
								  displayDeps();
							 | 
						|
								} else {
							 | 
						|
								  if (files.length) {
							 | 
						|
								    compileFiles(files);
							 | 
						|
								  } else {
							 | 
						|
								    compileStdio();
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Start Stylus REPL.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function repl() {
							 | 
						|
								  var options = { cache: false, filename: 'stdin', imports: [join(__dirname, '..', 'lib', 'functions')] }
							 | 
						|
								    , parser = new stylus.Parser('', options)
							 | 
						|
								    , evaluator = new stylus.Evaluator(parser.parse(), options)
							 | 
						|
								    , rl = require('readline')
							 | 
						|
								    , repl = rl.createInterface(process.stdin, process.stdout, autocomplete)
							 | 
						|
								    , global = evaluator.global.scope;
							 | 
						|
								
							 | 
						|
								  // expose BIFs
							 | 
						|
								  evaluator.evaluate();
							 | 
						|
								
							 | 
						|
								  // readline
							 | 
						|
								  repl.setPrompt('> ');
							 | 
						|
								  repl.prompt();
							 | 
						|
								
							 | 
						|
								  // HACK: flat-list auto-complete
							 | 
						|
								  function autocomplete(line){
							 | 
						|
								    var out = process.stdout
							 | 
						|
								      , keys = Object.keys(global.locals)
							 | 
						|
								      , len = keys.length
							 | 
						|
								      , words = line.split(/\s+/)
							 | 
						|
								      , word = words.pop()
							 | 
						|
								      , names = []
							 | 
						|
								      , name
							 | 
						|
								      , node
							 | 
						|
								      , key;
							 | 
						|
								
							 | 
						|
								    // find words that match
							 | 
						|
								    for (var i = 0; i < len; ++i) {
							 | 
						|
								      key = keys[i];
							 | 
						|
								      if (0 == key.indexOf(word)) {
							 | 
						|
								        node = global.lookup(key);
							 | 
						|
								        switch (node.nodeName) {
							 | 
						|
								          case 'function':
							 | 
						|
								            names.push(node.toString());
							 | 
						|
								            break;
							 | 
						|
								          default:
							 | 
						|
								            names.push(key);
							 | 
						|
								        }
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    return [names, line];
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  repl.on('line', function(line){
							 | 
						|
								    if (!line.trim().length) return repl.prompt();
							 | 
						|
								    parser = new stylus.Parser(line, options);
							 | 
						|
								    parser.state.push('expression');
							 | 
						|
								    evaluator.return = true;
							 | 
						|
								    try {
							 | 
						|
								      var expr = parser.parse();
							 | 
						|
								      evaluator.root = expr;
							 | 
						|
								      var ret = evaluator.evaluate();
							 | 
						|
								      var node;
							 | 
						|
								      while (node = ret.nodes.pop()) {
							 | 
						|
								        if (!node.suppress) {
							 | 
						|
								          var str = node.toString();
							 | 
						|
								          if ('(' == str[0]) str = str.replace(/^\(|\)$/g, '');
							 | 
						|
								          console.log('\033[90m=> \033[0m' + highlight(str));
							 | 
						|
								          break;
							 | 
						|
								        }
							 | 
						|
								      }
							 | 
						|
								      repl.prompt();
							 | 
						|
								    } catch (err) {
							 | 
						|
								      console.error('\033[31merror: %s\033[0m', err.message || err.stack);
							 | 
						|
								      repl.prompt();
							 | 
						|
								    }
							 | 
						|
								  });
							 | 
						|
								
							 | 
						|
								  repl.on('SIGINT', function(){
							 | 
						|
								    console.log();
							 | 
						|
								    process.exit(0);
							 | 
						|
								  });
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Highlight the given string of Stylus.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function highlight(str) {
							 | 
						|
								  return str
							 | 
						|
								    .replace(/(#)?(\d+(\.\d+)?)/g, function($0, $1, $2){
							 | 
						|
								      return $1 ? $0 : '\033[36m' + $2 + '\033[0m';
							 | 
						|
								    })
							 | 
						|
								    .replace(/(#[\da-fA-F]+)/g, '\033[33m$1\033[0m')
							 | 
						|
								    .replace(/('.*?'|".*?")/g, '\033[32m$1\033[0m');
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Convert a CSS file to a Styl file
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function compileCSSFile(file, fileOut) {
							 | 
						|
								  fs.stat(file, function(err, stat){
							 | 
						|
								    if (err) throw err;
							 | 
						|
								    if (stat.isFile()) {
							 | 
						|
								      fs.readFile(file, 'utf8', function(err, str){
							 | 
						|
								        if (err) throw err;
							 | 
						|
								        var styl = stylus.convertCSS(str);
							 | 
						|
								        fs.writeFile(fileOut, styl, function(err){
							 | 
						|
								         if (err) throw err;
							 | 
						|
								        });
							 | 
						|
								      });
							 | 
						|
								    }
							 | 
						|
								  });
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Compile with stdio.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function compileStdio() {
							 | 
						|
								  process.stdin.setEncoding('utf8');
							 | 
						|
								  process.stdin.on('data', function(chunk){ str += chunk; });
							 | 
						|
								  process.stdin.on('end', function(){
							 | 
						|
								    // Compile to css
							 | 
						|
								    var style = stylus(str, options);
							 | 
						|
								    if (includeCSS) style.set('include css', true);
							 | 
						|
								    if (disableCache) style.set('cache', false);
							 | 
						|
								    usePlugins(style);
							 | 
						|
								    importFiles(style);
							 | 
						|
								    style.render(function(err, css){
							 | 
						|
								      if (err) throw err;
							 | 
						|
								      if (compare) {
							 | 
						|
								        console.log('\n\x1b[1mInput:\x1b[0m');
							 | 
						|
								        console.log(str);
							 | 
						|
								        console.log('\n\x1b[1mOutput:\x1b[0m');
							 | 
						|
								      }
							 | 
						|
								      console.log(css);
							 | 
						|
								      if (compare) console.log();
							 | 
						|
								    });
							 | 
						|
								  }).resume();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Compile the given files.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function compileFiles(files) {
							 | 
						|
								  files.forEach(compileFile);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Display dependencies of the compiled files.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function displayDeps() {
							 | 
						|
								  files.forEach(function(file){
							 | 
						|
								    // ensure file exists
							 | 
						|
								    fs.stat(file, function(err, stat){
							 | 
						|
								      if (err) throw err;
							 | 
						|
								      fs.readFile(file, 'utf8', function(err, str){
							 | 
						|
								        if (err) throw err;
							 | 
						|
								        options.filename = file;
							 | 
						|
								        var style = stylus(str, options);
							 | 
						|
								
							 | 
						|
								        usePlugins(style);
							 | 
						|
								        importFiles(style);
							 | 
						|
								        console.log(style.deps().join('\n'));
							 | 
						|
								      });
							 | 
						|
								    });
							 | 
						|
								  });
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Compile the given file.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function compileFile(file) {
							 | 
						|
								  // ensure file exists
							 | 
						|
								  fs.stat(file, function(err, stat){
							 | 
						|
								    if (err) throw err;
							 | 
						|
								    // file
							 | 
						|
								    if (stat.isFile()) {
							 | 
						|
								      fs.readFile(file, 'utf8', function(err, str){
							 | 
						|
								        if (err) throw err;
							 | 
						|
								        options.filename = file;
							 | 
						|
								        options._imports = [];
							 | 
						|
								        var style = stylus(str, options);
							 | 
						|
								        if (includeCSS) style.set('include css', true);
							 | 
						|
								        if (disableCache) style.set('cache', false);
							 | 
						|
								        if (sourcemap) style.set('sourcemap', sourcemap);
							 | 
						|
								
							 | 
						|
								        usePlugins(style);
							 | 
						|
								        importFiles(style);
							 | 
						|
								        style.render(function(err, css){
							 | 
						|
								          watchImports(file, options._imports);
							 | 
						|
								          if (err) {
							 | 
						|
								            if (watchers) {
							 | 
						|
								              console.error(err.stack || err.message);
							 | 
						|
								            } else {
							 | 
						|
								              throw err;
							 | 
						|
								            }
							 | 
						|
								          } else {
							 | 
						|
								            writeFile(file, css);
							 | 
						|
								            // write sourcemap
							 | 
						|
								            if (sourcemap && !sourcemap.inline) {
							 | 
						|
								              writeSourcemap(file, style.sourcemap);
							 | 
						|
								            }
							 | 
						|
								          }
							 | 
						|
								        });
							 | 
						|
								      });
							 | 
						|
								    // directory
							 | 
						|
								    } else if (stat.isDirectory()) {
							 | 
						|
								      fs.readdir(file, function(err, files){
							 | 
						|
								        if (err) throw err;
							 | 
						|
								        files.filter(function(path){
							 | 
						|
								          return path.match(/\.styl$/);
							 | 
						|
								        }).map(function(path){
							 | 
						|
								          return join(file, path);
							 | 
						|
								        }).forEach(compileFile);
							 | 
						|
								      });
							 | 
						|
								    }
							 | 
						|
								  });
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Write the given CSS output.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function createPath(file, sourceMap) {
							 | 
						|
								  var out;
							 | 
						|
								  if (files.length === 1 && isCSS(dest)) {
							 | 
						|
								    return [dest, sourceMap ? '.map' : ''].join('');
							 | 
						|
								  }
							 | 
						|
								  // --out support
							 | 
						|
								  out = [basename(file, extname(file)), sourceMap ? ext + '.map' : ext].join('');
							 | 
						|
								  return dest
							 | 
						|
								    ? join(dest, out)
							 | 
						|
								    : join(dirname(file), out);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Check if the given path is a CSS file.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function isCSS(file) {
							 | 
						|
								  return file && '.css' === extname(file);
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								function writeFile(file, css) {
							 | 
						|
								  // --print support
							 | 
						|
								  if (print) return process.stdout.write(css);
							 | 
						|
								  var path = createPath(file);
							 | 
						|
								
							 | 
						|
								  mkdirSync(dirname(path), { recursive: true })
							 | 
						|
								
							 | 
						|
								  fs.writeFile(path, css, function(err){
							 | 
						|
								    if (err) throw err;
							 | 
						|
								    console.log('  \033[90mcompiled\033[0m %s', path);
							 | 
						|
								    // --watch support
							 | 
						|
								    watch(file, file);
							 | 
						|
								  });
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								* Write the given sourcemap.
							 | 
						|
								*/
							 | 
						|
								
							 | 
						|
								function writeSourcemap(file, sourcemap) {
							 | 
						|
								  var path = createPath(file, true);
							 | 
						|
								
							 | 
						|
								  mkdirSync(dirname(path), { recursive: true })
							 | 
						|
								
							 | 
						|
								  fs.writeFile(path, JSON.stringify(sourcemap), function(err){
							 | 
						|
								    if (err) throw err;
							 | 
						|
								    // don't output log message if --print is present
							 | 
						|
								    if (!print) console.log('  \033[90mgenerated\033[0m %s', path);
							 | 
						|
								  });
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Watch the given `file` and recompiling `rootFile` when modified.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function watch(file, rootFile) {
							 | 
						|
								  // not watching
							 | 
						|
								  if (!watchers) return;
							 | 
						|
								
							 | 
						|
								  // already watched
							 | 
						|
								  if (watchers[file]) {
							 | 
						|
								    watchers[file][rootFile] = true;
							 | 
						|
								    return;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  // watch the file itself
							 | 
						|
								  watchers[file] = {};
							 | 
						|
								  watchers[file][rootFile] = true;
							 | 
						|
								  if (print) {
							 | 
						|
								    console.error('Stylus CLI Error: Watch and print cannot be used together');
							 | 
						|
								    process.exit(1);
							 | 
						|
								  }
							 | 
						|
								  if(!quiet){
							 | 
						|
										console.log('  \033[90mwatching\033[0m %s', file);
							 | 
						|
									}
							 | 
						|
								  // if is windows use fs.watch api instead
							 | 
						|
								  // TODO: remove watchFile when fs.watch() works on osx etc
							 | 
						|
								  if (isWindows) {
							 | 
						|
								    fs.watch(file, compile);
							 | 
						|
								  } else {
							 | 
						|
								    fs.watchFile(file, { interval: 300 }, function(curr, prev) {
							 | 
						|
								      if (curr.mtime > prev.mtime) compile();
							 | 
						|
								    });
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  function compile() {
							 | 
						|
								    for (var rootFile in watchers[file]) {
							 | 
						|
								      compileFile(rootFile);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Watch `imports`, re-compiling `file` when they change.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function watchImports(file, imports) {
							 | 
						|
								  imports.forEach(function(imported){
							 | 
						|
								    if (!imported.path) return;
							 | 
						|
								    watch(imported.path, file);
							 | 
						|
								  });
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Utilize plugins.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function usePlugins(style) {
							 | 
						|
								  plugins.forEach(function(plugin){
							 | 
						|
								    var path = plugin.path;
							 | 
						|
								    var options = plugin.options;
							 | 
						|
								    fn = require(/^\.+\//.test(path) ? resolve(path) : path);
							 | 
						|
								    if ('function' != typeof fn) {
							 | 
						|
								      throw new Error('plugin ' + path + ' does not export a function');
							 | 
						|
								    }
							 | 
						|
								    style.use(fn(options));
							 | 
						|
								  });
							 | 
						|
								
							 | 
						|
								  if (urlFunction) {
							 | 
						|
								    style.define('url', stylus.url(urlFunction));
							 | 
						|
								  } else if (resolveURL) {
							 | 
						|
								    style.define('url', stylus.resolver(resolveURL));
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								/**
							 | 
						|
								 * Imports the indicated files.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								function importFiles(style) {
							 | 
						|
								  imports.forEach(function(file) {
							 | 
						|
								    style.import(file);
							 | 
						|
								  });
							 | 
						|
								}
							 |