Tag Archives: how-to

Auto-compile LESS file to CSS in emacs

LESS CSS is a great way of writing CSS code, thanks to its set of extended features that are not at all possible with CSS. Nested rules, variables, color functions, etc make it very handy. As the final output seen by the browser is plain CSS, there is no need for any third-party library or whatever.

Being an emacs user (and a fan) for a while, I’ve been looking for a way to compile LESS files to CSS, as and when they are saved. It would be even better if I could bind it to a keyboard shortcut, say F9. (This is not something big, just that I didn’t do it so far.)

My directory structure is like this:
LESS files in /some/path/less/
CSS files in /some/path/css/

So compiling a LESS file, say /some/path/less/style.less should output to /some/path/css/style.css

Here is the code that you have to add to .emacs

;; Function to compile current buffer (if it's a LESS file) to CSS
(defun compile-less-css ()
  "Compile LESS to CSS"
  (interactive)
  (if (string-match ".less$" (buffer-file-name))
    (async-shell-command (concat "lessc -x " (buffer-file-name) " "
      (file-name-directory (directory-file-name (file-name-directory buffer-file-name)))
      "css/" (file-name-sans-extension (file-name-nondirectory buffer-file-name)) ".css") nil nil))
  (delete-other-windows))

;; HotKey  to compile LESS to CSS
(global-set-key '[f9] 'compile-less-css)

;; To compile whenever the file is saved, uncomment the following line:
;(add-hook 'after-save-hook 'compile-less-css)

After saving the file, load the file so that the changes take effect. To load the file,
Mx load-file.

Enter .emacs in the prompt. Done! Now open a LESS file in emacs and press F9.

Happy hacking 🙂

Make your Javascript work perfect anywhere

For the past few weeks, I had a chance to work closely with Javascript and to understand it better;). I hope this post on my discoveries will help someone. Note this post is only about the cross-browser issues in javascript those I came across; I hope to write another post on general javascript tips.

One very basic thing you should always keep in mind while javascripting is that,

The environment on which your code will run is not in your hands.

Yes, the javascript engine which is going to compile your code may be a Spider Monkey, a TraceMonkey, a JägerMonkey, a Carakan, a SquirrelFish, a V8, a Chakra or even the sucking WSH. So you have to make sure that your code runs smart with any browser. Understanding how each of these engines work takes quite a lot of time. When you want to develop a cross-platform highly interactive web app in a short time, the following things are good to keep in mind.

Event handling

  • To know in which element the event occurred, use event.target and fallback to event.srcElement
    elem = event.target || event.srcElement;

Keyboard events

  • To know which key was pressed, use event.keyCode and fall back to event.which
    key = event.keyCode || event.which;
  • Use onkeydown if you want the event handler to be called continuously while the key is pressed and held. Suitable for backspaces, arrow key navigation, etc. Otherwise use onkeyup.
  • Never rely on punctuation keys. (These keys are dependant not only on browser and operating system, but also on keyboard configuration and the official system language).
  • To detect Alt, Shift and Ctrl keys, check if event.altKey, event.shiftKey and event.ctrlKey respectively are true. The keyCodes for these are less reliable on Mac.

Note: keypress event always returns 0 in Firefox.

Reference: http://www.quirksmode.org/js/keys.html

Callbacks and this

  • Value of this pointer is lost in callback functions. So,
    function outerFunction() {
      function print() {
        console.log('viky');
      }
      setInterval(this.print, 1000);
    }
    

    won’t work. Because inside setInterval, the value of this is lost. You can overcome this by copying this to something else, say that.

    function outerFunction(that) {
      var that = this;
      function print() {
        console.log('viky'); 
      }
      setInterval(that.print, 1000);
    }
    

    This can make your code messy. I would suggest you use Underscore.js bind and bindAll methods to bind this to functions.

Miscellaneous

  • Accessing characters in a string using normal way of indexing arrays, as in
    str[i]

    works fine in all browsers except IE. So, always use

    str.charAt(i)
  • split function using regular expressions as below doesn’t work in IE.
    var str = 'somestring';
    str.split(/[sr]/);
  • Comma at the end of an array or any object as in
    var position = { x: 5, y: 10, };

    works fine in all browsers but throws error in IE.

Faster backup of MySQL database with XtraBackup tool

The most common way to export and import databases is using mysqldump. This is fine for databases of small or medium size. What about huge databases, in case of a social networking site, for example? It takes hours to days to backup such databases. This is because the databases are not copied. Instead, SQL statements are generated to re-create the database. While importing, these statements are executed to create the database from scratch.

What is the alternative?

Instead of running SQL queries to create a database identical to the original one, the binary data can be copied, then crash-recovery can be performed on this to make it consistent. This is what Percona‘s XtraBackup utility (used in a lot of  web applications, including facebook! ) does exactly.

How to install?

The Free Software for most of the platforms can be downloaded from here. Installing them is not a thing to explain at all. Just double clicking the downloaded file should work fine.

Prerequisites

  • MySQL should be installed (If not run sudo apt-get install mysql-server mysql-client for Ubuntu machines)
  • It is assumed that the MySQL version is 5.1 or more

Step-by-step

The following steps may help you trying out this, without crashing your database by doing something wrong. A set of scripts to implement this is available here.

  1. Start mysql server if it is not running. (sudo service mysql start should work in most GNU/Linux distros).
  2. Connect with the mysql server using mysql -u username -p
  3. Create a sample database, say test.
  4. Create a sample table in test, say sample with ENGINE=InnoDB (The tool works with MyISAM engine as well; just for sake of simplicity).
  5. Insert some values into the table.
  6. Disconnect the client by just saying exit or just pressing Ctrl+C
  7. Now its time to backupour sample database. Run the following command:
    sudo innobackupex-1.5.1 --user=mysqlusername --password=mysqlpassword /data/backups/ --databases="test"

    Innobackupex is a wrapper script for xtrabackup for ease of use. The last two comman-line arguments above deserve special mention.

  1. The last argument is a list of databases that should be backed up. Ensure that this list has all databases having InnoDB tables. Otherwise all databases including MyISAM tables would be backed up.
  2. The last but one argument is the location where you want your backup data to be stored. It can be any path of your choice. In this location the backup files will be stored in a new directory whose name is the timestamp at which the above command was run. E.g. 2011-05-27_00-26-12
  • Now connect again with server and drop the database, so that it can be recovered from our backup.
  • Stop the mysql server (sudo service mysql stop)
  • Now run the following set of commands (first command to prepare the backup to be restored, the second one to restore the data)
    sudo innobackupex --apply-log /data/backups/2011-05-27_00-26-12
    sudo innobackupex --copy-back /data/backups/2011-05-27_00-26-12

    You may need to change the permissions of the following files/folders after executing above commands:

    • /var/lib/mysql/ibdata1
    • /var/lib/mysql/iblogfile0
    • /var/lib/mysql/iblogfile1
    • /var/lib/mysql/test/
  • Now start the MySQL server. MySQL will perform crash recovery over the data automatically to make it consistent.
  • Connect with the mysql and you can see your database alive back!
  • In my next post I’ll explain how to perform incremental backups using XtraBackup tool.
    Partial backups(backing up selected databases or tables) didn’t work fine for me. So I didn’t continue with XtraBackup hence didn’t post anything on incremental backups.