hdrawing

Simple shape drawing


Need help? Read Nimble

readme

Helper for pretty-printing things in terminal. Draw grids, boxes, easily concatenate string blocks. Correctly handles unicode and ANSI escape codes. Supports multicell grids.

Installation

nimble install hdrawing

Links

Primitives

withBufEcho:
  newTermText((1, 1), @["* 222", "    )))"]).render(buf)

:

 * 222
     )))
withBufEcho:
  newBoxedTermText(
    (1, 1), @["Text inside", "of ascii box"],
    makeAsciiRectBorder()
  ).render(buf)

:

 +------------+
 |Text inside |
 |of ascii box|
 +------------+

Contribution & development (planned/TODO)

The code is mostly just ten layers of if/else and for loops nested in each other, but if you have any questions about implementation can as them on my discord server. New features I might add later. Things I plan to add:

Annotations for expressions/parse trees

2 + 3   *    4
| | |   |    |
| | +-Factor-+
| |     |
+-Expr -+

Parse tree - token mapping

                      +-----------------------+
+---------------------+Sum -> Sum [+-] Product+-------------------+
|                     +-----------------------+                   |
|+--------------+ +----+           +-----------------+            |
++Sum -> Product++|[+-]|+----------+Product -> Factor+------------+
|+--------------+|+----+|          +-----------------+            |
|                |      |                                         |
0                1      2     3     4      5    6     7     8     9
+----------------+------+-----+-----+-----+-----+-----+-----+-----+
|       1        |  +   |  (  |  2  |  *  |  3  |  -  |  4  |  )  |
+----------------+------+-----+-----+-----+-----+-----+-----+-----+

Parse tree standalone

         +-------+
         | Block |
         +---+---+
           +-+--+
           | If |
           ++++++
   +--------+||+------------------+
   |         |+-------+           |
+--+---+ +---+---+ +--+-----+ +---+---+
| "if" | | Block | | "else" | | Block |
+------+ +---+---+ +--------+ +---+---+
           +-+--+             +---+--+
           | If |             | "{}" |
           +-++-+             +------+
        +----++----+
     +--+---+  +---+---+
     | "if" |  | Block |
     +------+  +---+---+
               +---+--+
               | "{}" |
               +------+

Embed nested grids into each other

+-------------------+---+---------+----+-----+
|World              |222|(((---)))|***)|***  |
|reallyu long string+---+---------+----+-----+
|                   |222|((()))   |*** |***  |
|                   +---+---------+----+-----+
|Hello              | Some annotation        |
+------+------------+-------------+----------+
|222   |(((---)))   |***          |***       |
|      |            |((()))       |          |
+------+------------+-------------+----------+
|222   |((()))      |***          |***       |
+------+------------+-------------+----------+

More Random examples

import strformat
import hdrawing

var buf = newBuf()
newTermText((0,0), @["* (0, 0)".toRunes()]).render(buf)
newTermText((8, 5), @["* (5, 5)"]).render(buf)
newTermPoint((39, 19)).render(buf)
newBoxedTermText(
  (0, 0), @["Hello world", "Some text", "to render"]
).render(buf)
newTermPoint((0, 0), '@').render(buf)

let w = 10
newTermRect((8, 6), w, 5, makeAsciiRectBorder()).render(buf)

for p in 6 .. 11:
  newTermText((8 + w, p), @[&"* ({8 + w}, {p})"]).render(buf)

newTermText((8, 11), @["12345"]).render(buf)

newBoxedTermText(
  (15, 15), @["Text inside", "of unicode box"],
  makeAsciiRectBorder()
).render(buf)
echo buf.toString()
@#############
#Hello world #
#Some text   #
#to render   #
##############
        * (5, 5)
        +--------+* (18, 6)
        |        |* (18, 7)
        |        |* (18, 8)
        |        |* (18, 9)
        +--------+* (18, 10)
        12345     * (18, 11)



               +--------------+
               |Text inside   |
               |of unicode box|
               +--------------+
                                       +
import strutils, sequtils, strformat, options
import ../src/hdrawing
import hmisc/types/[seq2d, colorstring]

proc ms(a, b: int): auto = makeArrSize(a, b)
let nn = none((ArrSize, TermBuf))
proc sb(s: string): TermBuf = s.toTermBuf()
echo newTermMultiGrid(
  (0, 0),
  @[
    @[
      some((ms(2, 3), sb("Hello\nWorld\nreallyu long str\ning"))),
      nn,
      some((ms(2, 3), sb(newTermMultiGrid(
        (0, 0),
        @[
          @[
            some((ms(1, 1), sb("222"))),
            some((ms(1, 1), sb("(((---)))"))),
            some((ms(1, 1), sb("***)"))),
            some((ms(1, 1), sb("***")))
          ],
          @[
            some((ms(1, 1), sb("222"))),
            some((ms(1, 1), sb("((()))"))),
            some((ms(1, 1), sb("***"))),
            some((ms(1, 1), sb("***")))
          ],
        ],
        makeAsciiGridBorders(),
      ).toTermBuf().toString() & "\nSome annotation"))),
      nn
    ],
    @[nn, nn, nn, nn],
    @[nn, nn, nn, nn
    ],
    @[
      some((ms(1, 1), sb("222"))),
      some((ms(1, 1), sb("(((---)))"))),
      some((ms(1, 1), sb("***\n((()))"))),
      some((ms(1, 1), sb("***")))
    ],
    @[
      some((ms(1, 1), sb("222"))),
      some((ms(1, 1), sb("((()))"))),
      some((ms(1, 1), sb("***"))),
      some((ms(1, 1), sb("***")))
    ],
  ],
  makeAsciiGridBorders(),
).toTermBuf().toString()
+----------------+------------------------+
|Hello           |+---+---------+----+---+|
|World           ||222|(((---)))|***)|***||
|reallyu long str|+---+---------+----+---+|
|ing             ||222|((()))   |*** |***||
|                |+---+---------+----+---+|
|                |Some annotation         |
+----+-----------+-------------+----------+
|222 |(((---)))  |***          |***       |
|    |           |((()))       |          |
+----+-----------+-------------+----------+
|222 |((()))     |***          |***       |
+----+-----------+-------------+----------+

Author: haxscramper

Licence: Apache-2.0

Project website

Docs