1P5: Nested boxes
Python, 204 chars
def P(n):x=raw_input();return eval('[(n+".","","-")]'+'+P(n+"| ")'*int(x))+[(n+"'",'','-')]if'0'<x<':'else[(n,x,' ')]
r=P('')
for q,t,f in r:print q+t+f*(max(len(2*x+y)for x,y,a in r)-len(2*q+t))+q[::-1]
P
returns a list of triples, each of which is a line prefix/suffix (the suffix being the reverse of the prefix), some line text, and a line fill character. After calculating all the triples, they are printed using the right number of fill characters to make all the lines the same length.
Ungolfed version:
def get_lines(prefix):
line=raw_input()
result=[]
if line.isdigit():
result.append((prefix+'.', '', '-'))
for i in xrange(int(line)):
result += get_lines(prefix + '| ')
result.append((prefix+"'", '', '-'))
else:
result.append((prefix, line, ' '))
return result
lines=get_lines('')
width=max(2*len(prefix)+len(text) for prefix,text,fill in lines)
for prefix,text,fill in lines:
print prefix+text+fill*(width-2*len(prefix)-len(text))+prefix[::-1]
Ruby 1.9, 174 characters
r=->l{$*<<(l*2+i=gets.chop).size;/\d/?eval('[l+?.,p=?-,p,'+'*r["| "+l],'*i.to_i+"l+?',p,p]"):[l,i,?\s]}
r[""].each_slice(3){|a,b,c|puts a+b+c*($*.max-(a*2+b).size)+a.reverse}
Somewhat similar to Keith's solution.
APL (78)
{∧/⎕D∊⍨I←⍞:{∆,('-'⍪⍵⍪'-'),∆←'.|'''/⍨1(⊃⍴⍵)1}⍕⍪/{⍵↑[2]⍨⌈/⊃∘⌽∘⍴¨∆}¨∆←∇¨⍳⍎I⋄⍉⍪I}⍬