[Question]
  [
This challenge is a simple [ascii-art](/questions/tagged/ascii-art "show questions tagged 'ascii-art'") one. Given two inputs, describing the height and width of a Lego piece, you have print an ASCII art representation of it.
Here is how the Lego pieces are supposed to look:
```
(4, 2)
___________
| o o o o |
| o o o o |
-----------
(8, 2)
___________________
| o o o o o o o o |
| o o o o o o o o |
-------------------
(4, 4)
___________
| o o o o |
| o o o o |
| o o o o |
| o o o o |
-----------
(3, 2)
_________
| o o o |
| o o o |
---------
(1, 1)
o
```
If you can't tell from the test-cases, the top and bottom are `width*2+3` underscores and dashes, and each row has pipes for the sides, `o`'s for the little things, and everything is separated by spaces.
The only exception for this is `(1, 1)`, which is just a single `o`.
You will never get `0` for any of the dimensions.
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so shortest code in **bytes** wins!
```
var QUESTION_ID=84050,OVERRIDE_USER=31343;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
```
```
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
```
```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
```
  
[Answer]
# [Befunge](https://en.wikipedia.org/wiki/Befunge), 165 ~~227~~ bytes
```
&::&*:1` v
v+3*2:\/\_"o",@
v       _$ v<
>"_",1-:^  2
v:,,"| ",*5<
v         _v
>" o",,1-:^$
>*v>\     #\^
5 #|:-1,"|"<
^2$<
v1, *95<
- >2*3+^
>:    #^_@
```
Not as much whitespace as before, but there are still gaps. The principle is the same as in the previous solution, but the layout is different. This time, to check if both numbers are 1, I'm just taking their product and seeing if the result is greater than 1.
---
Old solution (227 bytes)
```
v           v       <
&   >>\:2*3+>"_",1-:|
>&:1`|v ,,"| ",*52:$<   :\<
    #\v         <
     :>" o",,1-:|
     1          >"|",$\1-:|
    \`            @       $
    ^_"o",@>:!    |       2
           ^-1,*95<+3*2,*5<
```
It might be possible to golf it more. Just look at all that whitespace!
Here's my poor attempt at an explanation in MSPaint picture form:
[![How to Befunge](https://i.stack.imgur.com/4J1RS.png)](https://i.stack.imgur.com/4J1RS.png)
Code flows in the direction of the arrow.
[Answer]
# [V](https://github.com/DJMcMayhem/V), ~~43, 40, 38~~ 36 bytes
One of the longest V answers I've ever written...
```
Àio ddÀPñóo î½o
u2Pí.«/| °|
Vr-HVr_
```
[Try it online!](http://v.tryitonline.net/#code=w4BpbyAbZGTDgFDDscOzbyDDrsK9bwp1MlDDrS7Cqy98IMKwfApWci1IVnJf&input=&args=Mg+Mg)
Since this contains unicode and unprintable characters, here is a reversible hexdump:
```
0000000: c069 6f20 1b64 64c0 50f1 f36f 20ee bd6f  .io .dd.P..o ..o
0000010: 0d0a 7532 50ed 2eab 2f7c 20b0 7c0d 0a56  ..u2P.../| .|..V
0000020: 722d 4856 725f                           r-HVr_
```
This challenge is about manipulating text, so perfect for V! On the other hand, V is terrible at conditionals and math, so the differing output for (1, 1) really screwed it up... :(
Explanation:
```
À                   "Arg1 times:
 io <esc>           "Insert 'o '
         dd         "Delete this line, and
           À        "Arg2 times:
            P       "Paste it
```
Now we have 'Height' lines of o's with spaces between them.
```
ñ                   "Wrap all of the next lines in a macro. This makes it so that if any 
                    "Search fails, execution will stop (to handle for the [1, 1] case)
 ó                  "Search and replace
  o î½o             "'o'+space+0 or 1 newlines+another 'o'
u                   "Undo this last search/replace
 2P                 "Paste twice
   í                "Search and replace on every line
    .«/| °|         "A compressed regex. This surrounds every non-empty line with bars.
Vr-                 "Replace the current (last) line with '-'
   H                "Move to line one
    Vr_             "Replace this line with '_'
```
Non-competing version (31 bytes):
[Try it online!](http://v.tryitonline.net/#code=w4BpbyAbw4DDhMOxL28gw67CvW8KMlDDrS7Cqy98IMKwfArDki1Iw5Jf&input=&args=Mg+Mg)
This version uses several features that are newer then this challenge to be 5 bytes shorter!
Second explanation:
```
ddÀP
```
which is "Delete line, and paste it *n* times" is replaced with `ÀÄ` which is "Repeat this line *n* times". (-2 bytes)
```
óo î½o
u
```
which was "Replace the first match of this regex; Undo" was replaced with
```
/o î½o
```
Which is just "Search for a match of this regex" (-1 byte)
And lastly, `Ò` is just a simple synonym for `Vr`, which both "Replace every character on this line with 'x'". (-2 bytes)
[Answer]
# 32 16-bit little-endian x86 machine code, 57 54 51 bytes
*3 bytes less thanks to @ninjalj.*
*Heavily rewrote the code and have managed to shave off another 3 bytes*
In hex
```
FCBA6F208D48FFE20492AAEB2389D941D1E14151B05FF3AAEB0BB87C20AB89D992F3AB92AAB00AAA4E7DEF59B02DF3AA91AAC3
```
Input: BX=width, SI=height, DI points to the buffer that receives result as a NULL-terminated string with lines separated by "\n"
## Disassembly:
```
fc            cld
ba 6f 20      mov    dx,0x206f      ;Storing ' o' in DX for later use
8d 48 ff      lea    cx,[bx+si-0x1] ;CX=width+height-1
e2 04         loop   _main0         ;--CX & brahch if not zero
92            xchg   dx,ax          ;(1,1) case, swap DX & AX
aa            stosb                 ;AL == 'o', CX == 0
eb 23         jmp    _end
_main0:
89 d9         mov    cx,bx
41            inc    cx
d1 e1         shl    cx,1
41            inc    cx           ;Calculate (width+1)*2+1
51            push   cx           ;and save it for future use
b0 5f         mov    al,0x5f      ;'_'
f3 aa         rep    stosb        ;Output the whole line of them
eb 0b         jmp    _loopstart   ;Jump into the loop
_loop:
b8 7c 20      mov    ax,0x207c    ;' |'
ab            stosw               ;Output it once (left bar + space)
89 d9         mov    cx,bx        ;Copy width
92            xchg   dx,ax        ;AX == ' o'
f3 ab         rep    stosw        ;Output it CX times
92            xchg   dx,ax        ;Swap values back, AL == '|'
aa            stosb               ;Output only the right bar
_loopstart:
b0 0a         mov    al,0x0a      ;Newline. Can be replaced with mov ax,0x0a0d for windows newline
aa            stosb               ;convention (at the cost of 1 byte), with stosb replaced with stosw
4e            dec    si           ;Height--
7d ef         jge    _loop        ;Continue if si >= 0 (this accounts for the dummy first pass)
59            pop    cx
b0 2d         mov    al,0x2d      ;'-'
f3 aa         rep    stosb        ;Output bottom line
_end:
91            xchg   cx,ax        ;CX == 0, so swap to get zero in AL
aa            stosb               ;NULL-terminate output
c3            retn
```
[Answer]
## Python 2, ~~75~~ ~~73~~ 72 bytes
```
lambda x,y:(x*'__'+'___\n'+('| '+'o '*x+'|\n')*y+'-'*(x*2+3),'o')[x<2>y]
```
Returns a string, with a conditional to handle the 1,1 block.
*Thanks to Lynn and Chepner for two bytes*
[Answer]
# CJam, 34
```
'_q~'o*"||"\*S*f*f+'-f+zN*_,H='o@?
```
[Try it online](http://cjam.aditsu.net/#code=%27_q%7E%27o*%22%7C%7C%22%5C*S*f*f%2B%27-f%2BzN*_%2CH%3D%27o%40%3F&input=2%204)
**Explanation:**
```
'_        push a '_' character
q~        read and evaluate the input (height and width)
'o*       repeat the 'o' character <width> times
"||"\*    join the "||" string by the string of o's (putting them in between)
S*        join with spaces (inserting a space between every 2 characters)
f*        repeat each character <height> times, making it a separate string
f+        prepend '_' to each string
'-f+      append '-' to each string
z         transpose the array of strings
N*        join with newlines; lego piece is ready, special case to follow
_,        duplicate the string and get its length
H=        compare with H=17
'o        push 'o' for the true case
@         bring the lego piece to the top for the false case
?         if the length was 17, use 'o' else use the lego piece
```
[Answer]
# Ruby, ~~59~~ 56 bytes
Anonymous function, returns a multiline string. [Try it online!](https://repl.it/C73A)
-3 bytes thanks to borrowing a trick from @El'endiaStarman
```
->w,h{w*h<2??o:?_*(x=2*w+3)+$/+(?|+' o'*w+" |
")*h+?-*x}
```
[Answer]
# Java, 318 312 297 294 260 258 bytes
Saved 15 bytes thanks to [cliffroot](https://codegolf.stackexchange.com/users/53197/cliffroot)!
```
interface a{static void main(String[]A){int b=Byte.valueOf(A[0]),B=Byte.valueOf(A[1]),C=3+b*2;String c="";if(b<2&B<2)c="o";else{for(;C-->0;)c+="_";for(;B-->0;){c+="\n|";for(C=b;C-->0;)c+=" o";c+=" |";}c+="\n";for(C=3+b*2;C-->0;)c+="-";}System.out.print(c);}}
```
It works with command line arguments.
Ungolfed In a human-readable form:
```
interface a {
    static void main(String[] A) {
        int b = Byte.valueOf(A[0]),
            B = Byte.valueOf(A[1]),
            C = 3 + b*2;
        String c = "";
        if (b < 2 & B < 2)
            c = "o";
        else {
            for (; C-- > 0;)
                c += "_";
            for (; B-- > 0;) {
                c += "\n|";
                for (C = b; C-- >0;)
                    c += " o";
                c += " |";
            }
            c += "\n";
            for(C = 3 + b*2; C-- >0;)
                c += "-";
        }
        System.out.print(c);
    }
}
```
---
Yes, it's still difficult to understand what's going on even when the program is ungolfed. So here goes a step-by-step explanation:
```
static void main(String[] A)
```
The first two command line arguments -which we'll use to get dimensions- can be used in the program as `A[0]` and `A[1]` (respectively).
```
int b = Byte.valueOf(A[0]),
    B = Byte.valueOf(A[1]),
    C = 3 + b*2;
String c = "";
```
`b` is the number of columns, `B` is the number of rows and `C` is a variable dedicated for use in `for` loops.
`c` is the Lego piece. We'll append rows to it and then print it at the end.
```
if (b < 2 & B < 2)
    c = "o";
else {
```
If the piece to be printed is 1x1, then both `b` (number of columns) and `B` (number of rows) should be smaller than 2. So we simply set `c` to a single `o` and then skip **to** the statement that `System.out.print`s the piece if that's the case.
```
for (; C-- > 0; C)
    c += "_";
```
Here, we append `(integerValueOfA[0] * 2) + 3` underscores to `c`. This is the topmost row above all holes.
```
for (; B > 0; B--) {
    c += "\n|";
    for(C = b; C-- > 0;)
        c+=" o";
    c += " |";
}
```
This is the loop where we construct the piece one row at a time. What's going on inside is impossible to explain without examples. Let's say that the piece is 4x4:
```
Before entering the loop, c looks like this:
___________
After the first iteration (\n denotes a line feed):
___________\n
| o o o o |
After the second iteration:
___________\n
| o o o o |\n
| o o o o |
After the third iteration:
___________\n
| o o o o |\n
| o o o o |\n
| o o o o |
```
.
```
c += "\n";
for (C = 3 + b*2; C-- > 0;)
    c += "-";
```
Here, we append `(integerValueOfA[0] * 2) + 3` hyphens to the piece. This is the row at the very bottom, below all holes.
The 4x4 piece I used for explaining the `for` loop where the piece is actually constructed now looks like this:
```
___________\n
| o o o o |\n
| o o o o |\n
| o o o o |\n
| o o o o |\n
-----------
```
```
System.out.print(c);
```
And finally, we print the piece!
[Answer]
## [Minkolang 0.15](https://github.com/elendiastarman/Minkolang), ~~58~~ ~~57~~ 56 bytes
Yes, that's right. I golfed off *~~one~~ two stinkin' little bytes*...
```
nn$d*1-5&"o"O.rd2*3+$z1$([" o"]" ||"2Rlkr$Dlz["-_"0G]$O.
```
[Try it here!](http://play.starmaninnovations.com/minkolang/?code=nn%24d*1-5%26%22o%22O%2Erd2*3%2B%24z1%24%28%5B%22%20o%22%5D%22%20%7C%7C%222Rlkr%24Dlz%5B%22-_%220G%5D%24O%2E&input=4%202)
### Explanation
```
nn                Take two numbers from input (stack is now [w h])
                  C special case C
  $d              Duplicate stack
    *1-           Multiply and subtract 1
       5&         Jump 5 spaces if truthy
         "o"O.    Top of stack was 1*1-1=0, so output "o" and stop.
                     C precalculates width of top and bottom lines for later use C
         r           Reverse stack (now [h w])
          d          Duplicate top of stack
           2*3+      Multiply top of stack by 2 and add 3
               $z    Pop this and store in register (z = 2*w+3)
                                       C generates the row C
                 1$(                   Open while loop prepopulated with top of stack
                    [" o"]             w times, push "o "
                          " ||"        Push "|| "
                               2R      Rotate twice to the right
                                 l     Push newline (10)
                                  k    Break out of while loop
                                           C duplicates the row h times C
                                   r       Reverse stack
                                    $D     Duplicate whole stack h times
                                      l    Push newline
                     C this is for the top and bottom lines C
        z[           Open for loop that repeats z times
          "-_"       Push "_-"
              0G     Relocate top of stack to bottom of stack
                ]    Close for loop
                 $O.    Output whole stack as characters and stop.
```
Okay, that's two significant rewrites of the explanation for two bytes saved. I don't think I can or will golf anything more out of this one. :P
[Answer]
# brainfuck, 391 bytes
I know this can be golfed down more, but at this point I'm just glad it works. I will continue to work to golf it down.
```
+++++[-<+++[-<+++<++++++<+++++++<++<++++++++>>>>>]<<+<+<<+<++>>>>>>>]<<<<+<++<->>>>>>,<,>>++++++[<--------<-------->>-]<<->>+<<[>>-<<[>>>+<<<-]]>>>[<<<+>>>-]<[<->>>+<<<[>>>-<<<[>>>>+<<<<-]]>>>>[<<<<+>>>>-]<[<<<<<<<.[-].]<<<+>-]<<+>[->++>+<<]>+++[-<<<<.>>>>]>[-<<+>>]<<<<<<<<<.>>>>>>><[->[->+>+<<]<<<<<<.>>>>>>>[<<<<<<.>.>>>>>-]>[-<<+>>]<<<<<<<.<.<.>>>>>>]>[->++>+<<]>+++[-<<<.>>>]>[-<<+>>]<<
```
Input needs to be given as just two digits. As in, to do `(8, 2)` you would just enter `82`.
[Try it online!](http://brainfuck.tryitonline.net/#code=KysrKytbLTwrKytbLTwrKys8KysrKysrPCsrKysrKys8Kys8KysrKysrKys-Pj4-Pl08PCs8Kzw8KzwrKz4-Pj4-Pj5dPDw8PCs8Kys8LT4-Pj4-Piw8LD4-KysrKysrWzwtLS0tLS0tLTwtLS0tLS0tLT4-LV08PC0-Pis8PFs-Pi08PFs-Pj4rPDw8LV1dPj4-Wzw8PCs-Pj4tXTxbPC0-Pj4rPDw8Wz4-Pi08PDxbPj4-Pis8PDw8LV1dPj4-Pls8PDw8Kz4-Pj4tXTxbPDw8PDw8PC5bLV0uXTw8PCs-LV08PCs-Wy0-Kys-Kzw8XT4rKytbLTw8PDwuPj4-Pl0-Wy08PCs-Pl08PDw8PDw8PDwuPj4-Pj4-PjxbLT5bLT4rPis8PF08PDw8PDwuPj4-Pj4-Pls8PDw8PDwuPi4-Pj4-Pi1dPlstPDwrPj5dPDw8PDw8PC48LjwuPj4-Pj4-XT5bLT4rKz4rPDxdPisrK1stPDw8Lj4-Pl0-Wy08PCs-Pl08PA&input=NDI)
**Breakdown:**
First put the necessary characters into the tape: `(newline)| o_-`
```
+++++[-<+++[-<+++<++++++<+++++++<++<++++++++>>>>>]<<+<+<<+<++>>>>>>>]<<<<+<++<->>>>>
```
Then collect the input into two cells and subtract 48 from each (to get the numeric value and not the numeral character)
```
>,<,>>++++++[<--------<-------->>-]<<
```
Next, check for the special case of `(1, 1)` (Note that just this check accounts for 109 bytes of the code). As if `if`s weren't hard enough to do in brainfuck, we have a nested `if`:
```
->>+<<[>>-<<[>>>+<<<-]]>>>[<<<+>>>-]<[<->>>+<<<[>>>-<<<[>>>>+<<<<-]]>>>>[<<<<+>>>>-]<[<<<<<<<.[-].]<<<+>-]<<+
```
The following is the structure to check if a cell x is zero or nonzero:
```
temp0[-]+
temp1[-]
x[
 code1
 temp0-
 x[temp1+x-]
]
temp1[x+temp1-]
temp0[
 code2
temp0-]
```
However in a nested `if`, we need to have 4 temporary cells.
Now we get to the actual printing of characters:
Print the top bar and a newline:
```
>[->++>+<<]>+++[-<<<<.>>>>]>[-<<+>>]<<<<<<<<<.>>>>>>>
```
Print a `|`, a row of `o`'s, another `|` and a newline a number of times equal to the height: 
```
<[->[->+>+<<]<<<<<<.>>>>>>>[<<<<<<.>.>>>>>-]>[-<<+>>]<<<<<<<.<.<.>>>>>>] 
```
And print the bottom bar (no newline needed here):
```
>[->++>+<<]>+++[-<<<.>>>]>[-<<+>>]<<
```
[Answer]
## [Retina](https://github.com/m-ender/retina), 52 bytes
Byte count assumes ISO 8859-1 encoding. Note that the sixth line is supposed to contain a single space.
```
\G1?
$_¶
1* 
.+
|$&|
\G.
_
r`.\G
-
s`^.{17}$|1
o
```
[Try it online!](http://retina.tryitonline.net/#code=XEcxPwokX8K2CjEqIAoKCiAKLisKfCQmfApcRy4KXwpyYC5cRwotCnNgXi57MTd9JHwxCm8&input=MTEgMTExMQ)
Input is in unary, using `1` as the unary digit, space as a separator and height followed by width.
### Explanation
All stages in this program are bare substitutions, occasionally with a regular regex modifier (no repetition or loops, no other types of stages). It doesn't even use Retina-specific substitution features, apart from the usual `¶` alias for linefeeds.
```
\G1?
$_¶
```
The purpose of this is to "multiply" the two inputs. Our goal is to create `h+2` rows with `w` `1`s each (`h+2` so that we can turn the top and bottom into `_` and `-` later). The `\G` anchor requires the match to start where the last one left off. That is, if we ever fail to match a character in the string, further characters won't match either. We use this to match only the `1`s in `h`, but not in `w` because the regex doesn't allow the space that separates them to be matched. However, we also make the `1` optional, so that we get an additional empty match at the end of `h`. That's `h+1` matches. Each of those is replaced with the entire input (`$_`) followed by a linefeed. `w` itself remains untouched which gives us the `h+2`nd copy. Say the input was `11 1111`, then we've now got:
```
11 1111
11 1111
11 1111
 1111
```
That's pretty good. We've got some extra stuff, but the `h+2` copies of `w` are there.
```
1* 
```
Note that there's a space at the end of the first line. This removes those prefixes from the lines so that we only have the `w`s afterwards.
```
```
Ah well, that doesn't really work with SE's formatting... the first line is empty and the second line is supposed to contain a single space. This inserts spaces into every possible position, i.e. at the beginning and end of each line and between every pair of `1`s:
```
 1 1 1 1 
 1 1 1 1 
 1 1 1 1 
 1 1 1 1 
```
We will turn these into `o`s later
```
.+
|$&|
```
This simply wraps every line in a pair of `|`:
```
| 1 1 1 1 |
| 1 1 1 1 |
| 1 1 1 1 |
| 1 1 1 1 |
```
Now we take care of the top and bottom:
```
\G.
_
```
Time for `\G` to shine again. This matches each character on the first line and turns it into a `_`.
```
r`.\G
-
```
Same thing, but due to the `r` modifier (right-to-left mode), this matches the characters on the *last* line and turns them into `-`. So now we've got:
```
___________
| 1 1 1 1 |
| 1 1 1 1 |
-----------
```
There's only two things left to do now: turn those `1` into `o`s, and if the input was `1 1` then turn the entire thing into `o` instead. We can handle both of those with a single stage:
```
s`^.{17}$|1
o
```
`s` is regular singleline mode (i.e. it makes `.` match linefeeds). If the input was `1 1` the result will have the minimum size of 17 characters so we can match it with `^.{17}$` and replace it with `o`. Otherwise, if that fails, we'll just match all the `1`s and replace those with `o` instead.
[Answer]
# Jolf, 36 bytes
```
?w*jJρΡ,a+3ώj+2J'-"-+"d*'_lH"  ' o'o
?w*jJ                             'o   return "o" if j * J - 1
       ,a                              make a box
         +3ώj                           of width +3ώj = 3+2*j
             +2J                        of height +2J = 2+J
                '-                      specifying corners as "-"
      Ρ           "-+"                 replacing the first run of "-"s
                      d*'_lH            with a run of "_"s of equal length
     ρ                      "  '       replacing all "  "
                               ' o      with " o"
```
# Jolf, 24 bytes, noncompeting
Well, I made a better box builtin.
```
?w*jJ,AhώjJ"_-'_-'|' o'o
```
# Jolf, ~~38~~ 37 bytes
```
?w*jJΆ+*'_γ+3ώjS*JΆ'|*j" o' |
"*'-γ'o
```
Simple stuff, really. Saved a byte by noting that `!Ζ` (math zeta, or the stand deviance) is only 0 when both arguments are 1, and is falsey otherwise (for our case).
[Answer]
# [05AB1E](http://github.com/Adriandmen/05AB1E), 33 bytes
Code:
```
*i'oë¹·3+©'_×¶²F'|„ o¹×„ |¶}®'-×J
```
Explanation:
```
*i'o                               # If both input equal 1, push "o"
    ë                              # Else, do...
     ¹·3+                          # Push input_1 × 2 + 3
         ©                         # Copy this number to the register
          '_×                      # Multiply by "_"
             ¶                     # Push a newline character
              ²F           }       # Do the following input_2 times:
                '|                 # Push "|"
                  „ o              # Push " o"
                     ¹×            # Multiply this by input_1
                       „ |         # Push " |"
                          ¶        # Push a newline character
                            ®      # Retrieve the value from the register
                             '-×   # Multiply by "-"
                                J  # Join everything and implicitly print.
```
Uses the **CP-1252** encoding. [Try it online!](http://05ab1e.tryitonline.net/#code=Kmknb8OrwrnCtzMrwqknX8OXwrbCskYnfOKAniBvwrnDl-KAniB8wrZ9wq4nLcOXSg&input=NAo4).
[Answer]
## JavaScript (ES6), ~~89~~ 86 bytes
```
(x,y,g=c=>c[r=`repeat`](x*2+3))=>x*y-1?g(`_`)+`
`+`| ${`o `[r](x)}|
`[r](y)+g(`-`):`o`
```
Edit: Saved 3 bytes thanks to @Shaggy.
[Answer]
# Python 2, 71 bytes
```
lambda x,y:('o',x*'__'+'___\n'+'| %s|\n'%('o '*x)*y+'-'*(x*2+3))[x+y>2]
```
[Answer]
# Befunge, 144 Bytes
I would have prefered to comment to [this](https://codegolf.stackexchange.com/a/84061/56032) post, but I don't have the reputation yet, so I'm putting an answer of my own, which works a similar way, but is slightly more compact
```
&::&*:1`v
v3*2:\/\_"o",@
>+:  v   >52*," |",, v
>,1-:vLEG O MAKERv::\<
^"_" _$\:|<v "o "_v
v52:+3*2$<,>,,1-:^$
>*,v <    ^"|":-1\<
v-1_@,
>:"-"^
```
you can test the code [here](http://www.quirkster.com/iano/js/befunge.html)
[Answer]
# Reng v.4, 82 bytes, noncompeting
I pushed a bug fix that fixes functions being overwritten by themselves (please don't ask; my stuff is haunted)
```
i#wi#hhw+2e1+ø ~*x}o:{"-"ö<
"_"{:o}w2*3+#xx*2ø
"o"o~
ö"|"o"o"{Wo:o}w*"| "ooh1-?^#h
```
Takes input as space-joined numbers, like `4 2`. [Try it here!](https://jsfiddle.net/Conor_OBrien/avnLdwtq/)
[Answer]
## PowerShell v2+, 76 bytes
```
param($x,$y)if($x+$y-2){"_"*($z=$x*2+3);"|$(" o"*$x) |`n"*$y+'-'*$z;exit}"o"
```
Takes input, then checks an `if` statement. Since non-zero values are *truthy* in PowerShell, so long as at least one of `$x` and `$y` are not equal to `1`, the `if` will be true.
Inside the `if`, there's a series of string multiplications. First, we construct our string of underscores, saving `$z` for later. That gets placed on the pipeline. Next we construct our string of sides and pegs (with the pegs multiplied by `$x`), done `$y` times, and concatenate that with our dashes `$z` times. That string is then placed on the pipeline and we `exit`. The pipeline is flushed and printing is implicit. Note that we get the newline between the underscores and the first row of pegs for free, since the default `.ToString()` separator for array output is ``n` (and we're outputting an array of strings).
If the `if` is false, we're in the special `1 1` case, so we just put `"o"` by itself on the pipeline and exit, with printing again implicit.
### Examples
```
PS C:\Tools\Scripts\golfing> .\print-a-lego-piece.ps1 1 1
o
PS C:\Tools\Scripts\golfing> .\print-a-lego-piece.ps1 5 3
_____________
| o o o o o |
| o o o o o |
| o o o o o |
-------------
```
[Answer]
## Bash, 186,163,156, 148,131, 130 Bytes
```
 ## Arg1 - Lego width
 ## Arg2 - Lego height 
function print_lego() { 
(($1+$2>2))&&{
printf _%.0s `seq -1 $1`
echo
for((i=$2;i--;)){ 
 printf \|
 for((j=$1;j--;)){
  printf o
 }
 echo \| 
}
printf =%.0s `seq -1 $1`
echo 
}||echo o
}
```
Note: If you really need the lego to have hyphens for the last line, then change the last printf to 
```
printf -- -%.0s `seq -1 $1`
```
and add two bytes.
[Answer]
# Perl 5 - 84 77 bytes
84 Bytes
```
sub l{($x,$y)=@_;$w=3+2*$x;warn$x*$y<2?"o":'_'x$w.$/.('| '.'o 'x$x."|\n")x$y.'-'x$w}
```
77 Bytes. With some help from [Dom Hastings](https://codegolf.stackexchange.com/users/9365/dom-hastings)
```
sub l{($x,$y)=@_;$x*$y<2?o:'_'x($w=3+2*$x).('
| '.'o 'x$x."|")x$y.$/.'-'x$w}
```
[Answer]
## C, ~~202~~ 191 bytes
```
#define p printf
i,w,h;t(char*c){for(i=0;p(c),++i<w*2+3;);p("\n");}f(){t("_");for(i=0;i<w*h;)i%w<1?p("| o "):p("o "),i++%w>w-2&&p("|\n");t("-");}main(){scanf("%d %d",&w,&h);w*h<2?p("o"):f();}
```
Thanks to [@Lince Assassino](https://codegolf.stackexchange.com/users/29679/lince-assassino) for saving 11 bytes!
Ungolfed:
```
#include <stdio.h>
#define p printf
int i, w, h;
void t(char *c)
{
    for(i=0; p(c), ++i<w*2+3;);
    p("\n");
}
void f()
{
    t("_");
    for(i=0; i<w*h;)
    {
        i%w<1 ? p("| o ") : p("o ");
        i++%w>w-2 && p("|\n");
    }
    t("-");
}
int main()
{
    scanf("%d %d", &w, &h);
    w*h<2 ? p("o") : f();
}
```
[Answer]
# Cinnamon Gum, 32 bytes
```
0000000: 6c07 d5f5 7a5d 9cdf 5ae6 52ae 4050 0c35  l...z][[email protected]](/cdn-cgi/l/email-protection)
0000010: 18d9 052f 0082 9b42 e7c8 e422 5fe4 7d9f  .../...B..."_.}.
```
Non-competing. [Try it online.](http://cinnamon-gum.tryitonline.net/#code=MDAwMDAwMDogNmMwNyBkNWY1IDdhNWQgOWNkZiA1YWU2IDUyYWUgNDA1MCAwYzM1ICBsLi4uel0uLlouUi5AUC41CjAwMDAwMTA6IDE4ZDkgMDUyZiAwMDgyIDliNDIgZTdjOCBlNDIyIDVmZTQgN2Q5ZiAgLi4uLy4uLkIuLi4iXy59Lg&input=WzQsMl0) Input must be exactly in the form `[width,height]` with no space in between the comma and the height.
# Explanation
The string decompresses to this:
```
l[1,1]&o;?&`p___~__~
%| ~o ~|
%---~--~
```
The first `l` stage maps `[1,1]` to `o` (the special case) and everything else to the string
```
`p___~__~
%| ~o ~|
%---~--~
```
The backtick then signals the start of a second stage; instead of outputting that string, CG chops off the backtick and executes the string. The `p` mode then repeats all the characters inside the tildes first parameter (width) times and then afterwards repeats the characters inside the percent signs second parameter (height) times. So for `[4,2]` it turns into this:
```
___________
%| o o o o |
%-----------
```
and then into:
```
___________
| o o o o |
| o o o o |
-----------
```
[Answer]
## Batch, ~~172~~ 170 bytes
```
@echo off
if "%*"=="1 1" echo o&exit/b
set o=
for /l %%i in (1,1,%1)do call set o=%%o%% o
echo ---%o: o=--%
for /l %%i in (1,1,%2)do echo ^|%o% ^|
echo ---%o: o=--%
```
Edit: Saved 2 bytes thanks to ~~@CᴏɴᴏʀO'Bʀɪᴇɴ~~ @EʀɪᴋᴛʜᴇGᴏʟғᴇʀ.
I can save 7 bytes if I can assume delayed expansion is enabled.
[Answer]
# Vim, 56 keystrokes
This seems like a text editing task, so Vim is the obvious choice! I take input as a text file with two space separated integers and output the answer into the same file. Also, I hate you for having the 1x1 special case... Anyway:
```
"adt l"bDro:if@a*@b==1|wq|en<cr>Di| |<esc>@aio <esc>yy@bPVr_GpVr-ZZ
```
and if there hadn't been for the special case, 35 keystrokes
```
"adt x"bDi| |<esc>@aio <esc>yy@bPVr_GpVr-ZZ
```
## A breakdown for sane people:
```
"adt l"bD
```
Delete numbers from buffer into @a and @b (space char kept)
```
         ro:if@a*@b==1|wq|en<cr>
```
Replace space with "o" and if special case, save and quit
```
                                Di| |<esc>
```
Clear the line and write the edges of the lego block
```
                                          @aio <esc>
```
Insert @a lots of "o " to get a finished middle part
```
                                                    yy@bP
```
Yank line and make @b extra copies (one too many)
```
                                                         Vr_
```
We are at top of buffer, replace extra line with underscores
```
                                                            Gp
```
Jump to bottom of buffer, pull line that we yanked earlier
```
                                                              Vr-ZZ
```
Replace line with dashes, save and quit
[Answer]
# Befunge, ~~114~~ ~~113~~ ~~108~~ 101 bytes
I know there are already a number of Befunge solutions, but I was fairly certain they could be improved upon by taking a different approach to the layout of the code. I suspect this answer can be golfed further as well, but it is already a fair bit smaller than either of the previous entries.
```
&::&+:2`^|,+55_"_",^
-4:,,"| "<\_|#:+1\,,"|"+55$_2#$-#$" o",#!,#:<
  ,"-"_@#:-1<
 :*2+2\-_"o",@v!:-1<
```
[Try it online!](http://befunge.tryitonline.net/#code=Jjo6Jis6MmBefCwrNTVfIl8iLF4KLTQ6LCwifCAiPFxffCM6KzFcLCwifCIrNTUkXzIjJC0jJCIgbyIsIyEsIzo8CiAgLCItIl9AIzotMTwKIDoqMisyXC1fIm8iLEB2ITotMTw&input=NCAy)
[Answer]
# Pyth, 38 bytes
```
?t*QJEjb+sm\_K+\|+j\o*dhQ\|+mKJsm\-K\o
```
[Test suite.](http://pyth.herokuapp.com/?code=%3Ft%2aQJEjb%2Bsm%5C_K%2B%5C%7C%2Bj%5Co%2adhQ%5C%7C%2BmKJsm%5C-K%5Co&test_suite=1&test_suite_input=8%0A3%0A1%0A1&debug=0&input_size=2)
[Answer]
# Haskell, 76 bytes
```
1#1="o"
w#h|f<-w*2+3=f!"_"++'\n':h!('|':w!" o"++" |\n")++f!"-"
n!s=[1..n]>>s
```
Usage example: `3 # 2` gives you a multiline string for a 3-by-2 brick.
Ungolfed:
```
(#) :: Int -> Int -> String
1     #   1    = "o"
width # height = let longWidth = 2 * width + 3 in -- golfed as 'f'
                      (        longWidth `times` "_"  ++   "\n" )
  ++ height   `times` ( "|" ++     width `times` " o" ++ " |\n" )
  ++                  (        longWidth `times` "-"            )
-- | golfed as (!)
times :: Int -> [a] -> [a]
times n s = concat $ replicate n s
```
[Answer]
# Groovy, 107, 98, 70, 64
```
{x,y->t=x*2+3;x<2&&y<2?"o":'_'*t+"\n"+"|${' o'*x} |\n"*y+'-'*t}
```
Testing:
```
(2,2)
(1,1)
(8,2)
(1,4)
_______
| o o |
| o o |
-------
o
___________________
| o o o o o o o o |
| o o o o o o o o |
-------------------
_____
| o |
| o |
| o |
| o |
-----
```
[Answer]
# PHP 7, 98 bytes
```
<?=($P=str_pad)("",$w=3+2*$argv[1],_).$P("",$argv[2]*++$w,$P("
| ",$w-1,"o ")."|").$P("
",$w,"-");
```
`str_pad` saves a little from `str_repeat`.  
Juggling with preincrement on `$w` saves two bytes.  
But version 7 is needed for assigning `$r` while using it at the same time.
[Answer]
## APL, 46 bytes
```
{⍵≡1 1:'o'⋄'-'⍪⍨'_'⍪'|',' ','|',⍨'o '⍴⍨1 2×⌽⍵}
```
The guard: `⍵≡1 1:'o'` for the special case.
Otherwise `'o '⍴⍨1 2×⌽⍵` builds the content. And the rest is just the boxing.
[Answer]
## C#, 198 bytes
```
void f(int x,int y){int l=x*2+3;Console.Write(y==x&&x==1?"o":s("_",l)+"\n"+s("|"+s(" o",x)+" |\n",y)+s("-",l));}string s(string m,int u){return string.Join("",new string[u].Select(n=>m).ToArray());}
```
quick and dirty
I had to write a function that multiplies strings
ungolfed (for suggestions)
```
public static void f(int x,int y)
{
    int l=x*2+3;
    Console.Write(y == x && x == 1 ? "o" : s("_",l)+"\n"+ s("|" + s(" o", x) + " |\n", y) + s("-",l));
}
public static string s(string m,int u)
{
    return string.Join("", new string[u].Select(n => m).ToArray());
}
```
]