Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
Basic Elements
Simple Boxes
>>>
:{
aa2u "++ +-----+ +--+--+-----+ \n\ \++ +--+ | | | | | \n\ \ | | +--+--+--+--+ \n\ \+---+ | | | | | | \n\ \+---+ +--+ +-----+--+--+ " :} ┌┐ ┌─────┐ ┌──┬──┬─────┐ └┘ └──┐ │ │ │ │ │ │ │ ├──┴──┼──┬──┤ ┌───┐ │ │ │ │ │ │ └───┘ └──┘ └─────┴──┴──┘
Rounded Boxes
>>>
:{
aa2u ".. .-----. .--+--+-----. \n\ \'' '--. | | | | | \n\ \ | | +--+--+--+--+ \n\ \.---. | | | | | | \n\ \'---' '--' '-----+--+--' " :} ╭╮ ╭─────╮ ╭──┬──┬─────╮ ╰╯ ╰──╮ │ │ │ │ │ │ │ ├──┴──┼──┬──┤ ╭───╮ │ │ │ │ │ │ ╰───╯ ╰──╯ ╰─────┴──┴──╯
Dotted and double strokes
>>>
:{
aa2u "++ .-----. +==+==+=====+ \n\ \++ +==+ : | : | | \n\ \ : : +==+==+==+==+ \n\ \+===+ : : | | : | \n\ \+---+ '--' +=====+==+==+ " :} ┌┐ ╭─────╮ ╒══╤══╤═════╕ └┘ ╘══╕ ┆ │ ┆ │ │ ┆ ┆ ╞══╧══╪══╤══╡ ╒═══╕ ┆ ┆ │ │ ┆ │ └───┘ ╰──╯ ╘═════╧══╧══╛
Cast shadows
>>>
:{
aa2u "+-------------+ \n\ \| | \n\ \+---+ +---+# \n\ \ ##| |##### \n\ \ | |# \n\ \ +-----+# \n\ \ ###### " :} ┌─────────────┐ │ │ └───┐ ┌───┘█ ██│ │█████ │ │█ └─────┘█ ██████
Properties
Idempotent
Already rendered portions are not affected:
>>>
:{
aa2u "┌┐ ╭─────╮ ╒══╤══╤═════╕ ┌───┐ \n\ \└┘ ╘══╕ ┆ │ ┆ │ │ │ │ \n\ \ ┆ ┆ ╞══╧══╪══╤══╡ │ │█ \n\ \╒═══╕ ┆ ┆ │ │ ┆ │ └───┘█ \n\ \└───┘ ╰──╯ ╘═════╧══╧══╛ ████ " :} ┌┐ ╭─────╮ ╒══╤══╤═════╕ ┌───┐ └┘ ╘══╕ ┆ │ ┆ │ │ │ │ ┆ ┆ ╞══╧══╪══╤══╡ │ │█ ╒═══╕ ┆ ┆ │ │ ┆ │ └───┘█ └───┘ ╰──╯ ╘═════╧══╧══╛ ████
Incremental
Existing characters can be removed:
>>>
:{
aa2u "┌──┬ ┬──┐\n\ \ │ │ │\n\ \╞══╪ ╪══╡\n\ \│ \n\ \├──┼ ┼──┤\n\ \ │ │ │\n\ \└──┴ ┴──┘" :} ───┐ ┌──┐ │ │ │ ╒══╛ ╘══╛ │ └──┐ ┌──┐ │ │ │ ───┘ └──┘
New connections can be added:
>>>
:{
aa2u "┌──┐-┌──┐\n\ \│ │ │ │\n\ \╘══╛=╘══╛\n\ \| : : |\n\ \┌──┐-┌──┐\n\ \│ │ │ │\n\ \└──┘-└──┘" :} ┌──┬─┬──┐ │ │ │ │ ╞══╪═╪══╡ │ ┆ ┆ │ ├──┼─┼──┤ │ │ │ │ └──┴─┴──┘
Existing connections can be altered by replacing/adding characters:
>>>
:{
aa2u "┌──+──┐ .─────+─────. ┌────┐ \n\ \│ +==+ │ | │ │####│ \n\ \+==+ | │ | │ │# │█ \n\ \└──+─-┘ │ +-----+ └────┘█# \n\ \ +=====+ │ █████# \n\ \╭──+─-╮ │ | │ ##### \n\ \│ | | │ | │ \n\ \╰──+──╯ '───────────' " :} ┌──┬──┐ ╭─────┬─────╮ ┌────┐ │ ╞══╡ │ │ │ │████│ ╞══╡ │ │ │ │ │█ │█ └──┴──┘ │ ├─────┤ └────┘██ ╞═════╡ │ ██████ ╭──┬──╮ │ │ │ █████ │ │ │ │ │ │ ╰──┴──╯ ╰───────────╯
Limitations
Some connections do not work as expected (mostly because the corresponding Unicode characters do not exist), e.g. rounded corners with double-stroke lines, or connection pieces connecting horizontal single- and double-stroke lines:
>>>
:{
aa2u "--+== .==. .--.--. \n\ \ | | | | | | \n\ \==+-- '==' .--+--' \n\ \ | | | | \n\ \--+== --== '--'--' " :} ──┐══ ╒══╕ ╭──╮──╮ │ │ │ │ │ │ ══├── ╘══╛ ╰──┼──╯ │ │ │ │ ──┘══ ──══ ╰──╰──╯
- data Zipper a = Zipper {}
- moveBefore :: Zipper a -> Zipper a
- moveAfter :: Zipper a -> Zipper a
- zipperToList :: Int -> Zipper a -> [a]
- zipperOf :: a -> Zipper a
- zipperFromList :: a -> [a] -> Zipper a
- newtype Plane a = Plane {}
- moveLeft :: Plane a -> Plane a
- moveRight :: Plane a -> Plane a
- moveUp :: Plane a -> Plane a
- moveDown :: Plane a -> Plane a
- planeToList :: Int -> Int -> Plane a -> [[a]]
- planeOf :: a -> Plane a
- planeFromList :: a -> [[a]] -> Plane a
- newtype Pattern = Pattern ((Char, Char, Char), (Char, Char, Char), (Char, Char, Char))
- patternFromString :: String -> Pattern
- patternToString :: Pattern -> String
- lookupPattern :: Pattern -> Maybe Char
- connectsLike :: Char -> Char -> Bool
- patterns :: [(Pattern, Char)]
- substituteChar :: Plane Char -> Char
- renderAsciiToUnicode :: Plane Char -> Plane Char
Zipper
The Zipper
is assumed to be infinite, i.e. filled with empty values
outside the defined area.
moveBefore :: Zipper a -> Zipper a Source #
zipperToList :: Int -> Zipper a -> [a] Source #
zipperFromList :: a -> [a] -> Zipper a Source #
Plane (two-dimensional Zipper
)
planeFromList :: a -> [[a]] -> Plane a Source #
Create a Plane
from a list of lists, filling the rest with a
s in all
directions.
Patterns
patternFromString :: String -> Pattern Source #
patternToString :: Pattern -> String Source #
connectsLike :: Char -> Char -> Bool Source #
Whether a character can connect to another character. For example, +
connects both horizontally (like -
) and vertically (like |
), so it
connectsLike
-
, |
, and of course like itself.
patterns :: [(Pattern, Char)] Source #
The actual pattern definitions. For convenience, the simple patterns are at
the top, and more complex ones at the bottom. lookupPattern
will first try
the most complex pattern and work its way to the simpler patterns, thus
avoiding to choose a simpler pattern and forgetting some connection.
Transforming ASCII to Unicode
renderAsciiToUnicode :: Plane Char -> Plane Char Source #
Transform a Plane
of ASCII characters to an equivalent plane where the
ASCII box drawings have been replaced by their Unicode counterpart.
This function is a convolution with substituteChar
using the Comonad
ic
extend
.
>>>
:{
aa2u :: String -> IO () aa2u input = let inputLines = lines input plane = planeFromList ' ' inputLines width = maximum (fmap length inputLines) height = length inputLines in putStr . unlines . fmap (reverse . dropWhile (== ' ') . reverse) . planeToList height width . renderAsciiToUnicode $ plane :}