From f84c47622786b654f2dfbe2e6d79b7f269a91a06 Mon Sep 17 00:00:00 2001 From: Vincent Driessen Date: Thu, 19 Aug 2010 12:21:08 +0200 Subject: Add line partitioner. Is able to parse tables of the form: +=====+=====================+ | Foo | Bar | +=====+=====================+ | x | This is a long line | | | that is spread out | | | over multiple lines | +-----+---------------------+ Into: [['Foo', 'Bar'], ['x', 'This is a long line\nthat is spread out\nover multiple lines']] The draw_table function needs to be written still, though. --- ftplugin/rst_tables.vim | 37 ++++++++++++++++++++++++++++++++++--- src/rst_tables.py | 37 ++++++++++++++++++++++++++++++++++--- tests/test_rst_tables.py | 22 +++++++++++++++++----- 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/ftplugin/rst_tables.vim b/ftplugin/rst_tables.vim index 72fe5d4..c793dac 100644 --- a/ftplugin/rst_tables.vim +++ b/ftplugin/rst_tables.vim @@ -63,6 +63,37 @@ def join_rows(rows, sep='\n'): return map(lambda lines: sep.join(lines), output) +def line_is_separator(line): + return re.match('^[\t +=-]+$', line) + +def has_line_seps(raw_lines): + for line in raw_lines: + if line_is_separator(line): + return True + return False + + +def partition_raw_lines(raw_lines): + """Partitions a list of raw input lines so that between each partition, a + table row separator can be placed. + + """ + if not has_line_seps(raw_lines): + return map(lambda x: [x], raw_lines) + + curr_part = [] + parts = [curr_part] + for line in raw_lines: + if line_is_separator(line): + curr_part = [] + parts.append(curr_part) + else: + curr_part.append(line) + + # remove any empty partitions (typically the first and last ones) + return filter(lambda x: x != [], parts) + + def unify_table(table): """Given a list of rows (i.e. a table), this function returns a new table in which all rows have an equal amount of columns. If all full column is @@ -106,9 +137,9 @@ def split_table_row(row_string): def parse_table(raw_lines): - select_data_lines = lambda line: not re.match('^[\t +=-]+$', line) - lines = filter(select_data_lines, raw_lines) - lines = map(split_table_row, lines) + row_partition = partition_raw_lines(raw_lines) + lines = map(lambda row_string: join_rows(map(split_table_row, row_string)), + row_partition) return unify_table(lines) diff --git a/src/rst_tables.py b/src/rst_tables.py index 7273b8d..952a2b2 100644 --- a/src/rst_tables.py +++ b/src/rst_tables.py @@ -44,6 +44,37 @@ def join_rows(rows, sep='\n'): return map(lambda lines: sep.join(lines), output) +def line_is_separator(line): + return re.match('^[\t +=-]+$', line) + +def has_line_seps(raw_lines): + for line in raw_lines: + if line_is_separator(line): + return True + return False + + +def partition_raw_lines(raw_lines): + """Partitions a list of raw input lines so that between each partition, a + table row separator can be placed. + + """ + if not has_line_seps(raw_lines): + return map(lambda x: [x], raw_lines) + + curr_part = [] + parts = [curr_part] + for line in raw_lines: + if line_is_separator(line): + curr_part = [] + parts.append(curr_part) + else: + curr_part.append(line) + + # remove any empty partitions (typically the first and last ones) + return filter(lambda x: x != [], parts) + + def unify_table(table): """Given a list of rows (i.e. a table), this function returns a new table in which all rows have an equal amount of columns. If all full column is @@ -87,9 +118,9 @@ def split_table_row(row_string): def parse_table(raw_lines): - select_data_lines = lambda line: not re.match('^[\t +=-]+$', line) - lines = filter(select_data_lines, raw_lines) - lines = map(split_table_row, lines) + row_partition = partition_raw_lines(raw_lines) + lines = map(lambda row_string: join_rows(map(split_table_row, row_string)), + row_partition) return unify_table(lines) diff --git a/tests/test_rst_tables.py b/tests/test_rst_tables.py index 0f1f354..381adf8 100644 --- a/tests/test_rst_tables.py +++ b/tests/test_rst_tables.py @@ -22,7 +22,8 @@ import unittest # Load test subjects from rst_tables import get_table_bounds, reformat_table, parse_table, \ draw_table, table_line, get_column_widths, \ - pad_fields, unify_table, join_rows + pad_fields, unify_table, join_rows, \ + partition_raw_lines class TestRSTTableFormatter(unittest.TestCase): @@ -67,6 +68,19 @@ class TestRSTTableFormatter(unittest.TestCase): expected = ['x foo apple', 'y bar', 'z pear'] self.assertEquals(expected, join_rows(input_rows, sep=' ')) + def testPartitionRawLines(self): + self.assertEquals([], partition_raw_lines([])) + self.assertEquals([['']], partition_raw_lines([''])) + self.assertEquals( + [['foo'], ['bar']], + partition_raw_lines(['foo', 'bar'])) + self.assertEquals( + [['foo'], ['bar']], + partition_raw_lines(['foo', '+----+', 'bar'])) + self.assertEquals( + [['foo', 'bar'], ['baz']], + partition_raw_lines(['+-----+', 'foo', 'bar', '----', 'baz'])) + def testParseSimpleTable(self): self.assertEquals([['x y z']], parse_table(['x y z'])) self.assertEquals([['x', 'y z']], parse_table(['x y z'])) @@ -119,8 +133,7 @@ class TestRSTTableFormatter(unittest.TestCase): 'blah | A new line| ', '+-----+----+'] expect = [['Foo', 'Mu'], - ['x', 'This became somewhat larger'], - ['blah', 'A new line']] + ['x\nblah', 'This became somewhat larger\nA new line']] self.assertEquals(expect, parse_table(input)) input = ['+===+-----====+', @@ -130,8 +143,7 @@ class TestRSTTableFormatter(unittest.TestCase): 'blah | A new line|| ', '+-----+----+'] expect = [['Foo', 'Mu'], - ['x', 'This became somewhat larger'], - ['blah', 'A new line']] + ['x\nblah', 'This became somewhat larger\nA new line']] self.assertEquals(expect, parse_table(input)) def testTableLine(self): -- cgit v1.2.3