bailey.js is a pragmatic language that compiles to javascript. Sort of like coffeescript, but a lot more inspired by python than ruby, with a focus on creating a cleaner, saner language with less flaws.
Assuming you already have node.js, installation is as easy as:
$ npm install bailey -g
This installs it globally, but of course you can put it in your project’s package.json manually or by running npm install bailey --save
.
bailey sourceDir/ targetDir/
Converts all .bs
files in sourceDir to a .js
file in targetDir.
There are two possible ways to utilize bailey in Javascript. The first is to
compile a string using parseString
or compile the content of a folder like
the command line example by using parseFiles
.
var bailey = require('bailey');
var compiledString = bailey.parseString(sourceString, {});
// This is the equivalent of the command line example
bailey.parseFiles('sourceDir/', 'targetDir/', {}});
The options listed below can be used in different settings. Prepended with --
is used with the command line and the ones in the parentheses are used in the
option parameter when running bailey from javascript.
--node
(node
)Use node imports instead of requirejs-imports, for running things server-side.
--remove-comments
(removeComments
)Remove all comments in the compiled version.
--bare
(bare
)Make the Javascript file without the wrapper function.
--watch
Watch the source file or directory, recompiling when any file changes.
--version
Output the current version.
.baileyrc
Bailey.js has support for configuration through a json file called .baileyrc
.
It can be used in order to shorten the parse command or to define several
configurations for a project. This can often be the use case in an web project
with a node or io.js backend. The configuration file can define multiple sets
of options like the example below. Any options passed in the cli will override
the configuration file and if positional arguments are passed in the cli bailey
will not read the configuration file.
{
"server": {
"source": "src/server",
"target": "dist/server",
"node": true
},
"frontend": {
"source": "src/frontend",
"target": "dist/server/public"
}
}
The example above will compile the server code as node and the frontend code
as require.js when you run bailey
. It is also possible to run bailey -c frontend
or bailey --config frontend
in order to compile only the frontend code.
import bailey
import bailey as bs
import gulp-bailey as gulpBailey
import bailey: parseString, parseFiles
define(["bailey", "bailey", "gulp-bailey", "bailey"], function(bailey, bs, gulpBailey, bailey) {
var parseString = bailey.parseString;
var parseFiles = bailey.parseFiles;
}
var bailey = require('bailey');
var bs = require('bailey');
var gulpBailey = require("gulp-bailey");
var parseString = require('bailey').parseString;
var parseFiles = require('bailey').parseFiles;
export bailey
define([], function() {
"use strict";
return bailey;
});
module.exports = bailey;
number = 42
decimal = 3.14159265359
yeah = true
hellNo = false
# Strings are as you expect, plus string interpolation
string = 'Hi!'
anotherString = "The answer is #{number}"
stringWithMultipleLines = "This
is cool"
# Objects can be with commas...
obj = {
number: 42,
string: "Wee"
}
# ...or without
flavors = {
vanilla: true
chocolate: false
}
listOfStuff = [0,2,4,6]
anotherList = [
1,
3,
5
]
# Functions are very coffeelike
totallyRandomNumber = () ->
return 4 # guaranteed to be random
var number = 42;
var decimal = 3.14159265359;
var yeah = true;
var hellNo = false;
// Strings are as you expect, plus string interpolation
var string = 'Hi!';
var anotherString = "The answer is " + number + "";
var stringWithMultipleLines = "This\nis cool";
// Objects can be with commas...
var obj = {
'number': 42,
'string': "Wee"
};
// ...or without
var flavors = {
'vanilla': true,
'chocolate': false
};
var listOfStuff = [0, 2, 4, 6];
var anotherList = [1, 3, 5];
// Functions are very coffeelike
var totallyRandomNumber = function totallyRandomNumber() {
return 4;
};
# This is an awesome comment
// This is an awesome comment
if 'chocolate' in apartment
console.log("Awesome!")
else
console.log("Too bad for you.")
if numberOfIceCreamsToday == 0
console.log("Go eat ice-cream")
elif numberOfIceCreamsToday > 2
console.log("Good!")
if numberOfIceCreamsToday > 5
console.log("Serously?")
if 'chocolate' in apartment then console.log("Awesome!")
if ('chocolate' in apartment) {
console.log("Awesome!");
} else {
console.log("Too bad for you.");
}
if (numberOfIceCreamsToday === 0) {
console.log("Go eat ice-cream");
} else if (numberOfIceCreamsToday > 2) {
console.log("Good!");
if (numberOfIceCreamsToday > 5) {
console.log("Serously?");
}
}
if ('chocolate' in apartment) {
console.log("Awesome!")
}
for item in bagOfDelicousCandy
console.log(item)
for number in 0:10:2
console.log(number)
for value of IceCreamObject
console.log(value)
for key, value of IceCreamObject
console.log('#{key}: #{value}')
chocolateCount = 4
while chocolateCount > 0
console.log('Eat chocolate')
chocolateCount -= 1
var __l1 = bagOfDelicousCandy.length;
for (var __i1 = 0; __i1 < __l1; __i1++) {
var item = bagOfDelicousCandy[__i1];
console.log(item);
}
for (var number = 0; number < 10; number = number + 2) {
console.log(number);
}
for (var __i2 in IceCreamObject) {
var value = IceCreamObject[__i2];
console.log(value);
}
for (var key in IceCreamObject) {
var value = IceCreamObject[key];
console.log('' + key + ': ' + value + '');
}
var chocolateCount = 4;
while (chocolateCount > 0) {
console.log('Eat chocolate');
chocolateCount -= 1;
}
class Candy
title: ""
slug: ""
price: 0
quantity: 0
init: (title, price, quantity) ->
@title = title
@price = price
@quantity = quantity
@slug = slugify(title)
calculatePrice: (quantity) ->
return quantity * @price
class Chocolate extends Candy
types: ['dark', 'milk', 'white']
type: 0
chocolateDiscount: 0.8
init: (title, price, quantity, type) ->
super.init(title, price, quantity)
@type = type
calculatePrice: (quantity) ->
return super.calculatePrice(quantity) * @chocolateDiscount
function Candy(title, price, quantity) {
if ((typeof window !== "undefined" && this === window) || (typeof self !== "undefined" && this === self)) {
throw new TypeError("Tried to call class Candy as a regular function. Classes can only be called with the 'new' keyword.");
}
this.title = title;
this.price = price;
this.quantity = quantity;
this.slug = slugify(title);
}
Candy.prototype.title = "";
Candy.prototype.slug = "";
Candy.prototype.price = 0;
Candy.prototype.quantity = 0;
Candy.prototype.calculatePrice = function calculatePrice(quantity) {
return quantity * this.price;
};
function Chocolate(title, price, quantity, type) {
if ((typeof window !== "undefined" && this === window) || (typeof self !== "undefined" && this === self)) {
throw new TypeError("Tried to call class Chocolate as a regular function. Classes can only be called with the 'new' keyword.");
}
Candy.call(this, title, price, quantity);
this.type = type;
}
Chocolate.prototype = Object.create(Candy.prototype);
Chocolate.prototype.types = ['dark', 'milk', 'white'];
Chocolate.prototype.type = 0;
Chocolate.prototype.chocolateDiscount = 0.8;
Chocolate.prototype.calculatePrice = function calculatePrice(quantity) {
return Candy.prototype.calculatePrice.call(this, quantity) * this.chocolateDiscount;
};
@sent = false
request(url, (err, res, body) ->
if not err
# we can reach an outer scope by adding a @
# for each level out that we need to go
@@sent = true
)
var __scope_4__ = this;
this.sent = false;
request(url, function(err, res, body) {
if (!err) {
// we can reach an outer scope by adding a @
// for each level out that we need to go
__scope_4__.sent = true;
}
});
/\d+/.test('We have 20 different sorts of IceCream')
/\d+/.test('We have 20 different sorts of IceCream');
...and watch it appear here as javascript
Feedback is awesome! Did you find a bug, do you have a question or do you have a great idea for a feature? Just open an issue on Github or join our discussion on gitter.im/haeric/bailey.js