[Question]
  [
[Triangularity](https://github.com/Mr-Xcoder/Triangularity) is a new esolang developed by [Mr. Xcoder](https://codegolf.stackexchange.com/users/59487/mr-xcoder) where code structure has to follow a very specific pattern:
* For the `n`th line of code, there must be exactly `2n-1` characters of the program on it. This causes a triangular/pyramid shape, with the first line having only one character and the rest increasing by increments of 2.
* Each line must be padded with `.`s on the left and right, such that the characters are centered on their lines and all lines are padded to the same length. If `l` is defined as the number of lines in the program, each line in the program must have a length of `2 * l - 1`
For example, the program on the left is valid, but the program on the right isn't:
```
 Valid    |  Invalid  
          |
...A...   |  ABCDE
..BCD..   |  FGH
.EFGHI.   |  IJKLMN
JKLMNOP   |  OPQRS
```
When laid out in the valid structure, the name becomes obvious.
## Task
Your task is to take a single line string as input, representing Triangularity code, and output it converted into valid code as described above. 
Specifications for I/O:
* The input will only contain characters in the range `0x20 - 0x7e`
* The length of the input always will be a square number and thus paddable nicely.
* You must use dots for the output padding, not something else.
You may input and output through any [acceptable](https://codegolf.meta.stackexchange.com/q/2447/66833) method. This is a [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") so the shortest code in *bytes* wins!
## Test cases
```
input
----
output
g
----
g
PcSa
----
.P.
cSa
DfJ0vCq7G
----
..D..
.fJ0.
vCq7G
7xsB8a1Oqw5fhHX0
----
...7...
..xsB..
.8a1Oq.
w5fhHX0
QNYATbkX2sKZ6IuOmofwhgaef
----
....Q....
...NYA...
..TbkX2..
.sKZ6IuO.
mofwhgaef
ABCDEF"$%& G8"F@
----
...A...
..BCD..
.EF"$%.
& G8"F@
ab.c
----
.a.
b.c
```
For those who know Triangularity, you'll notice from the last test case that strings don't have to be handled
  
[Answer]
# [Triangularity](https://github.com/Mr-Xcoder/Triangularity), 127 bytes
```
.......).......
......2)1......
...../)IL^.....
....f)rMD@_....
...)2)1/)IL^...
..f+`"'.'*"+E..
.DWReD)2s^)Its.
D+@sh+s+})10cJ.
```
[Try it online!](https://tio.run/##KynKTMxLL81JLMosqfz/Xw8CNKE0F4Qy0jRE5utrevrEIfhpmkW@Lg7xML4mUDVMBZCfpp2gpK6nrqWk7Qriu4QHpbpoGhXHaXqWFOtxuWg7FGdoF2vXahoaJHvp/f8f6BfpGJKUHWFU7B1l5lnqn5ufVp6RnpiaBgA "Triangularity – Try It Online")
## Explanation
Removing the characters that make up for the padding, we get the following program:
```
)2)1/)IL^f)rMD@_)2)1/)IL^f+`"'.'*"+EDWReD)2s^)ItsD+@sh+s+})10cJ
```
... Which is quite length-ish, right? Let's break it down into pieces.
**Generating the integers [0 … √len(input))**
```
)2)1/)IL^f)r – Subprogram #1.
)            – Creates a new stack entry, equal to 0. This must precede any integer
               literal, because each character in '0123456789' isn't parsed on its
               own as a literal, but rather they are commands which multiply the ToS
               by 10 and add the value of their digit equivalent. 
 2           – ToS * 10 + 2 = 2.           || STACK: [2]
  )1         – The literal 1.              || STACK: [2, 1]
    /        – Division.                   || STACK: [1 / 2] = [0.5]
     )I      – Get the input at index 0.   || STACK: [0.5, input]
       L     – Length.                     || STACK: [0.5, len(input)]
        ^    – Exponentiation.             || STACK: [len(input) ** 0.5]
         f   – Trim decimals.              || STACK: [int(len(input) ** 0.5)] 
          )r – Create the list [0 .. ToS). || STACK: [[0 ... int(len(input) ** 0.5))]
```
**Generating the dots**
```
MD@_)2)1/)IL^f+`"'.'*"+E – Subprogram #2.
MD                       – For each integer in the range, run some code on a separate
                           stack, preinitialised to two copies of the argument.
  @_                     – Increment and negate the ToS.
    )2)1/)IL^f           – The square root of the length of the input, again.
              +          – Add the two.
               `         – And cast the integer given to a string.
                "'.'*"+  – Prepends the literal "'.'*" to the string representation.
                       E – Evaluate as a Python expression (basically string repetition).
```
**Trimming the characters at the front**
```
DWReD)2s^)It – Subprogram #3.
D            – Duplicate the result of the expression above.
 W           – Wrap the whole intermediate stack to an array.
  Re         – Reverse the stack and dump the contents separately onto the stack.
    D        – Duplicate the result.
     )2      – Push the literal 2.
       s^    – Swap and perform exponentiation.
         )It – Push the input and trim the characters before that index.
```
**Trimming the characters at the end**
```
sD+@sh+s+ – Subprogram #4.
s         – Swap the top two elements on the stack.
 D+       – Double. Push twice and add.
   @      – Increment.
    sh    – Swap the top two elements and trim the characters after that index.
      +   – Append the first set of dots.
       s+ – And prepend the second set of dots.
```
**Ending the loop and pretty-printing**
```
})10cJ – Subprogram #5.
}      – End the loop.
 )10   – Push the literal 10.
    c  – Convert from code-point to character (yields '\n').
     J – And join the result by newlines.
```
[Answer]
# [Japt](https://github.com/ETHproductions/japt), ~~15~~ ~~14~~ 10 bytes
Outputs an array of lines.
```
ò@°T¬v1Ãû.
```
[Try it](https://ethproductions.github.io/japt/?v=1.4.5&code=8kCwVKx2McP7Lg==&input=IlFOWUFUYmtYMnNLWjZJdU9tb2Z3aGdhZWYiCi1S) | [Check all test cases](https://ethproductions.github.io/japt/?v=1.4.5&code=o1Q9MCxYIPJAsFSsdjHD+y4gtytS&input=WyJnIiwiUGNTYSIsIkRmSjB2Q3E3RyIsIjd4c0I4YTFPcXc1ZmhIWDAiLCJRTllBVGJrWDJzS1o2SXVPbW9md2hnYWVmIiwnQUJDREVGIiQlJiBHOCJGQCcsImFiLmMiXQotUg==)
---
## Explantion
```
ò@     Ã       :Partition at characters where the following function returns true
  °T           :  Increment T (initially 0)
    ¬          :  Square root
     v1        :  Divisible by 1?
               :(Or, in other words, split after every character with a 1-based index that's a perfect square)
        û.     :Centre pad each element with .s to the length of the longest element
```
---
## Original Solution
```
Ê¬ÆsTT±X+°XÃû.
```
[Try it](https://ethproductions.github.io/japt/?v=1.4.5&code=yqzGc1RUsVgrsFjD+y4=&input=IlFOWUFUYmtYMnNLWjZJdU9tb2Z3aGdhZWYiCi1S)
```
Ê                  :Length of input
 ¬                 :Square root
  Æ        Ã       :Range [0,Ê¬) and pass each X through a function
   s               :  Slice input
    T              :    from index T, initially 0
     T±X+°X        :    to index T incremented by X plus X incremented
            û.     :Centre pad each element with .s to the length of the longest element
```
[Answer]
# [Husk](https://github.com/barbuz/Husk), 15 bytes
```
Ṡzö`JR2tR'.ṡCİ1
```
[Try it online!](https://tio.run/##yygtzv7//@HOBVWHtyV4BRmVBKnrPdy50PnIBsP///8rZaRXVOXnZOfnlGSAoRIA "Husk – Try It Online")
## Explanation
```
Ṡzö`JR2tR'.ṡCİ1  Implicit input, say s = "DfJ0vCq7G".
             İ1  List of odd positive integers: [1,3,5,7,..
            C    Cut s to those lengths: x = ["D","fJ0","vCq7G"]
           ṡ     Reversed indices of x: y = [3,2,1]
Ṡz               Zip x and y using this function:
                  Arguments are a string and a number, e.g. r = "fJ0" and n = 2.
        R'.       n copies of '.': ".."
       t          Drop first element: "."
     R2           Two copies of this: [".","."]
  ö`J             Join by r: ".fJ0."
                 Result is ["..D..",".fJ0.","vCq7G"]; implicitly print on separate lines.
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~20~~ ~~19~~ 18 bytes
Saved a byte thanks to *Magic Octopus Urn*
```
ā·<£õKRvy'.N×.ø}r»
```
[Try it online!](https://tio.run/##ATMAzP8wNWFiMWX//8SBwrc8wqPDtUtSdnknLk7Dly7DuH1ywrv//0FCQ0RFRiIkJSYgRzgiRkA "05AB1E – Try It Online")
**Explanation**
```
ā                    # push the list [1 ... len(input)]
 ·<                  # multiply each by 2 and decrement each, making a list of odd numbers
   £                 # split the input into chunks of these sizes
    õK               # remove empty strings
      R              # reverse list
       vy      }     # for each y in the list
             .ø      # surround it with
         '.N×        # "." (dot) repeated N times, where N is the current iteration index
                r    # reverse the stack
                 »   # join stack by newlines
```
[Answer]
# [Python 2](https://docs.python.org/2/), 83 bytes
```
i=input();u=int(len(i)**.5)
for t in range(u):g="."*(u+~t);print g+i[t*t:][:t-~t]+g
```
[Try it online!](https://tio.run/##K6gsycjPM/r/P9M2M6@gtERD07oUyCrRyEnN08jU1NLSM9XkSssvUihRyMxTKErMS0/VKNW0SrdV0lPS0ijVrivRtC4oAmpQSNfOjC7RKrGKjbYq0a0ridVO//9fKdAv0jEkKTvCqNg7ysyz1D83P608Iz0xNU0JAA "Python 2 – Try It Online")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~22~~ 19 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
J²‘Ṭœṗ⁸Ṛz”.Zµṙ"JC$Ṛ
```
A monadic link returning a list of lists of characters (the lines)
**[Try it online!](https://tio.run/##AT4Awf9qZWxsef//SsKy4oCY4bmsxZPhuZfigbjhuZp64oCdLlrCteG5mSJKQyThuZr/w4dZ//8iRGZKMHZDcTdHIg "Jelly – Try It Online")**
### How?
```
J²‘Ṭœṗ⁸Ṛz”.Zµṙ"JC$Ṛ - Link: list of characters e.g. "DfJ0vCq7G"
J                   - range of length               [1,2,3,4,5,6,7,8,9]
 ²                  - square (vectorises)           [1,4,9,16,25,36,49,64,81]
  ‘                 - increment                     [2,5,10,17,26,37,50,65,82]
   Ṭ                - untruth (1s at those indices) [0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,...]
      ⁸             - chain's left argument         "DfJ0vCq7G"
    œṗ              - partition at indexes          ["D","fJ0","vCq7G"]
       Ṛ            - reverse                       ["vCq7G","fJ0","D"]
         ”.         - literal '.'                   '.'
        z           - transpose with filler         ["vfD","CJ.","q0.","7..","G.."]
           Z        - transpose                     ["vCq7G","fJ0..","D...."]
            µ       - start a new monadic chain
                 $  - last two links as a monad:
               J    -   range of length             [1,2,3]
                C   -   complement (vectorises)     [0,-1,-2]
              "     - zip with:
             ṙ      -   rotate left by              ["vCq7G",".fJ0.","..D.."]
                  Ṛ - reverse                       ["..D..",".fJ0.","vCq7G"]
```
[Answer]
# JavaScript (ES7), ~~82~~ 78 bytes
```
f=(s,k=1-s.length**.5*2,p='')=>s&&f(s.slice(0,k),k+2,p+'.')+`
`+p+s.slice(k)+p
```
### Test cases
```
f=(s,k=1-s.length**.5*2,p='')=>s&&f(s.slice(0,k),k+2,p+'.')+`
`+p+s.slice(k)+p
console.log(f('g'))
console.log(f('PcSa'))
console.log(f('DfJ0vCq7G'))
console.log(f('7xsB8a1Oqw5fhHX0'))
console.log(f('QNYATbkX2sKZ6IuOmofwhgaef'))
console.log(f('ABCDEF"$%& G8"F@'))
```
### Commented
```
f = (                       // f = recursive function taking:
  s,                        //   s = input string
  k = 1 - s.length**.5 * 2, //   k = additive inverse of the length of the base
  p = ''                    //   p = padding string
) =>                        //
  s &&                      // if s is not empty:
    f(                      //   do a recursive call with:
      s.slice(0, k),        //     s without the last -k characters
      k + 2,                //     the updated base length (2 less characters)
      p + '.'               //     the updated padding string
    ) +                     //   end of recursive call()
    `\n` +                  //   append a line feed
    p +                     //   append the left padding string
    s.slice(k) +            //   append the last -k characters of s
    p                       //   append the right padding string
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 25 bytes
```
gÅÉ£õKð'ø‡.c¶¡ζøð'.‡'øð‡»
```
[Try it online!](https://tio.run/##MzBNTDJM/f8//XDr4c5Diw9v9T68Qf3wjkcNC/WSD207tPDctsM7gCJ6QAF1EAtIH9r9/7@jk7OLq5uSiqqagruFkpsDAA "05AB1E – Try It Online")
[Answer]
# [MATL](https://github.com/lmendo/MATL), 21 bytes
```
tnX^eRP&1ZvGyg(46y~(!
```
[Try it online!](https://tio.run/##y00syfn/vyQvIi41KEDNMKrMvTJdw8Sssk5D8f9/dUcnZxdXNyUVVTUFdwslNwd1AA "MATL – Try It Online")
### Explanation
Consider input `'DfJ0vCq7G'` as an example. The stack contents are shown separated by commas, with the top element last. Rows in a 2D array use semicolon as separator.
```
t      % Implicit input: string. Duplicate
       % STACK: 'DfJ0vCq7G',
                'DfJ0vCq7G'
nX^    % Number of elements. Square root
       % STACK: 'DfJ0vCq7G',
                3
e      % Reshape with that many rows (in column major order)
       % STACK: ['D0q';
                 'fv7';
                 'JCG']
R      % Upper triangular part: set elements below diagonal to char(0)
       % (displayed as space)
       % STACK: ['D0q';
                 ' v7';
                 '  G']
P      % Flip vertically
       % STACK: ['  G';
                 ' v7';
                 'D0q']
&1Zv   % Reflect vertically
       % STACK: ['  G';
                 ' v7';
                 'D0q';
                 ' v7';
                 '  G']
G      % Push input again
       % STACK: ['  G';
                 ' v7';
                 'D0q';
                 ' v7';
                 '  G'],
                'DfJ0vCq7G'
yg     % Duplicate from below and convert to logical. This gives true for
       % for nonzero chars (the entries where input chars will be written)
       % STACK: ['  G';
                 ' v7';
                 'D0q';
                 ' v7';
                 '  G'],
                'DfJ0vCq7G',
                [0 0 1;
                 0 1 1;
                 1 1 1;
                 0 1 1;
                 0 0 1]
(      % Assignment indexing: write values at those positions
       % STACK: ['  v';
                 ' fC';
                 'DJq';
                 ' 07';
                 '  G']
46     % Push 46, which is ASCII for '.'
       % STACK: ['  v';
                 ' fC';
                 'DJq';
                 ' 07';
                 '  G'],
                 46
y~     % Duplicate from below and apply logical negate. This gives true
       % for char(0) (the entries where '.' will be written)
       % STACK: ['  G';
                 ' v7';
                 'D0q';
                 ' v7';
                 '  G'],
                46
                [1 1 0;
                 1 0 0;
                 0 0 0;
                 1 0 0;
                 1 1 0]
(      % Assignment indexing: write value at those positions
       % STACK: ['..G';
                 '.v7';
                 'D0q';
                 '.v7';
                 '..G'],
!      % Transpose. Implicit display
       % STACK: ['..D..';
                 '.fJ0.';
                 'vCq7G']
```
[Answer]
# [Clean](https://clean.cs.ru.nl), ~~107~~ ~~94~~ ~~89~~ 88 bytes
```
import StdEnv
@s _[]=s
@s n r= @([['.':l]++['.']\\l<-s]++[take n r])(n+2)(drop n r)
```
```
@[]1
```
[Try it online!](https://tio.run/##HYxPC8IgHEDvfYofo9IxFtQpokF/tkXQbUcnQ6bGSN1QC/ryWXZ7Dx6vV4KZoEf@VAI0G0wY9DRaD43nlXnNJDjoCC3cnwzYQmJC0ArtFM2yCLRt1T530Tx7iNjQFJtsk2Juxyl6GhrPfs8CJKFrIOh4OpdVncwXS7hsk/qAaPj0UrG7C/n1Fsq3YXro3Rc "Clean – Try It Online") Example usage: `@[]1 ['ABCDEF"$%& G8"F@']`.
[Answer]
# [Haskell](https://www.haskell.org/), ~~84~~ 68 bytes
```
[]%1
(s%n)[]=s
(s%n)r=(['.':l++"."|l<-s]++[take n r])%(n+2)$drop n r
```
[Try it online!](https://tio.run/##JcldT8IwGIbhc3/Fm4bJlsoCJAoxLpEPAUVFgwdo14OXuW5kXSnrBh742602nt3P9eRoilRKm0WxZdzrnfnGUwHjkfmvKvJZO2xfS0pJSL7lTcdwSlmNRQoKKh54vqL9oPVZ7bUDW@JOQQQl6ifwdVOv6@pRQQiNkjuVmr/KAmDkJVkjuQAyFQ/d4@QwmLsx@DLjIfZWh9OlyBebrrPX5/fR27bY9M3y4@q@WZV7ccozTIU7R@PJ9G4Wk5Z3DvNhTGa3TnEbJoTbn0RIzIztJFr/Ag "Haskell – Try It Online")
Example usage: `[]%1 $ "abcd"` yields the list of lines `[".a.","bcd"]`.
[Answer]
# Perl, ~~56~~ 52 bytes
Includes `+3` for `-p`
```
#!/usr/bin/perl -p
$_=("."x y///c**.5)=~s%.%$'@{[$&x/$`$`./g]}$'
%rg
```
Give input on STDIN (in principle without final newline, but that only matters for the empty input)
[Answer]
# [Red](http://www.red-lang.org), 227 203 bytes
```
f: func[s][l: to-integer(length? s)** 0.5
n: 0 foreach m parse s[collect[(r: []repeat i l[append r reduce['keep i * 2 - 1
charset[not{Я}]]])r]][v: copy""insert/dup v"."l - n: n + 1 print rejoin[v m v]]]
```
[Try it online!](https://tio.run/##FY6xTsMwGAb3PMUnL22DWtpKMGRBjAgJBGIALA@p/TtJ69rWbycIIZ6JV@GNgplPdzomMz@TgVSzbWBHr2VS0jXIYT34TB3x0pHvcn@DtKprbDdXlW@whQ1Mre5xRmw5EZLUwTnSWS65KT2mSG3GACfbGMkbMJjMqEkuTkSxkBp7rLGrdP9fyNKH/PX7862UWrFScmqgQ/wUYvCJOF@aMWISG@GKVBY8LrBD5LJZwscweDmVm6nos4V4eni7fTmcXvfp/v36bnw8B/vRdy1ZUc1/ "Red – Try It Online")
Ungolfed:
```
f: func[s][
l: to-integer (length? s) ** 0.5
n: 0
foreach m parse s [ 
    collect [
        (r: []
        repeat i l [ append r reduce [
            'keep i * 2 - 1 charset [ not{Я} ]]])
    r ]] 
    [v: copy ""
    insert/dup v "." l - n: n + 1
    print rejoin [v m v]]
]
```
[Answer]
# [Retina](https://github.com/m-ender/retina/wiki/The-Language), ~~88~~ ~~72~~ 71 bytes
```
S1`
+m`^(.)+¶(?>(?<-1>.)+)..(?!¶)
$&¶
P^'.m`^.(?=(..)*)(?<-1>.)*
P'.`.+
```
[Try it online!](https://tio.run/##K0otycxLNPz/P9gwgUs7NyFOQ09T@9A2DXs7DXsbXUM7IE9TT0/DXvHQNk0uFbVD27gC4tT1gOqAYrYaenqaWpowhVpcAep6CXra//8H@kU6hiRlRxgVe0eZeZb65@anlWekJ6amAQA "Retina – Try It Online") Edit: Saved ~~12~~ 13 bytes thanks to @MartinEnder. Explanation:
```
S1`
```
Split first character into its own line to get the ball rolling.
```
+m`^(.)+¶(?>(?<-1>.)+)..(?!¶)
$&¶
```
Chop each line two characters longer than the previous one.
```
P^'.m`^.(?=(..)*)(?<-1>.)*
```
Left-pad the first half of each line, effectively centring them.
```
P'.`.+
```
Right-pad all of the lines.
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), ~~21~~ 19 bytes
```
ＵＢ.Ｆ₂Ｌθ«Ｐ✂θＸι²Ｘ⊕ι²↙
```
[Try it online!](https://tio.run/##NYw9D4IwFABn@BWE6TVBBwYHnTQuRPALB3Wr5QENpU9qgcH42ysOjneXnKi5EcSVcznaDRdNZajXBYTzkK38kkwAeddzg2ciCynqytbQMcaCt@9lvbLyaaS2kCspELooONKIBmQUxOwPiRYGW9QWC5DsV9j09jIaEJZbGnWKpZ3Mx7nT/ra@PJpr/NrdF0l/aKkc64pj6WaD@gI "Charcoal – Try It Online") Link is to verbose version of code. Edit: Saved 2 bytes by discovering `SquareRoot`. Explanation:
```
ＵＢ.                 Set the background fill to `.`
      θ             (First) input
     Ｌ              Length
    ₂               Square root
   Ｆ   «            Loop over implicit range
            ι   ι   Current value
               ⊕    Incremented
             ²   ²  Literal 2
           Ｘ  Ｘ     Power
         ✂θ         Slice the (first) input string
        Ｐ           Print without moving the cursor
                  ↙ Move down left
```
[Answer]
# [Python 2](https://docs.python.org/2/), 84 bytes
```
s=input()
l=int(len(s)**.5)
for i in range(l):print s[i*i:][:i-~i].center(l*2-1,'.')
```
[Try it online!](https://tio.run/##JcqxDoMgEADQ3a9g445UorS2lcQvUQfTYHsJOQnQwaW/Tk3c3vDCnj8bm7IOU0kDcfhmwMofyuAdQ0KldIfVukVBgljEhd8OPNoQjyPSSIrsPFqqfzTrl@PsInhl6vYitcRSZGuut@7@ePbNKfkH "Python 2 – Try It Online")
[Answer]
# [Clean](https://clean.cs.ru.nl), 123 bytes
```
import StdEnv
?n l#(a,b)=splitAt n l
|b>[]=[a: ?(n+2)b]=[a]
$s#s= ?1s
=[c++l++c\\l<-s&i<-[1..],c<-[repeatn(length s-i)'.']]
```
[Try it online!](https://tio.run/##FY1PC4IwHEDvfoofaqlMhTpFuOyvEXTruHaYc9lgLnErCPrsLbu99y6PK8G06x7NUwnomNROdv1jsHCxzUG/vFKDCmKW1gk2vZJ2Y2Es3qdeEYoJW0IZazRP6r9QLzSBwVDOjIcJR0ghxK9XVWRmKouMzPKcpnyEQfSCWR0roVt7B5PJJMojSt3FsnGNISTRZrvbHyo/nEzhuPCrdUTdl98Ua43LTme3f2vWSW5@ "Clean – Try It Online")
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~73~~ 66 bytes
```
->s{(1..z=s.size**0.5).map{|q|s[q*q-2*q+1...q*q].center 2*z-1,?.}}
```
[Try it online!](https://tio.run/##RY5NT8JAGITv@yvebNToSjdtE4RLVT4ElEQ0ekBLY7bLLiWGwvK2IqX89lqpxNPMMzOHWafhttBeYV3j7tzhPPOQ4zxTjNm8fsEXYrXLTY6@YcZymbksJ7z0AZcqTtQaXJZZTu2G7/dFojD5kAIVggc@AaAzWvuVJ/kiKtfVD/ZXxzT6FTa@sd0Uzshs6joajO0qfX58a72Gn2MXh@9X9@losdSbaCaUrupWu9O9603oyekZ9JsT2rutchFySUlAyP8ProSMYLqEfB6v0iQvZ6UgHOgI1KLAwLGPrP1DHfwxUfG0@AE "Ruby – Try It Online")
-5 bytes: Return an array of strings instead of printing them
-2 bytes: Declare `z` in place instead of ahead of time
Ungolfed:
```
->s{
  (1..z=s.size**0.5).map{|q|   # Map the range [1,sqrt(s.size)]
    s[q*q-2*q+1...q*q]         # To the relevant portion of s,
      .center 2*z-1, ?.        #   padded left and right with . characters
  }
}
```
Declaring a variable `r=q-1` so that I can take `s[r*r...q*q]` saves exactly zero bytes.
Using `.center` instead of padding manually also saves zero bytes, but I like it better.
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 19 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
╚└÷2╬#►o┴X≡¥ΩåV∙¬?♥
```
[Run and debug it](https://staxlang.xyz/#p=c8c0f632ce23106fc158f09dea8656f9aa3f03&i=DfJ0vCq7G%0AABCDEF%22%24%25%26+G8%22F%40&m=2)
ASCII equivalent:
```
z;%|q{Hv,:/~]+F|Cm0]'.R
```
]