Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1656x 1656x 1656x 1656x 1656x 1656x | import {Record} from '#util'
import {dual, K, type EndoOf} from '#Function'
import {segmentString} from '#String'
import {type TupleOf} from 'effect/Types'
import {elbowDirections} from '../direction.js'
import type {CornerDirection, ElbowSet} from './types.js'
const _replaceElbow = (
set: ElbowSet,
direction: CornerDirection,
glyph: string,
): ElbowSet => Record.modify(set, direction, K(glyph))
/**
* Given a direction and a glyph, replaces the elbow at this direction in a given
* elbow set with the given glyph and returns the new elbow set.
*
* At the key `named` you will find a version that does the same but accepts a
* _name_ of an elbow set instead of an elbow set.
* @param set Elbow set to change.
* @param direction A {@link CornerDirection} of the glyph to be changed.
* @param glyph String of new glyph.
* @returns Updated elbow set.
* @category drawing
* @function
*/
export const replaceElbow: {
(set: ElbowSet, direction: CornerDirection, glyph: string): ElbowSet
(direction: CornerDirection, glyph: string): EndoOf<ElbowSet>
named: (
direction: CornerDirection,
glyph: string,
) => (name: ElbowSetName) => ElbowSet
} = Object.assign(dual(3, _replaceElbow), {
named: (direction: CornerDirection, glyph: string) => (name: ElbowSetName) =>
_replaceElbow(elbowSet(name), direction, glyph),
})
/**
* Names of all elbow sets.
* @category drawing
*/
export const elbowSetNames = [
'ascii',
'diagonal',
'double',
'halfSolid',
'halfSolidNear',
'halfSolidFar',
'hDouble',
'hThick',
'round',
'solid',
'space',
'thick',
'thin',
'vDouble',
'vThick',
] as const
/**
* The type of a elbow set name.
* @category drawing
*/
export type ElbowSetName = (typeof elbowSetNames)[number]
/**
* A record of all elbow sets. An elbow set has an elbow defined for each elbow
* direction. The elbows are grouped into sets by style.
* @category drawing
*/
export type ElbowSets = Record<ElbowSetName, ElbowSet>
const elbowSets: ElbowSets = {
ascii: fromQuad(`..''`),
diagonal: {topLeft: '╱', topRight: '╲', bottomLeft: '╲', bottomRight: '╱'},
double: fromQuad('╔╗╚╝'),
hDouble: fromQuad('╒╕╘╛'),
hThick: fromQuad('┍┑┕┙'),
round: fromQuad('╭╮╰╯'),
solid: Record.monoRecord('█')(...elbowDirections),
space: Record.monoRecord(' ')(...elbowDirections),
thick: fromQuad('┏┓┗┛'),
thin: fromQuad('┌┐└┘'),
vDouble: fromQuad('╓╖╙╜'),
vThick: fromQuad('┎┒┖┚'),
halfSolid: fromQuad('▞▚▚▞'),
halfSolidNear: fromQuad('▗▖▝▘'),
halfSolidFar: fromQuad('▛▜▙▟'),
}
/**
* Get an elbow set by name.
*
* You can mix and match sets. For example if you need a set of elbows for a box
* where all borders are thin lines except the bottom which is a thick line,
* you could:
*
* ```ts
* import {Draw} from 'effect-tree'
*
* const myElbowSet: Draw.ElbowSet = {
* ...Struct.pick(Draw.elbowSet('thin'), ...Draw.topElbows),
* ...Struct.pick(Draw.elbowSet('hThick'), ...Draw.bottomElbows),
* }
* ```
*
* And your elbows will be thin, except for the bottom:
*
* ```txt
* topLeft ┌ ┐ topRight
*
* bottomLeft ┕ ┙ bottomRight
* ```
* @category drawing
* @function
*/
export const elbowSet = (name: ElbowSetName): ElbowSet => elbowSets[name]
function fromQuad(s: string): ElbowSet {
const [topLeft, topRight, bottomLeft, bottomRight] = segmentString(
s,
) as TupleOf<4, string>
return {topLeft, topRight, bottomRight, bottomLeft}
}
|