13 ms·
>Furthermore the XML-based syntax is pretty ugly and needlessly verbose. It’s tiring to write by hand and just as tiring to parse or generate automatically. Wh
by simias 6y ago
>Furthermore the XML-based syntax is pretty ugly and needlessly verbose. It’s tiring to write by hand and just as tiring to parse or generate automatically.
What's even worse is that because XML is a garbage fire of a format, SVG actually builds its own micro-DSL to work around limitations.
So for instance you have something like:
<circle cx="10" cy="10" r="2" fill="red"/>
Ok, fair enough. Readable, self-describing.
But then you have:
<path d="M 10 10 H 90 V 90 H 10 L 10 10"/>
Oh. You can almost hear the designer saying "well fuck it, we'll just jam it all into a string.
The fact that SGML-based formats managed to become as popular as they are is really proof that there's something fundamentally rotten in software engineering.
I do quite like SVG though. I mean, if the alternative is drawing with CSS, it's pretty amazing. I don't really agree that it's hard to generate programmatically either, you just have to decide what subset of the format you need, look at what inkscape generates and go from there. If you need to generate basic shapes it's fairly straightforward.
- tannhaeuser 6y agoAgree a vector graphics format isn't the use case for markup languages. SVG's saving grace, though, is that's designed to be embedded in HTML.
- goto11 6y ago> The fact that SGML-based formats managed to become as popular as they are is really proof that there's something fundamentally rotten in software engineering. HTML is a pretty good syntax though. SGML-like syntax is just less appropriate for formats which are not text-centered, since the element/attribute distinction becomes superfluous noise in the syntax.
- simias 6y agoI agree, HTML is fine (still a bit too verbose IMO, in particular having to repeat the tag to close it always felt useless and very noisy). But HTML is a markup language, the problem is that for some insane reason a big chunk of the industry at some point decided that XML was a reasonable serialization format. That's where it went really wrong IMO.
- goto11 6y agoIn HTML you can leave out the end tag in cases where they can be unambiguously inferred, like: <p>First paragraph<p>Second paragraph</p> P-element can't be nested, so a <p> will automatically close the previous p-element. But this also means it is necessary to indicate the tag name in the closing tag. For example this would be ambiguous: <div><p>Hello</> It cannot be inferred if it is the div or p which is closed. XML is of course different. Since all element have to be explicitly closed, repeating the tag-name in the close tag is in principle superfluous. I think it makes it easier to read though, at the cost of more effort to write.
- runarberg 6y agoUsing D3 to draw plots and other data visualizations is really golden. Next to other good plotting libraries (such as ggplot2) having SVG as my canvas really gives me the feeling that I can do everything that I want.
- qwertay 6y agoIts good if you need dynamic charts in JS but if you just want a graphic or a logo I wouldn't use it. Its also a huge pain to maintain, they update the library once a year with breaking changes and then it takes me a day or 2 to work out how the old version worked, how the new one works and how to move all my graphics over.
- gibolt 6y agoYou don't edit raw png values either, with rgb/index values in a list. SVGs are meant to be created and used like any image file. The fact that they are almost human-editable and can be inlined means we are bound to be disappointed when working with them in this manner
- Eisfunke 6y agoYes, but SVG is not good as a machine-focused format as well, that's kind of the point.
- dillondoyle 6y agoI like this kind of compromise where illustrator etc generates the SVG but you can read elements in the actual text so you can animate or transform with css or js. Fir example I recently made this 'hack' for gradient transform. even 'hacking' that was easier than maintaining and understanding complex canvas JS - at least to me. https://4degreesdigital.com https://4degreesdigital.com
- ROARosen 6y agoLove it! I'm just wondering, aside from the animation part do you ever need to edit an Illustrator-generated svg?
- nikkwong 6y agoI do personally for color control. You can see my heavy use of SVGs here at a site I'm in the middle of implementing [0]. For example, if you look in the :root {} you will see a lot of CSS variables that are declared and which manipulate their HSL value based on base variables like --hue. The SVGs implement these. So you can change the global --hue, and the hue of all the SVG elements on the page will change. I've modified output SVGs from figma/illustrator to reference a variable rather than a hardcoded fill i.e. <path fill="red"> becomes <path fill="var(--base)"> That's a simple example, you can go further to change relative saturation and lightness as well, which I also do with CSS calc(). It's fun! [0] www.holysnacks.us
- colllectorof 6y agoCan't wait for the improved JSON version: {"path": {"d": ["M", 10, 10, "H", 90, "V", 90, "H", 10, "L", 10, 10]}}
- goto11 6y agoSince this is HN I will point out that s-expressions are vastly superior: (path (d (M 10 10) (H 90) (V 90) (H 10) (L 10 10)))
- kazinator 6y agoYou probably mean (path d M 10 10 H 90 V 90 H 10 L 10 10) Shore up some nesting for the commands with pattern matching, returning a path struct: This is the TXR Lisp interactive listener of TXR 251. Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet. Garbage collection is on Tuesdays: bring unwanted pointers to curb by 7:30. 1> (defstruct path () name args) #<struct-type path> 2> (defun parse-path-args (args) (match-case args ((M @x @y . @rest) ^((M ,x ,y) ,*(parse-path-args rest))) ((L @x @y . @rest) ^((L ,x ,y) ,*(parse-path-args rest))) ((H @x . @rest) ^((H ,x) ,*(parse-path-args rest))) ((V @x . @rest) ^((V ,x) ,*(parse-path-args rest))) (()) (@else (error "bad path arguments: ~s" else)))) parse-path-args 3> (defun-match parse-path (((path @(symbolp @name) . @args)) (new path name name args (parse-path-args args))) ((@else) (error "bad path syntax: ~s" else))) parse-path 4> (parse-path '(path d M 10 10 H 90 V 90 H 10 L 10 10)) #S(path name d args ((M 10 10) (H 90) (V 90) (H 10) (L 10 10))) Error cases: 5> (parse-path '(path d M 10 10 H 90 V 90 X 10 L 10 10)) ** bad path arguments: (X 10 L 10 10) ** during evaluation of form (error "bad path arguments: ~s" else) ** ... an expansion of (progn (error "bad path arguments: ~s" else)) ** which is located at expr-2:2 ** run with --backtrace to enable backtraces 6> (parse-path '(paath d M 10 10 H 90 V 90 X 10 L 10 10)) ** bad path syntax: paath d M 10 10 H 90 V 90 X 10 L 10 10 ** during evaluation of form (error `bad path syntax: @else`) ** ... an expansion of (progn (error `bad path syntax: @else`)) ** which is located at expr-3:1 ** run with --backtrace to enable backtraces
- cdrini 6y agoHow is XML a garbage fire? In comparison to what? Also, representing paths succinctly as text is inherently complicated. You're trying to represent a very 2D thing in a linear 1D syntax. It's not a limitation of XML, it's a limitation of text being 1D. XML/SGML are a very effective way of representing tree data (again, non-1D data) in 1D strings. And they're wonderfully extensible, while still keeping a well defined schema. Is there an alternative language that is better? How is it better?
- runarberg 6y agoExactly, in the canvas API this is written like: <path d="M 10 10 H 90 V 90 H 10 L 10 10"/> ctx.moveTo(10, 10); ctx.lineTo(90, 10); ctx.lineTo(90, 90); ctx.lineTo(10, 90); ctx.lineTo(10, 10); Not much better.
- simias 6y agoI disagree, the JS code is immediately understandable without having to lookup anything. You could do it in pure XML but the result would probably be much more verbose.
- runarberg 6y agoTo be equivalent the SVG `<path>` element would probably need to take an idref to something like a `<draw>` element. This is how I would guess the equivalent would be: <draw id="my-path"> <move-to x="10" y="10" /> <line-to x="90" y="10" /> <line-to x="90" y="90" /> <line-to x="10" y="90" /> <line-to x="10" y="10" /> </draw> <path draw="my-path" /> EDIT: Come to think of it, the above is probably a lot easier to animate using CSS or SMIL. Animating the `d` attribute on `<path>`s is theoretically possible but in practice weird at best or browser inconsistent or simply impossible at worst. EDIT 2: In D3 it is not uncommon to draw area graphs with a thick border on top. The only way to do this is with two `<path>`s with almost identical `d` attributes. Allowing drawings to be strung together with multiple idrefs could solve that: <draw id=line-path><!-- ... --></draw> <draw id="area-box-close"> <line-to x="100" y="100" /> <line-to x="0" y="100" /> <end /> </draw> <path draw="line-path" class="line" /> <path draw="line-path area-box-close" class="area" /> Maybe this isn’t such a bad idea after all.
- Abhinav2000 6y agoThere's nothing wrong with xml or other SGML based markups. They are meant to be written by a computer, not by hand.....
- tannhaeuser 6y agoMaybe holds for XML, but not SGML. Its features such as SHORTREF and tag inference for eg parsing Wiki and other custom syntax into canonical angle-bracket markup (aka XML) are pretty much designed to be typed ergonomically and minimalistic, as popular as ever with markdown, etc.
- qwertay 6y agoXML is not an ideal format for computers.
- thangalin 6y ago> If you need to generate basic shapes it's fairly straightforward. You'd think so. While integrating TeX into my editor[0], using JMathTeX[1] as a starting point, I wanted to convert font glyphs to vector paths. At the time, every Java-based SVG renderer (Batik, JFreeSVG, SVG Salamander) suffered from the exact same performance problem: they all used Java's DecimalFormat class to convert floating point numbers to strings. These strings were then concatenated as paths into the output document. Sometimes the strings were re-copied numerous times because of buffer re-allocations and other reasons. (Part 5 of my series[2] on developing a TeX-oriented text editor covers this in depth.) To get great performance---in Java, at least---even for basic shapes requires a sufficiently large, reusable buffer that doesn't incur memory re-allocations and an efficient algorithm to convert floats to strings---such as Ryu[3]. See my implementation that converts glyph paths to vector paths for details[4]. With these two changes I was able to improve upon JFreeSVG's implementation four-fold. [0]: https://github.com/DaveJarvis/keenwrite https://github.com/DaveJarvis/keenwrite (my editor) [1]: https://github.com/DaveJarvis/JMathTeX/ https://github.com/DaveJarvis/JMathTeX/ (my fork) [2]: https://bell-sw.com/announcements/2020/11/02/TeXnical-Writing-Part-1-Foundations/ https://bell-sw.com/announcements/2020/11/02/TeXnical-Writin... (my blog series) [3]: https://github.com/ulfjack/ryu https://github.com/ulfjack/ryu [4]: https://github.com/DaveJarvis/JMathTeX/blob/d2d678717505765be78922774654091ec9295231/src/main/java/com/whitemagicsoftware/tex/graphics/SvgGraphics2D.java#L45 https://github.com/DaveJarvis/JMathTeX/blob/d2d678717505765b...
- hinkley 6y ago> "well fuck it, we'll just jam it all into a string. This is an almost universal disease of people trying to write XML grammars (or database schemas before that). Everyone thinks they can unambiguously decode multiple pieces of data stuffed into the same fixed-width field, and pretty much all of those people are wrong. Over, and over again. That they never learn is a testament to the developer's ability to make fixing their Kruger-Dunning moments Someone Else's Problem. Get promoted or switch teams before the consequences are unavoidable. You can make an argument that even Tim Bray did this. There are a lot of reasons XML was never going to succeed, and this is far from the most important, but it's a substantial contributing factor.
- pwdisswordfish6 6y agoSo one reason for XML failing is that people who nominally used XML didn’t fully use its capabilities to capture data structure and kept their habits from the days of representing all data by fixed-width records?
- hinkley 6y agoXML and Java both come out of the same era. Java was supposed to be Object Oriented, but what we got instead is stringly typed code. Array literals in programming languages are pretty much as compact as you can get (start, end, one character element separator), and the type system or a little code often allows you to fix a 1:1 mistake after the fact. This attribute is now a number or an array of numbers. In XML if you want a properly formatted list you have to use child elements, which gets expensive really quickly so people balk. Especially if you already failed the attribute/child test by mistaking the value for 1:1 when it turned out to be 1:many. We also already have HTML class, style, and on* attributes as prior art that we use to convince ourselves that one more will be okay. Basically XML gets it from both ends. XML makes entity relationships and irreversible decision, in an era where UML existed and harped constantly on it. I don't know if there was any fixing it at that point. What I do know is that a lot of us shot meaningful glances at each other and tried as hard as we could to find something else to do until the dust settled. But you really could not avoid XML in the 00's.
- paul_manias 6y ago> Oh. You can almost hear the designer saying "well fuck it, we'll just jam it all into a string. I'll throw in my 2 cents here because the responses aren't addressing why the path descriptors are stylised in this way. Whether SVG's underlying document format was XML, JSON, SGML, CSS or whatever is irrelevant. However else you did it, any alternative would be more verbose because the 'd' tag already offers the most compact way of describing vector paths in text form. And that's the point - it's small. Even in this compact form, it's not unusual for path strings to reach kilobytes in length when floating point numbers are catered for. Thus we need the path descriptions to be as small as possible for optimal parsing of the file and keeping the file size down. As a side-note I disagree with the author's conjecture that SVG doesn't succeed as a machine-focused language or a human-focused language. I think it serves both sides of the coin quite well in practice (certainly more-so than HTML) and a pared back version already exists in the form of SVG Tiny.
- felixfbecker 6y agoI wonder though why does that matter for a web format that can be served with GZIP encoding? Wouldn't GZIP eat the duplicative <move-to /> tags for breakfast? It would be so much easier to write, read, manipulate and animate.
- paul_manias 6y agoLet's imagine for a moment that path instructions could be mapped out with more verbose instructions. Would this really get enough practical use to be worthy of standardisation? For the most part, SVG path outlines are almost always defined in software like Illustrator and Inkscape. Bezier curves are beyond the average person's ability to create or modify without visual aids. Simple path constructs aren't all that common in practice and the examples I see posted here aren't representative of real-world use. SVG does provide transform capabilities to move, rotate and scale paths easily, and those features can be applied within a text editor. For anything else there are plenty of visual tools to aid path modification. Personally I've modified many an SVG file manually, but when it comes to the paths I can't say that seeing them laid bare would be of a help to my workflow.
- 6y ago
- jansan 6y agoI do not see what is wrong with the path string, which btw. is the same in HTML Canvas. I am using SVG on a daily basis and encountered many issues that annoyed me, but path data was never one of them.
- simias 6y agoI don't think it's wrong per-se, it's actually probably the best solution given the set of constraints. It was more about bashing XML's impracticality than SVG really.
- drewcoo 6y agoThose things are not equivalent. The circle has unordered properties. The path has ordered commands. I suppose those commands could be separated and numbered, but isn't that a lot more verbose and less readable?
- c-smile 6y agoFor the note, Sciter (https://sciter.com https://sciter.com) and Sciter.JS support inline vector images in its CSS. Instead of SVG and things like FontAwesome in 99% UI cases we use just these button { background-image: url(path:M 10 10 H 90 V 90 H 10 L 10 10); fill: red; } or <img src="path:M 10 10 H 90 V 90 H 10 L 10 10">
- ivanceras 6y agoAlso, don't forget the inconsistency of being able to use units like `px`, `ex`, ie: `<circle cx="10ex" cy="10ex" r="2ex" fill="red"/>`, but it would be invalid in `path`. The unit in path is exclusively `px` only.
- m463 6y agoI think it would be nice to have a design language: def port 0,0 100,100: L 10,10 90,0 90,70 70,70 70,90 20,90 20,70 10,70 10,10 def bank 0,0 400,100: port 0,0 100,100 port 100,0 200,100 port 200,0 300,100 port 300,0 400,100 def router 0,0 1100,200: port 50,50 150,150 bank 200,50 600,150 bank 650,50 1050,150 router 0,0 1100,200 I was thinking it would be cool to have an "about" page in openwrt showing your router with all the ports labeled in svg. Should be simple, but I couldn't figure out luci.
- DonHopkins 6y agoThe idea to stuff paths into attribute strings instead of using elements came from Microsoft's VML (one of the competing vector graphics standards that influenced SVG). https://en.wikipedia.org/wiki/Scalable_Vector_Graphics#Development_history https://en.wikipedia.org/wiki/Scalable_Vector_Graphics#Devel... Pragmatically it was a brilliant practical compromise in response to one of XML's horrible flaws as a serialization format (it's way too fluffy), saving enormous amounts of memory and fragmentation by using one string per path, instead of creating thousands of DOM objects with tens of thousands of attributes and text nodes. But you're right, that's the "original sin" of XML that SVG is doomed to suffer with. PDF is basically just the PostScript imaging model without the Turing-complete stack based programming language. SVG is just the latest expression of PostScript graphics model (if you ignore all the stuff about fonts), which is based on the Stencil/Paint imaging model with Porter Duff Compositing, and descendent from Interpress and Jam). The canvas 2d api is pretty much just immediate mode SVG / PostScript graphics, with a few new features added. JSON's a much better format for structured graphics in some ways, but has its own set of flaws and limitation, like not having comments, and being terrible for binary data. But at least JSON arrays are a bit more (but not much) memory efficient than XML elements, and JavaScript itself has typed binary arrays, although standard JSON doesn't support them (using base 64 strings sucks). So representing paths as flat strings like SVG, instead of JSON arrays of numbers, is probably still a win for JSON if you're mainly drawing static paths, but not if you want to read, process or edit those paths a lot. Now, instead of using SVG, it's usually easier and more efficient to just use your own (or some standard) JSON format for structured graphics, and draw it with the canvas api. But there will never be one universal JSON graphics format, just many special purpose ones. For example, d3 has a lot of different JSON formats (domain specific languages) for representing different kinds of graphics and data. More on PostScript and its history: https://news.ycombinator.com/item?id=21968175 https://news.ycombinator.com/item?id=21968175 >Brian Reid wrote about page independence, comparing Interpress' and PostScript's different approaches. Adobe's later voluntary Document Structuring Conventions actually used PostScript comments to make declarations and delimit different parts of the file -- it wasn't actually a part of the PostScript language, while Interpress defined pages as independent so they couldn't possibly affect each other: https://groups.google.com/g/fa.laser-lovers/c/H3us4h8S3Kk https://groups.google.com/g/fa.laser-lovers/c/H3us4h8S3Kk
- zimpenfish 6y ago> <path d="M 10 10 H 90 V 90 H 10 L 10 10"/> And that can be optimised further (by svgo) to: <path d="M10 10h80v80H10V10"/> They can get almost hilariously dense and obfuscated.
- j45 6y agoOddly sometimes.. XML syntax can be a bit more readable than JSON
- Mikhail_Edoshin 6y agoSVG provides elements for things you're going to individually address with XPath or JavaScript. Points are less likely to be manipulated that way, so it's OK to stop using XML to mark up the structure here. Many other data types, such as time, HTTP or email addresses also have structure, but you normally don't explicitly mark it up because they're trivial to parse.