Andrew E. Bruno
A sourceful of secrets

Archive for January, 2007

Converting MIF to XML - Java Version

Wednesday, January 31st, 2007

In my previous post I discussed a tool called mif2xml for converting MIF files to an intermediate XML dialect. In this post I'll talk about the Java port of mif2xml called mif2xml-j which you can download here including just the executable jar or browse the source online via svn.

JFlex is a lexical analyzer generator for Java and is the library I chose to use for creating the MIF lexer. The first step was to get JFlex integrated into my build environment. For this project I decided to use ant but integrating JFlex into another build environment ...Read the rest of this entry »

Converting MIF to XML

Thursday, January 25th, 2007

MIF (Maker Interchange Format) is an ASCII text representation of a FrameMaker document. You can export your FrameMaker documents into this text based representation to allow for parsing and manipulation by external tools outside of FrameMaker. You can also import MIF files back into FrameMaker. If your interested in reading more about MIF you can check out the MIF Reference from Adobe (link may be out of date).

There's a great perl module on CPAN for working with MIF files called FrameMaker::MifTree. It's a subclass of Tree::DAG_Node and provides a nice interface for modifying the in-memory tree structure and dumping back out into MIF. The only downside to this module is that it's very slow especially with larger MIF files.

At O'Reilly we've had to work with MIF files quite a bit and have taken several different approaches for processing MIF most of which turn out to be unmaintainable scripts that are not very pleasant to work with. One of the ideas Andrew S. and Keith came up with was to convert MIF to an intermediate XML format which would allow us to process MIF using XML tools such as XSLT and XQuery. From this intermediate XML format we can transform to DocBook, WordML, or even convert back to MIF again for later importing into FrameMaker. This approach was very appealing as it can greatly reduce the number of one off scripts and allow us to benefit from the wide variety of libraries for parsing and transforming XML. ...Read the rest of this entry »

Creating Sparklines with JFreeChart

Monday, January 15th, 2007

Sparklines are very small charts usually displayed along side some text and help quickly compare time series data. They are usually rendered without any axis, labels, or tick marks and appear as just a simple line. Sparklines were developed by Edward Tufte and further explained here.

JFreeChart does not have any built in classes for creating sparklines but are easily created by adjusting a few settings in the basic charting classes. Here's a few quick examples of some sparklines generated using JFreeChart:

Foo 90 Foo 90
Bar 34 Bar 34
Baz 54 Baz 54

To create sparklines using JFreeChart you just need to turn off the display of labels, tickmarks, lines, etc. on the domain/range axis as well as the XYPlot.

Here's a complete example:

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;

import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.ui.RectangleInsets;

public class Sparkline {
    public static void main(String[] args) {
        TimeSeriesCollection dataSet = new TimeSeriesCollection();
        Day day = new Day();
        TimeSeries data = new TimeSeries("Sparkline", day.getClass());

        // XXX add real data here
        Random r = new Random();
        Calendar c = Calendar.getInstance();
        for(int i = 0; i < 100; i++) {
            int val = r.nextInt(100);
            if(val < 50)
                val += 50;
            c.add(Calendar.DATE, 7);
            Date date = c.getTime();
            data.add(new Day(date), val);
        }

        dataSet.addSeries(data);

        // The sparkline is created by setting a bunch of the visible properties
        // on the domain, range axis and the XYPlot to false
        DateAxis x = new DateAxis();
        x.setTickUnit(new DateTickUnit(DateTickUnit.MONTH, 1));
        x.setTickLabelsVisible(false);
        x.setTickMarksVisible(false);
        x.setAxisLineVisible(false);
        x.setNegativeArrowVisible(false);
        x.setPositiveArrowVisible(false);
        x.setVisible(false);

        NumberAxis y = new NumberAxis();
        y.setTickLabelsVisible(false);
        y.setTickMarksVisible(false);
        y.setAxisLineVisible(false);
        y.setNegativeArrowVisible(false);
        y.setPositiveArrowVisible(false);
        y.setVisible(false);

        XYPlot plot = new XYPlot();
        plot.setInsets(new RectangleInsets(-1, -1, 0, 0));
        plot.setDataset(dataSet);
        plot.setDomainAxis(x);
        plot.setDomainGridlinesVisible(false);
        plot.setDomainCrosshairVisible(false);
        plot.setRangeGridlinesVisible(false);
        plot.setRangeCrosshairVisible(false);
        plot.setRangeAxis(y);
        plot.setRenderer(new StandardXYItemRenderer(
                StandardXYItemRenderer.LINES));

        JFreeChart chart = new JFreeChart(null, JFreeChart.DEFAULT_TITLE_FONT,
                plot, false);
        chart.setBorderVisible(false);

        try {
            ChartUtilities.saveChartAsPNG(new File("sparkline.png"), chart,
                    100, 30);
        } catch(IOException e) {
            System.err.println("Failed to render chart as png: "
                    + e.getMessage());
            e.printStackTrace();
        }
    }
}

Customizing Gaim Chat Windows

Sunday, January 14th, 2007

Gaim is an excellent instant messaging client with support for multiple protocols and runs on several different platforms. For the longest time I've wanted to customize the background color of my chat windows so they resemble my xterm settings of green text on a black background. There doesn't seem to be an easy way to do this via Gaim's preferences and after a little digging I finally got it working.

The most recent version of Gaim uses GTK+ 2.0 and the background color for chat windows can be customized by adding some styles to your ~/.gaim/gtkrc-2.0 file. You can also customize key bindings, fonts, and other widgets in Gaim by tweaking this file but I'm just going to discuss the settings for the chat windows in this post. I'm no GTK+ guru but I found the API docs and this mini-FAQ helpful and gave a nice introduction to styles and themes in GTK+.

To customize the colors in your chat windows edit your ~/.gaim/gtkrc-2.0 file or create if it doesn't exist and add the following lines:

style "gaim-dark" {
    base[NORMAL]="#000000"
    text[NORMAL]="#00FF00"
    GtkIMHtml::hyperlink-color="#007FFF"
    GtkWidget::cursor-color="#60AFFE"
    GtkWidget::secondary-cursor-color="#A4D3EE"
}
widget "*gaim_gtkconv_imhtml" style "gaim-dark"
widget "*gaim_gtkconv_entry" style "gaim-dark"

base[NORMAL] sets the background color and text[NORMAL] sets the color of the text. You can tweak the colors to your liking restart Gaim and your chat windows should now be customized. I didn't find a way to change the color of the screen names displayed in the chat window. Digging through the source code it looks like these colors are hardcoded using #define SEND_COLOR "#204a87" and #define RECV_COLOR "#cc0000" around line number 86 inside the file ./gtk/gtkconv.c of the Gaim source. You could always try changing these values and re-compiling Gaim. I haven't tested this but seems like it should work. Here's a screen shot of my customized chat window:

Custom Gaim Chat Window

There is also a plugin which comes with Gaim called Gaim GTK+ Theme Control which seems to provide a GUI interface for editing your ~/.gaim/gtkrc-2.0 file but I didn't see any options for customizing the chat windows. In the Gaim FAQ there is also a link to a sample gtkrc-2.0 which gives some good examples of other customizations.