### 6.1 Defining and Arranging Blocks

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

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.

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.

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.

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.

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.)

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.

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.

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.

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.8

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.

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.

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.

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.

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.

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).

#### Footnotes

##### (8)

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).