Generating animated GIFs using RMagick

Posted by Alpha Sun, 30 Dec 2007 23:38:00 GMT

anim = Magick::ImageList.new(*Dir["/some/path/*.jpg"])
anim.each {|img| img.resize!(200,200) }
anim.delay = 10
anim.unshift Magick::Image.read("/some/image.jpg")[0].resize(200,200)
anim << Magick::Image.read("/some/other/image.jpg")[0].resize(200,200)
anim.write("animated.gif")

Example image:

Gloria making a funny face.

Posted in ,  | no comments | no trackbacks

Centering image links using CSS

Posted by Alpha Sun, 30 Dec 2007 21:05:58 GMT

It took me no small amount of time to figure out how to horizontally and vertically center image links, so here it is for posterity’s sake. Note that this doesn’t work in IE and is rather specific to my purposes in creating thumbnail links for a bunch of pictures.

HTML:
<div class="thumbnail">
    <a href=/some/link>
        <img src=/some/image>
    </a>
</div>
CSS:
.thumbnail {
    height:150px;
    width:150px;
    line-height:150px;
    text-align:center;
}

.thumbnail img {
    vertical-align:middle;
}

Posted in ,  | no comments | no trackbacks

Postfix to Infix, Part 2

Posted by Alpha Tue, 04 Dec 2007 06:55:00 GMT

After seeing Christian von Kleist’s solution, I couldn’t help but play with it a bit to come up with this:

#!/usr/bin/env ruby

puts ARGV[0].split(/\s*/).inject([]) {|n,i|
  n << ((%w[+ - * /].include?(i)) ? (b,a=n.pop,n.pop; "(#{a} #{i} #{b})") : i)
}[0]

Posted in ,  | no comments | no trackbacks

RubyQuiz #148: Postfix to Infix

Posted by Alpha Tue, 04 Dec 2007 00:49:00 GMT

My extremely lazy whack at the latest Ruby Quiz. Turns a postfix expression into an infix expression via regular expressions.

#!/usr/bin/env ruby

str = ARGV[0].split(/\s+/).join('_')

while str.include?('_')
  str.sub!(/([^_]+)_([^_]+)_([+\-*\/])/, '(\1 \3 \2)')
end

puts str

A few test cases I used in developing the solution before turning it into an actual script:

require 'test/unit'

def postfix_to_infix(str)
  str = str.split(/[^.\d+\-*\/]/).join(' ')
  while str !~ /^\(.*\)$/
    str.sub!(/([^ ]+) ([^ ]+) ([+\-*\/])/, '(\1\3\2)')
  end
  str.gsub(/([+\-*\/])/, ' \1 ').sub(/^\((.*)\)$/, '\1')
end

class PostfixToInfixTest < Test::Unit::TestCase
  def test_postfix_to_infix
    assert_equal '2 + 3', postfix_to_infix('2 3 +')
    assert_equal '12 + 34', postfix_to_infix('12 34 +')
    assert_equal '1.2 + 3.4', postfix_to_infix('1.2 3.4 +')
    assert_equal '(1 - 2) - (3 + 4)', postfix_to_infix('1 2 - 3 4 + -')
    assert_equal '(56 * (34 + 213.7)) - 678', postfix_to_infix('56 34 213.7 + * 678 -')
  end
end

Posted in ,  | no comments | no trackbacks

AWStats with lighttpd on Ubuntu

Posted by Alpha Mon, 03 Dec 2007 01:23:00 GMT

Throughout this post, I’ll use foobar as a fake domain. You should replace this with the appropriate domain(s) for your own use.

First, install AWStats.

$ sudo apt-get install awstats

/etc/lighttpd.conf will need to be modified; this will be slightly different if you want to use a directory instead of a subdomain to check your stats.

/etc/lighttpd/lighttpd.conf

server.modules += ( "mod_cgi" )

$HTTP["host"] =~ "stats.foobar" {
  alias.url = ( "/icon/" => "/usr/share/awstats/icon/",
                "/css/" => "/usr/share/doc/awstats/examples/css/",
                "/cgi-bin/" => "/usr/lib/cgi-bin/" )
  cgi.assign = ( ".pl" => "/usr/bin/perl", ".cgi" => "/usr/bin/perl" )
}

Make sure this works by visiting http://stats.foobar/cgi-bin/awstats.pl. You should get an error message from the AWStats CGI file.

In /etc/awstats, make a awstats.foobar.conf file, replacing foobar with whatever is appropriate for your purposes.

/etc/awstats/awstats.foobar.conf

LogFile="/var/log/lighttpd/access.log"
LogType=W
LogFormat=1
SiteDomain="foobar"
HostAliases="localhost 127.0.0.1 REGEX[foobar$]"
DNSLookup=1
DirData="/var/lib/awstats"
DirCgi="/cgi-bin"
DirIcons="/icon"
SkipHosts="127.0.0.1 localhost REGEX[^192\.168\.]"

Run awstats.pl to initialize the statistics database.

$ sudo -u www-data /usr/lib/cgi-bin/awstats.pl -config=foobar -update

Your stats should now be visible at http://stats.foobar/cgi-bin/awstats.pl?config=foobar.

Now all that’s left is editing the crontab and logrotate configuration files to automatically populate the stats.

/etc/cron.d/awstats

0,10,20,30,40,50 * * * * www-data [ -x /usr/lib/cgi-bin/awstats.pl -a -f /etc/awstats/awstats.foobar.conf -a -r /var/log/lighttpd/access.log ] && /usr/lib/cgi-bin/awstats.pl -config=foobar -update >/dev/null

/etc/logrotate.d/lighttpd

prerotate
  /usr/lib/cgi-bin/awstats.pl -config=foobar -update
endscript

Posted in ,  | 2 comments | 1 trackback

The code behind the Ultraviolet textfilter

Posted by Alpha Sun, 02 Dec 2007 05:55:00 GMT

To start, we need to install Ultraviolet. Since the library uses Oniguruma, we’ll have to install that as well.

$ sudo apt-get install libonig-dev
$ sudo gem install ultraviolet

Use irb to copy the CSS syntax files into Typo’s stylesheet directory. From the base directory of the Typo installation:

$ mkdir public/stylesheets/ultraviolet
$ irb -ruv
irb(main):001:0> Uv.copy_files 'xhtml', 'public/stylesheets/ultraviolet'

Copy one of the existing textfilters to use as a base.

$ cd vendor/plugins
$ cp -r typo_textfilter_code typo_textfilter_ultraviolet
$ cd typo_textfilter_ultraviolet
$ mv lib/typo_textfilter_code.rb lib/typo_textfilter_ultraviolet.rb

Modify init.rb to require the Ultraviolet textfilter instead of the code textfilter.

init.rb

# Include hook code here

require 'typo_textfilter_ultraviolet'

And last, edit lib/typo_textfilter_ultraviolet.rb to use Ultraviolet instead of the Syntax library.

lib/typo_textfilter_ultraviolet.rb

require 'uv'

class Typo
  class Textfilter
    class Ultraviolet < TextFilterPlugin::MacroPre
      plugin_display_name "Ultraviolet"
      plugin_description "Apply syntax highlighting to a code block using Ultraviolet"

      def self.help_text
        syntaxes, themes = [Uv.syntaxes, Uv.themes].map do |ary|
          ary.sort.map {|i| "* #{i.gsub('_', '\_')}" }.join("\n")
        end

        %{
This uses the [Ultraviolet](http://ultraviolet.rubyforge.org/) syntax highlighting engine. Options:

* **lang**. Sets the programming language. The default language is Ruby.
* **linenumber**. Turns on line numbering. Use `linenumber="true"` to enable.
* **theme**. Sets the theme. The default theme is Idle.

### Supported themes:
#{themes}

### Supported languages:
#{syntaxes}
}
      end

      def self.macrofilter(blog,content,attrib,params,text="")
        lang       = attrib['lang'] || 'ruby'
        theme      = attrib['theme'] || 'idle'
        linenumber = attrib['linenumber']

        text = text.to_s.gsub(/\r/,'').gsub(/\A\n/,'').chomp

        result = Uv.parse(text, 'xhtml', lang, linenumber, theme)

        set_whiteboard(blog, content, theme)

        "<notextile>#{result}</notextile>"
      end

      def self.set_whiteboard(blog, content, theme)
        content.whiteboard["page_header_ultraviolet_#{theme}"] = <<-HTML
          <link href="#{blog.base_url}/stylesheets/ultraviolet/#{theme}.css" media="all" rel="Stylesheet" type="text/css" />
        HTML
      end 
    end
  end
end

Posted in , ,  | no comments | no trackbacks

Ultraviolet syntax highlighting test

Posted by Alpha Sun, 02 Dec 2007 01:53:00 GMT

Ruby:

class Foo
  def bar
    puts "hello world"
  end
end

C with linenumbers using the blackboard theme:

   1  void bar() {
   2    printf("hello world\n");
   3  }

Objective-C with the twilight theme:

#import <Foundation/NSObject.h>

@interface Fraction: NSObject {
    int numerator;
    int denominator;
}

-(void) print;
-(void) setNumerator: (int) d;
-(void) setDenominator: (int) d;
-(int) numerator;
-(int) denominator;
@end

Python with linenumbers and using the pastels_on_dark theme:

   1  class MyClass:
   2      "A simple example class"
   3      i = 12345
   4      def f(self):
   5          return 'hello world'

Done using Ultraviolet.

Posted in  | no comments | no trackbacks