Skip to content

Lua-like vexillographical description language, made for humans and computers alike.

License

Notifications You must be signed in to change notification settings

wallabra/Vexillogos

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Vexillogos 1.0.1

Table of Contents

Vexillogos is a vexillological description language, partially inspired by Lua, which has a focus on simplicity and expressivity, ease of reading and writing for humans, and ease of parsing for computers.

It is hierarchical in nature, and operates by subdividing a root region, the 'flag', recursively into smaller regions, and applying solid colour to those which are not split further.

1. Rules

Vexillogos grammar and hierarchy is roughly defined as follows.

  1. You "paint" the flag by writing a list of commands that divide an initial rectangle into regions, applying colour to 'leaf' regions (i.e. those which are not split further).

  2. The initial rectangle has the special region name flag, which does not need region before it; you can use an optional property ratio to define the size ratio, which defaults to 2:3

  3. After a region specifier and optional properties, must be, either a colour value, or a split definition followed by region stylesheets, followed by end.

    1. To paint a region, simply write a colour of your choice after its definition.

    2. To split a region, put a splitting command after it.

  4. A split command will define its own regions which are only valid in its region stylesheet block, and not child ones either.

  5. A region <id>` clause applies a colour or split to a region, while a 'default' clause will apply the same colour or split pattern to all unspecified regions.

    1. A split within a default clause will usually be repeated for each individual region.

    2. The optional property contiguous, after the clause keyword 'default', will change the behaviour above, so that the split only repeats for all contiguous areas.

  6. The above conditions also apply for concave shapes.

  7. Regular splits (bars or shapes) will split a region by it bounding box, even if the region is not a rectangle or convex shape.

    1. Horizontal and vertical bar strips are enumerated from left to right (for vertical splits), or top to bottom (for horizontal splits), starting at 1.

    2. Regular shape splits, split a region into an inner and an outer region, which are complements of the region; e.g. for a rectangle with a losangle inside it, 'outer' is the area outside the rectangle. regular shapes are inscribed as large as possible in the centre of the previous region.

      The following regular shapes are defined by standard, but more may be implemented: circle, losangle, equitriangle (equilateral triangle), square, pentagon, hexagon, octagon, fourstar, fivestar, sixstar.

      The {four,five,six}star shapes are concave isotonal star polygons, with the outer radius being the automatic radius of any regular shape (i.e. the maximum radius inscribable within the current region), and the inner radius defaulting to 50% of the outer radius, a default which is overridable with inner X, where X is a percentage or ratio value which multiplies the outer radius (e.g. 25%, 1/4 or 2:8). For instance, fivestar inner 75% is a fat, five-pointed star.

  8. Diagonal splits, split a region into left and right regions, by defining a line splitting thruogh the centre of the region, that from left to right either goes upward or downward - diagonal up or diagonal down.

    1. By default, this line’s angle is that between the bottom left and top right corners of the bounding box, even in the convex hull — this behaviour can be changed by manually specifying a slope property, slope a/b, after upward or downward, where 'a/b' is a fraction whose components are whole numbers of at least 1. Unlike the default automatic slope, this is an absolute value by default, but the value can be preceded by relative to instead serve as a multiplier, such as slope relative 3/2.

    2. By default, the centre of the region is considered to be the centre of mass of its convex hull. For non-rectangular convex hulls, this behaviour can be changed to instead consider the centre of the rectangular bounding box of this region.

  9. A border split splits a region into inner and outer regions, by adding a border along every edge. The area of this border becomes outer, and the area within inner.

    1. The default behaviour is to add a border within the convex hull of the region, which is parallel to the edges of the region.

    2. The optional property box between the split keyword 'border' and its thickness value (c), changes the default behaviour, by adding a border within the bounding box instead, akin to the regular splits described in (7).

    3. The thickness of the border is defined by a percentage or ratio proportion, between the edge and the centre.

      Note
      More precisely, it is defined such that at any point along the region edge, at the line segment formed between it, perpendicular to the edge, and the projection of the centre of the convex hull or bounding box (depending on (a) or (b)) onto an infinite line extending from line segment, the section of the line segment that intersects with the border is the outer N% (or A/Bths) of the full length of this line segment.
    4. For (c), the centre point is considered as either the centre of mass of the convex hull or, in case of 'box' mode, the centre of the rectangular bounding box.

  10. Comments are Lua-style.

  11. Akin to Lua, newlines and indentation are cosmetic only; any non-zero amount of whitespace is sufficient to separate tokens.

Note that all bounding boxes used for reference in the above rules are axis-aligned.

2. Example

-- The root region is called 'flag'. The region keyword can be omitted here.
-- The size ratio is an optional property and defaults to 2:3, but is included
-- here anyway for demonstrational completeness.
flag ratio 2:3 split horizontal 3 bars
    -- To colour a region, we simply follow its specifier with a colour value.
    region 1 #690420 end
    region 3 #069420 end

    -- Instead of a colour value, we can use 'split' followed by a split specifier.
    region 2 split horizontal 5 bars
        -- Here we have defined a split of 5 bars.
        -- However, we are only colouring the first and last ones.
        region 1 black end
        region 5 black end

        -- Since we did not apply any particular region clause to the
        -- remaining regions (2, 3 and 4), they are covered by the 'default' clause.
        -- Conveniently, the area they form together is contiguous, not disjoint, so
        -- we can simply apply the optional property 'contiguous' below to use them as
        -- a single region, rather than repeating a pattern once per region.
        default contiguous split border box 1/5
            -- Borders and regular shapes define two split regions: outer and inner.
            -- Hint: 'outer' is always simply any area of the region not within 'inner'!
            region outer white end
            region inner split losangle
                -- Since the outer region is not convex, the diagonal split will cut through it using
                -- the centre of its convex hull as a reference. In this case, that happens to be rectangular,
                -- so no 'box' property is needed.
                region outer split diagonal upward slope relative 3/2
                    region left #690600 end
                    region right #042690 end
                end
                region inner #800850 end
            end
        end
    end
end

This Vexillogos composition is equivalent to the following image:

A manual SVG rendering of the example flag in the Vexillogos README. If you’re reading this

3. Licensing

The Vexillogos language is free for use in all circumstances. It may not be patented.

All samples of example code and imagery are licensed freely under the Free Art License 1.3.

©2022 Gustavo Ramos Rehermann.