SVG Exporter
In[]:=
BeginPackage["SVG`"];
In[]:=
⌈ Simple SVG primitive support⌋
ToSVG::usage= "Export to an SVG XMLObject"
BeginPackage["SVG`Package`"];
toXML::usage= "Turns svgElement structures into XML";
toEl::usage= "Turns aliases and standard SVG into svgElement data";
register::usage= "Registers a new transformable SVG element";alias::usage= "Registers a new alias for toplevel elements in terms of SVG elements";
CSSGenerate::usage= "Copped from BTools. Just there to support style elements";
prepareSVGGraphics::usage="";getViewBox::usage="";getPlotRange::usage="";getImSize::usage="";getAspRat::usage="";getPlotRangePad::usage="";axesAndFrame::usage="";toSVGCore::usage="";exportGraphics::usage="";canonicalizeDirectives::usage="";splitGraphicsList::usage="";
EndPackage[];
In[]:=
Begin["`Private`"];
⌈CSSGenerate⌋
⌈ Used for styling things⌋
⌈AllowedProperties⌋
⌈AllowedTypes⌋
⌈$CSSPropertyRules⌋
⌈$CSSValueRules⌋
⌈$CSSTypeRules⌋
⌈cssThreadedOptions⌋
⌈cssGenerate⌋
⌈generateCSSString⌋
⌈generateObjectStyles⌋
⌈CSSGenerate⌋
In[]:=
⌈toXML⌋
⌈toNotStupidString⌋
⌈$SVGColorMap⌋
⌈$SVGValMap⌋
⌈ScalingFactors⌋
⌈toSVGString⌋
⌈ This attempts to take an SVG option value and get a proper string representation for it. There is some hacky-ness as handling of things like Dashing[{Small, Small}] must be different from that of Thickness[Large]. Hopefully this can be cleaned sometime.⌋
toSVGString//Clear
toSVGString[Scaled[s_],__]:= toNotStupidString[Floor@100*s]<>"%";toSVGString[RGBColor[r__],h__]:= "#"<>IntegerString[Floor[{r}*255],16,2];toSVGString[h_?ColorQ,__]:= toSVGString[ColorConvert[h,RGBColor],None,None];toSVGString[v_,_,"Style"]:= CSSGenerate[Flatten@{Normal@v}];toSVGString[v_,_,"Thickness"]:= IfStringQ@v, v, toSVGString[Scaled[v],None,None] ;toSVGString[v_,_,"AbsoluteThickness"]:= IfStringQ@v, v, toSVGString[If[NumericQ@v&&v>0,Max@{v,1},v],None,None]<>"pt" ;toSVGString[v_,_,"CapForm"]:= ToLowerCase[v];toSVGString[v_,_,"JoinForm"]:= ToLowerCase[v];toSVGString[l_List,_,"Dashing"]:= StringRiffle@Map[ToString]@ Module vbmin=$svgViewBox[[3]](*Min[$svgViewBox[[3;;]]]*) , MapIndexed Replace$symbDashingFactors[#], m_Missing#, e_e[[Mod[#2[[1]],2,1]]]*vbmin &, l ;toSVGString[(h:Except[List])[x_],_,_]:=(*handlingthingslikeRotate*) ToLowerCase@ToString[h]<>"("<>toSVGString[x,None,None]<>")";toSVGString[a_,head_,_]:= Block $scaling=$symbScalingFactors (*If[head==="stroke-dasharray",$symbDashingFactors,$symbScalingFactors]*), vbmin=$svgViewBox[[3]](*Min[$svgViewBox[[3;;]]]*) , a//.(*abunchofjunktohandlesymbolicsizes*) k:Alternatives@@Keys[$scaling]:> Lookup[$scaling,k]*vbmin //ReplaceAll@ {n_?NumericQ,m_?NumericQ} toNotStupidString[n]<>","<>toNotStupidString[m] , e:_?NumericQtoNotStupidString[e] // Replace@ l_ListStringRiffle[ToString/@l], e_ToString@e
⌈$SVGPropMap⌋
⌈toSVGProp⌋
⌈toXML⌋
toXML//Clear
toXML[svgElement["style",attrs_]]:= XMLElement"style", {}, KeyValueMap #<>" { "<>CSSGenerate[#2]<>" }"&, Association@attrs["Styles"] toXML[svgElement[head_,attrs_]]:= XMLElementhead, DeleteDuplicatesBy[First]@KeyValueMaptoSVGProp, KeyDrop[Association@attrs,"Body"] , Flatten@List@ReplaceAll Lookup[attrs,"Body",{}], s:(Alternatives@@Map[Blank,Prepend[Keys@$svgPrimitives,svgElement]]):> toXML@toEl[s]
In[]:=
⌈toEl⌋
In[]:=
⌈ellipse⌋
⌈style⌋
⌈Aliases⌋
⌈Disk⌋
⌈Circle⌋
⌈Text⌋
⌈ToSVG⌋
⌈prepareSVGGraphics⌋
⌈canonicalizeDirectives⌋