summaryrefslogtreecommitdiff
path: root/asciidoc/blocks/table.py
diff options
context:
space:
mode:
Diffstat (limited to 'asciidoc/blocks/table.py')
-rw-r--r--asciidoc/blocks/table.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/asciidoc/blocks/table.py b/asciidoc/blocks/table.py
new file mode 100644
index 0000000..489260b
--- /dev/null
+++ b/asciidoc/blocks/table.py
@@ -0,0 +1,75 @@
+import copy
+import re
+from typing import Optional, Tuple
+
+ALIGN = {'<': 'left', '>': 'right', '^': 'center'}
+VALIGN = {'<': 'top', '>': 'bottom', '^': 'middle'}
+
+
+def parse_align_spec(align_spec: Optional[str]) -> Tuple[Optional[str], Optional[str]]:
+ """
+ Parse AsciiDoc cell alignment specifier and return 2-tuple with
+ horizontal and vertical alignment names. Unspecified alignments
+ set to None.
+ """
+ result = (None, None)
+ if align_spec:
+ mo = re.match(r'^([<\^>])?(\.([<\^>]))?$', align_spec)
+ if mo:
+ result = (
+ ALIGN.get(mo.group(1)),
+ VALIGN.get(mo.group(3)),
+ )
+ return result
+
+
+# TODO: remove _table_ from name once Table class has been moved into this file
+def parse_table_span_spec(span_spec: Optional[str]) -> Tuple[int, int]:
+ """
+ Parse AsciiDoc cell span specifier and return 2-tuple with horizontal
+ and vertical span counts. Set default values (1,1) if not
+ specified.
+ """
+ result = (None, None)
+ if span_spec:
+ mo = re.match(r'^(\d+)?(\.(\d+))?$', span_spec)
+ if mo:
+ result = (
+ mo.group(1) and int(mo.group(1)),
+ mo.group(3) and int(mo.group(3)),
+ )
+ return (result[0] or 1, result[1] or 1)
+
+
+class Column:
+ """Table column."""
+ def __init__(self, width=None, align_spec=None, style=None):
+ self.width = width or '1'
+ self.halign, self.valign = parse_align_spec(align_spec)
+ self.style = style # Style name or None.
+ # Calculated attribute values.
+ self.abswidth = None # 1.. (page units).
+ self.pcwidth = None # 1..99 (percentage).
+
+
+class Cell:
+ def __init__(self, data, span_spec=None, align_spec=None, style=None):
+ self.data = data
+ self.span, self.vspan = parse_table_span_spec(span_spec)
+ self.halign, self.valign = parse_align_spec(align_spec)
+ self.style = style
+ self.reserved = False
+
+ def __repr__(self):
+ return '<Cell: %d.%d %s.%s %s "%s">' % (
+ self.span, self.vspan,
+ self.halign, self.valign,
+ self.style or '',
+ self.data)
+
+ def clone_reserve(self):
+ """Return a clone of self to reserve vertically spanned cell."""
+ result = copy.copy(self)
+ result.vspan = 1
+ result.reserved = True
+ return result