Преобразовать чертеж ASCII-блока в Unicode

16

Я беззастенчиво публикую запрос о чем-то, что я бы нашел полезным. Задача состоит в том, чтобы взять произвольный чертеж Ascii Box, как это

     |
+----+----+
| state A +---+
+---------+   |
              |
         +----v----+
         | state B |
         +---------+

... и превратить его во что-то более красивое, используя символы рисования юникодного блока, например

     │
╭────┴────╮
│ state A ├───╮
╰─────────╯   │
              │
         ╭────v────╮
         │ state B │
         ╰─────────╯

Подробнее:

  • конвертировать только + - | символы - другие символы должны быть неизменными
  • использование

    • ЯЩИКИ ЯЩИКОВ ЛЕГКИЙ ВЕРТИКАЛЬНЫЙ (U + 2502) │
    • ЯЩИКИ ЯЩИКОВ ЛАЙТ ГОРИЗОНТАЛЬНЫЕ (U + 2500) ─
    • ЧЕРТЕЖИ ЯЩИКА ОСВЕЩАЮТ ДУГУ ВНИЗ И ВПРАВО (U + 256D) ╭
    • ЧЕРТЕЖИ ЯЩИКА ОСВЕЩАЮТ ДУГУ И ВЛЕВО (U + 256E) ╮
    • ЧЕРТЕЖИ ЯЩИКА ОСВЕЩАЮТ ДУГУ И ВЛЕВО (U + 256F) ╯
    • ЧЕРТЕЖИ НА КОРОБКЕ ОСВЕЩАЮТ ДУГУ И ВПРАВО (U + 2570) ╰
    • ЯЩИКИ КОРОБКИ ЛЕГКИЕ ВЕРТИКАЛЬНЫЕ И ЛЕВЫЕ (U + 2524) ┤
    • ЯЩИКИ ЯЩИКОВ ВЕРТИКАЛЬНЫЕ И ПРАВЫЕ (U + 251C) ├
    • ЯЩИКИ КОРОБКИ ОСВЕЩЕНЫ И ГОРИЗОНТАЛЬНЫ (U + 252C) ┬
    • ЧЕРТЕЖИ КОРОБКИ ОСВЕЩАЮТ И ГОРИЗОНТАЛЬНО (U + 2534) ┴
    • ЯЩИКИ КОРОБКИ ЛЕГКИЕ ВЕРТИКАЛЬНО-ГОРИЗОНТАЛЬНЫЕ (U + 253C) ┼

    • - всегда заменяется на U + 2500

    • | всегда заменяется на U + 2502
    • + заменяется символом Unicode, который зависит от 4 символов к северу, югу, востоку и западу от него (если они существуют)
    • <и> обрабатываются как вертикальные сегменты стены, если к северу или югу от + (чтобы у вас могли быть стрелки, оканчивающиеся вертикальными стенками прямоугольника)
    • v и ^ рассматриваются как горизонтальные сегменты стены, если к востоку или западу от + (чтобы у вас могли быть стрелки, оканчивающиеся на горизонтальных стенках прямоугольника)
    • + рассматривается как сегмент стены, если к северу, югу, востоку или западу от + (так что линии могут соединяться рядом с углом коробки)

Testcases

+-+     +---+   +---+   |
| +--   |ABC|  -+   |  +++
+-+     ++--+   +---+  +-+
         |
         +--->
  |           +--+
+-v+   +---+  |  |  +-----+
|Hi|  ->   |  +^-+  |world<-----+
+--+   +---+   |    +-----+     |
               |                +--
   |
---+---
   |

становится

╭─╮     ╭───╮   ╭───╮   │
│ ├──   │ABC│  ─┤   │  ╭┴╮
╰─╯     ╰┬──╯   ╰───╯  ╰─╯
         │
         ╰───>
  │           ╭──╮
╭─v╮   ╭───╮  │  │  ╭─────╮
│Hi│  ─>   │  ╰^─╯  │world<─────╮
╰──╯   ╰───╯   │    ╰─────╯     │
               │                ╰──
   │
───┼───
   │

Самый короткий код выигрывает!

Алекс Зефферт
источник
1
Где находится «пересечение», т. Е. Везде ли +вокруг него линии?
Утренняя монахиня
1
Вы, вероятно, имеете в виду Unicode, а не UTF-8
Луис Мендо
1
Можем ли мы иметь несколько тестов? Особенно для краевых случаев, например, когда два бокса касаются края или угла (или уточнения, что этого никогда не произойдет).
трихоплакс
2
Было бы неплохо опубликовать необходимые результаты для этих тестов.
manatwork
2
Тьфу, я только сочинял ответ :-(
Нейл

Ответы:

2

JavaScript (ES6), 236 байт

s=>`
${s}
`.split`
`.map((l,i,a)=>l.replace(/[+-|]/g,(c,j)=>c>`-`?`│`:c>`+`?`─`:`┼┬├╭┤╮??┴?╰?╯`[g(a[i-1][j])+g(l[j-1],1)*2+g(l[j+1],1)*4+g(a[i+1][j])*8]),g=(c,f)=>(f?`+-^v`:`+<>|`).indexOf(c)<0).slice(1,-1).join`
`
Нил
источник