[Question]
  [
# 4-state barcodes
Many postal services (Royal Mail UK, Canada Post, US Mail, etc) use a 4-state barcode to encode information about their mail. Rendered in ASCII, it may look something like this:
```
|   | |   | | | |   |     |   |
| | | | | | | | | | | | | | | | |
    | |   |   | | |   |     |
```
A 4-state barcode is a row of bars. Each bar can be extended upwards, downwards, or both, allowing 4 possibilities. This means that each bar essentially represents a base 4 digit:
```
            |       |
Bar:    |   |   |   |
                |   |
Digit:  0   1   2   3
```
The problem with this symbology is that it each barcode is a valid, different barcode upside down: drastically changing the meaning if the orientation is incorrect. Therefore, a *start* and *stop* sequence are normally implemented so the scanner can calculate which way it is supposed to be read.
For the purpose of this challenge, we will be using the start/stop sequence specified by Australia Post: **each barcode begins and ends with a `1 0` sequence.**
---
# The Challenge
Your task is to write a program or function which, given a positive integer `N`, converts it to an ASCII 4-state barcode, where each bar (except for the start/stop sequences) represents a digit in the base-4 representation of `N`.
### Example:
Given the integer `19623`, we would first convert it to its base-4 representation, `10302213`.
We would then map each digit to the corresponding bar:
```
1 0 3 0 2 2 1 3
|   |       | |
| | | | | | | |
    |   | |   |
```
Finally, we would add the start/stop sequences:
```
Start:              End:
1 0                 1 0
|   |   |       | | |
| | | | | | | | | | | |
        |   | |   |
```
The resulting barcode should be the program's output.
---
# Rules:
* The input will be a positive integer, within the range of your language's standard integer size.
* The output:
	+ May be either a list of lines, or a string containing newlines.
	+ May contain leading or trailing newlines/spaces, as long as the shape remains intact.
	+ Should show the barcode with the above format - it must use the pipe character (`|`) and space character () when drawing bars, and there should be 1 space in between each upright bar.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest program (in bytes) wins!
---
# Test Cases
**4095:**
```
|   | | | | | | |  
| | | | | | | | | |
    | | | | | |    
```
**4096:**
```
|   |             |  
| | | | | | | | | | |
```
**7313145:**
```
|   |   | |   | |   | |   | |  
| | | | | | | | | | | | | | | |
      | | | |     | | | |      
```
  
[Answer]
# [Python 3](https://docs.python.org/3/), ~~103~~ ~~99~~ 96 bytes
```
def f(i,r=[]):
 while i:r=[' | |||||  ||'[i%4::4]]+r;i//=4
 k='|| ',' | ';[*map(print,*k,*r,*k)]
```
[Try it online!](https://tio.run/##K6gsycjPM/7/PyU1TSFNI1OnyDY6VtOKS6E8IzMnVSHTCshXV6hRqAEBBSClHp2pamJlZRIbq11knamvb2vCpZBtqw6UVNcBKVS3jtbKTSzQKCjKzCvR0crW0SoCkpqx/9M0DC3NjIw1/wMA "Python 3 – Try It Online")
[Answer]
# [MATL](https://github.com/lmendo/MATL), ~~34~~ ~~30~~ ~~29~~ 28 bytes
```
TFiK_YAyhhH&\EQE+t~vB!P'|'*c
```
[Try it online!](https://tio.run/##y00syfn/P8Qt0zs@0rEyI8NDLcZbS9tDu6SuzEkxQL1GXSv5/39DSzMjYwA)
### Explanation
```
TF      % Push array [1 0] (start sequence)
i       % Push input
K_YA    % Convert to base 4. Gives an array of 4-ary digits
y       % Duplicate from below: pushes [1 0] again (stop sequence)
hh      % Concatenate horizontally twice. Gives array of 4-ary digits
        % including start and stop sequences
H&\     % Two-output modulo 2: pushes array with remainders and array
        % with quotients of dividing by 2
EQE     % Times 2, plus 1, times 2, element-wise. This effectively
        % multiplies each entry by 4 and adds 2
+       % Add element-wise to the array of remainders. The stack now 
        % contains an array of numbers 2, 3, 6 or 7. Each number
        % encodes, in binary form, a column of the output. The
        % previous multiplication of the quotients by 4 will have the
        % effect of shifting one row down (one binary digit upwards),
        % to make room for the central row. The addition of 2 will
        % create the central row, which is always full
t~      % Duplicate, logical negate. Gives an array of zeros of the
        % same length
v       % Concatenate vertically into a 2-row matrix
B       % Convert to binary. Gives a matrix, where each row is the
        % binary representation of one of the numbers of the input
        % matrix, read in column-major order
!P      % Transpose, flip vertically
'|'*    % Multiply by '|'. This transforms 1 into 124 (ASCII code of
        % '|') and leaves 0 as is
c       % Convert to char. Char 0 is shown as space. Implicitly display
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~16~~ 15 bytes
```
4;jƓb|ṃ⁾| ẎZṙ2G
```
[Try it online!](https://tio.run/##ASgA1/9qZWxsef//NDtqxpNifOG5g@KBvnwg4bqOWuG5mTJH//83MzEzMTQ1 "Jelly – Try It Online")
### How it works
```
4;jƓb|ṃ⁾| ẎZṙ2G  Main link. No arguments.
4                Set the argument and the return value to 4.
 ;               Concatenate the return value with the argument, yielding [4, 4].
   Ɠ             Read an integer n from STDIN.
  j              Join, yielding [4, n, 4].
    b            Convert 4, n, and 4 to base 4. Note that 4 is [1, 0] in base 4.
     |           Perform bitwise OR of each resulting quaternary digit and 4.
                 This pads the binary representation of a digit d to three digits: 
                 [1, d:2, d%2]
      ṃ⁾|        Convert the results to base " |", i.e., binary where ' '
                 represents 0 and '|' represents 1.
          Ẏ      Concatenate the resulting arrays that correspond to 4, n, and 4.
           Z     Zip; transpose rows and columns.
            ṙ2   Rotate 2 units yo the left, correcting the order of [1, d:2, d%2]
                 to [d%2, 1, d:2].
              G  Grid; separate columns by spaces, rows by linefeeds.
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 19 bytes
```
;4⁺;b4Fd2Uj€1Zị⁾| G
```
[Try it online!](https://tio.run/##y0rNyan8/9/a5FHjLuskE7cUo9CsR01rDKMe7u5@1LivRsH9////hpZmRsYA "Jelly – Try It Online")
-1 thanks to [Mr. Xcoder](https://codegolf.stackexchange.com/users/59487/mr-xcoder).
[Answer]
# [Octave](https://www.gnu.org/software/octave/), ~~78 77 75 74 70~~ 69 bytes
```
@(x)' |'(dec2bin([2 6 3 7;~(1:4)](:,[2 1 dec2base(x,4)-47 2 1]))-47)'
```
[Try it online!](https://tio.run/##y08uSSxL/Z9mq6en999Bo0JTXaFGXSMlNdkoKTNPI9pIwUzBWMHcuk7D0MpEM1bDSgcoZKgAlk8sTtWo0DHR1DUxVwAKxmqCWJrq/9M0DC3NjIw1udI0TAwsTaG0GYg2NzY0NjQx1fwPAA "Octave – Try It Online")
Unlike the original approach, this one uses a simple lookup table to map the base-4 values onto their binary equivalent. The lookup table also adds the spacing between each bar by adding a zero in between each number (which maps to a bar of all spaces).
The lookup table directly maps to bars as:
```
   base4:  0 1 2 3 -
  lookup:  2 6 3 7 0
  binary:  0 1 0 1 0
           1 1 1 1 0
           0 0 1 1 0
```
Conversion from binary to `|` and  is now done by indexing into a string of those two characters - basically the same principle as the lookup table for binary conversion.
---
\*Saved 1 byte, thanks @LuisMendo
---
### Original:
```
@(x)['' circshift(dec2bin([a=[5 4 dec2base(x,4)-44 5 4];a*0](:))'*92,1)-4384]
```
[Try it online!](https://tio.run/##HcjRCkAwFADQX9nb7hWLuWSk/Mfaw8yWvVBI/n7k8ZzdXfb2KYxCiDTBg5pz5uLhzjWGCxbv5Bw30HbUDSP2254enpywIGJfmsFmpYEekWdK5tX3dUcmBahUK2tMLw "Octave – Try It Online")
Anonymous function which returns the barcode as a string.
This is based on the fact that if we add 4 to the base4 digits, then we can represent bar/space by the number converted to binary with bits 1 and 2 swapped:
```
   base4:  0 1 2 3
    add4:  4 5 6 7
  binary:  0 1 0 1
           0 0 1 1
           1 1 1 1
swap 2/1:  0 1 0 1
           1 1 1 1
           0 0 1 1
```
The tricky bit from a golfing perspective is adding the spaces between the bars and converting from `0/1` to `'|'/' '`.
[Answer]
# JavaScript (ES6), ~~89~~ ~~87~~ 83 bytes
```
n=>`|  ${(g=(a,k=n)=>k?g(a,k>>2)+(k&a?'| ':'  '):' ')(1)}|
| |${g(~0)}| |
   `+g(2)
```
### Test cases
```
let f =
n=>`|  ${(g=(a,k=n)=>k?g(a,k>>2)+(k&a?'| ':'  '):' ')(1)}|
| |${g(~0)}| |
   `+g(2)
console.log(f(4095))
console.log(f(4096))
console.log(f(7313145))
```
### How?
*NB*: In the version below, [template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) have been replaced with standard strings so that the code can be indented properly.
```
n =>                        // given the input n
  '|  ' +                   // append the top leading pattern
  (g = (a,                  // g is a recursive function taking a = mask
           k = n) =>        // and using k = value, initially set to n
    k ?                     //   if k is not zero:
      g(a, k >> 2) +        //     do a recursive call for the next group of 2 bits
      (k & a ? '| ' : '  ') //     append '| ' if the bit is set or '  ' otherwise
    :                       //   else:
      ' '                   //     append an extra leading space and stop the recursion
  )(1) +                    // invoke g() with mask = 0b01
  '|\n' +                   // append the top leading pattern and a linefeed
  '| |' +                   // append the middle leading pattern
  g(~0) +                   // invoke g() with all bits set in the mask
  '| |\n' +                 // append the middle trailing pattern and a linefeed
  '   ' +                   // append the bottom leading pattern
  g(2)                      // invoke g() with mask = 0b10
```
[Answer]
# [R](https://www.r-project.org/), ~~154~~ 109 bytes
```
function(n,d=c(1,0,n%/%4^floor(log(n,4):0)%%4,1,0),o=c(" ","|"))cat("",o[1+d%%2],"
",o[2+0*d],"
",o[1+(d>1)])
```
[Try it online!](https://tio.run/##NcrBCsIwDIDhu08xAoHERmy2iiCbLyITpKUijAbGvPnutR48/nz/WnM3Hmp@l7i9rFCRNEVS8VLwiOGeF7OVFns2CXzxjBikMYu1DzoQ@ABzfGwEIHZTlxD7WWD3q975ffqHOkpX5ZlrpvOgg4YT1y8 "R – Try It Online")
Saved a whole bunch of bytes by indexing and using `cat` rather than constructing a matrix and using `write`, as well as 6 from a slightly different conversion to base 4. Prints with a leading space in each row and no trailing newlines.
The indexing takes place using some modular arithmetic, not unlike some other answers, but since R uses 1-based indexing, the arithmetic is somewhat different.
Explanation:
```
function(n,
 d=c(1,0,                         # d contains the padding and 
   n%/%4^floor(log(n,4):0)%%4,   # the base 4 digits
   1,0),                         # 
 o=c("|"," ")                    # the vector to index into
 cat("",                         # cat separates things with spaces by default
                                 # so the empty string will print a leading space
  o[1+d%%2],"                    # odds have a | above
",                               # literal newline, a space will follow it (hence leading spaces)
 o[2+0*d],"                      # array of 2s since the middle is always |
",                               # another literal newline
 o[1+(d>1)])                     # digits greater than 1 have a | below
```
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 50 bytes
```
ＮθＦ²⊞υι¿θＷθ«⊞υ﹪θ⁴≧÷⁴θ»⊞υθＦ²⊞υιＥ⟦ |¦|¦  ||⟧⪫Ｅ⮌υ§ιλω
```
[Try it online!](https://tio.run/##dY47C8JAEIRr8yuWVHtwFr6wsBJsIihiKxbRrGbhvNN7RMH4288zoJ3NsrPfMLPHurRHU6oYC30Nfh0uB7J4E7PsZCzgUMAmuBqDBE43PkFicK9ZUbc9s96Xr0wVlMGbhLFI1t6qvM6d47Pe8rn2WGi/4IYrSlzCp@CVkXL0y//XubGsPaY03OXQ5hLybgC0bb6XsDSsO7qlhqwjDELC3Be6ogeyBCWSvqePYpyOBqPBeBL7jXoD "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
Ｎθ
```
Input a number.
```
Ｆ²⊞υι
```
Push the stop sequence to the predefined empty list.
```
¿θ
```
If the number is positive,
```
  Ｗθ«⊞υ﹪θ⁴≧÷⁴θ»
```
repeatedly apply divmod to convert it to reversed base 4,
```
  ⊞υθ
```
otherwise just push it.
```
Ｆ²⊞υι
```
Push the start sequence to the list.
```
Ｅ⟦ |¦|¦  ||⟧
```
Map over three strings. Each string represents barcode translation for the digits `0123` for each row.
```
⪫Ｅ⮌υ§ιλω
```
Map over the digits (reversed back into usual order), convert them to bars or spaces using the translation, then join the results into three strings which are then implicitly printed on separate lines.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), ~~32~~ 31 bytes
```
A¤i2Us4)¬®n s|iS)ù2 w i|1ÃqR² y
```
[Test it online!](https://ethproductions.github.io/japt/?v=1.4.5&code=QaRpMlVzNCmsrm4gc3xpUyn5MiB3IGl8McNxUrIgeQ==&input=MTk2MjM=)
Not really satisfied with this yet, but it's a start...
### Explanation
```
A¤  i2Us4)¬ ®   n s |iS)ù2 w i |1Ã qR²  y
As2 i2Us4)q mZ{Zn s'|iS)ù2 w i'|1} qRp2 y
                                           Implicit: U = input, A = 10, R = newline, S = space
As2                                        Convert 10 to a binary string.
    i2   )                                 At index 2, insert
      Us4                                    the input converted to base 4.
          q                                Split into chars.
            mZ{                  }         Map each char Z to
               Zn                            Z converted to a number,
                  s'|iS)                     converted to base " |" (binary using ' ' as 0 and '|' as 1),
                        ù2                   left-padded to length 2 with spaces,
                           w                 reversed,
                             i'|1            with another pipe inserted at index 1.
                                   q       Join the resulting list on
                                    Rp2      a newline repeated twice (adds in blank columns).
                                        y  Transpose the entire string.
                                           Implicit: output result of last expression
```
[Answer]
# [Haskell](https://www.haskell.org/), ~~91~~ 90 bytes
```
h s=[do a<-4%s++0%0;x!!a:" "|x<-[" | |","||||","  ||"]]
_%0=[1,0]
b%n=b%div n b++[mod n b]
```
[Try it online!](https://tio.run/##bYxRC4IwAITf9yvO0Z7UmBVB5X7JkJhtoKQTnIXQ@u1rifTUHcd3D8c1yt1N14XQwAmpB6gyPzCXppzxy5wk6kxB/VzmksLD04z6qAggoqrIlXEhi4xXpGZW1Ey3T1jUaSr7QX9bFXrVWgi0djKjuk3Y4GG71hqHLZqY0ShNXjnxiKdrsNAvnXj8N8FviXXrSf4Oxem4238A "Haskell – Try It Online") Returns a list of lines.
---
Same byte count alternative for first line:
```
h s=[do a<-4%s++0%0;" | |  ||||"!!(x+a):" "|x<-[0,6,4]]
```
[Answer]
# [J](http://jsoftware.com/), 57 49 47 bytes
10 bytes thanks to FrownyFrog!
```
[:,.2{."0[:|:' |'{~#:@2 6 3 7{~1 0,4&#.inv,1,0:
```
How it works:
`1 0,4&#.inv,1,0:` - converts the number to a list of base-4 digits, adds 1 0 to the beginning and the end of the list
`((#:2 6 3 7){' |')` - lookup table for the encryption, binary 0 corresponds to space, 1 to '|'
`{~` - encrypts the base 4 digit by selecting a string from the lookup table above (argument reversed)
`|:` - transposes the resulting array from 3 columns to 3 rows
`[:` - caps the fork
`,.2{."0` - puts spaces between the bars 
[Try it online!](https://tio.run/##DcNBCoAgEAXQvaf4FCTBMKhF0UDQPVxGUi1qEbTRurr14O05XKPA4J@9ELvIhfGSRCPp@JYyOXRo0MfXwlBblbwdN1kykmtVMHQYWYPwCMKl1DKvJwLs0Lkmfw "J – Try It Online")
[Answer]
# APL+WIN, 63 bytes
```
(⍉5 3⍴' | ||  |||||   ')[;,⍉(2 1,(1+((⌈4⍟n)⍴4)⊤n←⎕),2 1),[.1]5]
```
Explanation:
```
(⍉5 3⍴' | ||  |||||   ') create a matrix where columns represent bars plus one for separator spaces
(1+((⌈4⍟n)⍴4)⊤n←⎕) prompt for screen input and convert to base 4 and add 1 to convert to index origin 1
2 1,...,2 1 concatenate start stop
,[.1]5 concatenate separator space indices
(.....)[.....] index into bar matrix to display
```
[Answer]
# [Python 2](https://docs.python.org/2/), ~~116~~ 114 bytes
-2 bytes thanks to notjagan
```
c=a=0,1
n=input()
while n:c+=n%4,;n/=4
for l in zip(*[' |'[n%2]+'|'+' |'[n/2]for n in c+a][::-1]):print' '.join(l)
```
[Try it online!](https://tio.run/##JcrRCsIgFADQd7/ivgw1V0s3ggy/RHwYUuyGXGUYUezfjdHjgVM@dclkWotududeM3JI5VWFZO8F0x3IRuWom/obDW5ij7xCAiT4YhEHz2HjnjoTFN@4@mswYV@0r6jm4K096iBtWZEqB356ZiSRZGv6ejHjDw "Python 2 – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 19 bytes
```
4BT.øS4~bT„| ‡øÁ€S»
```
[Try it online!](https://tio.run/##AS4A0f8wNWFiMWX//zRCVC7DuFM0fmJU4oCefCDigKHDuMOB4oKsU8K7//83MzEzMTQ1 "05AB1E – Try It Online")
This is a half-port of Dennis' approach, which is just one byte shorter than the method I used before (which I am quite happy with):
# [05AB1E](https://github.com/Adriandmen/05AB1E), 20 bytes
```
4BT.øS2‰í1ýøT„| ‡€S»
```
[Try it online!](https://tio.run/##ATAAz/8wNWFiMWX//zRCVC7DuFMy4oCww60xw73DuFTigJ58IOKAoeKCrFPCu///MTk2MjM "05AB1E – Try It Online")
### How it works?
```
4BT.øS2‰í1ýøT„| ‡€S»  | Full program. Takes input from STDIN, outputs to STDOUT.
4B                    | Convert to base 4.
  T                   | Push a 10 to the stack.
   .ø                 | Surrond (prepend and append the 10 to the base 4 representation).
     S                | Split into individual characters/digits.
                      +---------------------------------------------------------------
                      | This part used to be ¸4.ø4в˜ in the previous version, which
                      | means: surround with 4's, convert each to base 4 (4 -> [1, 0])
                      | and finally deep-flatten the list.
                      +---------------------------------------------------------------
      2‰              | Divmod 2 ([N // 2, N % 2]).
        í             | Reverse (element-wise).
         1ý           | Add a 1 in the middle (element-wise).
           ø          | Transpose.
            T„| ‡     | Translate (‡) from "10" (T) to "| " („| ).
                 €S»  | Format as a grid.
                 €S   | Push the characters of each.
                   »  | Join by newlines, while joining inner lists by spaces.
```
I have asked [Adnan](https://codegolf.stackexchange.com/users/34388/adnan) (the creator of 05AB1E) about the grid thingy in [chat](https://chat.stackexchange.com/transcript/message/41494031#41494031), and they helped me save 2 bytes, by pointing out a feature of 05AB1E: when joining multi-dimenisional lists by newlines, the inner lists are joined using spaces too, so `ðý` is unnecessary.
[Answer]
# [APL (Dyalog Classic)](https://www.dyalog.com/), 33 bytes
```
' |'[≠\2/2⊖1⍪2 2⊤1 0(,,⊣)4⊥⍣¯1⊢⎕]
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT9dNzkksLs5M/v@ob2pm/qO2CQZcjzra0/6rK9SoRz/qXBBjpG/0qGua4aPeVUYKQNYSQwUDDR2dR12LNU0edS191Lv40HrDR12LgNpj/wN1/k/jMjGwNOVSV@cCs8wgLHNjQ2NDE1MA "APL (Dyalog Classic) – Try It Online")
[Answer]
# [J](http://jsoftware.com/), ~~42 40~~ 39 bytes
```
' |'{~[:#:4#.2|.0|:4#:@+1 0(,,[)4#.inv]
```
Shaved 2 bytes thanks to Dennis. 1 byte thanks to ngn.
[Try it online!](https://tio.run/##y/r/P81WT0FdoUa9ui7aStnKRFnPqEbPoAbIsHLQNlQw0NDRidYEimbmlcX@T03OyFdIUzC0NDMy5oJyTAwszWBsc2NDY0MT0/8A)
### How it works
```
                                4#.inv]      to base 4
                        1 0(,,[)             append (1 0) on both sides
                   4#:@+                     add 4 to each digit and convert to binary
                0|:                          transpose
             2|.                             rotate the rows
      [:#:4#.             from base 4 to base 2, it's supposed to separate the columns
' |'{~                                       to characters
```
[Answer]
# JavaScript (ES6) 79 bytes
Uses .toString to convert the number to base 4, and then casework with each line and bitwise OR to build the output line by line. Outputs a list of lines.
```
n=>[2,3,1].map(d=>[...'10'+n.toString(4)+'10'].map(q=>(q|d)>2?"|":" ").join` `)
```
```
f = n=>[2,3,1].map(d=>[...'10'+n.toString(4)+'10'].map(q=>(q|d)>2?"|":" ").join` `)
console.log(f(19623))
console.log(f(4095))
console.log(f(4096))
console.log(f(7313145))
```
[Answer]
# [Bash](https://www.gnu.org/software/bash/)+coreutils, 71 67 bytes
```
dc -e4ddon?np|sed 's/./& /g;h;y/01/23/;G;y/12/21/;H;x;y/0123/ | |/'
```
[Try it online!](https://tio.run/##S0oszvj/PyVZQTfVJCUlP88@r6CmODVFQb1YX09fTUE/3TrDulLfwFDfyFjf2h3INDTSNzLUt/awrgCLA4UVahRq9NX//ze0NDMyBgA "Bash – Try It Online")
# Explanation
The `dc` bit converts to base 4, prepending and appending with a `4` (turns into `10` in the output) and using `n` to keep everything on one line.
The rest happens in `sed`:
```
s/./& /g;     Add a space after each digit
h;            Make a copy in hold space
y/01/23/;     Prepare up the second row (2/3 will turn to pipes)
G;y/12/21/;   Append what will be the third row and prep it (1/3 will turn to pipes)
H;x;          Prepend hold space
y/0123/ | |/  Make 1 and 3 pipes, 0 and 2 spaces
         
```
[Answer]
# [Retina](https://github.com/m-ender/retina), 83 bytes
```
.+
$*
+`(1+)\1{3}
${1};
^
1;;
$
;1;;
1*;
$.&
.+
$&¶$&¶$&
T`13` `^.+
T`12` `.+$
\d
|
```
[Try it online!](https://tio.run/##K0otycxL/K@q4Z7wX0@bS0WLSztBw1BbM8aw2riWS6XasNaaK47L0NqaS4XLGkQZagGZempcIMVqh7ZBMFdIgqFxgkJCHFAUyDQCMvW0VbhiUrhq/v83tDQzMuYyMbA0BRFmAA "Retina – Try It Online") Link includes the faster test cases. Explanation:
```
.+
$*
```
Convert to unary.
```
+`(1+)\1{3}
${1};
```
Convert to base 4 as unary numbers separated by `;`s.
```
^
1;;
```
Prepend the start sequence.
```
$
;1;;
```
Append a `;`, turning it into a digit terminator rather than a separator, and the stop sequence.
```
1*;
$.&
```
Convert to decimal, but adding 1 to each digit.
```
.+
$&¶$&¶$&
```
Triplicate it.
```
T`13` `^.+
```
On the first row, `1`s and `3`s (representing `0`s and `2`s) become spaces.
```
T`12` `.+$
```
On the last row, `1`s and `2`s (representing `0`s and `1`s) become spaces.
```
\d
|
```
All other digits become bars.
[Answer]
# [Pip](https://github.com/dloscutoff/pip), ~~33~~ ~~31~~ ~~29~~ ~~27~~ 26 bytes
25 bytes of code, +1 for `-S` flag.
```
Y^aTB4WRt" |"@[y%2oMyy/2]
```
[Try it online!](https://tio.run/##K8gs@P8/Mi4xxMkkPKhESaFGySG6UtUo37eyUt8o9v///7rB/82NDY0NTUwB "Pip – Try It Online")
### Explanation
We observe a pattern in the four bar types:
* The first row is a space if the digit is even, pipe if odd.
* The second row is always a pipe.
* The third row is a space if the digit is 0 or 1, pipe if 2 or 3.
So:
```
                           a is cmdline arg; o is 1; t is 10 (implicit)
  aTB4                     Convert a to base 4
      WRt                  Wrap it before and after with 10
 ^                         Split into a list of digits
Y                          and yank into y
              [         ]  List of:
               y%2          0 if even, 1 if odd for each item in y
                  oMy       1 mapped to y, i.e. constant 1 for each item in y
                     y/2    Each item in y divided by 2 (0, 0.5, 1, or 1.5)
         " |"@             Use the elements of that list as indices into this string
                           Note that indices are truncated to integers!
                           Autoprint, separating rows with newline and elements of
                           each row with space (-S flag)
```
[Answer]
# [SOGL V0.12](https://github.com/dzaima/SOGL), 28 [bytes](https://github.com/dzaima/SOGL/blob/master/chartable.md)
```
4─10¹:h++{»1F2%¹{Ƨ| W}¹∑ā}⁰H
```
[Try it Here!](https://dzaima.github.io/SOGLOnline/?code=NCV1MjUwMDEwJUI5JTNBaCsrJTdCJUJCMUYyJTI1JUI5JTdCJXUwMUE3JTdDJTIwVyU3RCVCOSV1MjIxMSV1MDEwMSU3RCV1MjA3MEg_,inputs=NzMxMzE0NQ__)
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 176 bytes
```
#include<stdio.h>
int n,m;f(n,r){if(n)f(n>>2);printf("%c%c",n?32:10,(n&r||!r)&&n?'|':32);}main(){scanf("%d",&n);m=(n+(4<<(32-__builtin_clz(n)/2*2)))*16+4;f(m,1);f(m,0);f(m,2);}
```
[Try it online!](https://tio.run/##JY1LDoIwFEXnrkIxlD4oSlvUBBCXQrCINoGnKTARXDsWHdycwf2p8K7UPG81qmaoblnXV/q5e@Qrjf0aWZvWFJmBUVuCVZ4LSF/GujV1XOUqh@FFioRHjCIx07QxQAhevMlLpI1@2lIjhbFTJS6NymEEIW3PFAMaZxmVIiyK66CbXmOhmre92QtfAIDPj0Fs/1vG4Yfoj2V1nk@SSx4fvg "C (gcc) – Try It Online")
Slightly less terribly formatted (less golfed):
```
#include<stdio.h>
int n,m;
f(n,r) {
    if(n)
        f(n>>2);
    printf("%c%c",n?32:10,(n&r||!r)&&n?'|':32);
}
main() {
    scanf("%d",&n);
    m=(n+(4<<2*(16-__builtin_clz(n)/2)))*16+4;
    f(m,1);
    f(m,0);
    f(m,2);
}
```
## Explanation
First, consider the following code to read an integer and output the base 4 version: 
```
#include <stdio.h>
int n;
f(n) {if(n)printf("%d\n",n&3,f(n>>2));}
main(){scanf("%d",&n);f(n);}
```
This uses tail recursion to reverse the order of the output. Each recursive step bitshifts by 2 (lops off the last 2 bits and divides by 4). It outputs the result bitmasked with 3 (0b11), which only shows the last two bits, which is the last digit base 4. 
The function call is included in the `printf` as a trailing argument (it isn't printed, but it is evaluated) to avoid needing to use {} (+2 bytes) to group the `printf` and the function call. 
The solution here extends this base-4 code. First, m is defined as n, but such that in base 4 it will have 10 prepended and appended to it. We then print m.
In printing base 4 regularly, we used a bitmask of 3 to get the digit. In the mail code, the top line is that digit's low-order bit (a bitmask of 1) and the bottom line is the high order bit (a bitmask of 2). Accordingly, the `r` in `f(n,r)` is the bitmask - our main function calls `f(m,1)` for the first line and `f(m,2)` for the last line.
To make the middle line work (always print "|"), we add `||!r` to the conditional - if r is 0, it will always evaluate to true and print a "|". Then we call `f(m,0)` for the middle line. 
Finally, we want newlines to behave. Including an extra `printf` is expensive as far as bytes of source code goes, so instead we add another %c specifier to the existing `printf`. `n?32:10` prints a newline if n is 0 (false), and a space otherwise. 32 and 10 are used instead of '\n' and ' ' to save bytes. 
[Answer]
# Common Lisp, 191 bytes
```
(lambda(n &aux(k`(1 0,@((lambda(n &aux r f)(do()((= n 0)f)(setf(values n r)(floor n 4))(push r f)))n)1 0)))(format t"~3{~{~:[  ~;| ~]~}~%~}"`(,(mapcar'oddp k),k,(mapcar(lambda(c)(> c 1))k))))
```
[Try it online!](https://tio.run/##VY7dCoJAFIRf5SBUc8ALJbuoKHqPCNxWl8KflV2NwDyvbkvgRVcz88EMo@un72bMqFVzLxRaWqvhjSpHSkl8wT8nR4ZRWDBwopYSDtGXvcFL1UPpA3IMU1vrgs2Y0Q3@8Wsxtxwmg8JY16ie@ki2o4xyuBLJ8UNyk0lWMkU5YjSq08ptbFF0VHFcLWT5oxln0pQyV2GS5yzZ73j@Ag)
[Answer]
# PHP, 99+1 bytes
```
for($n=10 .base_convert($argn,10,4). 104;(~$c=$n[$i++])||3>$y+=$i=1;)echo" | ||  |||||
"[$c*3+$y];
```
requires PHP >= 5.5 for literal string indexing and < 7.1 for the indexing to not yield a warning.
Run as pipe with `-nR` or [try it online](http://sandbox.onlinephpfunctions.com/code/64c726c8d339340ae88c07c24b517553dce9feb3).
Insert one more newline to get a trailing one.
[Answer]
# Python 2, 142 126 bytes
```
B=lambda n:n<4and`n`or B(n/4)+`n%4`
def F(i):
 for r in 0,1,2:print' '.join(" |"[(int(x)%2,1,x>'1')[r]]for x in'10'+B(i)+'10') 
```
Big thanks to ovs!
I tried to not copy the other answers' methods and... yuck.
[Answer]
# [C# (.NET Core)](https://www.microsoft.com/net/core/platform), 160 bytes
```
i=>{string s=$"10{B(i)}10",a="";for(int y=0;y<3;y++,a+="\n")foreach(var t in s)a+=t<51&y!=1&t-(y>>1)!=49?"  ":"| ";return a;string B(int n)=>n>0?B(n/4)+n%4:"";}
```
[Try it online!](https://tio.run/##jY9BS8MwGIbP9ld8CzoS2mlDO2VL00GFnRSEHbx4CVnUwPwCSTootb@9ljkvnnZ@Ht6HV4eFdt6MbbD4AbsuRPMlEn1QIcBLn4SootWwbVFXFmMGIfpJrGHrWr@boGmU125vQMJoZd3/cgjymvC8b6hlA89JpiQh4t15Oo1AJ3PRVYXo0jRTqSRvSNjEjNKf9Kg8RLAIgU0oVks@72aSz@OCdnXN2UyWqw0BIGvyDUR4E1uPoMS525wCyGSNdb5pKN6VLMWbcj3lh1Ekf4eOzu7hWVmkLOmTq0eHwR3M7au30TxZNPT/P1rmqyVj4lL3/lL3oeAFL0/TQzKMPw "C# (.NET Core) – Try It Online")
I'm sure I've missed some improvements.
### DeGolfed
```
i=>{
    string s = $"10{B(i)}10", // prepend and append 10 to the base 4 number
           a="";
    for (int y=0; y<3; y++, a+="\n") // go through each row
        foreach (var t in s)         // go through each char digit
            a += t<51 & y != 1 & t-(y>>1) != 49 ? "  " : "| "; // check if bar or space occurs
    return a;
    string B(int n) => n>0? B(n/4) + n%4 : ""; // convert int to base 4
}
```
`t<51 & y != 1 & t-(y>>1) != 49` checks that the char isn't '3', not the second row, and then some binary magic to see if the first or third row should contain the space.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 42 bytes
```
s4 +A iA)d1"|| "0" | "2" ||"3'|³ ò3 miR ·y
```
[Try it online!](https://tio.run/##y0osKPn/v9hEQdtRIdNRM8VQqaZGQclASQFIGgHJGiVj9ZpDmxUObzJWyM0MUji0vfL/f0NLMyNjAA "Japt – Try It Online")
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 32 bytes
```
jjL;CmXX1jk_d1`T"| ".DR2sj[4Q4)4
```
**[Try it here!](https://pyth.herokuapp.com/?code=jjL%3BCmXX1jk_d1%60T%22%7C+%22.DR2sj%5B4Q4%294&input=19623&debug=0)**
[Answer]
# C, 120 bytes
Sadly only works on Windows, since `itoa` is too much of a convenience to be standard.
```
char*p,s[21]="10";g(a){for(p=s;*p;)printf(!a|*p++&a?" |":"  ");puts(p);}f(n){strcat(itoa(n,s+2,4),"10");g(1);g(0);g(2);}
```
[Answer]
# [APL (Dyalog)](https://www.dyalog.com/), 50 bytes
```
{↑,/(' |',¨' ')[⍉↑¯1⌽¨(3⍴2)∘⊤¨4+1 0,1 0,⍨4⊥⍣¯1⊢⍵]}
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///qG@qp/@jtgkG/9OAZPWjtok6@hrqCjXqOodWqCuoa0Y/6u0ECh5ab/ioZ@@hFRrGj3q3GGk@6pjxqGvJoRUm2oYKBjog/Kh3hcmjrqWPeheDlHYtetS7Nbb2//80BXNjQ2NDE1MA "APL (Dyalog Unicode) – Try It Online")
]