blob: a65bcf1ba47bc4815ed1c6492a137956b6858f7a [file] [log] [blame]
var pbxProj = require('./pbxProject'),
util = require('util'),
f = util.format,
INDENT = '\t',
COMMENT_KEY = /_comment$/,
QUOTED = /^"(.*)"$/,
EventEmitter = require('events').EventEmitter
// indentation
function i(x) {
if (x <=0)
return '';
else
return INDENT + i(x-1);
}
function comment(key, parent) {
var text = parent[key + '_comment'];
if (text)
return text;
else
return null;
}
// copied from underscore
function isObject(obj) {
return obj === Object(obj)
}
function isArray(obj) {
return Array.isArray(obj)
}
function pbxWriter(contents) {
this.contents = contents;
this.sync = false;
this.indentLevel = 0;
}
util.inherits(pbxWriter, EventEmitter);
pbxWriter.prototype.write = function (str) {
var fmt = f.apply(null, arguments);
if (this.sync) {
this.buffer += f("%s%s", i(this.indentLevel), fmt);
} else {
// do stream write
}
}
pbxWriter.prototype.writeFlush = function (str) {
var oldIndent = this.indentLevel;
this.indentLevel = 0;
this.write.apply(this, arguments)
this.indentLevel = oldIndent;
}
pbxWriter.prototype.writeSync = function () {
this.sync = true;
this.buffer = "";
this.writeHeadComment();
this.writeProject();
return this.buffer;
}
pbxWriter.prototype.writeHeadComment = function () {
if (this.contents.headComment) {
this.write("// %s\n", this.contents.headComment)
}
}
pbxWriter.prototype.writeProject = function () {
var proj = this.contents.project,
key, cmt, obj;
this.write("{\n")
if (proj) {
this.indentLevel++;
for (key in proj) {
// skip comments
if (COMMENT_KEY.test(key)) continue;
cmt = comment(key, proj);
obj = proj[key];
if (isArray(obj)) {
this.writeArray(obj, key)
} else if (isObject(obj)) {
this.write("%s = {\n", key);
this.indentLevel++;
if (key === 'objects') {
this.writeObjectsSections(obj)
} else {
this.writeObject(obj)
}
this.indentLevel--;
this.write("};\n");
} else if (cmt) {
this.write("%s = %s /* %s */;\n", key, obj, cmt)
} else {
this.write("%s = %s;\n", key, obj)
}
}
this.indentLevel--;
}
this.write("}\n")
}
pbxWriter.prototype.writeObject = function (object) {
var key, obj, cmt;
for (key in object) {
if (COMMENT_KEY.test(key)) continue;
cmt = comment(key, object);
obj = object[key];
if (isArray(obj)) {
this.writeArray(obj, key)
} else if (isObject(obj)) {
this.write("%s = {\n", key);
this.indentLevel++;
this.writeObject(obj)
this.indentLevel--;
this.write("};\n");
} else {
if (cmt) {
this.write("%s = %s /* %s */;\n", key, obj, cmt)
} else {
this.write("%s = %s;\n", key, obj)
}
}
}
}
pbxWriter.prototype.writeObjectsSections = function (objects) {
var first = true,
key, obj;
for (key in objects) {
if (!first) {
this.writeFlush("\n")
} else {
first = false;
}
obj = objects[key];
if (isObject(obj)) {
this.writeSectionComment(key, true);
this.writeSection(obj);
this.writeSectionComment(key, false);
}
}
}
pbxWriter.prototype.writeArray = function (arr, name) {
var i, entry;
this.write("%s = (\n", name);
this.indentLevel++;
for (i=0; i < arr.length; i++) {
entry = arr[i]
if (entry.value && entry.comment) {
this.write('%s /* %s */,\n', entry.value, entry.comment);
} else if (isObject(entry)) {
this.write('{\n');
this.indentLevel++;
this.writeObject(entry);
this.indentLevel--;
this.write('},\n');
} else {
this.write('%s,\n', entry);
}
}
this.indentLevel--;
this.write(");\n");
}
pbxWriter.prototype.writeSectionComment = function (name, begin) {
if (begin) {
this.writeFlush("/* Begin %s section */\n", name)
} else { // end
this.writeFlush("/* End %s section */\n", name)
}
}
pbxWriter.prototype.writeSection = function (section) {
var key, obj, cmt;
// section should only contain objects
for (key in section) {
if (COMMENT_KEY.test(key)) continue;
cmt = comment(key, section);
obj = section[key]
if (obj.isa == 'PBXBuildFile' || obj.isa == 'PBXFileReference') {
this.writeInlineObject(key, cmt, obj);
} else {
if (cmt) {
this.write("%s /* %s */ = {\n", key, cmt);
} else {
this.write("%s = {\n", key);
}
this.indentLevel++
this.writeObject(obj)
this.indentLevel--
this.write("};\n");
}
}
}
pbxWriter.prototype.writeInlineObject = function (n, d, r) {
var output = [];
var inlineObjectHelper = function (name, desc, ref) {
var key, cmt, obj;
if (desc) {
output.push(f("%s /* %s */ = {", name, desc));
} else {
output.push(f("%s = {", name));
}
for (key in ref) {
if (COMMENT_KEY.test(key)) continue;
cmt = comment(key, ref);
obj = ref[key];
if (isArray(obj)) {
output.push(f("%s = (", key));
for (var i=0; i < obj.length; i++) {
output.push(f("%s, ", obj[i]))
}
output.push("); ");
} else if (isObject(obj)) {
inlineObjectHelper(key, cmt, obj)
} else if (cmt) {
output.push(f("%s = %s /* %s */; ", key, obj, cmt))
} else {
output.push(f("%s = %s; ", key, obj))
}
}
output.push("}; ");
}
inlineObjectHelper(n, d, r);
this.write("%s\n", output.join('').trim());
}
module.exports = pbxWriter;