Table of Contents
Errors and Warnings
Errors
Every error cl-svgread signals is an svg-error, whose report says what is wrong and where:
(handler-case (cl-svgread:read-svg "<svg><g id='arrow'><path d='M 0 0 L 4'/></g></svg>")
(cl-svgread:svg-error (error) (princ-to-string error)))
;; => "The d attribute of the <path> in <g id=\"arrow\"> is malformed at
;; character 10: expected a number for L, but the value ends."
An element is named by its id, or by its place among its parent's children of its name, such as the 2nd <path> in <g id="layer">, and by the file's name when a file is read. svg-error-location returns that part alone, and svg-error-message the whole message:
(handler-case (cl-svgread:read-svg "<svg><g id='arrow'><path d='M 0 0 L 4'/></g></svg>")
(cl-svgread:svg-error (error) (cl-svgread:svg-error-location error)))
;; => "the <path> in <g id=\"arrow\">"
XML that xmls cannot read gives the line and column where it stopped, since xmls keeps no line numbers for elements. path-bounds signals one where a transform you give it takes the box beyond what single-floats hold, and cl-svgread/ft2 one for a shape FreeType cannot rasterize (see Rasterizing).
Reading on: the CONTINUE restart
Where SVG's error rules let a reader go on, the error offers a continue restart, whose report says what it does:
- a malformed attribute is left out, as if it were not there;
- path data and
pointsare kept up to the error; - a
useelement that refers to nothing, or to an element that holds it, is left out; - an element whose transforms, with those around it, scale it beyond 10^30 is left out, with what is inside it;
- a shape that reaches beyond 10^30 from the drawing's origin, its stroke included, is left out;
- a shape whose stroke is too wide to draw, as a percentage of a large viewport may make it, is drawn without its stroke.
(handler-bind ((cl-svgread:svg-error #'continue))
(cl-svgread:read-svg "<svg><path d='M 0 0 L 4 0 L 4'/></svg>"))
;; The path keeps its first line: its points are #(0.0 0.0 4.0 0.0).
Reading as leniently as a web browser does is then:
(handler-bind ((cl-svgread:svg-error #'continue)
(cl-svgread:svg-warning #'muffle-warning))
(cl-svgread:read-svg #p"art.svg"))
Input that is not SVG, such as malformed XML or a document whose root is no svg element, offers no restart: continue returns, and the error goes on to the debugger.
Warnings
What cl-svgread leaves out or approximates signals an svg-warning, with svg-warning-message and svg-warning-location, and reading goes on:
(let ((warnings '()))
(handler-bind ((cl-svgread:svg-warning
(lambda (warning)
(push (princ-to-string warning) warnings)
(muffle-warning warning))))
(cl-svgread:read-svg "<svg><text>Hi</text>
<rect width='4' height='4' fill='url(#g)' stroke-dasharray='none'/>
</svg>"))
(reverse warnings))
;; => ("The <text> in <svg> is left out: cl-svgread does not draw text."
;; "The fill attribute of the <rect> in <svg> is \"url(#g)\", a gradient or pattern,
;; which cl-svgread leaves out: the shape is not filled.")
stroke-dasharray='none' changes nothing, so it passes quietly: a warning comes only where the drawing would differ from what SVG draws. Unknown properties and attributes are ignored, as CSS ignores them, and elements of other namespaces are skipped without a word; unknown SVG elements warn.
Muffle the warnings with muffle-warning, as above, or collect them to show the user which parts of a file did not come through.
Using cl-svgread
Reference