fs = require 'fs'
path = require 'path'
Kal = require './kal'This module defines the command line kal utility.
fs = require 'fs'
path = require 'path'
Kal = require './kal'Some messages are written to stderr in this module.
function warn(line)
process.stderr.write line + '\n'This utility function checks if a file is “hidden” by the operating system.
function hidden(file)
/^\.|~$/.test fileparseOptions parses the command line switches.
function parseOptions()
options = {}
for arg in process.argv
if arg[0] is '-' and arg[1] isnt '-'
options.help = yes if 'h' in arg
options.tokens = yes if 't' in arg
options.javascript = yes if 'j' in arg
options.bare = yes if 'b' in arg
options.version = yes if 'v' in arg
options.minify = yes if 'm' in arg
else if arg[0] is '-' and arg[1] is '-'
options.help = yes if arg is '--help'
options.tokens = yes if arg is '--tokens'
options.javascript = yes if arg is '--javascript'
options.bare = yes if arg is '--bare'
options.version = yes if arg is '--version'
options.minify = yes if arg is '--minify'The -o option has an argument (the output directory).
if '-o' in process.argv
index = process.argv.indexOf '-o'
else if '--output' in process.argv
index = process.argv.indexOf '--output'
options.output = process.argv[index + 1] if index isnt -1The remaining arguments are assumed to be input file names. We loop through the array and ignore switches and the output directory (if any).
inputs = []
for arg in process.argv.slice(2)
if arg[0] is '-' or arg is options.outputSet the help flag if the user passed input files (or extra arguments) that were followed by other switches like kal -o output_dir some_file -j. This is considered invalid.
options.help = yes if inputs.length isnt 0
inputs = []Otherwise, add the argument to the list of input files.
else
inputs.push arg
options._ = inputs
return optionsexistsSync is used to retain compatibility between node.js versions.
existsSync = fs.existsSync or path.existsSyncfunction run()Parse the command line options and print the version/usage if necessary.
options = parseOptions()
return version() if options.version
return usage() if options.helpCheck the output path (if specified) and make sure it is valid.
if options.output exists and not existsSync(options.output)
warn('output path does not exist!')
return usage()If no input files are specified, start the interactive shell.
return require('./interactive') if options._.length is 0Let scripts know we are running in kal not node.
process.argv[0] = 'kal'
process.execPath = require.main.filenameConstruct the compile_options argument for Kal.compile or Kal.eval.
compile_options =
show_tokens: options.tokens
bare: options.bare
show_js: options.javascriptIf an output argument was specified, we are writing JavaScript files to an output directory.
if options.output existsAttempt to load uglify-js if the user wants to minify files. This is not listed as a dependency so the user needs it installed globally or manually.
try
require('uglify-js') if options.minify
catch
warn 'error: uglify-js must be installed to use the --minify option'
process.exit(3)If the user just specified one directory, assume they just want all the files in it. Compile the list of files with the given options.
if options._.length is 1 and fs.statSync(options._[0]).isDirectory()
files = [path.join(options._[0],file) for file in fs.readdirSync(options._[0])]
compile_files files, options.output, compile_options, options.minify
else
compile_files options._, options.output, compile_options, options.minify
elseIf no output was specified, just run the script using eval.
for filename in options._
compile_options.literate = path.extname(filename) in ['.litkal', '.md']
Kal.eval fs.readFileSync(filename), compile_optionsThe scripts/kal loader calls this entry point.
exports.run = runThis function recursively compiles a list of files/directories into output_dir.
function compile_files(filenames, output_dir, options, minify)
for filename in filenames
stat = fs.statSync filenameIf this file is a directory, get a list of files in the directory and call this function recursively.
if stat.isDirectory()
new_outdir = path.join(output_dir, path.basename(filename))
fs.mkdirSync new_outdir, stat.mode
subfiles = [path.join(filename, child) for child in fs.readdirSync(filename)]
compile_files subfiles, new_outdir, options, minifyFor .kal, .litkal, and .md (literate Kal assumed) files, set up the options structure and call Kal.compile.
else if path.extname(filename) in ['.kal', '.litkal', '.md']
extension = path.extname(filename)Check if this is Literate code.
options.literate = extension in ['.litkal', '.md']Compile the source.
js_output = Kal.compile fs.readFileSync(filename), optionsMinify if requested. We've already checked that uglify-js is installed at this point.
if minify
js_output = require('uglify-js').minify(js_output, {fromString:yes,mangle:no}).codePrint out the JavaScript if the debug option was passed in.
print js_output if options.show_jsWrite the output to the output directory with a .js extension.
js_filename = path.join(output_dir, path.basename(filename, extension)) + '.js'
fs.writeFileSync js_filename, js_outputReturns the Kal version when for the -v switch.
function version()
print "Kal version #{Kal.VERSION}"
process.exit(0)Help options or invalid input will cause this message to print to the screen.
function usage()
print "Usage: kal [options] SOURCE [-o OUTPUT_DIR]"
print ""
print "If called without the -o option, `kal` will run SOURCE."
print "If called without any options, `kal` will start an interactive session."
print ""
print ""
print "Options:"
print " --help, -h show the command line usage options [boolean]"
print " --tokens, -t print out the tokens that the lexer/sugarer produce [boolean]"
print " --javascript, -j print out the compiled javascript [boolean]"
print " --bare, -b don't wrap the output in a function [boolean]"
print " --version, -v display the version number [boolean]"
print " --output, -o the output directory for the compiled source"
print " --minify minify the output (requires uglify-js) [boolean]"
process.exit(2)