MetaUML

This post intends to serve a similar purpose as my mscgen post A tool that I sometimes like to use for simple UML diagrams is MetaUML. The documentation for this tool is unfortunately a bit sparse, so I thought I’d put some notes up here so I can find them more easily in the future.

Step One, Installation

On Ubuntu, the following two packages need to be installed:

  1. texlive-metapost
  2. texlive-fonts-recommended
  3. imagemagick

If you neglect the texlive-fonts-recommended package, you will receive the following cryptic error when trying to compile a simple metauml diagram:

(/usr/share/texmf-texlive/metapost/metauml/util_log.mp)))
! Font ptmr8r not usable: TFM file not found.
Picture_layout->...(SUFFIX2)info.iFont.name.scaled
(SUFFIX2)info.iFont.scale;...
<to be read again> 
;
layoutObject->...;scantokens(methodName)(SUFFIX2);
endgroup
<for(A.namePict)> ...)<>"":layoutObject((SUFFIX0))
;fi; ENDFOR
layoutObjects->...o)<>"":layoutObject(o);fi;endfor
;endgroup
Class_layout->...ributeStack,(SUFFIX2)methodStack)
;log"Computing maxFeatureW...
<to be read again> 
;
layoutObject->...;scantokens(methodName)(SUFFIX2);
endgroup
<for(A)> ...(SUFFIX0))<>"":layoutObject((SUFFIX0))
;fi; ENDFOR
layoutObjects->...o)<>"":layoutObject(o);fi;endfor
;endgroup
drawObjects->begingroup.layoutObjects((TEXT2))
;forsuffixes.o=(TEXT2):if(str....
l.6     drawObjects(A, B)
;

Step Two, Create a Source File

The syntax for MetaUML is quite a bit more involved than mscgen, but with some appropriate examples lying around, you can quickly cross reference them to find what you’re looking for.

prologues := 2; % Required to resolve fonts used by MetaUML
defaultscale := 1.0
input metauml;
  beginfig(1);
    Class.A("Object")()();
    Class.B("Point") % class name
    ("#x:int", "#y:int") % attributes
    ("+set(x:int, y:int)", % operations
    "+getX():int",
    "+getY():int",
    "-debug():void");
    B.e = A.w + (-20, 0);
    drawObjects(A, B);
    link(inheritance)(B.e -- A.w);
  endfig;
end

NOTE - Make sure to include prologues := 2; at the start of the metauml document. If you forget this step, convert will not be able to read the postscript file after running it through mpost.

This bit of magic is due to the following: “If prologues is set to 2, any used fonts in the output file are automatically re-encoded, and the encoding vector file specified in the fontmap entry will be embedded in the output file. If prologues is set to 3, MetaPost will also attempt to include (a subset of) the used PostScript fonts. For this to work, it needs to acquire font map information.”

Step Three, Make Pretty Pictures

First, compile the MetaUML source into a postscript figure:

$ mpost example.mp

Now you will have an example.1 file. You can view the contents of the file to see the raw postscript output - pretty ugly, huh?

Now we need to convert that postscript file into a png - you know, to make sure that the graphics are portable across networks. For this, we will use ImageMagick’s excellent convert utility.

$ convert -quality 90 -density 150 ps:example.1 png:example.png`

To get a larger or smaller image, adjust the density parameter passed to convert. If you try using scaling or transforms instead, the image will be blurry and of poor quality.

Additional Reading