Trick to use CoffeeScript in Hexo

Hexo has a scripts folder, and the files under which are loaded by Hexo when start. I usually uses this folder as the development folder for my plug-in scripts. And extract them into independent package after polished it into package-ready quality.

Usually, the files under scripts should be javascripts. But as I’m a fan of Coffee Script, so I wish to use coffee-script to write the plug-ins. For the formal package, I compile the coffee scripts into javascripts before release. But for development, I wish to use coffee script directly.

In node.js, it is possible to require coffee-script directly, if you registered the coffee-script runtime compiler:

1
require('coffee-script/register');

And as how node.js require function is implemented, you cannot register coffee-script runtime compiler in .coffee file. Or the compiler will complain:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[error] HexoError: Script load failed: plugin.coffee
SyntaxError: Unexpected string
at Module._compile (module.js:439:25)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at /usr/local/lib/node_modules/hexo/lib/loaders/scripts.js:17:11
at Array.forEach (native)
at /usr/local/lib/node_modules/hexo/lib/loaders/scripts.js:15:13
at /usr/local/lib/node_modules/hexo/lib/util/file2.js:339:7
at done (/usr/local/lib/node_modules/hexo/node_modules/async/lib/async.js:135:19)
at /usr/local/lib/node_modules/hexo/node_modules/async/lib/async.js:32:16
at /usr/local/lib/node_modules/hexo/lib/util/file2.js:335:11
at Object.oncomplete (evalmachine.<anonymous>:107:15)

Theoretically, it is possible to put the coffee-script registration code in a javascript file and also put it under /scripts folder. SO Hexo will load it when start-up.

Well, this approach doesn’t really work. If you try it, it is very likely to get the exactly same error as before. The reason is related to Hexo implementation. Hexo uses Scripts Loader to require files under /scripts. The loader doesn’t really provide an explicit way to specify which file is loaded before another. So the registration file is guaranteed to be loaded before any .coffee.

So far, it seems that there is no cure to this problem! But actually it does. There is undocumented feature will help to solve this issue.

Hexo uses [Script Loader] to load the scripts. In Scripts Loader use hexo.util.file2 to populate the source files under /scripts. And hexo.util.file2 use fs.readdir to actully populate the file system entries. For fs.readdir, there is a undocumented feature, that the populated entries are actually sorted alphabetically, which means a.js is loaded before b.coffee.

With this feature, we can put our coffee-script registration in a file with lower alphabetic-order name. Personally, I’d like called ___register_coffeescript.js, since _ is smaller than any letter or number.

⚠️WARNING: fs.readdir yielding sorted files is an undocumented behavior, which means it is not guaranteed either to work across platforms or not get changed in the future. So for, it works on Mac, and I expect it behaves similar on Linux. But not sure about Windows, since fs uses a different native binding on Windows.

Inject jQuery to current page

Now I’m hacking some web sites to try to grab the interesting informations from the page. But for some reason, all the sites I’m working on now, doesn’t included jQuery, they uses YUI or extJS, which makes me feel super inconvenient when trying hacking the page pattern.

Do I need to find a way to inject jQuery into the current page that I’m browsing.
Thanks to the browser address bar which allow us to execute javascript directly on current session. And also thanks to bookmark, which allow us to persists the script into bookmark, and invoke it with only one mouse click.

So I wrote this:

With this, we can quickly inject jQuery into current session in no time.

You can drag the following link to your browser favorites bar to:
Inject jQuery

Powershell Script to rename computer without reboot

We found a computer name issue when building our private cloud environment on CloudStack over KVM. We found that KVM doesn’t support to rename new created instance automatically.
As a result, all the instance booted from the same disk image have the exactly same computer name, same administrator password.

So we need to do some manual provision work before user can use the new booted instances.
Administrator password can be changed in several ways, it is not a difficult job. But to rename the computer running Windows is not an easy work. The typical way is to call the WMI interface to rename the computer, which is taken as the most “formal” and “documented” way to rename the computer. But this approach require to reboot the instance, which is what we don’t like.

So we try some “hack” way to solve this problem, we use powershell scripts to hack the registry. By doing this, we can rename the computer without rebooting, and it works fine on our environment.
But since it is a hacking way, it only changed the most common values in registry, which means it won’t modify the rare ones and all kind of cached values. Such as the values cached in the SQL Server or MSMQ service, etc. So there might be some unknown potential issues. Take if on your own risk:

Here is the gist:

Powershell script to serialize and deserialize hash-object to and from ini-like text

Powershell and .net fx provides a dozen of approaches to manipulate hash-object. And it is really easy and convenient to initialize hash-object with values from environment variables, registry or cli arguments.
And Hash-Object can be accessed and built into hierarchy easily, so to use powershell hash-object as deploy configuration is really powerful and convenient.

But in our system, the application uses the ini-like key-value pair plain text as the initial configuration file. So our deploy script need the ability to serialize and deserialize hash-object to and from ini-like config.

So I composed this piece of script.

TextMate command to create new post for jekyll

Here is a bash script that acts as a TextMate command, which enables blogger to create new post without leaving TextMate.
It depends on “Post” task of the Rakefile in Jekyll Bootstrap.

New Post Command for Jekyll Bootstrap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cd $TM_PROJECT_DIRECTORY
title=$(CocoaDialog standard-inputbox \
--title "New Post" \
--informative-text "Title of the new post:")
[[$(head -n1 <<<"$title") == "2" ]] && exit_discard
title=$(tail -n1 <<<"$title")
output=$(rake post title="$title")
expr="^\(in (.*)\) Creating new post: (.*)$"
if [[$output =~ $expr ]]; then
project=${BASH_REMATCH[1]}
post=${BASH_REMATCH[2]}
echo "new post file created at $post"
exit_show_tool_tip
else
echo "Error"
exit_show_tool_tip
fi