Found this very entertaining, thanks! Here is "short" bash variant:
s=$1 n=$2 l=${#s} N=$((n+n-1)); for ((p=0; p<n*N; p++)); { S[p]=" "; }; printf -v T "%${N}s"; T=${T// /%s}; while ((n>0)); do b='.'; for ((j=1; j<n; j++)); { t=${s:c:1} S[i]=${t:-$b} S[$((i+1))]="-" b='-' h='>'; ((i+=2)); ((c++)); }; ((n-=a)); b='.'; for ((j=1; j<n; j++)); { t=${s:c:1} S[i]=${t:-$b} b='|'; ((i+=N)); ((c++)); }; b="'"; for ((j=1; j<n; j++)); { t=${s:c:1} S[i]=${t:-$b} S[$((i-1))]="-" h='<' b='-'; ((i-=2)); ((c++)); }; ((n--)); b="'"; for ((j=1; j<n; j++)); { t=${s:c:1} S[i]=${t:-$b} b='|'; ((i-=N)); ((c++)); }; a=1; done; S[i]=$h; printf "$T\n" "${S[@]}"
And ungolfed for better readability:
#!/bin/bash
s=$1
n=$2
l=${#s}
N=$((n+n-1)) # items per row
# Check if n is in range
(( (n*n)>=(l+1) )) || { echo "n must be 'n^2≥l+1'"; exit 1; }
# Fill the 'area' with spaces
for ((i=0; i<n*N; i++)); { snake[$i]=" "; }
# Create printing template
printf -v row "%${N}s"
row=${row// /%s}
# Setcounters
i=0
c=0
a=0
forward(){
b='.'
for ((j=1; j<n; j++)); do
cut=${s:c:1}
snake[$i]=${cut:-$b}
snake[$((i+1))]="-"
b='-'
h='>'
((i+=2))
((c++))
done
((n-=a))
}
down(){
b='.'
for ((j=1; j<n; j++)); do
cut=${s:c:1}
snake[$i]=${cut:-$b}
b='|'
((i+=N))
((c++))
done
}
back(){
b="'"
for ((j=1; j<n; j++)); do
cut=${s:c:1}
snake[$i]=${cut:-$b}
snake[$((i-1))]="-"
h='<'
b='-'
((i-=2))
((c++))
done
((n--))
}
up(){
b="'"
for ((j=1; j<n; j++)); do
cut=${s:c:1}
snake[$i]=${cut:-$b}
b='|'
((i-=N))
((c++))
done
a=1
}
print(){
printf "$row\n" "${snake[@]}"
# echo $i,$c,$n
}
# Create snake
while ((n>0)); do
forward
down
back
up
done
snake[$i]=$h; printf "$row\n" "${snake[@]}"