From 8977ebf46f77998dc099b3c010c496157f4cc51c Mon Sep 17 00:00:00 2001 From: Blake Bourque Date: Mon, 5 Jan 2015 16:55:52 -0500 Subject: [PATCH] Changes needed to make headless work. --- .gitignore | 1 + app.headless.js | 29 +++++++++++++++++++ build.py | 71 +++++++++++++++++++++++++++------------------- input.xml | 5 ++++ readme.headless.md | 16 +++++++++++ 5 files changed, 93 insertions(+), 29 deletions(-) create mode 100644 app.headless.js create mode 100644 input.xml create mode 100644 readme.headless.md diff --git a/.gitignore b/.gitignore index 00504a0a9..709b48e44 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ npm-debug.log .project *.pyc *.komodoproject +node_modules \ No newline at end of file diff --git a/app.headless.js b/app.headless.js new file mode 100644 index 000000000..dfb0e22a2 --- /dev/null +++ b/app.headless.js @@ -0,0 +1,29 @@ +// This program is to be used with NodeJS run Blockly headless. It loads +// Blockly XML from `input.xml` and outputs python code on `stdout`. + +global.DOMParser = require('xmldom').DOMParser; + +global.Blockly = require('./blockly_uncompressed.js'); + +require('./blocks_compressed.js'); +require('./python_compressed.js'); + +var fs = require('fs'); + +//the contents of './input.xml' are passed as the `data` parameter +fs.readFile('./input.xml', function (err, data) { + if (err) throw err; + + var xmlText = data.toString(); //convert the data buffer to a string + try { + var xml = Blockly.Xml.textToDom(xmlText); + } catch (e) { + console.log(e); + return; + } + // Create a headless workspace. + var workspace = new Blockly.Workspace(); + Blockly.Xml.domToWorkspace(workspace, xml); + var code = Blockly.Python.workspaceToCode(workspace); + console.log(code); +}); \ No newline at end of file diff --git a/build.py b/build.py index b79ab9943..9593d271b 100755 --- a/build.py +++ b/build.py @@ -103,30 +103,43 @@ class Gen_uncompressed(threading.Thread): f = open(target_filename, "w") f.write(HEADER) f.write(""" -// 'this' is 'window' in a browser, or 'global' in node.js. -this.BLOCKLY_DIR = (function() { - // Find name of current directory. - var scripts = document.getElementsByTagName('script'); - var re = new RegExp('(.+)[\/]blockly_uncompressed\.js$'); - for (var x = 0, script; script = scripts[x]; x++) { - var match = re.exec(script.src); - if (match) { - return match[1]; +var isNodeJS = !!(typeof module !== 'undefined' && module.exports); + +if (isNodeJS) { + var window = {}; + require('../closure-library/closure/goog/bootstrap/nodejs') +} + +window.BLOCKLY_DIR = (function() { + if (!isNodeJS) + { + // Find name of current directory. + var scripts = document.getElementsByTagName('script'); + var re = new RegExp('(.+)[\/]blockly_uncompressed\.js$'); + for (var x = 0, script; script = scripts[x]; x++) { + var match = re.exec(script.src); + if (match) { + return match[1]; + } } + alert('Could not detect Blockly\\'s directory name.'); } - alert('Could not detect Blockly\\'s directory name.'); return ''; })(); -this.BLOCKLY_BOOT = function() { -// Execute after Closure has loaded. -if (!this.goog) { - alert('Error: Closure not found. Read this:\\n' + - 'developers.google.com/blockly/hacking/closure'); -} - -// Build map of all dependencies (used and unused). -var dir = this.BLOCKLY_DIR.match(/[^\\/]+$/)[0]; +window.BLOCKLY_BOOT = function() { + var dir = ''; + if (isNodeJS) { + require('../closure-library/closure/goog/bootstrap/nodejs') + dir = 'blockly'; + } else { + // Execute after Closure has loaded. + if (!window.goog) { + alert('Error: Closure not found. Read this:\\n' + + 'developers.google.com/blockly/hacking/closure'); + } + dir = window.BLOCKLY_DIR.match(/[^\\/]+$/)[0]; + } """) f.write(add_dependency + "\n") f.write("\n") @@ -139,17 +152,17 @@ delete this.BLOCKLY_DIR; delete this.BLOCKLY_BOOT; }; -if (typeof DOMParser == 'undefined' && typeof require == 'function') { - // Node.js needs DOMParser loaded separately. - var DOMParser = require('xmldom').DOMParser; +if (isNodeJS) { + window.BLOCKLY_BOOT() + module.exports = Blockly; +} else { + // Delete any existing Closure (e.g. Soy's nogoog_shim). + document.write(''); + // Load fresh Closure Library. + document.write(''); + document.write(''); } - -// Delete any existing Closure (e.g. Soy's nogoog_shim). -document.write(''); -// Load fresh Closure Library. -document.write(''); -document.write(''); """) f.close() print("SUCCESS: " + target_filename) diff --git a/input.xml b/input.xml new file mode 100644 index 000000000..d79b402ac --- /dev/null +++ b/input.xml @@ -0,0 +1,5 @@ + + + #ff0000 + + \ No newline at end of file diff --git a/readme.headless.md b/readme.headless.md new file mode 100644 index 000000000..66b7c4e92 --- /dev/null +++ b/readme.headless.md @@ -0,0 +1,16 @@ +# Blockly Headless + +Running Blockly headless is valuable to allow for server side code generation. + +The NodeJS program `app.headless.js` loads Blockly XML from `input.xml` and outputs python code on `stdout`. + +### Prerequisites +Be sure to have these installed on your system: +- NodeJS -- http://nodejs.org/ +- NPM -- (Bundled with NodeJS) +- closure-library -- http://developers.google.com/blockly/hacking/closure + +## Getting Started +1. run `npm install` in the blockly root directory(in the same location as the package.json). +2. run `./build.py` to update the compressed files, as `build.py` **has changed**. +3. run `node app.headless.js`