Husk, 44 43 41 bytes
|s0J'-x"+-"J'+f¹zμ+↓s²_&ε²¹↑□¹+"x^"s)¹m←ṡ This feels a bit clunky; Husk is not optimized for string manipulation. I'll try to golf it down. I borrowed some ideas from the Stax answer.
|s0J'-x"+-"J'+f¹zμ+↓s²_&ε²¹↑□¹+"x^"s)¹m←ṡ This feels a bit clunky; Husk is not optimized for string manipulation. I'll try to golf it down. I borrowed some ideas from the Stax answer.