[Question]
  [
This [ascii-art](/questions/tagged/ascii-art "show questions tagged 'ascii-art'") challenge is about walking around a string like a snake.
```
s-n-a-k
.---. e
d <-' a
n-u-o-r
```
You will be given a string \$ S \$ of length \$ l \$ and a positive integer \$ n \$ where \$ n ^ 2 \ge l + 1 \$.
The string rotates 90¬∞ after writing \$ n \$ characters of \$ S \$, or when it hits itself. When \$ S \$ is being written horizontally, characters are delimited by hyphens `-`. When it is being written vertically, there is no delimiter.
Once all characters of \$ S \$ have been exhausted, continue to fill the snake with hyphens and pipes `|`, with periods `.` at corners at the top of the spiral and single-quotes `'` at corners by the bottom of the spiral.
The final character of the spiral will be either `<` or `>`, depending on the direction the spiral is facing when it finishes.
When the snake has been constructed, output it in any reasonable way. The output may contain any whitespace that does not affect the snake's appearance, e.g. a fixed amount of leading whitespace on each line.
You can assume \$ S \$ will only contain mixed-case letters of the English alphabet. It will never be an empty string, but always have at least 1 character.
Here are some examples to test your program against:
```
S = snakearound
n = 4:
s-n-a-k
.---. e
d <-' a
n-u-o-r
n = 5:
s-n-a-k-e
.-----. a
| .-> | r
| '---' o
'---d-n-u
n = 6:
s-n-a-k-e-a
.-------. r
| .---. | o
| | <-' | u
| '-----' n
'---------d
n = 7:
s-n-a-k-e-a-r
.---------. o
| .-----. | u
| | .-> | | n
| | '---' | d
| '-------' |
'-----------'
==============
S = noodleman
n = 4:
n-o-o-d
.---. l
| <-' e
'-n-a-m
n = 6:
n-o-o-d-l-e
.-------. m
| .---. | a
| | <-' | n
| '-----' |
'---------'
==============
S = TheQuickBrownFoxJumps
n = 5:
T-h-e-Q-u
x-J-u-m i
o .-> p c
F '---s k
n-w-o-r-B
=============
S = pleaseno
N = 3:
p-l-e
o‚Äî> a
n-e-s
```
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest code per language, measured in bytes, wins.
  
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), ~~337~~ ~~331~~ ~~315~~ ~~290~~ ~~279~~ ~~231~~ ~~224~~ ~~211~~ 213 bytes
```
{(x,w)#@[(x*w)#" ";i,*|i;:;@["|-"{1|1=x|-x}@-':i:0,+\(,/-:\1,w:-1+2*x)4!2_&s;(-2_-2+\s;!#y);:;(".''."4!!-2+#s:,/+|1(2*1+)\|!x; y:,/((#l)#("-";"")){x/y}',''l:(0,((#y)>)#+\(0,(-1+#l)#-1 1)+l:1_|1+&x#2)_y)],"<>"2!x]}
```
[Try it online!](https://ngn.codeberg.page/k#eJw9jVFrwjAUhd/9Fe0NmNwmUROqg2QT2cMe9jbYW1s6mZYVazssxRTT/75sA58u55yP+1Xmxpy4ItllzCXhQgS2FomvrbG7DLyEm/LqyXnppp2kpjYrwXMmltLkSlyNVFwnDtNYl/PeMqlLqXne25iMGF4wWFC6gDSOQ016I5bcK6YTxTH3sbPRGCrGSIOEgQQLgHhzy3GigtLGsJUI44hbJEEaQtD9slJFCnljVOkVnzuisRyxEPC4BR27YprNPlaGBhlLiQCwVWahb/en4/7SDe0BCppG62gTPaC9k/pOtl13aI7nffvHbf4ZFlYUVba28P51fBvqz9Pzpbu2L517Hc7fPRSzHycXU3s=)
-6 : Save a few bytes with shorter names.  
-16 : Tidying up  
-25 : Cruft  
-46 : Golfing gets me back under limits  
-7 : Cleaner  
-13 : A single statement!  
+2 : handle empty string
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 78 bytes
```
ju&K>*hhHH+z>s.i_Psm*Rd"-|"Qs@L_B".'"tQlz.e++b?%klGd\-@K+Hk+j\-<KH__MGStQ]@"<>
```
[Try it online!](https://tio.run/##K6gsyfj/P6tUzdtOKyPDw0O7yq5YLzM@oDhXKyhFSbdGKbDYwSfeSUlPXakkMKdKL1VbO8leNTvHPSVG18Fb2yNbOytG18bbIz7e1z24JDDWQcnG7v9/U67ivMTs1MSi/NK8FAA "Pyth ‚Äì Try It Online")
[Answer]
# [Python 3](https://docs.python.org/3/), ~~371~~ ~~274~~ 255 and 253 bytes
```
def f(s,n):
 for y in(a:=range(n)):
  for x in a:r=min(x,y,n+~x,n+~y);i=4*r*(n-r)-2*r+x+y+2*(2*(n+~r)-x-y)*(y>x);H=max(n+~y,y)>x>min(y-2,n-y-2);b=x+1>n/2;print(s[i:]and s[i]or"|-..''><"[H+2*((n+2*~x)*b-~x==y)+4*((n+~x-x)*b+x==n+~y)],end=" -"[H])
  print()
```
[Try it online!](https://tio.run/##XZDBa8MgGMXv/SskPaiJdizNRpfMHHYYZbfBbiUHu9g1tPkMpmUKI/96pilldCAf8n7Pp8/OnfYalqvOjGOtdmhHegY0n6GdNsihBojMhZHwpQjQoE/AeoBkbkTrDZY5Bslgw3C0aEQWm5gAN5SnsUls4pI0Jn557jXLHY2JKy0t1qKVNsiOOVraMqQ5njLgftJiK2xyX8JdWnSmgRPpN01eSaiR31TaRD98scC4fI4263CDD0rjwdJ4ywcrhKNJNomD5UFMvDa9sGIKahEh7s9V1De6pNNxPnVrQrdL4yVDT77z3JcmUcQaOpv9c2QMrabfIrgHeVDS6DPUOFivsf4MwaB1fVStBMwyOruSW/D4BwL52Kv3c/N5eDH6G161fTu3XY/Zw62rOyrZK9CYLen4Cw "Python 3 ‚Äì Try It Online")
Minus 64 bytes thanks to @noodleman and another 11 bytes thanks to @Kevin Cruijssen! I then saved another 22 bytes. Most recent improvement of 6 bytes by @xnor and 13 bytes by me.
Instead of most other solutions (as far as I can tell), I tried calculating the index into the string. I dug up a post on [StackOverflow](https://stackoverflow.com/a/18786566/11298075) that helped with this, though a lot was just throwing random equations and seeing what they do. Maybe the indexing equation can be simplified with a bit more thought, but it's surprisingly short already.
There are lots of places where `-x-1` is replaced with `+~x` (or variants). Booleans are heavily used for indexing and cancelling parts of equations with multiplication.
Ungolfed:
```
def function(string: str, number: int):
  for y in range(number):
    for x in range(number):
      rounds = min(x, y, number - x - 1, number - y - 1)
        # total increments after `rounds` revolutions and fix for overcounting
      index = 4 * rounds * (number - rounds) - 2 * rounds
      index += x + y  # east + south increment
      index += 2 * (2 * (number - rounds - 1) - x - y) * (y > x)  # west + north
      # See below for explanation
      is_horizontal = max(number - y - 1, y) > x > min(y - 2, number - y - 2)
      is_right = x + 1 > number / 2
      # Both inlined
      is_up_corner = x + 1 + is_right * (number - 2 * (x + 1)) == y
      is_down_corner = x + is_right * (number - 1 - 2 * x) == number - y - 1
      # is_middle = x + 1 - number % 2 == y == number // 2
      # is_middle = is_up_corner and is_down_corner
      # is_down = y > number / 2
      # is_left_corner = y + is_down * (number - 2 * y) == x + 1
      # is_right_corner = y + is_down * (number - 1 - 2 * y) != number - x - 1
      print(
        # string[index] if index < len(string) else
        string[index:] and string[index] or \
        # See below for explanation
        "|-..''><"[is_horizontal + 2 * is_up_corner + 4 * is_down_corner],
        end=" -"[is_horizontal]
      )
    print()
```
Explanation of `is_horizontal` boolean:
There are effectively four quadrants in which we need to determine whether the coordinate is a horizontal part in the snake, we can do this for the upper right corner with `number - y - 1 > x`. On its own this is not enough, because the lower part of the snake is now messed up. Taking `y > x` works for the lower right quadrant, but messes up the snake above. Combining these two equations into `max(number - y - 1, y) > x` leaves only the left part of the snake to fix. Creating conditions for the other corners you can combine `x > min(y - 2, number - y - 2)` into one large expression.
```
------------.                 ------------.                 ------------.
.---------. |                 .---------. |                 .---------. |
--.-----. | |                 --.-----. | |                 | .-----. | |
----.-> | | |     becomes     ----.-> | | |     becomes     | | .-> | | |
----' | ' | |                 ----'---' | |                 | | '---' | |
--' | | | ' |                 --'-------' |                 | '-------' |
' | | | | | '                 '-----------'                 '-----------'
```
Explanation of special character indexing into `|-..''><`:
There are six special characters that we need to index into, which can be separated into three categories: Straight, corner and tail. By virtue of the equations, we can determine we need a tail if something is both an up- and down-corner. Obviously, if it is not a corner or tail, it should be a straight piece. Using the equation `is_up_corner + 2 * is_down_corner` we can differentiate the four cases straight, up-corner, down-corner, and tail. To select the correct straight and tail pieces we still need a more granular distinction. Using `is_horizontal` obviously works for straight pieces and additionally it works for the tail, because the left-pointing arrow has an appendage whereas the right-pointing does not. This can be combined with the previous equation by doubling the corners.
## 253 bytes solution
This solution outputs not a string, but a nested array/matrix of characters. This might be allowed according to the meta post: [Strings and arrays of characters are interchangeable](https://codegolf.meta.stackexchange.com/a/25275/58563).
It's effectively the same as the above, but also returns instead of prints. It unfortunately requires `*''.join()` in the inner loop, because you cannot populate an array with two items per iteration. (And by doubling the iterations I only managed to golf to 255.)
```
lambda s,n:[[*''.join((r:=min(x,y,n+~x,n+~y),i:=4*r*(n-r)-2*r+x+y+2*(2*(n+~r)-x-y)*(y>x),H:=max(n+~y,y)>x>min(y-2,n-y-2),b:=x+1>n/2,s[i:]and s[i]or"|-..''><"[H+2*((n+2*~x)*b-~x==y)+4*((n+~x-x)*b+x==n+~y)])[4]+" -"[H]for x in range(n))]for y in range(n)]
```
[Try it online!](https://tio.run/##ZZBBS8MwFMfv@xShOyQvTSZ2VWaxPXgQ8SZ464pkttPq@lLSDROQfvWZdnOKQnhJfvzyf@G1bvuqcb5ozX6dLvcb1axKRTqBSZ5zSmdvukbGTJI2frfCCQx7OxQHok7SmBvOUBqQETehDV0YceaXFzyz0gFnLrMg7nyCsgN3wkFmsyHPyUig9BXEKklteJ7hWSS6vE4KhSXxh0Kb4FPOZpRm10F@N6T7jIj3FvhK9jZNHYTxCHsrBxh6Nn6vgDwuwoBI/65Ya0MsqZEYhS8VQ4ARud@o2JfVmpT6ac24Mi8dJBOid9v0@zohralxy@gSj3NpVMuOMxLeBDg5MJlMydCh/ukwF@TKZ07JoUcQiNprf6RYkMXQeFRoh@q9UkbvsKSjfcCodbmpGoVUxPCfXZ7Ex9fqYVc/v98Y/YG32t7vmraj4uIktJtKdRVqKuaw/wI)
[Answer]
# [Python 3.8](https://docs.python.org/3.8/), ~~254~~ 247 bytes
```
lambda n,s:(r:=range,G:=["<>"[n%2]],[(K:=(s+''.join((2*[(n+~h//4)*"-",(n-2-h//4)*"|"],".''.")[h%2][h//2%4]for h in r(4*n))[len(s):])[~(f+1)**2:],G:=['-'.join(K[:f+1])]+[G[~g][::-1]+"- "[f-g>1]+K[f-~g]for g in r(f)])for f in r(1,n)])and'\n'.join(G)
```
[Try it online!](https://tio.run/##LY1NboMwEIWvYlmKmAE7EZRIlVWyZcERJl64AgNtOiCTLipVXJ06Dbv3M/O9@ec@TPzyOofNV9ft5r7eWydYLQaCqYLjvlO1qUi@XSTxobBWETSmgiVLkuPHNDJAkRJwtg6nU4mp1FIB60Lv9ldaJY/xViIN8Z9iXhxK66cgBjGyCFCmjEi3jmFBY5FW8FmOaVoY@7@d6H2pIRMbizajmtbekjE6t5nUQpLX/SXqJorYPOj9k@7R4sP6p80Vx8Bxm1x5x9a4zWHkO3g4KyEXdp@dC9M3txJx@wM "Python 3.8 (pre-release) ‚Äì Try It Online")
Essentially a port of my [Pyth answer](https://codegolf.stackexchange.com/a/263673/73054).
I'll hand wave a bit of an explanation. We start by assigning `G` to the center of the spiral, `n` being even or odd determines if the arrow points left or right. Next we construct the string for the spiral as if `s` was an empty string, then replace the beginning of that string with `s`. We then build the rest of the square, each iteration we flip `G` 180 degrees and add to the top and the right side. After `n-1` iterations of this, we return `G` joined on newlines.
[Answer]
# [Python 3.8 (pre-release)](https://docs.python.org/3.8/), ~~239~~ ~~209~~ ~~205~~ ~~204~~ ~~199~~ ~~197~~ 196 bytes
```
def f(s,n):
 i=n%-2;g="--.\n<-'>"[i:7-i]
 while(i:=i+2)<n:m="--"*i;g=m+f"--.\n.-%s |\n'{m}-'"%g.replace("\n"," |\n| ")
 z=d=0;*a,=g
 for c in s:d+=a[z]in".'";a[z]=c;z+=2*(1,n,-1,-n)[d%4]
 return a
```
[Try it online!](https://tio.run/##dY89T8MwFEX3/ArLVWSnsSP6AZSkZmBgYENiaztYiZOaJs@R06hQym8PNggJUdiedM@5erd93W8NzBatHYZClaikHYMoDZAWEPJpVgnMebKGJSe3eKXTa643ATpsda2oToWOp9ES0sZTeKwd3sTll5HwsEOnNZC35p0THFaJVW0tc0XxGjDDPjshHAXoKApxkY0lE1WASmNRjjSgLi1iIVfHjQacEJz5U@TZMRbTMZ0wYHzCOESrIpy7j6za9xaQHEafDdo3WAmVojOGbtygEXLbMGY6CoJfxJyhhZ/cWg17xyTPRgMtKelA7pS0poeCODGKvpmfHV6/@lMHY4paNRLO5DP0aasee53v7qw5wL15eeibtiPs0mv/W22tZKfAEDZz4PAB "Python 3.8 (pre-release) ‚Äì Try It Online")
I was able to simplify again by a significant amount. Now the output is a simple array of characters (this is better than before).
The recursive function `g` makes an empty snake, function `f` fills in the given string `s`.
* minus 30 bytes by simplification of function `g`
* minus 4 bytes by inlining the function `g` (now non-recursive)
* minus 1 byte thanks to c--
* minus another 5 bytes thanks to c-- !
* minus 2 bytes by using f-string and formatting
* minus 1 byte thanks to c--
## Here are my older versions:
### [Python 3.8 (pre-release)](https://docs.python.org/3.8/), ~~271~~ ~~269~~ ~~257~~ 254 bytes
This new version (built from the 275 bytes solution) stretches the output rules to the maximum, or even beyond? The output array contains iterables as elements, either strings or arrays of strings. By `"".join(e)` we always get a string out of element `e`.
* Minus 2 bytes, thanks to an idea of noodle man!
* Minus 12 bytes by myself, using new algorithm for spiral
* Minus 3 bytes by myself - small improvement
```
g=lambda n:[(m:="-"*(2*n-3))+"-."]+[".|- "[i>0::2]+g(n-2)[i]+" |"for i in range(n-2)]+[f"'{m}'"]if n>2else["--.",">","<-'"][n<2::2]
def f(s,n):
 z=d=0;a=g(n)
 for c in s:l=list(a[z//n]);d+=l[z%n*2]in".'";l[z%n*2]=c;a[z//n]=l;z+=(1,n,-1,-n)[d%4]
 return a
```
[Try it online!](https://tio.run/##jY@xTsMwFEX3fMWTEUrc2IGmBUFSd2BgYENiszKYxmlNnecoSQUU@PbiAB2oADF48H3vHF83z/3K4eSiaXe7pbCqvi8VYCajOhOEk1GUjpBPKI0JT0gRS5K8ciDSzE@zLC3iZYQ8pdIUMYFXUrkWDBiEVuFSf4w8UpHwpX4LSWEqwHmqbacl4V7HyNyfGfcjibN0EAalrqCKOoY0C2ArSnGaK@FfoQEM9sVg7zIrrOn6SMntyQkWNC9jYeX2GEdpYZAkIcn3V7HIv7aEzbexiMYMGR8zjlSWx9MigFb3mxZB7Y7goP@EwaWvcQS@ESHM0CA42JgyuBiKDrEd4ioKO1RrrVq3wTL0TAZNa7D3guTBGYws9V/5jL58exCdK62uFYZs@iO2p36Bzv@EvlF3K327MYv1Vese8do93WzqpgvZ2f8NjdWq0@hCNvkJ2r0D "Python 3.8 (pre-release) ‚Äì Try It Online")
### [Python 3.8 (pre-release)](https://docs.python.org/3.8/), ~~361~~ ... 275 bytes
* Minus 18 bytes, thanks to noodle man!
* Minus 18 bytes additionally by myself
* Minus 9 bytes by myself
* Minus 9 bytes by myself
* Minus 11 bytes by myself
* Minus 20 bytes by returning a 2 dimensional array, thanks to noodle man!
* Minus 1 byte by myself
```
g=lambda n:[(m:="-"*(2*n-3))+"-."]+[".|- "[i>0::2]+g(n-2)[i]+" |"for i in range(n-2)]+[f"'{m}'"]if n>2else["--.",">","<-'"][n<2::2]
def f(s,n):
 x,y,k,a=0,0,7,[list(s)for s in g(n)]
 for c in s:k=(7-5*(k>6),-5*(k>1),k)[".'".find(a[y][x])];a[y][x]=c;x+=k//3;y+=k%3-1
 return a
```
[Try it online!](https://tio.run/##jY8xT8MwEIX3/IqTKxS7sUubUFpS0oGBgQ2JzcpgGqeYJOcobkUr4LcXB8oAAsRg@e6dv3fP7X7zYDGZt93hsM5q1dwXCjCVtEkzIsiQxkMUCWMRESOSR5KMXgQQaZbjNI3zaE1RxEyaPCLwQkrbgQGD0Clc6/eRR0oSPjevIclNCbiMde20JMLbcbL051L4kcTLuDcMCl1CSR1Hlgaw43tecZWN@ZjPuKyN21DH@i2u3@KXszyAvl/1vUurjM7EdEir5TnjH8WE8Yr52CEZlQYLquQ@l7uc5Ytjla0WuyirTk@Txd7fJ4mYBNDpzbZDUIcBfPtUwuHCZxuAj0kINywIvr044zDv0/dy3cslDR2qSqvObrEIPZNC2xnceIPRozVIa8aCo3T0@wTR2qLWjcKQn/2IfVK/QOd/Ql@ouwd9uzWr6qqzT3htdzfbpnUhn/7foa21chptyJOfoMMb "Python 3.8 (pre-release) ‚Äì Try It Online")
Recursive, but not shortest, unfortunately.
Function `g` makes an empty snake, function `f` fills in the string.
[Answer]
# [BASH](https://www.gnu.org/software/bash/) , ~~580 349 308 303 291 286 283 277 275 272~~ 271 bytes
Found this very entertaining, thanks! First variant was 580 bytes, then 349, ..., now 271:
```
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[@]}"
```
[Try it online!](https://tio.run/##LZBNboMwEIWvMopcast1W5OumDjqCdgkO@wFvwIaDRUQdUE5O50k1WzG7/PzG0@RT@22TU5YICdiSJ3ISJOxARupFiiYYDOMUvbOYn8g7LVWChcpy0OqVBSdtXuaMMtAfEAIUdQ6bk5Zp0X8FgdncHZimZIysetNDnyaEyOK9fb2HgXf5OCXUuuAzI1kX6qC84Ar10/bXWop6fjOqdUADbxCDAb8ka1kXM6DsiRS8L/c@Wcwd3y4YxP@tQfP@Q/VQDU@Bmnxe@xobkCcvSfYieWUfYZ1t/FGKP@q83G4UtVcqZy7gdh36ageN2v/AA)
Squeezed to 271(with `2>/dev/null`):
```
#!/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[@]}"
```
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[@]}"
```
[Try it online!](https://tio.run/##vVTBjtowEL37K6bGu0mWTbPhUgnwqtJKPXLpsd1KjjEbL2ESxaGpBHxAP6Q/1h9JJ4aFtqirnrCU4BmPZ9570SNTLu@6wZsks5hkFDDmpEgZSjFihRSbgduxmRRhiEOM0yiCAdjGrBxUpoa6bBkbwENu9BLsAhCsA4tQK3wyLAwhxBuM7mVYDNMI6PJ2CxswOi@BI6zWroHMQIBfRj@//6CagE/AfLMNpBPY9Z0/2KKAJqcaVRsVQGubHFyltHFsUdYQhlbeTcBO8WZGP8NhFE1ogkO1NJ@EfZQc@KHVAzVoDFS1xcbiExCJqqAM85kFxF97OsCvxGa2c5xRQPTpnSSQXDnf46NpdLnGxtSO0WCm6VH0sB5Mq@p5GG0Y0Mpk8Dbwuz3KZ0mMnqdIrz3GeelP@6XXDQ1yYz1Od8fkiYHYUME4FtnZIZEnWSMiGfPjGU2Og2OUy@D@FPUX5CiKfkvoHo6P5yUatk9iLBVliTKbly1ehhR13/4FdfYa1B5dpvTyhI4H/AKSx2eSk8jT4B8foL/wf5LHB8XX1WUYnekdv653v1Ey9Ri9ZV5gHvzDBXnlM5LhCIcf/P5xx8k0tLzjhb0V@lag73D0oy9lbW4LA@MjpYOdDtNb3OtBX9tv1tWLalN5R/8q19d/eF7kE8io@7J3vsfuIXZd52tUTRae63Jl3H7bvfsF)
[Answer]
# JavaScript (ES12), 188 bytes
Expects `(string)(n)`. Returns a matrix of characters.
```
s=>n=>eval(`for(m=[k=x=y=0];~n;)for(d=-2;i=~n&&d++<2;n-=!n|d&!!y)for(;i++<(d&1?w=n*2-1:n||2);x-=d%2,y-=~-d%2)(m[y]||=[..."".padEnd(w)])[x]=d*x+1&1&&s[k++]||"|-..''< >"[i>2?d&1:d-3*~!n];m`)
```
[Attempt This Online!](https://ato.pxeger.com/run?1=TZBNTsMwEIX3PYUbicRuYoumtKC6TiUkWLBDYmcs1apTGpqMq4TSVIRehE2F4BZchFNwBdIfUFcz896nGb15-wBr4s37RHwunib04vurEBGIKH7WKR5NbI4zIWeiFCtxqvgaONlqRtCQJ2INrmt8fxByoKIJlXGbzdUO4EktY-O2h0sBrZC2-1BVIeElFeYkDFZUrGndEJzJlaoqIRljjsPm2lyBwUuiiCyVMK3Sb7tt1y3kzPdrzqkoY543QJEjkygc1gf6hnZa6yYono3IIcMPlw2EJHIK0LNY53YBxglq4SxA3QD1AnSOFFLBHgJrTRpnGv6Q3pF5N41vF8l4dpnbJVzb8maRzYsd2D2i5mmsixjszuhsjYZqsPoRV3o8xViiIkAaKYJEhPS_Dtvxpd4wtlDYNGapfcATXBAMhGV6jvMtkLNHmwD2PEIO3T14BPloV3njlRxibzb7-gs)
### Alternate formula
I've found the following alternate formula for special characters where each entry appears only once in the lookup string. But in the end, it's just as long as the simpler one.
```
".<'>|-"[i > 2 ? d & 1 | 4 : !n ^ d * 3 & 2]
```
### Commented
This is a version without `eval()` for readability.
```
// s = input string, n = size parameter
s => n => {
  for(
    // m[] is the output matrix
    // k is a pointer into s
    // (x, y) is the current position in the matrix
    m = [k = x = y = 0];
    // stop when n = -1
    ~n;
  )
    for( 
      // d is the direction
      d = -2;
      // stop when n = -1 or d = 2
      // i is the counter for the next loop
      i = ~n && d++ < 2;
      // decrement n if n = 0, or d is odd and y != 0
      n -= !n | d & !!y
    )
      for(
        ;
        // the width is 2n-1 if d is odd, or n if d is even
        // there's a special case for the last iteration
        i++ < (d & 1 ? w = n * 2 - 1 : n || 2);
        // (x, y) <- (x + dx, y + dy)
        x -= d % 2,
        y -= ~-d % 2
      )
        // if m[y] is undefined, initialize it to w spaces
        (m[y] ||= [..."".padEnd(w)])[x] =
          // if either d or x is even, attempt to get the next
          // character from s
          d * x + 1 & 1 && s[k++]
          // if falsy or undefined, use a special character:
          // - "|" or "-" for segments (i > 2)
          // - "." or "'" for corners (i = 2, n ‚â† 0)
          // - "<" or ">" for the final character (i = 2, n = 0)
          || "|-..''< >"[i > 2 ? d & 1 : d - 3 * ~!n];
  return m
}
```
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 61 bytes
```
Ôº¶‚ÆåÔº≥‚äûœÖŒπÔºÆŒ∑Ôº¶‚äñŒ∑¬´Ôº¶‚äñ‚ÅªŒ∑Œπ‚éáœÖ‚Å∫‚äüœÖ-¬≤‚Ü∑¬≤‚éáœÖ‚äüœÖ¬ß.'ŒπÔº¶‚Åª‚ÅªŒ∑Œπ¬≤‚éáœÖ‚äüœÖ¬π‚Ü∑¬≤‚éáœÖ‚äüœÖ¬ß'.Œπ¬π¬ª¬ß<>Œ∑
```
[Try it online!](https://tio.run/##nZDPisIwEMbP9ilCL05ABb14qAgLe/GgFHdfINuOJlgTmSZFWfbZs9NWVBAvXsL8@b7fN6TQigqnqhh3jgRssUGqEVb2FPyXJ2P3IKUUeag1hJEwMku63SYcf5BAc98ZP7EgPKL1WPJQit9k8DRfGxtq0C2lRTLcwzeSVXRp2XnF29ydIMiRSMcpvzPJ/EFuGue3Zq89zLr@yXk1ffiVLfEM6WSY9inZ9Yw@@uGAji1ekqZvBg8n9@BePeXyL@nrm2yxZBl/UxZjbdUBFblgy2Qex031Dw "Charcoal ‚Äì Try It Online") Link is to verbose version of code. Explanation:
```
Ôº¶‚ÆåÔº≥‚äûœÖŒπ
```
Get the reverse of the input into a stack, so that characters can be processed by popping from it.
```
ÔºÆŒ∑
```
Input `n`.
```
Ôº¶‚äñŒ∑¬´
```
Repeat `n-1` times. The loop counter is taken as an ascending number for the purposes of calculating which corner character to print, but for the side lengths I show how the actual number of repetitions of the inner loops vary.
```
Ôº¶‚äñ‚ÅªŒ∑Œπ
```
Repeat from `n-1` down to once...
```
‚éáœÖ‚Å∫‚äüœÖ-¬≤
```
... output the next character followed by a `-`, or two `-`s if none.
```
‚Ü∑¬≤
```
Start moving vertically.
```
‚éáœÖ‚äüœÖ¬ß.'Œπ
```
Output the next character or `.` or `'` appropriately if there are none left.
```
Ôº¶‚Åª‚ÅªŒ∑Œπ¬≤
```
Repeat from `n-2` down to zero...
```
‚éáœÖ‚äüœÖ¬π
```
... output the next character or `|` if there are none left.
```
‚Ü∑¬≤
```
Start moving horizontally, but in the other direction.
```
‚éáœÖ‚äüœÖ¬ß'.Œπ¬π
```
Output the next character or `'` or `.` appropriately if there are none left.
```
¬ª¬ß<>Œ∑
```
Output the head of the snake.
[Answer]
## Javascript, ~~384~~ ~~371~~ ~~304~~ ~~288~~ ~~263~~ 235 bytes
```
s=(S,n)=>(t=[...S],A=Array,a=A.from(A(n),r=>A(2*n).fill(e=' ')),x=y=0,p=(b,d,f)=>(a[y][x]=x&1&&t.shift()||b[d],f?.(d)),i=2*n-1,m=d=>(z=d&2,d&1?y+=1-z:x+=1-z,--i?p('-|-|',d,m):n<2?p('>><<',d):(i=d&1?2*--n:n-1,p("..''",++d%4,m))),m(0),a)
```
-13 bytes saved thanks to Samathingamajig  
-67 bytes by folding functions `u()` and `d()` into `v(¬±1)` and `l()` and `r()` into `h(¬±1)`  
-16 bytes with only one recursive function  
-25 bytes because of [this](https://codegolf.meta.stackexchange.com/questions/2447/default-for-code-golf-input-output-methods/25275#25275)  
-28 bytes with more golfing
### Try out
```
s=(S,n)=>(t=[...S],A=Array,a=A.from(A(n),r=>A(2*n).fill(e=' ')),x=y=0,p=(b,d,f)=>(a[y][x]=x&1&&t.shift()||b[d],f?.(d)),i=2*n-1,m=d=>(z=d&2,d&1?y+=1-z:x+=1-z,--i?p('-|-|',d,m):n<2?p('>><<',d):(i=d&1?2*--n:n-1,p("..''",++d%4,m))),m(0),a)
;[
  [ 'snake', 4 ],
  [ 'snakearound', 5 ],
  [ 'snakearoundandround', 6 ]
]
.forEach(([ S,n ]) => {
  console.log(s(S,n).map(r=>r.join('')).join('\n'))
})
```
## Ungolfed
```
s = (S,n) => {
  t = [...S];
  a = Array.from(Array(n), r => Array(2*n).fill(e=' '));
  x = y = 0;
  p = (b,d,f) => {            // set letter in all odd positions until
                              // exhausted, otherwise use snake
    a[y][x] = x&1 && t.shift() || b[d];
    f?.(d);                   // recurse unless end
  }
  i = 2*n-1;                  // counter for going in the same direction
  m = d => {
                              // the next position is set before p is called
    z = d&2;                  // forward or back?
    if (d&1) {                // vertical or horizontal?
      y+=1-z;
    } else {
      x+=1-z;
    }
    if (--i) {               // go on
      p('-|-|', d, m);
    } else if (n<2) {        // stop
      p('>><<', d);
    } else {                 // next direction
      i = d&1 ? 2*--n : n-1; // set going length, decrement n if horizontal
      p("..''", ++d%4, m);
    }
  }
  m(0);
  return a;
}
```
[Answer]
# Python3, 425 bytes
```
R=range
def f(n,s):
 r=[[' ']*2*n for x in R(n)];x=y=X=K=0;Y=C=1
 while 1:
  K+=1
  if s:r[x][y]=['-',s[0]][C%2or X!=0];s=s[C%2or X!=0:];C+=1
  else:r[x][y]='-|'[X!=0]
  if(y+Y==2*n-1or(0<=y+2*Y<2*n-1and' '!=r[x][y+2*Y])or Y<-y)and Y:
   if K==2:r[x][y]='<>'[Y>0];return r
   if r[x][y]in'-|':r[x][y]="'."[Y>0]
   X=Y;Y=0
  elif(x+X==n or' '!=r[x+X][y])and X:
   if r[x][y]in'-|':r[x][y]="'."[X<0]
   Y=-X;X=C=K=0
  x+=X;y+=Y
```
[Try it online!](https://tio.run/##nZHNbuIwFEbXk6dwK42cEIICzE9FclkM0iyG1aAubFleRINTPKXXkQ1qIs27Uzu0DItKbVnm5jufj32bbrcxOL1p7OGwAlvhnYrWqiZ1jEOXzCJiQQhKqBxMBkhqY0lLNJJVjIksWuiAwRLygsMCxhF53OitImOPkWUaBkTXxM2saKXoJAia0aETuZRi8Xniu9gV5LJw4M6@Z7JYHFm1derE0uwfFX2@b427lAN4p2xsbJyX0KWTAS/7QYVrb3wFRzTMZeLLeZl1if9HePALZkvf8P@Ack4Fn3sfq3Z7i8Q@p54DGoPCKX5NR9d9PKQYcP8Eee/s3dqUASAx9kUjZYHpD2ezt2tZeazlkLGC@add9t1tCqzoUuCHsAcd9lDHX4bUYXWvKmv2/t5@ZZ8aq3EXUzr6azTGOkmi4ySJzrivF3LfLuS@X8j5@6Ex6616qPBDlhdQ/k1uN@r3Xv@5/2HNI/407a/9Q@Pe3zAd0marKqfQvA4dngA)
[Answer]
# [Perl 5](https://www.perl.org/), ~~236~~ ~~224~~ ~~222~~ ~~214~~ 190 bytes
* minus 24 bytes, thanks to: good old time!
```
sub g{my$m="--"x($n=-2+pop);$m?"$m--.\n.-@{[g($n)=~s/\n/ |\n| /gr]} |\n'$m-'":$n?">":"--.\n<-'"}sub f{$a=g$p=pop;$z+=(1,$p,-1,-$p)[($#_+=(substr$a,2*$z,1,$_)=~/[.']/)%4]for$_[$z=0]=~/./g;$a}
```
[Try it online!](https://tio.run/##bc3BToNAEAbgu0@xWccAdhdsbTUprjUeevBm4g0IWS1gU5jdLCVWWnx1XDwoB2@Tf75/RmemXPR93byS4lh9QiUo5/TgAgo@m2ilvRCqFYWKcz9Gnz8co8IuPfFVBzEG5BTjiQSFSbphdKxz6BJwRe/pkv507mzSDffzI0hRgBb2agjtRLhTBprxKeOgvciF89RmVtZ7A5LNLqFlVqT2VxD5ThJ4F/MkVwbSCFpxldjYD4oQZNdrs8W9m7tOjXKXSaMa3DhDlREaY4zUI7ZI3Lnv33rh2S9HpTZlVkn8F7ObsX15z56b7dvu0agPXKvDU1Pp2mFk8dcbaV1mss5QWXA9Av03 "Perl 5 ‚Äì Try It Online")
I have derived this from my Python answer. Function `g` makes an empty snake, function `f` fills in the string.
Here is the same code with a little more spacing for better readability:
```
sub g{
  my$m="--"x($n=-2+pop);
  $m?"$m--.\n.-@{[ g($n)=~s/\n/ |\n| /gr ]} |\n'$m-'":$n?">":"--.\n<-'"
 }
sub f{
  $a=g$p=pop;
  $z+=(1,$p,-1,-$p)[($#_+=(substr$a,2*$z,1,$_)=~/[.']/)%4] for $_[$z=0]=~/./g;
  $a
}
```
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), ~~193~~ ~~192~~ ~~190~~ ~~188~~ ~~187~~ ~~182~~ 177 bytes
```
s=>n=>s.map(c=>a[d*=/[.']/.test(a[z-=d])?d*d<5?n:-1/n:1,z]=c,d=z=-2,a=[...g(n)])&&a
g=(n,m)=>--n?(m="--".repeat(--n))+`--.
${n?`.-${g(n).split`
`.join` |
| `} |
'`+m:"<"}-'`:">"
```
[Try it online!](https://tio.run/##jc47a8MwFIbh3b/CiBBLiaTQS1IwkQ0dOnQrdHMNEpacOrHPMZbTllx@uxt3a8nQ6cAHz8vZmg/ji65qewFo3VCqwasEVOJlY1paqMRkdqYWmYzyheyd76nJDkLZnKV2ZtfLFGJxs4D4hh9yVXCrDkrccqMyKeWGAsvZdGqCjaLAG6YSISCljSJCENm51pmeXibG5loIGUyOkGopJsdRSt/WVa8DLbdYgQ5PwSnU58uJ9LyJyZqcRaRjkpChxC6kVYhlmN3zJV/xh5yFBYLH2skaN7Sk4zuRB7NzpsM92ChntGI/ZUoIm5M3ICz4FVpdjwCirV1j4Hriinh9dy/7qtg9dvgJT/j1vG9aP@rlf3RbO@Md4Aju/oLhGw "JavaScript (Node.js) ‚Äì Try It Online")
Now even shorter than Arnauld's excellent answer!
* Minus 5 bytes thanks to noodle man!
* Minus 5 bytes by clever improvement thanks to Arnauld!
This answer has been derived from my Python solution.
Function `g` makes an empty snake and function `f` updates it with the chars from string `s`. The function has to be called by `f(s,n)` and returns a plain array of single char strings.
[Answer]
# [AWK](https://www.gnu.org/software/gawk/manual/gawk.html), 332 321 317 281 273 257 bytes
```
func R(C){r=++c<A*A?length($1)<c?i<A?C:S%2?"'":".":substr($1,c,1):S%2?"<":">";g[x,y]=S%2?G r:r G}func f(){for(x=c=S=i=0;i<A=$2;R(B="-",G=++i<A?B:""))y=i;while(S++<=A){for(i=S;i++<A;R("|",G=i<A?" ":B))x+=t=S%2*2-1;for(i=S;i++<A;R(B,G=i<A?B:""))y-=t}return G}
```
[Try it online!](https://tio.run/##XU7dboIwGL3nKZpGs1ZwUbe5BOgMmMxkyS4mu3NeMCxaxGIKRIzj2dkHuDnXq55zvvPjH7ZVFeYyQHMypSfFdD2wnZ4ziblcZxvSGVI7mAjbmUxNrzua4Bts4ltspvlnmimQjcAY0layQXrC1npRGMclq6kZUqZCs7IpCAk9hYkiBQuYxwQbWBDLOiNrTlyG@9iYQXnd5JoYU3pkwjpsRMyJp@s2c1qzYJ4lADvgwl@1p3ZghE2X0kJnWd3bG/WH1v9r93x7Tu@zrFQ8y5WEfdVJQ/D2SsgMdQYGxOGGefUzJQoG0xvYZg4sJGzYjSCats4fMarFqBEjENvEkOBuio31QhjRkv7eNxqBMQ1TXhbA/YcEuqxS6W@5r5JcrtC99hc9XKHxFXrUZJKsYr7zJbgu/7H2vuFvuQi2rkoO8jkpXvLdPoWsfcz9lMsE3X0D "AWK ‚Äì Try It Online")
* -11 bytes, replaced `condition ? var = val1 : var = val2` with `var = condition ? val1 : val2`
* -4 bytes, replaced `function` with `func`
* -36 bytes, thanks to [@ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat). Chained `=`, chained ternary operator and other optimization
* -8 bytes, thanks to [@ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat)
* -16 bytes, thanks to [@ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat). Passed ternary operator as second arg for `func R(C)` and moved incrementation of `c` in same function to allow more efficient one-liner loop.
---
## Ungolfed
```
function result(string2)
{
    rep = string2
    if ( i == $2-1 ) step % 2 ? rep = "'" : rep = "."
    if ( length($1) > cpt ) rep = substr($1, cpt+1, 1)
    if ( cpt == ($2 * $2)-1 ) step % 2 ? rep = "<" : rep = ">"
    return rep
}
function snakearound()
{
    x = 0
    y = 0
    cpt = 0
    step = 0
    for(i = 0; i < $2; i++)
    {
        grid[x, y] = result("-")
        if (i+1 < $2) grid[x, y] = grid[x, y] "-"
        cpt++
        y++
    }
    y--
    while(step <= $2)
    {
        step++
        step % 2 ? tmp = 1 : tmp = -1
        for(i = step; i < $2; i++)
        {
            x += tmp
            grid[x, y] = result("|")
            i == $2-1 ? string = "-" : string = " "
            step % 2 ? grid[x, y] = string grid[x, y] : grid[x, y] = grid[x, y] string
            cpt++
        }
        for(i = step; i < $2; i++)
        {
            y -= tmp
            grid[x, y] = result("-")
            i == $2-1 ? string = "" : string = "-"
            step % 2 ? grid[x, y] = string grid[x, y] : grid[x, y] = grid[x, y] string
            cpt++
        }
    }
    for(i = 0; i < $2; i++){
        for(j = 0; j < $2; j++) printf("%s", grid[i, j])
        printf("\n")
    }
}
```
```
[Answer]
# [Perl 5](https://www.perl.org/), 255 244 bytes
```
sub r{$a='';$a.=$/while s/.$/$a.=$&;''/emg;$_=$a}sub f{($s=pop.'-'x--($n=2*pop)**2)=~s/.\K/-/g;$k=local$_=($"x$n.$/)x$n;r while s@ +$|>(  )+@$_=substr$s,0,-1+length$&,'';s/^-/$k&2?"'":'.'/e;$k++&1&&y/-/|/;"$_>"@me;$n&2&&y/>/</||r&r;s/.\K.//g;r}
```
[Try it online!](https://tio.run/##LY5bS8NAEIXf/RVDGHZzHxvwguvWIuiDPojgo1hiTZvQdBN2U9vS1L8ep9WBYZjDfGdOW9j6Yhjc@hPsHnMtpcI81UibsqoLcJQinQShpKRitVA41ZgfjsB876PTbdOmMpHbJPHR6CzkPQjDLNA/DL8/U0LMLHXdzPKaWR@9LRp2DXgoC/9/JhBhP/YBgmjCV2zvOosuPo@TUVQXZtGVKGJO5@gjIVyK7M6T3o1MORTbR5EYCbHjZz0pD6djb7Ji3YjsqI7plvreCqtOkVLiSPYwtLYyHcwBpzHIt7J4XVez5b1tNuax2T6tV617@S7sA/euKyuzkGfAlZsv@CORYN5YuIzhKoZrNfwC "Perl 5 ‚Äì Try It Online")
Here's with newlines for better readability:
```
sub r{$a='';$a.=$/while s/.$/$a.=$&;''/emg;$_=$a}
sub f{
($s=pop.'-'x--($n=2*pop)**2)=~s/.\K/-/g;
$k=local$_=($"x$n.$/)x$n;
r while s@ +$|>(  )+@
$_=substr$s,0,-1+length$&,'';
s/^-/$k&2?"'":'.'/e;
$k++&1&&y/-/|/;
"$_>"
@me;
$n&2&&y/>/</||r&r;
s/.\K.//g;
r
}
```
I'm sure there are glaring opportunities to golf it further, but at least, for now, it's decently competitive with other answers, considering sigils. I was more interested to play with algorithm -- the square-ish string is actually rotated while being filled. Replace `r while...` with `print && r while...` to see intermediate steps.
P.S. It's funny to watch how snake's head moves and serves as anchor where to place the next fragment.
**Edit:** Just a little bit shorter. Rotation subroutine is also slightly less ugly and can now handle rectangular (not just square) shapes (but of course there ought to be Perl golfing pre-fab somewhere for the purpose, 20-odd years old, so I'm re-inventing the wheel), which fact was immediately used and lead to another couple bytes off.
In fact `local` can be ditched (-5) and TIO's footer written so that the `$_` doesn't hold read-only value while testing. And further couple bytes less if string is temporarily padded with arbitrarily large number of hyphens (`1E6`, say) instead of value computed from `n`. But I'm not that much desperate, yet :)
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 86 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
LR¬∑<‚Ç¨D¬¨≈°I√µ¬π¬∑n–∏¬´'-√Ω≈Ω9¬¶S.Œõ¬∂¬°Œπ–Ω¬ª¬∂¬´‚Äû -√Ç‚ÄöD√∞¬∂:¬´D'-'|::2√§Œµ‚Äû|-√Ç‚ÄöD'|‚Äû.'N√®::¬πN+√âiNi'''<.;√´¬®'>¬´]J
```
Inputs in the order \$n,S\$, where \$S\$ is a list of characters.  
Outputs with two trailing newlines. If this is not allowed, a trailing `¬®` or `?` could be added so it'll output a single trailing newline instead.
[Try it online](https://tio.run/##yy9OTMpM/f/fJ@jQdptHTWtcDq05utDz8NZDOw9tz7uw49Bqdd3De4/utTy0LFjv3OxD2w4tPLfzwt5Du4Gs1Y8a5inoHm561DDL5fCGQ9usDq12UddVr7GyMjq85NxWoGwNVFa9BsjRU/c7vMLK6tBOP@3DnZl@merq6jZ61odXH1qhbndodazX///mXNFKxUo6SnlAnAjE2UCcCmUXAXE@EJdC5VOUYgE) or [verify all test cases](https://tio.run/##ZY/PSgJRFMb38xSXS3AXjSP0l6bBIExIQikrAhO6Ohcc1HsHZwZbuBB3vUJBIEQYI9JGLWI25@JWfAZfZLqWm3J1zu/7zvk4p0y9alyhPkqhirCZITxadhiyLHSSz2j4lLuB75kIH@kazge@IgX67V3hCt5wfHYBE2vRHaRhMO3dyBEMYcLnHxCShIym0QG8FozZE4yhN/ucR/ClunDReUYJ2V10HtPyHcYmhGmSIG3T3JIvs5Fy2yuXtBUYJCf7pgnD3KZ8cHIOIcQyDmUIfZKCsJSNsXGta8tbtVbVqTPUZNRGDtdsoSGUFK6f/H1pVf59aaGNn1nO4uKOjj1Oa4w2RcBtXNKKu2vK3pqyv6aoHC6EXWcNylc7f1ilXlbZeeBUasdN0eIZcZ8NGq639LZ17NYZ9RgXCr8B).
**Explanation:**
*Step 1: Prepare the input character-list by joining by `-` and adding additional trailing `-`. Then use the (modifiable) Canvas builtin to put this string itself and all spaces at the correct positions in the output rectangle:*
```
LR¬∑<‚Ç¨D¬¨≈°         # Create the list of lengths for the Canvas builtin:
L                #  Push a list in the range [1, first (implicit) input-integer]
 R               #  Reverse it to range [n,1]
  ¬∑              #  Double each inner value
   <             #  Decrease each by 1
    ‚Ç¨D           #  Duplicate each value within the list
      ¬¨≈°         #  And prepend an additional copy of the first/largest item
I√µ¬π¬∑n–∏¬´'-√Ω      '# Create the string to draw for the Canvas builtin:
I                #  Push the second input-list of characters
  ¬π¬∑n            #  Push the first input, double it, take the square of that: 4n¬≤
 √µ   –∏           #  Create a list with that many empty strings ""
      ¬´          #  Append it to the input-list
       '-√Ω      '#  Join this list with "-" delimiter
≈Ω9¬¶S             # Create the list of directions for the Canvas builtin:
≈Ω9¬¶              #  Push compressed integer 2460
   S             #  Convert it to a list of digits: [2,4,6,0]
.Œõ               # Use the (modifiable) Canvas builtin with these three options
¬∂¬°Œπ–Ω¬ª            # Remove all (0-based) odd-indexed rows
¬∂¬°               # Split it on newlines
  Œπ              # Uninterleave it into two parts
   –Ω             # Pop and only leave the first part
    ¬ª            # Join it back together by newlines
```
[Try just step 1 online.](https://tio.run/##yy9OTMpM/f/fJ@jQdptHTWtcDq05utDz8NZDOw9tz7uw49Bqdd3De4/utTy0LFjv3OxD2w4tPLfzwt5Du///N@eKVipW0lHKA@JEIM4G4lQouwiI84G4FCqfohQLAA)
[For more information on how the Canvas builtin works, see this 05AB1E tip of mine.](https://codegolf.stackexchange.com/a/175520/52210)  
[See this 05AB1E tip of mine (section *How to compress large integers?*)](https://codegolf.stackexchange.com/a/166851/52210) to understand why `≈Ω9¬¶` is `2460`.
*Step 2: Replace all `-` that are currently at edge or corner positions with `|`:*
```
¬∂¬´               # Append a trailing newline
‚Äû -              # Push string " -"
   √Ç             # Bifurcate, short for Duplicate & Reverse copy: "- "
    ‚Äö            # Pair them together: [" -","- "]
     D           # Duplicate it
      √∞¬∂:        # Replace all spaces with newlines in the copy: ["\n-","-\n"]
         ¬´       # Merge the two together: [" -","- ","\n-","-\n"]
D                # Duplicate it
 '-'|:           # Replace all "-" with "|" in the copy: [" |","| ","\n|","|\n"]
:                # Replace all [" -","- ","\n-","-\n"] respectively with
                 # [" |","| ","\n|","|\n"]
```
[Try the first two steps online.](https://tio.run/##yy9OTMpM/f/fJ@jQdptHTWtcDq05utDz8NZDOw9tz7uw49Bqdd3De4/utTy0LFjv3OxD2w4tPLfzwt5Du4Gs1Y8a5inoHm561DDL5fCGQ9usDq12UddVr7Gy@v/fnCtaqVhJRykPiBOBOBuIU6HsIiDOB@JSqHyKUiwA)
*Step 3: Replace all `|` at corner positions with either `.` (for the top halve) or `'` (for the bottom halve):*
```
2√§               # Split the string into two equal-sized parts
  Œµ              # Map over both parts:
   ‚Äû|-           #  Push string "|-"
      √Ç‚Äö         #  Bifurcate and pair again: ["|-","-|"]
   D             #  Duplicate it
    '|     :    '#  Replace all "|" with the following in the copy:
      ‚Äû.'N√®     '#   The map-index'th character of string ".'"
   :             #  Replace all ["|-","-|"] respectively with
                 #  [".-","-."] for the first iteration of the map
                 #  or ["'-","-'"] for the second iteration of the map
```
[Try the first three steps online.](https://tio.run/##yy9OTMpM/f/fJ@jQdptHTWtcDq05utDz8NZDOw9tz7uw49Bqdd3De4/utTy0LFjv3OxD2w4tPLfzwt5Du4Gs1Y8a5inoHm561DDL5fCGQ9usDq12UddVr7GyMjq85NxWoGwNVFa9BsjRU/c7vMLK6n@s139zrmilYiUdpTwgTgTibCBOhbKLgDgfiEuh8ilKsQA)
*Step 4: And finally, fix the `>` or `<`*, and output the result:
```
    i            #   If
¬πN+              #   the first input + the (0-based) map-index
   √â             #   is odd:
     Ni          #    If it's the second iteration of the map:
       '' '<.;  '#     Replace the first "'" with "<"
      √´          #    Else (it's the first iteration of the map)
       ¬®         #     Remove the last character of the first part
        '>¬´     '#     And append a ">" instead
]                # Close both if-statements and the map
 J               # Join the two modified parts back together
                 # (after which the result is output implicitly with trailing newline)
```
[Answer]
# [Java (JDK)](http://jdk.java.net/), ~~279~~ ~~278~~ 276 bytes
```
char[]f(String s,int n){var a=g(n).toCharArray();int z=0,d=0;for(var c:s.toCharArray()){d+=a[z]/2&1;a[z]=c;z+=(d%2<1?1:n)*(d%4<2?2:-2);}return a;}String g(int n){String m;return n>1?(m="--".repeat(n-2))+"--.\n"+(n>2?".-"+g(n-2).replace("\n"," |\n| ")+" |\n'"+m:"<")+"-'":">";}
```
[Try it online!](https://tio.run/##dZBRb5swFIXf9yuuLG21S2AN7aQJx4m2SXvo25S9pXm4A4fSwDWyTbom5bdnJqFa@1AkxDXnO5zDfcAdxg/F9pjX6BwsCbcaDsf8Hu1qveFLbysqwU0q8kDisEMLqEpOIvHmR4C@WYtPXMhB36urSaGu5MZYPoB55t5S4lBEClf79ef001QOg8rlPlK8@JjOpotpRuIyzDezdJFmcSpkb7XvLAHKfmxS8rHJeG7kiNB8uuCNYnHMEqtbjZ5T@ISIwpvkjljEaZ4uWBKzqDwpA1VjrjkL6oTB8x09Awv8MF2wqMnYbDjGFyxjcyb7I0Brqx16Dc6jr3LYmaoAr53/vyc414PDBwjX8sl53SSm80mwkq@Jk348b5mLZMODgYSQ78EnpQ932/2pQ@Dr3AYrGnNXa0BbupfUsH84ralSNxIqmMHX8Igice7K3BCP1nRUsFB4jH/HpdIXGxlT1LpBemU6K7/v9a@uyrffrXmkn@bvbde0LlBf3lBtrdFpMkG4Hn@sP/4D "Java (JDK) ‚Äì Try It Online")
I have derived this from my JavaScript answer. Java is not really good for code golf, but I think, the result is not too bad.
* minus 3 bytes, thanks to ceilingcat
[Answer]
# [Haskell](https://www.haskell.org/), ~~333~~ 289 bytes
```
f s n=h s n 0 0$concatMap(++"\n").g$n
h(c:t)n d z m=take z l++c:drop(z+1)l where e=mod(d+sum[1|a<-".'",m!!z==a])4;l=h t n e(z+2*[1,n,-1,-n]!!e)m
h _ _ _ _ m=m
g 1=[">"]
g 2=["--.","<-'"]
g n=(m++"--."):(map(++" |").h)b++["'-"++m++"'"]where b=g(n-2);m=b>>"--";h(l:k)=[".-"++l]++map("| "++)k
```
[Try it online!](https://tio.run/##bZBfS8MwFMXf@ynuwmCJacs6p0K37MEHH8Q9iL7VIlmbraPJTekfJmPfvaZOdA8jEG5@nHvOIYVsSqV132@hARTFcMMUpuPMYibbtawo5@QDCQt3Y/QKmsUtQ8jhCEa0slRu0JxncV7bih55xDQcClUrUMLYnOa86UwSneQyIOGE@GY0OgohUzZfaJfWujTl1mY3SeSjH0R@gOlopJjxCvj8PUYYbweRSMiKpG6auSkIQuKTZTD5ISiocTUHyGJqzqXh5EoXbMN5QiYB4XyQOP253kbsKAYztjBis1q5VbIoqI5L5szDQa1Tt@GcyAnci5W9kXsUjqyh6tq3tn5BSDwAugXSoPsJWdsOcwJz5l/Dd9fx/XX88IfR2lwrI/HS@QL@G7wX6rXbZ@VjbQ/4ZL@eO1M1l8GVVrJRaAncsrT/Bg "Haskell ‚Äì Try It Online")
Function `g` makes an empty snake as a list of strings. Function `h` fills in the given string `s` while converting the list of strings to a single string. Function `f` is the resulting target function.
In function `h`, `d` is the direction where to go for the next character of string `s` and `z` is the position of the character to replace.
]