### 11.4 Block Layout ¶

The layout of blocks is central to the block diagram language. It is governed primarily by the alignment attributes of each block. We have quite a number of them, but they are quite easy to remember. Four are for horizontal alignment: `left`, `center`, `right` and `xpos` and four are for vertical alignment: `top`, `middle`, `bottom` and `ypos`. Since the words center and middle are easy to mix, `xmiddle` and `xcenter` can be used for `center` and `ymiddle` and `ycenter` for `middle`.

These attributes govern, where the sides or the centerline of the block is placed in the horizontal or vertical direction. As value you can name any side or centerline of any other block (in the same direction only). If you only specify a block name the same side/centerline is used, that is `left=A` means `left=A@left`.

When you set one of the four side attributes (`left`, `right`, `top` or `bottom`) it refers to the visible side of the block. If you want to align to the side of the block including margins prepend these four values with the letter `m` both as attribute names and attribute values, e.g., `mleft=a@right` or `top=b@mbottom`. Note that setting either of `left` or `mleft` both set the position of the left side, so setting one will overwrite the other - they are effectively the same attribute with the margin as difference. On the below example you can see that block `B` is aligned to block `A` without marging in the X direction and with margins in the Y direction.

You can not select a side for `xpos` or `ypos`, just a block. It is equivalent to setting both `left`/`right` or `top`/`bottom` to the same block effectively resulting in the same width or height as the referenced block.

You can specify multiple blocks separated by the plus sign (`+`) as value to any of the alignment attributes. In this case Msc-generator takes the bounding box of the listed blocks and aligns to that. If you specify the `m` letter after the `@` symbol, the bounding box is calculated from the listed blocks with their margin.

In addition to the tokens representing box sides or centers, you can align to any part of a block by appending a percentage number after the `@` symbol. The value `0%` is equivalent to `top` (or `left`), while `100%` represents `bottom` (or `right`). Naturally `50%` means `middle` (or `center`). However, you can also specify any other number, even smaller than zero or larger than 100%. (You can omit the percent sign.) You can use the `m` letter even with percentage numbers, such as `left=A@m33%`, which means the left thirdpoint of the span between the left side of A minus its left margin and right side of A plus its right margin.

Finally, you can also add a pixel offset at the end of alignment attribute values. Positive values mean right or down. Thus the full syntax for alignment attributes is as below.

    [block[+block]...][+-offset][@[m](token|percentage)[+-offset]]

Where

- `token` can be one side or `middle`/`center`;
- `percentage` is a number with an optional percentage sign;
- if no blocks are specified, `prev` is assumed;
- if no at (`@`) symbol (and parts after) is specified the token value defaults to the attribute we set; and
- only one of the two `offset` values can be present.

A second way to specify block alignment is to align it to its parent. In this case the `@` symbol shall be omitted and the syntax becomes as below.

    [m]percentage%[+-offset]]
    [m][offset]

If you specify a percentage, it refers to the position between the inner margins of the parent. Thus, `top=10%` will place the top of the block close to the upper internal margin of the parent, while `0%` and `100%` refers to alignment to the top or bottom internal margin of the parent, respectively. Specifying an offset is added in pixels to the position designated by the percentage. Specifying only an offset (no percentage sign) will be a pixel position added to the top or left internal margin. Prepending a `m` character will use space covered by the content part of the parent block ignoring any inner margin.70 71

Of course, all contained blocks must end up between the inner margins. Thus when you specify the above, do not use percentages outside the 100% region. Also, bear this in mind when ignoring the inner margin, e.g., do not specify `top=m0%` unless the inner margin is zero, since this by definition dictates a block to be outside. When the attribute specified violates this rule, it will be ignored with an error, see Block Layout Conflicts.

After applying all alignment attributes, exactly one or two of each direction triplet has to be specified. (`xpos` and `ypos` immediately specifies two of them.) If only one is specifed, the block’s size will determine the other side. That is, in case of specifying `top=A`, but neither of `bottom` or `middle` the bottom side will be determined by adding the height of the block in question. If two of the triplet are specified, they also act as a size specifier, so `left=A, right=A` makes the block as wide as `A`.

You can use `prev`, `next`, `first` and `last` instead of a block name. These refer to the block specified before the current one, the one specified after, the first or last block within this parent block.72 This allows easy default values. For example, `mleft=prev@mright, ycenter=prev` will align just right of the previous block - in a row including outer margins. Note that you must avoid using `prev` and `first` on the first element inside a block and `last` and `next` on the last one. These generate an error.

#### Footnotes

##### (70)

For shapes this is the area specified by the `T` line in a `defshape` command, see Defining Shapes. For boxes this is the inner edge of the box line. If the corners are bevelled or rounded, this is the largest rectangle that fits into the box.

##### (71)

Note that when referring to the parent the presence of the ’m’ character will ignore the inner margin, whereas when refferring to another block, the presence it will include the outer margin. This is so that the most common case would not need the ’m’ character.

##### (72)

Specifically, this is not the first and last element within the scope, since you can open new scopes any time. This is the first or last block, who has the same parent block.