Variable Pitch Tables

While using the Emacs WordPress interface on various screens here, it became clear that the sloppy way I was laying out various tables just didn’t really work. I was using the `variable-pitch’ font and sort of eyeballing how much space each column would take and then using `display ‘(space :align-to 100))’ to line stuff up.

But the size of fonts varies wildly from computer to computer, and what looked nice on my HiDPI laptop didn’t line up at all on my LoDPI screen.

So I switched to using fixed-width fonts:

And I just thought, *sigh*.

It just looks so oldz. I spend a lot of time in Emacs in eww which does nice fonts, so I’ve grown less used to the er starkness of tables like this.

Surely there has to be a way to do tables with proportional fonts, and of course there is: eww/shr lays stuff out without a problem, so I just had to take a similar approach here.

And behold:

The package is on Microsoft Github now.

This also allowed me to implement table headings that you can click on to sort the table on the different columns. And I wanted to keep the interface really simple, because I have to say that I hate working with the tabulated-list.el interface, which is a mess of buffer-local variables and magic always happening wherever you’re not looking in the code.

So the interface is one simple function that takes obvious parameters: A list of column names and max widths, and then a list of row contents:

(variable-pitch-table
 '((:name "First" :width 10)
   (:name "Second" :width 5))
 '(("A thing" "Yes")
   ("A wide thing that needs chopping" "And more")
   ("And the last one" "Foo")))

But you’d normally pass in strings that are made with something like

(propertize "At thing" 'face 'variable-pitch)

to get whatever proportional font you want on each element.

Further Fun With the Clipboard

In the previous episode of this blog, I mused about how Emacs should perhaps handle non-text yanking (i.e., HTML and images).

I didn’t really want to write a mode to examine the clipboard and the selections, but I did anyway just now, and I discovered something kinda interesting.

Well I never!

Anyway, this is basically what the mode looks like:

It just lists all the types of selection that exist under the primary/secondary selections, as well as the clipboard. In this instance, I’ve done a “Copy image” in Firefox. So I can inspect the text/html “version” the image…

Which turns out to be the <img;> bit, logically enough.

And the image/png is the image itself, even more logically enough.

But here’s the slightly interesting bit: If you mark some text in Firefox (i.e., put the text into the primary selection in nerd speak), you get these selection types:

And the TEXT bit is as you’d expect…

But what’s that text/x-moz-url-priv?

It’s the URL of the page you marked the text on! This can obviously be used for UX purposes, like providing a function that’d simultaneously quote something and do the link at the same time. Like this:

So something like:

  (when-let ((url (x-get-selection-internal 'PRIMARY 'text/x-moz-url-priv)))
    (insert (format "On <a href="%S">somebody</a> wrote:\n\n"
                    (ewp-decode-text-selection url))))
  (insert "<blockquote>\n")
  (insert (substring-no-properties (current-kill 0)))
  (insert "</blockquote>\n\n")

You can find this stuff on Microsoft Github.

Chrome isn’t as helpful as Firefox here, you just get a very minimal selection list when marking some text there:

(Oh, yeah, I added a command to do screenshots directly from the ewp composition buffer. Otherwise this blog would have taken me HOURS and HOURS to make.)

Of course, how useful this stuff is outside of a writing-for-the-web context is debatable…

PERSON A: It’s not useful!

PERSON B: Oh, OK.

Well, that was a short debate!

The Mysteries of the Selection

After writing the package to edit WordPress articles in Emacs, I started thinking about doing something about non-text X selections in Emacs.

Emacs has all the required low-level support it needs to be able to yank HTML and images into Emacs, but nobody’s mainstreamed more high-level support into Emacs. Mostly because nobody really knew what it would look like, I think. (And because most Emacsens don’t really blog that much.)

Let’s have a look at what’s available here.

Let’s mark a word in an xterm, and then let’s see what Emacs gets:

(gui-get-selection 'PRIMARY 'TARGETS)
[TIMESTAMP TARGETS MULTIPLE UTF8_STRING
COMPOUND_TEXT TEXT STRING text/plain\;charset=utf-8
text/plain]

and compare when marking a word in Firefox:

(gui-get-selection 'PRIMARY 'TARGETS)
[TIMESTAMP TARGETS MULTIPLE text/html
text/_moz_htmlcontext text/_moz_htmlinfo
UTF8_STRING COMPOUND_TEXT TEXT STRING
text/x-moz-url-priv]

See? When marking words in an xterm, you get at text/plain thing you can yank in Emacs (and that’s what normally happens), but you mark something in Firefox, you get a text/html (among other things) in addition).

The same thing is the case in Chrome, although there you have to say “Copy” first to get the text/html part, and it lands on the CLIPBOARD and not in PRIMARY.

But that should be OK, anyway. Let’s look at the output from the text/html selection from Firefox.

Er, OK, that’s… little-endian utf-16. Er, OK… So that’s a thing?

Let’s look at the selection from Chrome, then:

So that’s a UTF-8 string? With… a nul at the end?

*sigh*

Well, OK, it’s easy enough to recognise one or the other forms, as long as there’s only two. *crosses fingers*

That means that the function for yanking HTML ends up being something like:

(defun ewp-yank-html ()
  "Yank the contents of the current X text/html selection, if any."
  (interactive)
  (let ((data (loop for type in '(PRIMARY CLIPBOARD)
                    for data = (x-get-selection-internal type 'text/html)
                    when data
                    return data)))
    (if (not data)
        (message "No text/html data in the current selection")
      (set-mark (point))
      (insert
       (if (and (> (length data) 2)
                (= (aref data 0) 255)
                (= (aref data 1) 254))
           ;; Somehow the selection is UTF-16 when selecting text in
           ;; Firefox.
           (decode-coding-string data 'utf-16-le)
         ;; But some sources add a nul to the end of the data.
         (decode-coding-string
          (replace-regexp-in-string (string 0) "" data)
          'utf-8))))))

Or should it look at the TIMESTAMP from the selections and then yank the newest one? By testing, it seems to be doing the right thing when not doing that…

Yanking images into buffers works along the same line, but there’s differences between where the images originate, of course. If doing a “Copy image” from Firefox, I can yank them as any format (image/png, image/jpeg), but from Chrome doesn’t support transcoding, so you have to loop a bit to find what the format really is. Or… I could look at the output from `gui-get-selection’? Yes, that seems like a better idea.

Let me try to yank a random image from Google…

Yup, that works. So you end up with something like:

(loop for type in '(PRIMARY CLIPBOARD)
      for st = (loop for st across
                     (gui-get-selection type 'TARGETS)
                     when (equal (car (split-string
                                       (symbol-name st) "/"))
                                 "image")
                     return st)
      when st
      return (x-get-selection-internal type st))

But just yanking an image into Emacs isn’t very useful: You have to be able to do something with it. In an HTML-like mode as this Postpress editing mode makes that kinda easy: Just represent it as an <img> element… and stash the entire image in the src=”data:image/jpeg;base64,FKJDSHJF…” bit. Since I’m showing the image as the `display’ bit on top, having a few megabytes of noise in the buffer doesn’t make any difference.

I was worried that this might somehow slow Emacs down, but nope. Displaying very long lines is something that Emacs doesn’t like, but as long as it’s hidden, it doesn’t seem to make any difference.

And it autosaves nicely, too.

OK, making it that easy to insert images into blog posts perhaps isn’t a good idea, but why should all ideas be good?

Anyway, I think something like this is something that Emacs should have, and I think I’ll pursue that further when I get time to do some more real Emacs work (which probably won’t be until like February).

I was originally pondering whether to offer an interface to a detailed view of the selection/clipboard, so that you can journey into all the different selection types, but after using this stuff for a couple of days, I think I’ve reached the conclusion that the only other two yanking types that makes sense (other than plain text, which we have now) are HTML and images. At least in a WYSIWYG-ish context…

Finally! Emacs is going to catch up with 90s editors! At least on this minor point! Amazing!

Editing Wordpress Articles in Emacs

I’ve got my blog on WordPress.com, which has some positive aspects (I don’t have to run it) and some negative (I can’t control it fully). But whether I’m running WordPress myself or not, there’s one thing that’s always true: I loathe the browser-based editor.

When composing blog articles, I’ve been using the post-by-mail interface that WordPress.com offers, and it works OK. It’s got severe limitations in what it accepts, though: No <div>s or anything more fancy than a link and an image, really, and even those can’t be combined.

But editing is the main problem: I’ve tried using the Edit with Emacs Firefox plugin, and it doesn’t work with WordPress.com, apparently. So I’ve just… not… edited much, because it’s such a pain in the ass. The “visual” editor doesn’t even have reliable scrolling.

So yesterday evening I pulled myself together and started googling “emacs wordpress”, and found org2blog, which allows you to edit your WordPress blog posts using org mode. So it’s possible!

It turns out that this all is so much easier than I had imagined: WordPress has an old xmlrpc interface that you can just call with your credentials to do all this stuff. (It also has a new interface that’s oauth2-based, i.e., it requires a web browser in the auth flow with is just ick.)

The org2blog people have kindly separated out the low-level stuff into its own library, and I wrote a new library, ewp on top of that. Because even if Org is nice and stuff, I just want to edit my WordPress articles. I want WordPress to have the articles, and don’t want to have a “shadow” set of master texts.

With the help of that library (after fixing a multi/unibyte bug in the xml-rpl.el library (that was merged fast by the nice maintainer)), I finished off the library yesterday, and it’s basic, but does what I need, I think.

It lists the posts on WordPress, allows me to edit them, and to create new posts. (And, of course, since I’m very picture-happy, I also added some stuff to upload embedded media (which was a problem with the post-by-mail interface, because WordPress’ SMTP servers had a size limit of 100MB per email which they refused to increase, even after I asked them (so unreasonable!!!ONE!)).)

Here’s a Youtube demo of me typing away at my very shiny sofa laptop:

This has all been tested very, very lightly, of course, so I’d caution er caution. I’ve tried posting and editing myself on my WordPress.com blog, but who knows what happens on other WordPress installations…

And I’m sure it’ll grow more features as time passes. Things tend that way, don’t they?

Z-Wave and Emacs

I’ve had a 433-MHz-based “home automation” system (i.e., light switches) for quite some time. It works kinda OK. That is, I’m able to switch the lights on and off, which is the main point.

But, man, the range of 433MHz devices sucks, including all Telldus models. I’ve been able to overcome the problems by having transmitters all over the apt, but getting wall-mounted light switches to work with any kind of reliability has proven impossible.

The problem is that the protocol is just inherently unreliable: It just sends commands out into the ether, and doesn’t have any replay logic or ACKs going on.

But there’s newer (but also old) tech available, and 433MHz devices are disappearing from the stores, and the winning protocol is Z-Wave.

So I got a Z-Stick:

It’s a nice device: You plug it in and it shows up as either /tty/USBx or /tty/ACMx (depending on the model, but it makes no difference), and you talk to it by squirting some bytes at it.

I had expected the protocol to be really well-defined and open, but it’s a proprietary protocol that people have been reverse-engineering for years, which led me to believe that there surely would be a nice repository somewhere that describes the protocol in detail, and has, say, an XML file that describes all the different network packages.

Nope.

But after some googling I found this gist that at least let me check whether I can talk to the device…

… and it works!

It turns out that the Z-Wave protocol is kinda nice. Each package has a checksum, and devices retransmit commands a few times unless they get an ACK, and Z-Wave plugged-in devices (like outlets) work as repeaters, so the Z-Wave network works as a mesh. It’s kinda cool.

There’s a ton of software to control these devices, but using something like Open HAB is just so… end userish.

Instead I wanted to just plug it into my existing Emacs-based system so that I don’t have to, like, use software. Software sucks.

If no machine-parseable spec is available, at least there must be some other sensible software out there that I can just crib implementation details from, right? So I binged “z-wave python”.

And just found Python OpenZwave, which turns out to be nothing but a wrapper around OpenZWave, which is a C++ library.

Whyyy.

It’s a simple protocol, really. You just read from a serial device and then squirt some bytes at the device. It’s not like you need to do Fourier realtime transforms on a vast byte stream or anything.

But who am I to criticise people for choosing odd programming languages to implement their free software? Since it’s C++, at least probably they created some kind of over-engineered monster where you have some XML files that define the protocol, and then they create objects from the stream and use a lot of polymorphism that’ll make the control flow impossible to follow (according to the “everything happens somewhere else” object oriented methodology), but that’s good, because I can just use the protocol definition files and ignore the rest.

Right?

Right?!?

No, the main work flow is based on nested if statements with lots of “switch( _data[1] )”. But surely after that they’ll parse the protocol packages into something sensible?

*sigh*

Well, at least they used variable names that’s understandable. But what’s data[4] and data[6]?

*sigh*

I”M SORRY! THIS IS…

Ok, again, I have no business giving a code critique of this library written by, I’m sure, very nice people and put on the intertubes for the world to peruse and use, and despite being written in the “least information density per pixel displayed” style, it’s clear and easy to follow, and has an impressive amount of comments. It’s still all kinds of wrong.

Perhaps it’s just coming from a different culture? It’s Windows-style programming?

I don’t know, but anyway, with the guidance from this excellent piece of, er, software, I was able to make Emacs parse and execute commands when I touch a wall switch.

And Z-Wave works! Where a couple my light switches were a bit hit and miss before, they now work with 100% reliability over the last week.

I don’t have any Z-Wave outlets yet, so I haven’t bothered to implement sending commands to devices, but I’m sure I’ll have to implement that at some point. But as far as I can tell, that should be pretty straight-forward. I foresee a lot of “but what’s _data[7]?” in my future.

Somebody should still create a Z-Wave repo with protocol definitions, especially since it’s now an open-ish standard. But only as PDFs, of course.

[Edit: I should have googled a bit more, because it pretty much looks like everything I wondered about is in the OpenHAB distribution, which is in Java and has more XML protocol definition files than you can shake a stick at. Well done, Java peeps.]

Nails and Hammers

You know that old saying about gravitating to your favourite tool? Well, my go-to thing for compositing text on top of images (and stuff) was LaTeX, and I’ve been doing that for decades.

What I’m mostly using this stuff for these days is the extremely important task of displaying weather data on small, cheap USB-powered monitors that I have here and there around the apt.

For instance, in the hall I have something that plays a random-but-related youtube clip (with no audio, of course) of whatever’s playing on the stereo, and on top of that I have a LaTeX-generated overlay that says what temperature it is and the rain forecast over the next 24 hours (that’s the line; rain ahoy).

It’s composed by this Perl script that uses LaTeX to generate the clock and the temperature text, curl to download the weather data, gnuplot to make the nice line, ghostscript to make a .pnm file, and som pbmplus things to composite it all.

And what occurred to me the other night is that I wanted to have a tiny text at the bottom there that told me the name of what was playing to and I thought “that’s just so much work”, and then I started wondering whether I should just rewrite all this in Emacs Lisp and use my new favourite hammer: svg.el.

Presto! Still rainy!

It’s now a pure-Emacs image compositing thing which I’ve put on Microsoft Github if you want to read it, but it’s not generally useful. But you could perhaps use a couple of the elements if you want to do something similar.  I also finally got a reason to play with xelb/xcb, which I’ve always wondered about.  Seems like a very nice library, and maps 1:1 the X concepts onto Emacs Lisp.

Compositing images via svg.el is fun!

One thing that I thing I’m going to expand upon and put into Emacs is the SVG path/bezier curve stuff, because I think that would be generally useful.

This bug report adds a new function, svg-path, but I think Eli’s objections are right. Instead of adding such a low-level function, instead we should have, like (svg-multi-line svg points :type ‘bezier :smooth 0.2) that would compute the boring Bezier stuff for you. SVG supports insanely complicated paths, but I don’t think that’s all that useful in general…

But I don’t have time to do implement that properly now, but perhaps sometime this winter…

Oh, and while implementing this, I miscomputed the font size for one of the displays (that just displays what’s playing), and I thought it was such a striking mistake that I kept it.

IMDB in Emacs; or, Honey, I Made an ORM

I’ve always been frustrated by the IMDB web pages. Usually when I’m looking at a director’s oeuvre, I’m not interested in all the shorts, videos and games the director has created, but just want a list of the movies.

When I’m looking at a specific movie, it’s often because I want to know who the character on the screen I’m watching is being played by, but the images are so tiny and low res that it’s impossible to guess who’s who.

And once I found myself wondering, “what’s the name of that actor that played in that film with her and her”, and I know who the latter two are, but not what film, so it would be nice to be able to do a cross reference kind of thing… right? RIGHT!?

OK, the last thing happened only once, but it was still something that I thought might perhaps have been vaguely useful. But, of course, I didn’t do anything about all this because well you know.

I did download the IMDB data set and do various things with it (but mostly based on grepping and ad-hoc searches), but that came to a complete stop when IMDB revamped their data exports. Instead of semi-human semi-readable files, it’s now basically a database dump. No longer can you just grep for “Isaach De Bankolé”, because in the new files, you first have to find his ID, and then you can grep for that, but that just gives you movie IDs, and…

Long story short, I made an Emacs mode for looking at the new-format data.

It’s based on this sqlite3 module for Emacs. My first attempt was based on just storing all the data in hash tables in Emacs, because I’ve got lots of RAM. I thought that since I routinely open multi-gigabyte buffers in Emacs, and that’s no problem, and at work, I routinely have multi-tens-of-gigabyte processes in Common Lisp servers, that should be no problem in Emacs either.

I had forgotten that Emacs’ garbage collector is, er, kinda primitive. It’s an old-style stop-and-copy collector. This is fine for huge buffers, because that’s basically just a handful of objects, no matter how large the buffer is. When you create a 200M element hash table, all those elements need to be mark-and-sweeped individually, and as I found halfway through implementing it, that makes Emacs pause for like ten minutes at a time.

So scratch that. I went for sqlite3 and I store the data on disk. But interacting directly with the sqlite3 database data is a drag, so I wrote a kind of ORM… well, it’s more of a PRM. Plist-Relational Mapping. Because strong typing is for dweebs.

I mean, professionals.

Anyway, the raw dataset from IMDB is about 3GB. The sqlite3 database is about 7GB, and takes an hour or two to create on my machine. (Before I found out that sqlite3 autocommits by default, I had like two transactions per second. By slapping a transaction around the import, I get a few thousands of inserts per second.)

The module has some bugs, but I’ve sent a pull request, so hopefully it gets fixed.  Or pull down my fork instead, which is here, and you’ll need it to do regexp searches.

If you want to play with this, you need a newish Emacs built with module support, the sqlite3 module, and imdb-mode.el.

And then just eval (imdb-download-and-create) and wait for a few hours.

The PRM works pretty much as you’d expect.

(imdb-select 'movie :mid "tt0090798") 
=> 
((:_type movie 
  :mid "tt0090798" 
  :type "movie" 
  :primary-title "Caravaggio" 
  :original-title "Caravaggio" 
  :adultp "N" 
  :start-year 1986 
  :end-year nil 
  :length 93))

See?

(pp (imdb-select 'crew :mid "tt0090798") (current-buffer)) 
((:_type crew :mid "tt0090798" :pid "nm0147599" :category "writer") 
 (:_type crew :mid "tt0090798" :pid "nm0413897" :category "writer") 
 (:_type crew :mid "tt0090798" :pid "nm0418746" :category "director") 
 (:_type crew :mid "tt0090798" :pid "nm0418746" :category "writer"))

Easy!

(imdb-select 'person :pid "nm0147599") 
=>
((:_type person 
  :pid "nm0147599" 
  :primary-name "Suso Cecchi D'Amico" 
  :birth-year 1914 
  :death-year 2010))

Anyway, that’s the low-level interface. Here’s what the user interface looks like:

And then “x” and the noise is gone!!!

Only the real movies! *gasp* It cannot be!

(I didn’t choose Fincher here because I like his films, but because he’s done so much junk that’s it’s impossible to use his IMDB page.)

But… when looking at some actors I knew pretty well, I soon noticed that not all the films that the actor appeared in were listed. Here’s Tilda Swinton most recent few years:

What’s going on?! No Doctor Strange? Could there be a bug in my code? That seems impossible? I mean, it’s my code!

But nope, the problem is with the IMDB dataset. The file that lists what films actors appear in, “title.principals.tsv”, isn’t a complete list of participants, but instead, as the name really sorta kinda implies, a list of the most important people in that film. That means that it lists directors, writers, the cinematographer, (some) producers and then a few actors. But never more than ten people per film.

This is really weird, because directors and writers are already in the “title.crew.tsv” file.

This made me sad until I realised that I could just resort to web scraping.

So now I use the data set as a base and then insert the missing things afterwards.

Doctor Strange!

And when I’ve resorted to web scraping for that, I can just scrape for actor images, too:

*sigh*

In short, IMDB doesn’t have a usable API, and IMDB no longer export enough data to do anything useful with that data. So I guess this Emacs mode will work until they tweak their HTML.

While implementing the scraping, IMDB suddenly went missing and I just got:

I then found out that I had er slightly miswritten the end of the recursion, so I was hitting imdb.com with dozens of invalid hits per second in several concurrent threads.  I AM SORRY IMDB.

They unblocked me after an hour.

Here’s what it looks like in action:

(Click on the embiggen symbol to embiggen so that you can see what’s going on.)

I’m like, selecting a few things and then toggling what bits to see (acting/directing/all/shorts).

Exciting!

And now it’s feature complete, too, so I’ve definitely saved a lot of time by writing this.

Er…  Oh, yeah.  I was going to implement intersections (i.e., list movies that have several specific people involved.  So let’s see which films Tilda Swinton did with Luca Guadagnino:

Easy peasy.  Or the more complete, unfiltered version:

Heh.  I think “Dias de cine” and stuff are just Italian long-running movie news shows that both of them have appeared on?  Or in the same episode?  Hm…  probably the latter, because each TV episode has its own unique ID.