diff --git a/pytools/__init__.py b/pytools/__init__.py
index b7dc0989835991c6c29392894b48743a942b05ee..22459de742ba7067f93ade6e2611f5ea388d3960 100644
--- a/pytools/__init__.py
+++ b/pytools/__init__.py
@@ -1497,30 +1497,106 @@ a_star = MovedFunctionDeprecationWrapper(a_star_moved)
 class Table:
     """An ASCII table generator.
 
+    :arg alignments: List of alignments of each column ('l', 'c', or 'r',
+        for left, center, and right alignment, respectively). Columns which
+        have no alignment specifier will use the last specified alignment. For
+        example, with `alignments=['l', 'r']`, the third and all following
+        columns will use 'r' alignment.
+
     .. automethod:: add_row
     .. automethod:: __str__
     .. automethod:: latex
+    .. automethod:: github_markdown
     """
 
-    def __init__(self):
+    def __init__(self, alignments=None):
         self.rows = []
+        if alignments is not None:
+            self.alignments = alignments
+        else:
+            self.alignments = ['l']
 
     def add_row(self, row):
         self.rows.append([str(i) for i in row])
 
     def __str__(self):
+        """
+        Returns a string representation of the table.
+
+        .. doctest ::
+
+            >>> tbl = Table(alignments=['l', 'r', 'l'])
+            >>> tbl.add_row([1, '|'])
+            >>> tbl.add_row([10, '20||'])
+            >>> print(tbl)
+            1  |    |
+            ---+------
+            10 | 20||
+
+        """
+
         columns = len(self.rows[0])
         col_widths = [max(len(row[i]) for row in self.rows)
                       for i in range(columns)]
 
-        lines = [" | ".join([cell.ljust(col_width)
-            for cell, col_width in zip(row, col_widths)])
+        alignments = self.alignments
+        # If not all alignments were specified, extend alignments with the
+        # last alignment specified:
+        alignments += self.alignments[-1] * (columns - len(self.alignments))
+
+        lines = [" | ".join([
+            cell.center(col_width) if align == "c"
+            else cell.ljust(col_width) if align == "l"
+            else cell.rjust(col_width)
+            for cell, col_width, align in zip(row, col_widths, alignments)])
             for row in self.rows]
         lines[1:1] = ["+".join("-" * (col_width + 1 + (i > 0))
             for i, col_width in enumerate(col_widths))]
 
         return "\n".join(lines)
 
+    def github_markdown(self):
+        """Returns a string representation of the table formatted as
+        `GitHub-Flavored Markdown.
+        <https://docs.github.com/en/github/writing-on-github/organizing-information-with-tables>`__
+
+        .. doctest ::
+
+            >>> tbl = Table(alignments=['l', 'r', 'l'])
+            >>> tbl.add_row([1, '|'])
+            >>> tbl.add_row([10, '20||'])
+            >>> print(tbl.github_markdown())
+            1  |     \|
+            :--|-------:
+            10 | 20\|\|
+
+        """  # noqa: W605
+        # Pipe symbols ('|') must be replaced
+        rows = [[w.replace('|', '\\|') for w in r] for r in self.rows]
+
+        columns = len(rows[0])
+        col_widths = [max(len(row[i]) for row in rows)
+                      for i in range(columns)]
+
+        alignments = self.alignments
+        # If not all alignments were specified, extend alignments with the
+        # last alignment specified:
+        alignments += self.alignments[-1] * (columns - len(self.alignments))
+
+        lines = [" | ".join([
+            cell.center(col_width) if align == "c"
+            else cell.ljust(col_width) if align == "l"
+            else cell.rjust(col_width)
+            for cell, col_width, align in zip(row, col_widths, alignments)])
+            for row in rows]
+        lines[1:1] = ["|".join(
+            ":" + "-" * (col_width - 1 + (i > 0)) + ":" if align == "c"
+            else ":" + "-" * (col_width + (i > 0)) if align == "l"
+            else "-" * (col_width + (i > 0)) + ":"
+            for i, (col_width, align) in enumerate(zip(col_widths, alignments)))]
+
+        return "\n".join(lines)
+
     def latex(self, skip_lines=0, hline_after=None):
         if hline_after is None:
             hline_after = []