Monday, May 25, 2009

Code layout experiements

I managed to get my Black Triangle for the code layout project that I rambled on about earlier.

It has been pretty fun, getting to this stage I realize how long it's been since I got to sink in a good chunk of time into a side project. Also, making these ideas more solid convinces me that I wasn't on a total wild goose chase.

Let's start with a pretty typical view of Java code in an editor, in this case, emacs.



There are a few problems with reading code in this format:

  • The modifiers place the name of the class, member methods and members in an unpredictable place.

    • If you scan down the source code it's hard to pick out the method names because you have to scan left each time.
    • Take a look at how JavaDoc tries to make this easier. But there is still a problem, if you are scanning for names, it's hard to scan for arguments at the same time.
    • Scanning for extends and implements, very important pieces, also takes some time.

  • Indentation is used to separate the class header from its member declarations, but this space is wasted since there aren't too many top level classes in a file.
  • A lot of colors are needed to emphasize the various pieces of syntax, and the colors switch a lot as you are scanning through the text, which can be distracting.


Some of these can be solved by changing around the whitespace conventions, but these can only go so far. Looking at a few books on graphic design you will quickly realize that there are so many more effective ways to organize information.

Here's my first attempt at addressing these issues:


  • I've tried to stay away from colors, and use size and space to organize the information.
  • Modifiers aren't handled yet, I'm thinking of using something small like icons to indicate that information.
  • A lot of brackets, parentheses, and other punctuation have been removed. I think this makes everything look a lot less cluttered. The layout will have to make sure that it's still possible to see what's going on.
  • Indentation is reduced, and the class header and method declarations become more like headers in regular documents.
  • I've been experimenting with different ways of displaying the arguments, the current one which is a table with the types greyed out looks pretty good so far.
  • The for loop layout isn't fully worked in yet, it's trying to bring the initial and update pieces of the loop closer together.
  • I rely on Cairo for the text render dimensions, this gives me inconsistent results if the text happens to have/not have descenders or ascenders.


Ok, so IANAGD (I Am Not A Graphic Designer) but enough is set up now so that many different possible layouts are possible.
I'm hoping that this will be a nice sandbox that can be used to try out all sorts of different ways of laying out code.

It's written in Python and uses Cairo to render. To represent the Java syntax, I made a class for each grammar element that I figured made sense, then the layout class just does a big isinstance dispatch to render all the pieces. This seemed like the best way to allow multiple layout engines for any particular format. All grammar elements provide a text() method that allow you to have a fallthrough case, giving it a bit of graceful degradation.

The layout works in a TeX-ish way, building boxes into horizontal and vertical boxes with baseline information with another basic box type for Cairo rendered text. It only does the straightforward computations, not the more complicated line breaking and constraint solving.

Academic work is probably about to ramp up again, so this project is back on the back-burner, but I still have more that I hope to work in:

  • Integrate ANTLR parsing of Java files using Terrence Parr's Java 1.5 grammar. I've figured out mostly how to do this, so what's left is to go through the pain of coding it. Also it will take a fair bit of work to shape actual parse tree into the type of AST that I want. So some grammar hacking to get the right tree out, then additional processing to get it into a form that's friendly for the layout engine.
  • Implement horizontal and vertical "rules" or lines.
    Since I based this version on the functional version of TeX's layout, boxes have no notion of parent. It seems like the best way to make these work is to add in parents, which will also open up room for more interesting features. Hopefully some ideas from Hopscotch port over.
  • Work in some clipping, vertical boxes do not have to render contents outside of the window bounds... etc. Then add scrollbars.
  • More layout features. A basic table container has already been written, but I'd like something more general, maybe linear constraints, that would allow more flexible grid layouts. These would be used in small areas since they are harder to optimize.
  • A few more TeX features, fraction and exponent layout.
  • Interactivity! I didn't plan on this originally, but now that I'm at this stage, I have a fairly good idea of how this could work. Implementing vertical rules will give me an easy way to display a cursor.