Render an ASCII maze

APL (Dyalog Unicode), 57 35 bytesSBCS

–22 thanks to a novel solution by ngn.

Anonymous tacit function taking a character matrix as argument.

{⊃'+-|+'↓⍨2⊥5 4 2⊃¨⊂⍱∘⌽⍨' '≠,⍵}⌺3 3

Try it online!

{}⌺3 3 on each 3-by-3 neighbourhood, apply the following function:

,⍵ ravel (flatten)

' '≠ Boolean where non-space

⍱∘⌽⍨ that NOR it's reverse (incl. neither top NOR bottom, neither left NOR right)

5 4 2⊃¨⊂ pick 5th, 4th, and 2nd element from that entire list
  i.e. empty self, no vertical, no horizontal

2⊥ evaluate in base-2 (binary)
  i.e. ≥4:empty self; 3:no neighbours; 2:no horizontal neighbours; 1:no vertical; 0: has both

'+-|+'↓⍨ drop that many elements from this string
  i.e. empty self:; alone:+; vertical neighbour(s) only:|+; horizontal:-|+; both:+-|+

 pick the first element (pad with space if non are available)
  i.e. empty self: ; alone:+; vertical neighbour(s) only:|; horizontal:-; both:+


Old solution

Anonymous tacit function taking a character matrix as argument.

{' +-|+'⊃⍨1⍳⍨(' '=5⊃,⍵),(∧/,⊢)∨/2 2⍴1⌽' '≠(9⍴0 1)/,⍵}⌺3 3

Try it online!

{}⌺3 3 on each 3-by-3 neighbourhood, apply the following function:

,⍵ ravel (flatten)

()/ filter using the following mask:

  9⍴0 1 cyclically reshape [0,1] to length 9 (selects N, W, E, S)

' '≠ Boolean where non-space

1⌽ rotate one step left; [W,E,S,N]

2 2⍴ reshape to 2-by-2 matrix; [[W,E],[S,N]]

∨/ row-wise OR reduction: [horizontal,vertical]

() apply the following tacit function:

   the identity; [horizontal,vertical]

  ∧/, preceded by its AND reduction; [both,horizontal,vertical]

(), prepend the following:

  ,⍵ ravel (flatten) the neighbourhood

  5⊃ pick the 5th element (itself)

  ' '= Boolean if space (i.e. empty)

 Now we have [empty,both,horizontal,vertical]

1⍳⍨ index of leftmost 1 (gives 5 if no neighbours at all)

' +-|+'⊃⍨ use that to pick symbol

   


Python 2, 181 168 bytes

thanks to Leaky Nun for -13 bytes

m=input()
f=lambda x,y:(['']+m+[''])[y+1][x:x+1]>' '
print[[(c<'!')*' 'or'+-|+'[f(x+1,y)|f(x-1,y)|2*f(x,y+1)|2*f(x,y-1)]for x,c in enumerate(r)]for y,r in enumerate(m)]

Try it online!


JavaScript (ES6), 110 bytes

I/O format: array of strings.

a=>a.map((s,y)=>s.replace(/\S/g,(_,x)=>'+|-+'[[-1,p=0,1,2].map(c=>p|=(a[y+c%2]||0)[x+~-c%2]>' '?c&1||2:0)|p]))

Try it online!

Or 108 bytes by using a matrix of characters instead.