diff --git a/pyproject.toml b/pyproject.toml
index fd814c1..1a81a60 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
 
 [project]
 name = "table2ascii"
-version = "1.1.1"
+version = "2.0.0"
 authors = [{name = "Jonah Lawrence", email = "jonah@freshidea.com"}]
 description = "Convert 2D Python lists into Unicode/ASCII tables"
 readme = "README.md"
diff --git a/table2ascii/merge.py b/table2ascii/merge.py
index 0375a4e..4b41b83 100644
--- a/table2ascii/merge.py
+++ b/table2ascii/merge.py
@@ -12,6 +12,9 @@ class Merge(Enum):
     the merged cell will be wrapped onto multiple lines. The ``column_widths``
     option can be used to control the widths of the unmerged cells.
 
+    Using :attr:`Merge.UP` in a table cell will merge the cell it is used in
+    with the cell above it.
+
     Example::
 
         from table2ascii import Merge, PresetStyle, table2ascii
@@ -35,9 +38,14 @@ class Merge(Enum):
         \"\"\"
 
     .. versionadded:: 1.0.0
+
+    .. versionchanged:: 2.0.0
+
+        Added :attr:`Merge.UP` option.
     """
 
     LEFT = 0
+    UP = 1
 
     def __str__(self) -> str:
         return ""
diff --git a/table2ascii/preset_style.py b/table2ascii/preset_style.py
index 9480e3f..485736a 100644
--- a/table2ascii/preset_style.py
+++ b/table2ascii/preset_style.py
@@ -25,34 +25,34 @@ class PresetStyle:
         \"\"\"
     """
 
-    thin = TableStyle.from_string("┌─┬─┐││ ├─┼─┤├─┼─┤└┴─┘────┬┴┬┴")
-    thin_box = TableStyle.from_string("┌─┬┬┐│││├─┼┼┤├─┼┼┤└┴┴┘┬┴┬┴┬┴┬┴")
-    thin_rounded = TableStyle.from_string("╭─┬─╮││ ├─┼─┤├─┼─┤╰┴─╯────┬┴┬┴")
-    thin_compact = TableStyle.from_string("┌─┬─┐││ ├─┼─┤     └┴─┘  ──  ┬┴")
-    thin_compact_rounded = TableStyle.from_string("╭─┬─╮││ ├─┼─┤     ╰┴─╯  ──  ┬┴")
-    thin_thick = TableStyle.from_string("┌─┬─┐││ ┝━┿━┥├─┼─┤└┴─┘──━━┬┴┯┷")
-    thin_thick_rounded = TableStyle.from_string("╭─┬─╮││ ┝━┿━┥├─┼─┤╰┴─╯──━━┬┴┯┷")
-    thin_double = TableStyle.from_string("┌─┬─┐││ ╞═╪═╡├─┼─┤└┴─┘──══┬┴╤╧")
-    thin_double_rounded = TableStyle.from_string("╭─┬─╮││ ╞═╪═╡├─┼─┤╰┴─╯──══┬┴╤╧")
-    thick = TableStyle.from_string("┏━┳━┓┃┃ ┣━╋━┫┣━╋━┫┗┻━┛━━━━┳┻┳┻")
-    thick_box = TableStyle.from_string("┏━┳┳┓┃┃┃┣━╋╋┫┣━╋╋┫┗┻┻┛┳┻┳┻┳┻┳┻")
-    thick_compact = TableStyle.from_string("┏━┳━┓┃┃ ┣━╋━┫     ┗┻━┛  ━━  ┳┻")
-    double = TableStyle.from_string("╔═╦═╗║║ ╠═╬═╣╠═╬═╣╚╩═╝════╦╩╦╩")
-    double_box = TableStyle.from_string("╔═╦╦╗║║║╠═╬╬╣╠═╬╬╣╚╩╩╝╦╩╦╩╦╩╦╩")
-    double_compact = TableStyle.from_string("╔═╦═╗║║ ╠═╬═╣     ╚╩═╝  ══  ╦╩")
-    double_thin_box = TableStyle.from_string("╔═╦╤╗║║│╠═╬╪╣╟─╫┼╢╚╩╧╝┬┴╤╧╥╨╦╩")
-    double_thin_compact = TableStyle.from_string("╔═╦═╗║║ ╟─╫─╢     ╚╩═╝  ──  ╥╨")
-    minimalist = TableStyle.from_string(" ───  │  ━━━  ───  ── ──━━┬┴┯┷")
-    borderless = TableStyle.from_string("      ┃  ━              ━━  ━━")
-    simple = TableStyle.from_string(" ═    ║  ═              ══  ╦╩")
-    ascii = TableStyle.from_string("+-+-+|| +-+-++-+-+++-+----++++")
-    ascii_box = TableStyle.from_string("+-+++|||+-++++-+++++++++++++++")
-    ascii_compact = TableStyle.from_string("+-+-+|| +-+-+     ++-+  --  --")
-    ascii_double = TableStyle.from_string("+-+-+|| +=+=++-+-+++-+--==--==")
-    ascii_minimalist = TableStyle.from_string(" ---  |  ===  ---  -- --==--==")
-    ascii_borderless = TableStyle.from_string("      |  -              --  --")
-    ascii_simple = TableStyle.from_string(" =    |  =              ==  ==")
-    ascii_rounded = TableStyle.from_string(r"/===\|| |=|=||-|-|\|=/--==--==")
-    ascii_rounded_box = TableStyle.from_string(r"/===\||||=||||-|||\||/--==--==")
-    markdown = TableStyle.from_string("     ||||-|||           --  --")
-    plain = TableStyle.from_string(" " * 30).set(left_and_right_edge="")
+    thin = TableStyle.from_string("┌─┬─┐││ ├─┼─┤├─┼─┤└┴─┘────┬┴┬┴├┤├┤")
+    thin_box = TableStyle.from_string("┌─┬┬┐│││├─┼┼┤├─┼┼┤└┴┴┘┬┴┬┴┬┴┬┴├┤├┤")
+    thin_rounded = TableStyle.from_string("╭─┬─╮││ ├─┼─┤├─┼─┤╰┴─╯────┬┴┬┴├┤├┤")
+    thin_compact = TableStyle.from_string("┌─┬─┐││ ├─┼─┤     └┴─┘  ──  ┬┴  ├┤")
+    thin_compact_rounded = TableStyle.from_string("╭─┬─╮││ ├─┼─┤     ╰┴─╯  ──  ┬┴  ├┤")
+    thin_thick = TableStyle.from_string("┌─┬─┐││ ┝━┿━┥├─┼─┤└┴─┘──━━┬┴┯┷├┤┝┥")
+    thin_thick_rounded = TableStyle.from_string("╭─┬─╮││ ┝━┿━┥├─┼─┤╰┴─╯──━━┬┴┯┷├┤┝┥")
+    thin_double = TableStyle.from_string("┌─┬─┐││ ╞═╪═╡├─┼─┤└┴─┘──══┬┴╤╧├┤╞╡")
+    thin_double_rounded = TableStyle.from_string("╭─┬─╮││ ╞═╪═╡├─┼─┤╰┴─╯──══┬┴╤╧├┤╞╡")
+    thick = TableStyle.from_string("┏━┳━┓┃┃ ┣━╋━┫┣━╋━┫┗┻━┛━━━━┳┻┳┻┣┫┣┫")
+    thick_box = TableStyle.from_string("┏━┳┳┓┃┃┃┣━╋╋┫┣━╋╋┫┗┻┻┛┳┻┳┻┳┻┳┻┣┫┣┫")
+    thick_compact = TableStyle.from_string("┏━┳━┓┃┃ ┣━╋━┫     ┗┻━┛  ━━  ┳┻  ┣┫")
+    double = TableStyle.from_string("╔═╦═╗║║ ╠═╬═╣╠═╬═╣╚╩═╝════╦╩╦╩╞╡╞╡")
+    double_box = TableStyle.from_string("╔═╦╦╗║║║╠═╬╬╣╠═╬╬╣╚╩╩╝╦╩╦╩╦╩╦╩╠╣╠╣")
+    double_compact = TableStyle.from_string("╔═╦═╗║║ ╠═╬═╣     ╚╩═╝  ══  ╦╩  ╞╡")
+    double_thin_box = TableStyle.from_string("╔═╦╤╗║║│╠═╬╪╣╟─╫┼╢╚╩╧╝┬┴╤╧╥╨╦╩├┤╞╡")
+    double_thin_compact = TableStyle.from_string("╔═╦═╗║║ ╟─╫─╢     ╚╩═╝  ──  ╥╨  ├┤")
+    minimalist = TableStyle.from_string(" ───  │  ━━━  ───  ── ──━━┬┴┯┷    ")
+    borderless = TableStyle.from_string("      ┃  ━              ━━  ━━    ")
+    simple = TableStyle.from_string(" ═    ║  ═              ══  ╦╩    ")
+    ascii = TableStyle.from_string("+-+-+|| +-+-++-+-+++-+----++++++++")
+    ascii_box = TableStyle.from_string("+-+++|||+-++++-+++++++++++++++++++")
+    ascii_compact = TableStyle.from_string("+-+-+|| +-+-+     ++-+  --  --  ++")
+    ascii_double = TableStyle.from_string("+-+-+|| +=+=++-+-+++-+--==--==++++")
+    ascii_minimalist = TableStyle.from_string(" ---  |  ===  ---  -- --==--==    ")
+    ascii_borderless = TableStyle.from_string("      |  -              --  --    ")
+    ascii_simple = TableStyle.from_string(" =    |  =              ==  ==    ")
+    ascii_rounded = TableStyle.from_string(r"/===\|| |=|=||-|-|\|=/--==--==    ")
+    ascii_rounded_box = TableStyle.from_string(r"/===\||||=||||-|||\||/--==--==||||")
+    markdown = TableStyle.from_string("     ||||-|||           --  --||||")
+    plain = TableStyle.from_string(" " * 34).set(left_and_right_edge="")
diff --git a/table2ascii/table_style.py b/table2ascii/table_style.py
index 23db0ac..4d4a22f 100644
--- a/table2ascii/table_style.py
+++ b/table2ascii/table_style.py
@@ -37,36 +37,45 @@ class TableStyle:
         ║ SUM ║ 130 │ 140 │ 135 │ 130 ║
         ╚═════╩═════╧═════╧═════╧═════╝
 
-    In addition to the parts above, W-Z and the four fields that follow
-    (labeled 0-3) are used for top and bottom edges of merged cells as shown:
+    In addition to the parts above, W-Z and 0-3 are used for top and bottom
+    edges of merged-left cells, and 4-7 are used for left and right edges
+    of merged-up cells, as shown:
 
     .. code-block::
 
-        ╔══════════════╤══════╤══════╗
-        ║    Header    │      │      ║
-        ╠══════[2]═════╪═════[Z]═════╣
-        ║       ║      │             ║
-        ╟──────[1]─────┼─────────────╢
-        ║              │             ║
-        ╟──────[0]─────┼─────[W]─────╢
-        ║       ║      │      │      ║
-        ╟───────╫──────┼─────[X]─────╢
-        ║       ║      │             ║
-        ╠══════[3]═════╪═════[Y]═════╣
-        ║    Footer    │      │      ║
-        ╚══════════════╧══════╧══════╝
+        ╔═════════╤════╤════╤═══╤═══╗
+        ║ Header  │    │    │   │   ║
+        ╠═══[2]═══╪═══[Z]═══╡  [6]══╣
+        ║    ║    │         │   │   ║
+        ╟───[1]──[5]       [4]──┼───╢
+        ║         │         │   │   ║
+        ╟───[0]───┼───[W]───┼───┼───╢
+        ║    ║    │    │    │   │   ║
+        ╟────╫────┼───[X]───┼───┼───╢
+        ║    ║    │         │   │   ║
+        ╠═══[3]═══╪═══[Y]══[7]  ├───╢
+        ║ Footer  │    │    │   │   ║
+        ╚═════════╧════╧════╧═══╧═══╝
 
         [W] = ┬ [X] = ┴ [Y] = ╤ [Z] = ╧
         [0] = ╥ [1] = ╨ [2] = ╦ [3] = ╩
+        [4] = ├ [5] = ┤ [6] = ╞ [7] = ╡
 
     .. versionchanged:: 1.0.0
 
-        Added fields for edges of merged cells:
+        Added fields for edges of merged-left cells:
 
         ``col_row_top_tee``, ``col_row_bottom_tee``, ``heading_row_top_tee``,
         ``heading_row_bottom_tee``, ``heading_col_body_row_top_tee``,
         ``heading_col_body_row_bottom_tee``, ``heading_col_heading_row_top_tee``,
         ``heading_col_heading_row_bottom_tee``
+
+    .. versionchanged:: 2.0.0
+
+        Added fields for edges of merged-up cells:
+
+        ``col_row_left_tee``, ``col_row_right_tee``, ``col_heading_row_left_tee``,
+        ``col_heading_row_right_tee``
     """
 
     # parts of the table
@@ -100,6 +109,10 @@ class TableStyle:
     heading_col_body_row_bottom_tee: str  # 1
     heading_col_heading_row_top_tee: str  # 2
     heading_col_heading_row_bottom_tee: str  # 3
+    col_row_left_tee: str  # 4
+    col_row_right_tee: str  # 5
+    col_heading_row_left_tee: str  # 6
+    col_heading_row_right_tee: str  # 7
 
     @classmethod
     def from_string(cls, string: str) -> "TableStyle":
@@ -119,7 +132,7 @@ def from_string(cls, string: str) -> "TableStyle":
 
         Example::
 
-            TableStyle.from_string("╔═╦╤╗║║│╠═╬╪╣╟─╫┼╢╚╩╧╝┬┴╤╧╥╨╦╩")
+            TableStyle.from_string("╔═╦╤╗║║│╠═╬╪╣╟─╫┼╢╚╩╧╝┬┴╤╧╥╨╦╩├┤╞╡")
 
         Raises:
             TableStyleTooLongError: If the string is too long
diff --git a/table2ascii/table_to_ascii.py b/table2ascii/table_to_ascii.py
index dd092e2..e8fb31a 100644
--- a/table2ascii/table_to_ascii.py
+++ b/table2ascii/table_to_ascii.py
@@ -416,6 +416,43 @@ def __line_in_cell_column_to_ascii(
         Returns:
             The column in the ascii table
         """
+        # set values for checking for merged cells
+        next_value = prev_row_next_value = next_row_next_value = None
+        next_row_value = next_content_row[col_index] if next_content_row else None
+        if col_index < self.__columns - 1:
+            next_value = filler[col_index + 1] if isinstance(filler, list) else None
+            prev_row_next_value = (
+                previous_content_row[col_index + 1] if previous_content_row else None
+            )
+            next_row_next_value = next_content_row[col_index + 1] if next_content_row else None
+
+        # change separators and fillers if the cell below is merged up
+        above_merged_up_cell = False
+        next_column_above_merged_up_cell = False
+        is_heading_column = (col_index == 0 and self.__first_col_heading) or (
+            col_index == self.__columns - 2 and self.__last_col_heading
+        )
+        is_heading_row = previous_content_row == self.__header or next_content_row == self.__footer
+        if column_separator != " " and next_row_value is Merge.UP:
+            above_merged_up_cell = True
+            filler = " "
+            column_separator = self.__style.col_row_left_tee
+            if is_heading_row:
+                column_separator = self.__style.col_heading_row_left_tee
+        if column_separator != " " and next_row_next_value is Merge.UP:
+            next_column_above_merged_up_cell = True
+            column_separator = self.__style.col_row_right_tee
+            if is_heading_row and is_heading_column:
+                column_separator = self.__style.heading_row_right_tee
+            elif is_heading_column:
+                column_separator = self.__style.row_right_tee
+            elif is_heading_row:
+                column_separator = self.__style.col_heading_row_right_tee
+        if column_separator != " " and above_merged_up_cell and next_column_above_merged_up_cell:
+            column_separator = self.__style.col_sep
+            if is_heading_column:
+                column_separator = self.__style.heading_col_sep
+
         output = ""
         col_content = (
             # if filler is a separator character, repeat it for the full width of the column
@@ -430,17 +467,9 @@ def __line_in_cell_column_to_ascii(
             )
         )
         output += col_content
-        # check for merged cells
-        next_value = prev_row_next_value = next_row_next_value = None
-        if col_index < self.__columns - 1:
-            next_value = filler[col_index + 1] if isinstance(filler, list) else None
-            prev_row_next_value = (
-                previous_content_row[col_index + 1] if previous_content_row else None
-            )
-            next_row_next_value = next_content_row[col_index + 1] if next_content_row else None
         # column separator
         sep = column_separator
-        # handle separators between rows when previous or next row is a merged cell
+        # handle separators between rows when previous or next row is a merged-left cell
         if top_tee and prev_row_next_value is Merge.LEFT:
             sep = top_tee
         if bottom_tee and next_row_next_value is Merge.LEFT:
@@ -452,9 +481,7 @@ def __line_in_cell_column_to_ascii(
         ):
             sep = filler
         # use column heading if first or last column option is specified
-        if (col_index == 0 and self.__first_col_heading) or (
-            col_index == self.__columns - 2 and self.__last_col_heading
-        ):
+        if is_heading_column and not next_column_above_merged_up_cell:
             sep = heading_col_sep
             # handle separators between rows when previous or next row is a merged cell
             if heading_col_top_tee and prev_row_next_value is Merge.LEFT:
@@ -464,6 +491,8 @@ def __line_in_cell_column_to_ascii(
         # replace last separator with symbol for edge of the row
         elif col_index == self.__columns - 1:
             sep = right_edge
+            if above_merged_up_cell:
+                sep = self.__style.left_and_right_edge
         # if this is cell contents and the next column is Merge.LEFT, don't add a separator
         if next_value is Merge.LEFT:
             sep = ""
diff --git a/tests/test_merge.py b/tests/test_merge.py
index 3555ce9..df77959 100644
--- a/tests/test_merge.py
+++ b/tests/test_merge.py
@@ -173,3 +173,69 @@ def test_row_beginning_with_merge():
         "╚═══════╧═══╧═══╝"
     )
     assert text == expected
+
+
+def test_merge_up():
+    text = t2a(
+        header=["0", "1", "A", "B", "C", "D"],
+        body=[
+            ["A", Merge.UP, "C", Merge.UP, Merge.UP, Merge.UP],
+            ["D", Merge.LEFT, "E", Merge.LEFT, "F", "G"],
+            ["F", "G", "H", "I", "J", "K"],
+            ["J", Merge.UP, "L", "M", Merge.UP, Merge.UP],
+        ],
+        column_widths=[5] * 6,
+        footer=["Footer", Merge.LEFT, Merge.UP, "N", "O", Merge.UP],
+        first_col_heading=True,
+        last_col_heading=True,
+        style=PresetStyle.double_thin_box,
+    )
+    expected = (
+        "╔═════╦═════╤═════╤═════╤═════╦═════╗\n"
+        "║  0  ║  1  │  A  │  B  │  C  ║  D  ║\n"
+        "╠═════╣     ╞═════╡     │     ║     ║\n"
+        "║  A  ║     │  C  │     │     ║     ║\n"
+        "╟─────╨─────┼─────┴─────┼─────╫─────╢\n"
+        "║     D     │     E     │  F  ║  G  ║\n"
+        "╟─────╥─────┼─────┬─────┼─────╫─────╢\n"
+        "║  F  ║  G  │  H  │  I  │  J  ║  K  ║\n"
+        "╟─────╢     ├─────┼─────┤     ║     ║\n"
+        "║  J  ║     │  L  │  M  │     ║     ║\n"
+        "╠═════╩═════╡     ╞═════╪═════╣     ║\n"
+        "║  Footer   │     │  N  │  O  ║     ║\n"
+        "╚═══════════╧═════╧═════╧═════╩═════╝"
+    )
+    assert text == expected
+
+
+def test_merge_left_and_up_square():
+    text = t2a(
+        header=["0", "1", "A", "B", "C", "D"],
+        body=[
+            ["A", Merge.UP, "C", Merge.UP, Merge.UP, Merge.UP],
+            ["D", Merge.LEFT, "E", Merge.LEFT, "F", "G"],
+            ["F", "G", Merge.UP, Merge.UP, "J", "K"],
+            ["J", Merge.UP, "L", "M", Merge.UP, Merge.UP],
+        ],
+        column_widths=[5] * 6,
+        footer=["Footer", Merge.LEFT, Merge.UP, "N", "O", Merge.UP],
+        first_col_heading=True,
+        last_col_heading=True,
+        style=PresetStyle.double_thin_box,
+    )
+    expected = (
+        "╔═════╦═════╤═════╤═════╤═════╦═════╗\n"
+        "║  0  ║  1  │  A  │  B  │  C  ║  D  ║\n"
+        "╠═════╣     ╞═════╡     │     ║     ║\n"
+        "║  A  ║     │  C  │     │     ║     ║\n"
+        "╟─────╨─────┼─────┴─────┼─────╫─────╢\n"
+        "║     D     │     E     │  F  ║  G  ║\n"
+        "╟─────╥─────┤           ├─────╫─────╢\n"
+        "║  F  ║  G  │           │  J  ║  K  ║\n"
+        "╟─────╢     ├─────┬─────┤     ║     ║\n"
+        "║  J  ║     │  L  │  M  │     ║     ║\n"
+        "╠═════╩═════╡     ╞═════╪═════╣     ║\n"
+        "║  Footer   │     │  N  │  O  ║     ║\n"
+        "╚═══════════╧═════╧═════╧═════╩═════╝"
+    )
+    assert text == expected
