packages feed

chart-svg 0.3.1 → 0.3.2

raw patch · 8 files changed

+50/−64 lines, 8 filesdep ~luciddep ~timePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: lucid, time

API changes (from Hackage documentation)

- Data.Path.Parser: instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Path.Parser.PathInfo a)
- Data.Path.Parser: instance GHC.Generics.Generic (Data.Path.Parser.PathInfo a)
- Data.Path.Parser: instance GHC.Show.Show a => GHC.Show.Show (Data.Path.Parser.PathInfo a)

Files

chart-svg.cabal view
@@ -1,6 +1,6 @@ cabal-version:   2.4 name:            chart-svg-version:         0.3.1+version:         0.3.2 synopsis:        Charting library targetting SVGs. description:   This package provides a charting library targetting SVG as the rendered output.@@ -62,7 +62,7 @@     , cubicbezier         ^>=0.6     , foldl               ^>=1.4     , formatn             ^>=0.2-    , lucid               ^>=2.9+    , lucid               >=2.9 && <3     , mtl                 ^>=2.2.2     , neat-interpolation  ^>=0.5.1     , numhask             ^>=0.10@@ -73,7 +73,7 @@     , scientific          ^>=0.3     , tagsoup             ^>=0.14     , text                ^>=1.2-    , time                ^>=1.9+    , time                >=1.9 && <2     , transformers        ^>=0.5    default-language:   Haskell2010
other/usage.svg view
@@ -1,4 +1,4 @@-<svg xmlns="http://www.w3.org/2000/svg" width="446.753163625545" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-0.7380894953982863 -0.49743338195719966 1.4823989209774675 0.995448297856914" height="300.0"><style>svg {+<svg width="446.753163625545" height="300.0" viewBox="-0.7380894953982863 -0.49743338195719966 1.4823989209774675 0.995448297856914" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style>svg {   color-scheme: light dark; } {@@ -22,11 +22,11 @@   .legendBorder g {     fill: #0d0d0d;   }-}</style><g class="chart"><g class="line"><g fill="none" stroke="rgb(2%, 73%, 80%)" stroke-width="1.5e-2" stroke-opacity="1.0"><polyline points="-0.5962269120913996,0.2226262967974741+}</style><g class="chart"><g class="line"><g stroke-width="1.5e-2" stroke="rgb(2%, 73%, 80%)" stroke-opacity="1.0" fill="none"><polyline points="-0.5962269120913996,0.2226262967974741 -0.16239638210092033,0.2226262967974741-0.271434147889559,-0.47471244925575107"/></g><g fill="none" stroke="rgb(2%, 29%, 48%)" stroke-width="1.5e-2" stroke-opacity="1.0"><polyline points="-0.5962269120913996,0.39696098331078034-0.6184985718819421,-0.12604307622913857"/></g><g fill="none" stroke="rgb(66%, 7%, 55%)" stroke-width="1.5e-2" stroke-opacity="1.0"><polyline points="-0.37931164709615994,-0.30037776274244476--0.37931164709615994,0.39696098331078034"/></g></g></g><g class="hud"><g class="frame"><g fill="rgb(100%, 100%, 100%)" stroke="rgb(0%, 0%, 0%)" stroke-width="0.0" fill-opacity="2.0e-2" stroke-opacity="0.0"><rect x="-0.6027343700412567" width="1.3079990479212948" y="-0.48124999999999996" height="0.8847485340550292"/></g></g><g class="axis"><g class="ticks"><g class="tickglyph"><g fill="rgb(5%, 5%, 5%)" stroke="rgb(5%, 5%, 5%)" stroke-width="4.0e-3" fill-opacity="0.4" stroke-opacity="0.4"><g transform="rotate(-90.0, -0.6287642018406855, 0.39696098331078034)"><polyline points="-0.6287642018406855,0.41196098331078035+0.271434147889559,-0.47471244925575107"/></g><g stroke-width="1.5e-2" stroke="rgb(2%, 29%, 48%)" stroke-opacity="1.0" fill="none"><polyline points="-0.5962269120913996,0.39696098331078034+0.6184985718819421,-0.12604307622913857"/></g><g stroke-width="1.5e-2" stroke="rgb(66%, 7%, 55%)" stroke-opacity="1.0" fill="none"><polyline points="-0.37931164709615994,-0.30037776274244476+-0.37931164709615994,0.39696098331078034"/></g></g></g><g class="hud"><g class="frame"><g stroke-width="0.0" stroke="rgb(0%, 0%, 0%)" stroke-opacity="0.0" fill="rgb(100%, 100%, 100%)" fill-opacity="2.0e-2"><rect width="1.3079990479212948" height="0.8847485340550292" x="-0.6027343700412567" y="-0.48124999999999996"/></g></g><g class="axis"><g class="ticks"><g class="tickglyph"><g stroke-width="4.0e-3" stroke="rgb(5%, 5%, 5%)" stroke-opacity="0.4" fill="rgb(5%, 5%, 5%)" fill-opacity="0.4"><g transform="rotate(-90.0, -0.6287642018406855, 0.39696098331078034)"><polyline points="-0.6287642018406855,0.41196098331078035 -0.6287642018406855,0.3819609833107803"/></g><g transform="rotate(-90.0, -0.6287642018406855, 0.30979364005412724)"><polyline points="-0.6287642018406855,0.32479364005412725 -0.6287642018406855,0.2947936400541272"/></g><g transform="rotate(-90.0, -0.6287642018406855, 0.2226262967974741)"><polyline points="-0.6287642018406855,0.2376262967974741 -0.6287642018406855,0.20762629679747407"/></g><g transform="rotate(-90.0, -0.6287642018406855, 0.13545895354082088)"><polyline points="-0.6287642018406855,0.1504589535408209@@ -37,7 +37,7 @@ -0.6287642018406855,-0.2282104194857918"/></g><g transform="rotate(-90.0, -0.6287642018406855, -0.30037776274244476)"><polyline points="-0.6287642018406855,-0.28537776274244475 -0.6287642018406855,-0.3153777627424448"/></g><g transform="rotate(-90.0, -0.6287642018406855, -0.38754510599909786)"><polyline points="-0.6287642018406855,-0.37254510599909785 -0.6287642018406855,-0.4025451059990979"/></g><g transform="rotate(-90.0, -0.6287642018406855, -0.47471244925575107)"><polyline points="-0.6287642018406855,-0.45971244925575105--0.6287642018406855,-0.4897124492557511"/></g></g></g><g class="ticktext"><g fill="rgb(5%, 5%, 5%)" stroke="none" stroke-width="0.0" font-size="4.3383052999047926e-2" fill-opacity="1.0" text-anchor="end"><text x="-0.66" y="0.40894649300857017">0.00</text><text x="-0.66" y="0.321779149751917">0.50</text><text x="-0.66" y="0.2346118064952638">1.00</text><text x="-0.66" y="0.14744446323861077">1.50</text><text x="-0.66" y="6.027711998195756e-2">2.00</text><text x="-0.66" y="-2.689022327469548e-2">2.50</text><text x="-0.66" y="-0.11405756653134869">3.00</text><text x="-0.66" y="-0.2012249097880019">3.50</text><text x="-0.66" y="-0.2883922530446551">4.00</text><text x="-0.66" y="-0.3755595963013081">4.50</text><text x="-0.66" y="-0.4627269395579613">5.00</text></g></g><g class="ticklines"><g fill="none" stroke="rgb(5%, 5%, 5%)" stroke-width="5.0e-3" stroke-opacity="5.0e-2"><polyline points="-0.5962269120913996,0.39696098331078034+-0.6287642018406855,-0.4897124492557511"/></g></g></g><g class="ticktext"><g stroke-width="0.0" stroke="none" fill="rgb(5%, 5%, 5%)" fill-opacity="1.0" font-size="4.3383052999047926e-2" text-anchor="end"><text x="-0.66" y="0.40894649300857017">0.00</text><text x="-0.66" y="0.321779149751917">0.50</text><text x="-0.66" y="0.2346118064952638">1.00</text><text x="-0.66" y="0.14744446323861077">1.50</text><text x="-0.66" y="6.027711998195756e-2">2.00</text><text x="-0.66" y="-2.689022327469548e-2">2.50</text><text x="-0.66" y="-0.11405756653134869">3.00</text><text x="-0.66" y="-0.2012249097880019">3.50</text><text x="-0.66" y="-0.2883922530446551">4.00</text><text x="-0.66" y="-0.3755595963013081">4.50</text><text x="-0.66" y="-0.4627269395579613">5.00</text></g></g><g class="ticklines"><g stroke-width="5.0e-3" stroke="rgb(5%, 5%, 5%)" stroke-opacity="5.0e-2" fill="none"><polyline points="-0.5962269120913996,0.39696098331078034 0.7052646778800381,0.39696098331078034"/><polyline points="-0.5962269120913996,0.30979364005412724 0.7052646778800381,0.30979364005412724"/><polyline points="-0.5962269120913996,0.2226262967974741 0.7052646778800381,0.2226262967974741"/><polyline points="-0.5962269120913996,0.13545895354082088@@ -48,18 +48,18 @@ 0.7052646778800381,-0.21321041948579178"/><polyline points="-0.5962269120913996,-0.30037776274244476 0.7052646778800381,-0.30037776274244476"/><polyline points="-0.5962269120913996,-0.38754510599909786 0.7052646778800381,-0.38754510599909786"/><polyline points="-0.5962269120913996,-0.47471244925575107-0.7052646778800381,-0.47471244925575107"/></g></g></g><g class="axisbar"><g fill="rgb(5%, 5%, 5%)" stroke="rgb(0%, 0%, 0%)" stroke-width="0.0" fill-opacity="0.4" stroke-opacity="0.0"><rect x="-0.6148816248809902" width="3.4706442399238258e-3" y="-0.4764557961208842" height="0.8751601262967976"/></g></g></g><g class="axis"><g class="ticks"><g class="tickglyph"><g fill="rgb(5%, 5%, 5%)" stroke="rgb(5%, 5%, 5%)" stroke-width="4.0e-3" fill-opacity="0.4" stroke-opacity="0.4"><polyline points="-0.5962269120913996,0.44464873703202523+0.7052646778800381,-0.47471244925575107"/></g></g></g><g class="axisbar"><g stroke-width="0.0" stroke="rgb(0%, 0%, 0%)" stroke-opacity="0.0" fill="rgb(5%, 5%, 5%)" fill-opacity="0.4"><rect width="3.4706442399238258e-3" height="0.8751601262967976" x="-0.6148816248809902" y="-0.4764557961208842"/></g></g></g><g class="axis"><g class="ticks"><g class="tickglyph"><g stroke-width="4.0e-3" stroke="rgb(5%, 5%, 5%)" stroke-opacity="0.4" fill="rgb(5%, 5%, 5%)" fill-opacity="0.4"><polyline points="-0.5962269120913996,0.44464873703202523 -0.5962269120913996,0.4146487370320252"/><polyline points="-0.37931164709615994,0.44464873703202523 -0.37931164709615994,0.4146487370320252"/><polyline points="-0.16239638210092033,0.44464873703202523 -0.16239638210092033,0.4146487370320252"/><polyline points="5.4518882894319276e-2,0.44464873703202523 5.4518882894319276e-2,0.4146487370320252"/><polyline points="0.271434147889559,0.44464873703202523 0.271434147889559,0.4146487370320252"/><polyline points="0.4883494128847986,0.44464873703202523 0.4883494128847986,0.4146487370320252"/><polyline points="0.7052646778800381,0.44464873703202523-0.7052646778800381,0.4146487370320252"/></g></g><g class="ticktext"><g fill="rgb(5%, 5%, 5%)" stroke="none" stroke-width="0.0" font-size="4.3383052999047926e-2" fill-opacity="1.0" text-anchor="middle"><text x="-0.5962269120913996" y="0.485">0.00</text><text x="-0.37931164709615994" y="0.485">0.50</text><text x="-0.16239638210092033" y="0.485">1.00</text><text x="5.4518882894319276e-2" y="0.485">1.50</text><text x="0.271434147889559" y="0.485">2.00</text><text x="0.4883494128847986" y="0.485">2.50</text><text x="0.7052646778800381" y="0.485">3.00</text></g></g><g class="ticklines"><g fill="none" stroke="rgb(5%, 5%, 5%)" stroke-width="5.0e-3" stroke-opacity="5.0e-2"><polyline points="-0.5962269120913996,0.39696098331078034+0.7052646778800381,0.4146487370320252"/></g></g><g class="ticktext"><g stroke-width="0.0" stroke="none" fill="rgb(5%, 5%, 5%)" fill-opacity="1.0" font-size="4.3383052999047926e-2" text-anchor="middle"><text x="-0.5962269120913996" y="0.485">0.00</text><text x="-0.37931164709615994" y="0.485">0.50</text><text x="-0.16239638210092033" y="0.485">1.00</text><text x="5.4518882894319276e-2" y="0.485">1.50</text><text x="0.271434147889559" y="0.485">2.00</text><text x="0.4883494128847986" y="0.485">2.50</text><text x="0.7052646778800381" y="0.485">3.00</text></g></g><g class="ticklines"><g stroke-width="5.0e-3" stroke="rgb(5%, 5%, 5%)" stroke-opacity="5.0e-2" fill="none"><polyline points="-0.5962269120913996,0.39696098331078034 -0.5962269120913996,-0.47471244925575107"/><polyline points="-0.37931164709615994,0.39696098331078034 -0.37931164709615994,-0.47471244925575107"/><polyline points="-0.16239638210092033,0.39696098331078034 -0.16239638210092033,-0.47471244925575107"/><polyline points="5.4518882894319276e-2,0.39696098331078034 5.4518882894319276e-2,-0.47471244925575107"/><polyline points="0.271434147889559,0.39696098331078034 0.271434147889559,-0.47471244925575107"/><polyline points="0.4883494128847986,0.39696098331078034 0.4883494128847986,-0.47471244925575107"/><polyline points="0.7052646778800381,0.39696098331078034-0.7052646778800381,-0.47471244925575107"/></g></g></g><g class="axisbar"><g fill="rgb(5%, 5%, 5%)" stroke="rgb(0%, 0%, 0%)" stroke-width="0.0" fill-opacity="0.4" stroke-opacity="0.0"><rect x="-0.5979622342113615" width="1.3049622342113616" y="0.4122152683806946" height="3.4866937302661105e-3"/></g></g></g></g></svg>+0.7052646778800381,-0.47471244925575107"/></g></g></g><g class="axisbar"><g stroke-width="0.0" stroke="rgb(0%, 0%, 0%)" stroke-opacity="0.0" fill="rgb(5%, 5%, 5%)" fill-opacity="0.4"><rect width="1.3049622342113616" height="3.4866937302661105e-3" x="-0.5979622342113615" y="0.4122152683806946"/></g></g></g></g></svg>
src/Chart.hs view
@@ -104,7 +104,7 @@  -- $hud ----- Axes, titles, tick marks, grid lines and legends are chart elements that exist to provide references to help explain the data being represented. The collective noun used by the library for these elements is /hud/. Hud elements can usually be distinguished from data syntax, but need information from the chart domain (data domain and style domain) to function. A tick mark and tick value on an axis need to know the range of the data to be placed properly on the screen. A chart border needs to know the syntactic range of the entire data representation inclusive of representational artifacts that might extend beyond the data domain (A circle glyph representing a point has dimension).+-- Axes, titles, tick marks, grid lines and legends are chart elements that exist to provide references to help explain the data being represented. The collective noun used by the library for these elements is /hud/. Hud elements can usually be distinguished from data syntax, but need information from the chart domain (data domain and style domain) to function. A tick mark and tick value on an axis need to know the range of the data to be placed properly on the screen. A chart border needs to know the syntactic range of the entire data representation inclusive of representational artifacts that might extend beyond the data domain. A glyph representing a one-dimensional point exists in 2 dimensions, or we wouldn't be able to see it. -- -- Apart from this functional usage, however, hud elements are pretty much the same as data elements. They are typically composed of the same stuff; rectangles and lines and text and colors. --@@ -114,13 +114,13 @@ -- -- - measure the range of the data values ----- - fold hud elements into a chart, /creating new 'ChartTree' from the hud/, keeping track of chart dimensions across three domains:+-- - fold hud elements into a chart, creating new 'ChartTree's from the hud, keeping track of chart dimensions across three domains: -----   - The domain of the underlying data+--   1. The domain of the underlying data -----   - The domain of the canvas where the data is being represented+--   2. The domain of the canvas where the data is being represented -----   - The domain of the chart, inclusive of Hud or decorative elements.+--   3. The domain of the chart, inclusive of Hud or decorative elements. -- -- This process is reified in 'runHudWith'. The most common Hud concepts, such as axes and titles, have been collected into the 'HudOptions' type. --@@ -129,6 +129,6 @@  -- $optics ----- Usage suggests the use of optics-core and OverloadedLabels, but this is not required. 'Chart', 'HudOptions' and associated chart configuration types are big and sometimes deep syntax trees, and simple optics getting, setting and modding makes manipulation more pleasant. Lens works as well, and the library is perfectly capable of being used with records.+-- Usage suggests the use of optics-core and OverloadedLabels, but this is not required. 'Chart', 'HudOptions' and associated chart configuration types are big and sometimes deep syntax trees, and simple optics; getting, setting and modding, makes manipulation more pleasant. Lens works as well, and the library is perfectly capable of being used with records. -- -- Lenses are supplied, for the optics-core library, but can be easily modified for lens. The chart-svg convention is that lenses are either OverloadedLabels, or suffixed with a single quote /'/.
src/Chart/Primitive.hs view
@@ -80,8 +80,8 @@  -- | There are 6 Chart primitives, unified as the Chart type. ----- - 'RectChart': a rectangle in the XY-domain. For example, a @Rect 0 1 0 1@ is the set of points on the XY Plane bounded by (0,0), (0,1), (1,0) & (1,1). Much of the library is built on Rect Double's but the base types are polymorphic.--- - 'LineChart': a list of points which represent connected straight lines. [Point 0 0, Point 1 1, Point 2 2, Point 3 3] is an example; three lines connected up to form a line from (0,0) to (3,3).+-- - 'RectChart': a rectangle in the XY-domain. For example, a @'Rect' 0 1 0 1@ is the set of points on the XY Plane bounded by (0,0), (0,1), (1,0) & (1,1). Much of the library is built on 'Rect' 'Double''s but the base types are polymorphic.+-- - 'LineChart': a list of points which represent connected straight lines. ['Point' 0 0, 'Point' 1 1, 'Point' 2 2, 'Point' 3 3] is an example; three lines connected up to form a line from (0,0) to (3,3). -- - 'GlyphChart': a 'GlyphShape' which is a predefined shaped centered at a 'Point' in XY space. -- - 'TextChart': text centered at a 'Point' in XY space. -- - 'PathChart': specification of curvilinear paths using the SVG standards.
src/Chart/Svg.hs view
@@ -242,7 +242,7 @@ -- | Render a chart using the supplied svg and hud config. -- -- >>> chartSvg mempty--- "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"450.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"-0.75 -0.5 1.5 1.0\" height=\"300.0\"><style>svg {\n  color-scheme: light dark;\n}\n{\n  .canvas g, .title g, .axisbar g, .ticktext g, .tickglyph g, .ticklines g, .legendContent g text {\n    fill: #0d0d0d;\n  }\n  .ticklines g, .tickglyph g, .legendBorder g {\n    stroke: #0d0d0d;\n  }\n  .legendBorder g {\n    fill: #f0f0f0;\n  }\n}\n@media (prefers-color-scheme:dark) {\n  .canvas g, .title g, .axisbar g, .ticktext g, .tickglyph g, .ticklines g, .legendContent g text {\n    fill: #f0f0f0;\n  }\n  .ticklines g, .tickglyph g, .legendBorder g {\n    stroke: #f0f0f0;\n  }\n  .legendBorder g {\n    fill: #0d0d0d;\n  }\n}</style><g class=\"chart\"></g><g class=\"hud\"></g></svg>"+-- "<svg width=\"450.0\" height=\"300.0\" viewBox=\"-0.75 -0.5 1.5 1.0\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><style>svg {\n  color-scheme: light dark;\n}\n{\n  .canvas g, .title g, .axisbar g, .ticktext g, .tickglyph g, .ticklines g, .legendContent g text {\n    fill: #0d0d0d;\n  }\n  .ticklines g, .tickglyph g, .legendBorder g {\n    stroke: #0d0d0d;\n  }\n  .legendBorder g {\n    fill: #f0f0f0;\n  }\n}\n@media (prefers-color-scheme:dark) {\n  .canvas g, .title g, .axisbar g, .ticktext g, .tickglyph g, .ticklines g, .legendContent g text {\n    fill: #f0f0f0;\n  }\n  .ticklines g, .tickglyph g, .legendBorder g {\n    stroke: #f0f0f0;\n  }\n  .legendBorder g {\n    fill: #0d0d0d;\n  }\n}</style><g class=\"chart\"></g><g class=\"hud\"></g></svg>" chartSvg :: ChartSvg -> Text chartSvg cs = renderToText (renderToSvg (view #svgOptions cs) (toChartTree cs)) 
src/Data/Colour.hs view
@@ -566,6 +566,7 @@ -- The mix has gone out of gamut because we are swishing through hue mixes. -- -- In this case, settting the hue on the black colour within the LCH contruct helps:+-- -- >>> betterblack = set (lch' % hLCH') (view hue' (Colour 0.2 0.6 0.8 0.5)) (review lcha2colour' black) -- >>> view lcha2colour' $ mixLCHA 0.8 betterblack (review lcha2colour' $ Colour 0.2 0.6 0.8 0.5) -- Colour 0.14 0.44 0.59 0.60
src/Data/Path.hs view
@@ -225,6 +225,7 @@ -- | Convert from an ArcCentroid to an ArcPosition specification. -- -- Morally,+-- -- > arcPosition . arcCentroid == id -- -- Not isomorphic if:
src/Data/Path/Parser.hs view
@@ -24,7 +24,7 @@ import Data.Either import Data.FormatN import Data.Functor-import Data.Path+import Data.Path ( PathData(..), ArcInfo(ArcInfo) ) import Data.Scientific (toRealFloat) import Data.Text (Text, pack) import qualified Data.Text as Text@@ -40,9 +40,9 @@ -- -- References: ----- [SVG d](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d)+-- [SVG d attribute](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d) ----- [SVG path](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths)+-- [SVG Paths](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths)  -- | Parse a raw path string. --@@ -50,7 +50,6 @@ -- >>> parsePath outerseg1 -- Right [MoveTo OriginAbsolute [Point -1.0 0.5],EllipticalArc OriginAbsolute [(0.5,0.5,0.0,True,True,Point 0.0 -1.2320508075688774),(1.0,1.0,0.0,False,False,Point -0.5 -0.3660254037844387),(1.0,1.0,0.0,False,False,Point -1.0 0.5)],EndPath] ----- https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d parsePath :: Text -> Either String [PathCommand] parsePath = A.parseOnly pathParser @@ -164,21 +163,6 @@     OriginRelative   deriving (Eq, Show, Generic) --- | To fit in with the requirements of the library design, specifically the separation of what a chart is into XY data Points from representation of these points, path instructions need to be decontructed into:------ - define a single chart element as a line.------ - split a single path element into the start and end points of the line, which become the 'Chart.Types.xys' of a 'Chart.Types.Chart', and the rest of the information, which is called 'PathInfo' and incorporated into the 'Chart.Types.Chart' 'Chart.Types.annotation'.------ An arc path is variant to affine transformations of the 'Chart.Types.xys' points: angles are not presevred in the new reference frame.-data PathInfo a-  = StartI-  | LineI-  | CubicI (Point a) (Point a)-  | QuadI (Point a)-  | ArcI (ArcInfo a)-  deriving (Show, Eq, Generic)- pointToSvgCoords :: Point Double -> Point Double pointToSvgCoords (Point x y) = Point x (-y) @@ -193,7 +177,7 @@ -- -- Note that morally, ----- > toPathsAbsolute . toInfos . parsePath == id+-- > toPathsAbsolute . toPathDatas . parsePath == id -- -- but the round trip destroys much information, including: --@@ -263,17 +247,17 @@ stateCur0 :: PathCursor stateCur0 = PathCursor zero zero Nothing --- | Convert an SVG d path text snippet to a [PathData Double]+-- | Convert from an SVG d attribute text snippet to a [`PathData` `Double`] svgToPathData :: Text -> [PathData Double] svgToPathData = toPathDatas . either error id . parsePath --- | Convert [PathData] to an SVG d path text.+-- | Convert from [`PathData` `Double`] to an SVG d path text snippet. pathDataToSvg :: [PathData Double] -> Text pathDataToSvg xs = Text.intercalate " " $ fmap toPathAbsolute xs  -- | Convert from a path command list to a PathA specification toPathDatas :: [PathCommand] -> [PathData Double]-toPathDatas xs = fmap svgCoords $ mconcat $ flip evalState stateCur0 $ sequence $ toInfo <$> xs+toPathDatas xs = fmap svgCoords $ mconcat $ flip evalState stateCur0 $ sequence $ toPathData <$> xs  -- | Convert relative points to absolute points relToAbs :: (Additive a) => a -> [a] -> [a]@@ -383,43 +367,43 @@ -- | Convert a path command fragment to PathData -- -- flips the y-dimension of points.-toInfo :: PathCommand -> State PathCursor [PathData Double]-toInfo (MoveTo OriginAbsolute xs) = moveTo xs-toInfo (MoveTo OriginRelative xs) = do+toPathData :: PathCommand -> State PathCursor [PathData Double]+toPathData (MoveTo OriginAbsolute xs) = moveTo xs+toPathData (MoveTo OriginRelative xs) = do   (PathCursor p _ _) <- get   moveTo (relToAbs p xs)-toInfo EndPath = do+toPathData EndPath = do   (PathCursor _ s _) <- get   pure [LineP s]-toInfo (LineTo OriginAbsolute xs) = lineTo xs-toInfo (LineTo OriginRelative xs) = do+toPathData (LineTo OriginAbsolute xs) = lineTo xs+toPathData (LineTo OriginRelative xs) = do   (PathCursor p _ _) <- get   lineTo (relToAbs p xs)-toInfo (HorizontalTo OriginAbsolute xs) = horTo xs-toInfo (HorizontalTo OriginRelative xs) = do+toPathData (HorizontalTo OriginAbsolute xs) = horTo xs+toPathData (HorizontalTo OriginRelative xs) = do   (PathCursor (Point x _) _ _) <- get   horTo (relToAbs x xs)-toInfo (VerticalTo OriginAbsolute xs) = verTo xs-toInfo (VerticalTo OriginRelative ys) = do+toPathData (VerticalTo OriginAbsolute xs) = verTo xs+toPathData (VerticalTo OriginRelative ys) = do   (PathCursor (Point _ y) _ _) <- get   verTo (relToAbs y ys)-toInfo (CurveTo OriginAbsolute xs) = curveTo xs-toInfo (CurveTo OriginRelative xs) = do+toPathData (CurveTo OriginAbsolute xs) = curveTo xs+toPathData (CurveTo OriginRelative xs) = do   (PathCursor p _ _) <- get   curveTo (relToAbs3 p xs)-toInfo (SmoothCurveTo OriginAbsolute xs) = smoothCurveTo xs-toInfo (SmoothCurveTo OriginRelative xs) = do+toPathData (SmoothCurveTo OriginAbsolute xs) = smoothCurveTo xs+toPathData (SmoothCurveTo OriginRelative xs) = do   (PathCursor p _ _) <- get   smoothCurveTo (relToAbs2 p xs)-toInfo (QuadraticBezier OriginAbsolute xs) = quad xs-toInfo (QuadraticBezier OriginRelative xs) = do+toPathData (QuadraticBezier OriginAbsolute xs) = quad xs+toPathData (QuadraticBezier OriginRelative xs) = do   (PathCursor p _ _) <- get   quad (relToAbs2 p xs)-toInfo (SmoothQuadraticBezierCurveTo OriginAbsolute xs) = smoothQuad xs-toInfo (SmoothQuadraticBezierCurveTo OriginRelative xs) = do+toPathData (SmoothQuadraticBezierCurveTo OriginAbsolute xs) = smoothQuad xs+toPathData (SmoothQuadraticBezierCurveTo OriginRelative xs) = do   (PathCursor p _ _) <- get   smoothQuad (relToAbs p xs)-toInfo (EllipticalArc OriginAbsolute xs) = arcTo xs-toInfo (EllipticalArc OriginRelative xs) = do+toPathData (EllipticalArc OriginAbsolute xs) = arcTo xs+toPathData (EllipticalArc OriginRelative xs) = do   (PathCursor p _ _) <- get   arcTo (relToAbsArc p xs)