
Moving Ghost4J to GitHub gave me motivation… So, I decided to go a step further with Ghost4J !
And some weeks later: here comes Ghost4J 0.5.0 !
So what’s new ?
Many things ! Here is the full list (release notes):
What are the benefits ?
SimpleRender is now rendering nice antialiased images.
PSConverter is now more reliable as it uses Ghostscript ps2write device (when available) to generate PostScript files.
PS and PDF documents can now be mixed / splited thanks to the new extract, append and explode Document methods. SafeAppenderModifier can also be used to do the job (when PS files come from a different spool).
And last but not least : the InkAnalyzer can tell you how much of Cyan Magenta Yellow or Black (CMYK) ink will be used to print each page of a document.
Like that :
// load PS document
PSDocument document = new PSDocument();
document.load(new File("myfile.ps"));
// create analyzer
InkAnalyzer analyzer = new InkAnalyzer();
// analyze
List<AnalysisItem> coverageData = analyzer.analyze(document);
// print result
for (AnalysisItem analysisItem : coverageData) {
System.out.println(analysisItem);
}
Find it interesting ? Then checkout more examples on the Ghost4J website at http://www.ghost4j.org/highlevelapisamples.html.
And don’t forget you can contribute by forking the project on GitHub, here: https://github.com/zippy1978/ghost4j.
Happy new year to everyone !
To start 2013, I decided to move Ghost4J from sourceforge to GitHub !

Why moving ?
When I started Ghost4J, 4 years ago I chose to host it on sourceforge : I already knew the platform and it felt confortable for me: SVN, FTP access for the web site… Classical tools.
At the time I didn’t know GitHub (and not even git - the scm tool) at all, and even when I got to know it, it took me some time to understand the benefits of such a platform.
Then, last month I read a very interesting article (in french : A celui qui a fait Twitter Bootstrap), in few words : how a successful open source project can swallow your life and some things you should never do with open source.
Of course, Ghost4J is not Twitter Bootstrap (and will never be), but here are some lessons this article taught (or reminded) me:
Why GitHub ?
After that I realized that GitHub was the tool that could help me : with sourceforge I had to copy/paste or patch the code contributed by users by myself as GitHub provides the fork / pull request mechanism, probably the best way to integrate contributions.
GitHub is a social network… For coders, and this is very important : it is easier to get in touch with other developers, and the stars / forks give you a good mesure of involvement of others around your project, as sourceforge only gives you the number of binaries downloaded per day and a user rating mechanism that nobody uses anyway…
GitHub has also better (more recent) tools than sourceforge : git, issue tracking, general site looking (much clearer than sourceforge, even if it got better last year).
So what’s new ?
The web site for the project is now http://www.ghost4j.org (yes: I bought the domain!) and it is managed by the gh-pages feature of GitHub (and can be re-published with a single maven command !).
The site is still generated by the maven site plugin, but I decided to update the documentation and it uses the fluido skin now (form a Bootstrapped look !).
The GitHub page for the project is https://github.com/zippy1978/ghost4j.
I even set up a repository for maven artifact releases and snapshots (check the web site out for instructions).
Hi everyone,
Some weeks ago I decided to have a closer look to Sencha Touch.
The framework is quite complete as it exposes a full MVC in Javascript (where jQuery Mobile handles only rendering out of the box).
With Sencha Touch every piece of code is made of Javascript : models, controllers and even views.
However, as complete as it is, the framework does not provide any way to localize strings. By googling around it is possible to find different solutions, but if you are used to Java .properties for localization, a single file is enough.
Here is a solution I came up with…
A simple I18n utility class
That is the code :
Ext.define('MyApp.util.I18n', {
singleton : true,
config : {
defaultLanguage : 'en',
translations : {
'en' : {
'signIn' : 'Sign in',
'name' : 'Name',
'hello' : 'Hello {0} !',
'enOnly' : 'English only !'
'fr' : {
'signIn' : 'Identifiez-vous',
'name' : 'Nom',
'hello' : 'Bonjour {0} !'
}
}
},
constructor: function(config) {
this.initConfig(config);
this.callParent([config]);
},
translate: function (key) {
// Get browser language
var browserLanguage = window.navigator.userLanguage || window.navigator.language;
// Is it defined ? if not : use default
var language = this.getTranslations()[browserLanguage] === undefined ? this.getDefaultLanguage() : browserLanguage;
// Translate
var translation = "[" + key + "]";
if (this.getTranslations()[language][key] === undefined) {
// Key not found in language : tries default one
if (this.getTranslations()[this.getDefaultLanguage()][key] !== undefined) {
translation = this.getTranslations()[this.getDefaultLanguage()][key];
}
} else {
// Key found
translation = this.getTranslations()[language][key];
}
// If there is more than one argument : format string
if (arguments.length > 1) {
var tokenCount = arguments.length - 2;
for( var token = 0; token <= tokenCount; token++ )
{
translation = translation.replace( new RegExp( "\\{" + token + "\\}", "gi" ), arguments[ token + 1 ] );
}
}
return translation;
}
});
The code above is a simple Ext class. It defines a default language defaultLanguage and a map of translations translations by language code and key / string.
It also provides a translation method that is in charge of retrieving the string matching the provided key. Note that the method also supports arguments in strings.
Usage
In order to use the class, just add it to your project in the app/util with the name I18n.
Then declare it in the requires of your app.js.
Now you should be able to call it from anywhere like this :
MyApp.util.I18n.translate('my_key');
Behaviour
Given the data used in the class above, here is how the translation behaves if browser locale is set to french (fr):
MyApp.util.I18n.translate('signIn');
// Gives 'Identifiez-vous'
MyApp.util.I18n.translate('hello', 'Gilles');
// Gives 'Bonjour Gilles !'
MyApp.util.I18n.translate('enOnly');
// Gives 'English only !' (defaults to en, as the key is not defined for fr)
MyApp.util.I18n.translate('missing');
// Gives '[missing]' (the key is never defined, so it is returned into brackets)
Hope this will help !
Here is my first github generated page :)
After a simple try on jQuery plugin authoring with jquery.slicebar I decided to go further during my holidays : I wrote a scrolling plugin.
What is it for ?
The plugin, named jquery.scrollz, adds modern scrolling features on any HTML content and works well with jQuery Mobile (it was my initial purpose).
To enable the plugin on HTML content just do :
jQuery(function($) { $('#content').scrollz(); });
Or even simplier with jQuery Mobile : just add data-scrollz=’simple’ tag to the element you want to make scrollable !
You can also invoke it with options as described in the documentation.
The plugin is hosted on github, right here.
Checkout live examples here or here (jQuery Mobile).
The features
Version 1.0.1 (already !) includes the following features :
Grunt is nice !
To write this plugin I decided to go with Grunt, THE command line build tool for Javascript projects (a bit like Ant for Java).
Grunt comes as a Node.js module that can be installed with (requires Node.js):
sudo npm install -g grunt
Then you can use the grunt command from the shell to create a project boilerplate or run the build script.
Grunt comes with a jQuery plugin project template. To generate a boilerplate from it use:
grunt init:jquery
After a few interactions (questions for project configuration) a project with src, libs, tests (with Qunit) and even a README.md for easy github push is created.
By default, the generated build file can : lint (check JS syntax), concat (concatenate source files) min (minify sources) and qunit (run tests).
5 minutes where enough for this project setup ! And Grunt helped me a lot for syntax checking.
On the road map
The first release of the plugin seems to be working OK (I tested it on Chrome, Safari and FireFox). But I already have plans for the future !
So if I have time, I would like to add the bounce support, for an even closer to native app experience.
I also would like to make the scroll thumb more customizable to allow creation of more original thumbs (such as Path little moving clock).
There are also some animations I would like to enhance. And I guess I can optimize the code for speed a bit as well…
Anyway, I hope you will enjoy this plugin.
Diantre, me voilà démasqué ! (Pris avec Instagram)
Last week I spent a long time trying to find a jQuery plugin that I never found : a simple plugin, a bit like a progress bar but with multiple ‘slices’.
As often: as I could not find any, and it was simple enough to do, I decided to write my own…
I decided to name it jquery.slicebar. It is fairly basic but does the job : you just have to provide a model to the plugin (defining slices with there value, label, color and style) to get a nice rendition.
Here is an example:
jQuery(document).ready(function() {
$('#slicebar2').slicebar({
max : 100,
slices : [
{
value: 20,
label : 'Green plain slice',
color : 'green',
style : 'plain'
},
{
value: 20,
label : 'Emtpy',
style : 'empty'
},
{
value: 40,
label : 'Orange gradient slice',
color : 'orange',
style : 'gradient'
}
]
});
});
And that is the result:

A live example is available here.
The project is hosted on github and you can check it out here (with documentation).
J’écris très rarement en français dans ce blog, et encore moins pour parler de foot (oui, en fait je n’aime pas trop ça)…
Mais là l’occasion est trop belle : la victoire du Montpellier HSC en L1 hier m’a décidé à faire ce petit tableau, juste pour montrer que l’efficacité d’un club (ses points) par rapport à son budget, ça donne un classement très différent !
Je vous laisse juger :
