Autocall: A Script to Watch and “Call” Programs on a Changed Target Source File

UPDATE July 24, 2010: This post is now totally obsolete. See this post instead.

Recently, I’ve realized that the Autolily script I made was just one solution to a larger class of problems — that of calling a specific program on a target source/text file repeatedly every time you change the source. So, I’ve modified it slightly to make it accept any program name, so that the general format is: autocall [program] [file]. The source code is below:

# Program name: Autocall                                                                                        #
# Author: Shinobu (                                                                  #
# Date: March 2010                                                                                              #
# LICENSE: PUBLIC DOMAIN                                                                                        #
#                                                                                                               #
# This program takes 2 or 3 arguments; the first 2 is the command and file, while the third optional arg is the #
# delay b/n each possible execution of the command. By default this delay is 1 second (it checks if the file has#
# been modified every second)                                                                                   #
#                                                                                                               #
# Place this script somewhere, like in ~/scripts                                                                #
# Then, open up a terminal and call it like so: ~/scripts/autocall.rb [program] [file]                          #
#                                                                                                               #
# You might want to do a "sudo ln -s" of autocall.rb to one of your system's $PATH directories (e.g., /usr/bin) #
# to avoid typing out the path to autocall.rb every time you use it. Continuing the example from above,         #
# something like "sudo ln -s ~/scripts/autocall.rb /usr/bin/autocall" should do (make sure that                 #
# /usr/bin/autocall does not exist already, as the above comman will overwrite that file if it exists).         #
#                                                                                                               #
# Now you can just do:                                                                                          #
#                                                                                                               #
#     autocall [command] [file]                                                                                 #
#                                                                                                               #
# from anywhere in your system!                                                                                 #
#                                                                                                               #
# To exit, press CTRL-C.                                                                                        #

if ARGV.size > 1
    file_data_orig = ""
    call = ARGV.shift
    file = ARGV.shift
    delay = 1
    if ARGV.size > 0
        delay = ARGV.shift.to_i
    pathsize = file.split("/").size
    ls_call = "ls --full-time"

    # make sure that the "file" variable is a filename, and not mixed with its path
    if pathsize > 1
        path_to_file = file.split("/").first(pathsize - 1).join("/")
        file = file.split("/").last
        ls_call << " #{path_to_file}" # modify our `ls` command to reflect relative location of file

    `#{ls_call}`.split("\n").each do |line|
        if line.split(/\s/).last == file
            file_data_orig = line
    file_data_new = ""

    # enter infinite loop -- keep compiling the given file if it has changed in the past 1 second
    while true
        # detect the file size and also timestamp
        lsarr = `#{ls_call}`.split("\n")
        lsarr.shift # get rid of the first line, since that is the size of all the files in the directory

        # find our file from ls's output!
        lsarr.each do |line|
            if line.split(/\s/).last == file
                file_data_new = line

        # if there is any change detected, run given command on it
        if file_data_orig != file_data_new
            puts "\n\e[1;38;5;226mautocall: change detected @ #{} in file `#{file}'; invoking `#{call}'...\e[0m\n"
            if pathsize > 1
            `#{call} "#{path_to_file}/#{file}"`
            `#{call} "#{file}"`
            file_data_orig = file_data_new
        sleep delay
    puts "Usage: autocall [command] [file]\n"

I can think of at least 1 other time you would want to use this script aside from editing LilyPond files — when editing LaTeX files. For me, I use currently use autocall to call a program that converts text files intelligently to HTML files. You could further edit the source to let it pass along command line options to autocall as well, and not just the program name (I will probably do this myself if the situation presents itself in the future).

The Best Serif Font in the World: Linux Libertine

I did not find out about Linux Libertine until a couple months ago. Simply put, it’s the best serif font ever. For some reason, it still remains relatively unknown, even though Wikipedia uses it for its logo. Maybe it’s because the main developers don’t care to advertise it, or because powerhouse Linux distros have spread the word for other fonts like Nimbus Roman or Liberation Serif. Whatever the case, I think that it’s a shame that Linux Libertine remains in the shadows.

Reasons why you should use Linux Libertine:

  • It supports thousands of Unicode characters, which makes this font the best font to view all Western languages (including Cryllic).
  • It comes with an OpenType variant, “Linux Libertine O” (which is the one I use anywhere OpenType is supported)
  • It supports vritually all ligatures like “fi”, “ff”, “fl”, etc.
  • If you use Linux Libertine O in Firefox, Firefox will automatically put in ligatures for “fi,” “ff,” etc — but you will still be able to search through text as if they were their originals (i.e., ligature substitution is transparent to the user). This feature alone has made reading text zoomed at 150%-200% a pleasure — suddenly, larger text looks better.
  • It is open source (the fonts are generated from source code — which is GPL’d). This means that (1) this font will never die, and (2) this font will constantly improve over time.
  • It already looks asthetically far better than Times New Roman, yet it is not overly flamboyant like Garamond.
  • It has a good x-height, so it’s easy to read.
  • It has support for old-style figures (OSF). It even has variants for proportionally-spaced and non-proportionally spaced numerals (for both regular and OSF digits), making this an excellent choice for typesetting documents that deal heavily with numbers and tables.
  • It works beautifully well with XeTeX (fontspec)/LaTeX, and even comes with its own TeX package called “libertine”, making its symbols/glyphs easily programmable.
  • It comes with a TrueType (TTF) variant as well, so you can still use it in older programs.
  • It even has a glyph for Linux’s mascot, Tux (at codepoint U+E000)!

I can’t think of any cons. Its free, open-source nature makes it belong to the elite club of universally available, robust, free fonts (such as Latin Modern). Its robustness, versatility, and inclusion of numerous OpenType features make it easily the leading open-source serif font in the world.

UPDATE July 30, 2011: Grammar fixes; some sentences reworded.