JSFiddle - React, Tailwind, and code Playground
HTML
Paste text here, then focus out<br>
<textarea id='rows' onchange='Go(this.value)'></textarea><br>
Trees: <input readonly id='trees'>
<div style='overflow:auto'>
<canvas id='canvas'></canvas>
</div>
JavaScript
Go=rows=>{
var Display=(c,v)=>(
dx+=18,
ctx.beginPath(),
v&1&&ctx.moveTo(dx+3,dy+4)+ctx.lineTo(dx+9,dy+9),
v&2&&ctx.moveTo(dx-3,dy+4)+ctx.lineTo(dx-9,dy+9),
v&4&&ctx.moveTo(dx-3,dy-4)+ctx.lineTo(dx-9,dy-9),
v&8&&ctx.moveTo(dx+3,dy-4)+ctx.lineTo(dx+9,dy-9),
ctx.stroke(),
ctx.fillText(c,dx,dy)
)
var SetupDisplay=t=>(
canvas.width = 18*80,
canvas.height = 10+18*t.length,
ctx = canvas.getContext("2d"),
ctx.lineWidth = 1,
ctx.textAlign = 'center',
ctx.textBaseline = 'middle',
ctx.font = '15px Lucida Console',
ctx.strokeStyle ='#77f',
ctx.fillStyle = '#07f'
)
var dx=0, dy=0, t, m, p=[], b={}, nt, tt;
t=rows.split('\n');
SetupDisplay(t);
nt=tt=0;
var Join=(x,y)=>b[x]!=b[y] && (--tt, [...b[x],...b[y]].map((k,i,s)=>b[k]=s) )
m=t.map(l=>(
dx=0, dy+=18,
p=[...l].map(
(c,i)=>(
n=c<'A'?0:'0x'+'30909a8ff6f53a0213accccfc5'[c.charCodeAt()-65],
Display(c,n),
o=p[i-1]||[], q=p[i+1]||[], x=o[1], y=q[1],
k=(1&(n>>2)&o[0])|(2&(n>>2)&q[0]),
[n, k > 2 ? (Join(x,y),x) : k > 1 ? y : k > 0 ? x : n ? (++tt, b[++nt]=[nt], nt) : 0]
)
)
));
trees.value=tt;
// console.log(m);
// console.log(JSON.stringify(r));
}