| 28 | try: import xml.etree.cElementTree as ET |
| 29 | except ImportError: |
| 30 | try: import cElementTree as ET # python <2.5 |
| 31 | except ImportError: |
| 32 | try: import lxml.etree as ET |
| 33 | except ImportError: |
| 34 | try: import xml.etree.ElementTree as ET |
| 35 | except ImportError: |
| 36 | import elementtree.ElementTree as ET |
| 37 | |
| 38 | def split_at_len(s, max_len=50, delimiter=None): |
| 39 | """ |
| 40 | Returns a list of strings, that are split from an |
| 41 | input string. Delimits on whitespace by default. |
| 42 | """ |
| 43 | if delimiter is None: |
| 44 | s = s.split() |
| 45 | else: |
| 46 | s = s.split(delimiter) |
| 47 | |
| 48 | lines = [] |
| 49 | current_line = '' |
| 50 | for word in s: |
| 51 | if len(current_line) >= max_len: |
| 52 | short.append(current_line) |
| 53 | current_line = word |
| 54 | else: |
| 55 | current_line = '%s %s' % (current_line, word); |
| 56 | lines[0] = lines[0][1:] #hack required by string formatting |
| 57 | lines.append(current_line) |
| 58 | return lines |
| 59 | |
| 60 | def process_svg_text_element(el, max_len=50, line_height='1.1em'): |
| 61 | """ |
| 62 | Turns |
| 63 | <text>long ... content</text> |
| 64 | into |
| 65 | <text> |
| 66 | <tspan>long</tspan><tspan>...</tspan><tspan>content</tspan> |
| 67 | </text> |
| 68 | """ |
| 69 | # NOTE Assumes that there are no subelements this |
| 70 | # should be safe because TurtleArt shouldn't |
| 71 | # generate any |
| 72 | data = split_at_len(el.text, max_len=max_len) |
| 73 | |
| 74 | for line in data: |
| 75 | ET.SubElement(el, 'tspan') |
| 76 | |
| 77 | i = 0 |
| 78 | while i < len(data): |
| 79 | el[i].text = data[i] |
| 80 | el[i].attrib['dy'] = (i*line_height) |
| 81 | i = i+1 |
| 82 | return el |
| 83 | |
| 84 | def process_text_in_svg(svg, max_len=50, line_height='1.1em'): |
| 85 | """ |
| 86 | Takes an SVG as a string or file-like object |
| 87 | and returns a string with text elements split |
| 88 | into multiple lines surrounded by <tspan>. |
| 89 | """ |
| 90 | tree = ET.parse(svg) |
| 91 | svg_text = tree.findall('text') |
| 92 | if len(svg_text) > 0: |
| 93 | for el in svg_text: |
| 94 | # TODO check if this actually replaces the element in tree |
| 95 | el = process_svg_text_element(el, |
| 96 | max_len=max_len, |
| 97 | line_height=line_height) |
| 98 | return ET.tostring(tree) |
| 99 | |