[Question]
  [
Your task is to take a sequence of characters (the music) as input (in a function or program), and print (or return) the music as it would look like in a music box.
You will only receive the characters `ABCDEFG.()` as input, and the input will never be empty. You may also receive the letters in lowercase, if you wish for it.
This is an empty music box, of length 3:
```
.......
.......
.......
```
As you can see, the lines are 7 characters long, and since the length of the music box is 3, we have 3 lines. There are only `.`s here, since the music box is empty. Let's put some music in it!
First, we create the music box. In this example, the input will be `CDAG.DAG`.
The length of `CDAG.DAG` is 8, so we need a music box of length 8:
```
.......
.......
.......
.......
.......
.......
.......
.......
```
Then, we read the input, one character at a time, and place an `O` at its respective position.
The first character is `C`, and the location of each note is equivalent to this (I added spaces for clarity):
```
 A B C D E F G
 . . . . . . .
 . . . . . . .
 (and so on)
```
If the input character is a `.`, then we just print an empty line `.......`
So, the `C` would be the 3rd character along. Let's put it in our music box at the top:
```
..O....
.......
.......
.......
.......
.......
.......
.......
```
We will repeat this process for all the other characters (the text in brackets is just to show you the note, you shouldn't output that):
```
..O.... (C)
...O... (D)
O...... (A)
......O (G)
....... (.)
...O... (D)
O...... (A)
......O (G)
```
Because of how music boxes work, if we use a character other than `O`, `.` and `<insert newline here>`, such as a space, in our output, then it won't play the correct music!
This is a chord:
```
(ACE)
```
This chord is instructing us to play the notes `A`, `C` and `E` at the same time. There will never be a pause (ie a `.`) in a chord.
This is how it would be written:
```
O.O.O...
```
And this is how it might appear in music: `B(ACE)D`
You will never receive a chord in a chord, ie this won't be valid: `(AB(CD)EF)` or this: `A(B())`, and chord will not be empty, ie this won't be valid: `A()B`
You will never receive an invalid input.
### Examples:
```
B(ACE)D
.O.....
O.O.O..
...O...
B
.O.....
GGABC
......O
......O
O......
.O.....
..O....
...
.......
.......
.......
A..F.C(DA).
O......
.......
.......
.....O.
.......
..O....
O..O...
.......
.(ABCDEF)
.......
OOOOOO.
```
Trailing/leading whitespace on the output is permitted.
As this is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), the shortest code wins!
  
[Answer]
# [Python 2](https://docs.python.org/2/), ~~95~~ 94 bytes
-1 byte thanks to Value Ink
```
x=1
for i in input():
 if x:o=['.']*7
 if'@'<i:o[ord(i)-65]='O'
 if'*'>i:x=i>'('
 if x:print o
```
[Try it online!](https://tio.run/nexus/python2#@19ha8iVll@kkKmQmQdEBaUlGppWXAqZaQoVVvm20ep66rFa5iC@uoO6TaZVfnR@UYpGpqaumWmsrbq/OlhGS90u06rCNtNOXUMdqrWgKDOvRCH//391Jw1HZ1dNF/X/AA "Python 2 – TIO Nexus") or [Try all test cases](https://tio.run/nexus/python2#VY47CsMwDED3nEKb7JAKOrQFU4c637EHSLOlBi12MCnk9q6T0KGDJPQe@sTpbcEKdvNnkSqDVZ8zsD4AAzvYcaLAFlbl9YCEY37bAT7wzsoPPkyC5el6GTU@8VA5lqxWzSUK/E3Pgd0CPv4vF9vRQ@HLYcHZ9o2MA1bC1K1ssMAqRd@bqk6ViFI2RB3VojFy60gk17SdxDF@AQ "Python 2 – TIO Nexus")
### Explanation
`'@'<i` is to check if `i` is a letter, replacing the `.` by `O` on the right position.  
`'*'>i` is to check if `i` is a parenthesis, if it is `x=i>'('` will put `0` on `x` to prevent the printing/clearing of `o`, when `i==')'`, it will put `1` on `x` re-enabling the printing/clearing of `o`.  
When `i=='.'` nothing will be changed, and `'.......'` will be printed.  
The charater order is given by their ASCII code, where `'('<')'<'*'<'.'<'@'<'A'`
[Answer]
## Batch, 209 bytes
```
@set s=%1
@set p=)
@for %%n in (a b c d e f g)do @set %%n=.
:g
@if %s:~,1% lss @ (set "p=%s:~,1%")else set %s:~,1%=O
@set s=%s:~1%
@if %p%==( goto g
@echo %a%%b%%c%%d%%e%%f%%g%
@if not "%s%"=="" %0 %s%
```
Works by accumulating letters and outputting the line if the last symbol seen was not a `(`.
[Answer]
# [Röda](https://github.com/fergusq/roda), ~~97~~ ~~78~~ 76 bytes
```
{search`\(\w+\)|.`|{|c|seq 65,71|{|l|["O"]if[chr(l)in c]else["."]}_;["
"]}_}
```
[Try it online!](https://tio.run/nexus/roda#VYq7DoJAFERr@IqbW@0q3sRCLYgF79IPWIiQdTeQIChoLFi@HYHYWM2cOXMvqmawLX1Op6FXRSfLPGXpZ5tyQ7kZjDS9esLx4Jz2M9VG4AWzSgtZdqzmVQMyU3WvBBJm49UVaC85TpZAn3lBxEN0AJPE84OlENESHlFMAQs9viKxWYdRnHDMwMAAj65qXiDbm3J/HXe4Oc3w7st1n2/6z8EIuu1WZ4/TFw "Röda – TIO Nexus")
It's an anonymous function that reads the input from the stream. Use it like this: `main { f={...}; push("ABCD") | f() }`. It uses the regex from ETHproductions' answer.
Ungolfed:
```
{
    search(`\(\w+\)|.`) | for chord do
        seq(ord("A"), ord("G")) | for note do
            if [ chr(note) in chord ] do
                push("O")
            else
                push(".")
            done
        done
        push("\n")
    done
}
```
Previous answer:
```
f s{(s/"(?=([^()]*(\\([^()]*\\))?)*$)")|{|c|seq 65,71|{|l|["O"]if[chr(l)in c]else["."]}_;["
"]}_}
```
[Try it online!](https://tio.run/nexus/roda#ZYm7DoJAEEVr@YrJxGKG4BoLpSCG8C79gGU1BiGSICjYsXw7AqGzOufcOxbQ9dTtkdwzySuxMilNV0tTZpfNLSPrXme6yz9wOlr2YapKS7ygKguZPVuquKwhU3nV5RIFquHmSDRmDuPrPn29sZHokxdEHKIFmCSeH8wihJjhCRGLgEKPlxQ03WEUJ4wKNPTwbsv6C1nzyJ3VcYem7UDxP8IARdMuuzGMPw "Röda – TIO Nexus")
It works by splitting the given string at places where the string following contains only matched parentheses. Then, for each chord, it iterates through possible notes and print `O` if the note is a member of the chord and `.` otherwise.
[Answer]
# JavaScript (ES6), ~~86~~ ~~85~~ 76 bytes
*Saved 9 bytes thanks to @Neil*
```
let f =
s=>s.replace(r=/\(\w+\)|./g,x=>`ABCDEFG
`.replace(r,c=>x.match(c)?"O":"."))
```
```
<input oninput="if(/^([A-G.]|\([A-G]+\))+$/.test(value))O.textContent=f(value)"><br>
<pre id=O></pre>
```
### Explanation
First, we match what will form each line of the output: chords, and chars that aren't part of a chord. Then, for each line, we take the string `ABCDEFG\n` and replace each non-newline character in it with an `O` if the line contains it, and a `.` otherwise.
[Answer]
# [Pip](https://github.com/dloscutoff/pip), 29 bytes
28 bytes of code, +1 for `-l` flag.
```
'.X7RA_'OMz@?a@`\(\w+.|.`@XL
```
Takes input in lowercase as a command-line argument. [Try it online!](https://tio.run/nexus/pip#@6@uF2Ee5Biv7u9b5WCf6JAQoxFTrq1Xo5fgEOHz//9/3Zz/iXp6aXrJGimJmnoA "Pip – TIO Nexus")
### Explanation
```
                              a is 1st cmdline arg; XL is `[a-z]`; z is lowercase alphabet
             a@`\(\w+.|.`     List of all matches in a of this regex:
                               Either a ( followed by letters followed by another
                               character (i.e. the closing paren), or any one character
                         @XL  For each of those matches, a list of all matches of this
                               regex (effectively, split the match into a list of
                               characters and keep only the lowercase letters)
          z@?                 Find index of each letter in the lowercase alphabet
         M                    To that list of lists of indices, map this function:
'.X7                           Take a string of 7 periods
    RA_                        and replace the characters at all indices in the argument
       'O                      with O
                              Finally, autoprint the resulting list, with each item on
                              its own line (-l flag)
```
Here's a sample of how an input is transformed:
```
"b.(ceg)"
["b" "." "(ceg)"]
[["b"] [] ["c" "e" "g"]]
[[1] [] [2 4 6]]
[".O....." "......." "..O.O.O"]
```
[Answer]
## JavaScript (ES6), ~~118~~ ~~116~~ 114 bytes
```
f=([c,...t],s)=>c?((s?0:x=[...'.......'],c='ABCDEFG)('.indexOf(c))>6?c-7:(x[c]='O',s))?f(t,1):x.join``+`
`+f(t):''
```
### Test cases
```
f=([c,...t],s)=>c?((s?0:x=[...'.......'],c='ABCDEFG)('.indexOf(c))>6?c-7:(x[c]='O',s))?f(t,1):x.join``+`
`+f(t):''
console.log(f("B(ACE)D"))
console.log(f("GGABC"))
console.log(f("..."))
console.log(f("A..F.C(DA)."))
console.log(f(".(ABCDEF)"))
```
[Answer]
# Ruby, ~~78~~ ~~75~~ 71 bytes
```
->x{x.scan(/\(\w+\)|./).map{|x|l=?.*7
x.bytes{|x|x>47?l[x-65]=?O:1};l}}
```
Returns an array of strings.
## Ungolfed + explanation
```
def boxes string
  string.scan(/\(\w+\)|./)    # Split the string into an array of chords.
  .map do |chord|             # Replace each chord with...
    line = '.' * 7            # a line, where by default each character is a '.',
    chord.bytes do |note|     # but for each note in the chord...
      if note > '.'.ord       # (if it is in fact a note and not a dot or paren)
        line[note-65] = 'O'   # replace the corresponding dot with an 'O'.
      end
    end
    line               
  end
end
```
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), 30 [bytes](https://codegolf.meta.stackexchange.com/questions/9428/when-can-apl-characters-be-counted-as-1-byte-each/9429#9429)
```
'.O'[⍉(⍳7)∘.∊⍎⍕⎕A⍳@(~∊∘'()')⎕]
```
[Try it online!](https://tio.run/##ZcyxbsIwEMbx3U9x29lDT926YhJAnWBHDCZ1SoQVqsQSYmGEgGTUBYmlT9E3uhdJrx06wPq7@/7uIzy97VzYvPd8ub5O@fD5rLg7lj3SFOecTprT94vh7kbcnTldOF3l04oO9P6Xuhtqg0Zw0cuyL0HhUNtsZHJUSliaiMDpC2ZNVUdYBlevIVS1b2Hp49b7GrwrVhB9G6FwrYdy00ARXFPFHShVSlBS/60/mUzsMMM7JKJ7skRjynRuzcOJtCTy0djgDw "APL (Dyalog Unicode) – Try It Online")
Only 1b off the Pip solution, what a shame!
## Explanation
```
'.O'[⍉(⍳7)∘.∊⍎⍕⎕A⍳@(~∊∘'()')⎕]   ⍝ 
                            ⎕    ⍝ Read input. For below examples, this starts at '(AC).D'
               ⎕A⍳               ⍝ Converts to the index (⍳) of the alphabet (⎕A)...
                  @              ⍝ ... For characters which are...
                   (~∊∘'()')     ⍝ ... Not (~) an element (∊) of '()'. Characters outside the alphabet (e.g. dots) will get index 26
                                 ⍝ e.g. '(AC).D' -> ( 0 2 ) 26 3
              ⍕                  ⍝ Convert the mixed array (numerics and characters) to characters (⍕)
             ⍎                   ⍝ Evaluate this string. This abuses the remaining brackets to work as groups, e.g. ( 0 2 ) 26 3 -> three array elements (0  2) 26 3
          ∘.                     ⍝ For each element, compute the outer product of...
      (⍳7)                       ⍝ Each number 0-6...
            ∊                    ⍝ ... vs a boolean of whether this integer is contained in the corresponding vector. Result is a boolean matrix
     ⍉                           ⍝ Transpose this matrix. The result is now in the correct shape with 1 where 'O' needs to be and 0 where a '.' needs to be
'.O'[                        ]   ⍝ For each element of the boolean matrix, treat it as an index of the string '.O'. This will turn 1 into 'O' and 0 into '.'
```
[Answer]
# PHP, 171 bytes
```
preg_match_all('#[A-G\.]|\([A-G]+\)#',$argv[1],$m);foreach($m[0]as$l){if($l=='.')echo".......";else foreach([A,B,C,D,E,F,G]as$a)echo strpos($l,$a)!==false?O:'.';echo"\n";}
```
**Breakdown :**
```
preg_match_all('#[A-G\.]|\([A-G]+\)#',$argv[1],$m); // Matches either one character in the range [A-G.] OR multiple [A-G] characters between parentheses
foreach($m[0]as$l)                                  // For each match :
    if($l=='.')                                     //   If no note is played
        echo".......";                              //     Echo empty music line
    else                                            //   Else
        foreach([A,B,C,D,E,F,G]as$a)                //     For each note in the [A-G] range
            echo strpos($l,$a)!==false?O:'.';       //       Echo O i the note is played, . if not
    echo"\n";                                       //  Echo new line
}
```
[Try it here!](https://eval.in/752255)
[Answer]
# [Retina](https://github.com/m-ender/retina), 120 bytes
```
O`(?<=\([^)]*)[^)]
T`L.`d
(?<=\([^)]*)\d
$*x 
\)
m¶
+`\b(x+) \1(x+) m
$1 m$2 
 m?x
T`x m(`.\O_
\d
$*.O¶
¶
6$*.¶
%7>`.
```
I'm sure there's room for golfing, but it works now, so I'll try to golf it more later.
[Try it online!](https://tio.run/nexus/retina#@@@foGFvYxujER2nGaulCSK5QhJ89BJSuJDFY1K4VLQqFLhiNLlyD23j0k6ISdKo0NZUiDEEU7lcKoYKuSpGClwKufYVXApAIyoUcjUS9GL847nAevX8gdqAyAzIBFKq5nYJelz//zvq6bnpOWu4OGrqAQA "Retina – TIO Nexus")
**How it works**
Basically, the program works by changing each character to a number, then assigning a `O` to that position in a line. It maps `ABCDEFG.` to `01234569`.
To generate the single note lines, all that has to be done is to put an `O` after the corresponding number of `.`s, then pad out the line to 7 characters long.
However, the chords are a bit trickier to do. A similar process is used, but the numbers have to be translated to increments, i.e. the first note in the chord is (whatever), the second is X positions after the first, the third is Y positions after that, etc.
**Code**
```
O`(?<=\([^)]*)[^)]
```
Start out by sorting all characters within chords.
```
T`L.`d
```
Perform the transliteration (mapping) from letters to numbers.
```
(?<=\([^)]*)\d
$*x 
```
Replace all digits within brackets with a unary representation (using `x`s), followed by a space.
```
\)
m¶
```
Replace all closing brackets with `m` followed by a newline. The `m` will be used as a marker of sorts for the coming loop:
```
+`\b(x+) \1(x+) m
$1 m$2 
```
This is a replacement stage that loops until it can't replace anymore. It takes the last two sequences of `x`s before an `m`, and subtracts the first from the second, moving the `m` back. The marker `m` is needed because it has to perform this operation from right to left.
```
 m?x
```
Remove the first `x` in each sequence except the first one.
```
T`x m(`.\O_
```
`T`ransliterate by replacing `x` with `.`, space with `O`, and deleting `m` and `(`.
At this point, all the lines for the chords have been created. Now the single-note lines have to be created.
```
\d
$*.O¶
```
Replace each digit with that many `.`s, followed by an `O` and a newline. 
```
¶
6$*.¶
%7>`.
```
Pad each line to length 7 by adding `.`s to the right. This works by adding 6 `.`s to the end of each line (each line will have at least 1 other character), then replacing every character after the first 7 on each line with nothing. (Since `.` maps to 9, the `O` will be cut out on those lines)
[Answer]
# Perl, ~~87~~ ~~71~~ 45 + 2 (`-nl` flag) = 47 bytes
```
#!/usr/bin/env perl -nl
use v5.10;
say map$&=~/$_/i?O:".",a..g while/\(\w+\)|./g
```
Using:
```
perl -nlE 'say map$&=~/$_/i?O:".",a..g while/\(\w+\)|./g' <<< "A..F.C(DA)."
```
[Try it on Ideone.](http://ideone.com/ZCtlsD)
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 52 bytes
```
\(\w+\)|.
abcdefg$&¶
+`([a-g])(.*)\1
O$2
T`().l`___.
```
[Try it online!](https://tio.run/##K0otycxL/P8/RiOmXDtGs0aPKzEpOSU1LV1F7dA2Lu0EjehE3fRYTQ09Lc0YQy5/FSOukAQNTb2chPj4eL3//xP19NL0kjVSEjX1AA "Retina 0.8.2 – Try It Online") Takes input in lower case. Explanation:
```
\(\w+\)|.
abcdefg$&¶
```
Split the music into chords or notes, and start building the output by adding the list of note equivalents.
```
+`([a-g])(.*)\1
O$2
```
For each note in each chord, change the output to an `O` and delete the note from the chord.
```
T`().l`___.
```
Delete all the now extraneous music, and change all the unmatched notes to empty.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 24 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
žuS¡2Å€S}˜ε'.7×AySkv'Oyǝ
```
Input with lowercase letters; output as a list of lines.
[Try it online](https://tio.run/##ATkAxv9vc2FiaWX//8W@dVPCoTLDheKCrFN9y5zOtScuN8OXQXlTa3YnT3nHnf9dwrv/YS4uZi5jKGRhKS4) or [verify all test cases](https://tio.run/##yy9OTMpM/V9TpuSZV1BaYqWgZF@pw6XkX1oC4elU/j@6rzT40EKjw62PmtYE156ec26rup754emOlcHZZer@lcfn/q@tPbRb59A2@/9JGonJqZopXElc6emJSclcenp6XIl6eml6yRopiZp6XHoaQNGU1DRNLiBDMzlFA8jUSEzXBAA). (The `]»` in the footer is used to pretty-print the output by joining with newlines. Feel free to remove it to see the actual output-list.)
**Explanation:**
```
žu                       # Push builtin string "()<>[]{}"
  S                      # Convert "()<>[]{}" to a list of characters
   ¡                     # Split the (implicit) input by these characters
                         # (NOTE: If the input starts with a "("
                         #  the first item will be an empty string)
    2Å€ }                # For every item at a 0-based index that is divisible by 2:
       S                 #  Convert the string to a list of characters
         ˜               # Flatten the list
          ε              # Map each item to:
           '.7×         '#  Push a string with 7 "."s: "......."
               A         #  Push the lowercase alphabet
                y        #  Push the current item we're mapping over
                 S       #  Convert it to a list of characters
                  k      #  Get the index of each in the alphabet (-1 if it's a ".")
                   v     #  Loop over those indices:
                    'O  '#   Push an "O"
                      yǝ #   Insert it in the "......." string at the current index
                         #   (`ǝ` doesn't work with -1, but still pops the "O" and -1)
                         # (after which the resulting list of lines is output implicitly)
```
[Answer]
# Perl 5 - 78 + 1(flag) + 2(Input Quotes) = 81 Bytes
```
for(;/(\([a-g]+\)|[a-g\.])/g;){$i=$1;print$i=~/$_/?'o':'.'for(a..g);print"\n"}
```
Can be run like so:
```
perl -n <name of file holding script> <<< <input in quotations>
```
[Answer]
# Ruby, 68 bytes
```
->s{w=?.*m=7
s.bytes{|i|i>64?w[i-65]=?O:m=i!=40;m&&(puts w;w=?.*7)}}
```
The idea is to modify the string `.......` every time we find a letter, then output and reset it, but only when we are outside brackets. `(` switches the outputting off. `)` and `.` both switch/leave the outputting on, but the latter is inconsequential as it will never be found inside a bracket.
**Ungolfed in test program**
```
f=->s{w=?.*m=7              #set m to a truthy value (7) and w to seven .'s
  s.bytes{|i|               #for each byte in the string
    i>64?w[i-65]=?O:m=i!=40 #if a letter, modify the appropriate character of w ELSE set m to false if inside brackets, true otherwise.
    m&&(puts w;w=?.*7)      #if m is true, output the contents of w and reset to seven .'s
  }
}
p 1
f["B(ACE)D"]
p 2
f["B"]
p 3
f["GGABC"]
p 4
f["A..F.C(DA)."]
p 5
f[".(ABCDEF)"]
```
[Answer]
# Python 3, 94 bytes
An anonymous function
```
import re
lambda s:[''.join('.O'[c in x]for c in'ABCDEFG')for x in re.findall(r'\(\w+\)|.',s)]
```
[Answer]
# [Haskell](https://www.haskell.org/), 101 bytes
```
c#s|elem c s=c|1<3='.'
s?r=map(#s)"ABCDEFG":p r
p('(':r)|(x,_:t)<-span(')'<)r=x?t
p(x:r)=[x]?r
p e=[]
```
[Try it online!](https://tio.run/nexus/haskell#FYpLCoMwFAD3nuKhhbxAGyjdiQ/xEz2ESAkhC0FDSCxkkbunuhpmmKyrkMxuDtAQSKd38yEmWBFaT4dyWAVedv0wymkuawe@cMiQ1Z4njM/vxeYVnLLIOGu4p9jeR7w6LXG9BQwtaz7UZoFgs6fxSp/wgJ/dN2sCCHC5Ez0OI5fYj5JP8x8 "Haskell – TIO Nexus") Usage: `p "AB.(CA)D"`. Returns a list of strings.
**Explanation:**
The function `p` recurses over the string. If it finds an opening bracket `'('` then `(x,_:t)<-span(')'<)r` partitions the rest string `r` into the strings `x` before the occurrence of the closing bracket `')'` and `t` after it. Otherwise the current character `x` is turned into a string `[x]`. In both cases the function `?` is called with the current string of notes and the rest string.
`?` maps the function `#` over the string `"ABCDEFG"`, where `#` replaces all chars that are not in the current string of notes with `'.'`. The resulting music box line is prepended to the recursive call of `p` on the rest list `r`.
[Answer]
# PHP, 93 bytes
```
for($s=$t="
.......";$c=ord($argn[$i++]);$d||$s=$t.!print$s)$c<65?$c-46&&$d=~$c&1:$s[$c&7]=O;
```
Run as pipe with `-nR` or [try it online](http://sandbox.onlinephpfunctions.com/code/57df5ed6f63565a5a75890edabcde6712aee9839).
**breakdown**
```
for($s=$t="\n.......";      // init
    $c=ord($argn[$i++]);    // loop through characters
    $d||                        // 2. if chord flag is unset
        $s=$t.!print$s)             // then print and reset chord
    $c<65                       // 1. if not note
        ?$c-46                      // and not dot
            &&$d=~$c&1              // then set or clear chord flag
        :$s[$c&7]=O             // else set note in chord
    ;
```
]