diff --git a/extensions/fablabchemnitz/chip_scratches/chip_scratches.py b/extensions/fablabchemnitz/chip_scratches/chip_scratches.py
index 2d721a1f..3b3a4460 100644
--- a/extensions/fablabchemnitz/chip_scratches/chip_scratches.py
+++ b/extensions/fablabchemnitz/chip_scratches/chip_scratches.py
@@ -718,44 +718,6 @@ specks=(
"M -0.0742332 -0.173289 c -0.15768,0.0526 0.1494,0.70495 0.19313,0.0823 -0.0947,-0.0745 -0.15647,-0.0942 -0.19313,-0.0823 z",
)
-inxhead = """
-
- <_name>ChipScratches
- ca.sfu.AT.kurn.ChipScratches
- chipScratches.py
- inkex.py
-"""
-
-inxfoot = """
- all
-
-
-
-
-
-
-
-
-"""
-
-inxtype = {
- "i" : '%s\n',
- "f" : '%s\n',
- "s" : '%s\n',
- "b" : '%s\n',
- "n" : '\n',
- }
-
-inxbk = {
- "tabs" : '\n\n',
- "tab" : '\n\n',
- "tabe" : '\n\n',
- "lit" : '<_param name="%(s)s" type="description" >%(s)s\n',
-
- }
-
def mt( s ) :
return s.isspace() or len(s) == 0
diff --git a/extensions/fablabchemnitz/table_support/base_transform.py b/extensions/fablabchemnitz/table_support/base_transform.py
new file mode 100644
index 00000000..7365808b
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/base_transform.py
@@ -0,0 +1,266 @@
+#!/usr/bin/env python3
+"""
+base_transform.py
+Base matemathical operations for SVG 3x3 matrices
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+
+import re
+import inkex
+import os
+from math import *
+
+class BaseTransform(inkex.Effect):
+ unitMatrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
+
+ def isset(self, v, i = None):
+ try:
+ if (i is None):
+ v
+ else:
+ v[i]
+ return True
+ except:
+ return False
+
+ def __init__(self):
+ inkex.Effect.__init__(self)
+
+ def sizeToPx(self, s, dim = "y"):
+ root = self.document.getroot()
+ try:
+ factor = float(root.attrib[inkex.addNS('export-' + dim + 'dpi', 'inkscape')])
+ except:
+ factor = 90
+ unit = ''
+ pattern = '[\\-\\d\\.]+([a-zA-Z][a-zA-Z])'
+ if (re.search(pattern, s)):
+ res = re.search(pattern, s)
+ unit = res.group(1)
+ pattern = '^([\\-\\d\\.]*)'
+ res = re.search(pattern, s)
+ n = float(res.group(1))
+ if unit == 'cm':
+ return (n / 2.54) * factor
+ elif unit == 'ft':
+ return n * 12 * factor
+ elif unit == 'in':
+ return n * factor
+ elif unit == 'm':
+ return ((n * 10) / 2.54) * factor
+ elif unit == 'mm':
+ return ((n / 10) / 2.54) * factor
+ elif unit == 'pc':
+ return ((n * 2.36228956229) / 2.54) * factor
+ elif unit == 'pt':
+ return (((n / 2.83464646465) / 10) / 2.54) * factor
+ elif unit == 'px' or unit == '':
+ return n
+
+ return 0
+
+ def transform(self, el):
+ result = self.unitMatrix
+ if (el.tag == inkex.addNS('svg', 'svg')):
+ return result
+
+ if (not self.isset(el.attrib, 'transform')):
+ return self.multiply(self.transform(el.getparent()), result)
+ pattern = '(matrix|translate|scale|rotate|skewX|skewY)[\\s|,]*\\(([^\\)]*)\\)'
+ transforms = re.findall(pattern, el.attrib['transform'])
+
+ for transform in transforms:
+ values = re.split('[\\s|,]+', transform[1])
+ for i in range(len(values)):
+ values[i] = float(values[i])
+ function = transform[0]
+ if (function == 'matrix'):
+ a = [[values[0], values[2], values[4]],
+ [values[1], values[3], values[5]],
+ [0, 0, 1]]
+ result = self.multiply(result, a)
+ elif (function == 'translate'):
+ a = [[1, 0, values[0]],
+ [0, 1, values[1]],
+ [0, 0, 1]]
+ result = self.multiply(result, a)
+ elif (function == 'scale'):
+ a = [[values[0], 0, 0],
+ [0, values[1], 0],
+ [0, 0, 1]]
+ result = self.multiply(result, a)
+ elif (function == 'rotate'):
+ if (len(values) == 1):
+ a = [[math.cos(values[0]), -math.sin(values[0]), 0],
+ [math.sin(values[0]), math.cos(values[0]), 0],
+ [0, 0, 1]]
+ result = self.multiply(result, a)
+ else:
+ a = [[1, 0, values[2]],
+ [0, 1, values[2]],
+ [0, 0, 1]]
+ result = self.multiply(result, a)
+ a = [[math.cos(values[0]), -math.sin(values[0]), 0],
+ [math.sin(values[0]), math.cos(values[0]), 0],
+ [0, 0, 1]]
+ result = self.multiply(result, a)
+ a = [[1, 0, -values[2]],
+ [0, 1, -values[2]],
+ [0, 0, 1]]
+ result = self.multiply(result, a)
+ elif (function == 'skewX'):
+ a = [[1, math.tan(values[0]), 0],
+ [0, 1, 0],
+ [0, 0, 1]]
+ result = self.multiply(result, a)
+ elif (function == 'skewY'):
+ a = [[1, 0, 0],
+ [math.tan(values[0]), 1, 0],
+ [0, 0, 1]]
+ result = self.multiply(result, a)
+
+ return self.multiply(self.transform(el.getparent()), result)
+
+
+ def getPosition(self, el):
+ if not self.isset(el.attrib, 'x'):
+ return False
+
+ x = self.sizeToPx(el.attrib['x'], 'x')
+ y = self.sizeToPx(el.attrib['y'], 'y')
+ v = [x, y, 1]
+ t = self.transform(el)
+ v = self.multiply(t, v)
+
+ return {'coordinates': v, 'matrix': t}
+
+ def setPosition(self, el, position):
+ c = position['coordinates']
+ a = position['matrix']
+ if (not self.isUnitMatrix(a)):
+ c = self.multiply(self.inverse(a), c)
+ el.set('x', str(c[0]))
+ el.set('y', str(c[1]))
+
+
+ def determinant(self, a):
+ if len(a) != 3:
+ return False
+ if (len(a[0]) != 3):
+ return False
+
+ det = a[0][0] * (a[1][1] * a[2][2] - a[2][1] * a[1][2]) - a[0][1] * (a[1][0] * a[2][2] - a[2][0] * a[1][2]) + a[0][2] * (a[1][0] * a[2][1] - a[2][0] * a[1][1])
+
+ if (det == 0):
+ det = 0.00001
+
+ return det
+
+ def minors(self, a):
+ if len(a) != 3:
+ return False
+ if (len(a[0]) != 3):
+ return False
+
+ return [[a[1][1] * a[2][2] - a[2][1] * a[1][2], a[1][0] * a[2][2] - a[2][0] * a[1][2], a[1][0] * a[2][1] - a[2][0] * a[1][1]],
+ [a[0][1] * a[2][2] - a[2][1] * a[0][2], a[0][0] * a[2][2] - a[0][2] * a[2][0], a[0][0] * a[2][1] - a[2][0] * a[0][1]],
+ [a[0][1] * a[1][2] - a[1][1] * a[0][2], a[0][0] * a[1][2] - a[0][1] * a[0][2], a[0][0] * a[1][1] - a[1][0] * a[0][1]]
+ ]
+
+ def cofactors(self, a):
+ if len(a) != 3:
+ return False
+ if (len(a[0]) != 3):
+ return False
+
+ return [[a[0][0], -a[0][1], a[0][2]],
+ [-a[1][0], a[1][1], -a[1][2]],
+ [a[2][0], -a[2][1], a[2][2]]
+ ]
+
+ def adjoint(self, a):
+ if len(a) != 3:
+ return False
+ if (len(a[0]) != 3):
+ return False
+
+ return [[a[0][0], a[1][0], a[2][0]],
+ [a[0][1], a[1][1], a[2][1]],
+ [a[0][2], a[1][2], a[2][2]]
+ ]
+
+ def inverse(self, a):
+ if len(a) != 3:
+ return False
+ if (len(a[0]) != 3):
+ return False
+
+ det = self.determinant(a)
+ m = self.minors(a)
+ c = self.cofactors(m)
+ adj = self.adjoint(c)
+
+ return [[adj[0][0] / det, adj[0][1] / det, adj[0][2] / det],
+ [adj[1][0] / det, adj[1][1] / det, adj[1][2] / det],
+ [adj[2][0] / det, adj[2][1] / det, adj[2][2] / det]
+ ]
+
+ def multiply(self, a, v):
+ if len(a) != 3:
+ return False
+ if (len(a[0]) != 3):
+ return False
+
+ if (len(v) != 3):
+ return False
+
+ if (not self.isset(v[0], 0)):
+ return [a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2],
+ a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2],
+ a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2]
+ ]
+ else:
+ return [[a[0][0] * v[0][0] + a[0][1] * v[1][0] + a[0][2] * v[2][0], a[0][0] * v[0][1] + a[0][1] * v[1][1] + a[0][2] * v[2][1], a[0][0] * v[0][2] + a[0][1] * v[1][2] + a[0][2] * v[2][2]],
+ [a[1][0] * v[0][0] + a[1][1] * v[1][0] + a[1][2] * v[2][0], a[1][0] * v[0][1] + a[1][1] * v[1][1] + a[1][2] * v[2][1], a[1][0] * v[0][2] + a[1][1] * v[1][2] + a[1][2] * v[2][2]],
+ [a[2][0] * v[0][0] + a[2][1] * v[1][0] + a[2][2] * v[2][0], a[2][0] * v[0][1] + a[2][1] * v[1][1] + a[2][2] * v[2][1], a[2][0] * v[0][2] + a[2][1] * v[1][2] + a[2][2] * v[2][2]]
+ ]
+
+ def isUnitMatrix(self, a):
+ if (len(a) != 3):
+ return False
+ if (len(a[0]) != 3):
+ return False
+
+ for i in range(3):
+ for j in range(3):
+ if (a[i][j] != self.unitMatrix[i][j]):
+ return False
+
+ return True
+
+ def reParse(self):
+ if os.name == 'nt':
+ path = os.environ['USERPROFILE']
+ else:
+ path = os.path.expanduser("~")
+ text = inkex.etree.tostring(self.document.getroot())
+ f = open(path + '/tmp.svg', 'w')
+ f.write(text)
+ f.close()
+ self.parse(path + '/tmp.svg')
+
+ os.remove(path + '/tmp.svg')
+
+ def matrix2string(self, a):
+ return 'matrix(' + str(a[0][0]) + ',' + str(a[1][0]) + ',' + str(a[0][1]) + ',' + str(a[1][1]) + ',' + str(a[0][2]) + ',' + str(a[1][2]) + ')'
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/install b/extensions/fablabchemnitz/table_support/install
new file mode 100755
index 00000000..ccd5943b
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/install
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+./install_shortcuts.py -i keys.xml -o `inkscape -x`/../keys/default.xml
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/install_shortcuts.py b/extensions/fablabchemnitz/table_support/install_shortcuts.py
new file mode 100755
index 00000000..e69d5e96
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/install_shortcuts.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+
+import sys, os, optparse
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class install():
+ OptionParser = optparse.OptionParser(usage="usage: %prog [options] SVGfile")
+
+ def __init__(self):
+ opts = [('-i', '--input', 'string', 'input', '/tmp/i',
+ 'The input file'),
+ ('-o', '--output', 'string', 'output', '/tmp/o',
+ 'The output file'),
+ ]
+ for o in opts:
+ self.OptionParser.add_option(o[0], o[1], action="store", type=o[2],
+ dest=o[3], default=o[4], help=o[5])
+ self.getoptions()
+
+ def getoptions(self,args=sys.argv[1:]):
+ """Collect command line arguments"""
+ self.options, self.args = self.OptionParser.parse_args(args)
+
+ def do_install(self):
+ f = open(self.options.input, 'r')
+ content = f.read()
+ f.close()
+
+ f = open(self.options.output, 'r')
+ _c = f.read()
+ f.close()
+
+ _c = _c.replace('', content + '\n')
+
+ f = open(self.options.output, 'w')
+ f.write(_c)
+ f.close()
+
+if __name__ == '__main__': #pragma: no cover
+ e = install()
+ e.do_install()
diff --git a/extensions/fablabchemnitz/table_support/keys.xml b/extensions/fablabchemnitz/table_support/keys.xml
new file mode 100644
index 00000000..0650bdd5
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/keys.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/extensions/fablabchemnitz/table_support/table.py b/extensions/fablabchemnitz/table_support/table.py
new file mode 100644
index 00000000..0a90b62b
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table.py
@@ -0,0 +1,850 @@
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+import math
+
+import inkex
+from inkex import Guide
+from lxml import etree
+import base_transform
+import re
+
+class TableEngine(base_transform.BaseTransform):
+
+ defaultId = 'inkscape-table'
+ cell_type_row = 'row'
+ cell_type_column = 'column'
+ normalizeFactor = 5
+ tablesCount = 0
+ tables = None
+ selectedTables = {}
+ mergedCells = {}
+ tablesTexts = {}
+ get_tables = True
+ auto_split = True
+ delimiter = ','
+
+ def __init__(self, get_tables = True, auto_split = True):
+ inkex.NSS['inkex'] = 'http://sodipodi.sourceforge.net/DTD/inkex-0.dtd'
+ self.get_tables = get_tables
+ self.auto_split = auto_split
+ base_transform.BaseTransform.__init__(self)
+
+ def getTablesCount(self):
+ node = self.document.xpath('//inkex:tables', namespaces = inkex.NSS)
+ if len(node) == 0:
+ xml = ''
+ self.document.getroot().append(etree.fromstring(xml))
+ node = self.document.xpath('//inkex:tables', namespaces = inkex.NSS)
+ else:
+ self.tablesCount = int(node[0].attrib['count'])
+
+ self.tables = node[0]
+
+ def isTableCell(self, id):
+ el = self.svg.getElementById(id)
+ if (el == None):
+ return False
+
+ if (self.isset(el.attrib, inkex.addNS('table-id', 'inkex'))):
+ tableId = el.attrib[inkex.addNS('table-id', 'inkex')]
+ if (re.search('\\-text$', tableId)):
+ return False
+ else:
+ return True
+
+ return False
+
+ def effect(self):
+ self.getTablesCount()
+ if (self.get_tables):
+ self.getAllTables()
+ if (self.auto_split):
+ for id, table in self.selectedTables.items():
+ for i in range(len(table)):
+ for j in range(len(table[i])):
+ if (table[i][j] != None):
+ points = self.splitCell(table[i][j])
+ if (points != False):
+ if (self.isset(self.mergedCells, id)):
+ self.mergedCells[id].append(points)
+ else:
+ self.mergedCells[id] = [points]
+ for tableId in self.mergedCells:
+ self.getTable(tableId)
+ self.doinkex()
+ if (self.get_tables):
+ if (self.auto_split):
+ for tableId in self.mergedCells:
+ self.getTableText(tableId)
+ for points in self.mergedCells[tableId]:
+ if (not self.isset(points, 'removed')):
+ self.mergeTable(tableId, points)
+
+ def newCell(self, x, y, width, height, id, i, j, transform = None):
+ #path = '//*[@inkex:table-id="%s"]' % id
+ _id = self.svg.get_unique_id(id)
+ etree.SubElement(self.svg.get_current_layer(), 'rect', {
+ 'id': _id,
+ 'style': 'fill:none;stroke:#000000;stroke-width:1px;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none',
+ 'width': str(width) + 'px',
+ 'height': str(height) + 'px',
+ 'x': str(x) + 'px',
+ 'y': str(y) + 'px',
+ inkex.addNS('table-id', 'inkex'): id,
+ inkex.addNS('row', 'inkex'): str(i),
+ inkex.addNS('column', 'inkex'): str(j)
+ })
+
+ if (transform != None):
+ el = self.svg.getElementById(_id)
+ el.set('transform', transform)
+
+ return _id
+
+ '''
+ _id = self.svg.get_unique_id(id)
+ content = ''
+
+ self.svg.get_current_layer().append(etree.XML(content))
+ el = self.svg.getElementById(_id)
+ el.set(inkex.addNS('table-id', 'inkex'), id)
+ el.set(inkex.addNS('row', 'inkex'), str(i))
+ el.set(inkex.addNS('column', 'inkex'), str(j))
+ '''
+
+ def create(self, width, height, cols, rows):
+ tableId = self.defaultId + str(self.tablesCount)
+ self.tablesCount += 1
+ self.tables.set('count', str(self.tablesCount))
+ content = ''
+ self.tables.append(etree.fromstring(content))
+
+ width = self.sizeToPx(width, 'x')
+ height = self.sizeToPx(height, 'y')
+
+ x = 0
+ y = 0
+
+ content = ''
+
+ for i in range(rows):
+ x = 0
+ for j in range(cols):
+ self.newCell(x, y, width, height, tableId, i, j)
+ x += width
+ y += height
+
+ def getTree(self, id):
+ ids = [id]
+ el = self.svg.getElementById(id)
+ for _el in list(el):
+ for _id in self.getTree(_el.attrib['id']):
+ ids.append(_id)
+ return ids
+
+
+ def getSubSelectedIds(self):
+ ids = []
+ for id in self.svg.selected.ids:
+ for _id in self.getTree(id):
+ ids.append(_id)
+ return ids
+
+ def getAllTables(self):
+ ids = self.getSubSelectedIds()
+ for id in ids:
+ el = self.svg.getElementById(id)
+ if (self.isTableCell(id)):
+ tableId = el.attrib[inkex.addNS('table-id', 'inkex')]
+ if (not self.isset(self.selectedTables, tableId)):
+ self.getTable(tableId)
+ self.tablesTexts[tableId] = self.getTableText(tableId)
+
+ def getTableDimensions(self, tableId):
+ nodes = self.tables.xpath('//inkex:table[@table-id="' + tableId + '"]', namespaces = inkex.NSS)
+ if (len(nodes) > 0):
+ return {'rows': int(nodes[0].attrib['rows']), 'cols': int(nodes[0].attrib['columns'])}
+ return False
+
+ def setTableDimensions(self, tableId, dimensions):
+ table_dim = self.tables.xpath('//inkex:table[@table-id="' + tableId + '"]', namespaces = inkex.NSS)
+ if (len(table_dim) > 0):
+ table_dim[0].set('rows', str(dimensions['rows']))
+ table_dim[0].set('columns', str(dimensions['cols']))
+
+
+ def getTable(self, tableId):
+ nodes = self.tables.xpath('//inkex:table[@table-id="' + tableId + '"]', namespaces = inkex.NSS)
+ if (len(nodes) > 0):
+ cols = int(nodes[0].attrib['columns'])
+ rows = int(nodes[0].attrib['rows'])
+ table = [[None for i in range(cols)] for j in range(rows)]
+ path = '//*[@inkex:table-id="' + tableId + '"]'
+ cells = self.document.xpath(path, namespaces = inkex.NSS)
+ for cell in cells:
+ i = int(cell.attrib[inkex.addNS('row', 'inkex')])
+ j = int(cell.attrib[inkex.addNS('column', 'inkex')])
+ table[i][j] = cell.attrib['id']
+ self.selectedTables[tableId] = table
+
+ def getTableText(self, tableId):
+ nodes = self.tables.xpath('//inkex:table[@table-id="' + tableId + '"]', namespaces = inkex.NSS)
+ if (len(nodes) > 0):
+ cols = int(nodes[0].attrib['columns'])
+ rows = int(nodes[0].attrib['rows'])
+ texts = [[None for i in range(cols)] for j in range(rows)]
+ path = '//*[@inkex:table-id="' + tableId + '-text"]'
+ cells = self.document.xpath(path, namespaces = inkex.NSS)
+ for cell in cells:
+ i = int(cell.attrib[inkex.addNS('row', 'inkex')])
+ j = int(cell.attrib[inkex.addNS('column', 'inkex')])
+ texts[i][j] = cell.attrib['id']
+ return texts
+ return None
+
+ def doAddGuide(self, el, type):
+ px = self.sizeToPx(str(self.svg.unittouu(self.document.getroot().attrib['height'])), 'y')
+
+ position = self.getPosition(el)
+ if (position != False):
+ c = position['coordinates']
+ a = position['matrix']
+ x = c[0]
+ y = c[1]
+ angle = math.acos(a[0][0]) * 180 / math.pi
+ if angle < 90:
+ angle = 90 - angle
+ elif angle < 180:
+ angle = 180 - angle
+ elif angle < 270:
+ angle = 270 - angle
+ else:
+ angle = 360 - angle
+ if (type == self.cell_type_row):
+ angle += 90
+ self.svg.namedview.add(Guide().move_to(str(x), str(px - y), angle))
+
+ def _addGuides(self, tableId, type):
+ table = self.selectedTables[tableId]
+
+ count = len(table)
+ if (type == self.cell_type_column):
+ count = len(table[0])
+
+ for i in range(count):
+ _i = i
+ _j = 0
+ if (type == self.cell_type_column):
+ _i = 0
+ _j = i
+ el = self.svg.getElementById(table[_i][_j])
+ self.doAddGuide(el, type)
+
+ if (i == count - 1):
+ if (type == self.cell_type_column):
+ el.attrib['x'] = str(self.sizeToPx(el.attrib['x'], 'x') + self.sizeToPx(el.attrib['width'], 'x'))
+ else:
+ el.attrib['y'] = str(self.sizeToPx(el.attrib['y'], 'y') + self.sizeToPx(el.attrib['height'], 'y'))
+ self.doAddGuide(el, type)
+ if (type == self.cell_type_column):
+ el.attrib['x'] = str(self.sizeToPx(el.attrib['x'], 'x') - self.sizeToPx(el.attrib['width'], 'x'))
+ else:
+ el.attrib['y'] = str(self.sizeToPx(el.attrib['y'], 'y') - self.sizeToPx(el.attrib['height'], 'y'))
+
+ def addGuides(self, type):
+ for tableId in self.selectedTables:
+ self._addGuides(tableId, type)
+
+ def doEditText(self, id, fontSize):
+ el = self.svg.getElementById(id)
+ if (not self.isTableCell(id)):
+ return
+
+ position = self.getPosition(el)
+ if (position != False):
+ a = position['matrix']
+ if (not self.isUnitMatrix(a)):
+ transform = 'transform="' + self.matrix2string(a) + '"'
+ else:
+ transform = ''
+ content = 'text here'
+
+ self.svg.get_current_layer().append(etree.fromstring(content))
+
+ def editText(self, fontSize):
+ ids = self.getSubSelectedIds()
+
+ for id in ids:
+ self.doEditText(id, fontSize)
+
+ def getColumnIndex(self, id):
+ el = self.svg.getElementById(id)
+ if (self.isset(el.attrib, inkex.addNS('column', 'inkex'))):
+ return int(el.attrib[inkex.addNS('column', 'inkex')])
+
+ return -1
+
+ def getRowIndex(self, id):
+ el = self.svg.getElementById(id)
+ if (self.isset(el.attrib, inkex.addNS('row', 'inkex'))):
+ return int(el.attrib[inkex.addNS('row', 'inkex')])
+
+ return -1
+
+ def setTextRect(self, text, c):
+ for child in list(text):
+ if (child.tag == inkex.addNS('flowRegion', 'svg')):
+ for subchild in list(child):
+ if (subchild.tag == inkex.addNS('rect', 'svg')):
+ for key, value in c.iteritems():
+ if value != None:
+ subchild.set(key, str(value))
+ break
+
+ def getTextRect(self, text):
+ for child in list(text):
+ if (child.tag == inkex.addNS('flowRegion', 'svg')):
+ for subchild in list(child):
+ if (subchild.tag == inkex.addNS('rect', 'svg')):
+ return subchild
+
+ return None
+
+ def moveCells(self, tableId, idx, delta, type):
+ table = self.selectedTables[tableId]
+ texts = self.tablesTexts[tableId]
+ if (type == self.cell_type_column):
+ starti = 0
+ startj = idx
+ else:
+ starti = idx
+ startj = 0
+
+ for i in range(starti, len(table)):
+ for j in range(startj, len(table[i])):
+ el = self.svg.getElementById(table[i][j])
+ position = self.getPosition(el)
+ if (position != False):
+ c = [self.sizeToPx(el.attrib['x'], 'x'), self.sizeToPx(el.attrib['y'], 'y')]
+ c[0] += delta[0]
+ c[1] += delta[1]
+ el.set('x', str(c[0]))
+ el.set('y', str(c[1]))
+ if (texts != None):
+ if (texts[i][j] != None):
+ el = self.svg.getElementById(texts[i][j])
+ rect = self.getTextRect(el)
+ if (rect != None):
+ c[0] = self.sizeToPx(rect.attrib['x'], 'x') + delta[0]
+ c[1] = self.sizeToPx(rect.attrib['y'], 'y') + delta[1]
+ self.setTextRect(el, {'x': c[0], 'y': c[1]})
+
+ def setCellSize(self, tableId, idx, size, type):
+ table = self.selectedTables[tableId]
+ texts = self.tablesTexts[tableId]
+ if (type == self.cell_type_column):
+ size = self.sizeToPx(size, 'x')
+ old_size = self.sizeToPx(self.svg.getElementById(table[0][idx]).attrib['width'], 'x')
+ else:
+ size = self.sizeToPx(size, 'y')
+ old_size = self.sizeToPx(self.svg.getElementById(table[idx][0]).attrib['height'], 'y')
+
+ if (type == self.cell_type_column):
+ delta = [size - old_size, 0, 1]
+ else:
+ delta = [0, size - old_size, 1]
+
+ if ((idx + 1 < len(table) and type == self.cell_type_row) or (idx + 1 < len(table[0]) and type == self.cell_type_column)):
+ self.moveCells(tableId, idx + 1, delta, type)
+
+ count = len(table[idx])
+ if (type == self.cell_type_column):
+ count = len(table)
+
+ for i in range(count):
+ _i = idx
+ _j = i
+ if type == self.cell_type_column:
+ _i = i
+ _j = idx
+ el = self.svg.getElementById(table[_i][_j])
+ param = 'height'
+ if (type == self.cell_type_column):
+ param = 'width'
+
+ el.set(param, str(size))
+
+ if texts != None:
+ if texts[_i][_j] != None:
+ el = self.svg.getElementById(texts[_i][_j])
+ self.setTextRect(el, {param: size})
+
+ def editSize(self, size, type):
+ processed = {}
+ for node in self.svg.selected.values():
+ id = node.get('id')
+ if (self.isTableCell(id)):
+ tableId = node.attrib[inkex.addNS('table-id', 'inkex')]
+ if (type == self.cell_type_column):
+ idx = self.getColumnIndex(id)
+ else:
+ idx = self.getRowIndex(id)
+ if (not self.isset(processed, tableId)):
+ processed[tableId] = []
+
+ if (not self.isset(processed[tableId], idx)):
+ self.setCellSize(tableId, idx, size, type)
+ processed[tableId].append(idx)
+
+ def getTableWidth(self, tableId):
+ table = self.selectedTables[tableId]
+ width = 0
+ for i in range(len(table[0])):
+ el = self.svg.getElementById(table[0][i])
+ width += self.sizeToPx(el.attrib['width'], 'x')
+
+ return width
+
+ def getTableHeight(self, tableId):
+ table = self.selectedTables[tableId]
+ height = 0
+ for i in range(len(table)):
+ el = self.svg.getElementById(table[i][0])
+ height += self.sizeToPx(el.attrib['height'], 'y')
+
+ return height
+
+ def setTableSize(self, tableId, size, type):
+ if (type == self.cell_type_column):
+ size = self.sizeToPx(size, 'x')
+ old_size = self.getTableWidth(tableId)
+ else:
+ size = self.sizeToPx(size, 'y')
+ old_size = self.getTableHeight(tableId)
+
+ factor = size / old_size
+ table = self.selectedTables[tableId]
+ count = len(table)
+ if (type == self.cell_type_column):
+ count = len(table[0])
+
+ for i in range(count):
+ if (type == self.cell_type_column):
+ el = self.svg.getElementById(table[0][i])
+ new_size = self.sizeToPx(el.attrib['width'], 'x') * factor
+ else:
+ el = self.svg.getElementById(table[i][0])
+ new_size = self.sizeToPx(el.attrib['height'], 'y') * factor
+ self.setCellSize(tableId, i, str(new_size), type)
+
+ def editTable(self, width, height):
+ for id in self.selectedTables:
+ self.setTableSize(id, width, self.cell_type_column)
+ self.setTableSize(id, height, self.cell_type_row)
+
+ def getTablePosition(self, tableId):
+ table = self.selectedTables[tableId]
+ el = self.svg.getElementById(table[0][0])
+ return self.getPosition(el)
+
+ def fitPage(self):
+ width = str(self.svg.unittouu(self.document.getroot().attrib['width']))
+ height = str(self.svg.unittouu(self.document.getroot().attrib['height']))
+
+ for id in self.selectedTables:
+ position = self.getTablePosition(id)
+ if (position != False):
+ c = position['coordinates']
+ self.moveCells(id, 0, [-c[0], -c[1], 1], type)
+ self.setTableSize(id, width, self.cell_type_column)
+ self.setTableSize(id, height, self.cell_type_row)
+
+ def fitPageWidth(self):
+ width = str(self.svg.unittouu(self.document.getroot().attrib['width']))
+
+ for id in self.selectedTables:
+ position = self.getTablePosition(id)
+ if (position != False):
+ c = position['coordinates']
+ self.moveCells(id, 0, [-c[0], 0, 1], type)
+ self.setTableSize(id, width, self.cell_type_column)
+
+ def fitPageHeight(self):
+ height = str(self.svg.unittouu(self.document.getroot().attrib['height']))
+
+ for id in self.selectedTables:
+ position = self.getTablePosition(id)
+ if (position != False):
+ c = position['coordinates']
+ self.moveCells(id, 0, [0, -c[1], 1], type)
+ self.setTableSize(id, height, self.cell_type_row)
+
+ def getSelectedListIds(self):
+ idList = []
+ for id in self.getSubSelectedIds():
+ idList.append(id)
+ return idList
+
+ def getCellText(self, tableId, i, j):
+ texts = self.tablesTexts[tableId]
+ if (texts != None):
+ if (texts[i][j] != None):
+ return self.svg.getElementById(texts[i][j])
+ return None
+
+ def getMergePoints(self, tableId):
+ dim = self.getTableDimensions(tableId)
+ table = self.selectedTables[tableId]
+ idList = self.getSelectedListIds()
+ start = []
+ for i in range(dim['rows']):
+ for j in range(dim['cols']):
+ if (idList.count(table[i][j]) > 0):
+ start = [i, j]
+ break
+ if len(start) > 0:
+ break
+
+ if (len(start) != 2):
+ return False
+
+ end = [1, 1]
+
+ for i in range(start[0] + 1, len(table)):
+ if (idList.count(table[i][start[1]]) > 0):
+ end[0] += 1
+ else:
+ break
+
+ for i in range(start[1] + 1, len(table[0])):
+ if (idList.count(table[start[0]][i]) > 0):
+ end[1] += 1
+ else:
+ break
+
+ for i in range(start[0], start[0] + end[0]):
+ for j in range(start[1], start[1] + end[1]):
+ if (idList.count(table[i][j]) == 0):
+ return False
+
+ return {'i': start[0], 'j': start[1], 'rows': end[0], 'cols': end[1]}
+
+ def mergeTable(self, tableId, points = None):
+ if (points == None):
+ points = self.getMergePoints(tableId)
+ if (points == False):
+ inkex.errormsg('You have to select the cells to form a rectangle from a single table.')
+ return
+
+ table = self.selectedTables[tableId]
+ cell = self.svg.getElementById(table[points['i']][points['j']])
+ width = 0
+ height = 0
+ widths = ''
+ heights = ''
+
+ for i in range(points['i'], points['i'] + points['rows']):
+ el = self.svg.getElementById(table[i][points['j']])
+ height += self.sizeToPx(el.attrib['height'], 'y')
+ if (heights != ''):
+ heights += self.delimiter
+ heights += el.attrib['height']
+
+ for j in range(points['j'], points['j'] + points['cols']):
+ el = self.svg.getElementById(table[points['i']][j])
+ width += self.sizeToPx(el.attrib['width'], 'x')
+ if (widths != ''):
+ widths += self.delimiter
+ widths += el.attrib['width']
+
+ for i in range(points['i'], points['i'] + points['rows']):
+ for j in range(points['j'], points['j'] + points['cols']):
+ if (i != points['i'] or j != points['j']):
+ el = self.svg.getElementById(table[i][j])
+ el.getparent().remove(el)
+ text = self.getCellText(tableId, i, j)
+ if (text != None):
+ text.getparent().remove(text)
+
+ cell.set('width', str(width) + 'px')
+ cell.set('height', str(height) + 'px')
+ cell.set(inkex.addNS('merged', 'inkex'), str(points['rows']) + self.delimiter + str(points['cols']))
+ cell.set(inkex.addNS('merged-columns-widths', 'inkex'), widths)
+ cell.set(inkex.addNS('merged-rows-heights', 'inkex'), heights)
+
+ text = self.getCellText(tableId, points['i'], points['j'])
+
+ if (text != None):
+ rect = self.getTextRect(text)
+ rect.set('width', str(width) + 'px')
+ rect.set('height', str(height) + 'px')
+
+
+ def mergeMerge(self):
+ for id in self.selectedTables:
+ self.mergeTable(id)
+
+ def splitCell(self, cellId):
+ cell = self.svg.getElementById(cellId)
+ if (self.isset(cell.attrib, inkex.addNS('merged', 'inkex'))):
+ tableId = cell.attrib[inkex.addNS('table-id', 'inkex')]
+ row = int(cell.attrib[inkex.addNS('row', 'inkex')])
+ column = int(cell.attrib[inkex.addNS('column', 'inkex')])
+ position = self.getPosition(cell)
+
+ merge_size = cell.attrib[inkex.addNS('merged', 'inkex')].split(self.delimiter)
+ widths = cell.attrib[inkex.addNS('merged-columns-widths', 'inkex')].split(self.delimiter)
+ heights = cell.attrib[inkex.addNS('merged-rows-heights', 'inkex')].split(self.delimiter)
+
+ y = self.sizeToPx(cell.attrib['y'], 'y')
+
+ for i in range(row, row + int(merge_size[0])):
+ x = self.sizeToPx(cell.attrib['x'], 'x')
+ for j in range(column, column + int(merge_size[1])):
+ if (i != row or j != column):
+ transform = None
+ if position != False:
+ a = position['matrix']
+ if (not self.isUnitMatrix(a)):
+ transform = self.matrix2string(a)
+ self.newCell(x, y, self.sizeToPx(widths[j - column], 'x'), self.sizeToPx(heights[i - row], 'y'), tableId, i, j, transform)
+ x += self.sizeToPx(widths[j - column], 'x')
+ y += self.sizeToPx(heights[i - row], 'y')
+
+ result = {'i': row, 'j': column, 'rows': int(merge_size[0]), 'cols': int(merge_size[1])}
+ cell.set('width', widths[0])
+ cell.set('height', heights[0])
+ text = self.getCellText(tableId, row, column)
+ if (text != None):
+ rect = self.getTextRect(text)
+ rect.set('width', widths[0])
+ rect.set('height', heights[0])
+ del cell.attrib[inkex.addNS('merged', 'inkex')]
+ del cell.attrib[inkex.addNS('merged-columns-widths', 'inkex')]
+ del cell.attrib[inkex.addNS('merged-rows-heights', 'inkex')]
+
+ return result
+ return False
+
+ def mergeSplit(self):
+ for id in self.svg.selected.ids:
+ self.splitCell(id)
+
+ def updateMergedPoints(self, tableId, idx, delta, type):
+ if (self.get_tables):
+ if (self.auto_split):
+ if (self.isset(self.mergedCells, tableId)):
+ for points in self.mergedCells[tableId]:
+ cond1 = idx > points['i'] and idx < points['i'] + points['rows']
+ cond2 = idx <= points['i']
+ if (type == self.cell_type_column):
+ cond1 = idx > points['j'] and idx < points['j'] + points['cols']
+ cond2 = idx <= points['j']
+
+ if (cond1):
+ if (type == self.cell_type_column):
+ points['cols'] += delta
+ if (points['cols'] <= 1):
+ points['removed'] = 1
+ else:
+ points['rows'] += delta
+ if (points['rows'] <= 1):
+ points['removed'] = 1
+ elif (cond2):
+ if (type == self.cell_type_column):
+ if (delta == -1 and idx == points['j']):
+ points['cols'] += delta
+ if (points['cols'] <= 1):
+ points['removed'] = 1
+ else:
+ points['j'] += delta
+ else:
+ if (delta == -1 and idx == points['i']):
+ points['rows'] += delta
+ if (points['rows'] <= 1):
+ points['removed'] = 1
+ else:
+ points['i'] += delta
+
+ def incrementCoordonate(self, tableId, idx, inc, type):
+ table = self.selectedTables[tableId]
+ texts = self.getTableText(tableId)
+ starti = idx
+ startj = 0
+ dim = self.getTableDimensions(tableId)
+ if type == self.cell_type_column:
+ dim['cols'] += inc
+ else:
+ dim['rows'] += inc
+ self.setTableDimensions(tableId, dim)
+
+ if (type == self.cell_type_column):
+ starti = 0
+ startj = idx
+
+ for i in range(starti, len(table)):
+ for j in range(startj, len(table[i])):
+ cell = self.svg.getElementById(table[i][j])
+ text = self.svg.getElementById(texts[i][j])
+ if (type == self.cell_type_column):
+ cell.set(inkex.addNS('column', 'inkex'), str(int(cell.attrib[inkex.addNS('column', 'inkex')]) + inc))
+ if (text != None):
+ text.set(inkex.addNS('column', 'inkex'), str(int(text.attrib[inkex.addNS('column', 'inkex')]) + inc))
+ else:
+ cell.set(inkex.addNS('row', 'inkex'), str(int(cell.attrib[inkex.addNS('row', 'inkex')]) + inc))
+ if (text != None):
+ text.set(inkex.addNS('row', 'inkex'), str(int(text.attrib[inkex.addNS('row', 'inkex')]) + inc))
+
+ def addCell(self, tableId, idx, type):
+ table = self.selectedTables[tableId]
+ if (type == self.cell_type_column):
+ if (idx != -1):
+ delta = [self.sizeToPx(self.svg.getElementById(table[0][idx]).attrib['width'], 'x'), 0, 1]
+ else:
+ delta = [self.sizeToPx(self.svg.getElementById(table[0][0]).attrib['width'], 'x'), 0, 1]
+ else:
+ if (idx != -1):
+ delta = [0, self.sizeToPx(self.svg.getElementById(table[idx][0]).attrib['height'], 'y'), 1]
+ else:
+ delta = [0, self.sizeToPx(self.svg.getElementById(table[0][0]).attrib['height'], 'y'), 1]
+
+ count = len(table)
+ if type == self.cell_type_row:
+ if (idx != -1):
+ count = len(table[idx])
+ else:
+ count = len(table[0])
+ for i in range(count):
+ if (type == self.cell_type_column):
+ if (idx != -1):
+ cell = self.svg.getElementById(table[i][idx])
+ else:
+ cell = self.svg.getElementById(table[i][0])
+ else:
+ if (idx != -1):
+ cell = self.svg.getElementById(table[idx][i])
+ else:
+ cell = self.svg.getElementById(table[0][i])
+
+ position = self.getPosition(cell)
+ transform = ''
+ if (position != False):
+ a = position['matrix']
+ if (not self.isUnitMatrix(a)):
+ transform = self.matrix2string(a)
+ x = self.sizeToPx(cell.attrib['x'], 'x')
+ y = self.sizeToPx(cell.attrib['y'], 'y')
+ width = self.sizeToPx(cell.attrib['width'], 'x')
+ height = self.sizeToPx(cell.attrib['height'], 'y')
+
+ if (type == self.cell_type_column):
+ if (idx != -1):
+ x += width
+ self.newCell(x, y, width, height, tableId, i, idx + 1, transform)
+ else:
+ if (idx != -1):
+ y += height
+ self.newCell(x, y, width, height, tableId, idx + 1, i, transform)
+
+ self.moveCells(tableId, idx + 1, delta, type)
+ self.updateMergedPoints(tableId, idx + 1, 1, type)
+ self.incrementCoordonate(tableId, idx + 1, 1, type)
+ self.getTable(tableId)
+ self.tablesTexts[tableId] = self.getTableText(tableId)
+
+ def addColumns(self, count, where):
+ for id in self.svg.selected.ids:
+ el = self.svg.getElementById(id)
+ if (self.isTableCell(id)):
+ tableId = el.attrib[inkex.addNS('table-id', 'inkex')]
+ idx = self.getColumnIndex(id)
+ if (where == 'before'):
+ idx -= 1
+
+ for i in range(count):
+ self.addCell(tableId, idx, self.cell_type_column)
+
+ def addRows(self, count, where):
+ for id in self.svg.selected.ids:
+ el = self.svg.getElementById(id)
+ if (self.isTableCell(id)):
+ tableId = el.attrib[inkex.addNS('table-id', 'inkex')]
+ idx = self.getRowIndex(id)
+ if (where == 'before'):
+ idx -= 1
+
+ for i in range(count):
+ self.addCell(tableId, idx, self.cell_type_row)
+
+ break
+
+ def removeCell(self, tableId, idx, type):
+ table = self.selectedTables[tableId]
+ texts = self.tablesTexts[tableId]
+ if (type == self.cell_type_column):
+ delta = [-self.sizeToPx(self.svg.getElementById(table[0][idx]).attrib['width'], 'x'), 0, 1]
+ else:
+ delta = [0, -self.sizeToPx(self.svg.getElementById(table[idx][0]).attrib['height'], 'y'), 1]
+
+ count = len(table)
+ if type == self.cell_type_row:
+ count = len(table[idx])
+
+ for i in range(count):
+ if (type == self.cell_type_column):
+ cell = self.svg.getElementById(table[i][idx])
+ text = self.svg.getElementById(texts[i][idx])
+ else:
+ cell = self.svg.getElementById(table[idx][i])
+ text = self.svg.getElementById(texts[idx][i])
+
+ if (cell != None):
+ cell.getparent().remove(cell)
+ if (text != None):
+ text.getparent().remove(text)
+
+ self.moveCells(tableId, idx + 1, delta, type)
+ self.updateMergedPoints(tableId, idx, -1, type)
+ self.incrementCoordonate(tableId, idx + 1, -1, type)
+ self.getTable(tableId)
+ self.tablesTexts[tableId] = self.getTableText(tableId)
+
+ def removeRowsColumns(self, type):
+ for id in self.svg.selected.ids:
+ el = self.svg.getElementById(id)
+ if (el != None):
+ if (self.isTableCell(id)):
+ tableId = el.attrib[inkex.addNS('table-id', 'inkex')]
+ if (type == self.cell_type_column):
+ idx = self.getColumnIndex(id)
+ else:
+ idx = self.getRowIndex(id)
+
+ self.removeCell(tableId, idx, type)
diff --git a/extensions/fablabchemnitz/table_support/table_add_columns.inx b/extensions/fablabchemnitz/table_support/table_add_columns.inx
new file mode 100644
index 00000000..e442c071
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_add_columns.inx
@@ -0,0 +1,23 @@
+
+
+ Columns
+ fablabchemnitz.de.table_add_columns
+ 1
+
+
+
+
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_add_columns.py b/extensions/fablabchemnitz/table_support/table_add_columns.py
new file mode 100755
index 00000000..d188c041
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_add_columns.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+ def __init__(self):
+ table.TableEngine.__init__(self, True, True)
+ opts = [('-n', '--number', 'int', 'number', '1',
+ 'The number of rows'),
+ ('-w', '--where', 'string', 'where', 'after',
+ 'Where to add'),
+ ]
+ for o in opts:
+ self.OptionParser.add_option(o[0], o[1], action="store", type=o[2],
+ dest=o[3], default=o[4], help=o[5])
+
+ def doinkex(self):
+ self.addColumns(self.options.number, self.options.where)
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_add_guides.inx b/extensions/fablabchemnitz/table_support/table_add_guides.inx
new file mode 100644
index 00000000..0cf1c39a
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_add_guides.inx
@@ -0,0 +1,18 @@
+
+
+ Guide Lines
+ fablabchemnitz.de.table_add_guides
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_add_guides.py b/extensions/fablabchemnitz/table_support/table_add_guides.py
new file mode 100755
index 00000000..8cdda97c
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_add_guides.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+ def __init__(self):
+ table.TableEngine.__init__(self)
+
+ def doinkex(self):
+ self.addGuides(self.cell_type_row)
+ self.addGuides(self.cell_type_column)
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_add_rows.inx b/extensions/fablabchemnitz/table_support/table_add_rows.inx
new file mode 100644
index 00000000..26844555
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_add_rows.inx
@@ -0,0 +1,23 @@
+
+
+ Rows
+ fablabchemnitz.de.table_add_rows
+ 1
+
+
+
+
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_add_rows.py b/extensions/fablabchemnitz/table_support/table_add_rows.py
new file mode 100755
index 00000000..b315f917
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_add_rows.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+ def __init__(self):
+ table.TableEngine.__init__(self, True, True)
+ opts = [('-n', '--number', 'int', 'number', '1',
+ 'The number of rows'),
+ ('-w', '--where', 'string', 'where', 'after',
+ 'Where to add'),
+ ]
+ for o in opts:
+ self.OptionParser.add_option(o[0], o[1], action="store", type=o[2],
+ dest=o[3], default=o[4], help=o[5])
+
+ def doinkex(self):
+ self.addRows(self.options.number, self.options.where)
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_create.inx b/extensions/fablabchemnitz/table_support/table_create.inx
new file mode 100644
index 00000000..0420a5ce
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_create.inx
@@ -0,0 +1,28 @@
+
+
+ Create
+ fablabchemnitz.de.table_create
+
+
+ 2
+ 2
+ 100mm
+ 20mm
+
+
+
+
+
+
+
+ all
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_create.py b/extensions/fablabchemnitz/table_support/table_create.py
new file mode 100755
index 00000000..40d4f8c1
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_create.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+
+ def add_arguments(self, pars):
+ pars.add_argument("--rows", type=int, default=2, help='The number of table rows')
+ pars.add_argument("--cols", type=int, default=2, help='The number of table columns')
+ pars.add_argument("--width", default='100mm', help='The width of the table')
+ pars.add_argument("--height", default='20mm', help='The height of the table')
+ pars.add_argument("--tab")
+
+ def doinkex(self):
+ self.create(self.options.width, self.options.height, self.options.cols, self.options.rows)
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_edit_columns.inx b/extensions/fablabchemnitz/table_support/table_edit_columns.inx
new file mode 100644
index 00000000..be1890d3
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_edit_columns.inx
@@ -0,0 +1,20 @@
+
+
+ Selected columns width
+ fablabchemnitz.de.table_edit_columns
+ 10mm
+
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_edit_columns.py b/extensions/fablabchemnitz/table_support/table_edit_columns.py
new file mode 100755
index 00000000..a36b8218
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_edit_columns.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+
+ def add_arguments(self, pars):
+ pars.add_argument("--width", default='10mm', help='The new width')
+
+ def doinkex(self):
+ self.editSize(self.options.width, self.cell_type_column)
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_edit_rows.inx b/extensions/fablabchemnitz/table_support/table_edit_rows.inx
new file mode 100644
index 00000000..22a7ae3c
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_edit_rows.inx
@@ -0,0 +1,20 @@
+
+
+ Selected rows height
+ fablabchemnitz.de.table_edit_rows
+ 10mm
+
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_edit_rows.py b/extensions/fablabchemnitz/table_support/table_edit_rows.py
new file mode 100755
index 00000000..e71f847b
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_edit_rows.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+
+ def add_arguments(self, pars):
+ pars.add_argument("--height", default='10mm', help='The new height')
+
+ def doinkex(self):
+ self.editSize(self.options.height, self.cell_type_row)
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_edit_table.inx b/extensions/fablabchemnitz/table_support/table_edit_table.inx
new file mode 100644
index 00000000..bdea4b2e
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_edit_table.inx
@@ -0,0 +1,22 @@
+
+
+ Selected table width and height
+ fablabchemnitz.de.table_edit_table
+ table_edit_table.py
+ 150mm
+ 60mm
+
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_edit_table.py b/extensions/fablabchemnitz/table_support/table_edit_table.py
new file mode 100755
index 00000000..01ccedf0
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_edit_table.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+
+ def add_arguments(self, pars):
+ pars.add_argument("--width", default='150mm', help='The new width')
+ pars.add_argument("--height", default='60mm', help='The new height')
+
+ def doinkex(self):
+ self.editTable(self.options.width, self.options.height)
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_edit_text.inx b/extensions/fablabchemnitz/table_support/table_edit_text.inx
new file mode 100644
index 00000000..2b8413e9
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_edit_text.inx
@@ -0,0 +1,19 @@
+
+
+ Selected cells text
+ fablabchemnitz.de.table_edit_text
+ 12px
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_edit_text.py b/extensions/fablabchemnitz/table_support/table_edit_text.py
new file mode 100755
index 00000000..b21b10ff
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_edit_text.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+
+ def add_arguments(self, pars):
+ pars.add_argument("--size", default='12px', help='The font size')
+
+ def doinkex(self):
+ self.editText(self.options.size)
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_fit_height.inx b/extensions/fablabchemnitz/table_support/table_fit_height.inx
new file mode 100644
index 00000000..b830aa1d
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_fit_height.inx
@@ -0,0 +1,18 @@
+
+
+ Selected table to page height
+ fablabchemnitz.de.table_fit_height
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_fit_height.py b/extensions/fablabchemnitz/table_support/table_fit_height.py
new file mode 100644
index 00000000..7b6d6cb0
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_fit_height.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+ def __init__(self):
+ table.TableEngine.__init__(self)
+
+ def doinkex(self):
+ self.fitPageHeight()
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_fit_page.inx b/extensions/fablabchemnitz/table_support/table_fit_page.inx
new file mode 100644
index 00000000..f371f7bd
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_fit_page.inx
@@ -0,0 +1,18 @@
+
+
+ Selected table to page
+ fablabchemnitz.de.table_fit_page
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_fit_page.py b/extensions/fablabchemnitz/table_support/table_fit_page.py
new file mode 100644
index 00000000..2689e466
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_fit_page.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+
+ def doinkex(self):
+ self.fitPage()
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_fit_width.inx b/extensions/fablabchemnitz/table_support/table_fit_width.inx
new file mode 100644
index 00000000..779f481d
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_fit_width.inx
@@ -0,0 +1,18 @@
+
+
+ Selected table to page width
+ fablabchemnitz.de.table_fit_width
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_fit_width.py b/extensions/fablabchemnitz/table_support/table_fit_width.py
new file mode 100644
index 00000000..1ac7626e
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_fit_width.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+ def __init__(self):
+ table.TableEngine.__init__(self)
+
+ def doinkex(self):
+ self.fitPageWidth()
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_merge_merge.inx b/extensions/fablabchemnitz/table_support/table_merge_merge.inx
new file mode 100644
index 00000000..ebd93393
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_merge_merge.inx
@@ -0,0 +1,18 @@
+
+
+ Merge selected cells
+ fablabchemnitz.de.table_merge_merge
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_merge_merge.py b/extensions/fablabchemnitz/table_support/table_merge_merge.py
new file mode 100644
index 00000000..89d0a027
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_merge_merge.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+ def __init__(self):
+ table.TableEngine.__init__(self)
+
+ def doinkex(self):
+ self.mergeMerge()
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_merge_split.inx b/extensions/fablabchemnitz/table_support/table_merge_split.inx
new file mode 100644
index 00000000..1c7134c7
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_merge_split.inx
@@ -0,0 +1,18 @@
+
+
+ Split selected cells
+ fablabchemnitz.de.table_merge_split
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_merge_split.py b/extensions/fablabchemnitz/table_support/table_merge_split.py
new file mode 100755
index 00000000..c62c8cb8
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_merge_split.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+ def __init__(self):
+ table.TableEngine.__init__(self, True, False)
+
+ def doinkex(self):
+ self.mergeSplit()
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_remove_columns.inx b/extensions/fablabchemnitz/table_support/table_remove_columns.inx
new file mode 100644
index 00000000..eb840bf2
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_remove_columns.inx
@@ -0,0 +1,18 @@
+
+
+ Selected columns
+ fablabchemnitz.de.table_remove_columns
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_remove_columns.py b/extensions/fablabchemnitz/table_support/table_remove_columns.py
new file mode 100755
index 00000000..053f03ee
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_remove_columns.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+ def __init__(self):
+ table.TableEngine.__init__(self, True, True)
+
+ def doinkex(self):
+ self.removeRowsColumns(self.cell_type_column)
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()
diff --git a/extensions/fablabchemnitz/table_support/table_remove_rows.inx b/extensions/fablabchemnitz/table_support/table_remove_rows.inx
new file mode 100644
index 00000000..01f5dbc7
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_remove_rows.inx
@@ -0,0 +1,18 @@
+
+
+ Selected rows
+ fablabchemnitz.de.table_remove_rows
+
+ all
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/extensions/fablabchemnitz/table_support/table_remove_rows.py b/extensions/fablabchemnitz/table_support/table_remove_rows.py
new file mode 100755
index 00000000..11a3b3f5
--- /dev/null
+++ b/extensions/fablabchemnitz/table_support/table_remove_rows.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+"""
+table.py
+Table support for Inkscape
+
+Copyright (C) 2011 Cosmin Popescu, cosminadrianpopescu@gmail.com
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+"""
+import sys
+import os
+import table
+
+sys.path.append(os.path.dirname(sys.argv[0]))
+
+class Table(table.TableEngine):
+ def __init__(self):
+ table.TableEngine.__init__(self, True, True)
+
+ def doinkex(self):
+ self.removeRowsColumns(self.cell_type_row)
+
+if __name__ == '__main__': #pragma: no cover
+ Table().run()