summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/json2yaml70
-rw-r--r--bin/yaml.js2087
-rw-r--r--bin/yaml.min.js21
-rwxr-xr-xbin/yaml2json89
4 files changed, 101 insertions, 2166 deletions
diff --git a/bin/json2yaml b/bin/json2yaml
index 4e92bf8..f0a8791 100755
--- a/bin/json2yaml
+++ b/bin/json2yaml
@@ -4,7 +4,7 @@
* yaml2json cli program
*/
-var YAML = require('./yaml.js');
+var YAML = require('../lib/Yaml.js');
var ArgumentParser = require('argparse').ArgumentParser;
var cli = new ArgumentParser({
@@ -56,7 +56,7 @@ cli.addArgument(
);
cli.addArgument(['input'], {
- help: 'JSON file or directory containing JSON files.'
+ help: 'JSON file or directory containing JSON files or - to read JSON from stdin.'
});
try {
@@ -67,6 +67,7 @@ try {
var rootPath = process.cwd();
var parsePath = function(input) {
+ if (input == '-') return '-';
var output;
if (!(input != null)) {
return rootPath;
@@ -86,33 +87,39 @@ try {
// Find files
var findFiles = function(input) {
- var isDirectory = fs.statSync(input).isDirectory();
- var files = [];
+ if (input != '-' && input != null) {
+ var isDirectory = fs.statSync(input).isDirectory();
+ var files = [];
- if (!isDirectory) {
- files.push(input);
- }
- else {
- if (options.recursive) {
- files = files.concat(glob.sync(input+'/**/*.json'));
+ if (!isDirectory) {
+ files.push(input);
}
else {
- files = files.concat(glob.sync(input+'/*.json'));
+ if (options.recursive) {
+ files = files.concat(glob.sync(input+'/**/*.json'));
+ }
+ else {
+ files = files.concat(glob.sync(input+'/*.json'));
+ }
}
+
+ return files;
}
-
- return files;
+ return null;
};
// Convert to JSON
- var convertToYAML = function(input, inline, save, spaces) {
+ var convertToYAML = function(input, inline, save, spaces, str) {
var yaml;
if (inline == null) inline = 2;
if (spaces == null) spaces = 2;
- yaml = YAML.stringify(JSON.parse(fs.readFileSync(input)), inline, spaces);
+ if (str == null) {
+ str = ''+fs.readFileSync(input);
+ }
+ yaml = YAML.dump(JSON.parse(str), inline, spaces);
- if (!save) {
+ if (!save || input == null) {
// Ouput result
process.stdout.write(yaml);
}
@@ -139,18 +146,29 @@ try {
var runCommand = function() {
try {
var files = findFiles(input);
- var len = files.length;
-
- for (var i = 0; i < len; i++) {
- var file = files[i];
- var stat = fs.statSync(file);
- var time = stat.mtime.getTime();
- if (!stat.isDirectory()) {
- if (!mtimes[file] || mtimes[file] < time) {
- mtimes[file] = time;
- convertToYAML(file, options.depth, options.save, options.indentation);
+ if (files != null) {
+ var len = files.length;
+ for (var i = 0; i < len; i++) {
+ var file = files[i];
+ var stat = fs.statSync(file);
+ var time = stat.mtime.getTime();
+ if (!stat.isDirectory()) {
+ if (!mtimes[file] || mtimes[file] < time) {
+ mtimes[file] = time;
+ convertToYAML(file, options.depth, options.save, options.indentation);
+ }
}
}
+ } else {
+ // Read from STDIN
+ var stdin = process.openStdin();
+ var data = "";
+ stdin.on('data', function(chunk) {
+ data += chunk;
+ });
+ stdin.on('end', function() {
+ convertToYAML(null, options.depth, options.save, options.indentation, data);
+ });
}
} catch (e) {
process.stderr.write((e.message ? e.message : e)+"\n");
diff --git a/bin/yaml.js b/bin/yaml.js
deleted file mode 100644
index 88c1a28..0000000
--- a/bin/yaml.js
+++ /dev/null
@@ -1,2087 +0,0 @@
-/*
-Copyright (c) 2010 Jeremy Faivre
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is furnished
-to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-(function(){
-/**
- * Exception class thrown when an error occurs during parsing.
- *
- * @author Fabien Potencier <fabien@symfony.com>
- *
- * @api
- */
-
-/**
- * Constructor.
- *
- * @param string message The error message
- * @param integer parsedLine The line where the error occurred
- * @param integer snippet The snippet of code near the problem
- * @param string parsedFile The file name where the error occurred
- */
-
-var YamlParseException = function(message, parsedLine, snippet, parsedFile){
-
- this.rawMessage = message;
- this.parsedLine = (parsedLine !== undefined) ? parsedLine : -1;
- this.snippet = (snippet !== undefined) ? snippet : null;
- this.parsedFile = (parsedFile !== undefined) ? parsedFile : null;
-
- this.updateRepr();
-
- this.message = message;
-
-};
-YamlParseException.prototype =
-{
-
- name: 'YamlParseException',
- message: null,
-
- parsedFile: null,
- parsedLine: -1,
- snippet: null,
- rawMessage: null,
-
- isDefined: function(input)
- {
- return input != undefined && input != null;
- },
-
- /**
- * Gets the snippet of code near the error.
- *
- * @return string The snippet of code
- */
- getSnippet: function()
- {
- return this.snippet;
- },
-
- /**
- * Sets the snippet of code near the error.
- *
- * @param string snippet The code snippet
- */
- setSnippet: function(snippet)
- {
- this.snippet = snippet;
-
- this.updateRepr();
- },
-
- /**
- * Gets the filename where the error occurred.
- *
- * This method returns null if a string is parsed.
- *
- * @return string The filename
- */
- getParsedFile: function()
- {
- return this.parsedFile;
- },
-
- /**
- * Sets the filename where the error occurred.
- *
- * @param string parsedFile The filename
- */
- setParsedFile: function(parsedFile)
- {
- this.parsedFile = parsedFile;
-
- this.updateRepr();
- },
-
- /**
- * Gets the line where the error occurred.
- *
- * @return integer The file line
- */
- getParsedLine: function()
- {
- return this.parsedLine;
- },
-
- /**
- * Sets the line where the error occurred.
- *
- * @param integer parsedLine The file line
- */
- setParsedLine: function(parsedLine)
- {
- this.parsedLine = parsedLine;
-
- this.updateRepr();
- },
-
- updateRepr: function()
- {
- this.message = this.rawMessage;
-
- var dot = false;
- if ('.' === this.message.charAt(this.message.length - 1)) {
- this.message = this.message.substring(0, this.message.length - 1);
- dot = true;
- }
-
- if (null !== this.parsedFile) {
- this.message += ' in ' + JSON.stringify(this.parsedFile);
- }
-
- if (this.parsedLine >= 0) {
- this.message += ' at line ' + this.parsedLine;
- }
-
- if (this.snippet) {
- this.message += ' (near "' + this.snippet + '")';
- }
-
- if (dot) {
- this.message += '.';
- }
- }
-}
-/**
- * Yaml offers convenience methods to parse and dump YAML.
- *
- * @author Fabien Potencier <fabien@symfony.com>
- *
- * @api
- */
-
-var YamlRunningUnderNode = false;
-var Yaml = function(){};
-Yaml.prototype =
-{
-
- /**
- * Parses YAML into a JS representation.
- *
- * The parse method, when supplied with a YAML stream (file),
- * will do its best to convert YAML in a file into a JS representation.
- *
- * Usage:
- * <code>
- * obj = yaml.parseFile('config.yml');
- * </code>
- *
- * @param string input Path of YAML file
- *
- * @return array The YAML converted to a JS representation
- *
- * @throws YamlParseException If the YAML is not valid
- */
- parseFile: function(file /* String */, callback /* Function */)
- {
- if ( callback == null )
- {
- var input = this.getFileContents(file);
- var ret = null;
- try
- {
- ret = this.parse(input);
- }
- catch ( e )
- {
- if ( e instanceof YamlParseException ) {
- e.setParsedFile(file);
- }
- throw e;
- }
- return ret;
- }
-
- this.getFileContents(file, function(data)
- {
- callback(new Yaml().parse(data));
- });
- },
-
- /**
- * Parses YAML into a JS representation.
- *
- * The parse method, when supplied with a YAML stream (string),
- * will do its best to convert YAML into a JS representation.
- *
- * Usage:
- * <code>
- * obj = yaml.parse(...);
- * </code>
- *
- * @param string input string containing YAML
- *
- * @return array The YAML converted to a JS representation
- *
- * @throws YamlParseException If the YAML is not valid
- */
- parse: function(input /* String */)
- {
- var yaml = new YamlParser();
-
- return yaml.parse(input);
- },
-
- /**
- * Dumps a JS representation to a YAML string.
- *
- * The dump method, when supplied with an array, will do its best
- * to convert the array into friendly YAML.
- *
- * @param array array JS representation
- * @param integer inline The level where you switch to inline YAML
- *
- * @return string A YAML string representing the original JS representation
- *
- * @api
- */
- dump: function(array, inline, spaces)
- {
- if ( inline == null ) inline = 2;
-
- var yaml = new YamlDumper();
- if (spaces) {
- yaml.numSpacesForIndentation = spaces;
- }
-
- return yaml.dump(array, inline);
- },
-
- getXHR: function()
- {
- if ( window.XMLHttpRequest )
- return new XMLHttpRequest();
-
- if ( window.ActiveXObject )
- {
- var names = [
- "Msxml2.XMLHTTP.6.0",
- "Msxml2.XMLHTTP.3.0",
- "Msxml2.XMLHTTP",
- "Microsoft.XMLHTTP"
- ];
-
- for ( var i = 0; i < 4; i++ )
- {
- try{ return new ActiveXObject(names[i]); }
- catch(e){}
- }
- }
- return null;
- },
-
- getFileContents: function(file, callback)
- {
- if ( YamlRunningUnderNode )
- {
- var fs = require('fs');
- if ( callback == null )
- {
- var data = fs.readFileSync(file);
- if (data == null) return null;
- return ''+data;
- }
- else
- {
- fs.readFile(file, function(err, data)
- {
- if (err)
- callback(null);
- else
- callback(data);
- });
- }
- }
- else
- {
- var request = this.getXHR();
-
- // Sync
- if ( callback == null )
- {
- request.open('GET', file, false);
- request.send(null);
-
- if ( request.status == 200 || request.status == 0 )
- return request.responseText;
-
- return null;
- }
-
- // Async
- request.onreadystatechange = function()
- {
- if ( request.readyState == 4 )
- if ( request.status == 200 || request.status == 0 )
- callback(request.responseText);
- else
- callback(null);
- };
- request.open('GET', file, true);
- request.send(null);
- }
- }
-};
-
-var YAML =
-{
- /*
- * @param integer inline The level where you switch to inline YAML
- */
-
- stringify: function(input, inline, spaces)
- {
- return new Yaml().dump(input, inline, spaces);
- },
-
- parse: function(input)
- {
- return new Yaml().parse(input);
- },
-
- load: function(file, callback)
- {
- return new Yaml().parseFile(file, callback);
- }
-};
-
-// Handle node.js case
-if (typeof exports !== 'undefined') {
- if (typeof module !== 'undefined' && module.exports) {
- exports = module.exports = YAML;
- YamlRunningUnderNode = true;
-
- // Add require handler
- (function () {
- var require_handler = function (module, filename) {
- // fill in result
- module.exports = YAML.load(filename);
- };
-
- // register require extensions only if we're on node.js
- // hack for browserify
- if ( undefined !== require.extensions ) {
- require.extensions['.yml'] = require_handler;
- require.extensions['.yaml'] = require_handler;
- }
- }());
- }
-}
-
-// Handle browser case
-if ( typeof(window) != "undefined" )
-{
- window.YAML = YAML;
-}
-
-/**
- * YamlInline implements a YAML parser/dumper for the YAML inline syntax.
- */
-var YamlInline = function(){};
-YamlInline.prototype =
-{
- i: null,
-
- /**
- * Convert a YAML string to a JS object.
- *
- * @param string value A YAML string
- *
- * @return object A JS object representing the YAML string
- */
- parse: function(value)
- {
- var result = null;
- value = this.trim(value);
-
- if ( 0 == value.length )
- {
- return '';
- }
-
- switch ( value.charAt(0) )
- {
- case '[':
- result = this.parseSequence(value);
- break;
- case '{':
- result = this.parseMapping(value);
- break;
- default:
- result = this.parseScalar(value);
- }
-
- // some comment can end the scalar
- if ( value.substr(this.i+1).replace(/^\s*#.*$/, '') != '' ) {
- console.log("oups "+value.substr(this.i+1));
- throw new YamlParseException('Unexpected characters near "'+value.substr(this.i)+'".');
- }
-
- return result;
- },
-
- /**
- * Dumps a given JS variable to a YAML string.
- *
- * @param mixed value The JS variable to convert
- *
- * @return string The YAML string representing the JS object
- */
- dump: function(value)
- {
- if ( undefined == value || null == value )
- return 'null';
- if ( value instanceof Date)
- return value.toISOString();
- if ( typeof(value) == 'object')
- return this.dumpObject(value);
- if ( typeof(value) == 'boolean' )
- return value ? 'true' : 'false';
- if ( /^\d+$/.test(value) )
- return typeof(value) == 'string' ? "'"+value+"'" : parseInt(value);
- if ( this.isNumeric(value) )
- return typeof(value) == 'string' ? "'"+value+"'" : parseFloat(value);
- if ( typeof(value) == 'number' )
- return value == Infinity ? '.Inf' : ( value == -Infinity ? '-.Inf' : ( isNaN(value) ? '.NAN' : value ) );
- var yaml = new YamlEscaper();
- if ( yaml.requiresDoubleQuoting(value) )
- return yaml.escapeWithDoubleQuotes(value);
- if ( yaml.requiresSingleQuoting(value) )
- return yaml.escapeWithSingleQuotes(value);
- if ( '' == value )
- return '""';
- if ( this.getTimestampRegex().test(value) )
- return "'"+value+"'";
- if ( this.inArray(value.toLowerCase(), ['null','~','true','false']) )
- return "'"+value+"'";
- // default
- return value;
- },
-
- /**
- * Dumps a JS object to a YAML string.
- *
- * @param object value The JS array to dump
- *
- * @return string The YAML string representing the JS object
- */
- dumpObject: function(value)
- {
- var keys = this.getKeys(value);
- var output = null;
- var i;
- var len = keys.length;
-
- // array
- if ( value instanceof Array )
- /*( 1 == len && '0' == keys[0] )
- ||
- ( len > 1 && this.reduceArray(keys, function(v,w){return Math.floor(v+w);}, 0) == len * (len - 1) / 2) )*/
- {
- output = [];
- for ( i = 0; i < len; i++ )
- {
- output.push(this.dump(value[keys[i]]));
- }
-
- return '['+output.join(', ')+']';
- }
-
- // mapping
- output = [];
- for ( i = 0; i < len; i++ )
- {
- output.push(this.dump(keys[i])+': '+this.dump(value[keys[i]]));
- }
-
- return '{ '+output.join(', ')+' }';
- },
-
- /**
- * Parses a scalar to a YAML string.
- *
- * @param scalar scalar
- * @param string delimiters
- * @param object stringDelimiters
- * @param integer i
- * @param boolean evaluate
- *
- * @return string A YAML string
- *
- * @throws YamlParseException When malformed inline YAML string is parsed
- */
- parseScalar: function(scalar, delimiters, stringDelimiters, i, evaluate)
- {
- if ( delimiters == undefined ) delimiters = null;
- if ( stringDelimiters == undefined ) stringDelimiters = ['"', "'"];
- if ( i == undefined ) i = 0;
- if ( evaluate == undefined ) evaluate = true;
-
- var output = null;
- var pos = null;
- var matches = null;
-
- if ( this.inArray(scalar[i], stringDelimiters) )
- {
- // quoted scalar
- output = this.parseQuotedScalar(scalar, i);
- i = this.i;
- if (null !== delimiters) {
- var tmp = scalar.substr(i).replace(/^\s+/, '');
- if (!this.inArray(tmp.charAt(0), delimiters)) {
- throw new YamlParseException('Unexpected characters ('+scalar.substr(i)+').');
- }
- }
- }
- else
- {
- // "normal" string
- if ( !delimiters )
- {
- output = (scalar+'').substring(i);
-
- i += output.length;
-
- // remove comments
- pos = output.indexOf(' #');
- if ( pos != -1 )
- {
- output = output.substr(0, pos).replace(/\s+$/g,'');
- }
- }
- else if ( matches = new RegExp('^(.+?)('+delimiters.join('|')+')').exec((scalar+'').substring(i)) )
- {
- output = matches[1];
- i += output.length;
- }
- else
- {
- throw new YamlParseException('Malformed inline YAML string ('+scalar+').');
- }
- output = evaluate ? this.evaluateScalar(output) : output;
- }
-
- this.i = i;
-
- return output;
- },
-
- /**
- * Parses a quoted scalar to YAML.
- *
- * @param string scalar
- * @param integer i
- *
- * @return string A YAML string
- *
- * @throws YamlParseException When malformed inline YAML string is parsed
- */
- parseQuotedScalar: function(scalar, i)
- {
- var matches = null;
- //var item = /^(.*?)['"]\s*(?:[,:]|[}\]]\s*,)/.exec((scalar+'').substring(i))[1];
-
- if ( !(matches = new RegExp('^'+YamlInline.REGEX_QUOTED_STRING).exec((scalar+'').substring(i))) )
- {
- throw new YamlParseException('Malformed inline YAML string ('+(scalar+'').substring(i)+').');
- }
-
- var output = matches[0].substr(1, matches[0].length - 2);
-
- var unescaper = new YamlUnescaper();
-
- if ( '"' == (scalar+'').charAt(i) )
- {
- output = unescaper.unescapeDoubleQuotedString(output);
- }
- else
- {
- output = unescaper.unescapeSingleQuotedString(output);
- }
-
- i += matches[0].length;
-
- this.i = i;
- return output;
- },
-
- /**
- * Parses a sequence to a YAML string.
- *
- * @param string sequence
- * @param integer i
- *
- * @return string A YAML string
- *
- * @throws YamlParseException When malformed inline YAML string is parsed
- */
- parseSequence: function(sequence, i)
- {
- if ( i == undefined ) i = 0;
-
- var output = [];
- var len = sequence.length;
- i += 1;
-
- // [foo, bar, ...]
- while ( i < len )
- {
- switch ( sequence.charAt(i) )
- {
- case '[':
- // nested sequence
- output.push(this.parseSequence(sequence, i));
- i = this.i;
- break;
- case '{':
- // nested mapping
- output.push(this.parseMapping(sequence, i));
- i = this.i;
- break;
- case ']':
- this.i = i;
- return output;
- case ',':
- case ' ':
- break;
- default:
- var isQuoted = this.inArray(sequence.charAt(i), ['"', "'"]);
- var value = this.parseScalar(sequence, [',', ']'], ['"', "'"], i);
- i = this.i;
-
- if ( !isQuoted && (value+'').indexOf(': ') != -1 )
- {
- // embedded mapping?
- try
- {
- value = this.parseMapping('{'+value+'}');
- }
- catch ( e )
- {
- if ( !(e instanceof YamlParseException ) ) throw e;
- // no, it's not
- }
- }
-
- output.push(value);
-
- i--;
- }
-
- i++;
- }
-
- throw new YamlParseException('Malformed inline YAML string "'+sequence+'"');
- },
-
- /**
- * Parses a mapping to a YAML string.
- *
- * @param string mapping
- * @param integer i
- *
- * @return string A YAML string
- *
- * @throws YamlParseException When malformed inline YAML string is parsed
- */
- parseMapping: function(mapping, i)
- {
- if ( i == undefined ) i = 0;
- var output = {};
- var len = mapping.length;
- i += 1;
- var done = false;
- var doContinue = false;
-
- // {foo: bar, bar:foo, ...}
- while ( i < len )
- {
- doContinue = false;
-
- switch ( mapping.charAt(i) )
- {
- case ' ':
- case ',':
- i++;
- doContinue = true;
- break;
- case '}':
- this.i = i;
- return output;
- }
-
- if ( doContinue ) continue;
-
- // key
- var key = this.parseScalar(mapping, [':', ' '], ['"', "'"], i, false);
- i = this.i;
-
- // value
- done = false;
- while ( i < len )
- {
- switch ( mapping.charAt(i) )
- {
- case '[':
- // nested sequence
- output[key] = this.parseSequence(mapping, i);
- i = this.i;
- done = true;
- break;
- case '{':
- // nested mapping
- output[key] = this.parseMapping(mapping, i);
- i = this.i;
- done = true;
- break;
- case ':':
- case ' ':
- break;
- default:
- output[key] = this.parseScalar(mapping, [',', '}'], ['"', "'"], i);
- i = this.i;
- done = true;
- i--;
- }
-
- ++i;
-
- if ( done )
- {
- doContinue = true;
- break;
- }
- }
-
- if ( doContinue ) continue;
- }
-
- throw new YamlParseException('Malformed inline YAML string "'+mapping+'"');
- },
-
- /**
- * Evaluates scalars and replaces magic values.
- *
- * @param string scalar
- *
- * @return string A YAML string
- */
- evaluateScalar: function(scalar)
- {
- scalar = this.trim(scalar);
-
- var raw = null;
- var cast = null;
-
- if ( ( 'null' == scalar.toLowerCase() ) ||
- ( '' == scalar ) ||
- ( '~' == scalar ) )
- return null;
- if ( (scalar+'').indexOf('!str ') == 0 )
- return (''+scalar).substring(5);
- if ( (scalar+'').indexOf('! ') == 0 )
- return parseInt(this.parseScalar((scalar+'').substr(2)));
- if ( /^\d+$/.test(scalar) )
- {
- raw = scalar;
- cast = parseInt(scalar);
- return '0' == scalar.charAt(0) ? this.octdec(scalar) : (( ''+raw == ''+cast ) ? cast : raw);
- }
- if ( 'true' == (scalar+'').toLowerCase() )
- return true;
- if ( 'false' == (scalar+'').toLowerCase() )
- return false;
- if ( this.isNumeric(scalar) )
- return '0x' == (scalar+'').substr(0, 2) ? this.hexdec(scalar) : parseFloat(scalar);
- if ( scalar.toLowerCase() == '.inf' )
- return Infinity;
- if ( scalar.toLowerCase() == '.nan' )
- return NaN;
- if ( scalar.toLowerCase() == '-.inf' )
- return -Infinity;
- if ( /^(-|\+)?[0-9,]+(\.[0-9]+)?$/.test(scalar) )
- return parseFloat(scalar.split(',').join(''));
- if ( this.getTimestampRegex().test(scalar) )
- return new Date(this.strtotime(scalar));
- //else
- return ''+scalar;
- },
-
- /**
- * Gets a regex that matches an unix timestamp
- *
- * @return string The regular expression
- */
- getTimestampRegex: function()
- {
- return new RegExp('^'+
- '([0-9][0-9][0-9][0-9])'+
- '-([0-9][0-9]?)'+
- '-([0-9][0-9]?)'+
- '(?:(?:[Tt]|[ \t]+)'+
- '([0-9][0-9]?)'+
- ':([0-9][0-9])'+
- ':([0-9][0-9])'+
- '(?:\.([0-9]*))?'+
- '(?:[ \t]*(Z|([-+])([0-9][0-9]?)'+
- '(?::([0-9][0-9]))?))?)?'+
- '$','gi');
- },
-
- trim: function(str /* String */)
- {
- return (str+'').replace(/^\s+/,'').replace(/\s+$/,'');
- },
-
- isNumeric: function(input)
- {
- return (input - 0) == input && input.length > 0 && input.replace(/\s+/g,'') != '';
- },
-
- inArray: function(key, tab)
- {
- var i;
- var len = tab.length;
- for ( i = 0; i < len; i++ )
- {
- if ( key == tab[i] ) return true;
- }
- return false;
- },
-
- getKeys: function(tab)
- {
- var ret = [];
-
- for ( var name in tab )
- {
- if ( tab.hasOwnProperty(name) )
- {
- ret.push(name);
- }
- }
-
- return ret;
- },
-
- /*reduceArray: function(tab, fun)
- {
- var len = tab.length;
- if (typeof fun != "function")
- throw new YamlParseException("fun is not a function");
-
- // no value to return if no initial value and an empty array
- if (len == 0 && arguments.length == 1)
- throw new YamlParseException("empty array");
-
- var i = 0;
- if (arguments.length >= 2)
- {
- var rv = arguments[1];
- }
- else
- {
- do
- {
- if (i in tab)
- {
- rv = tab[i++];
- break;
- }
-
- // if array contains no values, no initial value to return
- if (++i >= len)
- throw new YamlParseException("no initial value to return");
- }
- while (true);
- }
-
- for (; i < len; i++)
- {
- if (i in tab)
- rv = fun.call(null, rv, tab[i], i, tab);
- }
-
- return rv;
- },*/
-
- octdec: function(input)
- {
- return parseInt((input+'').replace(/[^0-7]/gi, ''), 8);
- },
-
- hexdec: function(input)
- {
- input = this.trim(input);
- if ( (input+'').substr(0, 2) == '0x' ) input = (input+'').substring(2);
- return parseInt((input+'').replace(/[^a-f0-9]/gi, ''), 16);
- },
-
- /**
- * @see http://phpjs.org/functions/strtotime
- * @note we need timestamp with msecs so /1000 removed
- * @note original contained binary | 0 (wtf?!) everywhere, which messes everything up
- */
- strtotime: function (h,b){var f,c,g,k,d="";h=(h+"").replace(/\s{2,}|^\s|\s$/g," ").replace(/[\t\r\n]/g,"");if(h==="now"){return b===null||isNaN(b)?new Date().getTime()||0:b||0}else{if(!isNaN(d=Date.parse(h))){return d||0}else{if(b){b=new Date(b)}else{b=new Date()}}}h=h.toLowerCase();var e={day:{sun:0,mon:1,tue:2,wed:3,thu:4,fri:5,sat:6},mon:["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]};var a=function(i){var o=(i[2]&&i[2]==="ago");var n=(n=i[0]==="last"?-1:1)*(o?-1:1);switch(i[0]){case"last":case"next":switch(i[1].substring(0,3)){case"yea":b.setFullYear(b.getFullYear()+n);break;case"wee":b.setDate(b.getDate()+(n*7));break;case"day":b.setDate(b.getDate()+n);break;case"hou":b.setHours(b.getHours()+n);break;case"min":b.setMinutes(b.getMinutes()+n);break;case"sec":b.setSeconds(b.getSeconds()+n);break;case"mon":if(i[1]==="month"){b.setMonth(b.getMonth()+n);break}default:var l=e.day[i[1].substring(0,3)];if(typeof l!=="undefined"){var p=l-b.getDay();if(p===0){p=7*n}else{if(p>0){if(i[0]==="last"){p-=7}}else{if(i[0]==="next"){p+=7}}}b.setDate(b.getDate()+p);b.setHours(0,0,0,0)}}break;default:if(/\d+/.test(i[0])){n*=parseInt(i[0],10);switch(i[1].substring(0,3)){case"yea":b.setFullYear(b.getFullYear()+n);break;case"mon":b.setMonth(b.getMonth()+n);break;case"wee":b.setDate(b.getDate()+(n*7));break;case"day":b.setDate(b.getDate()+n);break;case"hou":b.setHours(b.getHours()+n);break;case"min":b.setMinutes(b.getMinutes()+n);break;case"sec":b.setSeconds(b.getSeconds()+n);break}}else{return false}break}return true};g=h.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);if(g!==null){if(!g[2]){g[2]="00:00:00"}else{if(!g[3]){g[2]+=":00"}}k=g[1].split(/-/g);k[1]=e.mon[k[1]-1]||k[1];k[0]=+k[0];k[0]=(k[0]>=0&&k[0]<=69)?"20"+(k[0]<10?"0"+k[0]:k[0]+""):(k[0]>=70&&k[0]<=99)?"19"+k[0]:k[0]+"";return parseInt(this.strtotime(k[2]+" "+k[1]+" "+k[0]+" "+g[2])+(g[4]?g[4]:""),10)}var j="([+-]?\\d+\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)|(last|next)\\s(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))(\\sago)?";g=h.match(new RegExp(j,"gi"));if(g===null){return false}for(f=0,c=g.length;f<c;f++){if(!a(g[f].split(" "))){return false}}return b.getTime()||0}
-
-};
-
-/*
- * @note uses only non-capturing sub-patterns (unlike PHP original)
- */
-YamlInline.REGEX_QUOTED_STRING = '(?:"(?:[^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'(?:[^\']*(?:\'\'[^\']*)*)\')';
-
-
-/**
- * YamlParser parses YAML strings to convert them to JS objects
- * (port of Yaml Symfony Component)
- */
-var YamlParser = function(offset /* Integer */)
-{
- this.offset = (offset !== undefined) ? offset : 0;
-};
-YamlParser.prototype =
-{
- offset: 0,
- lines: [],
- currentLineNb: -1,
- currentLine: '',
- refs: {},
-
- /**
- * Parses a YAML string to a JS value.
- *
- * @param String value A YAML string
- *
- * @return mixed A JS value
- */
- parse: function(value /* String */)
- {
- this.currentLineNb = -1;
- this.currentLine = '';
- this.lines = this.cleanup(value).split("\n");
-
- var data = null;
- var context = null;
-
- while ( this.moveToNextLine() )
- {
- if ( this.isCurrentLineEmpty() )
- {
- continue;
- }
-
- // tab?
- if ( this.currentLine.charAt(0) == '\t' )
- {
- throw new YamlParseException('A YAML file cannot contain tabs as indentation.', this.getRealCurrentLineNb() + 1, this.currentLine);
- }
-
- var isRef = false;
- var isInPlace = false;
- var isProcessed = false;
- var values = null;
- var matches = null;
- var c = null;
- var parser = null;
- var block = null;
- var key = null;
- var parsed = null;
- var len = null;
- var reverse = null;
-
- if ( values = /^\-((\s+)(.+?))?\s*$/.exec(this.currentLine) )
- {
-
- if (context && 'mapping' == context) {
- throw new YamlParseException('You cannot define a sequence item when in a mapping', this.getRealCurrentLineNb() + 1, this.currentLine);
- }
- context = 'sequence';
-
- if ( !this.isDefined(data) ) data = [];
- //if ( !(data instanceof Array) ) throw new YamlParseException("Non array entry", this.getRealCurrentLineNb() + 1, this.currentLine);
-
- values = {leadspaces: values[2], value: values[3]};
-
- if ( this.isDefined(values.value) && ( matches = /^&([^ ]+) *(.*)/.exec(values.value) ) )
- {
- matches = {ref: matches[1], value: matches[2]};
- isRef = matches.ref;
- values.value = matches.value;
- }
-
- // array
- if ( !this.isDefined(values.value) || '' == this.trim(values.value) || values.value.replace(/^ +/,'').charAt(0) == '#' )
- {
- c = this.getRealCurrentLineNb() + 1;
- parser = new YamlParser(c);
- parser.refs = this.refs;
- data.push(parser.parse(this.getNextEmbedBlock()));
- this.refs = parser.refs;
- }
- else
- {
- if ( this.isDefined(values.leadspaces) &&
- ' ' == values.leadspaces &&
- ( matches = new RegExp('^('+YamlInline.REGEX_QUOTED_STRING+'|[^ \'"\{\[].*?) *\:(\\s+(.+?))?\\s*$').exec(values.value) )
- ) {
- matches = {key: matches[1], value: matches[3]};
- // this is a compact notation element, add to next block and parse
- c = this.getRealCurrentLineNb();
- parser = new YamlParser(c);
- parser.refs = this.refs;
- block = values.value;
-
- if ( !this.isNextLineIndented() )
- {
- block += "\n"+this.getNextEmbedBlock(this.getCurrentLineIndentation() + 2);
- }
-
- data.push(parser.parse(block));
- this.refs = parser.refs;
- }
- else
- {
- data.push(this.parseValue(values.value));
- }
- }
- }
- else if ( values = new RegExp('^('+YamlInline.REGEX_QUOTED_STRING+'|[^ \'"\[\{].*?) *\:(\\s+(.+?))?\\s*$').exec(this.currentLine) )
- {
- if ( !this.isDefined(data) ) data = {};
- if (context && 'sequence' == context) {
- throw new YamlParseException('You cannot define a mapping item when in a sequence', this.getRealCurrentLineNb() + 1, this.currentLine);
- }
- context = 'mapping';
- //if ( data instanceof Array ) throw new YamlParseException("Non mapped entry", this.getRealCurrentLineNb() + 1, this.currentLine);
-
- values = {key: values[1], value: values[3]};
-
- try {
- key = new YamlInline().parseScalar(values.key);
- } catch (e) {
- if ( e instanceof YamlParseException ) {
- e.setParsedLine(this.getRealCurrentLineNb() + 1);
- e.setSnippet(this.currentLine);
- }
- throw e;
- }
-
-
- if ( '<<' == key )
- {
- if ( this.isDefined(values.value) && '*' == (values.value+'').charAt(0) )
- {
- isInPlace = values.value.substr(1);
- if ( this.refs[isInPlace] == undefined )
- {
- throw new YamlParseException('Reference "'+value+'" does not exist', this.getRealCurrentLineNb() + 1, this.currentLine);
- }
- }
- else
- {
- if ( this.isDefined(values.value) && values.value != '' )
- {
- value = values.value;
- }
- else
- {
- value = this.getNextEmbedBlock();
- }
-
- c = this.getRealCurrentLineNb() + 1;
- parser = new YamlParser(c);
- parser.refs = this.refs;
- parsed = parser.parse(value);
- this.refs = parser.refs;
-
- var merged = [];
- if ( !this.isObject(parsed) )
- {
- throw new YamlParseException("YAML merge keys used with a scalar value instead of an array", this.getRealCurrentLineNb() + 1, this.currentLine);
- }
- else if ( this.isDefined(parsed[0]) )
- {
- // Numeric array, merge individual elements
- reverse = this.reverseArray(parsed);
- len = reverse.length;
- for ( var i = 0; i < len; i++ )
- {
- var parsedItem = reverse[i];
- if ( !this.isObject(reverse[i]) )
- {
- throw new YamlParseException("Merge items must be arrays", this.getRealCurrentLineNb() + 1, this.currentLine);
- }
- merged = this.mergeObject(reverse[i], merged);
- }
- }
- else
- {
- // Associative array, merge
- merged = this.mergeObject(merged, parsed);
- }
-
- isProcessed = merged;
- }
- }
- else if ( this.isDefined(values.value) && (matches = /^&([^ ]+) *(.*)/.exec(values.value) ) )
- {
- matches = {ref: matches[1], value: matches[2]};
- isRef = matches.ref;
- values.value = matches.value;
- }
-
- if ( isProcessed )
- {
- // Merge keys
- data = isProcessed;
- }
- // hash
- else if ( !this.isDefined(values.value) || '' == this.trim(values.value) || this.trim(values.value).charAt(0) == '#' )
- {
- // if next line is less indented or equal, then it means that the current value is null
- if ( this.isNextLineIndented() && !this.isNextLineUnIndentedCollection() )
- {
- data[key] = null;
- }
- else
- {
- c = this.getRealCurrentLineNb() + 1;
- parser = new YamlParser(c);
- parser.refs = this.refs;
- data[key] = parser.parse(this.getNextEmbedBlock());
- this.refs = parser.refs;
- }
- }
- else
- {
- if ( isInPlace )
- {
- data = this.refs[isInPlace];
- }
- else
- {
- data[key] = this.parseValue(values.value);
- }
- }
- }
- else
- {
- // 1-liner followed by newline
- if ( 2 == this.lines.length && this.isEmpty(this.lines[1]) )
- {
- try {
- value = new YamlInline().parse(this.lines[0]);
- } catch (e) {
- if ( e instanceof YamlParseException ) {
- e.setParsedLine(this.getRealCurrentLineNb() + 1);
- e.setSnippet(this.currentLine);
- }
- throw e;
- }
-
- if ( this.isObject(value) )
- {
- var first = value[0];
- if ( typeof(value) == 'string' && '*' == first.charAt(0) )
- {
- data = [];
- len = value.length;
- for ( var i = 0; i < len; i++ )
- {
- data.push(this.refs[value[i].substr(1)]);
- }
- value = data;
- }
- }
-
- return value;
- }
-
- throw new YamlParseException('Unable to parse.', this.getRealCurrentLineNb() + 1, this.currentLine);
- }
-
- if ( isRef )
- {
- if ( data instanceof Array )
- this.refs[isRef] = data[data.length-1];
- else
- {
- var lastKey = null;
- for ( var k in data )
- {
- if ( data.hasOwnProperty(k) ) lastKey = k;
- }
- this.refs[isRef] = data[k];
- }
- }
- }
-
- return this.isEmpty(data) ? null : data;
- },
-
- /**
- * Returns the current line number (takes the offset into account).
- *
- * @return integer The current line number
- */
- getRealCurrentLineNb: function()
- {
- return this.currentLineNb + this.offset;
- },
-
- /**
- * Returns the current line indentation.
- *
- * @return integer The current line indentation
- */
- getCurrentLineIndentation: function()
- {
- return this.currentLine.length - this.currentLine.replace(/^ +/g, '').length;
- },
-
- /**
- * Returns the next embed block of YAML.
- *
- * @param integer indentation The indent level at which the block is to be read, or null for default
- *
- * @return string A YAML string
- *
- * @throws YamlParseException When indentation problem are detected
- */
- getNextEmbedBlock: function(indentation)
- {
- this.moveToNextLine();
- var newIndent = null;
- var indent = null;
-
- if ( !this.isDefined(indentation) )
- {
- newIndent = this.getCurrentLineIndentation();
-
- var unindentedEmbedBlock = this.isStringUnIndentedCollectionItem(this.currentLine);
-
- if ( !this.isCurrentLineEmpty() && 0 == newIndent && !unindentedEmbedBlock )
- {
- throw new YamlParseException('Indentation problem A', this.getRealCurrentLineNb() + 1, this.currentLine);
- }
- }
- else
- {
- newIndent = indentation;
- }
-
- var data = [this.currentLine.substr(newIndent)];
-
- var isUnindentedCollection = this.isStringUnIndentedCollectionItem(this.currentLine);
-
- var continuationIndent = -1;
- if (isUnindentedCollection === true) {
- continuationIndent = 1 + /^\-((\s+)(.+?))?\s*$/.exec(this.currentLine)[2].length;
- }
-
- while ( this.moveToNextLine() )
- {
-
- if (isUnindentedCollection && !this.isStringUnIndentedCollectionItem(this.currentLine) && this.getCurrentLineIndentation() != continuationIndent) {
- this.moveToPreviousLine();
- break;
- }
-
- if ( this.isCurrentLineEmpty() )
- {
- if ( this.isCurrentLineBlank() )
- {
- data.push(this.currentLine.substr(newIndent));
- }
-
- continue;
- }
-
- indent = this.getCurrentLineIndentation();
- var matches;
- if ( matches = /^( *)$/.exec(this.currentLine) )
- {
- // empty line
- data.push(matches[1]);
- }
- else if ( indent >= newIndent )
- {
- data.push(this.currentLine.substr(newIndent));
- }
- else if ( 0 == indent )
- {
- this.moveToPreviousLine();
-
- break;
- }
- else
- {
- throw new YamlParseException('Indentation problem B', this.getRealCurrentLineNb() + 1, this.currentLine);
- }
- }
-
- return data.join("\n");
- },
-
- /**
- * Moves the parser to the next line.
- *
- * @return Boolean
- */
- moveToNextLine: function()
- {
- if ( this.currentLineNb >= this.lines.length - 1 )
- {
- return false;
- }
-
- this.currentLineNb++;
- this.currentLine = this.lines[this.currentLineNb];
-
- return true;
- },
-
- /**
- * Moves the parser to the previous line.
- */
- moveToPreviousLine: function()
- {
- this.currentLineNb--;
- this.currentLine = this.lines[this.currentLineNb];
- },
-
- /**
- * Parses a YAML value.
- *
- * @param string value A YAML value
- *
- * @return mixed A JS value
- *
- * @throws YamlParseException When reference does not exist
- */
- parseValue: function(value)
- {
- if ( '*' == (value+'').charAt(0) )
- {
- if ( this.trim(value).charAt(0) == '#' )
- {
- value = (value+'').substr(1, value.indexOf('#') - 2);
- }
- else
- {
- value = (value+'').substr(1);
- }
-
- if ( this.refs[value] == undefined )
- {
- throw new YamlParseException('Reference "'+value+'" does not exist', this.getRealCurrentLineNb() + 1, this.currentLine);
- }
- return this.refs[value];
- }
-
- var matches = null;
- if ( matches = /^(\||>)(\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?( +#.*)?$/.exec(value) )
- {
- matches = {separator: matches[1], modifiers: matches[2], comments: matches[3]};
- var modifiers = this.isDefined(matches.modifiers) ? matches.modifiers : '';
-
- return this.parseFoldedScalar(matches.separator, modifiers.replace(/\d+/g, ''), Math.abs(parseInt(modifiers)));
- }
- try {
- return new YamlInline().parse(value);
- } catch (e) {
- if ( e instanceof YamlParseException ) {
- e.setParsedLine(this.getRealCurrentLineNb() + 1);
- e.setSnippet(this.currentLine);
- }
- throw e;
- }
- },
-
- /**
- * Parses a folded scalar.
- *
- * @param string separator The separator that was used to begin this folded scalar (| or >)
- * @param string indicator The indicator that was used to begin this folded scalar (+ or -)
- * @param integer indentation The indentation that was used to begin this folded scalar
- *
- * @return string The text value
- */
- parseFoldedScalar: function(separator, indicator, indentation)
- {
- if ( indicator == undefined ) indicator = '';
- if ( indentation == undefined ) indentation = 0;
-
- separator = '|' == separator ? "\n" : ' ';
- var text = '';
- var diff = null;
-
- var notEOF = this.moveToNextLine();
-
- while ( notEOF && this.isCurrentLineBlank() )
- {
- text += "\n";
-
- notEOF = this.moveToNextLine();
- }
-
- if ( !notEOF )
- {
- return '';
- }
-
- var matches = null;
- if ( !(matches = new RegExp('^('+(indentation ? this.strRepeat(' ', indentation) : ' +')+')(.*)$').exec(this.currentLine)) )
- {
- this.moveToPreviousLine();
-
- return '';
- }
-
- matches = {indent: matches[1], text: matches[2]};
-
- var textIndent = matches.indent;
- var previousIndent = 0;
-
- text += matches.text + separator;
- while ( this.currentLineNb + 1 < this.lines.length )
- {
- this.moveToNextLine();
-
- if ( matches = new RegExp('^( {'+textIndent.length+',})(.+)$').exec(this.currentLine) )
- {
- matches = {indent: matches[1], text: matches[2]};
-
- if ( ' ' == separator && previousIndent != matches.indent )
- {
- text = text.substr(0, text.length - 1)+"\n";
- }
-
- previousIndent = matches.indent;
-
- diff = matches.indent.length - textIndent.length;
- text += this.strRepeat(' ', diff) + matches.text + (diff != 0 ? "\n" : separator);
- }
- else if ( matches = /^( *)$/.exec(this.currentLine) )
- {
- text += matches[1].replace(new RegExp('^ {1,'+textIndent.length+'}','g'), '')+"\n";
- }
- else
- {
- this.moveToPreviousLine();
-
- break;
- }
- }
-
- if ( ' ' == separator )
- {
- // replace last separator by a newline
- text = text.replace(/ (\n*)$/g, "\n$1");
- }
-
- switch ( indicator )
- {
- case '':
- text = text.replace(/\n+$/g, "\n");
- break;
- case '+':
- break;
- case '-':
- text = text.replace(/\n+$/g, '');
- break;
- }
-
- return text;
- },
-
- /**
- * Returns true if the next line is indented.
- *
- * @return Boolean Returns true if the next line is indented, false otherwise
- */
- isNextLineIndented: function()
- {
- var currentIndentation = this.getCurrentLineIndentation();
- var notEOF = this.moveToNextLine();
-
- while ( notEOF && this.isCurrentLineEmpty() )
- {
- notEOF = this.moveToNextLine();
- }
-
- if ( false == notEOF )
- {
- return false;
- }
-
- var ret = false;
- if ( this.getCurrentLineIndentation() <= currentIndentation )
- {
- ret = true;
- }
-
- this.moveToPreviousLine();
-
- return ret;
- },
-
- /**
- * Returns true if the current line is blank or if it is a comment line.
- *
- * @return Boolean Returns true if the current line is empty or if it is a comment line, false otherwise
- */
- isCurrentLineEmpty: function()
- {
- return this.isCurrentLineBlank() || this.isCurrentLineComment();
- },
-
- /**
- * Returns true if the current line is blank.
- *
- * @return Boolean Returns true if the current line is blank, false otherwise
- */
- isCurrentLineBlank: function()
- {
- return '' == this.trim(this.currentLine);
- },
-
- /**
- * Returns true if the current line is a comment line.
- *
- * @return Boolean Returns true if the current line is a comment line, false otherwise
- */
- isCurrentLineComment: function()
- {
- //checking explicitly the first char of the trim is faster than loops or strpos
- var ltrimmedLine = this.currentLine.replace(/^ +/g, '');
- return ltrimmedLine.charAt(0) == '#';
- },
-
- /**
- * Cleanups a YAML string to be parsed.
- *
- * @param string value The input YAML string
- *
- * @return string A cleaned up YAML string
- */
- cleanup: function(value)
- {
- value = value.split("\r\n").join("\n").split("\r").join("\n");
-
- if ( !/\n$/.test(value) )
- {
- value += "\n";
- }
-
- // strip YAML header
- var count = 0;
- var regex = /^\%YAML[: ][\d\.]+.*\n/;
- while ( regex.test(value) )
- {
- value = value.replace(regex, '');
- count++;
- }
- this.offset += count;
-
- // remove leading comments
- regex = /^(#.*?\n)+/;
- if ( regex.test(value) )
- {
- var trimmedValue = value.replace(regex, '');
-
- // items have been removed, update the offset
- this.offset += this.subStrCount(value, "\n") - this.subStrCount(trimmedValue, "\n");
- value = trimmedValue;
- }
-
- // remove start of the document marker (---)
- regex = /^\-\-\-.*?\n/;
- if ( regex.test(value) )
- {
- trimmedValue = value.replace(regex, '');
-
- // items have been removed, update the offset
- this.offset += this.subStrCount(value, "\n") - this.subStrCount(trimmedValue, "\n");
- value = trimmedValue;
-
- // remove end of the document marker (...)
- value = value.replace(/\.\.\.\s*$/g, '');
- }
-
- return value;
- },
-
- /**
- * Returns true if the next line starts unindented collection
- *
- * @return Boolean Returns true if the next line starts unindented collection, false otherwise
- */
- isNextLineUnIndentedCollection: function()
- {
- var currentIndentation = this.getCurrentLineIndentation();
- var notEOF = this.moveToNextLine();
-
- while (notEOF && this.isCurrentLineEmpty()) {
- notEOF = this.moveToNextLine();
- }
-
- if (false === notEOF) {
- return false;
- }
-
- var ret = false;
- if (
- this.getCurrentLineIndentation() == currentIndentation
- &&
- this.isStringUnIndentedCollectionItem(this.currentLine)
- ) {
- ret = true;
- }
-
- this.moveToPreviousLine();
-
- return ret;
- },
-
- /**
- * Returns true if the string is unindented collection item
- *
- * @return Boolean Returns true if the string is unindented collection item, false otherwise
- */
- isStringUnIndentedCollectionItem: function(string)
- {
- return (0 === this.currentLine.indexOf('- '));
- },
-
- isObject: function(input)
- {
- return typeof(input) == 'object' && this.isDefined(input);
- },
-
- isEmpty: function(input)
- {
- return input == undefined || input == null || input == '' || input == 0 || input == "0" || input == false;
- },
-
- isDefined: function(input)
- {
- return input != undefined && input != null;
- },
-
- reverseArray: function(input /* Array */)
- {
- var result = [];
- var len = input.length;
- for ( var i = len-1; i >= 0; i-- )
- {
- result.push(input[i]);
- }
-
- return result;
- },
-
- merge: function(a /* Object */, b /* Object */)
- {
- var c = {};
- var i;
-
- for ( i in a )
- {
- if ( a.hasOwnProperty(i) )
- if ( /^\d+$/.test(i) ) c.push(a);
- else c[i] = a[i];
- }
- for ( i in b )
- {
- if ( b.hasOwnProperty(i) )
- if ( /^\d+$/.test(i) ) c.push(b);
- else c[i] = b[i];
- }
-
- return c;
- },
-
- strRepeat: function(str /* String */, count /* Integer */)
- {
- var i;
- var result = '';
- for ( i = 0; i < count; i++ ) result += str;
- return result;
- },
-
- subStrCount: function(string, subString, start, length)
- {
- var c = 0;
-
- string = '' + string;
- subString = '' + subString;
-
- if ( start != undefined ) string = string.substr(start);
- if ( length != undefined ) string = string.substr(0, length);
-
- var len = string.length;
- var sublen = subString.length;
- for ( var i = 0; i < len; i++ )
- {
- if ( subString == string.substr(i, sublen) )
- c++;
- i += sublen - 1;
- }
-
- return c;
- },
-
- trim: function(str /* String */)
- {
- return (str+'').replace(/^ +/,'').replace(/ +$/,'');
- }
-};
-/**
- * YamlEscaper encapsulates escaping rules for single and double-quoted
- * YAML strings.
- *
- * @author Matthew Lewinski <matthew@lewinski.org>
- */
-YamlEscaper = function(){};
-YamlEscaper.prototype =
-{
- /**
- * Determines if a JS value would require double quoting in YAML.
- *
- * @param string value A JS value
- *
- * @return Boolean True if the value would require double quotes.
- */
- requiresDoubleQuoting: function(value)
- {
- return new RegExp(YamlEscaper.REGEX_CHARACTER_TO_ESCAPE).test(value);
- },
-
- /**
- * Escapes and surrounds a JS value with double quotes.
- *
- * @param string value A JS value
- *
- * @return string The quoted, escaped string
- */
- escapeWithDoubleQuotes: function(value)
- {
- value = value + '';
- var len = YamlEscaper.escapees.length;
- var maxlen = YamlEscaper.escaped.length;
- var esc = YamlEscaper.escaped;
- for (var i = 0; i < len; ++i)
- if ( i >= maxlen ) esc.push('');
-
- var ret = '';
- ret = value.replace(new RegExp(YamlEscaper.escapees.join('|'),'g'), function(str){
- for(var i = 0; i < len; ++i){
- if( str == YamlEscaper.escapees[i] )
- return esc[i];
- }
- });
- return '"' + ret + '"';
- },
-
- /**
- * Determines if a JS value would require single quoting in YAML.
- *
- * @param string value A JS value
- *
- * @return Boolean True if the value would require single quotes.
- */
- requiresSingleQuoting: function(value)
- {
- return /[\s'":{}[\],&*#?]|^[-?|<>=!%@`]/.test(value);
- },
-
- /**
- * Escapes and surrounds a JS value with single quotes.
- *
- * @param string value A JS value
- *
- * @return string The quoted, escaped string
- */
- escapeWithSingleQuotes : function(value)
- {
- return "'" + value.replace(/'/g, "''") + "'";
- }
-};
-
-// Characters that would cause a dumped string to require double quoting.
-YamlEscaper.REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
-
-// Mapping arrays for escaping a double quoted string. The backslash is
-// first to ensure proper escaping.
-YamlEscaper.escapees = ['\\\\', '\\"', '"',
- "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07",
- "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f",
- "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17",
- "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f",
- "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9"];
-YamlEscaper.escaped = ['\\"', '\\\\', '\\"',
- "\\0", "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\a",
- "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", "\\x0e", "\\x0f",
- "\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17",
- "\\x18", "\\x19", "\\x1a", "\\e", "\\x1c", "\\x1d", "\\x1e", "\\x1f",
- "\\N", "\\_", "\\L", "\\P"];
-/**
- * YamlUnescaper encapsulates unescaping rules for single and double-quoted
- * YAML strings.
- *
- * @author Matthew Lewinski <matthew@lewinski.org>
- */
-var YamlUnescaper = function(){};
-YamlUnescaper.prototype =
-{
- /**
- * Unescapes a single quoted string.
- *
- * @param string value A single quoted string.
- *
- * @return string The unescaped string.
- */
- unescapeSingleQuotedString: function(value)
- {
- return value.replace(/''/g, "'");
- },
-
- /**
- * Unescapes a double quoted string.
- *
- * @param string value A double quoted string.
- *
- * @return string The unescaped string.
- */
- unescapeDoubleQuotedString: function(value)
- {
- var callback = function(m) {
- return new YamlUnescaper().unescapeCharacter(m);
- };
-
- // evaluate the string
- return value.replace(new RegExp(YamlUnescaper.REGEX_ESCAPED_CHARACTER, 'g'), callback);
- },
-
- /**
- * Unescapes a character that was found in a double-quoted string
- *
- * @param string value An escaped character
- *
- * @return string The unescaped character
- */
- unescapeCharacter: function(value)
- {
- switch (value.charAt(1)) {
- case '0':
- return String.fromCharCode(0);
- case 'a':
- return String.fromCharCode(7);
- case 'b':
- return String.fromCharCode(8);
- case 't':
- return "\t";
- case "\t":
- return "\t";
- case 'n':
- return "\n";
- case 'v':
- return String.fromCharCode(11);
- case 'f':
- return String.fromCharCode(12);
- case 'r':
- return String.fromCharCode(13);
- case 'e':
- return "\x1b";
- case ' ':
- return ' ';
- case '"':
- return '"';
- case '/':
- return '/';
- case '\\':
- return '\\';
- case 'N':
- // U+0085 NEXT LINE
- return "\x00\x85";
- case '_':
- // U+00A0 NO-BREAK SPACE
- return "\x00\xA0";
- case 'L':
- // U+2028 LINE SEPARATOR
- return "\x20\x28";
- case 'P':
- // U+2029 PARAGRAPH SEPARATOR
- return "\x20\x29";
- case 'x':
- return this.pack('n', new YamlInline().hexdec(value.substr(2, 2)));
- case 'u':
- return this.pack('n', new YamlInline().hexdec(value.substr(2, 4)));
- case 'U':
- return this.pack('N', new YamlInline().hexdec(value.substr(2, 8)));
- }
- },
-
- /**
- * @see http://phpjs.org/functions/pack
- * @warning only modes used above copied
- */
- pack: function(B){var g=0,o=1,m="",l="",z=0,p=[],E,s,C,I,h,c;var d,b,x,H,u,e,A,q,D,t,w,a,G,F,y,v,f;while(g<B.length){E=B.charAt(g);s="";g++;while((g<B.length)&&(B.charAt(g).match(/[\d\*]/)!==null)){s+=B.charAt(g);g++}if(s===""){s="1"}switch(E){case"n":if(s==="*"){s=arguments.length-o}if(s>(arguments.length-o)){throw new Error("Warning: pack() Type "+E+": too few arguments")}for(z=0;z<s;z++){m+=String.fromCharCode(arguments[o]>>8&255);m+=String.fromCharCode(arguments[o]&255);o++}break;case"N":if(s==="*"){s=arguments.length-o}if(s>(arguments.length-o)){throw new Error("Warning: pack() Type "+E+": too few arguments")}for(z=0;z<s;z++){m+=String.fromCharCode(arguments[o]>>24&255);m+=String.fromCharCode(arguments[o]>>16&255);m+=String.fromCharCode(arguments[o]>>8&255);m+=String.fromCharCode(arguments[o]&255);o++}break;default:throw new Error("Warning: pack() Type "+E+": unknown format code")}}if(o<arguments.length){throw new Error("Warning: pack(): "+(arguments.length-o)+" arguments unused")}return m}
-}
-
-// Regex fragment that matches an escaped character in a double quoted
-// string.
-// why escape quotes, ffs!
-YamlUnescaper.REGEX_ESCAPED_CHARACTER = '\\\\([0abt\tnvfre "\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})';
-
-/**
- * YamlDumper dumps JS variables to YAML strings.
- *
- * @author Fabien Potencier <fabien@symfony.com>
- */
-var YamlDumper = function(){};
-YamlDumper.prototype =
-{
- /**
- * Dumps a JS value to YAML.
- *
- * @param mixed input The JS value
- * @param integer inline The level where you switch to inline YAML
- * @param integer indent The level o indentation indentation (used internally)
- *
- * @return string The YAML representation of the JS value
- */
- dump: function(input, inline, indent)
- {
- if ( inline == null ) inline = 0;
- if ( indent == null ) indent = 0;
- var output = '';
- var prefix = indent ? this.strRepeat(' ', indent) : '';
- var yaml;
- if (!this.numSpacesForIndentation) this.numSpacesForIndentation = 2;
-
- if ( inline <= 0 || !this.isObject(input) || this.isEmpty(input) )
- {
- yaml = new YamlInline();
- output += prefix + yaml.dump(input);
- }
- else
- {
- var isAHash = !this.arrayEquals(this.getKeys(input), this.range(0,input.length - 1));
- var willBeInlined;
-
- for ( var key in input )
- {
- if ( input.hasOwnProperty(key) )
- {
- willBeInlined = inline - 1 <= 0 || !this.isObject(input[key]) || this.isEmpty(input[key]);
-
- if ( isAHash ) yaml = new YamlInline();
-
- output +=
- prefix + '' +
- (isAHash ? yaml.dump(key)+':' : '-') + '' +
- (willBeInlined ? ' ' : "\n") + '' +
- this.dump(input[key], inline - 1, (willBeInlined ? 0 : indent + this.numSpacesForIndentation)) + '' +
- (willBeInlined ? "\n" : '');
- }
- }
- }
-
- return output;
- },
-
- strRepeat: function(str /* String */, count /* Integer */)
- {
- var i;
- var result = '';
- for ( i = 0; i < count; i++ ) result += str;
- return result;
- },
-
- isObject: function(input)
- {
- return this.isDefined(input) && typeof(input) == 'object';
- },
-
- isEmpty: function(input)
- {
- var ret = input == undefined || input == null || input == '' || input == 0 || input == "0" || input == false;
- if ( !ret && typeof(input) == "object" && !(input instanceof Array)){
- var propCount = 0;
- for ( var key in input )
- if ( input.hasOwnProperty(key) ) propCount++;
- ret = !propCount;
- }
- return ret;
- },
-
- isDefined: function(input)
- {
- return input != undefined && input != null;
- },
-
- getKeys: function(tab)
- {
- var ret = [];
-
- for ( var name in tab )
- {
- if ( tab.hasOwnProperty(name) )
- {
- ret.push(name);
- }
- }
-
- return ret;
- },
-
- range: function(start, end)
- {
- if ( start > end ) return [];
-
- var ret = [];
-
- for ( var i = start; i <= end; i++ )
- {
- ret.push(i);
- }
-
- return ret;
- },
-
- arrayEquals: function(a,b)
- {
- if ( a.length != b.length ) return false;
-
- var len = a.length;
-
- for ( var i = 0; i < len; i++ )
- {
- if ( a[i] != b[i] ) return false;
- }
-
- return true;
- }
-};
-})();
diff --git a/bin/yaml.min.js b/bin/yaml.min.js
deleted file mode 100644
index c1440ac..0000000
--- a/bin/yaml.min.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright (c) 2010 Jeremy Faivre
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is furnished
-to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
diff --git a/bin/yaml2json b/bin/yaml2json
index 3d9075c..550230c 100755
--- a/bin/yaml2json
+++ b/bin/yaml2json
@@ -4,7 +4,7 @@
* yaml2json cli program
*/
-var YAML = require('./yaml.js');
+var YAML = require('../lib/Yaml.js');
var ArgumentParser = require('argparse').ArgumentParser;
var cli = new ArgumentParser({
@@ -55,7 +55,7 @@ cli.addArgument(
);
cli.addArgument(['input'], {
- help: 'YAML file or directory containing YAML files.'
+ help: 'YAML file or directory containing YAML files or - to read YAML from stdin.'
});
try {
@@ -66,6 +66,7 @@ try {
var rootPath = process.cwd();
var parsePath = function(input) {
+ if (input == '-') return '-';
var output;
if (!(input != null)) {
return rootPath;
@@ -85,38 +86,50 @@ try {
// Find files
var findFiles = function(input) {
- var isDirectory = fs.statSync(input).isDirectory();
- var files = [];
+ if (input != '-' && input != null) {
+ var isDirectory = fs.statSync(input).isDirectory();
+ var files = [];
- if (!isDirectory) {
- files.push(input);
- }
- else {
- if (options.recursive) {
- files = files.concat(glob.sync(input+'/**/*.yml'));
- files = files.concat(glob.sync(input+'/**/*.yaml'));
+ if (!isDirectory) {
+ files.push(input);
}
else {
- files = files.concat(glob.sync(input+'/*.yml'));
- files = files.concat(glob.sync(input+'/*.yaml'));
+ if (options.recursive) {
+ files = files.concat(glob.sync(input+'/**/*.yml'));
+ files = files.concat(glob.sync(input+'/**/*.yaml'));
+ }
+ else {
+ files = files.concat(glob.sync(input+'/*.yml'));
+ files = files.concat(glob.sync(input+'/*.yaml'));
+ }
}
+
+ return files;
}
-
- return files;
+ return null;
};
// Convert to JSON
- var convertToJSON = function(input, pretty, save, spaces) {
+ var convertToJSON = function(input, pretty, save, spaces, str) {
var json;
if (spaces == null) spaces = 2;
- if (pretty) {
- json = JSON.stringify(YAML.load(input), null, spaces);
- }
- else {
- json = JSON.stringify(YAML.load(input));
+ if (str != null) {
+ if (pretty) {
+ json = JSON.stringify(YAML.parse(str), null, spaces);
+ }
+ else {
+ json = JSON.stringify(YAML.parse(str));
+ }
+ } else {
+ if (pretty) {
+ json = JSON.stringify(YAML.parseFile(input), null, spaces);
+ }
+ else {
+ json = JSON.stringify(YAML.parseFile(input));
+ }
}
- if (!save) {
+ if (!save || input == null) {
// Ouput result
process.stdout.write(json+"\n");
}
@@ -146,18 +159,30 @@ try {
var runCommand = function() {
try {
var files = findFiles(input);
- var len = files.length;
-
- for (var i = 0; i < len; i++) {
- var file = files[i];
- var stat = fs.statSync(file);
- var time = stat.mtime.getTime();
- if (!stat.isDirectory()) {
- if (!mtimes[file] || mtimes[file] < time) {
- mtimes[file] = time;
- convertToJSON(file, options.pretty, options.save, options.indentation);
+ if (files != null) {
+ var len = files.length;
+
+ for (var i = 0; i < len; i++) {
+ var file = files[i];
+ var stat = fs.statSync(file);
+ var time = stat.mtime.getTime();
+ if (!stat.isDirectory()) {
+ if (!mtimes[file] || mtimes[file] < time) {
+ mtimes[file] = time;
+ convertToJSON(file, options.pretty, options.save, options.indentation);
+ }
}
}
+ } else {
+ // Read from STDIN
+ var stdin = process.openStdin();
+ var data = "";
+ stdin.on('data', function(chunk) {
+ data += chunk;
+ });
+ stdin.on('end', function() {
+ convertToJSON(null, options.pretty, options.save, options.indentation, data);
+ });
}
} catch (e) {
process.stderr.write((e.message ? e.message : e)+"\n");