274 lines
7.5 KiB
JavaScript
274 lines
7.5 KiB
JavaScript
|
#!/usr/bin/env node
|
||
|
|
||
|
var path = require('path')
|
||
|
var fs = require('fs')
|
||
|
var chalk = require('chalk')
|
||
|
var mkdirp = require('mkdirp')
|
||
|
var postcss = require('postcss')
|
||
|
var rtlcss = require('../lib/rtlcss')
|
||
|
var configLoader = require('../lib/config-loader')
|
||
|
|
||
|
var input, output, directory, ext, config, currentErrorcode, arg
|
||
|
var args = process.argv.slice(2)
|
||
|
var shouldBreak = false
|
||
|
|
||
|
process.on('exit', function () { process.reallyExit(currentErrorcode) })
|
||
|
|
||
|
function printWarning () {
|
||
|
console.warn(chalk.yellow.apply(this, printWarning.arguments))
|
||
|
}
|
||
|
|
||
|
function printInfo () {
|
||
|
console.info(chalk.green.apply(this, printInfo.arguments))
|
||
|
}
|
||
|
|
||
|
function printError () {
|
||
|
console.error(chalk.red.apply(this, printError.arguments))
|
||
|
}
|
||
|
|
||
|
function printHelp () {
|
||
|
console.log('Usage: rtlcss [option option=parameter ...] [source] [destination]')
|
||
|
console.log('')
|
||
|
/*eslint-disable*/
|
||
|
var options = [
|
||
|
'Option ' , 'Description ',
|
||
|
'--------------', '----------------------------------------------',
|
||
|
'-h,--help' , 'Print help (this message) and exit.',
|
||
|
'-v,--version' , 'Print version number and exit.',
|
||
|
'-c,--config' , 'Path to configuration settings file.',
|
||
|
'- ,--stdin' , 'Read from stdin stream.',
|
||
|
'-d,--dirctory' , 'Process all *.css files from input directory (recursive).',
|
||
|
'-e,--ext' , 'Used with -d option to set the output files extension.\n\t\t Default: ".rtl.css".',
|
||
|
'-s,--silent' , 'Silent mode, no warnings or errors are printed.'
|
||
|
]
|
||
|
/*eslint-enable */
|
||
|
for (var x = 0; x < options.length; x++) {
|
||
|
console.log(options[x++], '\t', options[x])
|
||
|
}
|
||
|
console.log('')
|
||
|
console.log('*If no destination is specified, output will be written to the same input folder as {source}.rtl.{ext}')
|
||
|
console.log('')
|
||
|
printInfo('RTLCSS version: ' + require('../package.json').version)
|
||
|
printInfo('Report issues to: https://github.com/MohammadYounes/rtlcss/issues')
|
||
|
}
|
||
|
while ((arg = args.shift())) {
|
||
|
switch (arg) {
|
||
|
case '-h':
|
||
|
case '--help':
|
||
|
printHelp()
|
||
|
shouldBreak = true
|
||
|
break
|
||
|
case '-v':
|
||
|
case '--version':
|
||
|
printInfo('rtlcss version: ' + require('../package.json').version)
|
||
|
shouldBreak = true
|
||
|
break
|
||
|
case '-c':
|
||
|
case '--config':
|
||
|
arg = args.shift()
|
||
|
try {
|
||
|
config = configLoader.load(path.resolve(arg))
|
||
|
} catch (e) {
|
||
|
printError('rtlcss: invalid config file. ', e)
|
||
|
shouldBreak = true
|
||
|
currentErrorcode = 1
|
||
|
}
|
||
|
break
|
||
|
case '-d':
|
||
|
case '--directory':
|
||
|
directory = true
|
||
|
break
|
||
|
case '-e':
|
||
|
case '--ext':
|
||
|
ext = args.shift()
|
||
|
break
|
||
|
case '-s':
|
||
|
case '--silent':
|
||
|
console.log = console.info = console.warn = function () {}
|
||
|
break
|
||
|
case '-':
|
||
|
case '--stdin':
|
||
|
input = '-'
|
||
|
break
|
||
|
default:
|
||
|
if (arg[0] === '-') {
|
||
|
printError('rtlcss: unknown option. ' + arg)
|
||
|
shouldBreak = true
|
||
|
} else {
|
||
|
if (!input) {
|
||
|
input = path.resolve(arg)
|
||
|
} else if (!output) {
|
||
|
output = path.resolve(arg)
|
||
|
}
|
||
|
}
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!shouldBreak) {
|
||
|
if (!directory && !input) {
|
||
|
printError('rtlcss: no input file')
|
||
|
console.log('')
|
||
|
printHelp()
|
||
|
shouldBreak = true
|
||
|
}
|
||
|
if (!config && input !== '-') {
|
||
|
try {
|
||
|
var cwd = input
|
||
|
if (directory !== true) {
|
||
|
cwd = path.dirname(input)
|
||
|
}
|
||
|
config = configLoader.load(null, cwd)
|
||
|
} catch (e) {
|
||
|
printError('rtlcss: invalid config file. ', e)
|
||
|
currentErrorcode = 1
|
||
|
shouldBreak = true
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!shouldBreak) {
|
||
|
if (!output && input !== '-') {
|
||
|
if (directory !== true) {
|
||
|
output = path.extname(input) ? input.replace(/\.[^.]*$/, function (ext) { return '.rtl' + ext }) : input + '.rtl'
|
||
|
} else {
|
||
|
output = input
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var processCSSFile = function (e, data, outputName) {
|
||
|
if (e) {
|
||
|
printError('rtlcss: ' + e.message)
|
||
|
return
|
||
|
}
|
||
|
var result
|
||
|
var opt = { map: false }
|
||
|
if (input !== '-') {
|
||
|
opt.from = input
|
||
|
opt.to = output
|
||
|
}
|
||
|
if (!config) {
|
||
|
printWarning('rtlcss: Warning! No config present, using defaults.')
|
||
|
result = postcss([rtlcss]).process(data, opt)
|
||
|
} else {
|
||
|
if ('map' in config === true && input !== '-') {
|
||
|
opt.map = config.map
|
||
|
}
|
||
|
result = postcss([rtlcss.configure(config)]).process(data, opt)
|
||
|
}
|
||
|
|
||
|
if (output) {
|
||
|
var savePath = outputName
|
||
|
if (directory !== true) {
|
||
|
savePath = output
|
||
|
}
|
||
|
printInfo('Saving:', savePath)
|
||
|
fs.writeFile(savePath, result.css, 'utf8', function (err) { err && printError(err) })
|
||
|
if (result.map) {
|
||
|
fs.writeFile(savePath + '.map', result.map, 'utf8', function (err) { err && printError(err) })
|
||
|
}
|
||
|
} else {
|
||
|
process.stdout.write(result.css + '\n')
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var walk = function (dir, done) {
|
||
|
fs.readdir(dir, function (error, list) {
|
||
|
if (error) {
|
||
|
return done(error)
|
||
|
}
|
||
|
var i = 0
|
||
|
;(function next () {
|
||
|
var file = list[i++]
|
||
|
if (!file) {
|
||
|
return done(null)
|
||
|
}
|
||
|
file = dir + path.sep + file
|
||
|
fs.stat(file, function (err, stat) {
|
||
|
if (err) {
|
||
|
printError(err)
|
||
|
} else if (stat && stat.isDirectory()) {
|
||
|
walk(file, function (err) {
|
||
|
if (err) {
|
||
|
printError(err)
|
||
|
} else {
|
||
|
next()
|
||
|
}
|
||
|
})
|
||
|
} else {
|
||
|
// process only *.css
|
||
|
if (/\.(css)$/.test(file)) {
|
||
|
// compute output directory
|
||
|
var relativePath = path.relative(input, file).split(path.sep)
|
||
|
relativePath.pop()
|
||
|
relativePath.push(path.basename(file).replace('.css', ext || '.rtl.css'))
|
||
|
|
||
|
// set rtl file name
|
||
|
var rtlFile = path.join(output, relativePath.join(path.sep))
|
||
|
|
||
|
// create output directory if it does not exist
|
||
|
var dirName = path.dirname(rtlFile)
|
||
|
if (!fs.existsSync(dirName)) {
|
||
|
mkdirp.sync(dirName)
|
||
|
}
|
||
|
|
||
|
// read and process the file.
|
||
|
fs.readFile(file, 'utf8', function (e, data) {
|
||
|
try {
|
||
|
processCSSFile(e, data, rtlFile)
|
||
|
} catch (e) {
|
||
|
printError('rtlcss: error processing file', file)
|
||
|
printError(e)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
next()
|
||
|
}
|
||
|
})
|
||
|
})()
|
||
|
})
|
||
|
}
|
||
|
|
||
|
if (input !== '-') {
|
||
|
if (directory !== true) {
|
||
|
fs.stat(input, function (error, stat) {
|
||
|
if (error) {
|
||
|
printError(error)
|
||
|
} else if (stat && stat.isDirectory()) {
|
||
|
printError('rtlcss: Input expected to be a file, use -d option to process a directory.')
|
||
|
} else {
|
||
|
fs.readFile(input, 'utf8', function (e, data) {
|
||
|
try {
|
||
|
processCSSFile(e, data)
|
||
|
} catch (e) {
|
||
|
printError('rtlcss: error processing file', input)
|
||
|
printError(e)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
})
|
||
|
} else {
|
||
|
walk(input, function (error) {
|
||
|
if (error) {
|
||
|
printError('rtlcss: ' + error)
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
} else {
|
||
|
process.stdin.resume()
|
||
|
process.stdin.setEncoding('utf8')
|
||
|
|
||
|
var buffer = ''
|
||
|
process.stdin.on('data', function (data) {
|
||
|
buffer += data
|
||
|
})
|
||
|
process.on('SIGINT', function () {
|
||
|
processCSSFile(false, buffer)
|
||
|
process.exit()
|
||
|
})
|
||
|
process.stdin.on('end', function () {
|
||
|
processCSSFile(false, buffer)
|
||
|
})
|
||
|
}
|
||
|
}
|