| Andrew Cooke | Contents | Latest | RSS | Twitter | Previous | Next

C[omp]ute

Welcome to my blog, which was once a mailing list of the same name and is still generated by mail. Please reply via the "comment" links.

Always interested in offers/projects/new ideas. Eclectic experience in fields like: numerical computing; Python web; Java enterprise; functional languages; GPGPU; SQL databases; etc. Based in Santiago, Chile; telecommute worldwide. CV; email.

Personal Projects

Lepl parser for Python.

Colorless Green.

Photography around Santiago.

SVG experiment.

Professional Portfolio

Calibration of seismometers.

Data access via web services.

Cache rewrite.

Extending OpenSSH.

C-ORM: docs, API.

Last 100 entries

Crypto AG DID work with NSA / GCHQ; UNUMS (Universal Number Format); MOOCs (Massive Open Online Courses); Interesting Looking Game; Euler's Theorem for Polynomials; Weeks 3-6; Reddit Comment; Differential Cryptanalysis For Dummies; Japanese Graphic Design; Books To Be Re-Read; And Today I Learned Bugs Need Clear Examples; Factoring a 67 bit prime in your head; Islamic Geometric Art; Useful Julia Backtraces from Tasks; Nothing, however, is lost with less discomfort than that which, when lost, cannot be missed; Article on Didion; Cost of Living by City; British Slavery; Derrida on Metaphor; African SciFi; Traits in Julia; Alternative Japanese Lit; Pulic Key as Address (Snow); Why Information Grows; The Blindness Of The Chilean Elite; Some Victoriagate Links; This Is Why I Left StackOverflow; New TLS Implementation; Maths for Physicists; How I Am 8; 1000 Word Philosophy; Cyberpunk Reading List; Detailed Discussion of Message Dispatch in ParserCombinator Library for Julia; FizzBuzz in Julia w Dependent Types; kokko - Design Shop in Osaka; Summary of Greece, Currently; LLVM and GPUs; See Also; Schoolgirl Groyps (Maths); Japanese Lit; Another Example - Modular Arithmetic; Music from United; Python 2 and 3 compatible alternative.; Read Agatha Christie for the Plot; A Constructive Look at TempleOS; Music Thread w Many Recommendations; Fixed Version; A Useful Julia Macro To Define Equality And Hash; k3b cdrom access, OpenSuse 13.1; Week 2; From outside, the UK looks less than stellar; Huge Fonts in VirtualBox; Keen - Complex Emergencies; The Fallen of World War II; Some Spanish Fiction; Calling C From Fortran 95; Bjork DJ Set; Z3 Example With Python; Week 1; Useful Guide To Starting With IJulia; UK Election + Media; Review: Reinventing Organizations; Inline Assembly With Julia / LLVM; Against the definition of types; Dumb Crypto Paper; The Search For Quasi-Periodicity...; Is There An Alternative To Processing?; CARDIAC (CARDboard Illustrative Aid to Computation); The Bolivian Case Against Chile At The Hague; Clear, Cogent Economic Arguments For Immigration; A Program To Say If I Am Working; Decent Cards For Ill People; New Photo; Luksic And Barrick Gold; President Bachelet's Speech; Baltimore Primer; libxml2 Parsing Stream; configure.ac Recipe For Library Path; The Davalos Affair For Idiots; Not The Onion: Google Fireside Chat w Kissinger; Bicycle Wheels, Inertia, and Energy; Another Tax Fraud; Google's Borg; A Verion That Redirects To Local HTTP Server; Spanish Accents For Idiots; Aluminium Cans; Advice on Spray Painting; Female View of Online Chat From a Male; UX Reading List; S4 Subgroups - Geometric Interpretation; Fucking Email; The SQM Affair For Idiots; Using Kolmogorov Complexity; Oblique Strategies in bash; Curses Tools; Markov Chain Monte Carlo Without all the Bullshit; Email Para Matias Godoy Mercado; The Penta Affair For Idiots; Example Code To Create numpy Array in C; Good Article on Bias in Graphic Design (NYTimes); Do You Backup github?

© 2006-2015 Andrew Cooke (site) / post authors (content).

Generating SVG in Python 2.4

From: andrew cooke <andrew@...>

Date: Fri, 23 Jul 2010 10:07:27 -0400

There's not much love for Python 2.4 and SVG (which, I admit is something of
an odd combination - who would be so conservative they would use Python 2.4
and then require SVG?), particularly if you need a non-GPL solution.  So I
ended up wiring a simple wrapper around DOM that helps generate the XML.
Here's a summary of the approach (there's nothing really hard here, just
fiddly DOM details):

class SvgBase(object):
    '''
    Support class.  Contains a reference to the DOM document and
    the element corresponding to this node.  Note that we allow any
    node to be extended with any child node; we also allow any 
    attribute to be added.
    '''
    
    SVG = 'http://www.w3.org/2000/svg'
    
    def __init__(self, doc, element, **attrs):
        self._doc = doc
        self._element = element
        for name in attrs:
            value = attrs[name]
            if value is not None:
                self._element.setAttributeNS(self.SVG, name, str(value))
        
    def line(self, (x1, y1), (x2, y2), **attrs):
        '''
        Add a child line
        '''
        return Line(self, (x1, y1), (x2, y2), **attrs)
       
    # more child metods here.....


class Svg(SvgBase):
    '''
    The root svg element.  This creates the document, allows a 
    stylesheet to be used, etc.
    '''

    def __init__(self, version='1.1', width=None, height=None):
        implementation = getDOMImplementation('')
        doctype = implementation.createDocumentType('svg', 
            '-//W3C//DTD SVG 1.1//EN', 
            'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd')
        document = implementation.createDocument(self.SVG, 'svg', doctype)
        for node in document.childNodes:
            if node.nodeType == Node.ELEMENT_NODE:
                element = node
                break
        # xlink lets "a" element work correctly (use xlink:href)
        ns = {'xmlns': self.SVG,
              'xmlns:xlink': 'http://www.w3.org/1999/xlink'}
        super(Svg, self).__init__(document, element, 
                                  version=version, width=width, height=height,
                                  **ns)
        
    def add_stylesheet(self, url):
        style = self._doc.createProcessingInstruction('xml-stylesheet',
                        'href="%s" type="text/css"' % url)
        for node in self._doc.childNodes:
            if node.nodeType == Node.DOCUMENT_TYPE_NODE:
                self._doc.insertBefore(style, node)
                break

    def __str__(self):
        '''
        The XML of the entire document.
        '''
        return self._doc.toxml()
    

class Line(SvgBase):
    '''
    An example child node.
    '''

    def __init__(self, parent, (x1, y1), (x2, y2), **attrs):
        element = parent._doc.createElementNS(self.SVG, 'line')
        super(Line, self).__init__(parent._doc, element,
                                   x1=self._1dp(x1), y1=self._1dp(y1), 
                                   x2=self._1dp(x2), y2=self._1dp(y2), 
                                   **attrs)
        parent._element.appendChild(self._element)


With that, it's pretty easy to do things like:

    >>> svg = Svg()
    >>> svg.line((1,2), (3,4), stroke='blue')
    >>> svg.add_stylesheet('http://example.com/foo')
    >>> str(svg)
    '''<?xml version="1.0" ?>
       <?xml-stylesheet href="http://example.com/foo" type="text/css"?>
       <!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  
                 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
       <svg version="1.1" xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink">
         <line x1="1.0" x2="3.0" y1="2.0" y2="4.0" stroke="blue"/>
       </svg>'''

Andrew

Comment on this post