Available for Node 32bit on Windows, complete 32/64bit support for Windows, MAC, Linux coming soon
mockupsNode is a binary module for Node JS that can read, modify, and write Balsamiq BMML files. It has an easy to use API and objects for each control type exposing the same properties that can be modified within Balsamiq .
Using this module you can automate bulk processing of many BMML files and quickly do things that would be very time consuming to do within Balsamiq itself, such as:
mockupsNode can be downloaded and used for free with minor restrictions on usage. Purchase a license to unlock full functionality.
You can either:
Download the appropriate platform package and unzip into your node_modules directory, or
Install via NPM: npm install mockupsnode.
mockupsnode is a binary only module. After the base package is downloaded from the npm repository the appropriate binaries for your node platform will be downloaded from our servers.
Set your license key to unlock full functionality
var mn = require('mockupsnode');
mn.setLicense('<insert license key here>');
console.log('Licensed to: ' + mn.licenseInfo);
// Licensed to: Tim Shnaider
Open a BMML file and recurse through it, outputting to console the control hierarchy and some properties, save it to a different file
var mn = require('mockupsnode');
var mockup = mn.openMockup('/temp/file.bmml');
mockup.controls.forEach(function(control,i)
{
var depthIndent = Array(getDepth(control)+1).join('-');
console.log('%sControl #%d: %s (pos:%d,%d,size:%d,%d)', depthIndent,i, control.controlType, control.x,control.y,
control.width, control.height);
}, true /* recurse through groups*/)
mockup.saveMockup('/temp/fileout.bmml');
function getDepth(c)
{
var depth = 0;
c = c.parent.parent; // skip the parent collection
while ( c instanceof mn.Control )
{
depth++;
c = c.parent.parent;
}
return depth;
}
// Output
// Control #0: iPhone (pos:179,391,size:282,510)
// Control #1: Button (pos:1234,199,size:60,24)
// Control #2: __group__ (pos:258,154,size:799,346)
// -Control #0: MediaControls (pos:5,0,size:110,36)
// -Control #1: __group__ (pos:463,157,size:336,189)
// --Control #0: Alert (pos:0,0,size:200,113)
// --Control #1: ComboBox (pos:242,165,size:94,24)
// -Control #2: Alert (pos:225,29,size:200,113)
// Control #3: ProgressBar (pos:0,66,size:100,20)
// Control #4: Button (pos:100,200,size:75,24)
Add and remove controls
var mn = require('mockupsnode');
var m = mn.newMockup();
var newC = new mn.ControlButton();
newC.x = 100;
newC.y = 200;
newC.color = "Red";
newC.width = 80;
newC.text = "Hello!";
newC.height = 75;
newC.state = mn.ButtonState.Disabled;
console.log('Control count: %d',m.controls.length);
console.log(newC);
m.controls.add(newC);
console.log('Control count: %d',m.controls.length);
console.log(m.controls[0]);
m.controls.remove(m.controls[0]);
console.log('Control count: %d',m.controls.length);
// Output
// Control count: 0
// { fontSize: 13,
// links: { parent: [Circular], objectType: 'Links' },
// hRef: '',
// italic: false,
// locked: false,
// state: 3,
// menuIcon: false,
// color: '#ff0000',
// map: '',
// parent: null,
// controlType: 'Button',
// text: 'Hello!',
// bold: false,
// groupId: -1,
// y: 200,
// objectType: 'Control',
// customId: '',
// measuredHeight: 24,
// iconSize: 1,
// textAlign: 0,
// icon: '',
// underline: false,
// height: 24,
// x: 100,
// width: 75,
// z: 0,
// id: -1,
// customData: '',
// measuredWidth: 60 }
// Control count: 1
// Control count: 0
Move controls around
m.controls.moveToTop(m.controls[2]); m.controls.moveBefore(m.controls[0], m.controls[2]); m.controls.moveAfter(m.controls[1], m.controls[0]); m.controls.moveToBottom(m.controls[1]); m.controls.moveForward(m.controls[1]); m.controls.moveBackward(m.controls[1]); // Move control to different collection, in this case a Group m.controls.add(m.controls[2].controls[1]);
mockupsNode is licensed software.
The module runs in Unlicensed mode until a license key has been set via mockupsnode.setLicense(). The only restriction when unlicensed is controls that have a Y location > 500px are excluded on save.
Purchase license (available from November 23)
We have included scripts in the examples directory with the package
You can also find a growing library of scripts on the nimbleScript marketplace. Extract the code from the run() function to use in regular node js code