Commits

Sergey Astanin committed ab757f0

colons in pipe format; better doctests; remove ALIGN*, TABLE*

Comments (0)

Files changed (1)

 from collections import namedtuple
 
 
-__all__ = ["tabulate", "TableFormat",
-           "ALIGN_LEFT", "ALIGN_RIGHT", "ALIGN_CENTER", "ALIGN_DECIMAL",
-           "TABLE_SIMPLE", "TABLE_GRID", "TABLE_PIPE", "TABLE_ORGTBL"]
-
-
-ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_DECIMAL = range(4)
-TABLE_SIMPLE, TABLE_GRID, TABLE_PIPE, TABLE_ORGTBL = range(4)
+__all__ = ["tabulate", "TableFormat" ]
 
 
 TableFormat = namedtuple("TableFormat", ["lineabove", "linebelow",
                                          "rowbegin", "rowend",
                                          "colons_align_columns"])
 
-_table_formats = {"simple":
+_table_formats = {"plain":
+                  TableFormat(lineabove=None, linebelow=None,
+                              headersline=None, rowline=None,
+                              colsep="  ", intersect="  ", edgeintersect="  ",
+                              rowbegin="", rowend="",
+                              colons_align_columns=False),
+                  "simple":
                   TableFormat(lineabove=None, linebelow="-",
                               headersline="-", rowline=None,
                               colsep="  ", intersect="  ", edgeintersect="",
                               colons_align_columns=False) }
 
 
-for key,strkey in zip([TABLE_SIMPLE, TABLE_GRID, TABLE_PIPE, TABLE_ORGTBL],
-                      ["simple", "grid", "pipe", "orgtbl"]):
-    _table_formats[key] = _table_formats[strkey]
-
-
 def _isconvertible(conv, string):
     try:
         n = conv(string)
     ['   12.345  ', '-1234.5    ', '    1.23   ', ' 1234.5    ', '    1e+234 ', '    1.0e234']
 
     """
-    if alignment in [ALIGN_RIGHT, "right"]:
+    if alignment == "right":
         strings = [s.strip() for s in strings]
         padfn = _padleft
-    elif alignment in [ALIGN_CENTER, "center"]:
+    elif alignment in "center":
         strings = [s.strip() for s in strings]
         padfn = _padboth
-    elif alignment in [ALIGN_DECIMAL, "decimal"]:
+    elif alignment in "decimal":
         decimals = map(_afterpoint, strings)
         maxdecimals = max(decimals)
         strings = [s + (maxdecimals - decs) * " "
 
 
 def _align_header(header, alignment, width):
-    if alignment in [ALIGN_LEFT, "left"]:
+    if alignment == "left":
         return _padright(width, header)
-    elif alignment in [ALIGN_CENTER, "center"]:
+    elif alignment == "center":
         return _padboth(width, header)
     else:
         return _padleft(width, header)
              floatfmt="g", numalign="decimal", stralign="left"):
     """Format a fixed width table for pretty printing.
 
-    >>> print(tabulate([[1, 2.34], [-56.7, "8.999"], ["2", "10001"]]))
-    -----  ---------
-      1        2.34
-    -56.7      8.999
-      2    10001
-    -----  ---------
+    >>> print(tabulate([[1, 2.34], [-56, "8.999"], ["2", "10001"]]))
+    ---  ---------
+      1      2.34
+    -56      8.999
+      2  10001
+    ---  ---------
 
     If headers is not empty, it is used as a list of column names
     to print a nice header. Otherwise a headerless table is produced.
 
-    Supported plain-text table formats (`tablefmt`) are: 'simple'
-    (like Pandoc's simple_tables), 'grid' (like Emacs' table.el
-    tables, with "=" used to show separated the headers), 'pipe'
-    (like in PHP Markdown Extra), 'orgtbl' (like Emacs' orgtbl-mode).
+    `tabulate` tries to detect column types automatically, and aligns
+    the values properly. By default it aligns decimal points of the
+    numbers (or flushes integer numbers to the right), and flushes
+    everything else to the left. Possible column alignments
+    (`numalign`, `stralign`) are: right, center, left, decimal (only
+    for `numalign`).
 
     `floatfmt` is a format specification used for columns which
     contain numeric data with a decimal point.
 
-    Possible column alignments (`numalign`, `stralign`): right,
-    center, left, decimal (for `numalign`).
-
-    Various table formats:
-
-    >>> print(tabulate([["foo","bar"]], ["spam","eggs"], tablefmt="simple"))
-    spam    eggs
-    ------  ------
-    foo     bar
-    ------  ------
-
-    >>> print(tabulate([["foo","bar"]], ["spam","eggs"],tablefmt="grid"))
-    +------+------+
-    |spam  |eggs  |
-    +======+======+
-    |foo   |bar   |
-    +------+------+
-
-    >>> print(tabulate([["foo","bar"]], ["spam","eggs"],tablefmt="pipe"))
-    |spam  |eggs  |
-    |------|------|
-    |foo   |bar   |
-
-    >>> print(tabulate([["foo","bar"]], ["spam","eggs"],tablefmt="orgtbl"))
-    |spam  |eggs  |
-    |------+------|
-    |foo   |bar   |
+    Various plain-text table formats (`tablefmt`) are supported:
+    'plain', 'simple', 'grid', 'pipe', and 'orgtbl'.
+
+    "plain" format doesn't use any pseudographics to draw tables,
+    it separates columns with a double space:
+
+    >>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]],
+    ...                 ["strings", "numbers"], "plain"))
+    strings      numbers
+    spam         41.9999
+    eggs        451
+
+    "simple" format is like Pandoc's simple_tables:
+
+    >>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]],
+    ...                 ["strings", "numbers"], "simple"))
+    strings      numbers
+    ---------  ---------
+    spam         41.9999
+    eggs        451
+    ---------  ---------
+
+    "grid" is similar to Emacs' table.el tables or Padoc's grid_tables:
+
+    >>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]],
+    ...                ["strings", "numbers"], "grid"))
+    +---------+---------+
+    |strings  |  numbers|
+    +=========+=========+
+    |spam     |  41.9999|
+    +---------+---------+
+    |eggs     | 451     |
+    +---------+---------+
+
+    "pipe" is like PHP Markdown Extra or Pandoc's pipe_tables:
+
+    >>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]],
+    ...                ["strings", "numbers"], "pipe"))
+    |strings  |  numbers|
+    |:--------|--------:|
+    |spam     |  41.9999|
+    |eggs     | 451     |
+
+    "orgtbl" is like tables in Emacs orgtbl-mode. It is slightly
+    different from"pipe" format by not using colons to define column alignment,
+    and using a "+" sign to indicate line intersections:
+
+    >>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]],
+    ...                ["strings", "numbers"], "orgtbl"))
+    |strings  |  numbers|
+    |---------+---------|
+    |spam     |  41.9999|
+    |eggs     | 451     |
 
     """
     # format rows and columns, convert numeric values to strings
         rows = zip(*cols)
 
     tablefmt = _table_formats.get(tablefmt, _table_formats["simple"])
-    return _format_table(tablefmt, headers, rows, minwidths)
+    return _format_table(tablefmt, headers, rows, minwidths, aligns)
 
 
-def _format_table(fmt, headers, rows, colwidths):
+def _format_table(fmt, headers, rows, colwidths, colaligns):
     """Produce a plain-text representation of the table."""
     lines = []
 
         cells = [fill*w for w in colwidths]
         return cells
 
+    def fill_cell_with_colons(fill, align, colwidth):
+        if align in ["right", "decimal"]:
+            return (fill * (colwidth - 1)) + ":"
+        elif align == "center":
+            return ":" + (fill * (colwidth - 2)) + ":"
+        elif align == "left":
+            return ":" + (fill * (colwidth - 1))
+        else:
+            return fill * colwidth
+
     if fmt.lineabove:
         lines.append(build_line(fill_cells(fmt.lineabove), fmt.intersect,
                                 fmt.edgeintersect, fmt.edgeintersect))
         lines.append(build_line(headers, fmt.colsep, fmt.rowbegin, fmt.rowend))
 
     if fmt.headersline:
-        # TODO: consider colons_align_columns
-        lines.append(build_line(fill_cells(fmt.headersline), fmt.intersect,
+        fill = fmt.headersline
+        if fmt.colons_align_columns:
+            cells = [fill_cell_with_colons(fill, a, w)
+                     for w, a in zip(colwidths, colaligns)]
+        else:
+            cells = fill_cells(fill)
+        lines.append(build_line(cells, fmt.intersect,
                                 fmt.edgeintersect, fmt.edgeintersect))
 
     if rows and fmt.rowline:  # with lines between rows
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.