2

I am trying to turn a SVG path into a list of points in Node. I'm using elementtree to parse the SVG file.

d is the definition for the path, getPos simply turns a "x,y" into an object with an x and a y, doLine simply adds the coordinates to the list.

  d = path.get('d')

  words = d.split(' ')

  oldPos = undefined
  startPos = undefined

  for i in [0..words.length]
    word = words[i]

    if word == 'm' or word == 'M'
      oldPos = getPos(words[i + 1])
      startPos = getPos(words[i + 1])
      i += 1

    else if word == 'l' or word == 'L'
      console.log('done nothing...')

    else if word == 'z' or word == 'Z'
      doLine(oldPos, startPos)

    else if word
      pos = getPos(word)
      doLine(oldPos, pos)
      oldPos = pos

Currently, this doesn't seem to work correctly.

I know that my path will never have curves, so I don't need to worry about that.

I'm not sure on the SVG standard, so if anyone could help me, that would be many thanks.

Tom Leese
  • 19,309
  • 12
  • 45
  • 70

2 Answers2

3

SVG contains its own path segment parser so why reinvent the wheel. Try building on this: http://jsfiddle.net/longsonr/skWH5/

In gecko the path is parsed by starting at the beginning, reading one non-whitespace character, then using a table of the number of expected arguments that follow to know to read so many numbers (which may have up to one comma separating them). This continues till the end of the string.

Robert Longson
  • 118,664
  • 26
  • 252
  • 242
  • I'm not actually doing this on the web, is it possible to access these functions from standalone node.js? – Tom Leese Feb 01 '12 at 21:18
  • You can see the underlying mozilla path parser code written in c++ here: http://mxr.mozilla.org/mozilla-central/source/content/svg/content/src/SVGPathSegListSMILType.cpp#319 does that help? – Robert Longson Feb 01 '12 at 21:33
1

I'm not familiar with coffeescript, but there seem to be a few problems with your code.

  • Most importantly, it seems that your i += 1 only happens if word == 'm or 'M', so I would have thought you get stuck in a loop most of the time.

  • Second, you don't seem to do anything if word == 'l' or 'L' and I would have though that is when you would want to add a node. If you don't have curves, then surely you have lines, unless you're just using horizontal or vertical lines. You will also need to update your current position and do so differently depending on whether it is a relative or absolute command.

  • Finally, you probably shouldn't split with a space as d="M90,20L100,30L110,20z" is a valid path. You say you know there will be no curves in your path, so maybe you also know that all your paths will be split with spaces. In which case, that's fair enough, but it might be worth bearing in mind.

Hope that's of some help.

Peter Collingridge
  • 10,849
  • 3
  • 44
  • 61
  • The i += 1 is used to skip a word, as the next one will be the coordinates. I don't get stuck in the loop as "for i in [0...length]" makes coffeescript loop through the list. I am using inkscape to create the SVG files and they do appear to always be split by words, I did not know that having no spaces was valid. – Tom Leese Feb 02 '12 at 19:48