svg-builder (empty) → 0.1
raw patch · 9 files changed
+1521/−0 lines, 9 filesdep +basedep +blaze-builderdep +bytestringsetup-changed
Dependencies added: base, blaze-builder, bytestring, hashable, text, unordered-containers
Files
- LICENSE +30/−0
- README.md +64/−0
- Setup.hs +2/−0
- src/Graphics/Svg.hs +151/−0
- src/Graphics/Svg/Attributes.hs +577/−0
- src/Graphics/Svg/Core.hs +170/−0
- src/Graphics/Svg/Elements.hs +351/−0
- src/Graphics/Svg/Path.hs +146/−0
- svg-builder.cabal +30/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2016, Jeffrey Rosenbluth++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Jeffrey Rosenbluth nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,64 @@+svg-builder [](https://hackage.haskell.org/package/svg-builder)+=========+Simple DSL for writing fast SVG.++## Example++``` haskell+{-# LANGUAGE OverloadedStrings #-}++import Graphics.Svg++svg :: Element -> Element+svg content =+ doctype+ <> with (svg11_ content) [Version_ <<- "1.1", Width_ <<- "300", Height_ <<- "200"]++contents :: Element+contents =+ rect_ [ Width_ <<- "100%", Height_ <<- "100%", "red" ->> Fill_]+ <> circle_ [ Cx_ <<- "150", Cy_ <<- "100", R_ <<- "80", Fill_ <<- "green"]+ <> text_ [ X_ <<- "150", Y_ <<- "125", Font_size_ <<- "60"+ , Text_anchor_ <<- "middle", Fill_ <<- "white"] "SVG"++main :: IO ()+main = do+ print $ svg contents+```++++## Haskell logo++``` haskell+{-# LANGUAGE OverloadedStrings #-}++import Graphics.Svg++svg :: Element -> Element+svg content =+ doctype+ <> with (svg11_ content) [Version_ <<- "1.1", Width_ <<- "482", Height_ <<- "340"]++logo :: Element+logo =+ path_ [ Fill_ <<- "#352950"+ , D_ <<- ( mA 0 340 <> lA 113 170 <> lA 0 0 <> lA 85 0+ <> lA 198 170 <> lA 85 340 <> lA 0 340 <> z <> mA 0 340 ) ]+ <> path_ [ Fill_ <<- "#4A3A74"+ , D_ <<- ( mA 113 340 <> lA 226 170 <> lA 113 0 <> lA 198 0+ <> lA 425 340 <> lA 340 340 <> lA 269 234 <> lA 198 340+ <> lA 113 340 <> z <> mA 113 340 ) ]+ <> path_ [ Fill_ <<- "#7C3679"+ , D_ <<- ( mA 387 241 <> lA 350 184 <> lA 482 184 <> lA 482 241+ <> lA 387 241 <> z <> mA 387 241 ) ]+ <> path_ [ Fill_ <<- "#7C3679"+ , D_ <<- ( mA 331 156 <> lA 293 99 <> lA 482 99 <> lA 482 156+ <> lA 331 156 <> z <> mA 331 156 ) ]++main :: IO ()+main = do+ print $ svg logo+``` ++
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Graphics/Svg.hs view
@@ -0,0 +1,151 @@+{-# LANGUAGE OverloadedStrings #-}++{-# OPTIONS -fno-warn-unused-imports #-}++-------------------------------------------------------------------------------+-- |+-- Module : Graphics.Svg+-- Copyright : (c) 2015 Jeffrey Rosenbluth+-- License : BSD-style (see LICENSE)+-- Maintainer : jeffrey.rosenbluth@gmail.com+--+-- DSL for creating SVG.+--+-------------------------------------------------------------------------------+module Graphics.Svg+ ( -- * Intro+ -- $intro+ -- * Re-exports+ module Graphics.Svg.Core+ , module Graphics.Svg.Path+ , module Graphics.Svg.Elements+ , module Graphics.Svg.Attributes+ , (<>)+ -- * Rendering+ , prettyText+ ) where++import Data.Functor.Identity+import Data.Int (Int64)+import Data.Monoid+import Data.Text.Lazy as LT+import Data.Text.Lazy.Builder as B+import Graphics.Svg.Core+import Graphics.Svg.Attributes+import Graphics.Svg.Elements+import Graphics.Svg.Path++prettyText :: Element -> Text+prettyText svg = B.toLazyText $ LT.foldr go mempty text Nothing (-1)+ where+ text = renderText svg+ go c f Nothing n+ | c == '<' || c == '/' = f (Just c) n+ go c f (Just '<') n+ | c == '?' = "<?" <> f Nothing n+ | c == '!' = "<!" <> f Nothing n+ | c == '/' = "\n"+ <> (B.fromLazyText $ LT.replicate n " " )+ <> "</"+ <> f Nothing (n-1)+ | otherwise = "\n"+ <> (B.fromLazyText $ LT.replicate (n+1) " " )+ <> "<"+ <> B.singleton c+ <> f Nothing (n+1)+ go '>' f (Just _) n = "/>" <> f Nothing (n-1)+ go c f s n = s' <> B.singleton c <> f Nothing n+ where s' = maybe mempty B.singleton s++-- $intro+--+-- SVG elements in Graphics-Svg are written with a postfix ‘@_@’.+-- Some examples:+--+-- 'path_', 'circle_', 'color_', 'scale_'+--+-- Plain text is written using the @OverloadedStrings@+-- extension, and is automatically escaped:+--+-- As in Graphics, elements nest by function application (unlike Graphics, there+-- is no Monad instance for 'Element's and an 'Attribute' list is always required):+--+-- >>> g_ [] (text_ [] "Hello SVG")+-- <g><text>Hello SVG</text></g>+--+-- and elements are juxtaposed via monoidal append:+--+-- >>> text_ [] "Hello" <> text_ [] "SVG"+-- <text>Hello</text><text>SVG</text>+--+-- Attributes are set by providing an argument list. Each argument is set+-- using the 'bindAttr' function or operators, '<<-' and '->>'.+--+-- >>> rect_ [Width_ <<- "100%", Height_ <<- "100%", "red" ->> Fill_]+-- <rect height="100%" width="100%" fill="red"></rect>+--+-- Path data can be constructed using the functions in 'Graphics.Svg.Path'+-- and combined monoidally:+--+-- @+-- path_+-- [ D_ <<- (mA 10 80 <> qA 52.5 10 95 80 <> tA 180 80 <> z)+-- , Stroke_ <<- "blue"+-- , Fill_ <<- "orange"+-- ]+-- @+-- > <path d="M 10,80 Q 52.5,10 95,80 T 180,80 Z" stroke="blue" fill="orange"/>+--+-- __A slightly longer example__+--+-- > import Graphics.Svg+-- >+-- > svg :: Element -> Element+-- > svg content =+-- > doctype+-- > <> with (svg11_ content) [Version_ <<- "1.1", Width_ <<- "300" , Height_ <<- "200"]+-- >+-- > contents :: Element+-- > contents =+-- > rect_ [Width_ <<- "100%", Height_ <<- "100%", Fill_ <<- "red"]+-- > <> circle_ [Cx_ <<- "150", Cy_ <<- "100", R_ <<- "80", Fill_ <<- "green"]+-- > <> text_ [ X_ <<- "150", Y_ <<- "125", FontSize_ <<- "60"+-- > , TextAnchor_ <<- "middle", Fill_ <<- "white" ] "SVG"+-- >+-- >+-- > main :: IO ()+-- > main = do+-- > print $ svg contents+-- <<http://i.imgur.com/dXu84xR.png>>+--+-- __The haskell logo__+--+-- > {-# LANGUAGE OverloadedStrings #-}+-- >+-- > import Graphics.Svg+-- >+-- > svg :: Element -> Element+-- > svg content =+-- > doctype+-- > <> with (svg11_ content) [Version_ <<- "1.1", Width_ <<- "482", Height_ <<- "340"]+-- >+-- > logo :: Element+-- > logo =+-- > path_ [ Fill_ <<- "#352950"+-- > , D_ <<- ( mA 0 340 <> lA 113 170 <> lA 0 0 <> lA 85 0+-- > <> lA 198 170 <> lA 85 340 <> lA 0 340 <> z <> mA 0 340 ) ]+-- > <> path_ [ Fill_ <<- "#4A3A74"+-- > , D_ <<- ( mA 113 340 <> lA 226 170 <> lA 113 0 <> lA 198 0+-- > <> lA 425 340 <> lA 340 340 <> lA 269 234 <> lA 198 340+-- > <> lA 113 340 <> z <> mA 113 340 ) ]+-- > <> path_ [ Fill_ <<- "#7C3679"+-- > , D_ <<- ( mA 387 241 <> lA 350 184 <> lA 482 184 <> lA 482 241+-- > <> lA 387 241 <> z <> mA 387 241 ) ]+-- > <> path_ [ Fill_ <<- "#7C3679"+-- > , D_ <<- ( mA 331 156 <> lA 293 99 <> lA 482 99 <> lA 482 156+-- > <> lA 331 156 <> z <> mA 331 156 ) ]+-- >+-- > main :: IO ()+-- > main = do+-- > print $ svg logo+-- <<http://i.imgur.com/tuFExZl.png>>
+ src/Graphics/Svg/Attributes.hs view
@@ -0,0 +1,577 @@+{-# LANGUAGE OverloadedStrings #-}++-------------------------------------------------------------------------------+-- |+-- Module : Graphics.Svg.Attributes+-- Copyright : (c) 2015 Jeffrey Rosenbluth+-- License : BSD-style (see LICENSE)+-- Maintainer : jeffrey.rosenbluth@gmail.com+--+-- SVG Attributes.+--+-------------------------------------------------------------------------------++module Graphics.Svg.Attributes+ ( (<<-)+ , (->>)+ , bindAttr+ , AttrTag(..)+ ) where++import Graphics.Svg.Core+import Data.Text (Text)++-- | Make an 'Attribute' from it's value constructor and it's text value.+-- by combining an 'AttrTag' with it's value.+--+-- > [bindAttr Width "100%, bindAttr Height "100%", bindAttr Fill "red"]+bindAttr :: AttrTag -> Text -> Attribute+bindAttr t v = makeAttribute (tag2text t) v++-- | Infix version of 'bindAttr'+-- Each argument is set using '<<-', the 'bindAttr' function or '->>'.+--+-- > [Width_ <<- "100%", Height_ <<- "100%", Fill_ <<- "red"]+infix 4 <<-+(<<-) :: AttrTag -> Text -> Attribute+(<<-) = bindAttr++-- | Infix version of 'bindAttr' with it's arguments reversed.+--+-- > ["100%" ->> Width_, "100%" ->> Height_, "red" ->> Fill_]+infix 4 ->>+(->>) :: Text -> AttrTag -> Attribute+(->>) = flip bindAttr++data AttrTag+ = Accent_height_+ | Accumulate_+ | Additive_+ | Alignment_baseline_+ | Alphabetic_+ | Amplitude_+ | Arabic_form_+ | Ascent_+ | AttributeName_+ | AttributeType_+ | Azimuth_+ | BaseFrequency_+ | Baseprofile_+ | Baseline_shift_+ | Bbox_+ | Begin_+ | Bias_+ | By_+ | CalcMode_+ | Cap_height_+ | Class_+ | Clip_+ | Clip_path_+ | Clip_rule_+ | ClipPathUnits_+ | Color_+ | Color_interpolation_+ | Color_interpolation_filters_+ | Color_profile_+ | Color_rendering_+ | ContentScriptType_+ | ContentStyleType_+ | Cursor_+ | Cx_+ | Cy_+ | D_+ | Descent_+ | DiffuseConstant_+ | Direction_+ | Display_+ | Divisor_+ | Dominant_baseline_+ | Dur_+ | Dx_+ | Dy_+ | EdgeMode_+ | Elevation_+ | Enable_background_+ | End_+ | Exponent_+ | ExternalResourcesRequired_+ | Fill_+ | Fill_opacity_+ | Fill_rule_+ | Filter_+ | FilterRes_+ | FilterUnits_+ | Flood_color_+ | Flood_opacity_+ | Font_family_+ | Font_size_+ | Font_size_adjust_+ | Font_stretch_+ | Font_style_+ | Font_variant_+ | Font_weight_+ | Format_+ | From_+ | Fx_+ | Fy_+ | G1_+ | G2_+ | Glyph_name_+ | Glyph_orientation_horizontal_+ | Glyph_orientation_vertical_+ | GradientTransform_+ | GradientUnits_+ | Hanging_+ | Height_+ | Horiz_adv_x_+ | Horiz_origin_x_+ | Horiz_origin_y_+ | Id_+ | Ideographic_+ | Image_rendering_+ | In_+ | In2_+ | Intercept_+ | K_+ | K1_+ | K2_+ | K3_+ | K4_+ | KernelMatrix_+ | KernelUnitLength_+ | Kerning_+ | KeyPoints_+ | KeySplines_+ | KeyTimes_+ | Lang_+ | LengthAdjust_+ | Letter_spacing_+ | Lighting_color_+ | LimitingConeAngle_+ | Local_+ | Marker_end_+ | Marker_mid_+ | Marker_start_+ | MarkerHeight_+ | MarkerUnits_+ | MarkerWidth_+ | MaskContentUnits_+ | MaskUnits_+ | Mathematical_+ | Max_+ | Media_+ | Method_+ | Min_+ | Mode_+ | Name_+ | NumOctaves_+ | Offset_+ | Onabort_+ | Onactivate_+ | Onbegin_+ | Onclick_+ | Onend_+ | Onerror_+ | Onfocusin_+ | Onfocusout_+ | Onload_+ | Onmousedown_+ | Onmousemove_+ | Onmouseout_+ | Onmouseover_+ | Onmouseup_+ | Onrepeat_+ | Onresize_+ | Onscroll_+ | Onunload_+ | Onzoom_+ | Opacity_+ | Operator_+ | Order_+ | Orient_+ | Orientation_+ | Origin_+ | Overflow_+ | Overline_position_+ | Overline_thickness_+ | Panose_1_+ | Paint_order_+ | Path_+ | PathLength_+ | PatternContentUnits_+ | PatternTransform_+ | PatternUnits_+ | Pointer_events_+ | Points_+ | PointsAtX_+ | PointsAtY_+ | PointsAtZ_+ | PreserveAlpha_+ | PreserveAspectRatio_+ | PrimitiveUnits_+ | R_+ | Radius_+ | RefX_+ | RefY_+ | Rendering_intent_+ | RepeatCount_+ | RepeatDur_+ | RequiredExtensions_+ | RequiredFeatures_+ | Restart_+ | Result_+ | Rotate_+ | Rx_+ | Ry_+ | Scale_+ | Seed_+ | Shape_rendering_+ | Slope_+ | Spacing_+ | SpecularConstant_+ | SpecularExponent_+ | SpreadMethod_+ | StartOffset_+ | StdDeviation_+ | Stemh_+ | Stemv_+ | StitchTiles_+ | Stop_color_+ | Stop_opacity_+ | Strikethrough_position_+ | Strikethrough_thickness_+ | String_+ | Stroke_+ | Stroke_dasharray_+ | Stroke_dashoffset_+ | Stroke_linecap_+ | Stroke_linejoin_+ | Stroke_miterlimit_+ | Stroke_opacity_+ | Stroke_width_+ | Style_+ | SurfaceScale_+ | SystemLanguage_+ | TableValues_+ | Target_+ | TargetX_+ | TargetY_+ | Text_anchor_+ | Text_decoration_+ | Text_rendering_+ | TextLength_+ | To_+ | Transform_+ | Type_+ | U1_+ | U2_+ | Underline_position_+ | Underline_thickness_+ | Unicode_+ | Unicode_bidi_+ | Unicode_range_+ | Units_per_em_+ | V_alphabetic_+ | V_hanging_+ | V_ideographic_+ | V_mathematical_+ | Values_+ | Version_+ | Vert_adv_y_+ | Vert_origin_x_+ | Vert_origin_y_+ | ViewBox_+ | ViewTarget_+ | Visibility_+ | Width_+ | Widths_+ | Word_spacing_+ | Writing_mode_+ | X_+ | X_height_+ | X1_+ | X2_+ | XChannelSelector_+ | XlinkActuate_+ | XlinkArcrole_+ | XlinkHref_+ | XlinkRole_+ | XlinkShow_+ | XlinkTitle_+ | XlinkType_+ | XmlBase_+ | XmlLang_+ | XmlSpace_+ | Y_+ | Y1_+ | Y2_+ | YChannelselector_+ | Z_+ | ZoomAndPan_++-- Link the tags to their svg strings.+tag2text :: AttrTag -> Text+tag2text Accent_height_ = "accent-height"+tag2text Accumulate_ = "accumulate"+tag2text Additive_ = "additive"+tag2text Alignment_baseline_ = "alignment-baseline"+tag2text Alphabetic_ = "alphabetic"+tag2text Amplitude_ = "amplitude"+tag2text Arabic_form_ = "arabic-form"+tag2text Ascent_ = "ascent"+tag2text AttributeName_ = "attributeName"+tag2text AttributeType_ = "attributeType"+tag2text Azimuth_ = "azimuth"+tag2text BaseFrequency_ = "baseFrequency"+tag2text Baseprofile_ = "baseprofile"+tag2text Baseline_shift_ = "baseline-shift"+tag2text Bbox_ = "bbox"+tag2text Begin_ = "begin"+tag2text Bias_ = "bias"+tag2text By_ = "by"+tag2text CalcMode_ = "calcMode"+tag2text Cap_height_ = "cap-height"+tag2text Class_ = "class"+tag2text Clip_ = "clip"+tag2text Clip_path_ = "clip-path"+tag2text Clip_rule_ = "clip-rule"+tag2text ClipPathUnits_ = "clipPathUnits"+tag2text Color_ = "color"+tag2text Color_interpolation_ = "color-interpolation"+tag2text Color_interpolation_filters_ = "color-interpolation-filters"+tag2text Color_profile_ = "color-profile"+tag2text Color_rendering_ = "color-rendering"+tag2text ContentScriptType_ = "contentScriptType"+tag2text ContentStyleType_ = "contentStyleType"+tag2text Cursor_ = "cursor"+tag2text Cx_ = "cx"+tag2text Cy_ = "cy"+tag2text D_ = "d"+tag2text Descent_ = "descent"+tag2text DiffuseConstant_ = "diffuseConstant"+tag2text Direction_ = "direction"+tag2text Display_ = "display"+tag2text Divisor_ = "divisor"+tag2text Dominant_baseline_ = "dominant-baseline"+tag2text Dur_ = "dur"+tag2text Dx_ = "dx"+tag2text Dy_ = "dy"+tag2text EdgeMode_ = "edgeMode"+tag2text Elevation_ = "elevation"+tag2text Enable_background_ = "enable-background"+tag2text End_ = "end"+tag2text Exponent_ = "exponent"+tag2text ExternalResourcesRequired_ = "externalResourcesRequired"+tag2text Fill_ = "fill"+tag2text Fill_opacity_ = "fill-opacity"+tag2text Fill_rule_ = "fill-rule"+tag2text Filter_ = "filter"+tag2text FilterRes_ = "filterRes"+tag2text FilterUnits_ = "filterUnits"+tag2text Flood_color_ = "flood-color"+tag2text Flood_opacity_ = "flood-opacity"+tag2text Font_family_ = "font-family"+tag2text Font_size_ = "font-size"+tag2text Font_size_adjust_ = "font-size-adjust"+tag2text Font_stretch_ = "font-stretch"+tag2text Font_style_ = "font-style"+tag2text Font_variant_ = "font-variant"+tag2text Font_weight_ = "font-weight"+tag2text Format_ = "format"+tag2text From_ = "from"+tag2text Fx_ = "fx"+tag2text Fy_ = "fy"+tag2text G1_ = "g1"+tag2text G2_ = "g2"+tag2text Glyph_name_ = "glyph-name"+tag2text Glyph_orientation_horizontal_ = "glyph-orientation-horizontal"+tag2text Glyph_orientation_vertical_ = "glyph-orientation-vertical"+tag2text GradientTransform_ = "gradientTransform"+tag2text GradientUnits_ = "gradientUnits"+tag2text Hanging_ = "hanging"+tag2text Height_ = "height"+tag2text Horiz_adv_x_ = "horiz-adv-x"+tag2text Horiz_origin_x_ = "horiz-origin-x"+tag2text Horiz_origin_y_ = "horiz-origin-y"+tag2text Id_ = "id"+tag2text Ideographic_ = "ideographic"+tag2text Image_rendering_ = "image-rendering"+tag2text In_ = "in"+tag2text In2_ = "in2"+tag2text Intercept_ = "intercept"+tag2text K_ = "k"+tag2text K1_ = "k1"+tag2text K2_ = "k2"+tag2text K3_ = "k3"+tag2text K4_ = "k4"+tag2text KernelMatrix_ = "kernelMatrix"+tag2text KernelUnitLength_ = "kernelUnitLength"+tag2text Kerning_ = "kerning"+tag2text KeyPoints_ = "keyPoints"+tag2text KeySplines_ = "keySplines"+tag2text KeyTimes_ = "keyTimes"+tag2text Lang_ = "lang"+tag2text LengthAdjust_ = "lengthAdjust"+tag2text Letter_spacing_ = "letter-spacing"+tag2text Lighting_color_ = "lighting-color"+tag2text LimitingConeAngle_ = "limitingConeAngle"+tag2text Local_ = "local"+tag2text Marker_end_ = "marker-end"+tag2text Marker_mid_ = "marker-mid"+tag2text Marker_start_ = "marker-start"+tag2text MarkerHeight_ = "markerHeight"+tag2text MarkerUnits_ = "markerUnits"+tag2text MarkerWidth_ = "markerWidth"+tag2text MaskContentUnits_ = "maskContentUnits"+tag2text MaskUnits_ = "maskUnits"+tag2text Mathematical_ = "mathematical"+tag2text Max_ = "max"+tag2text Media_ = "media"+tag2text Method_ = "method"+tag2text Min_ = "min"+tag2text Mode_ = "mode"+tag2text Name_ = "name"+tag2text NumOctaves_ = "numOctaves"+tag2text Offset_ = "offset"+tag2text Onabort_ = "onabort"+tag2text Onactivate_ = "onactivate"+tag2text Onbegin_ = "onbegin"+tag2text Onclick_ = "onclick"+tag2text Onend_ = "onend"+tag2text Onerror_ = "onerror"+tag2text Onfocusin_ = "onfocusin"+tag2text Onfocusout_ = "onfocusout"+tag2text Onload_ = "onload"+tag2text Onmousedown_ = "onmousedown"+tag2text Onmousemove_ = "onmousemove"+tag2text Onmouseout_ = "onmouseout"+tag2text Onmouseover_ = "onmouseover"+tag2text Onmouseup_ = "onmouseup"+tag2text Onrepeat_ = "onrepeat"+tag2text Onresize_ = "onresize"+tag2text Onscroll_ = "onscroll"+tag2text Onunload_ = "onunload"+tag2text Onzoom_ = "onzoom"+tag2text Opacity_ = "opacity"+tag2text Operator_ = "operator"+tag2text Order_ = "order"+tag2text Orient_ = "orient"+tag2text Orientation_ = "orientation"+tag2text Origin_ = "origin"+tag2text Overflow_ = "overflow"+tag2text Overline_position_ = "overline-position"+tag2text Overline_thickness_ = "overline-thickness"+tag2text Panose_1_ = "panose-1"+tag2text Paint_order_ = "paint-order"+tag2text Path_ = "path"+tag2text PathLength_ = "pathLength"+tag2text PatternContentUnits_ = "patternContentUnits"+tag2text PatternTransform_ = "patternTransform"+tag2text PatternUnits_ = "patternUnits"+tag2text Pointer_events_ = "pointer-events"+tag2text Points_ = "points"+tag2text PointsAtX_ = "pointsAtX"+tag2text PointsAtY_ = "pointsAtY"+tag2text PointsAtZ_ = "pointsAtZ"+tag2text PreserveAlpha_ = "preserveAlpha"+tag2text PreserveAspectRatio_ = "preserveAspectRatio"+tag2text PrimitiveUnits_ = "primitiveUnits"+tag2text R_ = "r"+tag2text Radius_ = "radius"+tag2text RefX_ = "refX"+tag2text RefY_ = "refY"+tag2text Rendering_intent_ = "rendering-intent"+tag2text RepeatCount_ = "repeatCount"+tag2text RepeatDur_ = "repeatDur"+tag2text RequiredExtensions_ = "requiredExtensions"+tag2text RequiredFeatures_ = "requiredFeatures"+tag2text Restart_ = "restart"+tag2text Result_ = "result"+tag2text Rotate_ = "rotate"+tag2text Rx_ = "rx"+tag2text Ry_ = "ry"+tag2text Scale_ = "scale"+tag2text Seed_ = "seed"+tag2text Shape_rendering_ = "shape-rendering"+tag2text Slope_ = "slope"+tag2text Spacing_ = "spacing"+tag2text SpecularConstant_ = "specularConstant"+tag2text SpecularExponent_ = "specularExponent"+tag2text SpreadMethod_ = "spreadMethod"+tag2text StartOffset_ = "startOffset"+tag2text StdDeviation_ = "stdDeviation"+tag2text Stemh_ = "stemh"+tag2text Stemv_ = "stemv"+tag2text StitchTiles_ = "stitchTiles"+tag2text Stop_color_ = "stop-color"+tag2text Stop_opacity_ = "stop-opacity"+tag2text Strikethrough_position_ = "strikethrough-position"+tag2text Strikethrough_thickness_ = "strikethrough-thickness"+tag2text String_ = "string"+tag2text Stroke_ = "stroke"+tag2text Stroke_dasharray_ = "stroke-dasharray"+tag2text Stroke_dashoffset_ = "stroke-dashoffset"+tag2text Stroke_linecap_ = "stroke-linecap"+tag2text Stroke_linejoin_ = "stroke-linejoin"+tag2text Stroke_miterlimit_ = "stroke-miterlimit"+tag2text Stroke_opacity_ = "stroke-opacity"+tag2text Stroke_width_ = "stroke-width"+tag2text Style_ = "style"+tag2text SurfaceScale_ = "surfaceScale"+tag2text SystemLanguage_ = "systemLanguage"+tag2text TableValues_ = "tableValues"+tag2text Target_ = "target"+tag2text TargetX_ = "targetX"+tag2text TargetY_ = "targetY"+tag2text Text_anchor_ = "text-anchor"+tag2text Text_decoration_ = "text-decoration"+tag2text Text_rendering_ = "text-rendering"+tag2text TextLength_ = "textLength"+tag2text To_ = "to"+tag2text Transform_ = "transform"+tag2text Type_ = "type"+tag2text U1_ = "u1"+tag2text U2_ = "u2"+tag2text Underline_position_ = "underline-position"+tag2text Underline_thickness_ = "underline-thickness"+tag2text Unicode_ = "unicode"+tag2text Unicode_bidi_ = "unicode-bidi"+tag2text Unicode_range_ = "unicode-range"+tag2text Units_per_em_ = "units-per-em"+tag2text V_alphabetic_ = "v-alphabetic"+tag2text V_hanging_ = "v-hanging"+tag2text V_ideographic_ = "v-ideographic"+tag2text V_mathematical_ = "v-mathematical"+tag2text Values_ = "values"+tag2text Version_ = "version"+tag2text Vert_adv_y_ = "vert-adv-y"+tag2text Vert_origin_x_ = "vert-origin-x"+tag2text Vert_origin_y_ = "vert-origin-y"+tag2text ViewBox_ = "viewBox"+tag2text ViewTarget_ = "viewTarget"+tag2text Visibility_ = "visibility"+tag2text Width_ = "width"+tag2text Widths_ = "widths"+tag2text Word_spacing_ = "word-spacing"+tag2text Writing_mode_ = "writing-mode"+tag2text X_ = "x"+tag2text X_height_ = "x-height"+tag2text X1_ = "x1"+tag2text X2_ = "x2"+tag2text XChannelSelector_ = "xChannelSelector"+tag2text XlinkActuate_ = "xlink:actuate"+tag2text XlinkArcrole_ = "xlink:arcrole"+tag2text XlinkHref_ = "xlink:href"+tag2text XlinkRole_ = "xlink:role"+tag2text XlinkShow_ = "xlink:show"+tag2text XlinkTitle_ = "xlink:title"+tag2text XlinkType_ = "xlink:type"+tag2text XmlBase_ = "xml:base"+tag2text XmlLang_ = "xml:lang"+tag2text XmlSpace_ = "xml:space"+tag2text Y_ = "y"+tag2text Y1_ = "y1"+tag2text Y2_ = "y2"+tag2text YChannelselector_ = "yChannelSelector"+tag2text Z_ = "z"+tag2text ZoomAndPan_ = "zoomAndPan"
+ src/Graphics/Svg/Core.hs view
@@ -0,0 +1,170 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeFamilies #-}++-------------------------------------------------------------------------------+-- |+-- Module : SVG.Core+-- Copyright : (c) 2015 Jeffrey Rosenbluth+-- License : BSD-style (see LICENSE)+-- Maintainer : jeffrey.rosenbluth@gmail.com+--+-- svg-builder Core types and functions.+--+-------------------------------------------------------------------------------++module Graphics.Svg.Core+( -- * Types+ Attribute+, Element+, ToElement(..)+, Term(..)+ -- * Combinators+, makeAttribute+, makeElement+, makeElementNoEnd+, makeElementDoctype+, with+ -- * Rendering+, renderBS+, renderToFile+, renderText+) where++import Blaze.ByteString.Builder (Builder)+import qualified Blaze.ByteString.Builder as BB+import qualified Blaze.ByteString.Builder.Html.Utf8 as BB+import qualified Data.ByteString.Lazy as LB+import Data.ByteString.Lazy (ByteString)+import Data.Hashable (Hashable(..))+import Data.HashMap.Strict (HashMap)+import qualified Data.HashMap.Strict as M+import Data.Monoid+import Data.String+import Data.Text (Text)+import qualified Data.Text.Lazy as LT+import qualified Data.Text.Lazy.Encoding as LT++--------------------------------------------------------------------------------+-- Types++-- | Attribute name value.+data Attribute = Attribute !Text !Text+ deriving (Show,Eq)++instance Hashable Attribute where+ hashWithSalt salt (Attribute a b) = salt `hashWithSalt` a `hashWithSalt` b++-- | Type of an SVG element.+newtype Element = Element (HashMap Text Text -> Builder)++instance Show Element where+ show e = LT.unpack . renderText $ e++instance Monoid Element where+ mempty = Element mempty+ mappend (Element e1) (Element e2) = Element (e1 <> e2)++instance IsString Element where+ fromString = toElement++-- | Things that can be converted to SVG elements.+class ToElement a where+ toElement :: a -> Element++instance ToElement String where+ toElement = Element . const . BB.fromHtmlEscapedString++instance ToElement Text where+ toElement = Element . const . BB.fromHtmlEscapedText++instance ToElement LT.Text where+ toElement = Element . const . BB.fromHtmlEscapedLazyText++-- | Used to make specific SVG element builders.+class Term result where+ -- | Used for constructing elements e.g. @term "circle"@ yields 'circle_'.+ term :: Text -> [Attribute] -> result++instance (e ~ Element) => Term (e -> Element) where+ term name attrs e = with (makeElement name e) attrs++instance Term Element where+ term name attrs = with (makeElementNoEnd name) attrs++--------------------------------------------------------------------------------+-- Combinators++-- | Make an attribute.+makeAttribute :: Text -- ^ Attribute name.+ -> Text -- ^ Attribute value.+ -> Attribute+makeAttribute = Attribute++-- | Union two sets of attributes and append duplicate keys.+unionAttrs :: HashMap Text Text -> HashMap Text Text -> HashMap Text Text+unionAttrs = M.unionWith (<>)++-- | Add a list of attributes to an element+with :: Element -> [Attribute] -> Element+with (Element e) attrs = Element $ \a ->+ e (unionAttrs (M.fromListWith (<>) (map toPair attrs)) a)+ where+ toPair (Attribute x y) = (x,y)++-- | Make an SVG element builder+makeElement :: Text -> Element -> Element+makeElement name (Element c) = Element $ \a -> go c a+ where+ go children attrs =+ s2b "<" <> BB.fromText name+ <> foldlMapWithKey buildAttr attrs <> s2b ">"+ <> children mempty+ <> s2b "</" <> BB.fromText name <> s2b ">"++-- | Make an SVG doctype element builder.+makeElementDoctype :: Text -> Element+makeElementDoctype name = Element $ \a -> go a+ where+ go attrs =+ s2b "<" <> BB.fromText name+ <> foldlMapWithKey buildAttr attrs <> s2b ">"++-- | Make an SVG element with no end tag, contains only attributes.+makeElementNoEnd :: Text -> Element+makeElementNoEnd name = Element $ \a -> go a+ where+ go attrs =+ s2b "<" <> BB.fromText name+ <> foldlMapWithKey buildAttr attrs <> s2b "/>"++-- | Folding and monoidally appending attributes.+foldlMapWithKey :: Monoid m => (k -> v -> m) -> HashMap k v -> m+foldlMapWithKey f = M.foldlWithKey' (\m k v -> m <> f k v) mempty++s2b :: String -> Builder+s2b = BB.fromString++-- | Build and encode an attribute.+buildAttr :: Text -> Text -> Builder+buildAttr key val =+ s2b " " <>+ BB.fromText key <>+ if val == mempty+ then mempty+ else s2b "=\"" <> BB.fromHtmlEscapedText val <> s2b "\""++--------------------------------------------------------------------------------+-- Rendering++-- | Render a 'Element' to lazy bytestring.+renderBS :: Element -> ByteString+renderBS (Element e) = BB.toLazyByteString $ e mempty++-- | Render a 'Element' to a file.+renderToFile :: FilePath -> Element -> IO ()+renderToFile fp = LB.writeFile fp . renderBS++-- | Reder an 'Element' to lazy text.+renderText :: Element -> LT.Text+renderText = LT.decodeUtf8 . renderBS
+ src/Graphics/Svg/Elements.hs view
@@ -0,0 +1,351 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE FlexibleContexts #-}++-------------------------------------------------------------------------------+-- |+-- Module : Graphics.Svg.Elements+-- Copyright : (c) 2015 Jeffrey Rosenbluth+-- License : BSD-style (see LICENSE)+-- Maintainer : jeffrey.rosenbluth@gmail.com+--+-- SVG elements.+--+-------------------------------------------------------------------------------++module Graphics.Svg.Elements where++import Graphics.Svg.Core++-- | @DOCTYPE@ element+doctype :: Element+doctype = makeElementDoctype "?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\""++-- | @svg@ element + svg 1.1 Attribute+svg11_:: Element -> Element+svg11_ = svg_ [ makeAttribute "xmlns" "http://www.w3.org/2000/svg"+ , makeAttribute "xmlns:xlink" "http://www.w3.org/1999/xlink"+ , makeAttribute "version" "1.1" ]++-- | @a@ element+a_ :: Term result => [Attribute] -> result+a_ = term "a"++-- | @altglyph@ element+{-# DEPRECATED altGlyph_ "Removed from web standards." #-}+altGlyph_ :: Term result => [Attribute] -> result+altGlyph_ = term "altGlyph"++-- | @altglyphdef@ element+{-# DEPRECATED altGlyphDef_ "Removed from web standards." #-}+altGlyphDef_ :: Term result => [Attribute] -> result+altGlyphDef_ = term "altGlyphDef"++-- | @altglyphitem@ element+{-# DEPRECATED altGlyphItem_ "Removed from web standards." #-}+altGlyphItem_ :: Term result => [Attribute] -> result+altGlyphItem_ = term "altGlyphItem"++-- | @animate@ element+animate_ :: Term result => [Attribute] -> result+animate_ = term "animate"++-- | @animatecolor@ element+{-# DEPRECATED animateColor_ "Removed from web standards." #-}+animateColor_ :: Term result => [Attribute] -> result+animateColor_ = term "animateColor"++-- | @animatemotion@ element+animateMotion_ :: Term result => [Attribute] -> result+animateMotion_ = term "animateMotion"++-- | @animatetransform@ element+animateTransform_ :: Term result => [Attribute] -> result+animateTransform_ = term "animateTransform"++-- | @circle@ element+circle_ :: Term result => [Attribute] -> result+circle_ = term "circle"++-- | @clipPath@ element or attribute+clipPath_ :: Term result => [Attribute] -> result+clipPath_ = term "clipPath"++-- | @colorProfile@ element+colorProfile_ :: Term result => [Attribute] -> result+colorProfile_ = term "color-profile"++-- | @cursor@ element+cursor_ :: Term result => [Attribute] -> result+cursor_ = term "cursor"++-- | @defs@ element+defs_ :: Term result => [Attribute] -> result+defs_ = term "defs"++-- | @desc@ element+desc_ :: Term result => [Attribute] -> result+desc_ = term "desc"++-- | @ellipse@ element+ellipse_ :: Term result => [Attribute] -> result+ellipse_ = term "ellipse"++-- | @feblend@ element+feBlend_ :: Term result => [Attribute] -> result+feBlend_ = term "feBlend"++-- | @fecolormatrix@ element+feColorMatrix_ :: Term result => [Attribute] -> result+feColorMatrix_ = term "feColorMatrix"++-- | @fecomponenttransfer@ element+feComponentTransfer_ :: Term result => [Attribute] -> result+feComponentTransfer_ = term "feComponentTransfer"++-- | @fecomposite@ element+feComposite_ :: Term result => [Attribute] -> result+feComposite_ = term "feComposite"++-- | @feconvolvematrix@ element+feConvolveMatrix_ :: Term result => [Attribute] -> result+feConvolveMatrix_ = term "feConvolveMatrix"++-- | @fediffuselighting@ element+feDiffuseLighting_ :: Term result => [Attribute] -> result+feDiffuseLighting_ = term "feDiffuseLighting"++-- | @fedisplacementmap@ element+feDisplacementMap_ :: Term result => [Attribute] -> result+feDisplacementMap_ = term "feDisplacementMap"++-- | @fedistantlight@ element+feDistantLight_ :: Term result => [Attribute] -> result+feDistantLight_ = term "feDistantLight"++-- | @feflood@ element+feFlood_ :: Term result => [Attribute] -> result+feFlood_ = term "feFlood"++-- | @fefunca@ element+feFuncA_ :: Term result => [Attribute] -> result+feFuncA_ = term "feFuncA"++-- | @fefuncb@ element+feFuncB_ :: Term result => [Attribute] -> result+feFuncB_ = term "feFuncB"++-- | @fefuncg@ element+feFuncG_ :: Term result => [Attribute] -> result+feFuncG_ = term "feFuncG"++-- | @fefuncr@ element+feFuncR_ :: Term result => [Attribute] -> result+feFuncR_ = term "feFuncR"++-- | @fegaussianblur@ element+feGaussianBlur_ :: Term result => [Attribute] -> result+feGaussianBlur_ = term "feGaussianBlur"++-- | @feimage@ element+feImage_ :: Term result => [Attribute] -> result+feImage_ = term "feImage"++-- | @femerge@ element+feMerge_ :: Term result => [Attribute] -> result+feMerge_ = term "feMerge"++-- | @femergenode@ element+feMergeNode_ :: Term result => [Attribute] -> result+feMergeNode_ = term "feMergeNode"++-- | @femorphology@ element+feMorphology_ :: Term result => [Attribute] -> result+feMorphology_ = term "feMorphology"++-- | @feoffset@ element+feOffset_ :: Term result => [Attribute] -> result+feOffset_ = term "feOffset"++-- | @fepointlight@ element+fePointLight_ :: Term result => [Attribute] -> result+fePointLight_ = term "fePointLight"++-- | @fespecularlighting@ element+feSpecularLighting_ :: Term result => [Attribute] -> result+feSpecularLighting_ = term "feSpecularLighting"++-- | @fespotlight@ element+feSpotLight_ :: Term result => [Attribute] -> result+feSpotLight_ = term "feSpotLight"++-- | @fetile@ element+feTile_ :: Term result => [Attribute] -> result+feTile_ = term "feTile"++-- | @feturbulence@ element+feTurbulence_ :: Term result => [Attribute] -> result+feTurbulence_ = term "feTurbulence"++-- | @filter_@ element+filter_ :: Term result => [Attribute] -> result+filter_ = term "filter"++-- | @font@ element+font_ :: Term result => [Attribute] -> result+font_ = term "font"++-- | @fontFace@ element+fontFace_ :: Term result => [Attribute] -> result+fontFace_ = term "font-face"++-- | @fontFaceFormat@ element+fontFaceFormat_ :: [Attribute] -> Element+fontFaceFormat_ = with $ makeElementNoEnd "font-face-format"++-- | @fontFaceName@ element+fontFaceName_ :: [Attribute] -> Element+fontFaceName_ = with $ makeElementNoEnd "font-face-name"++-- | @fontFaceSrc@ element+fontFaceSrc_ :: Term result => [Attribute] -> result+fontFaceSrc_ = term "font-face-src"++-- | @fontFaceUri@ element+fontFaceUri_ :: Term result => [Attribute] -> result+fontFaceUri_ = term "font-face-uri"++-- | @foreignobject@ element+foreignObject_ :: Term result => [Attribute] -> result+foreignObject_ = term "foreignObject"++-- | @g@ element+g_ :: Term result => [Attribute] -> result+g_ = term "g"++-- | @glyph@ element or attribute+glyph_ :: Term result => [Attribute] -> result+glyph_ = term "glyph"++-- | @glyphref@ element+glyphRef_ :: [Attribute] -> Element+glyphRef_ = with $ makeElementNoEnd "glyphRef"++-- | @hkern@ element+hkern_ :: [Attribute] -> Element+hkern_ = with $ makeElementNoEnd "hkern"++-- | @image@ element+image_ :: Term result => [Attribute] -> result+image_ = term "image"++-- | @line@ element+line_ :: Term result => [Attribute] -> result+line_ = term "line"++-- | @lineargradient@ element+linearGradient_ :: Term result => [Attribute] -> result+linearGradient_ = term "linearGradient"++-- | @marker@ element+marker_ :: Term result => [Attribute] -> result+marker_ = term "marker"++-- | @mask@ element or attribute+mask_ :: Term result => [Attribute] -> result+mask_ = term "mask"++-- | @metadata@ element+metadata_ :: Term result => [Attribute] -> result+metadata_ = term "metadata"++-- | @missingGlyph@ element+missingGlyph_ :: Term result => [Attribute] -> result+missingGlyph_ = term "missing-glyph"++-- | @mpath@ element+mpath_ :: Term result => [Attribute] -> result+mpath_ = term "mpath"++-- | @path@ element+path_ :: Term result => [Attribute] -> result+path_ = term "path"++-- | @pattern@ element+pattern_ :: Term result => [Attribute] -> result+pattern_ = term "pattern"++-- | @polygon@ element+polygon_ :: Term result => [Attribute] -> result+polygon_ = term "polygon"++-- | @polyline@ element+polyline_ :: Term result => [Attribute] -> result+polyline_ = term "polyline"++-- | @radialgradient@ element+radialGradient_ :: Term result => [Attribute] -> result+radialGradient_ = term "radialGradient"++-- | @rect@ element+rect_ :: Term result => [Attribute] -> result+rect_ = term "rect"++-- | @script@ element+script_ :: Term result => [Attribute] -> result+script_ = term "script"++-- | @set@ element+set_ :: Term result => [Attribute] -> result+set_ = term "set"++-- | @stop@ element+stop_ :: Term result => [Attribute] -> result+stop_ = term "stop"++-- | @style@ element+style_ :: Term result => [Attribute] -> result+style_ = term "style"++-- | @svg@ element+svg_ :: Term result => [Attribute] -> result+svg_ = term "svg"++-- | @switch@ element+switch_ :: Term result => [Attribute] -> result+switch_ = term "switch"++-- | @symbol@ element+symbol_ :: Term result => [Attribute] -> result+symbol_ = term "symbol"++-- | @text_@ element+text_ :: Term result => [Attribute] -> result+text_ = term "text"++-- | @textpath@ element+textPath_ :: Term result => [Attribute] -> result+textPath_ = term "textPath"++-- | @title@ element+title_ :: Term result => [Attribute] -> result+title_ = term "title"++-- | @tref@ element+tref_ :: Term result => [Attribute] -> result+tref_ = term "tref"++-- | @tspan@ element+tspan_ :: Term result => [Attribute] -> result+tspan_ = term "tspan"++-- | @use@ element+use_ :: Term result => [Attribute] -> result+use_ = term "use"++-- | @view@ element+view_ :: Term result => [Attribute] -> result+view_ = term "view"++-- | @vkern@ element+vkern_ :: [Attribute] -> Element+vkern_ = with $ makeElementNoEnd "vkern"
+ src/Graphics/Svg/Path.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE OverloadedStrings #-}++-------------------------------------------------------------------------------+-- |+-- Module : Graphics.Svg.Path+-- Copyright : (c) 2015 Jeffrey Rosenbluth+-- License : BSD-style (see LICENSE)+-- Maintainer : jeffrey.rosenbluth@gmail.com+--+-- Utility functions to help create SVG path attributes,+-- and transforms.+--+-------------------------------------------------------------------------------++module Graphics.Svg.Path where++import Data.Text (Text)+import qualified Data.Text as T+import Data.Text.Lazy (toStrict)+import Data.Text.Lazy.Builder (toLazyText)+import Data.Text.Lazy.Builder.RealFloat++-- | Convert a number to Text.+toText :: RealFloat a => a -> Text+toText = toStrict . toLazyText . formatRealFloat Fixed (Just 4)++-- | moveto (absolute)+mA :: RealFloat a => a -> a -> Text+mA x y = T.concat ["M " ,toText x, ",", toText y, " "]++-- | moveto (relative)+mR :: RealFloat a => a -> a -> Text+mR dx dy = T.concat ["m ", toText dx, ",", toText dy, " "]++-- | lineto (absolute)+lA :: RealFloat a => a -> a -> Text+lA x y = T.concat ["L ", toText x, ",", toText y, " "]++-- | lineto (relative)+lR :: RealFloat a => a -> a -> Text+lR dx dy = T.concat ["l ", toText dx, ",", toText dy, " "]++-- | horizontal lineto (absolute)+hA :: RealFloat a => a -> Text+hA x = T.concat ["H ", toText x, " "]++-- | horizontal lineto (relative)+hR :: RealFloat a => a -> Text+hR dx = T.concat ["h ", toText dx, " "]++-- | vertical lineto (absolute)+vA :: RealFloat a => a -> Text+vA y = T.concat ["V ", toText y, " "]++-- | vertical lineto (relative)+vR :: RealFloat a => a -> Text+vR dy = T.concat ["v ", toText dy, " "]++-- | Cubic Bezier curve (absolute)+cA :: RealFloat a => a -> a -> a -> a -> a -> a -> Text+cA c1x c1y c2x c2y x y = T.concat+ [ "C ", toText c1x, ",", toText c1y, " ", toText c2x, ","+ , toText c2y, " ", toText x, " ", toText y]++-- | Cubic Bezier curve (relative)+cR :: RealFloat a => a -> a -> a -> a -> a -> a -> Text+cR dc1x dc1y dc2x dc2y dx dy = T.concat+ [ "c ", toText dc1x, ",", toText dc1y, " ", toText dc2x+ , ",", toText dc2y, " ", toText dx, " ", toText dy]++-- | Smooth Cubic Bezier curve (absolute)+sA :: RealFloat a => a -> a -> a -> a -> Text+sA c2x c2y x y = T.concat+ ["S ", toText c2x, ",", toText c2y, " ", toText x, ",", toText y, " "]++-- | Smooth Cubic Bezier curve (relative)+sR :: RealFloat a => a -> a -> a -> a -> Text+sR dc2x dc2y dx dy = T.concat+ ["s ", toText dc2x, ",", toText dc2y, " ", toText dx, ",", toText dy, " "]++-- | Quadratic Bezier curve (absolute)+qA :: RealFloat a => a -> a -> a -> a -> Text+qA cx cy x y = T.concat+ ["Q ", toText cx, ",", toText cy, " ", toText x, ",", toText y, " "]++-- | Quadratic Bezier curve (relative)+qR :: RealFloat a => a -> a -> a -> a -> Text+qR dcx dcy dx dy = T.concat+ ["q ", toText dcx, ",", toText dcy, " ", toText dx, ",", toText dy, " " ]++-- | Smooth Quadratic Bezier curve (absolute)+tA :: RealFloat a => a -> a -> Text+tA x y = T.concat ["T ", " ", toText x, ",", toText y, " "]++-- | Smooth Quadratic Bezier curve (relative)+tR :: RealFloat a => a -> a -> Text+tR x y = T.concat [ "t ", toText x, ",", toText y, " "]++-- | Arc (absolute)+aA :: RealFloat a => a -> a -> a -> a -> a -> a -> a -> Text+aA rx ry xrot largeFlag sweepFlag x y = T.concat+ [ "A ", toText rx, ",", toText ry, " ", toText xrot, " ", toText largeFlag+ , " ", toText sweepFlag, " ", toText x, " ", toText y, " "]++-- | Arc (relative)+aR :: RealFloat a => a -> a -> a -> a -> a -> a -> a -> Text+aR rx ry xrot largeFlag sweepFlag x y = T.concat+ [ "a ", toText rx, ",", toText ry, " ", toText xrot, " ", toText largeFlag+ , " ", toText sweepFlag, " ", toText x, " ", toText y, " "]++-- | closepath+z :: Text+z = "Z"++-- | SVG Transform components+-- | Specifies a translation by @x@ and @y@+translate :: RealFloat a => a -> a -> Text+translate x y = T.concat ["translate(", toText x, " ", toText y, ")"]++-- | Specifies a scale operation by @x@ and @y@+scale :: RealFloat a => a -> a -> Text+scale x y = T.concat ["scale(", toText x, " ", toText y, ")"]++-- | Specifies a rotation by @rotate-angle@ degrees+rotate :: RealFloat a => a -> Text+rotate angle = T.concat ["rotate(", toText angle, ")"]++-- | Specifies a rotation by @rotate-angle@ degrees about the given time @rx,ry@+rotateAround :: RealFloat a => a -> a -> a -> Text+rotateAround angle rx ry = T.concat+ ["rotate(", toText angle, ",", toText rx, ",", toText ry, ")"]++-- | Skew tansformation along x-axis+skewX :: RealFloat a => a -> Text+skewX angle = T.concat ["skewX(", toText angle, ")"]++-- | Skew tansformation along y-axis+skewY :: RealFloat a => a -> Text+skewY angle = T.concat ["skewY(", toText angle, ")"]++-- | Specifies a transform in the form of a transformation matrix+matrix :: RealFloat a => a -> a -> a -> a -> a -> a -> Text+matrix a b c d e f = T.concat+ [ "matrix(", toText a, ",", toText b, ",", toText c+ , ",", toText d, ",", toText e, ",", toText f, ")"]
+ svg-builder.cabal view
@@ -0,0 +1,30 @@+name: svg-builder+version: 0.1+synopsis: DSL for building SVG.+description: Fast, easy to write SVG.+homepage: http://github.com/jeffreyrosenbluth/svg-builder.git+license: BSD3+license-file: LICENSE+author: Jeffrey Rosenbluth+maintainer: jeffrey.rosenbluth@gmail.com+copyright: 2016 Jeffrey Rosenbluth+category: Graphics+build-type: Simple+extra-source-files: README.md+cabal-version: >=1.10++library+ ghc-options: -Wall -rtsopts -O2+ exposed-modules: Graphics.Svg,+ Graphics.Svg.Core,+ Graphics.Svg.Path,+ Graphics.Svg.Elements,+ Graphics.Svg.Attributes+ build-depends: base >= 4.5 && < 4.10,+ blaze-builder >= 0.4 && < 0.5,+ bytestring >= 0.10 && < 0.11,+ hashable >= 1.1 && < 1.3,+ text >= 0.11 && < 1.3,+ unordered-containers >= 0.2 && < 0.2.7+ hs-source-dirs: src+ default-language: Haskell2010