[Question]
  [
Given an input of two integers *n* and *m*, output an ASCII ladder of length
*n* and size *m*.
This is an ASCII ladder of length 3 and size 3:
```
o---o
|   |
|   |
|   |
+---+
|   |
|   |
|   |
+---+
|   |
|   |
|   |
o---o
```
This is an ASCII ladder of length 5 and size 1:
```
o-o
| |
+-+
| |
+-+
| |
+-+
| |
+-+
| |
o-o
```
This is an ASCII ladder of length 2 and size 5:
```
o-----o
|     |
|     |
|     |
|     |
|     |
+-----+
|     |
|     |
|     |
|     |
|     |
o-----o
```
To be specific:
* The length (*n*) represents how many squares the ladder is made up of.
* The size (*m*) represents the width and height of the interior of—that is,
not counting the "borders"—each square.
* Each square is made up of the interior area filled with spaces, surrounded by
`-`s on the top and bottom, `|`s on the left and right, and `+`s at all four
corners.
* Borders between squares merge together, so two lines in a row with
`+--...--+` merge into one.
* The corners of the entire ladder are replaced with the character `o`.
* You may optionally output a trailing newline.
The length of the ladder (*n*) will always be ≥ 2, and the size (*m*) will
always be ≥ 1.
Input can be taken as a whitespace-/comma-separated string, an array/list/etc.,
or two function/command line/etc. arguments. The arguments can be taken in
whichever order is most convenient / golfiest.
Since this is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), the shortest code in bytes wins.
Tip: The examples above can also be used as test cases.
  
[Answer]
# Ruby, 71
```
->m,n{h=0;(?o+?+*(n-1)+?o).chars{|c|puts [?|+' '*m+?|]*h,c+?-*m+c;h=m}}
```
**ungolfed in test program**
```
f=->m,n{
  h=0                             #The number of | above the 1st rung is 0
  (?o+?+*(n-1)+?o).chars{|c|      #Make a string of all the rung ends o++...++o and iterate through it
    puts [?|+' '*m+?|]*h,         #draw h vertical segments |  ...  |
      c+?-*m+c                    #and a rung with the correct ends
    h=m                           #The number of | above all rungs except the 1st is m
  }
}
f[gets.to_i,gets.to_i]
```
[Answer]
# CJam, ~~43~~ 42 bytes
I'm not sastified by the score. But I'm not Dennis, right?
```
q~:Z;'-'o{[\Z*1$N]}:X~['-_'+X\'|XZ*]@*1>1$
```
Input is 2 space separated items. Length first
```
2 3
o---o
|   |
|   |
|   |
+---+
|   |
|   |
|   |
o---o
```
Explanation
```
q~:Z;'-'o{[\Z*1$N]}:X~['-_'+X\'|XZ*]@*1>1$
q~                                         e# read input
  :Z;                                      e# Record the size in Z and discard
     '-'o{[\Z*1$N]}:X~                     e# Create the initial line (and final). also creates a shorcut to do this later
           \                               e# Capture two arguments
            Z*                             e# The separator is repeated size times
              1$                           e# Repeat the first argument
                N                          e# Add newline
                                           e# X is a function to create line in a ladder
                      ['-_'+X\'|XZ*]       e# Design the repeating part
                                    @*     e# Repeat the pattern n times
                                      1>   e# Discard the initial
                                        1$ e# Since the final line is same than the initial, we just write it.
                                           e# Implicit printing
```
[Answer]
# JavaScript (ES6), 89
... repeat, repeat, repeat ...
```
(n,m,R=x=>x.repeat(m),b=R(`|${R(' ')}|
`),d=`o${c=R('-')}o
`)=>d+R(b+`+${c}+
`,m=n-1)+b+d
```
**Test** 
```
F=(n,m,R=x=>x.repeat(m),b=R(`|${R(' ')}|
`),d=`o${c=R('-')}o
`)=>d+R(b+`+${c}+
`,m=n-1)+b+d
// Less golfed
U=(n,m)=>
{
  var R=x=>x.repeat(m),
      a=R(' '),
      b=R(`|${a}|\n`);
      c=R('-'),
      d=`o${c}o\n`;
  m=n-1;
  return d+R(b+`+${c}+\n`)+b+d
}
function test() {
  var i=I.value.match(/\d+/g)
  if (i) O.textContent=F(+i[0],+i[1])
  console.log(i,I.value)
}  
 
test()
```
```
N,M: <input id=I value="3,5" oninput=test()>
<pre id=O></pre>
```
[Answer]
# C#, 1412 bytes
... My first CodeGolf attempt, Not likely to win but it works so here we go:
```
using System;
namespace Ascii_Ladders
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 0;
            int m = 0;
            Console.Write("Please enter Height: ");
            n = int.Parse(Console.ReadLine());
            Console.Write("Please Enter Width: ");
            m = int.Parse(Console.ReadLine());
            Console.Write("o");
            for (int i = 0; i < m; i++)
            {
                Console.Write("-");
            }
            Console.WriteLine("o");
            for (int k = 0; k < n; k++)
            {
                for (int i = 0; i < m; i++)
                {
                    Console.Write("|");
                    for (int j = 0; j < m; j++)
                    {
                        Console.Write(" ");
                    }
                    Console.WriteLine("|");
                }
                if (k != n - 1)
                {
                    Console.Write("+");
                    for (int i = 0; i < m; i++)
                    {
                        Console.Write("-");
                    }
                    Console.WriteLine("+");
                }
            }
            Console.Write("o");
            for (int i = 0; i < m; i++)
            {
                 Console.Write("-");
            }
            Console.WriteLine("o");
            Console.ReadKey();
        }
    }
}
```
[Answer]
# Julia, 87 bytes
```
f(n,m)=(g(x)=(b=x[1:1])x[2:2]^m*b*"\n";(t=g("o-"))join([g("| ")^m for i=1:n],g("+-"))t)
```
This is a function that accepts two integers and returns a string.
Ungolfed:
```
function f(n::Int, m::Int)
    # Create a function g that takes a string of two characters and
    # constructs a line consisting of the first character, m of the
    # second, and the first again, followed by a newline.
    g(x) = (b = x[1:1]) * x[2:2]^m * b * "\n"
    # Assign t to be the top and bottom lines. Construct an array
    # of length n where each element is a string containing the
    # length-m segment of the interior. Join the array with the
    # ladder rung line. Concatenate all of this and return.
    return (t = g("o-")) * join([g("| ")^m for i = 1:n], g("+-")) * t
end
```
[Answer]
# [pb](http://esolangs.org/wiki/pb) - 147 bytes
```
^t[B]>>[B]vw[T!0]{b[43]<[X]b[43]>w[B=0]{b[45]>}v[X-1]w[B=0]{b[124]^}v[X]t[T-1]}t[111]b[T]<w[X!0]{b[45]<}b[T]w[Y!0]{w[B!0]{^}b[124]^}b[T]^>>[B]vb[T]
```
This is the kind of challenge that, by rights, pb should be really good at. Drawing simple pictures with characters is exactly what pb was designed for. Alas, it's just a wordy language I guess.
Takes input length first, followed by size. Takes input in the form of byte values, for example: `python -c 'print(chr(5) + chr(7))' | ./pbi.py ladder.pb`
Look, a fun animation!
![](https://i.stack.imgur.com/TdZfb.gif)
With comments:
```
^t[B]            # Save length to T
>>[B]v           # Go to X=size+1, Y=0
w[T!0]{          # While T is not 0:
    b[43]            # Write a '+'
    <[X]b[43]        # Write a '+' on the left side as well
    >w[B=0]{b[45]>}  # Travel back to the right '+', writing '-' on the way
    v[X-1]           # Go down by X-1 (== size)
    w[B=0]{b[124]^}  # Travel back up to the '+', writing '|' on the way
    v[X]             # Go down by X (== size + 1, location of next '+')
    t[T-1]           # Decerement T
}
t[111]           # Save 'o' to T (it's used 4 times so putting it
                 # in a variable saves bytes)
b[T]             # Write an 'o' (bottom right)
<w[X!0]{         # While not on X=0:
    b[45]<           # Travel left, writing '-' on the way
}
b[T]             # Write an 'o' (bottom left)
w[Y!0]{          # While not on Y=0:
    w[B!0]{^}        # Skip nonempty spaces
    b[124]           # Write a '|'
    ^                # Travel up
}
b[T]             # Write an 'o' (top left, replaces existing '+')
^>>[B]v          # Go back to where the size is saved and go to X=size+1, Y=0
b[T]             # Write an 'o' (top right, replaces existing '+')
```
[Answer]
### Pure bash, ~~132 130 128~~ 127 bytes
Yes I could drop 1 more byte replacing last `${p% *}`, but I prefer this:
```
p=printf\ -v;$p a %$1s;$p b %$2s;o="|$a|\n";h=+${a// /-}+\\n v=${a// /$o}
a=${b// /$h$v}${h//+/o};a=${a/+/o};${p% *} "${a/+/o}"
```
Sample:
```
ladders() {
    p=printf\ -v;$p a %$1s;$p b %$2s;o="|$a|\n";h=+${a// /-}+\\n v=${a// /$o}
    a=${b// /$h$v}${h//+/o};a=${a/+/o};${p% *} "${a/+/o}"
}
ladders 3 4
o---o
|   |
|   |
|   |
+---+
|   |
|   |
|   |
+---+
|   |
|   |
|   |
+---+
|   |
|   |
|   |
o---o
ladders 2 1
o--o
|  |
|  |
o--o
```
[Answer]
# Pyth, 34 bytes
```
.NjjNm*QTvz*2YjC:M++J"+|o"m"- -"QJ
```
[Test suite](https://pyth.herokuapp.com/?code=.NjjNm%2aQTvz%2a2YjC%3AM%2B%2BJ%22%2B%7Co%22m%22-+-%22QJ&test_suite=1&test_suite_input=3%0A3%0A5%0A1%0A2%0A5&debug=0&input_size=2)
Takes arguments newline separated on STDIN.
Uses a helper function, `:`, which builds each type of vertical string from three characters, then replicates as necessary, transposes and joins on newlines.
[Answer]
## Haskell, ~~100~~ 97 bytes
```
l#s=unlines$t:m++[t]where _:m=[1..l]>>["+"!"-"]++("|"!" "<$u);t="o"!"-";o!i=o++(u>>i)++o;u=[1..s]
```
Usage example:
```
*Main> putStr $ 4 # 3
o---o
|   |
|   |
|   |
+---+
|   |
|   |
|   |
+---+
|   |
|   |
|   |
+---+
|   |
|   |
|   |
o---o
```
How it works:
```
l#s=unlines$t:m++[t]         -- concat top line, middle part and end line
                             -- with newlines between every line
  where                      -- where
  _:m=                       -- the middle part is all but the first line of
     [1..l]>>                -- l times
         ["+"!"-"]           --    a plus-dashes-plus line
         ++("|"!" "<$u)      --    followed by s times a bar-spaces-bar line
  t="o"!"-"                  -- very first and last line
  o!i=o++(u>>i)++o           -- helper to build a line
  u=[1..s]
```
Edit: @Christian Irwan found 3 bytes. Thanks!
[Answer]
# brainfuck - 334 bytes
```
,[<+<<<<+>>>>>-]<[[>>]+[<<]>>-]<----[>---<----]--[>[+>>]<<[<<]>++++++]>[+.>>]-[<+>---]<+++++++>>--[<+>++++++]->---[<------->+]++++++++++[<++<]+++++[>[++++++>>]<<[<<]>-]>[-]>.-<<----[>>+++<<----]--[>+<--]>---<<<<++++++++++.,[>[>+>+<<-]>[<+>-]>[<<<<[>>>>>>[.>>]<<[<<]>>-]>>>>>[.>>]<<[<<]>-]<<<<+>-]>>>>[-]----[>---<----]>+.[>]<<<<<[.<<]
```
I expected this to be a lot shorter.
This sets up a "string" that looks like `| (...) |` and one that looks like `+----(...)----+`, printing each one as necessary, with some special casing for the `o`s on the top and bottom.
Requires an interpreter that uses 8-bit cells and allows you to go left from cell 0 (be it into negative cells or looping). In my experience, these are the most common default settings.
With comments:
```
,[<+<<<<+>>>>>-]<[[>>]+[<<]>>-] Get m from input; make a copy
                      Turn it into m cells containing 1 with empty cells between
<----[>---<----]      Put 67 at the beginning (again with an empty cell between)
--[>[+>>]<<[<<]>++++++]  Add 43 to every nonempty cell
>[+.>>]               Add 1 to each cell and print it
-[<+>---]<+++++++    Put 92 after the last 45 (no empty cell!)
>>--[<+>++++++]      Put 43 immediately after the 92
->---[<------->+]    Put 234 after 43
++++++++++           And 10 after that
[<++<]             Add two to the 234; 92; the empty spaces; and left of the 111
+++++[>[++++++>>]<<[<<]>-] Add 30 to each 2; the 94; and the 236
>[-]>.-<<----[>>+++<<----] Erase leftmost 32; Print 111; subtract 68 from it
--[>+<--]>---        Put 124 where the 32 was
<<<<++++++++++.,     Print a newline; override the cell with n from input
[                    n times:
  >[>+>+<<-]>[<+>-]    Make a copy of m
  >[                   m times:
    <<<<                 Look for a flag at a specific cell
    [                    If it's there:
      >>>>>>[.>>]          Go to the 43; print it and every second cell after
      <<[<<]>>-            Clear the flag
    ]
    >>>>>[.>>]           Go to the 124; print it and every second cell after
    <<[<<]>              Go back to the copy of m
  -]
  <<<<+>               Plant the flag
-]
>>>>
[-]----[>---<----]>+ Erase the 124; add 68 to 43
.[>]                 Print it; then head to the end
<<<<<[.<<] Go to the last 45; print it; then print every second cell to the left
```
[Answer]
# PowerShell, 77 ~~80~~
```
param($l,$s)$a='-'*$s
($c="o$a`o")
(($b=,"|$(' '*$s)|"*$s)+"+$a+")*--$l
$b
$c
```
[Answer]
# Jolf, 36 bytes
[Try it here!](http://conorobrien-foxx.github.io/Jolf/#code=z4FwaSxhKzJKKzJKIm8tfCAiaiJvKC4rKW8Kby4rbycrJDEr&input=NQoKMw)
```
ρpi,a+2J+2J"o-| "j"o(.+)o
o.+o'+$1+
```
## Explanation
```
ρpi,a+2J+2J"o-| "j"o(.+)o\no.+o'+$1+
 pi              j                   repeat vertically j times
   ,a+2J+2J"o-| "                    a box with dimensions 2+J
ρ                 "o(.+)p\np.+o'     replace with regex
                                +$1+ with the -...-
```
[Answer]
# Perl, 98 bytes
```
($n,$m)=@ARGV;print$h="o"."-"x$m."o\n",((("|".(" "x$m)."|\n")x$m.$h)x$n)=~s{o(-+)o(?=\n.)}{+$1+}gr
```
[Answer]
## C, 122 bytes
```
f(int m,int n,char*s){int i=0,w=3+m++;for(;i<w*m*n+w;++i)*s++=i%w>m?10:" |-+-o"[!(i/w%m)*2+!(i%w%m)+!(i/w%(m*n))*2];*s=0;}
```
[Try it online](https://ideone.com/jAItbm).
[Answer]
# Tcl, 187 bytes
```
lassign $argv n w
set c 0
while { $c < [expr {($w * $n) + ($n + 2)}]} {if {[expr {$c % ($n + 1)}] == 0} {puts "o[string repeat "-" $w ]o"} else {puts "|[string repeat " " $w ]|"}
incr c}
```
This code is made to put into a file with arguments input on the command line. provide number of boxes and width in that order.
[Answer]
# PHP, 81bytes
Expects 2 arguments, passed when calling the PHP command directly. The first one is the size and the 2nd one is the number of steps.
```
$R=str_repeat;echo$P="o{$R('-',$W=$argv[1])}o
",$R("|{$R(' ',$W)}|
$P",$argv[2]);
```
May require some improvements.
[Answer]
# [Vyxal](https://github.com/Lyxal/Vyxal), 30 bytes
```
(‛+on¬i:⁰-p,⁰(\|:⁰꘍p,))\o:⁰-p,
```
[Try it Online!](http://lyxal.pythonanywhere.com?flags=&code=%28%E2%80%9B%2Bon%C2%ACi%3A%E2%81%B0-p%2C%E2%81%B0%28%5C%7C%3A%E2%81%B0%EA%98%8Dp%2C%29%29%5Co%3A%E2%81%B0-p%2C&inputs=3%0A3&header=&footer=)
```
(                     )        # Length times...
 ‛+on¬i                        # If first iteration, o, else +
       :                       # Duplicate
        ⁰-                     # add (size) minuses
          p,                   # Add the o/+ and print
            ⁰(       )         # Size times
              \|               # A pipe character
                :              # Duplicate
                 ⁰꘍            # Add (size) spaces
                   p,          # Add the pipe and print
                       \o:     # Push two os
                          ⁰-   # Add (size) minuses
                            p, # Add the o and print
```
[Answer]
## Python 2, 94 bytes
```
def F(n,m):a,b,c,d='o|+-';r=[a+d*m+a]+([b+' '*m+b]*m+[c+d*m+c])*n;r[-1]=r[0];print'\n'.join(r)
```
'Ungolfed':
```
def F(n,m):
 # 'o---o'
 r = ['o'+'-'*m+'o']
 # ('|   |'*m+'+---+') n times
 r += (['|'+' '*m+'|']*m+['+'+'-'*m+'+'])*n
 # replace last +---+ with o---o
 r[-1] = r[0]
 print '\n'.join(r)
```
[Answer]
# [Perl 5](https://www.perl.org/), 91 + 1 (-a) = 92 bytes
```
$_='|'.$"x$F[1].'|';push@a,y/| /+-/r,($_)x$F[1]while$F[0]--;$a[0]=y/| /o-/r;say for@a,$a[0]
```
[Try it online!](https://tio.run/##K0gtyjH9/18l3la9Rl1PRalCxS3aMFYPyLEuKC3OcEjUqdSvUdDX1tUv0tFQideEyJdnZOakAlkGsbq61iqJQNoWrCwfqMy6OLFSIS2/CKgVLPP/v6mC8b/8gpLM/Lzi/7q@pnoGhgb/dRMB "Perl 5 – Try It Online")
[Answer]
# [Pip](https://github.com/dloscutoff/pip) `-l`, 35 bytes
```
(^YsXbRLaJW'-)XbWR^('|XbRLaJ'+)WR'o
```
[Try it online!](https://tio.run/##K8gs@P9fIy6yOCIpyCfRK1xdVzMiKTwoTkO9BiKirq0ZHqSe////f92c/8b/jQE "Pip – Try It Online")
### Explanation
```
(^YsXbRLaJW'-)XbWR^('|XbRLaJ'+)WR'o
                                     a is length, b is size, s is space (implicit)
   sXb                               String containing b spaces
      RLa                            List containing a copies of that string
         JW'-                        Join on "-" and wrap the result in "-" as well
  Y                                  Necessary for operator precedence reasons
 ^                                   Split into a list of characters
(            )Xb                     String-repeat each character in the list b times
                                     This list represents the central columns of the ladder
                    '|Xb             String containing b pipe characters
                        RLa          List containing a copies of that string
                           J'+       Join on "+"
                   (          )WR'o  Wrap in "o"
                  ^                  Split into a list of characters
                                     This list represents the outer columns of the ladder
                WR                   Wrap the left list in the right list, vectorizing
```
### Some other versions
I tried a lot of different approaches trying to catch Pyth...
```
[Y'-XbWR'o;@>(sXbWR'|RLbPE'-XbWR'+RL:a)y]  41
Y^(t**b.1*:t**bX--a.1)" --"@yXbWR"|o+"@y   40
Y'|XbRLaJ'+YyWR'o;Z:sXbRLaJW'-RLbPEyAEy    39
t**:b(" |-o-+"<>2)@_@^t.1M$*Y[ttXa-1].1    39
J*Z:sXbRLaJW'-RLbWR:^('|XbRLaJ'+)WR'o      37
Y^$*Y[t**:btXa-1].1" --"@yXbWR"|o+"@y      37
```
I'm particularly fond of the `t**b` ones, which use math to generate the ladder's vertical pattern:
```
        b           Size; e.g. 3
    t               Preset variable for 10
     **:            Set t to t**b (e.g. 1000)
           a        Length; e.g. 3
            -1      2
         tX         String-repeat (the new value of) t 2 times: 10001000
   [          ]     Put t and the above into a list: [1000; 10001000]
               .1   Append 1 to both of them: [10001; 100010001]
$*(              )  Fold on multiplication: 1000200020001
```
The `1000200020001` can then be used to generate the patterns `o|||+|||+|||o` and `- - - -`, which make up the ladder. Unfortunately, I couldn't get this approach to be shorter than the join/wrap approach.
]