Table of Contents
Reading SVG
(read-svg source) reads one SVG document and returns its drawing. The source is:
- a pathname, naming an SVG file, decoded as UTF-8, with or without a byte order mark, or as US-ASCII or ISO-8859-1 where its XML declaration says so;
- a string of SVG text:
(read-svg "<svg ...>...</svg>"). A string is never a file name; to read a file named by a string, pass(pathname string); - a stream, of characters, read as text, or of octets, decoded as a file is, read from where it stands to its end;
- a vector of octets, decoded as a file is.
(cl-svgread:read-svg #p"icons/save.svg")
(cl-svgread:read-svg "<svg viewBox='0 0 16 16'><circle cx='8' cy='8' r='6'/></svg>")
(with-open-file (stream "art.svg" :element-type '(unsigned-byte 8))
(cl-svgread:read-svg stream))
A string that holds no SVG is taken for the mistake it most likely is:
(cl-svgread:read-svg "art.svg")
;; svg-error: The string given to READ-SVG holds no SVG: it does not start with <.
;; READ-SVG reads a string as SVG text; to read a file of that name, pass a
;; pathname, such as #p"art.svg".
Malformed input signals an svg-error, and a part of SVG that cl-svgread leaves out signals an svg-warning (see Errors and Warnings). A missing file signals a file-error, as open does. Gzipped SVG (.svgz) and UTF-16 files are refused with an error that says so.
What it reads
- Elements:
svg, the document's and nested ones;ganda;path,rect,circle,ellipse,line,polylineandpolygon;defs;use, of any of them and ofsymbolelements, byhreforxlink:href;title,descandmetadata, which draw nothing. Elements of other namespaces, such as an editor's, are skipped quietly. - Path data: all of it, absolute and relative: moves, lines, horizontal and vertical lines, cubic and quadratic curves and their smooth forms, arcs and close path, with commands repeated by giving more numbers, and numbers packed as tightly as the grammar allows.
- Geometry:
x,y,width,height,rxandry, which may beauto,cx,cy,r,x1,y1,x2,y2andpoints;transform, with every transform function;viewBoxandpreserveAspectRatio, with every alignment,meetandslice. - Properties, as presentation attributes and in the
styleattribute, which wins over them, inherited as SVG inherits them, withinherit,initialandunset:fill,fill-opacity,fill-rule,stroke,stroke-width,stroke-opacity,stroke-linecap,stroke-linejoin,stroke-miterlimit,opacity,color,display,visibilityandpaint-order. - Colours: the named colours of SVG and CSS,
transparent,#rgb,#rgba,#rrggbband#rrggbbaa,rgb(),rgba(),hsl()andhsla(), with numbers or percentages, in the comma or the space syntax;currentColorandnone. - Units: plain numbers and
px, andin,cm,mm,Q,ptandpcat 96 px to the inch; percentages of the viewport's width, its height, or its diagonal over the square root of 2, as SVG says for each length. Numbers, whatever their exponent, and lengths in user units, are at most 10^30, and a number below 10^-45 is zero: a length beyond 10^30, as a unit or a percentage of a large viewport may make one, is malformed, and the error says which attribute and the limit. The transform from an element's coordinates to the drawing's is held to the same limit at every step of composing it, from the outermost group in: an element whose transforms take it beyond is left out with ansvg-error, even where a transform further in would scale back down, since a file that scales up past 10^30 and back is absurd enough to refuse. So is what a shape paints, its stroke included: a shape that reaches beyond 10^30 from the drawing's origin is left out with ansvg-error.
What it leaves out
Text, images, gradients and patterns, filters, clip paths, masks, markers, dashes, blend modes, vector effects, CSS transforms, animation, scripts, style sheets, conditional content, and lengths in units relative to a font or a window (em, ex, vw and the like).
Each is left out with an svg-warning that names it, where it would change the drawing. Values that change nothing pass quietly: Inkscape writes stroke-dasharray:none and mix-blend-mode:normal on everything, and cl-svgread says nothing of them. A paint server's fallback colour stands in for it, as in fill="url(#gradient) red", or else nothing is painted. Properties that do nothing to shapes, such as the text properties, are ignored, as are names that are no property, as CSS ignores them.
Two parts of SVG are approximated, with a warning where the difference shows:
- Group opacity. SVG paints a group with opacity, and a shape with both a fill and a stroke, as one layer faded as a whole. cl-svgread multiplies the opacity into each fill and stroke instead, so where they overlap they show darker than SVG draws them, and a shape's fill shows through its stroke. Where nothing overlaps, the result is exact, and
read-svgwarns only where something does. Give the shapes their ownfill-opacityandstroke-opacity, which are exact. - Clipping. Nested
svgelements andsymbols clip to their viewports, which cl-svgread does not do. It warns where their shapes reach outside.
XML
xmls reads the XML. It does not resolve entities defined in a document's DTD, which old Illustrator exports use; such a file fails with an XML error that names the entity. Remove the DTD's entities, or save the file again from an editor that writes none.
Using cl-svgread
Reference