chris blogs: September 2004

29sep2004 · Viereiige Zwillinge

Zurzeit heftige vokalseismische Aktivitäten in der Klasse:

Meine Mutter hat Angst vor der Wäschespinne!

Wasserdamf

Wenn’s Jungen wären, wären es viereiige Zwillinge.

Können wir nicht einfach in’s Pornokino gehen? Das ist auch moralisch nicht bedenklich.

NP: Bob Dylan—Just My Imagination

28sep2004 · Glotzt nicht so romantisch!

‘Mal wieder paar Quotes:

Grüß Rock, Herr Gott!

Natürlich, die ganzen Wichsflecken gehen ja bei 60° auch raus!

Einmal blasen 1€, ergo: 1€-Job.

Mein Onkel wird bald General!Bei Henkel?

AAH! Ich hab’ alle Vorzeichen vergessen!

Glotzt nicht so romantisch!

Der schnucklige, alte Trottel.

Irgendjemand wird hier Windowmanager!

NP: Manda Clair—Mama Can’t Hear You (Mama Don’t Feel No Pain)

26sep2004 · Practical Tangerine

Today, we’ll use Tangerine (download at the end of this post) to convert the ports information file of RPA into a Debian-dctrl-like format. This has some advantages, for example, we will be able to use grep-dctrl and other tools that expect the Debian-format.

The ports.info is a simply YAML file with entries like these:

  metadata: 
    name: progressbar
    rpaversion: "0.0"
    version: 0.8.0-1
    classification: 
      - Top.Library.Development
    description: >
      A text progress bar library.
      Ruby/ProgressBar is a text progress bar library for Ruby. It can indicate
      progress with percentage, a progress bar, and estimated remaining time.
  url: http://rpa-base.rubyforge.org/ports/progressbar_0.8.0-1.rps

So, let’s write a small script to load a YAML file and apply a Tangerine template on it:

require 'yaml'
require 'tangerine'

# Convenient hashes
class Hash
  # Defined methods can be accessed by prefixing with _, e.g. _to_s.
  def method_missing(name, *args)
    name = name.to_s
    name = name[1..-1]  if name =~ /^_/
    self[name]
  end
end

object = YAML.load File.read(ARGV[0])
print Tangerine::RFC822.new(STDIN.read).expand(object)

We also added an extension to Hash to write hash.key instead of hash[key]. This makes using Tangerine easier (The better solution would have been to make YAML generate a OpenStruct, but I just couldn’t get it doing that…).

For testing, the first template: Simply show all packages:

,,(self){,,(metadata.name)
}

Save that into a file, and run it like this:

$ ruby yaml2whatever.rb ports.info < packages.tng

You should now see a list of packages.

This template is interpreted as follows: For each self (i.e. the list of entries), output metadata.name and a newline.

Now, to our debian-like output:

,,(self){,,([metadata]){Package: ,,name
Section: ,,classification
Version: ,,version
,,requires{Depends: ,,(self)}},,#
Url: ,,(url)
Description: ,,(metadata.description.gsub(/^$/, '.'))
}

This template has a small twist. Usually ,,(array){block} would expand the block for each element. But since we only want to save writing metadata. all the time, we need to make an array out of it, therefore ,,([metadata]). The ,,# in the Depends-line stops Tangerine from outputting a superfluous newline (Think % in TeX).

$ ruby yaml2whatever.rb ports.info < debian.tng

Voila, a nice package list. Now, let’s query it, for example all packages related to XML, but show only the package name:

$ ruby yaml2whatever.rb ports.info < debian.tng | grep-dctrl -s Package XML -
Package: copland
Package: gettext
Package: libxml
Package: rake
Package: test-report

Of course, this was an relatively easy job (RPA already has an query mechanism too :-)), but what if we’d like to have HTML or XML output? We’d simply need to adjust the templates without changing any code.

The whole job could have been done using plain Ruby of course, but such programs get confusing quickly due to mixing of code, strings and their escaping.

Download: tangerine-0.3.1.tar.gz
This is a bugfix release without any new features.

Ich trage einen Sturzhelm, weil ich sturzbesoffen bin.

NP: Bob Dylan — License To Kill (Live in Austria)

24sep2004 · Amphetamine im Trinkwasser?

… könnte man denken, wenn man so liest, was bei uns alles abgeht:

Ich weiß, dass ihr Latein könnt!Da wissen sie aber mehr als wir.

Was gibt’s im indischen Café zu essen und trinken?Buddhamilch, Buddhabrot und Buddhakuchen.

Die Trägheit der Masse ist unantastbar.

Rettet den Drogenwald!

Da machen wir paar Ausflüge in die…Zukunft!

Vielleicht liegt’s aber auch daran, das zur Zeit eher Kaffee Trinkwasser bevorzugt wird. =:-)

NP: Starfuck—Masquerade

24sep2004 · More on Scribble

I’ve decided to drop the plan to use Emacs as the interface to Scribble, instead writing it in Ruby/Tk too. This allows smaller size of binaries around (I’d RigRag and Scribble to be portable and small, easily fetchable from the web.), at the cost of editing convenience. But I’ll add external editor support (after all, every page is a simple text file), thereby outweighing that issue.

I have to say that Ruby/Tk is really great for getting a GUI done quickly although the API really sucks at times. For example, why can’t I index contents of a TkText widget by character count? Instead I need to twiddle with lines and chars. D’oh. (Of course, this is all being inherited from Tcl/Tk.)

Here a screenhot:

Scribble screenshot showing a test page

I think that page is great: Japanese Death Poems.

NP: Leadbelly—Where Did You Sleep Last Night?

22sep2004 · Donnerstag, 22. September

Man gönnt sich ja sonst nix:

Wuzaspitze

Der Papst ist Alkoholiker!

Ihr faulen Schwanz!

Persönliche Neigung?Linksträger.

Dann, Sport:

Das war filmreif!

Du musst mehr laufen! … sonst frierst du bei dem Wetter!

NP: Redrum—Blue Blood

21sep2004 · Auch mal wieder...

ein paar Quotes der letzten Tage:

Does it make you think?I think so.

I love you. [Zum Englischlehrer als Demonstration von Ironie.]

Wo wachsen Kiefern?Im Wald!

Hackt’s euch?

Freitags kann ich nicht.Und ‘ne Woche vorher?

NP: Bob Dylan — Hard Rain (Live in Japan)

19sep2004 · Tangerine 0.3 released

I just released Tangerine 0.3. Grab it here.

New features over 0.2.1 include:

  • Tag libraries provide an easy way to build and structure complex templates. Tags starting with @ are looked up using the tag library which is given as the second argument to Tangerine.new.

    Tag libraries are objects that implement resolve(tag) and return a string that gets evaluated as a Tangerine template instead of the tag upon calling that method.

    One sample tag library that maps tags to files is included as Tangerine::FileLib.

  • Support for RFC(2)822 message escaping.

    Header values can be escaped automatically to conform to RFC(2)822.

  • Better error handlers.

    The erroneous line in the generated code should now be the same as the erroneous template line.

Download: tangerine-0.3.tar.gz

NP: Billy Talent—Nothing to Loose

18sep2004 · ETE - Errors To Emacs

I’ve spent the whole afternoon writing two small scripts. What did I do?

My desktop is basically one Emacs instance beneath one Aterm. (Well, there’s a lot of stuff around it, but that doesn’t matter here.) When I code, I write the programs in Emacs, and run them in Aterm. Switching between those two windows is easy, I simply press M-Tab. This is a feature by Enlightenment. However, when my code raises an unhandled exception, there was no easy way to jump directly to the error; I had to jump to and retype the line number of the erroneous file.

This has changed now. I simply run my programs as usual, but write ete before:

$ ete ruby fuckup.rb
fuckup.rb:1: undefined method `fuckup' for main:Object (NoMethodError)

To handle this (trivial) error, I simply switch to Emacs and type C-x :. Emacs will now load the output of ete and jump to the first (mostly only) error. I could use C-x ` if I had several errors. (Unlikely with Ruby, but maybe a C extension…)

You can download ete here: ete (shell script), ete.el (elisp).

On a side note, put this into your .emacs:

;; Make ruby-mode usable for hs-minor-mode.
(add-to-list 'hs-special-modes-alist
         (list 'ruby-mode
           (concat ruby-block-beg-re "\|{")
           (concat ruby-block-end-re "\|}")
           "#"
           'ruby-forward-sexp nil))

Now open some lengthy Ruby file, and do:

M-x hs-minor-mode
M-x reveal-mode

Move over some defs, press C-c @ C-l (better rebind that :P), and be astonished moving your cursor in and out. ;-) Cool, eh?

NP: Velvet Revolver—Superhuman

15sep2004 · Tangerine 0.2.1 released

I just released Tangerine version 0.2.1.

This is the first public release. All user-visible methods are fully documented, the same is true for the template language.

Use Tangerine::XML instead of plain Tangerine if you want your data to be escaped automatically (this is overridable).

Tangerine 0.2.1 can be downloaded here: tangerine-0.2.1.tar.gz.

Osmöse

Lehrer zeichnet Brown’sche-Molekularbewegung an die Tafel.Hat der grad’ seine Schamhaare hingemalt?

Knietief im Wochenende

Hallo, Herr Rotz

NP: Redrum—Heroin Girl

13sep2004 · Tangerine

Since there are more Ruby packages for templating than there are real users of them (:-P), I’ve decided it can’t hurt to make one myself.

It’s called Tangerine, and is the first library I’ve developed using TDD. (Thanks, dragonkh :-)).

Of course it’s hard to design (and not only implement) something new, therefore I did two spikes before, dubbed AllOfMyLove which was a 20 lines gsub for experimentation, and DeepBlueTea, a lot longer code that used a “real” parser (as needed for nested parentheses). (I guess I’m a grand-master in inventing silly project names :-P).

Tangerine finally implements a compiler which creates a Proc out of the template for good performance. In benchmarks I did myself (never trust a benchmark…), Tangerine turned out to be 2 times faster than a comparable ERB template. (ERB evals all the time.)

Finally, I’ll show a short sample to show how it feels like:

<h1>,,title</h1>
<h2>,,tagline</h2>
<p>,,(Time.now)</p>

,,# overview
<ul id="toc">
,,entries{
  [<li>,,(title.upcase)</li>]
}
</ul>

,,entries{
<h3>,,title</h3>
  ,,recent?{<em>[New]</em>}
  <p>,,body</p>
<hr />

}

<p>,,title -- ,,tagline. ,,(Time.now.strftime("%d%b%Y").downcase)</p>

This is a very primitive template for a simple weblog, and will result in something like this:

<h1>chris blogs</h1>
<h2>a blog by christian neukirchen</h2>
<p>Mon Sep 13 19:29:04 CEST 2004</p>

<ul id="toc">
  [<li>HEAD</li>]
  [<li>ANOTHER</li>]
</ul>

<h3>head</h3>
  <em>[New]</em>
  <p>some &lt;content&gt;</p>
<hr />
<h3>another</h3>

  <p>again</p>
<hr />

<p>chris blogs -- a blog by christian neukirchen. 13sep2004</p>

A few issues still need to be handled better, I’ll do a release soon.

Name für eine jüdische Kneipe: Bar Mitzwah.

Zustand des Religionsbuches bei Erhalt: lächerlich. :-)

NP: Led Zeppelin—Tangerine

12sep2004 · Sommerferien vorbei

Und schon wieder sind die Sommerferien rum…

Ging das nicht schnell?

Ab morgen wieder die neusten Quotes aus dem Klassenzimmer!

NP: Led Zeppelin—Stairway to Heaven

12sep2004 · Slides with conTeXt

I spent some time to get into conTeXt, an alternative macro package for TeX. I prefer it over LaTeX, because it has full plain TeX under the hood and is more easy to customize.

To start, I’ve decided to re-invent the wheel by mimicking Richard P. Gabriels slide style that he used for “Form & Function in Software” (available at his site, http://www.dreamsongs.com).

Basically, it’s a very easy style. Just white P22Typewriter on black background. After deciding to use pdfTeX, I figured how to use a TTF with it. Basically, you need these steps (teTeX on debian):

ttf2afm -e /usr/share/texmf/ttf2tfm/T1-WGL4.enc -o FONT.afm FONT.ttf
afm2tfm FONT.afm -T /usr/share/texmf/ttf2tfm/T1-WGL4.enc
echo `afm2tfm FONT.afm -T /usr/share/texmf/ttf2tfm/T1-WGL4.enc` \
     '<FONT.ttf' >> fonts.map

However, be sure fonts.map is being loaded in some pdftex.cfg by adding that line:

map +fonts.map

It turns out that was the easiest part. :-) After fighting a bit with the conTeXt documentation (nice manual actually, but kind of confusing and incomplete…), I’ve finally managed to copy that style.

See a sample document: a hash of my life [src]

NP: The Hives—Love In Plaster

10sep2004 · Scribble

Today I’ve spent some time to implement the counterpart of RigRag, a wiki-like hypertext system which I dub Scribble.

I decided to write it in Emacs Lisp, since I use Emacs for most of my other stuff too (I keep all my addresses in bbdb, for example), so that would be a nice fit.

I’d have liked to implement RigRag in elisp too, but it’s too graphical to be practical to be used inside a text editor (if you want to call Emacs that way :-)).

Well, I discovered that my elisp knowledge leaves a lot to be desired, so it’s probably going to take some time until I get into it again. However, I need to say that the Emacs documentation really is superb: Being clearly written, covering just about everything one needs to know, and having a comprehensive index is not something you see every day when working with software.

NP: Presidents of the USA—Last Girl On Earth

08sep2004 · Fun on IRC

After I managed to keep my irssi open for more than 100 days,

Irssi uptime: 101d 22h 13m 1s

empi leave message made me rofl:

22:59 -!- empi [~moar@dsl-XXX-XXX-XXX-XXX.arcor-ip.net] has quit
      ["Girlfriend pregnant error, [A]bort, [M]arry, [I]gnore ?"]

Yeah, nothing happening here. Go along.

NP: Billy Talent—Prisoners Of Today

06sep2004 · RigRag screenshots

My organizing tool (see RigRag) now looks fairly acceptable, so I’ve decided to put some screenshots up:

RigRag shot

RigRag shot

These shots show the “Holm Family”-Example known from the original ZigZag distribution. Both display the same dataset, the first shows first- and surname, the latter one children and spouses.

RigRag is still unusable, as I need to think a bit more about editing and moving the data; therefore is no source available yet.

NP: Bob Dylan—Mr. Tambourine Man

06sep2004 · Sparen durch Einwegpfand

Es ist doch tatsächlich möglich, mit Einwegpfand zu sparen: Am diesjährigen “sun&fun Radio 7 bla bla blub — Der beste Mix die meisten Hits” (das mit den Hits stimmt wohl nicht für die Website :-P) hat mich die Halbe Schussenrieder nur 70¢ gekostet.

Wie man das macht? Ganz einfach.

Geh’ zur Aral und kauf’ eine Flasche Schussenrieder Original No°1. Kostet 1.05€ + 15¢ Pfand, also 1.20€.

Bei sun&fun kostet genau dieselbe Flasche (etwas wärmer ;-)), 1.50€ + 50¢ Pfand, also 2€. Wenn man das Pfand der Aral-Flasche aber bei sun&fun abgibt, bekommt man ja auch 50¢ raus, ergo: Die Halbe kostet 70¢. q.e.d

Schön, dass sun&fun keine Pfandmarken ausgeteilt hat. :-)

NP: Bob Dylan—Talking World War III Blues

03sep2004 · RigRag

For some time now I’ve been thinking of and how to organize information of all kinds. Many people like to use wikis for that, and so would I (I’d probably prefer a standalone wiki, for example emacs-wiki), but they lack one important thing: Getting an overview.

A wiki is essentially a set of nodes, each having links to other nodes—a.k.a. a graph. Graphs can be drawn in lots of different ways, but it’s hard to make that visually appealing, and lot’s of algorithms related to graphs have large complexity, both in space and time.

Recently, I learned about ZigZag, a tool to organize data in n-dimensional hyperspace. This may sound complicated, but once you get into it, it’s really easy. Basically, you have a spreadsheet where each field can have neighbors in every dimension. In usual implementations, only two dimensions are visible at once, being mapped to the x- and the y-axis. You now can move between these fields and change the dimensions shown.

One example of the original ZigZag disk shows how to build a family tree. First you see a list of first names of the people, ordered alphabetically. On the right-hand side, they’re linked to their surnames. If you now go over to these, they’ll be ordered too, and the first names will be shown on the left, unordered this time.

By rotating the dimensions, one can now see how these people are linked. There are two additional dimensions, marriage and children. If one enables both, he’ll see a family diagram with the parents on top and the children going downward. If you put marriage on the x-axis and 1 on the y-axis, you’ll get a list of all people with their spouses.

As you can see—or at least guess—, this is a very powerful way of structurizing data. However, you can’t simply do “cross-links”, since your number of links per dimension is limited to two (one at each side).

Therefore I’ve decided to build something that will unite the both approaches: The wiki and ZigZag.

I’ll simply build a ZigZag where each cell contains the name of a Wiki-page. I’ve already taken a shot at implementing ZigZag in Ruby (therefore the name, RigRag), and a wiki will be easy to hook up.

I already can view and browse simple graphs, but editing and persistance is still missing. More soon. ;-)

NP: Josh Ritter—Lawrence, KS

01sep2004 · eesh.rb

A first public version of my Ruby library to script Enlightenment is available in eesh.rb.

It’s still very alpha, and I some code too complicated, but I don’t know yet how do make it better.

The library can also be used as a binary, where it calls it’s first command-line argument on the current window.

These methods are useful to be called in this context:

  • move_{left,right,top,bottom}_to: Move the current window to the corresponding direction until it hits a different window. If two windows are already touching each other, move over that window (sounds awkward, but it very nice to use; try it!)

  • focus_{left,right,top,bottom}: Focus the next window placed at that direction. (These methods behave inconsistent, I’ll fix that soon; they work fine if the windows are near each other, though)

  • focus_{left,right,top,bottom}_neighbor: Focus the next window placed at that direction which is on the same height (width) as the current window.

I use vi-like key-bindings (h, j, k, l) plus Windows-key to focus the windows, and move them with Windows+Shift.

You can set your keys easily using e16keyedit, which is also available as an Debian package.

NP: Dead Moon—In The Altitudes

Copyright © 2004–2016