Stack the Christmas Gifts

CJam, 81 70 bytes

'"qN/{__Sm0=#>}%N*"=
="/"=\"\"="*'"++~]$_W='=/,f{1$'=/,m4/\N/\f{S*\N}}

So we have to stack the Christmas presents? This code does it like an actual person would do*.

First, we stack all the presents against a wall to easily move them up and down using this code:

'"qN/{__Sm0=#>}%N*

then, we identify each present as a separate item using this code:

"=
="/"=\"\"="*'"++~]

then, we sort the presents based on their heights and widths using this code:

$

Till now, all the gifts have been stacked against a wall in order to have perfect alignment with each other. But as this is Christmas, we want to place the gifts aligned centered like a Christmas tree! This code does that:

_W=Af{1$Am4/\N/\f{S*\N}}

Here is a step by step output of the code for example in the question:

"Step 1 - Stack the presents against a wall";
========================
|                      |
========================
=============
|           |
|           |
|           |
|           |
|           |
|           |
=============
=======
|     |
|     |
|     |
=======
===================
|                 |
|                 |
|                 |
===================
=================
|               |
|               |
|               |
|               |
=================
=======
|     |
|     |
=======

"Step 2 - Identify the presents as a collection of presents";
["========================
|                      |
========================" "=============
|           |
|           |
|           |
|           |
|           |
|           |
=============" "=======
|     |
|     |
|     |
=======" "===================
|                 |
|                 |
|                 |
===================" "=================
|               |
|               |
|               |
|               |
=================" "=======
|     |
|     |
======="]

"Step 3 - Sort on height & width, with presents stacked against a wall to help sort them";
=======
|     |
|     |
=======
=======
|     |
|     |
|     |
=======
=============
|           |
|           |
|           |
|           |
|           |
|           |
=============
=================
|               |
|               |
|               |
|               |
=================
===================
|                 |
|                 |
|                 |
===================
========================
|                      |
========================

"Final step - stack them like a Christmas Tree";
        =======
        |     |
        |     |
        =======
        =======
        |     |
        |     |
        |     |
        =======
     =============
     |           |
     |           |
     |           |
     |           |
     |           |
     |           |
     =============
   =================
   |               |
   |               |
   |               |
   |               |
   =================
  ===================
  |                 |
  |                 |
  |                 |
  ===================
========================
|                      |
========================

Try it online here

* Might differ from person to person though :P


Japt, 18 bytes

mx óÈíY b'=²Ãn c û

Try it online!

I use a sufficiently different strategy from the other Japt answer that I thought it was worth its own answer. Takes input and output as an array of lines

Explanation:

mx                    #Trim leading whitespace from each line
   ó        Ã         #Split the array between lines where:
    ÈíY               # The lines interleaved (e.g. "abc","def" => "adbecf")
        b'=²          # starts with "=="
             n        #Default sorting for "array of arrays of strings"
               c      #Flatten to a single array of lines
                 û    #Pad each line so they are centered

I don't know precisely why "default sort" works like that, but I've tested that the taller box of the two with the same width is on the bottom regardless of which comes first in the input.


Ruby, 164

Neat challenge! Couldn't get it down much further.

f=->x{y=x.scan(/\s+=+[\s|]+\s+=+/).sort_by{|p|-p.count(?|)}.sort_by{|p|p.count ?=}
y.map{|p|p.gsub(/^\s+/,'').each_line{|l|puts l.strip.center(y[-1].count(?=)/2)}}}

Explanation

The input String is chopped up into an Array where each present is an element. Then the array is sorted by the number of pipe characters and sorted again by the number of equal signs.

It then removes all leading whitespace and prints each line individually, centered by the width of the largest present.

It behaves the same with or without a trailing newline on the input.

Readable version

f = lambda do |x|
  y = x.scan(/\s+=+[\s|]+\s+=+/)
       .sort_by { |p| -p.count("|") }
       .sort_by { |p|  p.count("=") }

  y.map do |p|
    p.gsub(/^\s+/,'').each_line do |l|
      puts l.strip.center(y.last.count("=") / 2 )
    end
  end
end