// ----------------------------------------
// Data
pub.JSON = {
/**
* Function parses and validates a string as JSON-object. Usage:
* var obj = b.JSON.decode(str);
* var str = b.JSON.encode(obj);
*
* @cat Data
* @subcat JSON
* @method JSON.decode
* @param {String} String to be parsed as JSON-object.
* @return {Object} Returns JSON-object or throws an error if invalid JSON has been provided.
*/
// From: jQuery JavaScript Library v1.7.1 http://jquery.com/
decode: function(data) {
if ( typeof data !== "string" || !data ) {
return null;
}
var rvalidchars = /^[\],:{}\s]*$/,
rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
// Make sure the incoming data is actual JSON
// Logic borrowed from http://json.org/json2.js
if ( rvalidchars.test( data.replace( rvalidescape, "@" )
.replace( rvalidtokens, "]" )
.replace( rvalidbraces, "")) ) {
return ( new Function( "return " + data ) )();
}
error( "b.JSON.decode(), invalid JSON: " + data );
},
/**
* Function convert an javascript object to a JSON-string. Usage:
* var str = b.JSON.encode(obj);
* var obj = b.JSON.decode(str);
*
* @cat Data
* @subcat JSON
* @method JSON.encode
* @param {Object} Object to be converted to a JSON-string
* @return {String} Returns JSON-string
*/
// From: https://gist.github.com/754454
encode: function(obj) {
var t = typeof (obj);
if (t !== "object" || obj === null) {
// simple data type
if (t === "string") obj = '"' + obj + '"';
return String(obj);
} else {
// recurse array or object
var n, v, json = [], arr = (obj && obj.constructor === Array);
for (n in obj) {
v = obj[n];
t = typeof(v);
if (obj.hasOwnProperty(n)) {
if (t === "string") v = '"' + v + '"'; else if (t === "object" && v !== null) v = pub.JSON.encode(v);
json.push((arr ? "" : '"' + n + '":') + String(v));
}
}
return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
}
}
};
// Taken and hijacked from d3.js robust csv parser. Hopefully Michael Bostock won't mind.
// https://github.com/mbostock/d3/tree/master/src/dsv
pub.CSV = new CSV();
function CSV() {
var reParse = null,
reFormat = null,
delimiterStr = null,
delimiterCode = null;
initDelimiter(',');
function initDelimiter(delimiter) {
reParse = new RegExp("\r\n|[" + delimiter + "\r\n]", "g"), // field separator regex
reFormat = new RegExp("[\"" + delimiter + "\n]"),
delimiterCode = delimiter.charCodeAt(0);
delimiterStr = delimiter;
};
/**
* Sets the delimiter of the CSV decode and encode function.
*
* @cat Data
* @subcat CSV
* @method CSV.delimiter
* @param {String} [delimiter] Optional Sets the delimiter for CSV parsing
* @return {String} Returns the current delimiter if called without argument
*/
this.delimiter = function(delimiter) {
if (arguments.length === 0) return delimiterStr;
if (typeof delimiter === 'string') {
initDelimiter(delimiter);
} else {
error("b.CSV.delimiter, separator has to be a character or string");
}
};
/**
* Function parses a string as CSV-object Array. Usage:
* var arr = b.CSV.decode(str);
* var str = b.CSV.encode(arr);
*
* @cat Data
* @subcat CSV
* @method CSV.decode
* @param {String} String to be parsed as CSV-object.
* @return {Array} Returns CSV-object Array
*/
this.decode = function(text) {
var header;
return parseRows(text, function(row, i) {
if (i) {
var o = {}, j = -1, m = header.length;
while (++j < m) o[header[j]] = row[j];
return o;
} else {
header = row;
return null;
}
});
};
/**
* Function convert an javascript array of objects to a CSV-string. Usage:
* var str = b.CSV.encode(arr);
* var arr = b.CSV.decode(str);
*
* @cat Data
* @subcat CSV
* @method CSV.encode
* @param {Array} Array to be converted to a CSV-string
* @return {String} Returns CSV-string
*/
this.encode = function(rows) {
var csvStrings = [];
var header = [];
var firstRow = rows[0]; // all rows have to have the same properties keys
// gather infos for the header
for (var propname in firstRow) {
if (firstRow.hasOwnProperty(propname)) {
header.push(propname);
};
};
csvStrings.push( formatRow(header) );
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
var tokens = [];
for (var ii = 0; ii < header.length; ii++) {
tokens.push(row[header[ii]]);
};
csvStrings.push( formatRow(tokens) );
};
return csvStrings.join("\n");
};
function formatRow(row) {
return row.map(formatValue).join(delimiterStr);
}
function formatValue(text) {
return reFormat.test(text) ? "\"" + text.replace(/\"/g, "\"\"") + "\"" : text;
}
function parseRows(text, f) {
var EOL = {}, // sentinel value for end-of-line
EOF = {}, // sentinel value for end-of-file
rows = [], // output rows
n = 0, // the current line number
t, // the current token
eol; // is the current token followed by EOL?
reParse.lastIndex = 0; // work-around bug in FF 3.6
function token() {
if (reParse.lastIndex >= text.length) return EOF; // special case: end of file
if (eol) { eol = false; return EOL; } // special case: end of line
// special case: quotes
var j = reParse.lastIndex;
if (text.charCodeAt(j) === 34) {
var i = j;
while (i++ < text.length) {
if (text.charCodeAt(i) === 34) {
if (text.charCodeAt(i + 1) !== 34) break;
i++;
}
}
reParse.lastIndex = i + 2;
var c = text.charCodeAt(i + 1);
if (c === 13) {
eol = true;
if (text.charCodeAt(i + 2) === 10) reParse.lastIndex++;
} else if (c === 10) {
eol = true;
}
return text.substring(j + 1, i).replace(/""/g, "\"");
}
// common case
var m = reParse.exec(text);
if (m) {
eol = m[0].charCodeAt(0) !== delimiterCode;
return text.substring(j, m.index);
}
reParse.lastIndex = text.length;
return text.substring(j);
}
while ((t = token()) !== EOF) {
var a = [];
while (t !== EOL && t !== EOF) {
a.push(t);
t = token();
}
if (f && !(a = f(a, n++))) continue;
rows.push(a);
}
return rows;
};
};
// -- Conversion --
/** @class b */
/**
* Converts a byte, char, int, or color to a String containing the
* equivalent binary notation. For example color(0, 102, 153, 255)
* will convert to the String "11111111000000000110011010011001". This
* function can help make your geeky debugging sessions much happier.
*
* @cat Data
* @subcat Conversion
* @method binary
* @param {Number} num value to convert
* @param {Number} [numBits] number of digits to return
* @return {String} A formatted string
*/
// From: http://processingjs.org/reference/binary_/
pub.binary = function(num, numBits) {
var bit;
if (numBits > 0) bit = numBits;
else if (num instanceof Char) {
bit = 16;
num |= 0;
} else {
bit = 32;
while (bit > 1 && !(num >>> bit - 1 & 1)) bit--;
}
var result = "";
while (bit > 0) result += num >>> --bit & 1 ? "1" : "0";
return result;
};
/**
* Converts a String representation of a binary number to its
* equivalent integer value. For example, unbinary("00001000") will
* return 8.
*
* @cat Data
* @subcat Conversion
* @method unbinary
* @param {String} binaryString value to convert
* @return {Number} The integer representation
*/
// From: http://processingjs.org/reference/unbinary_/
pub.unbinary = function(binaryString) {
var i = binaryString.length - 1,
mask = 1,
result = 0;
while (i >= 0) {
var ch = binaryString[i--];
if (ch !== "0" && ch !== "1") throw "the value passed into unbinary was not an 8 bit binary number";
if (ch === "1") result += mask;
mask <<= 1;
}
return result;
};
var decimalToHex = function(d, padding) {
padding = padding === undef || padding === null ? padding = 8 : padding;
if (d < 0) d = 4294967295 + d + 1;
var hex = Number(d).toString(16).toUpperCase();
while (hex.length < padding) hex = "0" + hex;
if (hex.length >= padding) hex = hex.substring(hex.length - padding, hex.length);
return hex;
};
/**
* Convert a number to a hex representation.
*
* @cat Data
* @subcat Conversion
* @method hex
* @param {Number} value The number to convert
* @param {Number} [len] The length of the hex number to be created, default: 8
* @return {String} The hex representation as a string
*/
pub.hex = function(value, len) {
if (arguments.length === 1) len = 8;
return decimalToHex(value, len);
};
var unhexScalar = function(hex) {
var value = parseInt("0x" + hex, 16);
if (value > 2147483647) value -= 4294967296;
return value;
}
/**
* Convert a hex representation to a number.
*
* @cat Data
* @subcat Conversion
* @method unhex
* @param {String} hex The hex representation
* @return {Number} The number
*/
pub.unhex = function(hex) {
if (hex instanceof Array) {
var arr = [];
for (var i = 0; i < hex.length; i++) arr.push(unhexScalar(hex[i]));
return arr;
}
return unhexScalar(hex);
};
// -- String Functions --
/**
* Removes multiple, leading or trailing spaces and punctuation from "words". E.g. converts "word!" to "word". Especially useful together with b.words();
*
* @method trimWord
* @cat Data
* @subcat String Functions
* @param {String} s The String to trim
* @param
*/
// from: http://www.qodo.co.uk/blog/javascript-trim-leading-and-trailing-spaces/
pub.trimWord = function(s) {
s = s.replace(/(^[,.!?-]*)|([-,.!?]*$)/gi,"");
s = s.replace(/\s*/gi,"");
// s = s.replace(/[ ]{2,}/gi," ");
s = s.replace(/\n*/,"");
return s;
};
/**
* Combines an array of Strings into one String, each separated by
* the character(s) used for the separator parameter. To join arrays
* of ints or floats, it's necessary to first convert them to strings
* using nf() or nfs().
*
* @method join
* @cat Data
* @subcat String Functions
* @param {Array} array A string array
* @param {String} separator The separator to be inserted
* @return {String} The joined string
*/
// http://processingjs.org/reference/join_/
pub.join = function(array, separator) {
return array.join(separator);
};
/**
* The split() function breaks a string into pieces using a
* character or string as the divider. The delim parameter specifies the
* character or characters that mark the boundaries between each piece. A
* String[] array is returned that contains each of the pieces.
*
* If the result is a set of numbers, you can convert the String[] array
* to to a float[] or int[] array using the datatype conversion functions
* int() and float() (see example above).
*
* The splitTokens() function works in a similar fashion, except that it
* splits using a range of characters instead of a specific character or
* sequence.
*
* @cat Data
* @subcat String Functions
* @method split
* @param {String} str the String to be split
* @param {String} [delim] The string used to separate the data
* @return {Array} Array of strings
*/
// http://processingjs.org/reference/split_/
pub.split = function(str, delim) {
return str.split(delim);
};
/**
* The splitTokens() function splits a String at one or many character
* "tokens." The tokens parameter specifies the character or characters
* to be used as a boundary.
*
* If no tokens character is specified, any whitespace character is used
* to split. Whitespace characters include tab (\t), line feed (\n),
* carriage return (\r), form feed (\f), and space. To convert a String
* to an array of integers or floats, use the datatype conversion functions
* int() and float() to convert the array of Strings.
*
* @cat Data
* @subcat String Functions
* @method splitTokens
* @param {String} str the String to be split
* @param {String} [tokens] list of individual characters that will be used as separators
* @return {Array} Array of strings
*/
// From: http://processingjs.org/reference/splitTokens_/
pub.splitTokens = function(str, tokens) {
if (arguments.length === 1) tokens = "\n\t\r\u000c ";
tokens = "[" + tokens + "]";
var ary = [];
var index = 0;
var pos = str.search(tokens);
while (pos >= 0) {
if (pos === 0) str = str.substring(1);
else {
ary[index] = str.substring(0, pos);
index++;
str = str.substring(pos);
}
pos = str.search(tokens);
}
if (str.length > 0) ary[index] = str;
if (ary.length === 0) ary = undef;
return ary;
};
/* todo */
pub.match = function(str, regexp) {
return str.match(regexp);
};
/* todo */
pub.matchAll = function(aString, aRegExp) {
var results = [],
latest;
var regexp = new RegExp(aRegExp, "g");
while ((latest = regexp.exec(aString)) !== null) {
results.push(latest);
if (latest[0].length === 0)++regexp.lastIndex;
}
return results.length > 0 ? results : null;
};
function nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group) {
var sign = value < 0 ? minus : plus;
var autoDetectDecimals = rightDigits === 0;
var rightDigitsOfDefault = rightDigits === undef || rightDigits < 0 ? 0 : rightDigits;
var absValue = Math.abs(value);
if (autoDetectDecimals) {
rightDigitsOfDefault = 1;
absValue *= 10;
while (Math.abs(Math.round(absValue) - absValue) > 1.0E-6 && rightDigitsOfDefault < 7) {
++rightDigitsOfDefault;
absValue *= 10;
}
} else if (rightDigitsOfDefault !== 0) absValue *= Math.pow(10, rightDigitsOfDefault);
var number, doubled = absValue * 2;
if (Math.floor(absValue) === absValue) number = absValue;
else if (Math.floor(doubled) === doubled) {
var floored = Math.floor(absValue);
number = floored + floored % 2;
} else number = Math.round(absValue);
var buffer = "";
var totalDigits = leftDigits + rightDigitsOfDefault;
while (totalDigits > 0 || number > 0) {
totalDigits--;
buffer = "" + number % 10 + buffer;
number = Math.floor(number / 10);
}
if (group !== undef) {
var i = buffer.length - 3 - rightDigitsOfDefault;
while (i > 0) {
buffer = buffer.substring(0, i) + group + buffer.substring(i);
i -= 3;
}
}
if (rightDigitsOfDefault > 0) return sign + buffer.substring(0, buffer.length - rightDigitsOfDefault) + "." + buffer.substring(buffer.length - rightDigitsOfDefault, buffer.length);
return sign + buffer;
}
function nfCore(value, plus, minus, leftDigits, rightDigits, group) {
if (value instanceof Array) {
var arr = [];
for (var i = 0, len = value.length; i < len; i++) arr.push(nfCoreScalar(value[i], plus, minus, leftDigits, rightDigits, group));
return arr;
}
return nfCoreScalar(value, plus, minus, leftDigits, rightDigits, group);
}
/**
* Utility function for formatting numbers into strings. There
* are two versions, one for formatting floats and one for formatting
* ints. The values for the digits, left, and right parameters should
* always be positive integers.
* As shown in the above example, nf() is used to add zeros to the
* left and/or right of a number. This is typically for aligning a list
* of numbers. To remove digits from a floating-point number, use the
* int(), ceil(), floor(), or round() functions.
*
* @cat Data
* @subcat String Functions
* @method nf
* @param {Number} value The Number to convert
* @param {Number} leftDigits
* @param {Number} rightDigits
* @return {String} The formatted string
*/
// From: http://processingjs.org/reference/nf_/
pub.nf = function(value, leftDigits, rightDigits) {
return nfCore(value, "", "-", leftDigits, rightDigits);
};
/**
* Utility function for formatting numbers into strings. Similar to nf()
* but leaves a blank space in front of positive numbers so they align
* with negative numbers in spite of the minus symbol. There are two
* versions, one for formatting floats and one for formatting ints. The
* values for the digits, left, and right parameters should always be
* positive integers.
*
* @cat Data
* @subcat String Functions
* @method nfs
* @param {Number} value The Number to convert
* @param {Number} leftDigits
* @param {Number} rightDigits
* @return {String} The formatted string
*/
// From: http://processingjs.org/reference/nfs_/
pub.nfs = function(value, leftDigits, rightDigits) {
return nfCore(value, " ", "-", leftDigits, rightDigits);
};
/**
* Utility function for formatting numbers into strings. Similar to nf()
* but puts a "+" in front of positive numbers and a "-" in front of
* negative numbers. There are two versions, one for formatting floats
* and one for formatting ints. The values for the digits, left, and right
* parameters should always be positive integers.
*
* @cat Data
* @subcat String Functions
* @method nfp
* @param {Number} value The Number to convert
* @param {Number} leftDigits
* @param {Number} rightDigits
* @return {String} The formatted string
*/
// From: http://processingjs.org/reference/nfp_/
pub.nfp = function(value, leftDigits, rightDigits) {
return nfCore(value, "+", "-", leftDigits, rightDigits);
};
/**
* Utility function for formatting numbers into strings and placing
* appropriate commas to mark units of 1000. There are two versions, one
* for formatting ints and one for formatting an array of ints. The value
* for the digits parameter should always be a positive integer.
*
* @cat Data
* @subcat String Functions
* @method nfc
* @param {Number} value The Number to convert
* @param {Number} leftDigits
* @param {Number} rightDigits
* @return {String} The formatted string
*/
// From: http://processingjs.org/reference/nfc_/
pub.nfc = function(value, leftDigits, rightDigits) {
return nfCore(value, "", "-", leftDigits, rightDigits, ",");
};
/**
* Removes whitespace characters from the beginning and end of a String.
* In addition to standard whitespace characters such as space, carriage
* return, and tab, this function also removes the Unicode "nbsp" character.
*
* @cat Data
* @subcat String Functions
* @method trim
* @param {String|Array} str A string or an array of strings to be trimmed
* @return {String|Array} Returns the input in a trimmed way
*/
// From: http://processingjs.org/reference/trim_/
pub.trim = function(str) {
if (str instanceof Array) {
var arr = [];
for (var i = 0; i < str.length; i++) arr.push(str[i].replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, ""));
return arr;
}
return str.replace(/^\s*/, "").replace(/\s*$/, "").replace(/\r*$/, "");
};
/**
* Checks whether an URL string is valid.
*
* @cat Data
* @subcat String Functions
* @method isURL
* @param {String} url An url string to be checked
* @return {Boolean} Returns either true or false
*/
var isURL = pub.isURL = function(url) {
var pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
return pattern.test(url);
};
/**
* Checks whether a string ends with a specific character or string.
*
* @cat Data
* @subcat String Functions
* @method endsWith
* @param {String} str A string to be checked
* @param {String} suffix The string to look for
* @return {Boolean} Returns either true or false
*/
var endsWith = pub.endsWith = function(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
};
/**
* Checks whether a string starts with a specific character or string.
*
* @cat Data
* @subcat String Functions
* @method startsWith
* @param {String} str A string to be checked
* @param {String} prefix The string to look for
* @return {Boolean} Returns either true or false
*/
var startsWith = pub.startsWith = function(str, prefix) {
return str.indexOf(prefix) === 0;
};
/**
* Checks whether a var is an Array, returns true if this is the case
*
* @cat Data
* @subcat Type-Check
* @method isArray
* @param {Object|String|Number|Boolean} obj The object to check
* @return {Boolean} returns true if this is the case
*/
var isArray = pub.isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
};
/**
* Checks whether a var is a number, returns true if this is the case
*
* @cat Data
* @subcat Type-Check
* @method isNumber
* @param {Object|String|Number|Boolean} num The number to check
* @return {Boolean} returns true if this is the case
*/
var isNumber = pub.isNumber = function(num) {
return !isNaN(parseFloat(num)) && isFinite(num);
};
/**
* Checks whether a var is a string, returns true if this is the case
*
* @cat Data
* @subcat Type-Check
* @method isString
* @param {Object|String|Number|Boolean} str The string to check
* @return {Boolean} returns true if this is the case
*/
var isString = pub.isString = function(str) {
return Object.prototype.toString.call(str) === '[object String]';
};
/**
* Checks whether a var is an indesign text object, returns true if this is the case
* NB: a indesign TextFrame will return false as it is just a container holding text.
* So you could say that isText() refers to all the things inside a TextFrame.
*
* @cat Document
* @subcat Type-Check
* @method isText
* @param {Character|InsertionPoint|Line|Paragraph|TextColumn|TextStyleRange|Word} obj The object to check
* @return {Boolean} returns true if this is the case
*/
var isText = pub.isText = function(obj) {
return obj instanceof Character ||
obj instanceof InsertionPoint ||
obj instanceof Line ||
obj instanceof Paragraph ||
obj instanceof TextColumn ||
obj instanceof TextStyleRange ||
obj instanceof Word;
};
var initDataFile = function(file, mustExist) {
var result = null;
if (file instanceof File) {
result = file;
} else {
var folder = new Folder(projectFolder().absoluteURI + '/data');
folder.create(); // creates data folder if not existing, otherwise it just skips
result = new File(folder.absoluteURI + '/' + file);
}
if (mustExist && !result.exists) {
error('The file "' + result + '" does not exist.');
}
return result;
};
var initExportFile = function(file, mustExist) {
var result = null;
if (file instanceof File) {
result = file;
} else {
// get rid of some special cases the user might specify
var pathNormalized = file.split("/");
for (var i = 0; i < pathNormalized.length; i++) {
if (pathNormalized[i] === "" || pathNormalized[i] === ".") {
pathNormalized.splice(i,1);
};
};
var tmpPath = projectFolder().absoluteURI;
var fileName = pathNormalized[pathNormalized.length-1];
// contains the path folders? if so create them ...
if (pathNormalized.length > 1) {
var folders = pathNormalized.slice(0,-1);
for (var i = 0; i < folders.length; i++) {
tmpPath += "/"+folders[i]
var f = new Folder(tmpPath);
if (!f.exists) f.create();
};
}
// result = new File(projectFolder().absoluteURI + '/' + file);
result = new File(tmpPath + '/' + fileName);
}
if (mustExist && !result.exists) {
error('The file "' + result + '" does not exist.');
}
return result;
};
/**
* Get the folder of the active document as a Folder object. Use .absoluteURI to access a string representation of the folder path.
*
* @cat Document
* @subcat Misc
* @method projectFolder
* @return {Folder} The folder of the the active document
*/
var projectFolder = pub.projectFolder = function() {
var docPath = null;
try {
docPath = currentDoc().filePath;
} catch (e) {
error("The current document must be saved before its project directory can be accessed.");
}
return docPath;
};
/**
* Executes a shell command and returns the result, currently Mac only.
*
* BE CAREFUL!
*
* @cat Data
* @subcat Input
* @method shellExecute
* @param {String} cmd The shell command to execute
* @return {String}
*/
pub.shellExecute = function(cmd) {
if (Folder.fs === "Macintosh") {
try {
return app.doScript("return do shell script item 1 of arguments", ScriptLanguage.applescriptLanguage, [cmd]);
} catch (e) {
error("b.shellExecute(): "+e);
}
} else {
error("b.shellExecute() is a Mac only feature at the moment. Sorry!")
}
};
/**
* Reads the contents of a file or loads an URL into a String.
* If the file is specified by name as String, it must be located in the document's data directory.
*
* @cat Data
* @subcat Input
* @method loadString
* @param {String|File} fileOrString The text file name in the document's data directory or a File instance or an URL
* @return {String} String file or URL content.
*/
pub.loadString = function(fileOrString) {
if (isURL(fileOrString)) {
return getURL(fileOrString);
} else {
var inputFile = initDataFile(fileOrString, true),
data = null;
inputFile.open('r');
data = inputFile.read();
inputFile.close();
return data;
}
};
var getURL = function(url) {
if (isURL(url)) {
if (Folder.fs === "Macintosh") {
return pub.shellExecute("curl -m 15 -L '"+url+"'");
} else {
error("Loading of strings via an URL is a Mac only feature at the moment. Sorry!")
}
} else {
error("The url "+url+" is not a valid one. Please double check!")
}
};
/**
* Reads the contents of a file or loads an URL and creates a String array of its individual lines.
* If the file is specified by name as String, it must be located in the document's data directory.
*
* @cat Data
* @subcat Input
* @method loadStrings
* @param {String|File} file The text file name in the document's data directory or a File instance or an URL
* @return {String[]} Array of the individual lines in the given File or URL
*/
pub.loadStrings = function(file) {
if (isURL(file)) {
var result = getURL(file);
return result.match(/[^\r\n]+/g);
} else {
var inputFile = initDataFile(file, true),
result = [];
inputFile.open('r');
while (!inputFile.eof) {
result.push(inputFile.readln());
}
inputFile.close();
return result;
}
};
// ----------------------------------------
// Output
/**
* Prints a message line to the console output in the ExtendScript editor.
*
* @cat Output
* @method println
* @param {String} msg The message to print
*/
var println = pub.println = function(msg) {
$.writeln(msg);
if (progressPanel)
progressPanel.writeMessage(msg + "\n");
};
/**
* Prints a message to the console output in the ExtendScript editor, but unlike b.println() it doesn't return the carriage to a new line at the end.
*
* @cat Output
* @method print
* @param {String} msg The message to print
*/
pub.print = function(msg) {
$.write(msg);
if (progressPanel)
progressPanel.writeMessage(msg);
};
/**
* Print numerous information about the current environment to the console
*
* @cat Output
* @method printInfo
*/
pub.printInfo = function() {
pub.println("###");
pub.println("OS: " + $.os);
pub.println("ExtendScript Build: " + $.build);
pub.println("ExtendScript Version:" + $.version);
pub.println("Engine: " + $.engineName);
pub.println("memCache: " + $.memCache + " bytes");
pub.println("###");
};
/**
* Writes an array of strings to a file, one line per string.
* If the given file exists it gets overridden.
*
* @cat Output
* @method saveStrings
* @param {String|File} file The file name or a File instance
* @param {String[]} strings The string array to be written
*/
pub.saveStrings = function(file, strings) {
var outputFile = initDataFile(file);
outputFile.open('w');
forEach(strings, function(s) {
outputFile.writeln(s);
});
outputFile.close();
};
/**
* Writes a string to a file.
* If the given file exists it gets overridden.
*
* @cat Output
* @method saveString
* @param {String|File} file The file name or a File instance
* @param {String} string The string to be written
*/
pub.saveString = function(file, string) {
var outputFile = initDataFile(file);
outputFile.open('w');
outputFile.write(string);
outputFile.close();
};
// TODO: make savePDF and savePNG D.R.Y.
/**
* Exports the current document as PDF to the documents folder. Please note, that export options default to the last used export settings.
*
* @cat Output
* @method savePDF
* @param {String|File} file The file name or a File instance
* @param {Boolean} [showOptions] Whether to show the export dialog
*/
pub.savePDF = function(file, showOptions){
var outputFile = initExportFile(file);
if (typeof showOptions !== "boolean") showOptions = false;
currentDoc().exportFile(ExportFormat.PDF_TYPE, outputFile, showOptions);
};
/**
* Exports the current document as PNG (or sequence of PNG files) to the documents folder. Please note, that export options default to the last used export settings.
*
* @cat Output
* @method savePNG
* @param {String|File} file The file name or a File instance
* @param {Boolean} [showOptions] Whether to show the export dialog
*/
pub.savePNG = function(file, showOptions){
var outputFile = initExportFile(file);
if (typeof showOptions !== "boolean") showOptions = false;
currentDoc().exportFile(ExportFormat.PNG_FORMAT, outputFile, showOptions);
};
/**
* Downloads an URL to a file, currently Mac only.
*
* @cat Output
* @method download
* @param {String} url The download url
* @param {String|File} [file] A relative file path in the project folder or a File instance
*/
pub.download = function(url, file){
var projPath = projectFolder().fsName.replace(" ","\\ ");
var scriptPath = "~/Documents/basiljs/bundle/lib/download.sh";
if (isURL(url)) {
var cmd = null;
if (file) {
if (file instanceof File) {
var downloadFolder = file.parent.fsName;
var fileName = file.displayName;
downloadFolder = downloadFolder.replace(" ","\\ ");
fileName = fileName.replace(" ","\\ ");
cmd = ["sh",scriptPath,downloadFolder,url,fileName].join(" ");
} else {
var downloadFolder = file.substr(0,file.lastIndexOf("/"));
var fileName = file.substr(file.lastIndexOf("/")+1);
// get rif of some special cases
if(startsWith(downloadFolder,"./")) downloadFolder.substr(2);
if(startsWith(downloadFolder,"/")) downloadFolder.substr(1);
downloadFolder = downloadFolder.replace(" ","\\ ");
fileName = fileName.replace(" ","\\ ");
downloadFolder = projPath + "/data/"+ downloadFolder;
cmd = ["sh",scriptPath,downloadFolder,url,fileName].join(" ");
}
} else {
var downloadFolder = projPath + "/data/download";
var cmd = ["sh",scriptPath,downloadFolder,url].join(" ");
}
println(cmd);
pub.shellExecute(cmd);
} else {
error("The url "+url+" is not a valid one. Please double check!")
}
};