BASH , 580 349 308 303 291 286 283 bytes
Found this very entertaining, thanks! First variant was 580 bytes, then 349, ..., now 283:
s=$1 n=$2 N=$[n+n-1];f(){ b=$1;for((j=1;j<n;j++));{((c<N)) && T+=%s;[[ $4 ]]&&h=$4 S[$[i+$2/2]]=-;t=${s:c:1} S[i]=${t:-$b} b=$3;((i+=$2,c++));S[$[i-($2/N)]]=\ ;};};while((n>0));do f . 2 - \>;((n-=a));f . $N \|;f \' -2 - \<;((n--));f \' -$N \|;a=1;done;S[i]=$h;printf "$T\n" "${S[@]}"
Squeezed to 283:
#!/bin/bash
s=$1 n=$2 N=$[n+n-1]
f(){
b=$1
for ((j=1; j<n; j++)); {
((c<N)) && T+="%s"
[[ $4 ]] && h=$4 S[$[i+$2/2]]=-
t=${s:c:1} S[i]=${t:-$b} b=$3
((i+=$2,c++))
S[$[i-($2/N)]]=' '
}
}
while ((n>0)); do
f . 2 - \>; ((n-=a))
f . $N \|
f \' -2 - \<; ((n--))
f \' -$N \| ; a=1
done; S[i]=$h; printf "$T\n" "${S[@]}"
Reduced to 349 bytes:
s=$1 n=$2 N=$[n+n-1]; for ((p=0; p<n*N; p++)); { S[p]=" "; }; printf -v T "%${N}s"; T=${T// /%s}; f(){ b=$1; for ((j=1; j<n; j++)); { [[ $4 ]] && h=$4 S[$[i+$2/2]]=-; t=${s:c:1} S[i]=${t:-$b} b=$3; ((i+=$2,c++)); }; }; while ((n>0)); do f . 2 - \>; ((n-=a)); f . $N \|; f \' -2 - \<; ((n--)); f \' -$N \|; a=1; done; S[i]=$h; printf "$T\n" "${S[@]}"
And ungolfed for better readability:
#!/bin/bash
s=$1 n=$2 N=$[n+n-1]
for ((p=0; p<n*N; p++)); { S[p]=" "; }
printf -v T "%${N}s"; T=${T// /%s}
f(){
b=$1
for ((j=1; j<n; j++)); {
[[ $4 ]] && h=$4 S[$[i+$2/2]]=-
t=${s:c:1} S[i]=${t:-$b} b=$3
((i+=$2,c++))
}
}
while ((n>0)); do
f . 2 - \>; ((n-=a))
f . $N \|
f \' -2 - \<; ((n--))
f \' -$N \| ; a=1
done; S[i]=$h; printf "$T\n" "${S[@]}"
First variant was:
#!/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[@]}"