bsw@0: function stringthesizer(options, struct) { bsw@0: // options: bsw@0: // nextPlaceholder (function) bsw@0: // valueSeparator (string) bsw@0: // coerce (function) bsw@0: var cmdParts = []; bsw@0: var args = []; bsw@0: var process = function(struct, skipCoercion) { bsw@0: if (struct instanceof Array) { bsw@0: var structIdx = 0; bsw@0: var next = function() { return struct[structIdx++]; }; bsw@0: next().match(/[^?$]+|\?\??\??|\$\$?\$?/g).forEach(function(stringPart) { bsw@0: if (stringPart == "?") { bsw@0: cmdParts.push(options.nextPlaceholder(args.length)); bsw@0: args.push(next()) bsw@0: } else if (stringPart == "??") { bsw@0: var first = true; bsw@0: next().forEach(function(entry) { bsw@0: if (first) first = false; bsw@0: else cmdParts.push(options.valueSeparator); bsw@0: cmdParts.push(options.nextPlaceholder(args.length)); bsw@0: args.push(entry) bsw@0: }); bsw@0: } else if (stringPart == "???") { bsw@0: cmdParts.push("?"); bsw@0: } else if (stringPart == "$") { bsw@0: process(next()); bsw@0: } else if (stringPart == "$$") { bsw@0: var sep = next(); bsw@0: var first = true; bsw@0: next().forEach(function(entry) { bsw@0: if (first) first = false; bsw@0: else cmdParts.push(sep); bsw@0: process(entry); bsw@0: }); bsw@0: } else if (stringPart == "$$$") { bsw@0: cmdParts.push("$"); bsw@0: } else { bsw@0: cmdParts.push(stringPart); bsw@0: } bsw@0: }); bsw@0: if (structIdx != struct.length) { throw "Wrong argument count for stringthesizer"; } bsw@0: } else if (skipCoercion || typeof (struct) == 'string') { bsw@0: cmdParts.push(struct); bsw@0: } else { bsw@0: process(options.coerce(struct), true); bsw@0: } bsw@0: } bsw@0: process(struct); bsw@0: return { cmd: cmdParts.join(""), args: args }; bsw@0: } bsw@0: bsw@0: exports.stringthesizer = stringthesizer;