m`^ *
$&├──
{4}
|
T+`|├` └`(?<=(.)*).(?!.+¶(?>(?<-1>.)*)[|├└])
^
.¶
Try it online!
I suppose I could technically count this as one byte per character by swapping out some characters, reading the source as ISO 8859-1 and then finding a single-byte encoding for the output which contains ├
and └
, but I can't be bothered to work out the details right now. (For the record, that would be 72 bytes.)
Explanation
Stage 1: Substitution
m`^ *
$&├──
We start by matching the indentation on each line and inserting ├──
.
Stage 2: Substitution
{4}
|
Next, we match every group of 4 spaces and replace the first with a |
. Now all that needs fixing is |
that go to the bottom of the output and ├
that should be └
. Both of those cases can be recognised by looking at the character directly below the one we potentially want to change.
Stage 3: Transliteration
T+`|├` └`(?<=(.)*).(?!.+¶(?>(?<-1>.)*)[|├└])
The (?<=(.)*)
counts how many characters precede the match on the current line to measure it's horizontal position. Then the lookahead skips to the next line with .+¶
, matches as many characters as we've captured in group 1
with (?>(?<-1>.)*)
(to advance to the same horizontal position) and then checks whether the next character (i.e. the one below the actual match) is one of |├└
. If that's the case, the match fails, and in all other cases it succeeds and the stage substitutes spaces for |
and └
for ├
.
This won't fix all characters in a single run, so we apply this stage repeatedly with the +
option until the output stops changing.
Stage 4: Substitution
^
.¶
All that's left is the first line, so we simply match the beginning of the string and prepend a .
and a linefeed.