Open File and Read
I mentioned I needed a project to work on and Zach Beane mentioned an SVG parser. I thought it sounded really cool, but I have never programmed a parser before in any language. So, I started writing code yesterday that hopefully will turn into an SVG parser. I started with simply opening an SVG and reading it line by line.
An SVG is actually created by using XML. I heard you can use javascript to do this, but I don’t know much about that yet. I have been reading the w3.org site for SVG information. They had an example of an upside down triangle, so I grabbed that to test my code. Here is the XML code that makes up the SVG. If you copied this to a text file and then saved it as a .svg, you could open the file with your web browser and see the red upside down triangle it creates.
<?xml version=”1.0″ standalone=”no”?>
<!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1//EN”
“http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd”>
<svg width=”4cm” height=”4cm” viewBox=”0 0 400 400″
xmlns=”http://www.w3.org/2000/svg” version=”1.1″>
<title>Example triangle01- simple example of a ‘path’</title>
<desc>A path that draws a triangle</desc>
<rect x=”1″ y=”1″ width=”398″ height=”398″
fill=”none” stroke=”blue” />
<path d=”M 100 100 L 300 100 L 200 300 z”
fill=”red” stroke=”blue” stroke-width=”3″ />
</svg>
I have been using CUSP lately to do all of my Common Lisp coding. Especially after talking with Jasko at the programming meetup we had last week. I like using it, plus I can use it on Windows and that is all I have at work, so it makes it more convenient.
What took me the longest with this code was the Windows pathname. I wasn’t sure how SBCL looks at that. SBCL is what CUSP uses as it’s implementation, by the way. Which is great, because I want to use SBCL. I had to play with it quite a bit but finally figured out the pathname. I placed my tri.svg file in my C:\lispstuff directory. So after playing in the REPL and trying different options, I figured out SBCL reads it as “C:\\lispstuff\\tri.svg”.
Once I had that, I knew the best thing to use to open a file and read it was the Common Lisp macro WITH-OPEN-FILE. Peter Seibel talks about this in his Practical Common Lisp book in chapter 14. Then I used a do loop to step through each line of the file and “format” to print them out. Here is the code:
Keep in mind this code is indented, but WordPress really sucks when it comes to handling code. I need to switch this to a different blog.
I uploaded the actual text file so you could see the indention, get it here.
(defun pjmain ()
(with-open-file (stream “C:\\lispstuff\\tri.svg”)
(do ((line (read-line stream nil)
(read-line stream nil)))
((null line))
(format t “~A~%” line))))
I will have to revisit this code for the parser, because I need a way for it to ask the person what SVG file they would like to parse. The next thing I need to do is try to parse this. I have a lot of reading to do. I know Zach mentioned he only needed the path data of the SVG, so I will concentrate on obtaining that first.
Any tips or suggestions on any of this is definitely welcome. I am a beginner after all.
6 comments so far
Leave a reply
I don’t recommend putting pathnames into functions. It’s better to pass the pathname in as an argument. If you you pass it as an argument, you can do something like:
(parse-svg “foo.svg”)
Then you don’t have to change the function if you want to use it on a different file.
Another option is to keep the filename in a special variable:
(defvar *input-file* “foo.svg”)
Then you can change the input file by changing the special, without having to redefine your function.
I think CXML will be your best bet for processing XML structure. The path data itself will require something else.
Thanks for the comments Zach, will do.
Thanks for the tip on CXML, I just Googled it and found the site. Closure XML Parser. I’ll check it out.
WordPress is really nice. You could always find a plugin that would format your code nicely. You could also just format your code in HTML.
For Scheme I use http://scheme.dk/paste/, and, as prescribed, paste in the resulting HTML. It works really well.
May I ask what exactly does the SVG parser do? Is the goal to be able to edit SVG or to render SVG?
As a side note, WordPress allow you to use
tags for source code. The code renders in a monospace typeface and is formatted. Tab characters can be an issue, but nothing's perfect.Wonderful comments about WordPress, that is good advice. I’ll give that a shot.
@Ralph:
The SVG Parser is basically Zach’s idea. He wanted to pull the data path out of SVG’s so he can use it in Vecto, found here:
http://www.xach.com/lisp/vecto/