Combinators for creating and manipulating two-dimensional rectangular text layouts
// Create a single character box
let star = singleton('*')
// Create filled rectangles
let rect = fill('█', 3, 5) // 3 rows, 5 columns of █
// Create empty space
let gap = space(2, 4) // 2 rows, 4 columns of spaces// Place boxes side by side
let horizontal = box1.beside(box2)
// Stack boxes vertically
let vertical = box1.above(box2)
// Combine multiple boxes
let combined = hconcat([box1, box2, box3]) // horizontal
let stacked = vconcat([box1, box2, box3]) // verticalfn sierpinski(n) {
guard n > 0 else { singleton('*') }
let s = sierpinski(n - 1)
s.above([s, singleton(' '), s] |> hconcat())
}
sierpinski(4) *
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *fn diamond(size : Int) -> Box {
let lines = []
// Top half including middle
for i = 0; i <= size; i = i + 1 {
let spaces = size - i
let stars = 2 * i + 1
let line = space(1, spaces)
.beside(fill('*', 1, stars))
.beside(space(1, spaces))
lines.push(line)
}
// Bottom half
for i = size - 1; i >= 0; i = i - 1 {
let spaces = size - i
let stars = 2 * i + 1
let line = space(1, spaces)
.beside(fill('*', 1, stars))
.beside(space(1, spaces))
lines.push(line)
}
vconcat(lines)
} *
***
*****
*******
**********
*******
*****
***
*fn bar_chart(values : Array[Int]) -> Box {
let max_val = values.fold(init=0, fn(a, b) { if b > a { b } else { a } })
let bars = values.map(fn(v) {
let height = v * 10 / max_val + 1
fill('█', height, 3).above(
v.to_string().iter().map(singleton).to_array() |> hconcat(),
)
})
hconcat(bars, align=Bottom)
}fn spiral(n : Int) -> Box {
if n <= 0 {
singleton('+')
} else {
let s = spiral(n - 1)
let (h, w) = s.dimensions()
let vbar = fill('|', h, 1)
grid([
[
singleton('|').beside(singleton(' ')).beside(singleton('+')),
fill('-', 1, w),
singleton('+'),
],
[vbar, singleton(' '), s, singleton(' '), vbar],
[singleton('+'), fill('-', 1, w + 2), singleton('+')],
])
}
}| +-------------------------------------+
| | +---------------------------------+ |
| | | +-----------------------------+ | |
| | | | +-------------------------+ | | |
| | | | | +---------------------+ | | | |
| | | | | | +-----------------+ | | | | |
| | | | | | | +-------------+ | | | | | |
| | | | | | | | +---------+ | | | | | | |
| | | | | | | | | +-----+ | | | | | | | |
| | | | | | | | | | +-+ | | | | | | | | |
| | | | | | | | | | + | | | | | | | | | |
| | | | | | | | | +---+ | | | | | | | | |
| | | | | | | | +-------+ | | | | | | | |
| | | | | | | +-----------+ | | | | | | |
| | | | | | +---------------+ | | | | | |
| | | | | +-------------------+ | | | | |
| | | | +-----------------------+ | | | |
| | | +---------------------------+ | | |
| | +-------------------------------+ | |
| +-----------------------------------+ |
+---------------------------------------+fn binary_tree(depth : Int) -> Box {
if depth <= 0 {
singleton('*')
} else {
let left = binary_tree(depth - 1)
let right = binary_tree(depth - 1)
let root = singleton('*')
let branches = [left, space(1, 3), right] |> hconcat()
root.above(branches)
}
} *
* *
* * * *
* * * * * * * *type Boxlet box = fill('*', 2, 3)
let logger = @buffer.new()
box.output(logger)
// Logs:
// ***
// ***let top = fill('T', 1, 5)
let bottom = fill('B', 2, 3)
let _stacked = top.above(bottom, align=Left)let left = fill('L', 2, 3)
let right = fill('R', 3, 2)
let _combined = left.beside(right, align=Top)let box = fill('*', 3, 5)
let _ = box.dimensions() // returns (3, 5)let content = fill('*', 2, 4)
let _framed = content.framed()
// Creates:
// +----+
// |****|
// |****|
// +----+let box = fill('*', 3, 5)
let _ = box.height() // returns 3let box = fill('*', 2, 3)
let _heightened = box.heighten(5, align=Top)
// Adds 3 rows of spaces belowlet base = fill('.', 3, 5)
let marker = grid([
[singleton(' '), singleton('#')],
[singleton('#'), singleton('#')],
])
let _combined = base.overlay(marker, dx=1, dy=1)
// Result:
// .....
// ..#..
// .##..let box = fill('*', 2, 3)
let _widened = box.widen(7, align=Left)
// Adds 4 spaces to the rightpub(all) enum Horizontal {
Left
Center
Right
}pub(all) enum Vertical {
Top
Center
Bottom
}let _star = fill('*', 3, 5)
// Creates:
// *****
// *****
// *****let corner = singleton('+')
let h_bar = fill('-', 1, 3)
let v_bar = fill('|', 1, 1)
let center = fill(' ', 1, 3)
let _frame = grid([
[corner, h_bar, corner],
[v_bar, center, v_bar],
[corner, h_bar, corner],
])let boxes = [fill('A', 2, 1), fill('B', 3, 1), fill('C', 1, 1)]
let _combined = hconcat(boxes, align=Bottom)let _star = singleton('*')
// Creates a single '*'let _gap = space(2, 4)
// Creates 2 rows of 4 spaces eachlet boxes = [fill('A', 1, 3), fill('B', 1, 5), fill('C', 1, 2)]
let _stacked = vconcat(boxes, align=Left)Combinators for creating and manipulating two-dimensional rectangular text layouts