├── .gitignore ├── README.md ├── bin └── xml2tss ├── package.json └── xml2tss.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xml2tss 2 | 3 | Build an empty tss file from an Alloy view xml file 4 | 5 | ## Install 6 | 7 | ``` 8 | sudo npm install -g xml2tss 9 | ``` 10 | 11 | ## CLI Usage 12 | 13 | ``` 14 | xml2tss [filename.xml] 15 | ``` 16 | 17 | converted file is returned to stdout (so you can build your own editor 18 | plugin) 19 | 20 | **NEW** 21 | 22 | ``` 23 | xml2tss [filename.xml] (filename.tss) 24 | ``` 25 | 26 | if a target tss file is supplied it will write the output to the target 27 | tss file. If the file already exists it will _update_ the file appending 28 | to the end the missing ids and/or classes. 29 | 30 | 31 | ### to output to a file 32 | 33 | ``` 34 | xml2tss row.xml > ../styles/row.tss 35 | ``` 36 | 37 | or **new** 38 | 39 | ``` 40 | xml2tss row.xml ../styles/row.tss 41 | ``` 42 | 43 | the second command will create or update the target file with the missing tags 44 | 45 | 46 | ### to clipboard (OS X) 47 | 48 | ``` 49 | xml2tss row.xml | pbcopy 50 | ``` 51 | ## Library Usage 52 | 53 | The `convertString`, `convertFile` and `updateFile` functions are available: 54 | 55 | e.g. 56 | 57 | ``` 58 | var xml2tss = require("xml2tss"); 59 | 60 | xml2tss.convertString('',function(err,data) { 61 | console.log(data); 62 | }); 63 | 64 | xml2tss.convertFile('row.xml',function(err,data) { 65 | console.log(data); 66 | }); 67 | 68 | // will create or update the target row.tss 69 | xml2tss.updateFile('row.xml','row.tss', function(err,data) { 70 | console.log(data); 71 | }); 72 | ``` 73 | 74 | # Output 75 | 76 | From this: 77 | 78 | ``` 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | ``` 87 | 88 | Generates this: 89 | 90 | ``` 91 | "#addBtn" : { 92 | 93 | } 94 | "#addWin" : { 95 | 96 | } 97 | "#cancelBtn" : { 98 | 99 | } 100 | "#itemField" : { 101 | 102 | } 103 | ".again" : { 104 | 105 | } 106 | ".button" : { 107 | 108 | } 109 | ".container" : { 110 | 111 | } 112 | ``` 113 | -------------------------------------------------------------------------------- /bin/xml2tss: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var xml2tss = require("../xml2tss"); 4 | if (process.argv.length === 3) { 5 | xml2tss.convertFile(process.argv[2] ,function(err,data) { 6 | console.log(data); 7 | }); 8 | } else if (process.argv.length === 4) { 9 | xml2tss.updateFile(process.argv[2], process.argv[3],function(err,data) { 10 | console.log(err||data); 11 | }); 12 | } else { 13 | console.log("USAGE: xml2tss [view.xml] (view.tss)"); 14 | } 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xml2tss", 3 | "version": "0.0.5", 4 | "description": "Alloy View XML to tss generator", 5 | "main": "xml2tss.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": "", 10 | "keywords": [ 11 | "alloy", 12 | "titanium", 13 | "appcelerator", 14 | "xml", 15 | "tss" 16 | ], 17 | "bin":"./bin/xml2tss", 18 | "author": "David Bankier", 19 | "license": "MIT", 20 | "dependencies": { 21 | "xml2js": "~0.2.8" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /xml2tss.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'), 2 | path = require('path'), 3 | xml2js = require('xml2js'), 4 | parser = new xml2js.Parser(); 5 | 6 | // older nodes 7 | function parseXML(o) { 8 | var buffer = []; 9 | function process(internal_object) { 10 | if(typeof internal_object !== 'string' && !(internal_object instanceof String)){ 11 | for(key in internal_object) { 12 | value = internal_object[key]; 13 | if (key ==="$") { 14 | if (value.id) { 15 | buffer.push("#" + value.id); 16 | } 17 | if (value.class) { 18 | buffer = buffer.concat(value.class.split(" ").map(function(o) { return "." + o;})); 19 | } 20 | } else if (key !== "_") { 21 | buffer = buffer.concat(parseXML(value)); 22 | } 23 | } 24 | } 25 | } 26 | if (o instanceof Array) { 27 | o.forEach(function(i) { 28 | process(i); 29 | }); 30 | } else { 31 | process(o); 32 | } 33 | return buffer; 34 | } 35 | 36 | function parseXMLAndFormat(data, custom_filter) { 37 | var raw = parseXML(data); 38 | return raw 39 | .filter(function(elem, pos) { 40 | return raw.indexOf(elem) === pos && (custom_filter ? custom_filter(elem) : true); 41 | }) 42 | .sort() 43 | .map(function(e) { 44 | return '"'+e+'" : {\n \n}'; 45 | }).join('\n'); 46 | } 47 | 48 | function parseTSS(data) { 49 | var buffer = []; 50 | // collect existing classses and ids 51 | var match, regex = /^["']([\.#].+?)['"'][.\n]*?/gm; 52 | while (match = regex.exec(data)) { 53 | buffer.push(match[1]); 54 | } 55 | return buffer; 56 | } 57 | 58 | exports.convertString=function(string, callback) { 59 | parser.parseString(string, function(err,data) { 60 | callback(err, parseXMLAndFormat(data)); 61 | }); 62 | }; 63 | 64 | exports.convertFile=function(file,callback) { 65 | fs.readFile(file, function(err, data) { 66 | exports.convertString(data,callback); 67 | }); 68 | }; 69 | 70 | exports.updateFile=function(source, target, callback) { 71 | var existing =[], content = ""; 72 | if (fs.existsSync(target)) { 73 | content = fs.readFileSync(target); 74 | existing = parseTSS(content); 75 | } 76 | parser.parseString(fs.readFileSync(source), function(err, data) { 77 | var additional_content = parseXMLAndFormat(data, function(elem) { 78 | return existing.indexOf(elem) == -1; 79 | }); 80 | if (additional_content.length > 0 ) { 81 | fs.writeFileSync(target, content + "\n" + additional_content); 82 | callback(null, target + " updated"); 83 | } else { 84 | callback(target + " already upto date", null); 85 | } 86 | }); 87 | }; 88 | --------------------------------------------------------------------------------