home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Inkscape / Inkscape-0.48.2-1-win32.exe / share / extensions / split.py < prev    next >
Text File  |  2011-07-08  |  8KB  |  216 lines

  1. #!/usr/bin/env python 
  2. '''
  3. Copyright (C) 2009 Karlisson Bezerra, contato@nerdson.com
  4.  
  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.
  9.  
  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.
  14.  
  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. '''
  19.  
  20. import inkex
  21.  
  22. class Split(inkex.Effect):
  23.     def __init__(self):
  24.         inkex.Effect.__init__(self)
  25.         self.OptionParser.add_option("-s", "--splittype", 
  26.                         action="store", type="string", 
  27.                         dest="split_type", default="word", 
  28.                         help="type of split")
  29.         self.OptionParser.add_option("-p", "--preserve", 
  30.                         action="store", type="inkbool", 
  31.                         dest="preserve", default="True", 
  32.                         help="Preserve original")
  33.  
  34.  
  35.     def split_lines(self, node):
  36.         """Returns a list of lines"""
  37.  
  38.         lines = []
  39.         count = 1
  40.         
  41.         for n in node:
  42.             if not (n.tag == inkex.addNS("flowPara", "svg") or n.tag == inkex.addNS("tspan", "svg")):
  43.                 if n.tag == inkex.addNS("textPath", "svg"):
  44.                     inkex.debug("This type of text element isn't supported. First remove text from path.")
  45.                     break
  46.                 else:
  47.                     continue
  48.            
  49.             text = inkex.etree.Element(inkex.addNS("text", "svg"), node.attrib)
  50.             
  51.             #handling flowed text nodes
  52.             if node.tag == inkex.addNS("flowRoot", "svg"):
  53.                 try:
  54.                     from simplestyle import parseStyle
  55.                     fontsize = parseStyle(node.get("style"))["font-size"]
  56.                 except:
  57.                     fontsize = "12px"
  58.                 fs = inkex.unittouu(fontsize)
  59.                 
  60.                 #selects the flowRegion's child (svg:rect) to get @X and @Y
  61.                 id = node.get("id")
  62.                 flowref = self.xpathSingle('/svg:svg//*[@id="%s"]/svg:flowRegion[1]' % id)[0]
  63.                 
  64.                 if flowref.tag == inkex.addNS("rect", "svg"):
  65.                     text.set("x", flowref.get("x"))
  66.                     text.set("y", str(float(flowref.get("y")) + fs * count))
  67.                     count += 1
  68.                 else:
  69.                     inkex.debug("This type of text element isn't supported. First unflow text.")
  70.                     break
  71.                 
  72.                 #now let's convert flowPara into tspan
  73.                 tspan = inkex.etree.Element(inkex.addNS("tspan", "svg"))
  74.                 tspan.set(inkex.addNS("role","sodipodi"), "line")
  75.                 tspan.text = n.text
  76.                 text.append(tspan)
  77.             
  78.             else:
  79.                 from copy import copy
  80.                 x = n.get("x") or node.get("x")
  81.                 y = n.get("y") or node.get("y")
  82.  
  83.                 text.set("x", x)
  84.                 text.set("y", y)
  85.                 text.append(copy(n))
  86.             
  87.             lines.append(text)
  88.  
  89.         return lines
  90.  
  91.  
  92.     def split_words(self, node):
  93.         """Returns a list of words"""
  94.         
  95.         words = []
  96.  
  97.         #Function to recursively extract text
  98.         def plain_str(elem):
  99.             words = []
  100.             if elem.text:
  101.                 words.append(elem.text)
  102.             for n in elem:
  103.                 words.extend(plain_str(n))
  104.                 if n.tail:
  105.                     words.append(n.tail)
  106.             return words
  107.         
  108.         #if text has more than one line, iterates through elements
  109.         lines = self.split_lines(node)
  110.         if not lines:
  111.             return words
  112.  
  113.         for line in lines:
  114.             #gets the position of text node
  115.             x = float(line.get("x"))
  116.             y = line.get("y")
  117.             
  118.             #gets the font size. if element doesn't have a style attribute, it assumes font-size = 12px
  119.             try:
  120.                 from simplestyle import parseStyle
  121.                 fontsize = parseStyle(line.get("style"))["font-size"]
  122.             except:
  123.                 fontsize = "12px"
  124.             fs = inkex.unittouu(fontsize)
  125.  
  126.             #extract and returns a list of words
  127.             words_list = "".join(plain_str(line)).split()
  128.             prev_len = 0
  129.             
  130.             #creates new text nodes for each string in words_list
  131.             for word in words_list:
  132.                 tspan = inkex.etree.Element(inkex.addNS("tspan", "svg"))
  133.                 tspan.text = word
  134.                 
  135.                 text = inkex.etree.Element(inkex.addNS("text", "svg"), line.attrib)
  136.                 tspan.set(inkex.addNS("role","sodipodi"), "line")
  137.                 
  138.                 #positioning new text elements
  139.                 x = x + prev_len * fs
  140.                 prev_len = len(word)
  141.                 text.set("x", str(x))
  142.                 text.set("y", str(y))
  143.                 
  144.                 text.append(tspan)
  145.                 words.append(text)
  146.         
  147.         return words
  148.  
  149.  
  150.     def split_letters(self, node):
  151.         """Returns a list of letters"""
  152.  
  153.         letters = []
  154.         
  155.         words = self.split_words(node)
  156.         if not words:
  157.             return letters
  158.  
  159.         for word in words:
  160.             
  161.             x = float(word.get("x"))
  162.             y = word.get("y")
  163.            
  164.             #gets the font size. If element doesn't have a style attribute, it assumes font-size = 12px
  165.             try:
  166.                 import simplestyle
  167.                 fontsize = simplestyle.parseStyle(word.get("style"))["font-size"]
  168.             except:
  169.                 fontsize = "12px"
  170.             fs = inkex.unittouu(fontsize)
  171.  
  172.             #for each letter in element string
  173.             for letter in word[0].text:
  174.                 tspan = inkex.etree.Element(inkex.addNS("tspan", "svg"))
  175.                 tspan.text = letter
  176.  
  177.                 text = inkex.etree.Element(inkex.addNS("text", "svg"), node.attrib)
  178.                 text.set("x", str(x))
  179.                 text.set("y", str(y))
  180.                 x += fs
  181.                 
  182.                 text.append(tspan)
  183.                 letters.append(text)
  184.         return letters
  185.  
  186.  
  187.     def effect(self):
  188.         """Applies the effect"""
  189.  
  190.         split_type = self.options.split_type
  191.         preserve = self.options.preserve
  192.        
  193.         #checks if the selected elements are text nodes
  194.         for id, node in self.selected.iteritems():
  195.             if not (node.tag == inkex.addNS("text", "svg") or node.tag == inkex.addNS("flowRoot", "svg")):
  196.                 inkex.debug("Please select only text elements.")
  197.                 break
  198.             else:
  199.                 if split_type == "line":
  200.                     nodes = self.split_lines(node)
  201.                 elif split_type == "word":
  202.                     nodes = self.split_words(node)
  203.                 elif split_type == "letter":
  204.                     nodes = self.split_letters(node)
  205.                 
  206.                 for n in nodes:
  207.                     node.getparent().append(n)
  208.                         
  209.                 #preserve original element
  210.                 if not preserve and nodes:
  211.                     parent = node.getparent()
  212.                     parent.remove(node)
  213.  
  214. b = Split()
  215. b.affect()
  216.