added table support extension

This commit is contained in:
Mario Voigt 2021-07-05 15:41:42 +02:00
parent 3964634190
commit 7445d7b5f4
36 changed files with 1990 additions and 38 deletions

View File

@ -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", "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 = """<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<_name>ChipScratches</_name>
<id>ca.sfu.AT.kurn.ChipScratches</id>
<dependency type="executable" location="extensions">chipScratches.py</dependency>
<dependency type="executable" location="extensions">inkex.py</dependency>
"""
inxfoot = """ <effect>
<object-type>all</object-type>
<effects-menu>
<submenu _name="Generate">
<submenu _name="Noise"/>
</submenu>
</effects-menu>
</effect>
<script>
<command reldir="extensions" interpreter="python">chipScratches.py</command>
</script>
</inkscape-extension>
"""
inxtype = {
"i" : '<param name="%s" type="int" %s _gui-text="%s">%s</param>\n',
"f" : '<param name="%s" type="float" %s _gui-text="%s">%s</param>\n',
"s" : '<param name="%s" type="string" %s _gui-text="%s">%s</param>\n',
"b" : '<param name="%s" type="boolean" %s _gui-text="%s">%s</param>\n',
"n" : '<!-- Dummy line for index. %s %s %s %s -->\n',
}
inxbk = {
"tabs" : '<param type="notebook" name="Nmain">\n<page name="%(s)s" _gui-text="%(s)s">\n',
"tab" : '</page>\n<page name="%(s)s" _gui-text="%(s)s">\n',
"tabe" : '</page>\n</param>\n',
"lit" : '<_param name="%(s)s" type="description" >%(s)s</_param>\n',
}
def mt( s ) : def mt( s ) :
return s.isspace() or len(s) == 0 return s.isspace() or len(s) == 0

View File

@ -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]) + ')'

View File

@ -0,0 +1,3 @@
#!/bin/sh
./install_shortcuts.py -i keys.xml -o `inkscape -x`/../keys/default.xml

View File

@ -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('</keys>', content + '\n</keys>')
f = open(self.options.output, 'w')
f.write(_c)
f.close()
if __name__ == '__main__': #pragma: no cover
e = install()
e.do_install()

View File

@ -0,0 +1,3 @@
<bind key="C" modifiers="Ctrl,Shift,Alt" action="org.greygreen.inkscape.effects.table_create" display="true"/>
<bind key="D" modifiers="Ctrl,Shift,Alt" action="org.greygreen.inkscape.effects.table_duplicate" display="true"/>
<bind key="T" modifiers="Ctrl,Shift,Alt" action="org.greygreen.inkscape.effects.table_edit_text" display="true"/>

View File

@ -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 = '<inkex:tables xmlns:inkex="http://sodipodi.sourceforge.net/DTD/inkex-0.dtd" count="0"/>'
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 = '<rect style="fill:none;stroke:#000000;stroke-width:1px;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"\n\
id="' + _id + '"\n\
width="' + str(width) + '"\n\
height="' + str(height) + '"\n\
x="' + str(x) + '"\n\
y="' + str(y) + '"\n\
/>'
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 = '<inkex:table xmlns:inkex="http://sodipodi.sourceforge.net/DTD/inkex-0.dtd" table-id="' + tableId + '" rows="' + str(rows) + '" columns="' + str(cols) + '"/>'
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 = '<flowRoot id="' + self.svg.get_unique_id(el.attrib[inkex.addNS('table-id', 'inkex')]) + '" xmlns:inkex="http://sodipodi.sourceforge.net/DTD/inkex-0.dtd" ' + transform + ' \
inkex:table-id="' + el.attrib[inkex.addNS('table-id', 'inkex')] + '-text" inkex:row="' + el.attrib[inkex.addNS('row', 'inkex')] + '" inkex:column="' + el.attrib[inkex.addNS('column', 'inkex')] + '" \
style="font-size:' + fontSize + ';font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"\
xml:space="preserve"><flowRegion id="' + self.svg.get_unique_id(el.attrib[inkex.addNS('table-id', 'inkex')]) + '"><rect id="' + self.svg.get_unique_id(el.attrib[inkex.addNS('table-id', 'inkex')]) + '" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;font-family:Sans;-inkscape-font-specification:Sans"\
x="' + el.attrib['x'] + '"\
y="' + el.attrib['y'] + '"\
width="' + el.attrib['width'] + '"\
height="' + el.attrib['height'] + '"/></flowRegion><flowPara id="' + self.svg.get_unique_id(el.attrib[inkex.addNS('table-id', 'inkex')]) + '">text here</flowPara></flowRoot>'
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)

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Columns</name>
<id>fablabchemnitz.de.table_add_columns</id>
<param name="number" type="int" gui-text="The number of columns to add:">1</param>
<param name="where" type="optiongroup" appearance="radio" gui-text="Before or after the selected column:">
<option value="before">Before</option>
<option value="after">After</option>
</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Add" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_add_columns.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Guide Lines</name>
<id>fablabchemnitz.de.table_add_guides</id>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Add" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_add_guides.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Rows</name>
<id>fablabchemnitz.de.table_add_rows</id>
<param name="number" type="int" gui-text="The number of rows to add:">1</param>
<param name="where" type="optiongroup" appearance="radio" gui-text="Before or after the selected rows:">
<option value="before">Before</option>
<option value="after">After</option>
</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Add" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_add_rows.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Create</name>
<id>fablabchemnitz.de.table_create</id>
<param name="tab" type="notebook">
<page name="options" gui-text="Options">
<param name="cols" type="int" gui-text="The number of columns:">2</param>
<param name="rows" type="int" gui-text="The number of rows:">2</param>
<param name="width" type="string" gui-text="The width of the cell:">100mm</param>
<param name="height" type="string" gui-text="The height of the cell:">20mm</param>
<label>VERY IMPORTANT: You will notice that the newly created table does not contain text. In order to edit any cell's text, just select the cell and then from the Extensions menu select Table -&gt; Edit -&gt; Selected cells text</label>
</page>
<page name="help" gui-text="Help">
<label>This is the first step in using the table support. First create a table. You have to input the number of rows, the number of columns and the width and the height of each cell. The width of the table will equal the number of columns times the width of each cell and the table height will equal the number of rows times the height of each cell. If you want to set a specific width and height for the table, after creating it, you just select it and then select from the Extensions menu -&gt; Table -&gt; Edit -&gt; Table width and height. For the width and height you can also input the measurement unit (mm, cm, in, px etc.). If you don't input any measurement unit, the size will be calculated in pixels. Do not use any space between the value and the unit.</label>
</page>
</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table" />
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_create.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Selected columns width</name>
<id>fablabchemnitz.de.table_edit_columns</id>
<param name="width" type="string" gui-text="Input the new width:">10mm</param>
<!--param name="keep" type="boolean" gui-text="Keep the table original height">false</param-->
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Edit" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_edit_columns.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Selected rows height</name>
<id>fablabchemnitz.de.table_edit_rows</id>
<param name="height" type="string" gui-text="Input the new height:">10mm</param>
<!--param name="keep" type="boolean" gui-text="Keep the table original height">false</param-->
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Edit" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_edit_rows.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Selected table width and height</name>
<id>fablabchemnitz.de.table_edit_table</id>
<dependency type="executable" location="extensions">table_edit_table.py</dependency>
<param name="width" type="string" gui-text="Input the new width of the table:">150mm</param>
<param name="height" type="string" gui-text="Input the new height of the table:">60mm</param>
<!--param name="keep" type="boolean" gui-text="Keep the table original height">false</param-->
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Edit" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_edit_table.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Selected cells text</name>
<id>fablabchemnitz.de.table_edit_text</id>
<param name="size" type="string" gui-text="The font size:">12px</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Edit" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_edit_text.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Selected table to page height</name>
<id>fablabchemnitz.de.table_fit_height</id>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Fit" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_fit_height.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Selected table to page</name>
<id>fablabchemnitz.de.table_fit_page</id>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Fit" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_fit_page.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Selected table to page width</name>
<id>fablabchemnitz.de.table_fit_width</id>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Fit" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_fit_width.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Merge selected cells</name>
<id>fablabchemnitz.de.table_merge_merge</id>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Merge cells" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_merge_merge.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Split selected cells</name>
<id>fablabchemnitz.de.table_merge_split</id>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Merge cells" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_merge_split.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Selected columns</name>
<id>fablabchemnitz.de.table_remove_columns</id>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Remove" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_remove_columns.py</command>
</script>
</inkscape-extension>

View File

@ -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()

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Selected rows</name>
<id>fablabchemnitz.de.table_remove_rows</id>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="FabLab Chemnitz">
<submenu name="Table">
<submenu name="Remove" />
</submenu>
</submenu>
</effects-menu>
</effect>
<script>
<command location="inx" interpreter="python">table_remove_rows.py</command>
</script>
</inkscape-extension>

View File

@ -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()