| 1 | #!/usr/bin/env python |
| 2 | # -*- coding: utf-8 -*- |
| 3 | """ |
| 4 | visio2sodipodi - pas de doc cette fois-ci... :-P |
| 5 | |
| 6 | Copyright : Agence universitaire de la Francophonie |
| 7 | Licence : GNU General Public Licence, version 2 |
| 8 | Auteur : Jean Christophe André |
| 9 | Date de création : 13 octobre 2009 |
| 10 | """ |
| 11 | import sys |
| 12 | import re |
| 13 | from xml.dom import minidom |
| 14 | |
| 15 | SODIPODI_NS = "http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
| 16 | |
| 17 | if len(sys.argv) != 2 or not sys.argv[1].endswith('.svg'): |
| 18 | print "Usage: %s <filename.svg>" % sys.argv[0] |
| 19 | sys.exit(1) |
| 20 | filename = sys.argv[1] |
| 21 | |
| 22 | doc = minidom.parse(filename) |
| 23 | |
| 24 | svg = doc.getElementsByTagName('svg') |
| 25 | if len(svg) != 1: |
| 26 | print u"Ce document n'est pas au format SVG." |
| 27 | sys.exit(1) |
| 28 | svg = svg[0] |
| 29 | |
| 30 | if not svg.hasAttribute('xmlns:v'): |
| 31 | print u"Ce document n'est pas au format MS–Visio." |
| 32 | sys.exit(1) |
| 33 | |
| 34 | if svg.hasAttribute('xmlns:sodipodi'): |
| 35 | print u"Ce document est déjà compatible 'sodipodi'." |
| 36 | sys.exit(1) |
| 37 | # ajout de l'espace de noms SODIPODI_NS |
| 38 | svg.setAttribute('xmlns:sodipodi', SODIPODI_NS) |
| 39 | |
| 40 | default_class = svg.getAttribute('class') |
| 41 | if default_class == '': |
| 42 | print u"Ce document ne contient pas de style par défaut ??" |
| 43 | sys.exit(1) |
| 44 | |
| 45 | style = svg.getElementsByTagName('style') |
| 46 | if len(style) != 1: |
| 47 | print u"Ce document contient plusieurs sections de styles ??" |
| 48 | sys.exit(1) |
| 49 | style = style[0] |
| 50 | |
| 51 | # ajout de "text-align:center" au style .st7 |
| 52 | for child in style.childNodes: |
| 53 | if child.nodeType == minidom.Node.CDATA_SECTION_NODE: |
| 54 | value = child.nodeValue |
| 55 | pat = r'\.st7 {([^}]*)}' |
| 56 | rep = r'.st7 {\1;text-align:center}' |
| 57 | value = re.sub(pat, rep, value, 1) |
| 58 | pat = r'(\.st7 {[^}]*font-size):[^;]*(;[^}]*})' |
| 59 | rep = r'\1:0.833336em\2' |
| 60 | value = re.sub(pat, rep, value, 1) |
| 61 | pat = r'(\.%s {[^}]*font-size):[^;]*(;[^}]*})' % default_class |
| 62 | rep = r'\1:8\2' |
| 63 | value = re.sub(pat, rep, value, 1) |
| 64 | child.nodeValue = value |
| 65 | break |
| 66 | |
| 67 | for text in svg.getElementsByTagName('text'): |
| 68 | childNodes = [child for child in text.childNodes] |
| 69 | for child in childNodes: |
| 70 | # encadrer tout TEXT dans un <text> par un <tspan> |
| 71 | if child.nodeType == minidom.Node.TEXT_NODE: |
| 72 | tspan = doc.createElement('tspan') |
| 73 | tspan.appendChild(doc.createTextNode(child.nodeValue)) |
| 74 | text.replaceChild(tspan, child) |
| 75 | elif child.nodeType == minidom.Node.ELEMENT_NODE: |
| 76 | # virer les <v:newlineChar/> |
| 77 | if child.nodeName == 'v:newlineChar': |
| 78 | text.removeChild(child) |
| 79 | # y compris à l'intérieur des tspan |
| 80 | elif child.nodeName == 'tspan': |
| 81 | if child.hasAttribute('dy'): |
| 82 | tspan = doc.createElement('tspan') |
| 83 | tspan.setAttribute('sodipodi:role', 'line') |
| 84 | text.insertBefore(tspan, child) |
| 85 | node = child.firstChild |
| 86 | if node.nodeType == minidom.Node.ELEMENT_NODE and \ |
| 87 | node.nodeName == 'v:newlineChar': |
| 88 | child.removeChild(node) |
| 89 | node = child.lastChild |
| 90 | if node.nodeType == minidom.Node.ELEMENT_NODE and \ |
| 91 | node.nodeName == 'v:newlineChar': |
| 92 | child.removeChild(node) |
| 93 | |
| 94 | file = open(filename.replace('.svg','-new.svg'), 'wb') |
| 95 | file.write(doc.toxml(encoding=doc.encoding)) |
| 96 | file.close() |
| 97 | |
| 98 | sys.exit(0) |