1 #!/usr/bin/env python
2 '''
3 Guides Creator v2.0 (25/11/2008)
4 http://code.google.com/p/inkscape-guides-creator/
6 Copyright (C) 2008 Jonas Termeau - jonas.termeau **AT** gmail.com
8 Thanks to Bernard Gray - bernard.gray **AT** gmail.com
10 ## This basic extension allows you to automatically draw guides in inkscape.
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 '''
27 # inspired by hello_world turorial by Blackhex and Rubikcube
28 # (http://wiki.inkscape.org/wiki/index.php/PythonEffectTutorial)
30 # Making an .INX file : http://wiki.inkscape.org/wiki/index.php/MakingAnINX
31 # see also http://codespeak.net/lxml/dev/tutorial.html#namespaces for XML namespaces manipulation
33 # # # # # # # #
34 # TODO: See http://code.google.com/p/inkscape-guides-creator/wiki/Roadmap
35 #
36 # # # # # # # #
39 # # # extension's begining # # #
41 # These two lines are only needed if you don't put the script directly into
42 # the installation directory
43 import sys
44 sys.path.append('/usr/share/inkscape/extensions')
46 # We will use the inkex module with the predefined Effect base class.
47 import inkex
48 from simplestyle import *
50 from xml.etree import ElementTree as ET
52 # for golden number formulae
53 from math import sqrt
55 # for printing debugging output
56 import gettext
57 _ = gettext.gettext
59 def printDebug(string):
60 inkex.errormsg(_(string))
62 def drawVerticalGuides(division,w,h,edges,parent):
63 if (division > 0):
64 if (edges):
65 var = 1
66 else:
67 var = 0
69 for v in range(0,division-1+2*var):
70 # setting up the guide's attributes (id is generated automatically)
71 position = str(round((w / division) + (v - var) * (w / division),4)) + ",0"
72 orientation = str(round(h,4)) + ",0"
74 createGuide(position,orientation,parent)
76 def drawHorizontalGuides(division,w,h,edges,parent):
77 if (division > 0):
78 if (edges):
79 var = 1
80 else:
81 var = 0
83 for x in range(0,division-1+2*var):
84 # setting up the guide's attributes (id is generated automatically)
85 position = "0," + str(round((h / division) + (x - var) * (h / division),4))
86 orientation = "0," + str(round(w,4))
88 createGuide(position,orientation,parent)
90 def createGuide(position,orientation,parent):
91 # Create a sodipodi:guide node
92 # (look into inkex's namespaces to find 'sodipodi' value in order to make a "sodipodi:guide" tag)
93 # see NSS array in file inkex.py for the other namespaces
94 inkex.etree.SubElement(parent,'{http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd}guide',{'position':position,'orientation':orientation})
96 def getVerticalDivisionsFromPreset(preset):
97 # take a "string1;string2" preset
98 # and return "string1"
100 str_array = preset.split(';')
101 result = int(str_array[0])
103 return result
105 def getHorizontalDivisionsFromPreset(preset):
106 # take a "string1;string2" preset
107 # and return "string2"
109 str_array = preset.split(';')
110 result = int(str_array[1])
112 return result
114 class Guides_Creator(inkex.Effect):
116 def __init__(self):
117 """
118 Constructor.
119 Defines options of the script.
120 """
121 # Call the base class constructor.
122 inkex.Effect.__init__(self)
124 # Define string option "--preset" with default value 'custom'.
125 self.OptionParser.add_option('--preset',
126 action = 'store',type = 'string',
127 dest = 'preset',default = 'custom',
128 help = 'Preset')
130 # Define string option "--vertical_guides" with default value '0'.
131 self.OptionParser.add_option('--vertical_guides',
132 action = 'store',type = 'string',
133 dest = 'vertical_guides',default = 0,
134 help = 'Vertical guides each:')
136 # Define string option "--horizontal_guides" with default value '0'.
137 self.OptionParser.add_option('--horizontal_guides',
138 action = 'store',type = 'string',
139 dest = 'horizontal_guides',default = 0,
140 help = 'Horizontal guides each:')
142 # Define string option "--start_from_edges" with default value False.
143 self.OptionParser.add_option('--start_from_edges',
144 action = 'store',type = 'inkbool',
145 dest = 'start_from_edges',default = False,
146 help = 'Start from edges')
148 # Define string option "--delete_existing_guides" with default value False.
149 self.OptionParser.add_option('--delete_existing_guides',
150 action = 'store',type = 'inkbool',
151 dest = 'delete_existing_guides',default = False,
152 help = 'Delete existing guides')
154 def effect(self):
156 # Get script's options value.
157 from_edges = self.options.start_from_edges
158 delete_existing = self.options.delete_existing_guides
159 h_division = int(self.options.horizontal_guides)
160 v_division = int(self.options.vertical_guides)
161 preset = self.options.preset
163 # Get access to main SVG document element and get its dimensions.
164 svg = self.document.getroot()
166 # getting the width and height attributes of the canvas
167 width = inkex.unittouu(svg.get('width'))
168 height = inkex.unittouu(svg.attrib['height'])
170 # getting the parent tag of the guide
171 nv = self.document.xpath('/svg:svg/sodipodi:namedview',namespaces=inkex.NSS)[0]
173 if (delete_existing):
174 # getting all the guides
175 children = self.document.xpath('/svg:svg/sodipodi:namedview/sodipodi:guide',namespaces=inkex.NSS)
177 # removing each guides
178 for element in children:
179 nv.remove(element)
181 if (preset == 'custom'):
183 # creating vertical guides
184 drawVerticalGuides(v_division,width,height,from_edges,nv)
186 # creating horizontal guides
187 drawHorizontalGuides(h_division,width,height,from_edges,nv)
189 elif (preset == 'golden'):
191 gold = (1 + sqrt(5)) / 2
193 # horizontal golden guides
194 position1 = '0,' + str(height / gold)
195 position2 = '0,'+ str(height - (height / gold))
196 h_orientation = '0,' + str(round(width,4))
198 createGuide(position1,h_orientation,nv)
199 createGuide(position2,h_orientation,nv)
201 # vertical golden guides
202 position1 = str(width / gold) + ',0'
203 position2 = str(width - (width / gold)) + ',0'
204 v_orientation = str(round(height,4)) + ',0'
206 createGuide(position1,v_orientation,nv)
207 createGuide(position2,v_orientation,nv)
209 if (from_edges):
210 # horizontal borders
211 createGuide('0,' + str(height),h_orientation,nv)
212 createGuide(str(height) + ',0',h_orientation,nv)
214 # horizontal borders
215 createGuide('0,' + str(width),v_orientation,nv)
216 createGuide(str(width) + ',0',v_orientation,nv)
219 else:
221 v_division = getVerticalDivisionsFromPreset(preset)
222 h_division = getHorizontalDivisionsFromPreset(preset)
224 drawVerticalGuides(v_division,width,height,from_edges,nv)
225 drawHorizontalGuides(h_division,width,height,from_edges,nv)
228 if __name__ == '__main__': #pragma: no cover
229 # Create effect instance and apply it.
230 effect = Guides_Creator()
231 effect.affect()
233 ## end of file guide_creator.py ##