1 #!/usr/bin/env python
2 '''
3 Copyright (C) 2010 Aurelio A. Heckert, aurium (a) gmail dot com
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 '''
20 from webslicer_effect import *
21 import inkex
22 import gettext
23 import os.path
24 import tempfile
25 import commands
27 _ = gettext.gettext
29 class WebSlicer_Export(WebSlicer_Effect):
31 def __init__(self):
32 WebSlicer_Effect.__init__(self)
33 self.OptionParser.add_option("--dir",
34 action="store", type="string",
35 dest="dir",
36 help="")
37 self.OptionParser.add_option("--create-dir",
38 action="store", type="inkbool",
39 default=False,
40 dest="create_dir",
41 help="")
42 self.OptionParser.add_option("--with-code",
43 action="store", type="inkbool",
44 default=False,
45 dest="with_code",
46 help="")
48 def effect(self):
49 # The user must supply a directory to export:
50 if is_empty( self.options.dir ):
51 inkex.errormsg(_('You must to give a directory to export the slices.'))
52 return {'error':'You must to give a directory to export the slices.'}
53 # No directory separator at the path end:
54 if self.options.dir[-1] == '/' or self.options.dir[-1] == '\\':
55 self.options.dir = self.options.dir[0:-1]
56 # Test if the directory exists:
57 if not os.path.exists( self.options.dir ):
58 if self.options.create_dir:
59 # Try to create it:
60 try:
61 os.makedirs( self.options.dir )
62 except Exception as e:
63 inkex.errormsg( _('Can\'t create "%s".') % self.options.dir )
64 inkex.errormsg( _('Error: %s') % e )
65 return {'error':'Can\'t create the directory to export.'}
66 else:
67 inkex.errormsg(_('The directory "%s" does not exists.') % self.options.dir)
68 return
69 # Create HTML and CSS files, if the user wants:
70 if self.options.with_code:
71 try:
72 self.html = open(os.path.join(self.options.dir,'layout.html'), 'w')
73 self.css = open(os.path.join(self.options.dir,'style.css'), 'w')
74 self.html.write('Only a test yet\n\n')
75 self.css.write('/* Only a test yet */\n\n')
76 except Exception as e:
77 inkex.errormsg( _('Can\'t create code files.') )
78 inkex.errormsg( _('Error: %s') % e )
79 return {'error':'Can\'t create code files.'}
80 # Create the temporary SVG with invisible Slicer layer to export image pieces
81 self.create_the_temporary_svg()
82 # Start what we really want!
83 self.export_chids_of( self.get_slicer_layer() )
84 # Close the HTML and CSS files:
85 if self.options.with_code:
86 self.html.close()
87 self.css.write( self.css_code() )
88 self.css.close()
89 # Delete the temporary SVG with invisible Slicer layer
90 self.delete_the_temporary_svg()
91 #TODO: prevent inkex to return svg code to update Inkscape
94 svgNS = '{http://www.w3.org/2000/svg}'
97 def create_the_temporary_svg(self):
98 (ref, self.tmp_svg) = tempfile.mkstemp('.svg')
99 layer = self.get_slicer_layer()
100 current_style = ('style' in layer.attrib) and layer.attrib['style'] or ''
101 layer.attrib['style'] = 'display:none'
102 self.document.write( self.tmp_svg );
103 layer.attrib['style'] = current_style
106 def delete_the_temporary_svg(self):
107 os.remove( self.tmp_svg )
110 noid_element_count = 0
111 def get_el_conf(self, el):
112 desc = el.find('{http://www.w3.org/2000/svg}desc')
113 conf = {}
114 if desc is None:
115 desc = inkex.etree.SubElement(el, 'desc')
116 if desc.text is None:
117 desc.text = ''
118 for line in desc.text.split("\n"):
119 if line.find(':') > 0:
120 line = line.split(':')
121 conf[line[0].strip()] = line[1].strip()
122 if not 'html-id' in conf:
123 if el == self.get_slicer_layer():
124 return {'html-id':'#body#'}
125 else:
126 self.noid_element_count += 1
127 conf['html-id'] = 'element-'+str(self.noid_element_count)
128 desc.text += "\nhtml-id:"+conf['html-id']
129 return conf
132 def export_chids_of(self, parent):
133 parent_id = self.get_el_conf( parent )['html-id']
134 for el in parent.getchildren():
135 el_conf = self.get_el_conf( el )
136 if el.tag == self.svgNS+'g':
137 if self.options.with_code:
138 self.register_group_code( el, el_conf )
139 else:
140 self.export_chids_of( el )
141 if el.tag in [ self.svgNS+'rect', self.svgNS+'path', self.svgNS+'circle' ]:
142 if self.options.with_code:
143 self.register_unity_code( el, el_conf, parent_id )
144 self.export_img( el, el_conf )
147 def register_group_code(self, group, conf):
148 #inkex.errormsg( 'group CSS and HTML' )
149 self.html.write( '<div id="G">\n' )
150 for att in conf:
151 self.html.write( ' <!-- {att} : {val} -->\n'.format(att=att, val=conf[att]) )
152 self.export_chids_of( group )
153 self.html.write( '</div><!-- end id="G" -->\n' )
156 def register_unity_code(self, el, conf, parent_id):
157 #inkex.errormsg( 'unity CSS and HTML' )
158 css_selector = '#'+conf['html-id']
159 if not 'layout-disposition' in conf:
160 conf['layout-disposition'] = 'bg-el-norepeat'
161 if conf['layout-disposition'][0:9] == 'bg-parent':
162 if parent_id == '#body#':
163 css_selector = 'body'
164 else:
165 css_selector = '#'+parent_id
166 for att in conf:
167 self.html.write( '<!-- bg {att} : {val} -->\n'.format(att=att, val=conf[att]) )
168 else:
169 self.html.write( '<div id="image">\n' )
170 for att in conf:
171 self.html.write( ' <!-- {att} : {val} -->\n'.format(att=att, val=conf[att]) )
172 self.html.write( '</div><!-- end id="image" -->\n' )
173 self.reg_css( css_selector, 'background',
174 'url("%s")' % self.img_name(el, conf) )
177 def img_name(self, el, conf):
178 return el.attrib['id']+'.png'
180 def export_img(self, el, conf):
181 (status, output) = commands.getstatusoutput(
182 "inkscape -i '%s' -e '%s' '%s'" % (
183 el.attrib['id'],
184 os.path.join( self.options.dir, self.img_name(el, conf) ),
185 self.tmp_svg
186 )
187 )
188 #inkex.errormsg( status )
189 #inkex.errormsg( output )
192 _css = {}
193 def reg_css(self, selector, att, val):
194 if not selector in self._css: self._css[selector] = {}
195 if not att in self._css[selector]: self._css[selector][att] = []
196 self._css[selector][att].append( val )
198 def css_code(self):
199 code = ''
200 for selector in self._css:
201 code += '\n'+selector+' {\n'
202 for att in self._css[selector]:
203 code += ' '+ att +': '+ (', '.join(self._css[selector][att])) +';\n'
204 code += '}\n'
205 return code
208 if __name__ == '__main__':
209 e = WebSlicer_Export()
210 e.affect()