6.1 Defining and Arranging Blocks

The simplest diagram is (from Andrew Tannenbaum’s famous book) two connected blocks.

exC0_cshexC0

This is essentially an arrow specification with the participating blocks automatically created (using default shape, label, layout and other attributes). A more detailed version can be seen below.

exC1_cshexC1

Here each block is first defined to be a box, which essentially dictates its shape. After the box keyword comes the name of the block that is used later to specify the arrow. These names also become the label of the block if you do not specify any other label. In this example, we do - after the colon comes the label. Note that you do not have to name a block, names can be omitted. They are needed only if you want to refer to the block later (such as for an arrow).

Note that you can omit the box keyword. In that case the block is created only if it has not been created previously. If it has, only its attributes are changed, such as in the case of block B below. Blocks that are created take their attributes from the running style, which can be set by the use command. Any block or arrow created after that is impacted by any attributes setting after use. There is in fact two running styles, one for blocks and one for arrows. They can be set via the blocks use and arrows use command. Writing just use will impact both.

exD6_cshexD6

If just listed one after the other, the blocks are laid left-to-right. This is called a row. You can make blocks go top-to-bottom by inserting them into a column, or col for short. On the figure below, blocks B and C are part of an nunnamed column, where block A and the unnamed col are in a row (that is laid left-to-right). The space command is used to insert a bit of extra blank space between block A and the unnamed column.

exC2_cshexC2

You can also see that it is easy to specify several arrows at once, by listing multiple destinations (or sources) in a comma-separated list.

If you want to enclose two blocks in another block, add them as content. In the example below the unnamed col has been replaced to an unnamed box. We use the boxcol keyword, this is the same as box, but arranges its content in a column instead of a row by default. After the boxcol keyword, attributes can be specified in square brackets, similar to other languages of Msc-generator. In particular, we set the corners of the unnamed box to round.

exC3_cshexC3

Next, we can add a label to a container block, that is, one which has content. This, however, moves blocks B and C downwards messing up the symmetry of the arrows. This is because in a row elements are vertically centered by default, thus block A is vertically centered to the unnamed container block right to it. (Note also that blocks in a column are also centered horizontally by default. Note also, that you can define multiple block with one box command.)

exC4_cshexC4

To fix the arrow asymmetry problem, we can add a named column (BC) inside the container box and make block A align to that vertically. For this we use the middle attribute on the block A. This makes the block’s middle to vertically align to the middle of another block. This way we can override the default row alignment between block A and the unnamed container block. Note that you can forward reference BC even before it was defined.

exC5_cshexC5

Adding this extra column is a bit cumbersome just to group blocks for alignment. You can shortcut it by listing a group of blocks directly in the middle attribute. Msc-generator will calculate the middle (or top, bottom or any other part) of the blocks combined and will align there.

exE7_cshexE7

Continuing the example, we could add two more blocks with different alignment. The attributes top and bottom make the top and the bottom of the block to align to that of another block. Note that the blocks A and E are laid out further apart from one another - this is the only way to fulfill the alignment requirements we have specified via the attributes.

exC6_cshexC6

You can use the below, above, leftof and rightof alignment modifiers in front of any block to place it in relation to the previous block. In the example below, below refer to the big container Cont, so block N is placed below it. In turn, leftof refers to block N, so block M is placed left of it.9

exC7_cshexC7

In addition to middle, top and bottom there are three more alignment attributes that can be used to govern horizontal alignment. They are called center, left and right. Since I always confuse middle (the vertical one) and center (the horizontal one), Msc-generator also has four aliases to these two: xcenter, xmiddle, ycenter and ymiddle to disambiguite which axis is along with we seek the center position.

As value for these attributes, you can specify not only a block name, but also a part of the block after the at sign @. Furthermore, alignment modifiers can be followed by a block so that they can work no blocks other than the previous ones.

exC8_cshexC8

It is possible to have not only boxes, but any arbitrary shape for a block. This can be achieved via using the shape keyword followed by the name of the shape instead of the box keyword. As a shorthand, the asterisk symbol (*) can also be used. A handful of basic shapes are defined in the default design library and can be used. You can also add text without any borders or background. This is useful as explanatory notes. Those can be added with the text command as seen below.

exD3_cshexD3

You can define your own shapes via the defshape command, but defining a separate shape for something simple is often too complicated. To this end, Msc-generator allows you to join blocks that are overlapping or touching. Joing blocks will remove any internal lines and keep a single contour. Below you can see 4 blocks without and with an additional join command.

exF7_cshexF6exF7

Note that the fill of the joined blocks is kept, together with any label. You can assign any line, fill or shadow attributes to the joined block, which override the line, fill and shadow attributes of the original blocks. By default, only line attributes are on, thus the joined block has no fill or shadow.

Another way to define a new block is to encircle a set of existing blocks. This can be done by the around keyword. In the middle figure of the below example you can see that we use two boxes (A1 and A2) and an oval (A3) to encircle various boxes. On the right figure, we have added the join command at the last line of the example, which combined the two boxes. Note that even if A3 does not touch or overlap with A1 or A2, it can still be part of the join.

exF9_cshexF8exF9

Such around blocks have no fill by default. Note that we have used compound names when specifying the boxes to encircle. Each of the four column had a name (x, y, z and v), but inside the columns the box names were re-used (a, b, c and d). To name a specific block you can use the name of the containing block to disambiguite before the block name.

When drawing diagrams, a technique is often used to indicate that we have several instances of a block. This technique can be expressed by prepending the multi keyword in front of any block definition.

exG0_cshexG0

You can apply a number after the multi keyword to specify how many copies do you want, the default is 3. You can still refer to any blocks contained within (B.o in the example) and two more blocks: front and back to refer to the first and last in the series of copies.

You can also copy an already existing block. This is a quick way to define larger diagrams. You can give the copy a name, change its attributes or even replace its content (or add to it).

exG8_cshexG8

Footnotes

(9)

Alignment modifiers also result in side-by-side placement (subject to the respective margins). Thus below means that the Y coordinate of the bottom of the previous block (plus its bottom margin) equals to the Y coordinate of the current block (minus its top margin).