packages feed

graphviz 2999.14.1.0 → 2999.15.0.0

raw patch · 27 files changed

+2522/−2120 lines, 27 filesdep ~QuickCheckdep ~bytestringPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: QuickCheck, bytestring

API changes (from Hackage documentation)

- Data.GraphViz.Attributes: box, vee, tee, normal, noArrow, inv, dotArrow, diamond, crow :: Arrow
- Data.GraphViz.Attributes: oDot, oDiamond, oBox, invODot, invDot :: Arrow
+ Data.GraphViz: isDotCluster :: GraphvizParams n nl el cl l -> (cl -> Bool)
+ Data.GraphViz.Attributes: Assembly :: Shape
+ Data.GraphViz.Attributes: CDS :: Shape
+ Data.GraphViz.Attributes: FivePovOverhang :: Shape
+ Data.GraphViz.Attributes: Insulator :: Shape
+ Data.GraphViz.Attributes: LArrow :: Shape
+ Data.GraphViz.Attributes: LPromoter :: Shape
+ Data.GraphViz.Attributes: NoOverhang :: Shape
+ Data.GraphViz.Attributes: PrimerSite :: Shape
+ Data.GraphViz.Attributes: Promoter :: Shape
+ Data.GraphViz.Attributes: ProteaseSite :: Shape
+ Data.GraphViz.Attributes: ProteinStab :: Shape
+ Data.GraphViz.Attributes: RArrow :: Shape
+ Data.GraphViz.Attributes: RNAStab :: Shape
+ Data.GraphViz.Attributes: RPromoter :: Shape
+ Data.GraphViz.Attributes: RestrictionSite :: Shape
+ Data.GraphViz.Attributes: Ribosite :: Shape
+ Data.GraphViz.Attributes: Signature :: Shape
+ Data.GraphViz.Attributes: Terminator :: Shape
+ Data.GraphViz.Attributes: ThreePovOverhang :: Shape
+ Data.GraphViz.Attributes: UTR :: Shape
+ Data.GraphViz.Attributes: box :: Arrow
+ Data.GraphViz.Attributes: crow :: Arrow
+ Data.GraphViz.Attributes: diamond :: Arrow
+ Data.GraphViz.Attributes: dotArrow :: Arrow
+ Data.GraphViz.Attributes: inv :: Arrow
+ Data.GraphViz.Attributes: invDot :: Arrow
+ Data.GraphViz.Attributes: invODot :: Arrow
+ Data.GraphViz.Attributes: noArrow :: Arrow
+ Data.GraphViz.Attributes: normal :: Arrow
+ Data.GraphViz.Attributes: oBox :: Arrow
+ Data.GraphViz.Attributes: oDiamond :: Arrow
+ Data.GraphViz.Attributes: oDot :: Arrow
+ Data.GraphViz.Attributes: tee :: Arrow
+ Data.GraphViz.Attributes: vee :: Arrow
+ Data.GraphViz.Attributes.Complete: Assembly :: Shape
+ Data.GraphViz.Attributes.Complete: CDS :: Shape
+ Data.GraphViz.Attributes.Complete: FivePovOverhang :: Shape
+ Data.GraphViz.Attributes.Complete: FontConfigNames :: SVGFontNames
+ Data.GraphViz.Attributes.Complete: GSize :: Double -> Maybe Double -> Bool -> GraphSize
+ Data.GraphViz.Attributes.Complete: Insulator :: Shape
+ Data.GraphViz.Attributes.Complete: LArrow :: Shape
+ Data.GraphViz.Attributes.Complete: LPromoter :: Shape
+ Data.GraphViz.Attributes.Complete: NoOverhang :: Shape
+ Data.GraphViz.Attributes.Complete: PostScriptNames :: SVGFontNames
+ Data.GraphViz.Attributes.Complete: PrimerSite :: Shape
+ Data.GraphViz.Attributes.Complete: Promoter :: Shape
+ Data.GraphViz.Attributes.Complete: ProteaseSite :: Shape
+ Data.GraphViz.Attributes.Complete: ProteinStab :: Shape
+ Data.GraphViz.Attributes.Complete: RArrow :: Shape
+ Data.GraphViz.Attributes.Complete: RNAStab :: Shape
+ Data.GraphViz.Attributes.Complete: RPromoter :: Shape
+ Data.GraphViz.Attributes.Complete: RestrictionSite :: Shape
+ Data.GraphViz.Attributes.Complete: Ribosite :: Shape
+ Data.GraphViz.Attributes.Complete: Signature :: Shape
+ Data.GraphViz.Attributes.Complete: SvgNames :: SVGFontNames
+ Data.GraphViz.Attributes.Complete: Terminator :: Shape
+ Data.GraphViz.Attributes.Complete: ThreePovOverhang :: Shape
+ Data.GraphViz.Attributes.Complete: UTR :: Shape
+ Data.GraphViz.Attributes.Complete: data GraphSize
+ Data.GraphViz.Attributes.Complete: data SVGFontNames
+ Data.GraphViz.Attributes.Complete: desiredSize :: GraphSize -> Bool
+ Data.GraphViz.Attributes.Complete: endPoint :: Spline -> Maybe Point
+ Data.GraphViz.Attributes.Complete: height :: GraphSize -> Maybe Double
+ Data.GraphViz.Attributes.Complete: instance Bounded SVGFontNames
+ Data.GraphViz.Attributes.Complete: instance Enum SVGFontNames
+ Data.GraphViz.Attributes.Complete: instance Eq GraphSize
+ Data.GraphViz.Attributes.Complete: instance Eq SVGFontNames
+ Data.GraphViz.Attributes.Complete: instance Ord GraphSize
+ Data.GraphViz.Attributes.Complete: instance Ord SVGFontNames
+ Data.GraphViz.Attributes.Complete: instance ParseDot GraphSize
+ Data.GraphViz.Attributes.Complete: instance ParseDot SVGFontNames
+ Data.GraphViz.Attributes.Complete: instance PrintDot GraphSize
+ Data.GraphViz.Attributes.Complete: instance PrintDot SVGFontNames
+ Data.GraphViz.Attributes.Complete: instance Read GraphSize
+ Data.GraphViz.Attributes.Complete: instance Read SVGFontNames
+ Data.GraphViz.Attributes.Complete: instance Show GraphSize
+ Data.GraphViz.Attributes.Complete: instance Show SVGFontNames
+ Data.GraphViz.Attributes.Complete: splinePoints :: Spline -> [Point]
+ Data.GraphViz.Attributes.Complete: startPoint :: Spline -> Maybe Point
+ Data.GraphViz.Attributes.Complete: width :: GraphSize -> Double
+ Data.GraphViz.Parsing: ignoreSep :: (a -> b -> c) -> Parse a -> Parse sep -> Parse b -> Parse c
+ Data.GraphViz.Parsing: liftEqParse :: Parse a -> String -> (a -> b) -> Parse b
+ Data.GraphViz.Parsing: liftEqParse' :: ParseDot a => String -> (a -> b) -> Parse b
+ Data.GraphViz.Parsing: parseFieldNumDef :: ParseDot a => (a -> b) -> a -> String -> [(String, Parse b)]
- Data.GraphViz: Params :: Bool -> [GlobalAttributes] -> ((n, nl) -> NodeCluster cl (n, l)) -> (cl -> GraphID) -> (cl -> [GlobalAttributes]) -> ((n, l) -> Attributes) -> ((n, n, el) -> Attributes) -> GraphvizParams n nl el cl l
+ Data.GraphViz: Params :: Bool -> [GlobalAttributes] -> ((n, nl) -> NodeCluster cl (n, l)) -> (cl -> Bool) -> (cl -> GraphID) -> (cl -> [GlobalAttributes]) -> ((n, l) -> Attributes) -> ((n, n, el) -> Attributes) -> GraphvizParams n nl el cl l
- Data.GraphViz.Attributes.Complete: FontNames :: Text -> Attribute
+ Data.GraphViz.Attributes.Complete: FontNames :: SVGFontNames -> Attribute
- Data.GraphViz.Attributes.Complete: Size :: Point -> Attribute
+ Data.GraphViz.Attributes.Complete: Size :: GraphSize -> Attribute
- Data.GraphViz.Attributes.Complete: Spline :: (Maybe Point) -> (Maybe Point) -> [Point] -> Spline
+ Data.GraphViz.Attributes.Complete: Spline :: Maybe Point -> Maybe Point -> [Point] -> Spline
- Data.GraphViz.Parsing: class ParseDot a where parse = optionalQuoted parseUnqt parseUnqtList = bracketSep (parseAndSpace $ character '[') (wrapWhitespace parseComma `onFail` whitespace1) (whitespace >> character ']') parseUnqt parseList = quotedParse parseUnqtList
+ Data.GraphViz.Parsing: class ParseDot a where parse = optionalQuoted parseUnqt parseUnqtList = bracketSep (parseAndSpace $ character '[') (wrapWhitespace parseComma `onFail` whitespace1) (whitespace *> character ']') parseUnqt parseList = quotedParse parseUnqtList
- Data.GraphViz.Types: class ParseDot a where parse = optionalQuoted parseUnqt parseUnqtList = bracketSep (parseAndSpace $ character '[') (wrapWhitespace parseComma `onFail` whitespace1) (whitespace >> character ']') parseUnqt parseList = quotedParse parseUnqtList
+ Data.GraphViz.Types: class ParseDot a where parse = optionalQuoted parseUnqt parseUnqtList = bracketSep (parseAndSpace $ character '[') (wrapWhitespace parseComma `onFail` whitespace1) (whitespace *> character ']') parseUnqt parseList = quotedParse parseUnqtList
- Data.GraphViz.Types.Graph: Cntxt :: !n -> !Maybe GraphID -> !Attributes -> ![(n, Attributes)] -> ![(n, Attributes)] -> Context n
+ Data.GraphViz.Types.Graph: Cntxt :: !n -> !(Maybe GraphID) -> !Attributes -> ![(n, Attributes)] -> ![(n, Attributes)] -> Context n
- Data.GraphViz.Types.Graph: inCluster :: Context n -> !Maybe GraphID
+ Data.GraphViz.Types.Graph: inCluster :: Context n -> !(Maybe GraphID)

Files

− Changelog
@@ -1,637 +0,0 @@-% Changelog-% Ivan Lazar Miljenovic--Release History and Changelog-=============================--The following is information about what major changes have gone into-each release.--Changes in 2999.14.1.0-------------------------* Add `isGraphvizInstalled` and `quitWithoutGraphviz` for programs to-  test whether Graphviz has been installed (as previous attempts at-  doing so via actual calls to dot, neato, etc. weren't working and-  would be too verbose anyway).--Changes in 2999.14.0.0-------------------------* Added an instance of `Labellable` for strict `Text` values, as-  requested by **Erik Rantapaa**.--Changes in 2999.13.0.3-------------------------* Allow usage of transformers-0.3.*.  Spotted by **Peter Simons**.--Changes in 2999.13.0.2-------------------------* The `String` instance for `ToGraphID` requires the-  `TypeSynonymInstances` pragma (at least on GHC < 7.4).  Spotted by-  **Gregory Guthrie**.--Changes in 2999.13.0.1-------------------------* Fixed Haddock typos.--Changes in 2999.13.0.0-------------------------* Added support for the `osage` and `patchwork` visualisation tools,-  available as of Graphviz-2.28.0.--* Updated attributes as of Graphviz-2.28.0:--    - `SVG` colors are now supported, and the support for different-      colors has been revamped.--    - `overlap=false` is now equivalent to `overlap=prism` and the-      `RemoveOverlaps` option has been removed.--    - `LabelScheme` and `Rotation` are new attributes for use with-      `sfdp`.--    - `Scale` is a new attribute for use with `twopi`.--    - Add new italics, bold, underline, superscript and subscript-      options for HTML-like labels.--    - `LHeight` and `LWidth` for getting the height and width of the-      root graph and clusters.--* Updated attributes from the current development branch of Graphviz-  (i.e. 2.29.*).  Please note that these will probably not work yet,-  but are implemented now for future-proofing.--    - A new style for edges: `Tapered`.--    - `XLabel` allows you to specify labels external to a node or-      edge.  `ForceLabels` allow you to specify that these should be-      drawn even when they will cause overlaps.--    - `ImagePath` allows you to specify where to search for images.--    - HTML-like labels now support `ID` values as well as horizontal-      and vertical rules.--    - `BgColor` and `FillColor` now take a list of colors: this allows-      gradient fills for graphs, clusters and nodes.  The `Radial`-      style and `GradientAngle` are also used for this purpose.--    - `FillColor` is now used by edges to set the color of any arrows.--    - [WebP](http://en.wikipedia.org/wiki/WebP) output support added.--* Other attribute changes:--    - Use a specified data type for the `Ordering` attribute rather-      than an arbitrary `Text` value, and provide a documented wrapper-      in `Data.GraphViz.Attributes`.--    - `Bb` has been renamed `BoundingBox`.--    - `ID` now only takes `EscString` (a type alias for `Text`) values-      rather than arbitrary `Label`s.--    - The `Data.GraphViz.Attributes.HTML` module has had all values-      re-named and is now meant to be imported qualified.  It is also-      no longer re-exported from `Data.GraphViz.Attributes.Complete`.--* The `ToGraphID` class provides a common wrapper to help create-  cluster identifiers, etc.--* Cabal's `Test-Suite` functionality is now used.  As part of this,-  the `Data.GraphViz.Testing` module and sub-modules are no longer-  exported by the library.--* The new `Benchmark` support in Cabal-1.14 is now used for the-  benchmark script.--* Dropped support for base-3.--* The `Data.GraphViz.State` module is no longer exposed, as there's no-  need for users to use it.--* Bugfixes:--    - Some corner cases in canonicalisation prevented it from being-      idempotent.--    - The `TestParsing` script will no longer crash and refuse to-      continue if an IO-based error (e.g. unable to successfully call-      `dot`) occurs.--    - A typo was spotted by **Gabor Greif**.--Changes in 2999.12.0.4-------------------------* Parsing error messages have been cleared up, especially when parsing-  Dot graphs.  This came about from trying to help **Uri J. Braun**-  with an error in his code (which took a while to diagnose as a-  problem with the node type).--* Made more clear to people looking in `Data.GraphViz` who want to-  create Dot graphs by hand to look in `Data.GraphViz.Types` (came-  about when **Rustom Mody** stated he got confused trying to work out-  how to do this).--* Fixed up augmentation; bug and fix spotted by **Max Rabkin**.--* Fix up the TestParsing script to actually use the new type setup.-  It can also now take a single directory as an argument, and will try-  to parse all (non-recursive) files in that directory.--Changes in 2999.12.0.3-------------------------* Fixes various mistakes in the Haddock documentation that slipped-  through (either in the `String -> Text` conversion or adding new-  modules and not checking their documentation thoroughly enough).--Changes in 2999.12.0.2-------------------------* Forgot to explicitly list the module for Arbitrary instance for the-  graph representation.--Changes in 2999.12.0.1-------------------------* Fix a bug that prevented graphviz from being built with GHC 7.2.--Changes in 2999.12.0.0-------------------------Many large-level changes were done in this release; in rough-categories these are:--### Conversions from other types--* Can now more easily create Dot graphs from other graph-like data-  structures with the new `graphElemsToDot` function, which takes a-  list of nodes and edges.--* It is now no longer possible to use `graphToDot`, etc. to create Dot-  graphs with anonymous clusters; all clusters must now have explicit-  names (note that uniqueness is not enforced, and it is still-  possible to directly create Dot graphs with anonymous clusters).--### Dot graph representations--* The canonical graph representation has been moved to its own module:-  `Data.GraphViz.Types.Canonical`.--* The generalised representation has had all its "G" and "g" prefixes-  removed.--* Two new representations:--    - `Data.GraphViz.Types.Graph` allows graph-like manipulation of-      Dot code.--    - `Data.GraphViz.Types.Monadic` provides a monadic interface into-      building relatively static graphs, based upon the-      [_dotgen_](http://hackage.haskell.org/package/dotgen) library by-      Andy Gill.--* The `DotRepr` class has been expanded, and three pseudo-classes have-  been provided to reduce type-class contexts in type signatures.--### Using and manipulation Dot graphs--* Pure Haskell implementations of `dot -Tcanon` and `tred` are-  available in `Data.GraphViz.Algorithms`.--* A new module is available for more direct low-level I/O with Dot-  graphs, including the ability to run custom commands as opposed to-  being limited to the standard dot, neato, etc.--### Attributes--* `Data.GraphViz.Attributes` now contains a slimmed-down recommended-  list of attributes; the complete list can still be found in-  `Data.GraphViz.Attributes.Complete`.--* The `charset` attribute is no longer available.--* Functions for specifying custom attributes (for pre-processors,-  etc.) are available.--### Implementation--* Now uses [`Text`](http://hackage.haskell.org/package/text) values-  rather than `String`s.  Whilst performing this migration, the-  improvements in speed for both printing and parsing improved-  dramatically.--    - As part of this, human-readable Dot code is now produced by-      default.  As such, the `prettyPrint` and `prettyPrint'`-      functions have been removed.--* Now uses state-based printing and parsing, so that things like graph-  directedness, layer separators and color schemes can be taken into-  account.--* Parsing large data-types (e.g. `Attributes`) now uses less-  back-tracking.--* Now has a benchmarking script for testing printing and parsing-  speed.--* Uses a custom exception type rather than a mish-mash of error,-  `Maybe`, `Either`, exception types from used libraries, etc.--* Usage of UTF-8 is now enforced when doing I/O.  If another encoding-  is required, the `Text` value that's printed/parsed has to be-  written/read from disk/network/etc. manually.--### Bug-Fixes--* The `Rects` `Attribute` should be able to take a list of `Rect`-  values; error spotted by **Henning Gunther**.--* In some cases, global attribute names were being printed without-  even an empty list (which doesn't match what dot, etc. expect).--Changes in 2999.11.0.0-------------------------* Addition of the `Labellable` class (and its method `toLabel`) to-  make it easier to construct labels.--* Backslashes (i.e. the `\` character) are now escaped/unescaped-  properly (bug spotted by **Han Joosten**).  As part of this:--    - Dot-specific escapes such as `\N` are now also handled-      correctly, so the slash does not need to be escaped.--    - Newline (`'\n'`) characters in labels, etc. are escaped to-      centred-newlines in Dot code, but not unescaped.--* `Point` values can now have the optional third dimension and end in-  a `!` to indicate that that position should be used (as input to-  Graphviz).--* `LayerList` uses `LayerID` values, and now has a proper `shrink`-  implementation in the test suite.--Changes in 2999.10.0.1-------------------------* Fixed a mistake in one of the source files that was made just to-  make-  [haskell-src-exts](http://hackage.haskell.org/package/haskell-src-exts)-  happier.--* Fix the `Arbitrary` instance for `Point` in the testsuite (since-  there's only one constructor now).--Changes in 2999.10.0.0-------------------------* Conversion of `FGL`-style graphs to `DotRepr` values is now achieved-  using the new `GraphvizParams` configuration type.  This allows us-  to define a single parameter that stores all the conversion-  functions to pass around rather than having to pass around several-  functions.  This also allows all the non-clustered and clustered-  functions to be collapsed together, whereas what used to be handled-  by the primed functions is now achieved by using the-  `setDirectedness` function.--    There are three default `GraphvizParams` available:--    - `defaultParams` provides some sensible defaults (no attributes-      or clustering).--    - `nonClusteredParams` is an alias of `defaultParams` where the-      clustering type is explicitly set to be `()` for cases where you-      don't want any clustering at all (whereas `defaultParams` allows-      you to set your own clustering functions).--    - `blankParams` sets all fields to be `undefined`; this is useful-      for situations where you have functions that will set some-      values for you and there is no sensible default you can use-      (mainly for the clustering function).--* Expansion of the `DotRepr` class:--    - More common functions are now defined as methods (`getID`,-      etc.).--    - The ability to get more information about the structure of the-      `DotRepr` graph, as well as where all the `DotNode`s are, etc.--    - `graphNodes` now returns `DotNode`s defined only as part of-      `DotEdge`s, and will also merge duplicate `DotNode`s together.--    - `graphNodes` and `graphEdges` also return `GlobalAttributes`-      that apply to them.--* The `Point` type now only has one constructor: `Point Double-  Double`.  The `Int`-only constructor was present due to historical-  purposes and I thought that the `Pos` value for a `DotNode` would-  always be a pair of `Int`s; this turns out not to be the case.--* `SortV` and `PrismOverlap` now only take `Word16` values rather than-  `Int`s, as they're not meant to allow negative values (the choice of-  using `Word16` rather than `Word` was arbitrary, and because it's-  unlikely those values will be large enough to require the larger-  values available in `Word`).--* `NodeCluster` has been generalised to not have to take an `LNode`-  for the node type; the type alias `LNodeCluster` is available if you-  still want this.--* Several documentation typos fixed, including one spotted by **Kevin-  Quick**.--* The test-suite now allows running individual tests.--Changes in 2999.9.0.0------------------------* graphviz now has an FAQ and an improved README as well as its own-  [homepage](http://projects.haskell.org/graphviz/).--* Canonicalisation of `DotRepr` values is now available with the-  `canonicalise` function.--* Add support for record labels; values are automatically-  escaped/unescaped.  The `Record` and `MRecord` shapes have been-  added for use with these labels.  **Requested by Minh Thu and Eric-  Kow.**--* Add support for HTML-like values (this replaces the wrong and-  completely broken URL datatype).  Strings are automatically-  escaped/unescaped.--* Named `PortPos` values are now accepted (as required for record and-  HTML-like labels).--* `GraphID` no longer allows HTML-like values (since Graphviz doesn't-  seem to allow it).--* `RankSep` takes a list of `Double` values as required.--* `Attribute` has a new constructor `UnknownAttribute` for use when-  parsing deprecated Graphviz attributes in old Dot code.--* Various parsing fixes; of special note:--    - Statements no longer need to end in a semi-colon;--    - Anonymous sub-graphs are now supported.--    - Edge statements can now handle node groupings (e.g. ` a -> {b-      c}`) as well as `portPos` values (e.g. `a:from -> b:to`).--    - Unquoted `String`s containing non-ASCII characters are now-      parsed properly (though they are assumed to be encoded with-      UTF-8).  **Thanks to Jules Bean (aka quicksilver) for working-      out how to do this.**--    More specifically: almost all Dot files that ship with Graphviz, as-    documentation in the Linux kernel, etc. are now parseable.--* A new script to assist in testing whether "real-world" Dot graphs-  are parseable.--* Slight performance increase when parsing: whereas parsing is done-  case-insensitively, the "correct" case is now checked by default-  which has a moderate affect on parsing times.--* Split lines are now able to be handled when parsing.--Changes in 2999.8.0.0------------------------* Added support for generalised `DotGraph`s; this optional-  representation removes the restriction of ordering of Dot-  statements.  This allows for greater flexibility of how to specify-  Dot code.  As an offshoot from this, most relevant functions now-  utilise a new `DotRepr` class that work with both `DotGraph`s and-  the new `GDotGraph`s; this shouldn't affect any code already in use.--* With the **prompting of Noam Lewis**, the augmentation functions-  have been revamped in two ways:--  - Now contains support for multiple edges.--  - The ability to perform "manual" augmentation if greater control is-    desired.--* Add a preview function to quickly render and visualise an `FGL`-  graph using the `Xlib` canvas.--* Added a pseudo-inverse of the `FGL -> Dot` functions (a graph is-  created, but the original node and edge labels are unrecoverable).--* The `Printing` and `Parsing` modules have been moved (from-  `Data.GraphViz.Types` to `Data.GraphViz`).--* Reworked file-generating commands such that they return the filename-  of the created file if successful.--Changes in 2999.7.0.0------------------------* Updated and extended functions to interact with the Graphviz tools.-  This now includes:--  - a better listing of available output types;--  - distinguishing file outputs from canvas outputs;--  - ability to automatically add the correct file extension to file-    outputs--  - Return any errors if calling Graphviz failed rather than just-    printing them to stderr--* Improved `Color` support:--  - fixed `ColorScheme` values--  - explicitly named `X11` colors--  - conversion to/from values from the [colour] library--  [colour]: http://www.haskell.org/haskellwiki/Colour--* Removed `OrientationGraph`; problems with distinguishing it when-  parsing from node-based `Orientation` values; its functionality is-  duplicated by `Rotate`.--* By default, the generated Dot code is now no longer indented; you-  can now use the `prettyPrint` functions in `Data.GraphViz` to-  produce readable Dot code.--* Added a testsuite; this is buildable by building with-  `--flags-test`.  Numerous printing and parsing bugs were picked up-  with this.--Changes in 2999.6.0.0------------------------* Remove some `Shape` aliases and change capitalisation of others.--* Properly parse and print IDs of clusters.--* Allow `NodeCluster` values to have node types different from the-  `LNode` they come from.--Changes in 2999.5.1.1------------------------* When used as labels, etc., the Dot keywords `node`, `edge`, `graph`,-  `digraph`, `subgraph`, and `strict` need to be quoted.  **Spotted by-  Kathleen Fisher.**--Changes in 2999.5.1.0------------------------* Potentially fixed the `graphvizWithHandle` bug; correct approach-  **spotted by Nikolas Mayr**.--* Fixed up `Parsing` of various `Attribute` sub-values, especially-  `Point` and `Spline` (and hence `Pos`, which uses them).--* Pre-process out comments and join together multi-line strings before-  parsing.--* Properly parse `Doubles` like `".2"`.--Changes in 2999.5.0.0------------------------A major re-write occured; these are the highlights:--* Re-write parsing and printing of Dot code using the new `ParseDot`-  and `PrintDot` classes.  This should finally fix all quoting issues,-  as well as leaving `Show` as the code representation for hacking-  purposes.  As part of this, the `Data.GraphViz.ParserCombinators`-  module has been moved to `Data.GraphViz.Types.Parsing`.--* Re-write the various `Dot*` datatypes in `Data.GraphViz.Types`.-  Sub-graphs/clusters are now their own entity rather than being part-  of `DotNode` and the Node ID type is now a type parameter rather-  than being just `Int`.  Sub-graphs/clusters can now also be parsed.--* The various conversion functions in `Data.GraphViz` now come in two-  flavours: the unprimed versions take in a `Bool` indicating if the-  graph is directed or not; the primed versions attempt to-  automatically detect this.--* Add cluster support for the graph augmentation functions, **as-  requested by Nikolas Mayr**.--* Allow custom arrow types as supported by GraphViz; **as requested by-  Han Joosten**.--* Fixed a bug in HSV-style `Color` values where `Int` was used instead of-  `Double`; **spotted by Michael deLorimier**.--* Properly resolved the situation initially spotted by Neil Brown:-  Matthew Sackman was following Dot terminology for an edge `a -> b`-  when using _head_ for `b` and _tail_ for `a` (this is presumably-  because the head/tail of the arrow are at those nodes).  `DotEdge`-  now uses _from_ and _to_ avoid ambiguity; the various `Attribute`-  values still follow upstream usage.--Changes in 2999.1.0.2------------------------* Fix a bug **spotted by Srihari Ramanathan** where `Color` values-  were double-quoted.--Changes in 2999.1.0.1------------------------* The `Color` `Attribute` should take `[Color]`, not just a single-  `Color`.--Changes in 2999.1.0.0------------------------* Stop using `Either` for composite `Attributes` and use a custom-  type: this avoids problems with the `Show` instance.--Changes in 2999.0.0.0------------------------* Fixed a bug where the Show instance and read function for `DotEdge`-  had the from/to nodes the wrong way round.  This was not immediately-  noticed since the `Graph` to `DotGraph` functions created them the-  wrong way round, so for those users who only used these this was not-  apparent.  **Spotted by Neil Brown.**--* Greatly improved `Attribute` usage: almost all attributes are now-  covered with allowed values.--* Extend DotGraph to include whether a graph is strict or not and if-  it has an ID.  Also move the directedGraph field.--* Make `Dot` refer to the actual dot command and `DotArrow` refer to-  the `ArrowType` (rather than `DotCmd` and `Dot` as before).--* Make the `Data.GraphViz.ParserCombinators` module available to end-  users again, but not re-exported by `Data.GraphViz`; it has a-  warning message up the top not to be used.  It is there purely for-  documentative purposes.--* Use [extensible-exceptions] so that `base-3.x` is once again-  supported.--  [extensible-exceptions]: http://hackage.haskell.org/package/extensible-exceptions--* Follow the [Package Versioning Policy] rather than using dates for-  versions.--  [Package Versioning Policy]: http://www.haskell.org/haskellwiki/Package_versioning_policy---Changes in 2009.5.1----------------------* New maintainer: Ivan Lazar Miljenovic.--* Support `polyparse >= 1.1` (as opposed to `< 1.3`)--* Require `base == 4.*` (i.e. `GHC 6.10.*`) due to new exception handling.--* Include functions from [Graphalyze-0.5] for running GraphViz-  commands, etc.--  [Graphalyze-0.5]: http://hackage.haskell.org/package/Graphalyze-0.5--* Module re-organisation.--* The `Data.GraphViz.ParserCombinators` module is no longer available-  to end users.--* Improved Haddock documentation.--Changes in 2008.9.20-----------------------* Differentiate between undirected and directed graphs (previously-  only directed graphs were supported).--* Clustering support was added.--Older versions-----------------For versions of graphviz older than `2008.9.20`, the exact differences-between versions is unknown.--<!---     Local Variables:-     mode:markdown-     End:-  -->
+ Changelog.md view
@@ -0,0 +1,687 @@+% Changelog+% Ivan Lazar Miljenovic++Release History and Changelog+=============================++The following is information about what major changes have gone into+each release.++Changes in 2999.15.0.0+----------------------++* The repository is now hosted on+  [hub.darcs.net](http://hub.darcs.net/ivanm/graphviz), and using the+  bug-tracker there.++* Updates to various `Attribute` definitions:++    - The list of available shapes has been expanded to take into+      account the new synthetic biology shapes.++    - The `Size` and `FontNames` attributes now have specified data types.++    - The optional start and end points for `Spline`s were previously+      the wrong way round; this has now been fixed.++    - Explicitly only print 2-dimensional `Point` values for `Rect`+      and `DPoint` (previously only 2-dimensional values where parsed,+      but it was possible to print a 3-dimensional value).++    - HTML-like labels previously disallowed empty textual label+      components when parsing; spotted by **Daniel Hummel**.++* `GraphvizParams` now lets you specify whether a "cluster" is+  actually a cluster or a sub-graph.  Requested by **Gabor Greif**.++* Fixed an error where printing edges whose attributes contained a+  `ColorScheme` attribute, that attribute would stay in the state and+  the old color scheme would override the _parent's_ state.++* Previously, some malformed attributes were accepted when being+  parsed as they silently became parsed as an `UnknownAttribute`.+  Now, attributes where the attribute name and the equal sign are+  successfully parsed **but** the value of the attribute is _not_+  successfully parse will throw an unrecoverable error.++    **Note**: this does mean that some Dot graphs that are accepted by+    Graphviz (as they separate tokenizing from parsing; as such+    something like `"0.1"` is successfully accepted as an integer,+    specifically `0`) are no longer accepted when parsing them in.++* Miscellaneous parsing improvements:++    - Whilst not specified anywhere, Graphviz seems to treat empty+      quotes as values for attributes expecting a number as their+      default; as such, this is now taken into account when parsing.++    - `DPoint` values can now parse an optional `+` prefix.++    - Whitespaces after commas in HSV colors are now accepted.++* Error messages from parsing are improved to help you track down+  where the parsing error occurred (in that it's easier to find which+  attribute failed to parse, etc.).++Changes in 2999.14.1.0+----------------------++* Add `isGraphvizInstalled` and `quitWithoutGraphviz` for programs to+  test whether Graphviz has been installed (as previous attempts at+  doing so via actual calls to dot, neato, etc. weren't working and+  would be too verbose anyway).++Changes in 2999.14.0.0+----------------------++* Added an instance of `Labellable` for strict `Text` values, as+  requested by **Erik Rantapaa**.++Changes in 2999.13.0.3+----------------------++* Allow usage of transformers-0.3.*.  Spotted by **Peter Simons**.++Changes in 2999.13.0.2+----------------------++* The `String` instance for `ToGraphID` requires the+  `TypeSynonymInstances` pragma (at least on GHC < 7.4).  Spotted by+  **Gregory Guthrie**.++Changes in 2999.13.0.1+----------------------++* Fixed Haddock typos.++Changes in 2999.13.0.0+----------------------++* Added support for the `osage` and `patchwork` visualisation tools,+  available as of Graphviz-2.28.0.++* Updated attributes as of Graphviz-2.28.0:++    - `SVG` colors are now supported, and the support for different+      colors has been revamped.++    - `overlap=false` is now equivalent to `overlap=prism` and the+      `RemoveOverlaps` option has been removed.++    - `LabelScheme` and `Rotation` are new attributes for use with+      `sfdp`.++    - `Scale` is a new attribute for use with `twopi`.++    - Add new italics, bold, underline, superscript and subscript+      options for HTML-like labels.++    - `LHeight` and `LWidth` for getting the height and width of the+      root graph and clusters.++* Updated attributes from the current development branch of Graphviz+  (i.e. 2.29.*).  Please note that these will probably not work yet,+  but are implemented now for future-proofing.++    - A new style for edges: `Tapered`.++    - `XLabel` allows you to specify labels external to a node or+      edge.  `ForceLabels` allow you to specify that these should be+      drawn even when they will cause overlaps.++    - `ImagePath` allows you to specify where to search for images.++    - HTML-like labels now support `ID` values as well as horizontal+      and vertical rules.++    - `BgColor` and `FillColor` now take a list of colors: this allows+      gradient fills for graphs, clusters and nodes.  The `Radial`+      style and `GradientAngle` are also used for this purpose.++    - `FillColor` is now used by edges to set the color of any arrows.++    - [WebP](http://en.wikipedia.org/wiki/WebP) output support added.++* Other attribute changes:++    - Use a specified data type for the `Ordering` attribute rather+      than an arbitrary `Text` value, and provide a documented wrapper+      in `Data.GraphViz.Attributes`.++    - `Bb` has been renamed `BoundingBox`.++    - `ID` now only takes `EscString` (a type alias for `Text`) values+      rather than arbitrary `Label`s.++    - The `Data.GraphViz.Attributes.HTML` module has had all values+      re-named and is now meant to be imported qualified.  It is also+      no longer re-exported from `Data.GraphViz.Attributes.Complete`.++* The `ToGraphID` class provides a common wrapper to help create+  cluster identifiers, etc.++* Cabal's `Test-Suite` functionality is now used.  As part of this,+  the `Data.GraphViz.Testing` module and sub-modules are no longer+  exported by the library.++* The new `Benchmark` support in Cabal-1.14 is now used for the+  benchmark script.++* Dropped support for base-3.++* The `Data.GraphViz.State` module is no longer exposed, as there's no+  need for users to use it.++* Bugfixes:++    - Some corner cases in canonicalisation prevented it from being+      idempotent.++    - The `TestParsing` script will no longer crash and refuse to+      continue if an IO-based error (e.g. unable to successfully call+      `dot`) occurs.++    - A typo was spotted by **Gabor Greif**.++Changes in 2999.12.0.4+----------------------++* Parsing error messages have been cleared up, especially when parsing+  Dot graphs.  This came about from trying to help **Uri J. Braun**+  with an error in his code (which took a while to diagnose as a+  problem with the node type).++* Made more clear to people looking in `Data.GraphViz` who want to+  create Dot graphs by hand to look in `Data.GraphViz.Types` (came+  about when **Rustom Mody** stated he got confused trying to work out+  how to do this).++* Fixed up augmentation; bug and fix spotted by **Max Rabkin**.++* Fix up the TestParsing script to actually use the new type setup.+  It can also now take a single directory as an argument, and will try+  to parse all (non-recursive) files in that directory.++Changes in 2999.12.0.3+----------------------++* Fixes various mistakes in the Haddock documentation that slipped+  through (either in the `String -> Text` conversion or adding new+  modules and not checking their documentation thoroughly enough).++Changes in 2999.12.0.2+----------------------++* Forgot to explicitly list the module for Arbitrary instance for the+  graph representation.++Changes in 2999.12.0.1+----------------------++* Fix a bug that prevented graphviz from being built with GHC 7.2.++Changes in 2999.12.0.0+----------------------++Many large-level changes were done in this release; in rough+categories these are:++### Conversions from other types++* Can now more easily create Dot graphs from other graph-like data+  structures with the new `graphElemsToDot` function, which takes a+  list of nodes and edges.++* It is now no longer possible to use `graphToDot`, etc. to create Dot+  graphs with anonymous clusters; all clusters must now have explicit+  names (note that uniqueness is not enforced, and it is still+  possible to directly create Dot graphs with anonymous clusters).++### Dot graph representations++* The canonical graph representation has been moved to its own module:+  `Data.GraphViz.Types.Canonical`.++* The generalised representation has had all its "G" and "g" prefixes+  removed.++* Two new representations:++    - `Data.GraphViz.Types.Graph` allows graph-like manipulation of+      Dot code.++    - `Data.GraphViz.Types.Monadic` provides a monadic interface into+      building relatively static graphs, based upon the+      [_dotgen_](http://hackage.haskell.org/package/dotgen) library by+      Andy Gill.++* The `DotRepr` class has been expanded, and three pseudo-classes have+  been provided to reduce type-class contexts in type signatures.++### Using and manipulation Dot graphs++* Pure Haskell implementations of `dot -Tcanon` and `tred` are+  available in `Data.GraphViz.Algorithms`.++* A new module is available for more direct low-level I/O with Dot+  graphs, including the ability to run custom commands as opposed to+  being limited to the standard dot, neato, etc.++### Attributes++* `Data.GraphViz.Attributes` now contains a slimmed-down recommended+  list of attributes; the complete list can still be found in+  `Data.GraphViz.Attributes.Complete`.++* The `charset` attribute is no longer available.++* Functions for specifying custom attributes (for pre-processors,+  etc.) are available.++### Implementation++* Now uses [`Text`](http://hackage.haskell.org/package/text) values+  rather than `String`s.  Whilst performing this migration, the+  improvements in speed for both printing and parsing improved+  dramatically.++    - As part of this, human-readable Dot code is now produced by+      default.  As such, the `prettyPrint` and `prettyPrint'`+      functions have been removed.++* Now uses state-based printing and parsing, so that things like graph+  directedness, layer separators and color schemes can be taken into+  account.++* Parsing large data-types (e.g. `Attributes`) now uses less+  back-tracking.++* Now has a benchmarking script for testing printing and parsing+  speed.++* Uses a custom exception type rather than a mish-mash of error,+  `Maybe`, `Either`, exception types from used libraries, etc.++* Usage of UTF-8 is now enforced when doing I/O.  If another encoding+  is required, the `Text` value that's printed/parsed has to be+  written/read from disk/network/etc. manually.++### Bug-Fixes++* The `Rects` `Attribute` should be able to take a list of `Rect`+  values; error spotted by **Henning Gunther**.++* In some cases, global attribute names were being printed without+  even an empty list (which doesn't match what dot, etc. expect).++Changes in 2999.11.0.0+----------------------++* Addition of the `Labellable` class (and its method `toLabel`) to+  make it easier to construct labels.++* Backslashes (i.e. the `\` character) are now escaped/unescaped+  properly (bug spotted by **Han Joosten**).  As part of this:++    - Dot-specific escapes such as `\N` are now also handled+      correctly, so the slash does not need to be escaped.++    - Newline (`'\n'`) characters in labels, etc. are escaped to+      centred-newlines in Dot code, but not unescaped.++* `Point` values can now have the optional third dimension and end in+  a `!` to indicate that that position should be used (as input to+  Graphviz).++* `LayerList` uses `LayerID` values, and now has a proper `shrink`+  implementation in the test suite.++Changes in 2999.10.0.1+----------------------++* Fixed a mistake in one of the source files that was made just to+  make+  [haskell-src-exts](http://hackage.haskell.org/package/haskell-src-exts)+  happier.++* Fix the `Arbitrary` instance for `Point` in the testsuite (since+  there's only one constructor now).++Changes in 2999.10.0.0+----------------------++* Conversion of `FGL`-style graphs to `DotRepr` values is now achieved+  using the new `GraphvizParams` configuration type.  This allows us+  to define a single parameter that stores all the conversion+  functions to pass around rather than having to pass around several+  functions.  This also allows all the non-clustered and clustered+  functions to be collapsed together, whereas what used to be handled+  by the primed functions is now achieved by using the+  `setDirectedness` function.++    There are three default `GraphvizParams` available:++    - `defaultParams` provides some sensible defaults (no attributes+      or clustering).++    - `nonClusteredParams` is an alias of `defaultParams` where the+      clustering type is explicitly set to be `()` for cases where you+      don't want any clustering at all (whereas `defaultParams` allows+      you to set your own clustering functions).++    - `blankParams` sets all fields to be `undefined`; this is useful+      for situations where you have functions that will set some+      values for you and there is no sensible default you can use+      (mainly for the clustering function).++* Expansion of the `DotRepr` class:++    - More common functions are now defined as methods (`getID`,+      etc.).++    - The ability to get more information about the structure of the+      `DotRepr` graph, as well as where all the `DotNode`s are, etc.++    - `graphNodes` now returns `DotNode`s defined only as part of+      `DotEdge`s, and will also merge duplicate `DotNode`s together.++    - `graphNodes` and `graphEdges` also return `GlobalAttributes`+      that apply to them.++* The `Point` type now only has one constructor: `Point Double+  Double`.  The `Int`-only constructor was present due to historical+  purposes and I thought that the `Pos` value for a `DotNode` would+  always be a pair of `Int`s; this turns out not to be the case.++* `SortV` and `PrismOverlap` now only take `Word16` values rather than+  `Int`s, as they're not meant to allow negative values (the choice of+  using `Word16` rather than `Word` was arbitrary, and because it's+  unlikely those values will be large enough to require the larger+  values available in `Word`).++* `NodeCluster` has been generalised to not have to take an `LNode`+  for the node type; the type alias `LNodeCluster` is available if you+  still want this.++* Several documentation typos fixed, including one spotted by **Kevin+  Quick**.++* The test-suite now allows running individual tests.++Changes in 2999.9.0.0+---------------------++* graphviz now has an FAQ and an improved README as well as its own+  [homepage](http://projects.haskell.org/graphviz/).++* Canonicalisation of `DotRepr` values is now available with the+  `canonicalise` function.++* Add support for record labels; values are automatically+  escaped/unescaped.  The `Record` and `MRecord` shapes have been+  added for use with these labels.  **Requested by Minh Thu and Eric+  Kow.**++* Add support for HTML-like values (this replaces the wrong and+  completely broken URL datatype).  Strings are automatically+  escaped/unescaped.++* Named `PortPos` values are now accepted (as required for record and+  HTML-like labels).++* `GraphID` no longer allows HTML-like values (since Graphviz doesn't+  seem to allow it).++* `RankSep` takes a list of `Double` values as required.++* `Attribute` has a new constructor `UnknownAttribute` for use when+  parsing deprecated Graphviz attributes in old Dot code.++* Various parsing fixes; of special note:++    - Statements no longer need to end in a semi-colon;++    - Anonymous sub-graphs are now supported.++    - Edge statements can now handle node groupings (e.g. ` a -> {b+      c}`) as well as `portPos` values (e.g. `a:from -> b:to`).++    - Unquoted `String`s containing non-ASCII characters are now+      parsed properly (though they are assumed to be encoded with+      UTF-8).  **Thanks to Jules Bean (aka quicksilver) for working+      out how to do this.**++    More specifically: almost all Dot files that ship with Graphviz, as+    documentation in the Linux kernel, etc. are now parseable.++* A new script to assist in testing whether "real-world" Dot graphs+  are parseable.++* Slight performance increase when parsing: whereas parsing is done+  case-insensitively, the "correct" case is now checked by default+  which has a moderate affect on parsing times.++* Split lines are now able to be handled when parsing.++Changes in 2999.8.0.0+---------------------++* Added support for generalised `DotGraph`s; this optional+  representation removes the restriction of ordering of Dot+  statements.  This allows for greater flexibility of how to specify+  Dot code.  As an offshoot from this, most relevant functions now+  utilise a new `DotRepr` class that work with both `DotGraph`s and+  the new `GDotGraph`s; this shouldn't affect any code already in use.++* With the **prompting of Noam Lewis**, the augmentation functions+  have been revamped in two ways:++  - Now contains support for multiple edges.++  - The ability to perform "manual" augmentation if greater control is+    desired.++* Add a preview function to quickly render and visualise an `FGL`+  graph using the `Xlib` canvas.++* Added a pseudo-inverse of the `FGL -> Dot` functions (a graph is+  created, but the original node and edge labels are unrecoverable).++* The `Printing` and `Parsing` modules have been moved (from+  `Data.GraphViz.Types` to `Data.GraphViz`).++* Reworked file-generating commands such that they return the filename+  of the created file if successful.++Changes in 2999.7.0.0+---------------------++* Updated and extended functions to interact with the Graphviz tools.+  This now includes:++  - a better listing of available output types;++  - distinguishing file outputs from canvas outputs;++  - ability to automatically add the correct file extension to file+    outputs++  - Return any errors if calling Graphviz failed rather than just+    printing them to stderr++* Improved `Color` support:++  - fixed `ColorScheme` values++  - explicitly named `X11` colors++  - conversion to/from values from the [colour] library++  [colour]: http://www.haskell.org/haskellwiki/Colour++* Removed `OrientationGraph`; problems with distinguishing it when+  parsing from node-based `Orientation` values; its functionality is+  duplicated by `Rotate`.++* By default, the generated Dot code is now no longer indented; you+  can now use the `prettyPrint` functions in `Data.GraphViz` to+  produce readable Dot code.++* Added a testsuite; this is buildable by building with+  `--flags-test`.  Numerous printing and parsing bugs were picked up+  with this.++Changes in 2999.6.0.0+---------------------++* Remove some `Shape` aliases and change capitalisation of others.++* Properly parse and print IDs of clusters.++* Allow `NodeCluster` values to have node types different from the+  `LNode` they come from.++Changes in 2999.5.1.1+---------------------++* When used as labels, etc., the Dot keywords `node`, `edge`, `graph`,+  `digraph`, `subgraph`, and `strict` need to be quoted.  **Spotted by+  Kathleen Fisher.**++Changes in 2999.5.1.0+---------------------++* Potentially fixed the `graphvizWithHandle` bug; correct approach+  **spotted by Nikolas Mayr**.++* Fixed up `Parsing` of various `Attribute` sub-values, especially+  `Point` and `Spline` (and hence `Pos`, which uses them).++* Pre-process out comments and join together multi-line strings before+  parsing.++* Properly parse `Doubles` like `".2"`.++Changes in 2999.5.0.0+---------------------++A major re-write occured; these are the highlights:++* Re-write parsing and printing of Dot code using the new `ParseDot`+  and `PrintDot` classes.  This should finally fix all quoting issues,+  as well as leaving `Show` as the code representation for hacking+  purposes.  As part of this, the `Data.GraphViz.ParserCombinators`+  module has been moved to `Data.GraphViz.Types.Parsing`.++* Re-write the various `Dot*` datatypes in `Data.GraphViz.Types`.+  Sub-graphs/clusters are now their own entity rather than being part+  of `DotNode` and the Node ID type is now a type parameter rather+  than being just `Int`.  Sub-graphs/clusters can now also be parsed.++* The various conversion functions in `Data.GraphViz` now come in two+  flavours: the unprimed versions take in a `Bool` indicating if the+  graph is directed or not; the primed versions attempt to+  automatically detect this.++* Add cluster support for the graph augmentation functions, **as+  requested by Nikolas Mayr**.++* Allow custom arrow types as supported by GraphViz; **as requested by+  Han Joosten**.++* Fixed a bug in HSV-style `Color` values where `Int` was used instead of+  `Double`; **spotted by Michael deLorimier**.++* Properly resolved the situation initially spotted by Neil Brown:+  Matthew Sackman was following Dot terminology for an edge `a -> b`+  when using _head_ for `b` and _tail_ for `a` (this is presumably+  because the head/tail of the arrow are at those nodes).  `DotEdge`+  now uses _from_ and _to_ avoid ambiguity; the various `Attribute`+  values still follow upstream usage.++Changes in 2999.1.0.2+---------------------++* Fix a bug **spotted by Srihari Ramanathan** where `Color` values+  were double-quoted.++Changes in 2999.1.0.1+---------------------++* The `Color` `Attribute` should take `[Color]`, not just a single+  `Color`.++Changes in 2999.1.0.0+---------------------++* Stop using `Either` for composite `Attributes` and use a custom+  type: this avoids problems with the `Show` instance.++Changes in 2999.0.0.0+---------------------++* Fixed a bug where the Show instance and read function for `DotEdge`+  had the from/to nodes the wrong way round.  This was not immediately+  noticed since the `Graph` to `DotGraph` functions created them the+  wrong way round, so for those users who only used these this was not+  apparent.  **Spotted by Neil Brown.**++* Greatly improved `Attribute` usage: almost all attributes are now+  covered with allowed values.++* Extend DotGraph to include whether a graph is strict or not and if+  it has an ID.  Also move the directedGraph field.++* Make `Dot` refer to the actual dot command and `DotArrow` refer to+  the `ArrowType` (rather than `DotCmd` and `Dot` as before).++* Make the `Data.GraphViz.ParserCombinators` module available to end+  users again, but not re-exported by `Data.GraphViz`; it has a+  warning message up the top not to be used.  It is there purely for+  documentative purposes.++* Use [extensible-exceptions] so that `base-3.x` is once again+  supported.++  [extensible-exceptions]: http://hackage.haskell.org/package/extensible-exceptions++* Follow the [Package Versioning Policy] rather than using dates for+  versions.++  [Package Versioning Policy]: http://www.haskell.org/haskellwiki/Package_versioning_policy+++Changes in 2009.5.1+-------------------++* New maintainer: Ivan Lazar Miljenovic.++* Support `polyparse >= 1.1` (as opposed to `< 1.3`)++* Require `base == 4.*` (i.e. `GHC 6.10.*`) due to new exception handling.++* Include functions from [Graphalyze-0.5] for running GraphViz+  commands, etc.++  [Graphalyze-0.5]: http://hackage.haskell.org/package/Graphalyze-0.5++* Module re-organisation.++* The `Data.GraphViz.ParserCombinators` module is no longer available+  to end users.++* Improved Haddock documentation.++Changes in 2008.9.20+--------------------++* Differentiate between undirected and directed graphs (previously+  only directed graphs were supported).++* Clustering support was added.++Older versions+--------------++For versions of graphviz older than `2008.9.20`, the exact differences+between versions is unknown.
Data/GraphViz.hs view
@@ -75,6 +75,7 @@ import Data.GraphViz.Commands import Data.GraphViz.Commands.IO(hGetDot) +import Data.Functor((<$>)) import Data.Graph.Inductive.Graph import qualified Data.Set as Set import Control.Arrow((&&&), first)@@ -82,7 +83,6 @@ import qualified Data.Map as Map import qualified Data.Text.Lazy as T import Data.Text.Lazy(Text)-import Control.Monad(liftM) import System.IO.Unsafe(unsafePerformIO) import Control.Concurrent(forkIO) @@ -169,6 +169,11 @@ --   These correspond to 'LNode' and 'LEdge' in FGL graphs. -- --   The clustering in 'clusterBy' can be to arbitrary depth.+--+--   Note that the term \"cluster\" is slightly conflated here: in+--   terms of @GraphvizParams@ values, a cluster is a grouping of+--   nodes; the 'isDotCluster' function lets you specify whether it is+--   a cluster in the Dot sense or just a sub-graph. data GraphvizParams n nl el cl l      = Params { -- | @True@ if the graph is directed; @False@                 --   otherwise.@@ -179,6 +184,9 @@                 -- | A function to specify which cluster a particular                 --   node is in.               , clusterBy        :: ((n,nl) -> NodeCluster cl (n,l))+                -- | Is this \"cluster\" actually a cluster, or just a+                --   sub-graph?+              , isDotCluster     :: (cl -> Bool)                 -- | The name/identifier for a cluster.               , clusterID        :: (cl -> GraphID)                 -- | Specify which global attributes are applied in@@ -208,6 +216,7 @@ defaultParams = Params { isDirected       = True                        , globalAttributes = []                        , clusterBy        = N+                       , isDotCluster     = const True                        , clusterID        = const (Int 0)                        , fmtCluster       = const []                        , fmtNode          = const []@@ -232,6 +241,7 @@ blankParams = Params { isDirected       = undefined                      , globalAttributes = undefined                      , clusterBy        = undefined+                     , isDotCluster     = undefined                      , clusterID        = undefined                      , fmtCluster       = undefined                      , fmtNode          = undefined@@ -271,8 +281,8 @@                      , nodeStmts = ns                      , edgeStmts = es                      }-    (cs, ns) = clustersToNodes (clusterBy params) (clusterID params)-                               (fmtCluster params) (fmtNode params)+    (cs, ns) = clustersToNodes (clusterBy params) (isDotCluster params)+                               (clusterID params) (fmtCluster params) (fmtNode params)                                lns     es = mapMaybe mkDotEdge les     mkDotEdge e@(f,t,_) = if dirGraph || f <= t@@ -294,7 +304,7 @@     -- Applying uniqBy just in case...     ns = uniqBy fst . map toLN $ graphNodes dg     es = concatMap toLE $ graphEdges dg-    -- Need to ensure that for some reason there are node IDs in an+    -- Need to check that for some reason there aren't node IDs in an     -- edge but not on their own.     nSet = Set.fromList $ map fst ns     nEs = map (flip (,) [])@@ -415,8 +425,8 @@     es' = zipWith addID es ([1..] :: [Int])     addID (f,t,l) i = (f,t,EID (T.pack $ show i) l) --- | Add the 'Comment' to the list of attributes containing the value---   of the unique edge identifier.+-- | Add a custom attribute to the list of attributes containing the+--   value of the unique edge identifier. setEdgeIDAttribute     :: (LEdge el -> Attributes)                           -> (LEdge (EdgeID el) -> Attributes) setEdgeIDAttribute f = \ e@(_,_,eid) -> identifierAttribute (eID eid)@@ -437,8 +447,7 @@ dotAttributes :: (Graph gr, PPDotRepr dg Node) => Bool -> gr nl (EdgeID el)                  -> dg Node -> IO (gr (AttributeNode nl) (AttributeEdge el)) dotAttributes isDir gr dot-  = liftM (augmentGraph gr . parseDG)-    $ graphvizWithHandle command dot DotOutput hGetDot+  = augmentGraph gr . parseDG <$> graphvizWithHandle command dot DotOutput hGetDot   where     parseDG = (`asTypeOf` dot)     command = if isDir then dirCommand else undirCommand
Data/GraphViz/Algorithms/Clustering.hs view
@@ -32,11 +32,11 @@  -- | Extract the clusters and nodes from the list of nodes. clustersToNodes :: (Ord c) => ((n,a) -> NodeCluster c (n,l))-                  -> (c -> GraphID) -> (c -> [GlobalAttributes])+                  -> (c -> Bool) -> (c -> GraphID) -> (c -> [GlobalAttributes])                   -> ((n,l) -> Attributes) -> [(n,a)]                   -> ([DotSubGraph n], [DotNode n])-clustersToNodes clusterBy cID fmtCluster fmtNode-    = treesToDot cID fmtCluster fmtNode+clustersToNodes clusterBy isC cID fmtCluster fmtNode+    = treesToDot isC cID fmtCluster fmtNode       . collapseNClusts       . map (clustToTree . clusterBy) @@ -84,23 +84,23 @@ -- | Convert the cluster representation of the trees into 'DotNode's --   and 'DotSubGraph's (with @'isCluster' = 'True'@, and --   @'subGraphID' = 'Nothing'@).-treesToDot :: (c -> GraphID) -> (c -> [GlobalAttributes])+treesToDot :: (c -> Bool) -> (c -> GraphID) -> (c -> [GlobalAttributes])               -> ((n,a) -> Attributes) -> [ClusterTree c (n,a)]               -> ([DotSubGraph n], [DotNode n])-treesToDot cID fmtCluster fmtNode+treesToDot isC cID fmtCluster fmtNode     = partitionEithers-      . map (treeToDot cID fmtCluster fmtNode)+      . map (treeToDot isC cID fmtCluster fmtNode)  -- | Convert this 'ClusterTree' into its /Dot/ representation.-treeToDot :: (c -> GraphID) -> (c -> [GlobalAttributes])+treeToDot :: (c -> Bool) -> (c -> GraphID) -> (c -> [GlobalAttributes])              -> ((n,a) -> Attributes) -> ClusterTree c (n,a)              -> Either (DotSubGraph n) (DotNode n)-treeToDot _ _ fmtNode (NT ln)+treeToDot _ _ _ fmtNode (NT ln)     = Right DotNode { nodeID         = fst ln                     , nodeAttributes = fmtNode ln                     }-treeToDot cID fmtCluster fmtNode (CT c nts)-    = Left DotSG { isCluster     = True+treeToDot isC cID fmtCluster fmtNode (CT c nts)+    = Left DotSG { isCluster     = isC c                  , subGraphID    = Just $ cID c                  , subGraphStmts = stmts                  }@@ -110,4 +110,4 @@                      , nodeStmts = ns                      , edgeStmts = []                      }-    (cs, ns) = treesToDot cID fmtCluster fmtNode nts+    (cs, ns) = treesToDot isC cID fmtCluster fmtNode nts
Data/GraphViz/Attributes/Colors.hs view
@@ -52,7 +52,6 @@ import Data.Maybe(isJust) import Data.Word(Word8) import qualified Data.Text.Lazy as T-import Control.Monad(liftM)  -- ----------------------------------------------------------------------------- @@ -122,6 +121,8 @@                     , parseNC (undefined :: SVGColor) False                     , parseX11Color False                     ]+              `onFail`+              fail "Could not parse Color"     where       parseHexBased           = do character '#'@@ -132,13 +133,12 @@                           _ -> throw . NotDotCode                                $ "Not a valid hex Color specification: "                                   ++ show cs-      parseHSV = do h <- parse-                    parseSep-                    s <- parse-                    parseSep-                    v <- parse-                    return $ HSV h s v-      parseSep = oneOf [ string ","+      parseHSV = HSV <$> parse+                     <*  parseSep+                     <*> parse+                     <*  parseSep+                     <*> parse+      parseSep = oneOf [ string "," *> whitespace                        , whitespace1                        ]       parse2Hex = do c1 <- satisfy isHexDigit@@ -152,10 +152,16 @@                 , parseNC (undefined :: SVGColor) True                 , parseX11Color True                 ]+          `onFail`+          fail "Could not parse Color"    parseUnqtList = sepBy1 parseUnqt (character ':')+                  `onFail`+                  do cs <- getColorScheme+                     failBad $ "Error parsing list of Colors with color scheme of "+                               ++ show cs -  parseList = liftM (:[])+  parseList = fmap (:[])               -- Unquoted single color               (oneOf [ parseNC (undefined :: BrewerColor) True                      , parseNC (undefined :: SVGColor) True@@ -164,6 +170,10 @@               )               `onFail`               quotedParse parseUnqtList+              `onFail`+              do cs <- getColorScheme+                 failBad $ "Error parsing list of Colors with color scheme of "+                           ++ show cs  -- ----------------------------------------------------------------------------- @@ -175,6 +185,7 @@      printNC :: Bool -> nc -> DotCode +    -- | Bool is for whether quoting is needed.     parseNC' :: Bool -> Parse nc  -- First value just used for type@@ -234,7 +245,7 @@                    => (ColorScheme -> Maybe cs) -> Parse cs -> (cs -> Bool)                    -> (cs -> lv -> nc) -> Bool -> Parse nc parseNamedColor gcs parseCS vcs mkC q-    = do Just cs <- gcs `fmap` getColorScheme+    = do Just cs <- gcs <$> getColorScheme          lv <- bool parseUnqt parse q                `onFail`                mQts (string "//" *> parseUnqt)@@ -244,8 +255,7 @@                 cs <- parseCS                 character '/'                 if vcs cs-                   then do lv <- parseUnqt-                           return $ mkC cs lv+                   then mkC cs <$>  parseUnqt                    else fail "Explicit colorscheme not as expected."            )     where@@ -256,16 +266,16 @@ -- X11 has a special case when parsing: '/yyyy'  parseX11Color   :: Bool -> Parse Color-parseX11Color q = fmap X11Color-                  $ parseNC' q-                    `onFail`-                    bool id quotedParse q (character '/' *> parseUnqt)-                    `onFail`-                    -- Can use X11 colors within brewer colorscheme.-                    do cs <- getColorScheme-                       case cs of-                         Brewer{} -> bool parseUnqt parse q-                         _        -> fail "Unable to parse an X11 color within Brewer"+parseX11Color q = X11Color+                  <$> parseNC' q+                      `onFail`+                      bool id quotedParse q (character '/' *> parseUnqt)+                      `onFail`+                      -- Can use X11 colors within brewer colorscheme.+                      do cs <- getColorScheme+                         case cs of+                           Brewer{} -> bool parseUnqt parse q+                           _        -> fail "Unable to parse an X11 color within Brewer"  -- ----------------------------------------------------------------------------- 
Data/GraphViz/Attributes/Complete.hs view
@@ -110,6 +110,7 @@        , Label(..)        , VerticalPlacement(..)        , LabelScheme(..)+       , SVGFontNames(..)          -- *** Types representing the Dot grammar for records.        , RecordFields        , RecordField(..)@@ -146,6 +147,7 @@        , DPoint(..)           -- ** Layout+       , GraphSize(..)        , AspectType(..)        , ClusterMode(..)        , Model(..)@@ -197,7 +199,6 @@ import qualified Data.Set as S import qualified Data.Text.Lazy as T import Data.Text.Lazy(Text)-import Control.Monad(liftM, liftM2) import System.FilePath(searchPathSeparator, splitSearchPath)  -- -----------------------------------------------------------------------------@@ -244,9 +245,9 @@   = Damping Double                      -- ^ /Valid for/: G; /Default/: @0.99@; /Minimum/: @0.0@; /Notes/: neato only   | K Double                            -- ^ /Valid for/: GC; /Default/: @0.3@; /Minimum/: @0@; /Notes/: sfdp, fdp only   | URL EscString                       -- ^ /Valid for/: ENGC; /Default/: none; /Notes/: svg, postscript, map only-  | ArrowHead ArrowType                 -- ^ /Valid for/: E; /Default/: @'AType' [('noMods', 'Normal')]@+  | ArrowHead ArrowType                 -- ^ /Valid for/: E; /Default/: @'normal'@   | ArrowSize Double                    -- ^ /Valid for/: E; /Default/: @1.0@; /Minimum/: @0.0@-  | ArrowTail ArrowType                 -- ^ /Valid for/: E; /Default/: @'AType' [('noMods', 'Normal')]@+  | ArrowTail ArrowType                 -- ^ /Valid for/: E; /Default/: @'normal'@   | Aspect AspectType                   -- ^ /Valid for/: G; /Notes/: dot only   | BoundingBox Rect                    -- ^ /Valid for/: G; /Notes/: write only   | ColorScheme ColorScheme             -- ^ /Valid for/: ENCG; /Default/: @'X11'@@@ -259,7 +260,7 @@   | Concentrate Bool                    -- ^ /Valid for/: G; /Default/: @'False'@; /Parsing Default/: 'True'   | Constraint Bool                     -- ^ /Valid for/: E; /Default/: @'True'@; /Parsing Default/: 'True'; /Notes/: dot only   | Decorate Bool                       -- ^ /Valid for/: E; /Default/: @'False'@; /Parsing Default/: 'True'-  | DefaultDist Double                  -- ^ /Valid for/: G; /Default/: @1+(avg. len)*sqrt(|V|)@; /Minimum/: @epsilon@; /Notes/: neato only, only if @'Pack' 'DontPack'@+  | DefaultDist Double                  -- ^ /Valid for/: G; /Default/: @1+(avg. len)*sqrt(abs(V))@; /Minimum/: @epsilon@; /Notes/: neato only, only if @'Pack' 'DontPack'@   | Dim Int                             -- ^ /Valid for/: G; /Default/: @2@; /Minimum/: @2@; /Notes/: sfdp, fdp, neato only   | Dimen Int                           -- ^ /Valid for/: G; /Default/: @2@; /Minimum/: @2@; /Notes/: sfdp, fdp, neato only   | Dir DirType                         -- ^ /Valid for/: E; /Default/: @'Forward'@ (directed), @'NoDir'@ (undirected)@@ -275,7 +276,7 @@   | FixedSize Bool                      -- ^ /Valid for/: N; /Default/: @'False'@; /Parsing Default/: 'True'   | FontColor Color                     -- ^ /Valid for/: ENGC; /Default/: @'X11Color' 'Black'@   | FontName Text                       -- ^ /Valid for/: ENGC; /Default/: @\"Times-Roman\"@-  | FontNames Text                      -- ^ /Valid for/: G; /Default/: @\"\"@; /Notes/: svg only+  | FontNames SVGFontNames              -- ^ /Valid for/: G; /Default/: @'SvgNames'@; /Notes/: svg only   | FontPath Text                       -- ^ /Valid for/: G; /Default/: system dependent   | FontSize Double                     -- ^ /Valid for/: ENGC; /Default/: @14.0@; /Minimum/: @1.0@   | ForceLabels Bool                    -- ^ /Valid for/: G; /Default/: @'False'@; /Parsing Default/: 'True'; /Notes/: Only for 'XLabel' attributes, requires Graphviz >= 2.29.0@@ -369,7 +370,7 @@   | ShapeFile Text                      -- ^ /Valid for/: N; /Default/: @\"\"@   | ShowBoxes Int                       -- ^ /Valid for/: ENG; /Default/: @0@; /Minimum/: @0@; /Notes/: dot only   | Sides Int                           -- ^ /Valid for/: N; /Default/: @4@; /Minimum/: @0@-  | Size Point                          -- ^ /Valid for/: G+  | Size GraphSize                      -- ^ /Valid for/: G   | Skew Double                         -- ^ /Valid for/: N; /Default/: @0.0@; /Minimum/: @-100.0@   | Smoothing SmoothType                -- ^ /Valid for/: G; /Default/: @'NoSmooth'@; /Notes/: sfdp only   | SortV Word16                        -- ^ /Valid for/: GCN; /Default/: @0@; /Minimum/: @0@@@ -559,11 +560,11 @@   listToDot = unqtListToDot  instance ParseDot Attribute where-  parseUnqt = stringParse (concat [ parseField Damping "Damping"-                                  , parseField K "K"+  parseUnqt = stringParse (concat [ parseFieldNumDef Damping 0.99 "Damping"+                                  , parseFieldNumDef K 0.3 "K"                                   , parseFields URL ["URL", "href"]                                   , parseField ArrowHead "arrowhead"-                                  , parseField ArrowSize "arrowsize"+                                  , parseFieldNumDef ArrowSize 1 "arrowsize"                                   , parseField ArrowTail "arrowtail"                                   , parseField Aspect "aspect"                                   , parseField BoundingBox "bb"@@ -578,11 +579,11 @@                                   , parseFieldBool Constraint "constraint"                                   , parseFieldBool Decorate "decorate"                                   , parseField DefaultDist "defaultdist"-                                  , parseField Dim "dim"-                                  , parseField Dimen "dimen"+                                  , parseFieldNumDef Dim 2 "dim"+                                  , parseFieldNumDef Dimen 2 "dimen"                                   , parseField Dir "dir"                                   , parseFieldDef DirEdgeConstraints EdgeConstraints "diredgeconstraints"-                                  , parseField Distortion "distortion"+                                  , parseFieldNumDef Distortion 0 "distortion"                                   , parseFields DPI ["dpi", "resolution"]                                   , parseFields EdgeURL ["edgeURL", "edgehref"]                                   , parseField EdgeTarget "edgetarget"@@ -595,9 +596,9 @@                                   , parseField FontName "fontname"                                   , parseField FontNames "fontnames"                                   , parseField FontPath "fontpath"-                                  , parseField FontSize "fontsize"+                                  , parseFieldNumDef FontSize 14 "fontsize"                                   , parseFieldBool ForceLabels "forcelabels"-                                  , parseField GradientAngle "gradientangle"+                                  , parseFieldNumDef GradientAngle 0 "gradientangle"                                   , parseField Group "group"                                   , parseFields HeadURL ["headURL", "headhref"]                                   , parseFieldBool HeadClip "headclip"@@ -605,7 +606,7 @@                                   , parseField HeadPort "headport"                                   , parseField HeadTarget "headtarget"                                   , parseField HeadTooltip "headtooltip"-                                  , parseField Height "height"+                                  , parseFieldNumDef Height 0.5 "height"                                   , parseField ID "id"                                   , parseField Image "image"                                   , parseField ImagePath "imagepath"@@ -613,12 +614,12 @@                                   , parseField Label "label"                                   , parseFields LabelURL ["labelURL", "labelhref"]                                   , parseField LabelScheme "label_scheme"-                                  , parseField LabelAngle "labelangle"-                                  , parseField LabelDistance "labeldistance"+                                  , parseFieldNumDef LabelAngle (-25) "labelangle"+                                  , parseFieldNumDef LabelDistance 1 "labeldistance"                                   , parseFieldBool LabelFloat "labelfloat"                                   , parseField LabelFontColor "labelfontcolor"                                   , parseField LabelFontName "labelfontname"-                                  , parseField LabelFontSize "labelfontsize"+                                  , parseFieldNumDef LabelFontSize 14 "labelfontsize"                                   , parseField LabelJust "labeljust"                                   , parseField LabelLoc "labelloc"                                   , parseField LabelTarget "labeltarget"@@ -629,8 +630,8 @@                                   , parseField LayerSep "layersep"                                   , parseField Layout "layout"                                   , parseField Len "len"-                                  , parseField LevelsGap "levelsgap"-                                  , parseField Levels "levels"+                                  , parseFieldNumDef LevelsGap 0 "levelsgap"+                                  , parseFieldNumDef Levels maxBound "levels"                                   , parseField LHead "lhead"                                   , parseField LHeight "LHeight"                                   , parseField LPos "lp"@@ -638,34 +639,34 @@                                   , parseField LWidth "lwidth"                                   , parseField Margin "margin"                                   , parseField MaxIter "maxiter"-                                  , parseField MCLimit "mclimit"-                                  , parseField MinDist "mindist"-                                  , parseField MinLen "minlen"+                                  , parseFieldNumDef MCLimit 1 "mclimit"+                                  , parseFieldNumDef MinDist 1 "mindist"+                                  , parseFieldNumDef MinLen 1 "minlen"                                   , parseField Mode "mode"                                   , parseField Model "model"                                   , parseFieldBool Mosek "mosek"-                                  , parseField NodeSep "nodesep"+                                  , parseFieldNumDef NodeSep 0.25 "nodesep"                                   , parseFieldBool NoJustify "nojustify"                                   , parseFieldBool Normalize "normalize"                                   , parseField Nslimit "nslimit"                                   , parseField Nslimit1 "nslimit1"                                   , parseField Ordering "ordering"-                                  , parseField Orientation "orientation"+                                  , parseFieldNumDef Orientation 0 "orientation"                                   , parseField OutputOrder "outputorder"                                   , parseFieldDef Overlap KeepOverlaps "overlap"-                                  , parseField OverlapScaling "overlap_scaling"+                                  , parseFieldNumDef OverlapScaling (-4) "overlap_scaling"                                   , parseFieldDef Pack DoPack "pack"                                   , parseField PackMode "packmode"                                   , parseField Pad "pad"                                   , parseField Page "page"                                   , parseField PageDir "pagedir"                                   , parseField PenColor "pencolor"-                                  , parseField PenWidth "penwidth"-                                  , parseField Peripheries "peripheries"+                                  , parseFieldNumDef PenWidth 1 "penwidth"+                                  , parseFieldNumDef Peripheries 1 "peripheries"                                   , parseFieldBool Pin "pin"                                   , parseField Pos "pos"                                   , parseFieldDef QuadTree NormalQT "quadtree"-                                  , parseField Quantum "quantum"+                                  , parseFieldNumDef Quantum 0 "quantum"                                   , parseField Rank "rank"                                   , parseField RankDir "rankdir"                                   , parseField RankSep "ranksep"@@ -673,22 +674,22 @@                                   , parseField Rects "rects"                                   , parseFieldBool Regular "regular"                                   , parseFieldBool ReMinCross "remincross"-                                  , parseField RepulsiveForce "repulsiveforce"+                                  , parseFieldNumDef RepulsiveForce 1 "repulsiveforce"                                   , parseFieldDef Root IsCentral "root"-                                  , parseField Rotate "rotate"-                                  , parseField Rotation "rotation"+                                  , parseFieldNumDef Rotate 0 "rotate"+                                  , parseFieldNumDef Rotation 0 "rotation"                                   , parseField SameHead "samehead"                                   , parseField SameTail "sametail"                                   , parseField SamplePoints "samplepoints"                                   , parseField Scale "scale"-                                  , parseField SearchSize "searchsize"+                                  , parseFieldNumDef SearchSize 30 "searchsize"                                   , parseField Sep "sep"                                   , parseField Shape "shape"                                   , parseField ShapeFile "shapefile"-                                  , parseField ShowBoxes "showboxes"-                                  , parseField Sides "sides"+                                  , parseFieldNumDef ShowBoxes 0 "showboxes"+                                  , parseFieldNumDef Sides 4 "sides"                                   , parseField Size "size"-                                  , parseField Skew "skew"+                                  , parseFieldNumDef Skew 0 "skew"                                   , parseField Smoothing "smoothing"                                   , parseField SortV "sortv"                                   , parseFieldDef Splines SplineEdges "splines"@@ -706,14 +707,16 @@                                   , parseFieldBool TrueColor "truecolor"                                   , parseField Vertices "vertices"                                   , parseField ViewPort "viewport"-                                  , parseField VoroMargin "voro_margin"+                                  , parseFieldNumDef VoroMargin 0.05 "voro_margin"                                   , parseField Weight "weight"-                                  , parseField Width "width"+                                  , parseFieldNumDef Width 0.75 "width"                                   , parseField XLabel "xlabel"-                                  , parseField Z "z"+                                  , parseFieldNumDef Z 0 "z"                                   ])               `onFail`-              liftM2 UnknownAttribute stringBlock (parseEq >> parse)+              do attrName <- stringBlock+                 liftEqParse' ("UnknownAttribute (" ++ T.unpack attrName ++ ")")+                              (UnknownAttribute attrName)    parse = parseUnqt @@ -1142,7 +1145,7 @@ defaultAttributeValue FixedSize{}          = Just $ FixedSize False defaultAttributeValue FontColor{}          = Just $ FontColor (X11Color Black) defaultAttributeValue FontName{}           = Just $ FontName "Times-Roman"-defaultAttributeValue FontNames{}          = Just $ FontNames ""+defaultAttributeValue FontNames{}          = Just $ FontNames SvgNames defaultAttributeValue FontSize{}           = Just $ FontSize 14 defaultAttributeValue ForceLabels{}        = Just $ ForceLabels False defaultAttributeValue GradientAngle{}      = Just $ GradientAngle 0@@ -1545,10 +1548,7 @@ instance ParseDot ArrowType where   parseUnqt = specialArrowParse               `onFail`-              do mas <- many1 $ do m <- parseUnqt-                                   a <- parseUnqt-                                   return (m,a)-                 return $ AType mas+              (AType <$> many1 (liftA2 (,) parseUnqt parseUnqt))  specialArrowParse :: Parse ArrowType specialArrowParse = stringValue [ ("ediamond", eDiamond)@@ -1610,9 +1610,7 @@   unqtDot (ArrMod f s) = unqtDot f <> unqtDot s  instance ParseDot ArrowModifier where-  parseUnqt = do f <- parseUnqt-                 s <- parseUnqt-                 return $ ArrMod f s+  parseUnqt = liftA2 ArrMod parseUnqt parseUnqt  data ArrowFill = OpenArrow                | FilledArrow@@ -1623,8 +1621,7 @@   unqtDot FilledArrow = empty  instance ParseDot ArrowFill where-  parseUnqt = liftM (bool FilledArrow OpenArrow . isJust)-              $ optional (character 'o')+  parseUnqt = bool FilledArrow OpenArrow . isJust <$> optional (character 'o')    -- Not used individually   parse = parseUnqt@@ -1642,8 +1639,7 @@   unqtDot BothSides = empty  instance ParseDot ArrowSide where-  parseUnqt = liftM getSideType-              $ optional (oneOf $ map character ['l', 'r'])+  parseUnqt = getSideType <$> optional (oneOf $ map character ['l', 'r'])     where       getSideType = maybe BothSides                           (bool RightSide LeftSide . (==) 'l')@@ -1665,14 +1661,14 @@   toDot at@RatioPassCount{} = dquotes $ unqtDot at  instance ParseDot AspectType where-  parseUnqt = liftM (uncurry RatioPassCount) commaSepUnqt+  parseUnqt = fmap (uncurry RatioPassCount) commaSepUnqt               `onFail`-              liftM RatioOnly parseUnqt+              fmap RatioOnly parseUnqt  -  parse = quotedParse (liftM (uncurry RatioPassCount) commaSepUnqt)+  parse = quotedParse (uncurry RatioPassCount <$> commaSepUnqt)           `onFail`-          liftM RatioOnly parse+          fmap RatioOnly parse  -- ----------------------------------------------------------------------------- @@ -1681,14 +1677,14 @@             deriving (Eq, Ord, Show, Read)  instance PrintDot Rect where-  unqtDot (Rect p1 p2) = commaDel p1 p2+  unqtDot (Rect p1 p2) = printPoint2DUnqt p1 <> comma <> printPoint2DUnqt p2    toDot = dquotes . unqtDot    unqtListToDot = hsep . mapM unqtDot  instance ParseDot Rect where-  parseUnqt = liftM (uncurry Rect) $ commaSep' parsePoint2D parsePoint2D+  parseUnqt = uncurry Rect <$> commaSep' parsePoint2D parsePoint2D    parse = quotedParse parseUnqt @@ -1750,7 +1746,7 @@   unqtDot HierConstraints = text "hier"  instance ParseDot DEConstraints where-  parseUnqt = liftM (bool NoConstraints EdgeConstraints) parse+  parseUnqt = fmap (bool NoConstraints EdgeConstraints) parse               `onFail`               stringRep HierConstraints "hier" @@ -1758,28 +1754,90 @@  -- | Either a 'Double' or a (2D) 'Point' (i.e. created with --   'createPoint').+--+--   Whilst it is possible to create a 'Point' value with either a+--   third co-ordinate or a forced position, these are ignored for+--   printing/parsing.+--+--   An optional prefix of @\'+\'@ is allowed when parsing. data DPoint = DVal Double             | PVal Point             deriving (Eq, Ord, Show, Read)  instance PrintDot DPoint where   unqtDot (DVal d) = unqtDot d-  unqtDot (PVal p) = unqtDot p+  unqtDot (PVal p) = printPoint2DUnqt p    toDot (DVal d) = toDot d-  toDot (PVal p) = toDot p+  toDot (PVal p) = printPoint2D p  instance ParseDot DPoint where-  parseUnqt = liftM PVal parsePoint2D+  parseUnqt = fmap PVal parsePoint2D               `onFail`-              liftM DVal parseUnqt+              fmap DVal parseUnqt    parse = quotedParse parseUnqt           `onFail`-          liftM DVal parseUnqt+          fmap DVal parseUnqt  -- ----------------------------------------------------------------------------- +-- | The mapping used for 'FontName' values in SVG output.+--+--   More information can be found at <http://www.graphviz.org/doc/fontfaq.txt>.+data SVGFontNames = SvgNames        -- ^ Use the legal generic SVG font names.+                  | PostScriptNames -- ^ Use PostScript font names.+                  | FontConfigNames -- ^ Use fontconfig font conventions.+                  deriving (Eq, Ord, Bounded, Enum, Show, Read)++instance PrintDot SVGFontNames where+  unqtDot SvgNames        = text "svg"+  unqtDot PostScriptNames = text "ps"+  unqtDot FontConfigNames = text "gd"++instance ParseDot SVGFontNames where+  parseUnqt = oneOf [ stringRep SvgNames "svg"+                    , stringRep PostScriptNames "ps"+                    , stringRep FontConfigNames "gd"+                    ]++  parse = stringRep SvgNames "\"\""+          `onFail`+          optionalQuoted parseUnqt++-- -----------------------------------------------------------------------------++-- | Maximum width and height of drawing in inches.+data GraphSize = GSize { width :: Double+                         -- | If @Nothing@, then the height is the+                         --   same as the width.+                       , height :: Maybe Double+                         -- | If drawing is smaller than specified+                         --   size, this value determines whether it+                         --   is scaled up.+                       , desiredSize :: Bool+                       }+               deriving (Eq, Ord, Show, Read)++instance PrintDot GraphSize where+  unqtDot (GSize w mh ds) = bool id (<> char '!') ds+                            . maybe id (\h -> (<> unqtDot h) . (<> comma)) mh+                            $ unqtDot w++  toDot (GSize w Nothing False) = toDot w+  toDot gs                      = dquotes $ unqtDot gs++instance ParseDot GraphSize where+  parseUnqt = GSize <$> parseUnqt+                    <*> optional (parseComma *> whitespace *> parseUnqt)+                    <*> (isJust <$> optional (character '!'))++  parse = quotedParse parseUnqt+          `onFail`+          fmap (\ w -> GSize w Nothing False) parseUnqt++-- -----------------------------------------------------------------------------+ data ModeType = Major               | KK               | Hier@@ -1845,14 +1903,14 @@   -- between an HtmlLabel and a RecordLabel starting with a PortPos,   -- since the latter will be in quotes and the former won't. -  parseUnqt = oneOf [ liftM HtmlLabel $ parseAngled parseUnqt-                    , liftM RecordLabel parseUnqt-                    , liftM StrLabel parseUnqt+  parseUnqt = oneOf [ HtmlLabel <$> parseAngled parseUnqt+                    , RecordLabel <$> parseUnqt+                    , StrLabel <$> parseUnqt                     ] -  parse = oneOf [ liftM HtmlLabel $ parseAngled parse-                , liftM RecordLabel parse-                , liftM StrLabel parse+  parse = oneOf [ HtmlLabel <$> parseAngled parse+                , RecordLabel <$> parse+                , StrLabel <$> parse                 ]  -- -----------------------------------------------------------------------------@@ -1888,15 +1946,16 @@   listToDot fs  = dquotes $ unqtListToDot fs  instance ParseDot RecordField where-  parseUnqt = do t <- liftM PN $ parseAngled parseRecord-                 ml <- optional (whitespace1 >> parseRecord)-                 return $ maybe (PortName t)-                                (LabelledTarget t)-                                ml+  parseUnqt = (liftA2 maybe PortName LabelledTarget+                <$> (PN <$> parseAngled parseRecord)+                <*> optional (whitespace1 *> parseRecord)+              )               `onFail`-              liftM FieldLabel parseRecord+              fmap FieldLabel parseRecord               `onFail`-              liftM FlipFields (parseBraced parseUnqt)+              fmap FlipFields (parseBraced parseUnqt)+              `onFail`+              fail "Unable to parse RecordField"    parse = quotedParse parseUnqt @@ -1966,8 +2025,14 @@ createPoint     :: Double -> Double -> Point createPoint x y = Point x y Nothing False +printPoint2DUnqt   :: Point -> DotCode+printPoint2DUnqt p = commaDel (xCoord p) (yCoord p)++printPoint2D :: Point -> DotCode+printPoint2D = dquotes . printPoint2DUnqt+ parsePoint2D :: Parse Point-parsePoint2D = liftM (uncurry createPoint) commaSepUnqt+parsePoint2D = uncurry createPoint <$> commaSepUnqt  instance PrintDot Point where   unqtDot (Point x y mz frs) = bool id (<> char '!') frs@@ -1981,10 +2046,10 @@   listToDot = dquotes . unqtListToDot  instance ParseDot Point where-  parseUnqt = do (x,y) <- commaSepUnqt-                 mz <- optional $ parseComma >> parseUnqt-                 bng <- liftM isJust . optional $ character '!'-                 return $ Point x y mz bng+  parseUnqt = uncurry Point+                <$> commaSepUnqt+                <*> optional (parseComma *> parseUnqt)+                <*> (isJust <$> optional (character '!'))    parse = quotedParse parseUnqt @@ -2017,7 +2082,7 @@   parseUnqt = oneOf [ stringRep KeepOverlaps "true"                     , stringRep ScaleXYOverlaps "scalexy"                     , stringRep ScaleOverlaps "scale"-                    , string "prism" >> liftM PrismOverlap (optional parse)+                    , string "prism" *> fmap PrismOverlap (optional parse)                     , stringRep (PrismOverlap Nothing) "false"                     , stringRep CompressOverlap "compress"                     , stringRep VpscOverlap "vpsc"@@ -2030,11 +2095,9 @@                  deriving (Eq, Ord, Show, Read)  instance PrintDot LayerSep where-  unqtDot (LSep ls) = do setLayerSep $ T.unpack ls-                         unqtDot ls+  unqtDot (LSep ls) = setLayerSep (T.unpack ls) *> unqtDot ls -  toDot (LSep ls) = do setLayerSep $ T.unpack ls-                       toDot ls+  toDot (LSep ls) = setLayerSep (T.unpack ls) *> toDot ls  instance ParseDot LayerSep where   parseUnqt = do ls <- parseUnqt@@ -2059,26 +2122,18 @@   toDot lrs        = dquotes $ unqtDot lrs  instance ParseDot LayerRange where-  parseUnqt = do id1 <- parseUnqt-                 _   <- parseLayerSep-                 id2 <- parseUnqt-                 return $ LRS id1 id2+  parseUnqt = ignoreSep LRS parseUnqt parseLayerSep parseUnqt               `onFail`-              liftM LRID parseUnqt+              fmap LRID parseUnqt  -  parse = quotedParse ( do id1 <- parseUnqt-                           _   <- parseLayerSep-                           id2 <- parseUnqt-                           return $ LRS id1 id2-                      )+  parse = quotedParse (ignoreSep LRS parseUnqt parseLayerSep parseUnqt)           `onFail`-          liftM LRID parse+          fmap LRID parse  parseLayerSep :: Parse () parseLayerSep = do ls <- getLayerSep-                   many1Satisfy (`elem` ls)-                   return ()+                   many1Satisfy (`elem` ls) *> return ()  parseLayerName :: Parse Text parseLayerName = parseEscaped False [] =<< getLayerSep@@ -2114,10 +2169,10 @@   listToDot ll  = dquotes $ unqtDot ll  instance ParseDot LayerID where-  parseUnqt = liftM checkLayerName parseLayerName -- tests for Int and All+  parseUnqt = checkLayerName <$> parseLayerName -- tests for Int and All -  parse = oneOf [ liftM checkLayerName parseLayerName'-                , liftM LRInt parse -- Mainly for unquoted case.+  parse = oneOf [ checkLayerName <$> parseLayerName'+                , LRInt <$> parse -- Mainly for unquoted case.                 ]  checkLayerName     :: Text -> LayerID@@ -2139,11 +2194,11 @@   toDot (LL ll) = toDot ll  instance ParseDot LayerList where-  parseUnqt = liftM LL $ sepBy1 parseUnqt parseLayerSep+  parseUnqt = LL <$> sepBy1 parseUnqt parseLayerSep    parse = quotedParse parseUnqt           `onFail`-          liftM (LL . (:[]) . LRName) stringBlock+          fmap (LL . (:[]) . LRName) stringBlock           `onFail`           quotedParse (stringRep (LL []) "") @@ -2192,8 +2247,8 @@  instance ParseDot Pack where   -- What happens if it parses 0?  It's non-negative, but parses as False-  parseUnqt = oneOf [ liftM PackMargin parseUnqt-                    , liftM (bool DontPack DoPack) onlyBool+  parseUnqt = oneOf [ PackMargin <$> parseUnqt+                    , bool DontPack DoPack <$> onlyBool                     ]  -- -----------------------------------------------------------------------------@@ -2229,8 +2284,7 @@                     , stringRep PackClust "clust"                     , stringRep PackGraph "graph"                     , do string "array"-                         mcu <- optional $ do character '_'-                                              many1 $ satisfy isCU+                         mcu <- optional $ character '_' *> many1 (satisfy isCU)                          let c = hasCharacter mcu 'c'                              u = hasCharacter mcu 'u'                          mi <- optional parseUnqt@@ -2288,7 +2342,7 @@  instance ParseDot EdgeType where   -- Can't parse NoEdges without quotes.-  parseUnqt = oneOf [ liftM (bool LineEdges SplineEdges) parse+  parseUnqt = oneOf [ bool LineEdges SplineEdges <$> parse                     , stringRep SplineEdges "spline"                     , stringRep LineEdges "line"                     , stringRep PolyLine "polyline"@@ -2331,11 +2385,14 @@  -- | The number of points in the list must be equivalent to 1 mod 3; --   note that this is not checked.-data Spline = Spline (Maybe Point) (Maybe Point) [Point]+data Spline = Spline { endPoint     :: Maybe Point+                     , startPoint   :: Maybe Point+                     , splinePoints :: [Point]+                     }             deriving (Eq, Ord, Show, Read)  instance PrintDot Spline where-  unqtDot (Spline ms me ps) = addS . addE+  unqtDot (Spline me ms ps) = addE . addS                              . hsep                              $ mapM unqtDot ps     where@@ -2350,14 +2407,10 @@   listToDot = dquotes . unqtListToDot  instance ParseDot Spline where-  parseUnqt = do ms <- parseP 's'-                 me <- parseP 'e'-                 ps <- sepBy1 parseUnqt whitespace1-                 return $ Spline ms me ps+  parseUnqt = Spline <$> parseP 'e' <*> parseP 's'+                     <*> sepBy1 parseUnqt whitespace1       where-        parseP t = optional $ do character t-                                 parseComma-                                 parseUnqt `discard` whitespace1+        parseP t = optional (character t *> parseComma *> parseUnqt <* whitespace1)    parse = quotedParse parseUnqt @@ -2381,8 +2434,8 @@   parseUnqt = oneOf [ stringRep NormalQT "normal"                     , stringRep FastQT "fast"                     , stringRep NoQT "none"-                    , character '2'   >> return FastQT -- weird bool-                    , liftM (bool NoQT NormalQT) parse+                    , character '2' *> return FastQT -- weird bool+                    , bool NoQT NormalQT <$> parse                     ]  -- -----------------------------------------------------------------------------@@ -2402,13 +2455,13 @@   toDot r            = unqtDot r  instance ParseDot Root where-  parseUnqt = liftM (bool NotCentral IsCentral) onlyBool+  parseUnqt = fmap (bool NotCentral IsCentral) onlyBool               `onFail`-              liftM NodeName parseUnqt+              fmap NodeName parseUnqt -  parse = optionalQuoted (liftM (bool NotCentral IsCentral) onlyBool)+  parse = optionalQuoted (bool NotCentral IsCentral <$> onlyBool)           `onFail`-          liftM NodeName parse+          fmap NodeName parse  -- ----------------------------------------------------------------------------- @@ -2460,7 +2513,7 @@ data Shape     = BoxShape -- ^ Has synonyms of /rect/ and /rectangle/.     | Polygon-    | Ellipse+    | Ellipse  -- ^ Has synonym of /oval/.     | Circle     | PointShape     | Egg@@ -2488,43 +2541,83 @@     | Folder     | Box3D     | Component+    | Promoter+    | CDS+    | Terminator+    | UTR+    | PrimerSite+    | RestrictionSite+    | FivePovOverhang+    | ThreePovOverhang+    | NoOverhang+    | Assembly+    | Signature+    | Insulator+    | Ribosite+    | RNAStab+    | ProteaseSite+    | ProteinStab+    | RPromoter+    | RArrow+    | LArrow+    | LPromoter     | Record -- ^ Must specify the record shape with a 'Label'.     | MRecord -- ^ Must specify the record shape with a 'Label'.     deriving (Eq, Ord, Bounded, Enum, Show, Read)  instance PrintDot Shape where-  unqtDot BoxShape      = text "box"-  unqtDot Polygon       = text "polygon"-  unqtDot Ellipse       = text "ellipse"-  unqtDot Circle        = text "circle"-  unqtDot PointShape    = text "point"-  unqtDot Egg           = text "egg"-  unqtDot Triangle      = text "triangle"-  unqtDot PlainText     = text "plaintext"-  unqtDot DiamondShape  = text "diamond"-  unqtDot Trapezium     = text "trapezium"-  unqtDot Parallelogram = text "parallelogram"-  unqtDot House         = text "house"-  unqtDot Pentagon      = text "pentagon"-  unqtDot Hexagon       = text "hexagon"-  unqtDot Septagon      = text "septagon"-  unqtDot Octagon       = text "octagon"-  unqtDot DoubleCircle  = text "doublecircle"-  unqtDot DoubleOctagon = text "doubleoctagon"-  unqtDot TripleOctagon = text "tripleoctagon"-  unqtDot InvTriangle   = text "invtriangle"-  unqtDot InvTrapezium  = text "invtrapezium"-  unqtDot InvHouse      = text "invhouse"-  unqtDot MDiamond      = text "Mdiamond"-  unqtDot MSquare       = text "Msquare"-  unqtDot MCircle       = text "Mcircle"-  unqtDot Note          = text "note"-  unqtDot Tab           = text "tab"-  unqtDot Folder        = text "folder"-  unqtDot Box3D         = text "box3d"-  unqtDot Component     = text "component"-  unqtDot Record        = text "record"-  unqtDot MRecord       = text "Mrecord"+  unqtDot BoxShape         = text "box"+  unqtDot Polygon          = text "polygon"+  unqtDot Ellipse          = text "ellipse"+  unqtDot Circle           = text "circle"+  unqtDot PointShape       = text "point"+  unqtDot Egg              = text "egg"+  unqtDot Triangle         = text "triangle"+  unqtDot PlainText        = text "plaintext"+  unqtDot DiamondShape     = text "diamond"+  unqtDot Trapezium        = text "trapezium"+  unqtDot Parallelogram    = text "parallelogram"+  unqtDot House            = text "house"+  unqtDot Pentagon         = text "pentagon"+  unqtDot Hexagon          = text "hexagon"+  unqtDot Septagon         = text "septagon"+  unqtDot Octagon          = text "octagon"+  unqtDot DoubleCircle     = text "doublecircle"+  unqtDot DoubleOctagon    = text "doubleoctagon"+  unqtDot TripleOctagon    = text "tripleoctagon"+  unqtDot InvTriangle      = text "invtriangle"+  unqtDot InvTrapezium     = text "invtrapezium"+  unqtDot InvHouse         = text "invhouse"+  unqtDot MDiamond         = text "Mdiamond"+  unqtDot MSquare          = text "Msquare"+  unqtDot MCircle          = text "Mcircle"+  unqtDot Note             = text "note"+  unqtDot Tab              = text "tab"+  unqtDot Folder           = text "folder"+  unqtDot Box3D            = text "box3d"+  unqtDot Component        = text "component"+  unqtDot Promoter         = text "promoter"+  unqtDot CDS              = text "cds"+  unqtDot Terminator       = text "terminator"+  unqtDot UTR              = text "utr"+  unqtDot PrimerSite       = text "primersite"+  unqtDot RestrictionSite  = text "restrictionsite"+  unqtDot FivePovOverhang  = text "fivepovoverhang"+  unqtDot ThreePovOverhang = text "threepovoverhang"+  unqtDot NoOverhang       = text "nooverhang"+  unqtDot Assembly         = text "assembly"+  unqtDot Signature        = text "signature"+  unqtDot Insulator        = text "insulator"+  unqtDot Ribosite         = text "ribosite"+  unqtDot RNAStab          = text "rnastab"+  unqtDot ProteaseSite     = text "proteasesite"+  unqtDot ProteinStab      = text "proteinstab"+  unqtDot RPromoter        = text "rpromoter"+  unqtDot RArrow           = text "rarrow"+  unqtDot LArrow           = text "larrow"+  unqtDot LPromoter        = text "lpromoter"+  unqtDot Record           = text "record"+  unqtDot MRecord          = text "Mrecord"  instance ParseDot Shape where   parseUnqt = stringValue [ ("box3d", Box3D)@@ -2533,6 +2626,7 @@                           , ("rect", BoxShape)                           , ("polygon", Polygon)                           , ("ellipse", Ellipse)+                          , ("oval", Ellipse)                           , ("circle", Circle)                           , ("point", PointShape)                           , ("egg", Egg)@@ -2560,6 +2654,26 @@                           , ("tab", Tab)                           , ("folder", Folder)                           , ("component", Component)+                          , ("promoter", Promoter)+                          , ("cds", CDS)+                          , ("terminator", Terminator)+                          , ("utr", UTR)+                          , ("primersite", PrimerSite)+                          , ("restrictionsite", RestrictionSite)+                          , ("fivepovoverhang", FivePovOverhang)+                          , ("threepovoverhang", ThreePovOverhang)+                          , ("nooverhang", NoOverhang)+                          , ("assembly", Assembly)+                          , ("signature", Signature)+                          , ("insulator", Insulator)+                          , ("ribosite", Ribosite)+                          , ("rnastab", RNAStab)+                          , ("proteasesite", ProteaseSite)+                          , ("proteinstab", ProteinStab)+                          , ("rpromoter", RPromoter)+                          , ("rarrow", RArrow)+                          , ("larrow", LArrow)+                          , ("lpromoter", LPromoter)                           , ("record", Record)                           , ("Mrecord", MRecord)                           ]@@ -2607,11 +2721,9 @@   unqtDot (StartStyleSeed ss s) = unqtDot ss <> unqtDot s  instance ParseDot StartType where-  parseUnqt = oneOf [ do ss <- parseUnqt-                         s  <- parseUnqt-                         return $ StartStyleSeed ss s-                    , liftM StartStyle parseUnqt-                    , liftM StartSeed parseUnqt+  parseUnqt = oneOf [ liftA2 StartStyleSeed parseUnqt parseUnqt+                    , StartStyle <$> parseUnqt+                    , StartSeed <$> parseUnqt                     ]  data STStyle = RegularStyle@@ -2655,20 +2767,18 @@   listToDot sis           = dquotes $ unqtListToDot sis  instance ParseDot StyleItem where-  parseUnqt = do nm <- parseUnqt-                 args <- tryParseList' parseArgs-                 return $ SItem nm args+  parseUnqt = liftA2 SItem parseUnqt (tryParseList' parseArgs) -  parse = quotedParse (liftM2 SItem parseUnqt parseArgs)+  parse = quotedParse (liftA2 SItem parseUnqt parseArgs)           `onFail`-          liftM (flip SItem []) parse+          fmap (flip SItem []) parse    parseUnqtList = sepBy1 parseUnqt parseComma    parseList = quotedParse parseUnqtList               `onFail`               -- Might not necessarily need to be quoted if a singleton...-              liftM return parse+              fmap return parse  parseArgs :: Parse [Text] parseArgs = bracketSep (character '(')@@ -2709,11 +2819,11 @@   toDot sn      = unqtDot sn  instance ParseDot StyleName where-  parseUnqt = liftM checkDD parseStyleName+  parseUnqt = checkDD <$> parseStyleName    parse = quotedParse parseUnqt           `onFail`-          liftM checkDD quotelessString+          fmap checkDD quotelessString  checkDD     :: Text -> StyleName checkDD str = case T.toLower str of@@ -2730,9 +2840,8 @@                 _           -> DD str  parseStyleName :: Parse Text-parseStyleName = do f <- orEscaped . noneOf $ ' ' : disallowedChars-                    r <- parseEscaped True [] disallowedChars-                    return $ f `T.cons` r+parseStyleName = liftA2 T.cons (orEscaped . noneOf $ ' ' : disallowedChars)+                               (parseEscaped True [] disallowedChars)   where     disallowedChars = [quoteChar, '(', ')', ',']     -- Used because the first character has slightly stricter requirements than the rest.@@ -2758,13 +2867,12 @@   toDot = dquotes . unqtDot  instance ParseDot ViewPort where-  parseUnqt = do wv <- parseUnqt-                 parseComma-                 hv <- parseUnqt-                 parseComma-                 zv <- parseUnqt-                 mf <- optional $ parseComma >> parseUnqt-                 return $ VP wv hv zv mf+  parseUnqt = VP <$> parseUnqt+                 <*  parseComma+                 <*> parseUnqt+                 <*  parseComma+                 <*> parseUnqt+                 <*> optional (parseComma *> parseUnqt)    parse = quotedParse parseUnqt @@ -2781,13 +2889,13 @@   toDot (NodeFocus nm) = toDot nm  instance ParseDot FocusType where-  parseUnqt = liftM XY parseUnqt+  parseUnqt = fmap XY parseUnqt               `onFail`-              liftM NodeFocus parseUnqt+              fmap NodeFocus parseUnqt -  parse = liftM XY parse+  parse = fmap XY parse           `onFail`-          liftM NodeFocus parse+          fmap NodeFocus parse  -- ----------------------------------------------------------------------------- @@ -2819,11 +2927,11 @@     toDot ps          = dquotes $ unqtDot ps  instance ParseDot Paths where-    parseUnqt = liftM (Paths . splitSearchPath) parseUnqt+    parseUnqt = Paths . splitSearchPath <$> parseUnqt      parse = quotedParse parseUnqt             `onFail`-            liftM (Paths . (:[]) . T.unpack) quotelessString+            fmap (Paths . (:[]) . T.unpack) quotelessString  -- ----------------------------------------------------------------------------- @@ -2884,7 +2992,7 @@   unqtDot AutoRatio       = text "auto"  instance ParseDot Ratios where-  parseUnqt = oneOf [ liftM AspectRatio parseUnqt+  parseUnqt = oneOf [ AspectRatio <$> parseUnqt                     , stringRep FillRatio "fill"                     , stringRep CompressRatio "compress"                     , stringRep ExpandRatio "expand"
Data/GraphViz/Attributes/HTML.hs view
@@ -81,7 +81,6 @@ import Data.Word(Word8, Word16) import qualified Data.Map as Map import qualified Data.Text.Lazy as T-import Control.Monad(liftM, liftM2)  -- ----------------------------------------------------------------------------- @@ -99,9 +98,9 @@  instance ParseDot Label where   -- Try parsing Table first in case of a FONT tag being used.-  parseUnqt = liftM Table parseUnqt+  parseUnqt = fmap Table parseUnqt               `onFail`-              liftM Text parseUnqt+              fmap Text parseUnqt               `adjustErr`               ("Can't parse Html.Label\n\t"++) @@ -140,7 +139,7 @@   listToDot = unqtListToDot  instance ParseDot TextItem where-  parseUnqt = oneOf [ liftM Str unescapeValue+  parseUnqt = oneOf [ fmap Str unescapeValue                     , parseEmptyTag Newline "BR"                     , parseFontTag Font parseUnqt                     , parseTagRep Format parseUnqt parseUnqt@@ -150,7 +149,7 @@    parse = parseUnqt -  parseUnqtList = many1 parseUnqt -- sepBy1 parseUnqt whitespace+  parseUnqtList = many parseUnqt    parseList = parseUnqtList @@ -381,7 +380,7 @@                     , parseHtmlField' (Port . PN) "PORT" unescapeAttribute                     , parseHtmlField  RowSpan "ROWSPAN"                     , parseHtmlField  Scale "SCALE"-                    , parseHtmlField' Src "SRC" $ liftM T.unpack unescapeAttribute+                    , parseHtmlField' Src "SRC" $ fmap T.unpack unescapeAttribute                     , parseHtmlField' Target "TARGET" unescapeAttribute                     , parseHtmlField' Title "TITLE" unescapeAttribute                       `onFail`@@ -404,9 +403,15 @@  parseHtmlField'       :: (a -> Attribute) -> String -> Parse a                      -> Parse Attribute-parseHtmlField' c f p = do string f-                           parseEq-                           liftM c $ quotedParse p+parseHtmlField' c f p = string f+                        *> parseEq+                        *> ( c <$> ( quotedParse p+                                      `adjustErr`+                                      (("Can't parse HTML.Attribute." ++ f ++ "\n\t")++)+                                   )+                           )+-- Can't use liftEqParse, etc. here because it causes backtracking+-- problems when the attributes could apply to multiple constructors.  -- | Specifies horizontal placement. When an object is allocated more --   space than required, this value determines where the extra space@@ -460,11 +465,11 @@ --   cell.  If undefined, the image inherits the value of the --   @ImageScale@ attribute. data Scale = NaturalSize -- ^ Default value.-               | ScaleUniformly-               | ExpandWidth-               | ExpandHeight-               | ExpandBoth-               deriving (Eq, Ord, Bounded, Enum, Show, Read)+           | ScaleUniformly+           | ExpandWidth+           | ExpandHeight+           | ExpandBoth+           deriving (Eq, Ord, Bounded, Enum, Show, Read)  instance PrintDot Scale where   unqtDot NaturalSize    = text "FALSE"@@ -492,14 +497,14 @@ escapeValue = escapeHtml True  escapeHtml               :: Bool -> T.Text -> DotCode-escapeHtml quotesAllowed = hcat . liftM concat+escapeHtml quotesAllowed = hcat . fmap concat                            . mapM (escapeSegment . T.unpack)                            . T.groupBy ((==) `on` isSpace)   where     -- Note: use numeric version of space rather than nbsp, since this     -- matches what Graphviz does (since Inkscape apparently can't     -- cope with nbsp).-    escapeSegment (s:sps) | isSpace s = liftM2 (:) (char s) $ mapM numEscape sps+    escapeSegment (s:sps) | isSpace s = liftA2 (:) (char s) $ mapM numEscape sps     escapeSegment txt                 = mapM xmlChar txt      allowQuotes = if quotesAllowed@@ -523,7 +528,7 @@ --   Note: this /will/ fail if an unknown non-numeric HTML-escape is --   used. unescapeHtml               :: Bool -> Parse T.Text-unescapeHtml quotesAllowed = liftM (T.pack . catMaybes)+unescapeHtml quotesAllowed = fmap (T.pack . catMaybes)                              . many1 . oneOf $ [ parseEscpd                                                , validChars                                                ]@@ -551,7 +556,7 @@      escMap = Map.fromList htmlUnescapes -    validChars = liftM Just $ satisfy (`notElem` needEscaping)+    validChars = fmap Just $ satisfy (`notElem` needEscaping)     needEscaping = allowQuotes $ map fst htmlEscapes  -- | The characters that need to be escaped and what they need to be@@ -610,32 +615,38 @@ -- | Parse something like @<FOO ATTR=\"ATTR_VALUE\">value<\/FOO>@ parseTag        :: (Attributes -> val -> tag) -> String                        -> Parse val -> Parse tag-parseTag c t pv = do as <- parseAngled openingTag-                     v <- pv-                     parseAngled $ character '/' >> t' >> whitespace-                     return $ c as v+parseTag c t pv = c <$> parseAngled openingTag+                    <*> pv+                    <* parseAngled (character '/' *> t' *> whitespace)+                  `adjustErr`+                  (("Can't parse Html tag: " ++ t ++ "\n\t")++)   where     t' = string t-    openingTag = do t'-                    as <- tryParseList' $ whitespace1 >> parse-                    whitespace-                    return as--parseTagRep :: (tagName -> val -> tag) -> Parse tagName -> Parse val -> Parse tag-parseTagRep c pt pv = do tn <- parseAngled (pt `discard` whitespace)-                         v <- pv-                         parseAngled $ character '/' >> pt >> whitespace-                         return $ c tn v+    openingTag :: Parse Attributes+    openingTag = t'+                 *> tryParseList' (whitespace1 >> parse)+                 <* whitespace  parseFontTag :: (Attributes -> val -> tag) -> Parse val -> Parse tag parseFontTag = flip parseTag "FONT" +-- Should this just be specialised for tagName ~ Format ?++-- | Parse something like @<FOO>value<\/FOO>@.+parseTagRep :: (tagName -> val -> tag) -> Parse tagName -> Parse val -> Parse tag+parseTagRep c pt pv = c <$> parseAngled (pt `discard` whitespace)+                        <*> pv+                        <* parseAngled (character '/' *> pt *> whitespace)+                    `adjustErr`+                    ("Can't parse attribute-less Html tag\n\t"++)+ -- | Parse something like @<FOO ATTR=\"ATTR_VALUE\"\/>@ parseEmptyTag     :: (Attributes -> tag) -> String -> Parse tag-parseEmptyTag c t = parseAngled-                        ( do string t-                             as <- tryParseList' $ whitespace1 >> parse-                             whitespace-                             character '/'-                             return $ c as+parseEmptyTag c t = c <$> parseAngled+                        ( string t+                          *> tryParseList' (whitespace1 *> parse)+                          <* whitespace+                          <* character '/'                         )+                    `adjustErr`+                    (("Can't parse empty Html tag: " ++ t ++ "\n\t")++)
Data/GraphViz/Attributes/Internal.hs view
@@ -28,7 +28,6 @@ import qualified Data.Map as Map import Data.Map(Map) import Data.Text.Lazy(Text)-import Control.Monad(liftM, liftM2)  -- ----------------------------------------------------------------------------- @@ -52,15 +51,14 @@   toDot = toDot . portName  instance ParseDot PortName where-  parseUnqt = liftM PN-              $ parseEscaped False [] ['"', ':']+  parseUnqt = PN <$> parseEscaped False [] ['"', ':']    parse = quotedParse parseUnqt           `onFail`           unqtPortName  unqtPortName :: Parse PortName-unqtPortName = liftM PN quotelessString+unqtPortName = PN <$> quotelessString  -- ----------------------------------------------------------------------------- @@ -86,7 +84,7 @@    parse = quotedParse parseUnqt           `onFail`-          liftM checkPortName unqtPortName+          fmap checkPortName unqtPortName  checkPortName    :: PortName -> PortPos checkPortName pn = maybe (LabelledPort pn Nothing) CompassPoint@@ -96,7 +94,7 @@ -- | When attached to a node in a DotEdge definition, the 'PortName' --   and the 'CompassPoint' can be in separate quotes. parseEdgeBasedPP :: Parse PortPos-parseEdgeBasedPP = liftM2 LabelledPort parse (liftM Just $ character ':' >> parse)+parseEdgeBasedPP = liftA2 LabelledPort parse (fmap Just $ character ':' *> parse)                    `onFail`                    parse 
Data/GraphViz/Commands.hs view
@@ -45,9 +45,6 @@     , quitWithoutGraphviz     ) where --- Want to use the extensible-exception version-import Prelude hiding (catch)- import Data.GraphViz.Types -- This is here just for Haddock linking purposes. import Data.GraphViz.Attributes.Complete(Attribute(Z))
Data/GraphViz/Parsing.hs view
@@ -33,6 +33,7 @@     , checkValidParse       -- * Convenience parsing combinators.     , bracket+    , ignoreSep     , onlyBool     , quotelessString     , stringBlock@@ -68,6 +69,9 @@     , parseFieldsBool     , parseFieldDef     , parseFieldsDef+    , parseFieldNumDef+    , liftEqParse+    , liftEqParse'     , commaSep     , commaSepUnqt     , commaSep'@@ -96,7 +100,7 @@                 ) import Data.List(groupBy, sortBy) import Data.Function(on)-import Data.Maybe(fromMaybe, isNothing, listToMaybe)+import Data.Maybe(fromMaybe, isJust, isNothing, listToMaybe) import Data.Ratio((%)) import qualified Data.Set as Set import qualified Data.Text.Lazy as T@@ -104,7 +108,7 @@ import Data.Text.Lazy(Text) import Data.Word(Word8, Word16) import Control.Arrow(first, second)-import Control.Monad(liftM, liftM2, when)+import Control.Monad(when)  -- ----------------------------------------------------------------------------- -- Based off code from Text.Parse in the polyparse library@@ -122,7 +126,7 @@ runParser'   :: Parse a -> Text -> a runParser' p = checkValidParse . fst . runParser p'   where-    p' = p `discard` (whitespace >> eof)+    p' = p `discard` (whitespace *> eof)  class ParseDot a where   parseUnqt :: Parse a@@ -136,7 +140,7 @@                                `onFail`                                whitespace1                              )-                             (whitespace >> character ']')+                             (whitespace *> character ']')                              parseUnqt    parseList :: Parse [a]@@ -177,12 +181,12 @@    parseList = quotedParse parseUnqtList               `onFail`-              liftM return parse+              fmap (:[]) parse  instance ParseDot Bool where   parseUnqt = onlyBool               `onFail`-              liftM (zero /=) parseInt'+              fmap (zero /=) parseInt'     where       zero :: Int       zero = 0@@ -201,9 +205,9 @@           `onFail`           quotedParse parseUnqt -  parseUnqtList = liftM T.unpack parseUnqt+  parseUnqtList = T.unpack <$> parseUnqt -  parseList = liftM T.unpack parse+  parseList = T.unpack <$> parse  instance ParseDot Text where   -- Too many problems with using this within other parsers where@@ -227,34 +231,38 @@ quotelessString = numString `onFail` stringBlock  numString :: Parse Text-numString = liftM tShow parseStrictFloat+numString = fmap tShow parseStrictFloat             `onFail`-            liftM tShow parseInt'+            fmap tShow parseInt'   where     tShow :: (Show a) => a -> Text     tShow = T.pack . show  stringBlock :: Parse Text-stringBlock = do frst <- satisfy frstIDString-                 rest <- manySatisfy restIDString-                 return $ frst `T.cons` rest+stringBlock = liftA2 T.cons (satisfy frstIDString) (manySatisfy restIDString)  -- | Used when quotes are explicitly required; quotedString :: Parse Text quotedString = parseEscaped True [] []  parseSigned :: (Num a) => Parse a -> Parse a-parseSigned p = (character '-' >> liftM negate p)+parseSigned p = (character '-' *> fmap negate p)                 `onFail`                 p  parseInt :: (Integral a) => Parse a parseInt = do cs <- many1Satisfy isDigit+                    `adjustErr` ("Expected one or more digits\n\t"++)               case T.decimal cs of-                Right (n,"")  -> return n+                Right (n,"")  -> checkInt n+                -- This case should never actually happen...                 Right (_,txt) -> fail $ "Trailing digits not parsed as Integral: " ++ T.unpack txt                 Left err      -> fail $ "Could not read Integral: " ++ err-           `adjustErr` ("Expected one or more digits\n\t"++)+  where+    checkInt n = do c <- optional $ oneOf [ character '.', character 'e' ]+                    if isJust c+                      then fail "This number is actually Floating, not Integral!"+                      else return n  parseInt' :: Parse Int parseInt' = parseSigned parseInt@@ -265,9 +273,7 @@  parseFloat :: (RealFrac a) => Parse a parseFloat = do ds   <- manySatisfy isDigit-                frac <- optional-                        $ do character '.'-                             manySatisfy isDigit+                frac <- optional $ character '.' *> manySatisfy isDigit                 when (T.null ds && noDec frac)                   (fail "No actual digits in floating point number!")                 expn  <- optional parseExp@@ -280,8 +286,8 @@              `onFail`              fail "Expected a floating point number"   where-    parseExp = do character 'e'-                  ((character '+' >> parseInt)+    parseExp = character 'e'+               *> ((character '+' *> parseInt)                    `onFail`                    parseInt')     noDec = maybe True T.null@@ -289,7 +295,7 @@ parseFloat' :: Parse Double parseFloat' = parseSigned ( parseFloat                             `onFail`-                            liftM fI parseInt+                            fmap fI parseInt                           )   where     fI :: Integer -> Double@@ -303,10 +309,9 @@ --   'adjustErrBad' and thus doesn't allow backtracking and trying the --   next possible parser.  This is a version of @bracket@ that does. bracket               :: Parse bra -> Parse ket -> Parse a -> Parse a-bracket open close pa = do open `adjustErr` ("Missing opening bracket:\n\t"++)-                           pa `discard`-                             (close-                              `adjustErr` ("Missing closing bracket:\n\t"++))+bracket open close pa = (open `adjustErr` ("Missing opening bracket:\n\t"++))+                        *> pa+                        <* (close `adjustErr` ("Was expecting closing bracket:\n\t"++))  parseAndSpace   :: Parse a -> Parse a parseAndSpace p = p `discard` whitespace@@ -318,7 +323,7 @@ stringRep v = stringReps v . return  stringReps      :: a -> [String] -> Parse a-stringReps v ss = oneOf (map string ss) >> return v+stringReps v ss = oneOf (map string ss) *> return v  stringParse :: [(String, Parse a)] -> Parse a stringParse = toPM . sortBy (flip compare `on` fst)@@ -326,8 +331,8 @@     toPM = oneOf . map mkPM . groupBy ((==) `on` (listToMaybe . fst))      mkPM [("",p)] = p-    mkPM [(str,p)] = string str >> p-    mkPM kv = character (head . fst $ head kv) >> toPM (map (first tail) kv)+    mkPM [(str,p)] = string str *> p+    mkPM kv = character (head . fst $ head kv) *> toPM (map (first tail) kv)  stringValue :: [(String, a)] -> Parse a stringValue = stringParse . map (second return)@@ -350,13 +355,13 @@  -- | Parses at least one whitespace character. whitespace1 :: Parse ()-whitespace1 = many1Satisfy isSpace >> return ()+whitespace1 = many1Satisfy isSpace *> return ()  -- | Parses zero or more whitespace characters. whitespace :: Parse ()-whitespace = manySatisfy isSpace >> return ()+whitespace = manySatisfy isSpace *> return () --- | Parse and discard optional whitespace.+-- | Parse and discard optional surrounding whitespace. wrapWhitespace :: Parse a -> Parse a wrapWhitespace = bracket whitespace whitespace @@ -371,8 +376,8 @@ quotedParse :: Parse a -> Parse a quotedParse = bracket parseQuote parseQuote -parseQuote :: Parse Char-parseQuote = character quoteChar+parseQuote :: Parse ()+parseQuote = character quoteChar *> return ()  orQuote   :: Parse Char -> Parse Char orQuote p = stringRep quoteChar "\\\""@@ -388,7 +393,7 @@ --   'Bool' value indicates whether empty 'String's are allowed or --   not. parseEscaped             :: Bool -> [Char] -> [Char] -> Parse Text-parseEscaped empt cs bnd = liftM T.pack . lots $ qPrs `onFail` oth+parseEscaped empt cs bnd = fmap T.pack . lots $ qPrs `onFail` oth   where     lots = if empt then many else many1     cs' = quoteChar : slash : cs@@ -396,9 +401,10 @@     bndSet = Set.fromList bnd `Set.union` csSet     slash = '\\'     -- Have to allow standard slashes-    qPrs = do character slash-              mE <- optional $ oneOf (map character cs')-              return $ fromMaybe slash mE+    qPrs = fromMaybe slash+           <$> (character slash+                *> optional (oneOf $ map character cs')+               )     oth = satisfy (`Set.notMember` bndSet)  -- | Parses a newline.@@ -409,7 +415,7 @@ --   non-whitespace is reached.  The whitespace on that line is --   not consumed. newline' :: Parse ()-newline' = many (whitespace >> newline) >> return ()+newline' = many (whitespace *> newline) *> return ()  -- | Parses and returns all characters up till the end of the line, --   but does not touch the newline characters.@@ -417,10 +423,10 @@ consumeLine = manySatisfy (`notElem` ['\n','\r'])  parseEq :: Parse ()-parseEq = wrapWhitespace (character '=') >> return ()+parseEq = wrapWhitespace (character '=') *> return ()  parseField       :: (ParseDot a) => (a -> b) -> String -> [(String, Parse b)]-parseField c fld = [(fld, parseEq >> liftM c parse)]+parseField c fld = [(fld, liftEqParse' fld c)]  parseFields   :: (ParseDot a) => (a -> b) -> [String] -> [(String, Parse b)] parseFields c = concatMap (parseField c)@@ -436,7 +442,7 @@ parseFieldDef         :: (ParseDot a) => (a -> b) -> a -> String -> [(String, Parse b)] parseFieldDef c d fld = [(fld, p)]   where-    p = (parseEq >> liftM c parse)+    p = liftEqParse' fld c         `onFail`         do nxt <- optional $ satisfy restIDString            bool (fail "Not actually the field you were after")@@ -446,6 +452,34 @@ parseFieldsDef     :: (ParseDot a) => (a -> b) -> a -> [String] -> [(String, Parse b)] parseFieldsDef c d = concatMap (parseFieldDef c d) +-- | For numeric attributes, @dot -Tdot@ seems to use @\"\"@ to+--   indicate the default value.+parseFieldNumDef :: (ParseDot a) => (a -> b) -> a -> String -> [(String, Parse b)]+parseFieldNumDef c d fld = [(fld, liftEqParse p fld c)]+  where+    p = stringRep d "\"\""+        `onFail`+        parse++-- | 'liftEqParse'' using 'parse' as the parser.+liftEqParse' :: (ParseDot a) => String -> (a -> b) -> Parse b+liftEqParse' = liftEqParse parse++-- | Attempt to parse the @\"=value\"@ part of a @key=value@ pair.  If+--   there is an equal sign but the @value@ part doesn't parse, throw+--   an un-recoverable error.+liftEqParse :: Parse a -> String -> (a -> b) -> Parse b+liftEqParse p k c = parseEq+                    *> ( fmap c p+                         `adjustErrBad`+                         (("Unable to parse key=value with key of " ++ k+                           ++ "\n\t") ++)+                       )++-- | The opposite of 'bracket'.+ignoreSep :: (a -> b -> c) -> Parse a -> Parse sep -> Parse b -> Parse c+ignoreSep f pa sep pb = f <$> pa <* sep <*> pb+ commaSep :: (ParseDot a, ParseDot b) => Parse (a, b) commaSep = commaSep' parse parse @@ -453,19 +487,19 @@ commaSepUnqt = commaSep' parseUnqt parseUnqt  commaSep'       :: Parse a -> Parse b -> Parse (a,b)-commaSep' pa pb = do a <- pa-                     wrapWhitespace parseComma-                     b <- pb-                     return (a,b)+commaSep' pa pb = ignoreSep (,) pa (wrapWhitespace parseComma) pb  parseComma :: Parse ()-parseComma = character ',' >> return ()+parseComma = character ',' *> return () +-- | Try to parse a list of the specified type; returns an empty list+--   if parsing fails. tryParseList :: (ParseDot a) => Parse [a] tryParseList = tryParseList' parse +-- | Return an empty list if parsing a list fails. tryParseList' :: Parse [a] -> Parse [a]-tryParseList' = liftM (fromMaybe []) . optional+tryParseList' = fmap (fromMaybe []) . optional  parseAngled :: Parse a -> Parse a parseAngled = bracket (character '<') (character '>')@@ -482,13 +516,13 @@ parseColorScheme     :: Bool -> Parse ColorScheme parseColorScheme scs = do cs <- oneOf [ stringRep X11 "X11"                                       , stringRep SVG "svg"-                                      , liftM Brewer parseUnqt+                                      , Brewer <$> parseUnqt                                       ]                           when scs $ setColorScheme cs                           return cs  instance ParseDot BrewerScheme where-  parseUnqt = liftM2 BScheme parseUnqt parseUnqt+  parseUnqt = liftA2 BScheme parseUnqt parseUnqt  instance ParseDot BrewerName where   -- The order is different from above to make sure longer names are
Data/GraphViz/PreProcessing.hs view
@@ -16,8 +16,8 @@      * Split lines (by inserting a @\\@ the rest of that \"line\" is        continued on the next line). -     * 'Text's concatenated together using @\"...\" + \"...\"@; these-       are concatenated into one big 'Text'.+     * Strings concatenated together using @\"...\" + \"...\"@; these+       are concatenated into one big string. -} module Data.GraphViz.PreProcessing(preProcess) where @@ -29,7 +29,6 @@ import qualified Data.Text.Lazy.Builder as B import Data.Text.Lazy.Builder(Builder) import Data.Monoid(Monoid(..), mconcat)-import Control.Monad(liftM)  -- ----------------------------------------------------------------------------- -- Filtering out unwanted Dot items such as comments@@ -46,7 +45,7 @@ --   lines only over a single line.  Should parse the /entire/ input --   'Text'. parseOutUnwanted :: Parse Builder-parseOutUnwanted = liftM mconcat (many getNext)+parseOutUnwanted = mconcat <$> many getNext   where     getNext = parseOK               `onFail`@@ -56,10 +55,11 @@               `onFail`               parseUnwanted               `onFail`-              liftM B.singleton next-    parseOK = liftM B.fromLazyText-              $ many1Satisfy (`notElem` ['\n', '\r', '\\', '/', '"', '<'])+              fmap B.singleton next +    parseOK = B.fromLazyText+              <$> many1Satisfy (`notElem` ['\n', '\r', '\\', '/', '"', '<'])+ -- | Parses an unwanted part of the Dot code (comments and --   pre-processor lines; also un-splits lines). parseUnwanted :: (Monoid m) => Parse m@@ -74,65 +74,58 @@ --   previous line, but will leave the one from the pre-processor line --   there (so in the end it just removes the line). parsePreProcessor :: (Monoid m) => Parse m-parsePreProcessor = do newline-                       character '#'-                       consumeLine-                       return mempty+parsePreProcessor = newline *> character '#' *> consumeLine *> pure mempty  -- | Parse @//@-style comments. parseLineComment :: (Monoid m) => Parse m-parseLineComment = do string "//"-                      -- Note: do /not/ consume the newlines, as they're-                      -- needed in case the next line is a pre-processor-                      -- line.-                      consumeLine-                      return mempty+parseLineComment = string "//"+                   -- Note: do /not/ consume the newlines, as they're+                   -- needed in case the next line is a pre-processor+                   -- line.+                   *> consumeLine+                   *> pure mempty  -- | Parse @/* ... */@-style comments. parseMultiLineComment :: (Monoid m) => Parse m-parseMultiLineComment = bracket start end (many inner)-                        >> return mempty+parseMultiLineComment = bracket start end (many inner) *> pure mempty   where     start = string "/*"     end = string "*/"-    inner = (many1Satisfy ('*' /=) >> return ())+    inner = (many1Satisfy ('*' /=) *> pure ())             `onFail`-            do character '*'-               satisfy ('/' /=)-               inner+            (character '*' *> satisfy ('/' /=) *> inner)  parseConcatStrings :: Parse Builder-parseConcatStrings = liftM (wrapQuotes . mconcat)-                     $ sepBy1 parseString parseConcat+parseConcatStrings = wrapQuotes . mconcat <$> sepBy1 parseString parseConcat   where     qParse = bracket (character '"') (commit $ character '"')-    parseString = qParse (liftM mconcat $ many parseInner)-    parseInner = (string "\\\"" >> return (B.fromLazyText $ T.pack "\\\""))+    parseString = qParse (mconcat <$> many parseInner)+    parseInner = (string "\\\"" *> pure (B.fromLazyText $ T.pack "\\\""))                  `onFail`                  -- Need to parse an explicit `\', in case it ends the                  -- string (and thus the next step would get parsed by the                  -- previous option).-                 (string "\\\\" >> return (B.fromLazyText $ T.pack "\\\\"))+                 (string "\\\\" *> pure (B.fromLazyText $ T.pack "\\\\"))                  `onFail`                  parseSplitLine -- in case there's a split mid-quote                  `onFail`-                 liftM B.singleton (satisfy (quoteChar /=))-    parseConcat = parseSep >> character '+' >> parseSep+                 fmap B.singleton (satisfy (quoteChar /=))+    parseConcat = parseSep *> character '+' *> parseSep     parseSep = many $ whitespace1 `onFail` parseUnwanted     wrapQuotes str = qc `mappend` str `mappend` qc     qc = B.singleton '"'  -- | Lines can be split with a @\\@ at the end of the line. parseSplitLine :: (Monoid m) => Parse m-parseSplitLine = character '\\' >> newline >> return mempty+parseSplitLine = character '\\' *> newline *> pure mempty  parseHTML :: Parse Builder-parseHTML = liftM (addAngled . mconcat)+parseHTML = fmap (addAngled . mconcat)             . parseAngled $ many inner   where     inner = parseHTML             `onFail`-            (liftM B.fromLazyText $ many1Satisfy (\c -> c /= open && c /= close))+            (B.fromLazyText <$> many1Satisfy (\c -> c /= open && c /= close))     addAngled str = B.singleton open `mappend` str `mappend` B.singleton close     open = '<'     close = '>'
Data/GraphViz/Printing.hs view
@@ -78,7 +78,9 @@                                                    , hPutDoc                                                    , Pretty(..)                                                    , bool-                                                   , string)+                                                   , string+                                                   , width+                                                   , (<$>)) import qualified Text.PrettyPrint.Leijen.Text.Monadic as PP import qualified Data.Text.Lazy as T import Data.Text.Lazy(Text)
Data/GraphViz/Types/Canonical.hs view
@@ -91,7 +91,6 @@ import Data.GraphViz.Util(bool)  import Control.Arrow((&&&))-import Control.Monad(liftM)  -- ----------------------------------------------------------------------------- @@ -182,8 +181,8 @@   parseUnqt = parseSubGraph DotSG parseUnqt               `onFail`               -- Take "anonymous" DotSubGraphs into account.-              liftM (DotSG False Nothing)-                    (parseBracesBased SubGraphAttribute parseUnqt)+              fmap (DotSG False Nothing)+                   (parseBracesBased SubGraphAttribute parseUnqt)    parse = parseUnqt -- Don't want the option of quoting           `adjustErr`
Data/GraphViz/Types/Common.hs view
@@ -26,7 +26,7 @@ import qualified Data.Text.Lazy as T import qualified Data.Text.Lazy.Read as T import Data.Text.Lazy(Text)-import Control.Monad(liftM, liftM2, when)+import Control.Monad(when, unless)  -- ----------------------------------------------------------------------------- -- This is re-exported by Data.GraphViz.Types@@ -49,9 +49,9 @@   toDot gID       = unqtDot gID  instance ParseDot GraphID where-  parseUnqt = liftM stringNum parseUnqt+  parseUnqt = stringNum <$> parseUnqt -  parse = liftM stringNum parse+  parse = stringNum <$> parse           `adjustErr`           ("Not a valid GraphID\n\t"++) @@ -115,13 +115,13 @@                  oldTp <- getAttributeType                  maybe (return ()) setAttributeType mtp -                 as <- whitespace >> parse+                 as <- whitespace *> parse                   -- Safe to set back even if not changed.                  setAttributeType oldTp                  return $ gat as               `onFail`-              liftM determineType parse+              fmap determineType parse    parse = parseUnqt -- Don't want the option of quoting           `adjustErr`@@ -184,14 +184,14 @@   parseList = parseUnqtList  parseNodeID :: (ParseDot n) => Parse (Attributes -> DotNode n)-parseNodeID = liftM DotNode parseAndCheck+parseNodeID = DotNode <$> parseAndCheck   where     parseAndCheck = do n <- parse                        me <- optional parseUnwanted                        maybe (return n) (const notANode) me     notANode = fail "This appears to be an edge, not a node"-    parseUnwanted = oneOf [ parseEdgeType >> return ()-                          , character ':' >> return () -- PortPos value+    parseUnwanted = oneOf [ parseEdgeType *> return ()+                          , character ':' *> return () -- PortPos value                           ]  instance Functor DotNode where@@ -227,22 +227,20 @@   instance (ParseDot n) => ParseDot (DotEdge n) where-  parseUnqt = parseAttrBased EdgeAttribute True parseEdgeID+  parseUnqt = parseAttrBased EdgeAttribute False parseEdgeID    parse = parseUnqt -- Don't want the option of quoting    -- Have to take into account edges of the type "n1 -> n2 -> n3", etc.-  parseUnqtList = liftM concat-                  $ parseStatements parseEdgeLine+  parseUnqtList = concat <$> parseStatements parseEdgeLine    parseList = parseUnqtList  parseEdgeID :: (ParseDot n) => Parse (Attributes -> DotEdge n)-parseEdgeID = do eFrom <- parseEdgeNode-                 -- Parse both edge types just to be more liberal-                 parseEdgeType-                 eTo <- parseEdgeNode-                 return $ mkEdge eFrom eTo+parseEdgeID = ignoreSep mkEdge parseEdgeNode parseEdgeType parseEdgeNode+              `adjustErr`+              ("Parsed beginning of DotEdge but could not parse Attributes:\n\t"++)+              -- Parse both edge types just to be more liberal  type EdgeNode n = (n, Maybe PortPos) @@ -254,11 +252,11 @@                                $ parseStatements parseEdgeNode                              )                  `onFail`-                 liftM return parseEdgeNode+                 fmap (:[]) parseEdgeNode  parseEdgeNode :: (ParseDot n) => Parse (EdgeNode n)-parseEdgeNode = liftM2 (,) parse-                           (optional $ character ':' >> parseEdgeBasedPP)+parseEdgeNode = liftA2 (,) parse+                           (optional $ character ':' *> parseEdgeBasedPP)  mkEdge :: EdgeNode n -> EdgeNode n -> Attributes -> DotEdge n mkEdge (eFrom, mFP) (eTo, mTP) = DotEdge eFrom eTo@@ -267,7 +265,7 @@  mkEdges :: [EdgeNode n] -> [EdgeNode n]            -> Attributes -> [DotEdge n]-mkEdges fs ts as = liftM2 (\f t -> mkEdge f t as) fs ts+mkEdges fs ts as = liftA2 (\f t -> mkEdge f t as) fs ts  addPortPos   :: (PortPos -> Attribute) -> Maybe PortPos                 -> Attributes -> Attributes@@ -280,12 +278,11 @@  parseEdgeLine :: (ParseDot n) => Parse [DotEdge n] parseEdgeLine = do n1 <- parseEdgeNodes-                   ens <- many1 $ do parseEdgeType-                                     parseEdgeNodes+                   ens <- many1 $ parseEdgeType *> parseEdgeNodes                    let ens' = n1 : ens                        efs = zipWith mkEdges ens' (tail ens')                        ef = return $ \ as -> concatMap ($as) efs-                   parseAttrBased EdgeAttribute True ef+                   parseAttrBased EdgeAttribute False ef  instance Functor DotEdge where   fmap f e = e { fromNode = f $ fromNode e@@ -351,8 +348,7 @@  parseGraphID   :: (Bool -> Bool -> Maybe GraphID -> a) -> Parse a parseGraphID f = do whitespace-                    str <- liftM isJust-                           $ optional (parseAndSpace $ string strGraph)+                    str <- isJust <$> optional (parseAndSpace $ string strGraph)                     dir <- parseAndSpace ( stringRep True dirGraph                                            `onFail`                                            stringRep False undirGraph@@ -390,7 +386,7 @@ parseBracesBased      :: AttributeType -> Parse a -> Parse a parseBracesBased tp p = do gs <- getsGS id                            setAttributeType tp-                           a <- whitespace >> parseBraced (wrapWhitespace p)+                           a <- whitespace *> parseBraced (wrapWhitespace p)                            modifyGS (const gs)                            return a                         `adjustErr`@@ -418,16 +414,15 @@ parseSubGraph         :: (Bool -> Maybe GraphID -> stmt -> c) -> Parse stmt -> Parse c parseSubGraph pid pst = do (isC, fID) <- parseSubGraphID pid                            let tp = bool SubGraphAttribute ClusterAttribute isC-                           liftM fID $ parseBracesBased tp pst+                           fID <$> parseBracesBased tp pst  parseSubGraphID   :: (Bool -> Maybe GraphID -> c) -> Parse (Bool,c)-parseSubGraphID f = do string sGraph-                       whitespace1-                       (isC,mid) <- parseSGID-                       return (isC, f isC mid)+parseSubGraphID f = appl <$> (string sGraph *> whitespace1 *> parseSGID)+  where+    appl (isC, mid) = (isC, f isC mid)  parseSGID :: Parse (Bool, Maybe GraphID)-parseSGID = oneOf [ liftM getClustFrom $ parseAndSpace parse+parseSGID = oneOf [ getClustFrom <$> parseAndSpace parse                   , return (False, Nothing)                   ]   where@@ -440,7 +435,7 @@     pStr = do isCl <- checkCl                       `onFail`                       return False-              when isCl $ optional (character '_') >> return ()+              when isCl $ optional (character '_') *> return ()               sID <- optional pID               let sID' = if sID == emptyID                          then Nothing@@ -451,7 +446,7 @@      -- For Strings, there are no more quotes to unescape, so consume     -- what you can.-    pID = liftM stringNum $ manySatisfy (const True)+    pID = stringNum <$> manySatisfy (const True)  {- This is a much nicer definition, but unfortunately it doesn't work.    The problem is that Graphviz decides that a subgraph is a cluster@@ -462,9 +457,9 @@                        `onFail`                        return False                sID <- optional $ do when isCl-                                      $ optional (character '_') >> return ()+                                      $ optional (character '_') *> return ()                                     parseUnqt-               when (isCl || isJust sID) $ whitespace1 >> return ()+               when (isCl || isJust sID) $ whitespace1 *> return ()                return (isCl, sID) -} @@ -474,8 +469,8 @@ printAttrBased prEmp ff ftp fas a = do oldType <- getAttributeType                                        maybe (return ()) setAttributeType mtp                                        oldCS <- getColorScheme-                                       (dc <> semi) <* setAttributeType oldType-                                                    <* when prEmp (setColorScheme oldCS)+                                       (dc <> semi) <* unless prEmp (setColorScheme oldCS)+                                                    <* setAttributeType oldType   where     mtp = ftp a     f = ff a@@ -494,8 +489,8 @@                             setAttributeType tp                             oldCS <- getColorScheme                             f <- p-                            atts <- tryParseList' (whitespace >> parse)-                            when lc $ setColorScheme oldCS+                            atts <- tryParseList' (whitespace *> parse)+                            unless lc $ setColorScheme oldCS                             when (tp /= oldType) $ setAttributeType oldType                             return $ f atts                          `adjustErr`@@ -507,16 +502,16 @@  -- | Parse the separator (and any other whitespace1 present) between statements. statementEnd :: Parse ()-statementEnd = parseSplit >> newline'+statementEnd = parseSplit *> newline'   where-    parseSplit = (whitespace >> oneOf [ character ';' >> return ()-                                       , newline-                                       ]+    parseSplit = (whitespace *> oneOf [ character ';' *> return ()+                                      , newline+                                      ]                  )                  `onFail`                  whitespace1  parseStatements   :: Parse a -> Parse [a]-parseStatements p = sepBy (whitespace >> p) statementEnd+parseStatements p = sepBy (whitespace *> p) statementEnd                     `discard`                     optional statementEnd
Data/GraphViz/Types/Generalised.hs view
@@ -74,7 +74,6 @@ import qualified Data.Foldable as F import qualified Data.Traversable as T import Control.Arrow((&&&))-import Control.Monad(liftM) import Control.Monad.Trans.State(get, put, modify, execState, evalState)  -- -----------------------------------------------------------------------------@@ -154,7 +153,7 @@ printGStmts = toDot . F.toList  parseGStmts :: (ParseDot n) => Parse (DotStatements n)-parseGStmts = liftM Seq.fromList parse+parseGStmts = Seq.fromList <$> parse  statementStructure :: DotStatements n -> GraphState () statementStructure = F.mapM_ stmtStructure@@ -191,24 +190,24 @@   listToDot = unqtListToDot  instance (ParseDot n) => ParseDot (DotStatement n) where-  parseUnqt = oneOf [ liftM GA parseUnqt-                    , liftM SG parseUnqt-                    , liftM DN parseUnqt-                    , liftM DE parseUnqt+  parseUnqt = oneOf [ GA <$> parseUnqt+                    , SG <$> parseUnqt+                    , DN <$> parseUnqt+                    , DE <$> parseUnqt                     ]    parse = parseUnqt -- Don't want the option of quoting           `adjustErr`-          (++ "Not a valid statement")+          ("Not a valid statement\n\t"++) -  parseUnqtList = liftM concat . wrapWhitespace+  parseUnqtList = fmap concat . wrapWhitespace                   $ parseStatements p     where       -- Have to do something special here because of "a -> b -> c"       -- syntax for edges.-      p = liftM (map DE) parseEdgeLine+      p = fmap (map DE) parseEdgeLine           `onFail`-          liftM return parse+          fmap (:[]) parse    parseList = parseUnqtList @@ -262,14 +261,14 @@   parseUnqt = parseSubGraph DotSG parseGStmts               `onFail`               -- Take anonymous DotSubGraphs into account-              liftM (DotSG False Nothing)-                    (parseBracesBased SubGraphAttribute parseGStmts)+              fmap (DotSG False Nothing)+                   (parseBracesBased SubGraphAttribute parseGStmts)    parse = parseUnqt -- Don't want the option of quoting           `adjustErr`-          (++ "\n\nNot a valid Sub Graph")+          ("Not a valid Sub Graph\n\t"++) -  parseUnqtList = sepBy (whitespace >> parseUnqt) newline'+  parseUnqtList = sepBy (whitespace *> parseUnqt) newline'    parseList = parseUnqtList @@ -298,8 +297,8 @@     newStmts = evalState (stsRe $ graphStatements dg) startN      stsRe = T.mapM stRe-    stRe (SG sg) = liftM SG $ sgRe sg-    stRe stmt    = return stmt+    stRe (SG sg) = SG <$> sgRe sg+    stRe stmt    = pure stmt     sgRe sg = do sgid' <- case subGraphID sg of                             Nothing -> do n <- get                                           put $ succ n
Data/GraphViz/Types/Graph.hs view
@@ -114,8 +114,8 @@ import Data.Map(Map) import qualified Data.Set as S import qualified Data.Sequence as Seq+import Control.Applicative(liftA2, (<$>), (<*>)) import Control.Arrow((***))-import Control.Monad(liftM, liftM2) import Text.Read(Lexeme(Ident), lexP, parens, readPrec) import Text.ParserCombinators.ReadPrec(prec) @@ -361,7 +361,7 @@     lns = map (\ (n,ni) -> (n,(_inCluster ni, _attributes ni)))           . M.assocs $ values dg -    (cs,ns) = clustersToNodes pathOf id clustAs snd lns+    (cs,ns) = clustersToNodes pathOf (const True) id clustAs snd lns      pathOf (n,(c,as)) = pathFrom c (n,as)     pathFrom c ln = F.foldr C (N ln) . fromMaybe Seq.empty $ (`M.lookup`pM) =<< c@@ -471,7 +471,7 @@     invNs = usedClustsIn . M.map _inCluster $ values dg      usedClustsIn = M.fromAscList-                   . map (liftM2 (,) (fst . head) (map snd))+                   . map ((,) <$> fst . head <*> map snd)                    . groupSortBy fst                    . mapMaybe (uncurry (fmap . flip (,)))                    . M.assocs@@ -489,7 +489,7 @@  -- | Determine if this graph has nodes or clusters. isEmptyGraph :: DotGraph n -> Bool-isEmptyGraph = liftM2 (&&) isEmpty (not . hasClusters)+isEmptyGraph = liftA2 (&&) isEmpty (not . hasClusters)  graphAttributes :: DotGraph n -> [GlobalAttributes] graphAttributes = fromGlobAttrs . graphAttrs@@ -575,7 +575,7 @@  -- | Uses the ParseDot instance for generalised 'G.DotGraph's. instance (Ord n, ParseDot n) => ParseDot (DotGraph n) where-  parseUnqt = liftM fromGDot $ parseUnqt+  parseUnqt = fromGDot <$> parseUnqt     where       -- fromGDot :: G.DotGraph n -> DotGraph n       fromGDot = fromDotRepr . flip asTypeOf (undefined :: G.DotGraph n)@@ -657,7 +657,7 @@                  -> Map n (EdgeMap n) toEdgeMap f t = M.map eM . M.fromList . groupSortCollectBy f t'   where-    t' = liftM2 (,) t edgeAttributes+    t' = liftA2 (,) t edgeAttributes     eM = M.fromList . groupSortCollectBy fst snd  mapNs :: (Ord n, Ord n') => (n -> n') -> DotGraph n -> DotGraph n'
− FAQ
@@ -1,644 +0,0 @@-% FAQ-% Ivan Lazar Miljenovic--Fortuitously Anticipated Queries (FAQ)-======================================--Note that to distinguish it from [Graphviz], the library shall be-henceforth referred to as _graphviz_.--Graphviz vs _graphviz_-------------------------### What is the difference between Graphviz and _graphviz_? ###--[Graphviz] is an open source library and collection of utility-programs using that library to visualise [graphs] (which are specified-using the [Dot] language).--_graphviz_ is a library for the purely functional programming language-[Haskell] that provides "bindings" to Graphviz's programs.  It does so-by allowing programmers to specify the layout of the graph and then-converts that to Dot code before calling the appropriate program to-perform the visualisation.--[Graphviz]: http://www.graphviz.org/-[graphs]: http://en.wikipedia.org/wiki/Graph_theory-[Dot]: http://www.graphviz.org/doc/info/lang.html-[Haskell]: http://haskell.org/--### Why should I use graphviz over one of the other Haskell Graphviz libraries? ###--Various Haskell libraries have support for Graphviz to one extent or-another; however _graphviz_ has the most comprehensive support-available out of all of them:--* There are [four different representations] of Dot graphs:--       1. Canonical, which matches the layout of `dot -Tcanon`.-       2. Generalised, which allows statements to be in any order.-       3. A graph-based one that allows manipulation of the Dot graph.-       4. A monadic interface for embedding graphs in Haskell.--    There are also conversion functions between them.-- [four different representations]: #whats-the-difference-between-the-different-dotgraph-types--* The ability to parse and generate most aspects of Dot [syntax] and-  [attributes].  This includes taking into account escaping and-  quoting rules where applicable.--  [syntax]: http://graphviz.org/doc/info/lang.html-  [attributes]: http://graphviz.org/doc/info/attrs.html--* The ability to use a custom node type for Dot graphs.--* Support for the all five layout algorithm programs and all specified-  [output formats] as well as the ability to use custom programs, etc.--  [output formats]: http://www.graphviz.org/doc/info/output.html--* Functions to convert [FGL] graphs and other graph-like structures-  (albeit not as nicely) to and from the internal Dot representations.-  In future, this will be expanded to a much larger range of-  graph-like values once a suitable abstraction is available.--  [FGL]: http://web.engr.oregonstate.edu/~erwig/fgl/haskell/--* The ability to augment Dot and FGL graphs with positioning-  information by round-trip passing through Graphviz.--* Pure Haskell implementations of `dot -Tcanon` and `tred`.--* _graphviz_ is continually being worked upon and expanded to better-  suit/match the requirements of Graphviz, to improve performance and-  to make it easier for the programmer to use.--### Is the API of _graphviz_ stable? ###--For the most part, yes: the only items that are likely to change in-the future are those with bugs/errors or if a radically better way of-doing things is found.  For most uses, however, the API should not-change for the foreseeable future.--Note that _graphviz_'s version numbers follow the-[package versioning policy]; this means that you can immediately tell-when the API has had a backwards-incompatible change by comparing the-first two elements of the version.  However, these changes won't-always affect most users.--[package versioning policy]: http://www.haskell.org/haskellwiki/Package_versioning_policy--### What aspects of Dot syntax and attributes are covered? ###--It's easier to state which aspects of Dot [syntax] and [attributes]-_aren't_ covered:--#### Overall syntax items not covered ####--* Cannot specify a sub-graph as an end point in an edge;--* Comments, pre-processor lines and split lines are (currently) not-  supported within HTML-like labels.--* _graphviz_ only uses UTF-8 encoding for printing and parsing-  (whereas Graphviz allows Latin1 encoding with the `charset`-  attribute).--* Graphviz is more liberal in accepting "invalid" values-  (e.g. accepting a floating-point value when only integer values are-  meant to be accepted); _graphviz_ is more strict in this aspect (and-  will indeed throw an exception if it cannot parse something-  properly).--* No extensions (e.g. postscript-specific attributes) are available.--#### Attribute and value items not covered ####--* The global `orientation` attribute is not defined; however its-  behaviour is duplicated by the `rotate` attribute.--* The deprecated `overlap` algorithms have not been defined.--* `pointf` and `point` values have been combined into one datatype; as-  such, when constructing values such as `Rect` care should be taken-  about which parts of a `Point` are allowed.--* Only polygon-based `shape`s are available.--* The `charset` attribute is not available as _graphviz_ assumes that-  all Dot graphs will be in UTF-8 for simplicity; if Latin1-encoded-  graphs need to be parsed then you shall need to do all I/O for them-  by hand.--* `colorscheme` attributes _are_ parsed, but the behaviour is not-  quite the same: consider the following minimal Dot graph:--    ~~~~~ {.dot}-    digraph {-        a [ style=filled, fillcolor=gray, colorscheme=svg ]-    }-    ~~~~~--    Despite the fact that the color is specified before the colorscheme,-    Graphviz will use that colorscheme to parse the color (as an SVG-    gray differs from the X11 gray); _graphviz_, however, will use the-    default colorscheme of `x11` to parse the color, and **then** set-    the colorscheme to be `svg` (despite it not being used after it is-    set).--#### Available items of note ####--There are a few items of note that are available that are worthy of-special note (as they may not be immediately obvious from the-generated documentation):--* _graphviz_ is able to parse (but not print) the following special-  aspects of specifying edges in Dot code:--    - The `node:port` method of specifying of head/tail `portPos`-      values.--    - Stating multiple edges with common interior nodes (e.g. `a -> b-      -> c`).--    - Stating edges with a grouping of nodes (e.g. `a -> {b c}`).--* Sub-graphs are specified as being clusters when the subgraph name-  starts with either `"cluster"` or `"cluster_"`; note that this-  prefix is removed when determining the subraph's name for the-  internal datatypes.--* Anonymous subgraphs (where not even the `subgraph` keyword is-  specified) are also parseable.--* HTML-like and record labels are available, and feature proper-  escaping/unescaping when printing/parsing.--* Other syntactic issues are taken care of for you automatically (such-  as escaping/unescaping quotation marks).  Even newlines are-  automatically escaped (but not unescaped) for you, defaulting to-  centered lines.--Getting _graphviz_ and more documentation--------------------------------------------### Where can I obtain _graphviz_? ###--The best place to get _graphviz_ is from its [HackageDB] page.--[HackageDB]: http://hackage.haskell.org/package/graphviz--### Where can I find the API documentation for _graphviz_? ###--Also on its [HackageDB] page.--### Is it safe to install and use _graphviz_ from its darcs repository? ###--No; unlike other projects I make no guarantees as to the stability of-the live version of _graphviz_.  Whilst the [darcs] [repository] is-_usually_ stable, it's often in a state of flux and at times patches-that break the repository are recorded (when it's simpler/cleaner to-break one patch into several smaller patches).--[darcs]: http://darcs.net/-[repository]: http://code.haskell.org/graphviz/--### How is _graphviz_ licensed? ###--_graphviz_ is licensed under a [3-Clause BSD License] (note that the-ColorBrewer Color Schemes found in `Data.GraphViz.Attributes.Colors.Brewer`-are covered under-[their own license](http://graphviz.org/doc/info/colors.html#brewer_license)).--[3-Clause BSD License]: http://www.opensource.org/licenses/bsd-license.php--Simplistically, this means that you can do whatever you want with-_graphviz_ as long as you cite both myself and [Matthew Sackman] (the-original author) as being the authors of _graphviz_.  However, I would-appreciate at least an [email] letting me know how _graphviz_ is being-used.--[Matthew Sackman]: http://www.wellquite.org/-[email]: mailto:Ivan.Miljenovic+graphviz@gmail.com--### Where can I find more information on _graphviz_? ###--From its [home page].--[home page]: http://projects.haskell.org/graphviz/--### Are there any tutorials on how to use _graphviz_? ###--A basic tutorial on-[how to visualise graph-like data](http://ivanmiljenovic.wordpress.com/2011/10/16/graphviz-in-vacuum/)-is available; more will come if people ask for it.--### What other packages use _graphviz_? ###--This is a list of all known packages that use _graphviz_: if you know-of any others please let me know and I'll add it to the list.--* [Graphalyze](http://hackage.haskell.org/package/Graphalyze)-* [SourceGraph](http://hackage.haskell.org/package/SourceGraph)--### What is the history of _graphviz_? ###--_graphviz_ was originally written by [Matthew Sackman] (if you want-his reasons for doing so, you'll have to ask him yourself) with the-first known release being on 10 July, 2008.  In 2008 I (Ivan-Miljenovic) needed a library that provided bindings to Graphviz with-clustering support; at the time _graphviz_ was the most fully featured-and closest to what I wanted, so I submitted a patch that provided-support for both clustering and undirected graphs.--In April 2009, Matthew wanted to step down from maintaining _graphviz_-and asked if I wanted to take over.  Since then the library has been-almost completely re-written with greatly improved coverage of the Dot-language and extra features.  However, the original outline of the-library still remains.--Using _graphviz_-------------------### Can I start using _graphviz_ without knowing anything about Graphviz? ###--You can, but if you want to start doing anything more advanced then-you should be reading Graphviz's documentation as well as-_graphviz_'s.  This is because the layout and design of _graphviz_ is-heavily based upon the Dot language and the various [attributes] that-Graphviz supports.--### Can I just use _graphviz_ without reading its documentation? ###--You should _at least_ read the various messages about possible-ambiguities, etc. at the top of each module and for the attributes you-use before you use _graphviz_.--### Do I need to have Graphviz installed to use _graphviz_? ###--Technically, no if you're only dealing with the Dot language aspects.-However, usage of the functions in the `Commands` module, or the-augmentation of pretty-printing functions in the GraphViz module _do_-require Graphviz to be installed.--### Why didn't you use FFI to bind to the Graphviz library? ###--Because I just kept working where [Matthew Sackman] left off and it-was already using Graphviz's tools rather than the actual library.-However, most other language bindings (for Python, Perl, etc.) seem to-do the same: generate Dot code and pass that to the relevant tool.--This, however, does provide a fortunate side effect where the ability-to print and parse Dot code means that _graphviz_ can be used for more-than just visualising graphs created solely in Haskell: it can also-import pre-defined graphs, or else generate Dot code for use with-other tools.--### What's the difference between the different DotGraph types? ###--_graphviz_ has four different "implementations" of Dot code:--**Canonical:**--:   matches the output of `dot -Tcanon`.  Recommended for use when-    converting existing data into Dot (especially with the-    `graphElemsToDot` function in `Data.GraphViz`).--**Generalised:**--:   most closely matches the layout of actual Dot code, as such this is-    preferred when parsing in arbitrary Dot graphs.  Also useful in-    cases where you want to use the common Graphviz "hack" of specifying-    global attributes that don't apply to sub-graphs _after_ the-    sub-graphs in question.--**Graph:**--:   provides common graph operations on Dot graphs, based upon those-    found in the [FGL].--**Monadic:**--:   a nicer way of defining relatively static Dot graphs to embed within-    Haskell code, etc.  Loosely based (with permission!) upon Andy-    Gill's [dotgen] library.--[dotgen]: http://hackage.haskell.org/package/dotgen--### What's the best way to parse Dot code? ###--In both cases below, you should use the `parseDotGraph` function to-parse the Dot code: this is because it will strip out comments and-pre-processor lines and join together split lines (if any of these-remain the parser will fail).  Also, if you are not sure what the type-of the nodes are, use either String or else the `GraphID` type as it-explicitly caters for both Strings and numbers (whereas just assuming-it being a String will result in numbers being stored internally as a-String).--If you can, first run `dot -Tcanon` on the Dot code and parse it as a-`DotGraph` value.  This is because `DotGraph` types are easier to deal-with.--If, however, this isn't possible (e.g. it uses an image that isn't in-the current working directory) then use the `GDotGraph` type.--### There are too many attributes!!! Which ones should I use? ###--The `Data.GraphViz.Attributes` module contains a cut-down list of-recommended and commonly used attributes.--The entire list of attributes can be found in-`Data.GraphViz.Attributes.Complete`.  In particular, the following-attributes are **not** recommended for use:--* `Color` for anything except edge colours or gradients for nodes,-  clusters and graphs when using Graphviz >= 2.29.0 (and if you must,-  the border colour for a node).--* `ColorScheme`: just stick with X11 colours.--* `Comment`: pretty useless.  Enough said.--### Can I use any attribute wherever I want? ###--No: attributes are all defined in one big datatype for the sake of-simplicity, but not all attributes are valid in all places.  Read the-documentation (either for Graphviz or _graphviz_) to determine which is-suitable where.--### How can I use _graphviz_ to visualise non-FGL graphs? ###--The `graphElemsToDot` function allows you to visualise any graph for-which you can specify a list of labelled nodes and a list of labelled-edges.--### How can I use/process multiple graphs like Graphviz does? ###--At one stage, _graphviz_ supported dealing with lists of `DotGraph`s;-however, it was found to be faster to deal with each graph-individually rather than try to get Graphviz to deal with them all in-one go.  In future, once the problem causing this has been tracked-down and fixed this feature will be returned.--### How can I use custom datatypes for node IDs? ###--The important thing here is to ensure that your custom datatype has-defined instances of `PrintDot` and `ParseDot`.  Probably the easiest-way of doing this is to have functions that convert between your type-and `String` and let graphviz determine how to print and parse those.-Here is an example of a more difficult type that should be printed-like `"1: Foo"`:--~~~~~~~~~~~~~~~~~~~~ {.haskell}-data MyType = MyType String Int--instance PrintDot MyType where-  unqtDot (MyType s i) = unqtDot i <> colon <+> unqtDot s--  -- We have a space in there, so we need quotes.-  toDot = doubleQuotes . unqtDot--instance ParseDot MyType where-  parseUnqt = do i <- parseUnqt-                 character ':'-                 whitespace1-                 s <- parseUnqt-                 return $ MyType s i--  -- Has at least one space, so it will be quoted.-  parse = quotedParse parseUnqt-~~~~~~~~~~~~~~~~~~~~--Things to note from this example:--* Whilst `PrintDot` and `ParseDot` have default definitions for-  `toDot` and `parse`, they assume the datatype doesn't need quotes;-  as such if the value will-  [need quoting](http://www.graphviz.org/doc/info/lang.html), then you-  should do so explicitly.--* It is better to use the `PrintDot` instances for common types such-  as `Int` and `String` rather than using the pretty-printers inbuilt-  conversion functions (`int`, `text`, etc.) to ensure that-  quotations, etc. are dealt with correctly.--* Be as liberal as you can when parsing, especially with whitespace:-  when printing only one space is used, yet when parsing we use the-  `whitespace1` parsing combinator that will parse all whitespace-  characters (but it must consume _at least_ one; there is a variant-  that does not need to parse any).--### When parsing Dot code, do I have to worry about the case? ###--Not at all: _graphviz_'s parser is case-insensitive; however, the-correct case is checked first so there is a slight degradation in-performance when the wrong case is used.--### How do I set portPos values for nodes in edges? ###--Graphviz allows you to specify edges such as `from:a -> to:b` where-the nodes "from" and "to" are defined with either `RecordLabel` or-`Html.Label` labels and have different sections; the edge is then drawn-from the "a" section of the "from" node to the "b" section of the "to"-node.--Whilst _graphviz_ can parse this, you can't define this yourself;-instead, do it the manual way:--~~~~~~~~~~~~~~~~~~~~ {.haskell}-DotEdge "from" "to" True [ TailPort (LabelledPort (PN "a") Nothing)-                         , HeadPort (LabelledPort (PN "b") Nothing)-                         ]-~~~~~~~~~~~~~~~~~~~~--I realise that doing this manually isn't as convenient, but I am open-to suggestions on how this can be improved.--Note where `TailPort` and `HeadPort` are used; the next question-explains this.--### Is there anything else I should know? ###--A few other things of note that you should know about:--* For an edge `a -> b`, Graphviz terms "a" to be the _tail_ node and-  "b" to be the _head_ node.--* When creating `GraphID` values for the graphs and sub-graphs, you-  should ensure that they won't clash with any of the `nodeID` values-  when printed to avoid possible problems.--* It is a good idea to have unique IDs for sub-graphs to ensure that-  global attributes are applied only to items in that sub-graph and so-  that clusters aren't combined (it took me a _long_ time to find out-  that this was the case).--* You should specify an ID for the overall graph when outputting to a-  format such as SVG as it becomes the title of that image.--* Graphviz allows a node to be "defined" twice with different-  attributes; in practice they are combined into one node.  Running-  Dot code through `dot -Tcanon` before parsing removes this problem.--* Several attributes are defined with taking a list of items; all of-  these assume that the provided lists are non-empty (sub-values are a-  different story).--* If a particular Dot graph is not parseable, the parser throws an-  error rather than failing gracefully.--Design Decisions-------------------### Why does _graphviz_ use Polyparse rather than Parsec? ###--Short answer: because _graphviz_ was already using [Polyparse] when I-started working on it (and I hadn't done any parsing before so I had-no preference either way).--[Polyparse]: http://www.cs.york.ac.uk/fp/polyparse/--Longer answer: Polyparse has several advantages I feel over [Parsec]:--* Simpler types.-* Avoids the whole "but Parsec-3 is slower than Parsec-2" debate (with-  its associated baggage/problems).-* Few inbuilt combinators: since there is no inbuilt `character`-  parsing combinator, there are no problems with _graphviz_ using its-  own case-less one.-* [Easier backtracking](http://www.cs.york.ac.uk/fp/polyparse/#how)--[Parsec]: http://hackage.haskell.org/package/parsec--### Why do you have four different representations of Dot graphs? ###--_graphviz_ has [four different representations] of Dot graphs.  Apart-from the reasons given before, the canonical implementation was the-original representation, whereas the generalised one was only-introduced in the 2999.8.0.0 release and the other two in the-2999.12.0.0 release.--Note, however, that I was thinking of adding something like the-generalised implementation back around the time of the-[2999.0.0.0 release](http://www.haskell.org/pipermail/haskell-cafe/2009-July/064436.html),-yet-[people didn't like the idea](http://www.haskell.org/pipermail/haskell-cafe/2009-July/064442.html).--The graph-based implementation was added solely so I could write as-(un-yet finished) tutorial, and thought others might find it useful.-The monadic implementation came about as an attempt to encourage more-people to use _graphviz_ rather than other libraries such as [dotgen],-and I thought a nicer way of writing Dot graphs might help (the-initial plans involved complicated type-hackery to try and almost make-it a DSL for actual Dot code; however it ended up being too-complicated and unwieldy).--### Why are only FGL graphs supported? ###--Love them or hate them, [FGL] currently provides the best graph-datatype and library available for Haskell at this time.  As such, if-any one graph type had to be chosen to have conversion functions-written for it then FGL is the best option.  Furthermore, I needed FGL-graph support (which is the much more important reason!).--### Why are the version numbers so high? ###--To make sure the latest release has the highest version number:-Matthew Sackman originally made releases with date-based versioning,-but when I switched to using the [package versioning policy] I had to-change this.  I could have started with 2010.x.y.z or so, but at the-time I had initial hopes of introducing compatibility with other-graphs (not just [FGL] ones) soon and wanted to make that the-3000.0.0.0 release; however that has not yet come to pass.--### Why do you use the American spelling of colour in _graphviz_? ###--Because that's how Graphviz spells it, and I was following upstream to-avoid confusion.--Bugs, Feature Requests and Development-----------------------------------------### Do you have any future plans for _graphviz_? ###--Yes, I do!  See the TODO file for more information.--### Does _graphviz_ have a test suite? ###--Yes, there is: to get it, you have to build it with the `test` flag-enabled; for example:--~~~~~~~~~~~~~~~~~~~~ {.bash}-cabal install graphviz --flags=test-~~~~~~~~~~~~~~~~~~~~--Then run the `graphviz-testsuite` executable.  This test suite uses-[QuickCheck] to ensure that _graphviz_ can parse the Dot code it-generates (as well as a few other things).  Note that it isn't-perfect: there are no guarantees that the Dot graphs that are-generated are indeed valid, and those more extensive tests are not yet-available.--[QuickCheck]: http://hackage.haskell.org/package/QuickCheck--Furthermore, you can do more controlled testing to try and track down-the source of a bug as the above flag will also expose several-testing modules which give you access to the various tests used as-well as the `Arbitrary` instances for use with [QuickCheck].--For proper testing of real-life Dot code, there is also the-`TestParsing.hs` script that comes in the _graphviz_ tarball (but is-not installed).  Once you have _graphviz_ installed you can just run-this script, passing it any files containing Dot graphs you wish to-test.  It will attempt to parse each Dot graph as a `GDotGraph`, and-then test to see if the canonicalised form is parseable as a-`DotGraph`.--### I've found a bug! ###--Oh-oh... please [email] me the specifics of what you were doing-(including the Dot file in question if it's a parsing problem) and-I'll get right on it.--### I have a feature request. ###--Is it in the TODO?  If not, [email] me and I'll consider implementing-it (depending on time and how well I think it will fit in the overall-library).--### I want to help out with developing _graphviz_. ###--Great!  Whether you have a specific feature in mind or want to help-clear the TODO list, please [email] me to check with what you're doing-(who knows, I could already be implementing that very feature).--Once we've discussed what you're going to do, first get yourself a-copy of the darcs repository:--~~~~~~~~~~~~~~~~~~~~ {.bash}-darcs get --lazy http://code.haskell.org/graphviz-~~~~~~~~~~~~~~~~~~~~--Once you've made your changes, make sure you build and run the-testsuite (and ensure it passes!).  Then record the patch[es] and-`darcs send` them.  I'll then review them and if I'm happy with them,-I'll apply them.--### What is the purpose of the AttributeGenerator.hs file? ###--Graphviz has a large number of attributes.  Rather than try to edit-everything manually each time I want to change how I use the large-`Attribute` datatype, the AttributeGenerator script generates the-datatype, instances, etc. for me.--<!---     Local Variables:-     mode:markdown-     End:-  -->---<!--  LocalWords:  graphviz- -->
+ FAQ.md view
@@ -0,0 +1,632 @@+% FAQ+% Ivan Lazar Miljenovic++Fortuitously Anticipated Queries (FAQ)+======================================++Note that to distinguish it from [Graphviz], the library shall be+henceforth referred to as _graphviz_.++Graphviz vs _graphviz_+----------------------++### What is the difference between Graphviz and _graphviz_? ###++[Graphviz] is an open source library and collection of utility+programs using that library to visualise [graphs] (which are specified+using the [Dot] language).++_graphviz_ is a library for the purely functional programming language+[Haskell] that provides "bindings" to Graphviz's programs.  It does so+by allowing programmers to specify the layout of the graph and then+converts that to Dot code before calling the appropriate program to+perform the visualisation.++[Graphviz]: http://www.graphviz.org/+[graphs]: http://en.wikipedia.org/wiki/Graph_theory+[Dot]: http://www.graphviz.org/doc/info/lang.html+[Haskell]: http://haskell.org/++### Why should I use graphviz over one of the other Haskell Graphviz libraries? ###++Various Haskell libraries have support for Graphviz to one extent or+another; however _graphviz_ has the most comprehensive support+available out of all of them:++* There are [four different representations] of Dot graphs:++       1. Canonical, which matches the layout of `dot -Tcanon`.+       2. Generalised, which allows statements to be in any order.+       3. A graph-based one that allows manipulation of the Dot graph.+       4. A monadic interface for embedding graphs in Haskell.++    There are also conversion functions between them.++ [four different representations]: #whats-the-difference-between-the-different-dotgraph-types++* The ability to parse and generate most aspects of Dot [syntax] and+  [attributes].  This includes taking into account escaping and+  quoting rules where applicable.++  [syntax]: http://graphviz.org/doc/info/lang.html+  [attributes]: http://graphviz.org/doc/info/attrs.html++* The ability to use a custom node type for Dot graphs.++* Support for the all five layout algorithm programs and all specified+  [output formats] as well as the ability to use custom programs, etc.++  [output formats]: http://www.graphviz.org/doc/info/output.html++* Functions to convert [FGL] graphs and other graph-like structures+  (albeit not as nicely) to and from the internal Dot representations.+  In future, this will be expanded to a much larger range of+  graph-like values once a suitable abstraction is available.++  [FGL]: http://web.engr.oregonstate.edu/~erwig/fgl/haskell/++* The ability to augment Dot and FGL graphs with positioning+  information by round-trip passing through Graphviz.++* Pure Haskell implementations of `dot -Tcanon` and `tred`.++* _graphviz_ is continually being worked upon and expanded to better+  suit/match the requirements of Graphviz, to improve performance and+  to make it easier for the programmer to use.++### Is the API of _graphviz_ stable? ###++For the most part, yes: the only items that are likely to change in+the future are those with bugs/errors or if a radically better way of+doing things is found.  For most uses, however, the API should not+change for the foreseeable future.++Note that _graphviz_'s version numbers follow the+[package versioning policy]; this means that you can immediately tell+when the API has had a backwards-incompatible change by comparing the+first two elements of the version.  However, these changes won't+always affect most users.++[package versioning policy]: http://www.haskell.org/haskellwiki/Package_versioning_policy++### What aspects of Dot syntax and attributes are covered? ###++It's easier to state which aspects of Dot [syntax] and [attributes]+_aren't_ covered:++#### Overall syntax items not covered ####++* Cannot specify a sub-graph as an end point in an edge;++* Comments, pre-processor lines and split lines are (currently) not+  supported within HTML-like labels.++* _graphviz_ only uses UTF-8 encoding for printing and parsing+  (whereas Graphviz allows Latin1 encoding with the `charset`+  attribute).++* Graphviz is more liberal in accepting "invalid" values+  (e.g. accepting a floating-point value when only integer values are+  meant to be accepted); _graphviz_ is more strict in this aspect (and+  will indeed throw an exception if it cannot parse something+  properly).++* No extensions (e.g. postscript-specific attributes) are available.++#### Attribute and value items not covered ####++* The global `orientation` attribute is not defined; however its+  behaviour is duplicated by the `rotate` attribute.++* The deprecated `overlap` algorithms have not been defined.++* `pointf` and `point` values have been combined into one datatype; as+  such, when constructing values such as `Rect` care should be taken+  about which parts of a `Point` are allowed.++* Only polygon-based `shape`s are available.++* The `charset` attribute is not available as _graphviz_ assumes that+  all Dot graphs will be in UTF-8 for simplicity; if Latin1-encoded+  graphs need to be parsed then you shall need to do all I/O for them+  by hand.++* `colorscheme` attributes _are_ parsed, but the behaviour is not+  quite the same: consider the following minimal Dot graph:++    ~~~~~ {.dot}+    digraph {+        a [ style=filled, fillcolor=gray, colorscheme=svg ]+    }+    ~~~~~++    Despite the fact that the color is specified before the colorscheme,+    Graphviz will use that colorscheme to parse the color (as an SVG+    gray differs from the X11 gray); _graphviz_, however, will use the+    default colorscheme of `x11` to parse the color, and **then** set+    the colorscheme to be `svg` (despite it not being used after it is+    set).++#### Available items of note ####++There are a few items of note that are available that are worthy of+special note (as they may not be immediately obvious from the+generated documentation):++* _graphviz_ is able to parse (but not print) the following special+  aspects of specifying edges in Dot code:++    - The `node:port` method of specifying of head/tail `portPos`+      values.++    - Stating multiple edges with common interior nodes (e.g. `a -> b+      -> c`).++    - Stating edges with a grouping of nodes (e.g. `a -> {b c}`).++* Sub-graphs are specified as being clusters when the subgraph name+  starts with either `"cluster"` or `"cluster_"`; note that this+  prefix is removed when determining the subraph's name for the+  internal datatypes.++* Anonymous subgraphs (where not even the `subgraph` keyword is+  specified) are also parseable.++* HTML-like and record labels are available, and feature proper+  escaping/unescaping when printing/parsing.++* Other syntactic issues are taken care of for you automatically (such+  as escaping/unescaping quotation marks).  Even newlines are+  automatically escaped (but not unescaped) for you, defaulting to+  centered lines.++Getting _graphviz_ and more documentation+-----------------------------------------++### Where can I obtain _graphviz_? ###++The best place to get _graphviz_ is from its [HackageDB] page.++[HackageDB]: http://hackage.haskell.org/package/graphviz++### Where can I find the API documentation for _graphviz_? ###++Also on its [HackageDB] page.++### Is it safe to install and use _graphviz_ from its darcs repository? ###++No; unlike other projects I make no guarantees as to the stability of+the live version of _graphviz_.  Whilst the [darcs] [repository] is+_usually_ stable, it's often in a state of flux and at times patches+that break the repository are recorded (when it's simpler/cleaner to+break one patch into several smaller patches).++[darcs]: http://darcs.net/+[repository]: http://hub.darcs.net/ivanm/graphviz++### How is _graphviz_ licensed? ###++_graphviz_ is licensed under a [3-Clause BSD License] (note that the+ColorBrewer Color Schemes found in `Data.GraphViz.Attributes.Colors.Brewer`+are covered under+[their own license](http://graphviz.org/doc/info/colors.html#brewer_license)).++[3-Clause BSD License]: http://www.opensource.org/licenses/bsd-license.php++Simplistically, this means that you can do whatever you want with+_graphviz_ as long as you cite both myself and [Matthew Sackman] (the+original author) as being the authors of _graphviz_.  However, I would+appreciate at least an [email] letting me know how _graphviz_ is being+used.++[Matthew Sackman]: http://www.wellquite.org/+[email]: mailto:Ivan.Miljenovic+graphviz@gmail.com++### Where can I find more information on _graphviz_? ###++From its [home page].++[home page]: http://projects.haskell.org/graphviz/++### Are there any tutorials on how to use _graphviz_? ###++A basic tutorial on+[how to visualise graph-like data](http://ivanmiljenovic.wordpress.com/2011/10/16/graphviz-in-vacuum/)+is available; more will come if people ask for it.++### What other packages use _graphviz_? ###++This is a list of all known packages that use _graphviz_: if you know+of any others please let me know and I'll add it to the list.++* [Graphalyze](http://hackage.haskell.org/package/Graphalyze)+* [SourceGraph](http://hackage.haskell.org/package/SourceGraph)++### What is the history of _graphviz_? ###++_graphviz_ was originally written by [Matthew Sackman] (if you want+his reasons for doing so, you'll have to ask him yourself) with the+first known release being on 10 July, 2008.  In 2008 I (Ivan+Miljenovic) needed a library that provided bindings to Graphviz with+clustering support; at the time _graphviz_ was the most fully featured+and closest to what I wanted, so I submitted a patch that provided+support for both clustering and undirected graphs.++In April 2009, Matthew wanted to step down from maintaining _graphviz_+and asked if I wanted to take over.  Since then the library has been+almost completely re-written with greatly improved coverage of the Dot+language and extra features.  However, the original outline of the+library still remains.++Using _graphviz_+----------------++### Can I start using _graphviz_ without knowing anything about Graphviz? ###++You can, but if you want to start doing anything more advanced then+you should be reading Graphviz's documentation as well as+_graphviz_'s.  This is because the layout and design of _graphviz_ is+heavily based upon the Dot language and the various [attributes] that+Graphviz supports.++### Can I just use _graphviz_ without reading its documentation? ###++You should _at least_ read the various messages about possible+ambiguities, etc. at the top of each module and for the attributes you+use before you use _graphviz_.++### Do I need to have Graphviz installed to use _graphviz_? ###++Technically, no if you're only dealing with the Dot language aspects.+However, usage of the functions in the `Commands` module, or the+augmentation of pretty-printing functions in the GraphViz module _do_+require Graphviz to be installed.++### Why didn't you use FFI to bind to the Graphviz library? ###++Because I just kept working where [Matthew Sackman] left off and it+was already using Graphviz's tools rather than the actual library.+However, most other language bindings (for Python, Perl, etc.) seem to+do the same: generate Dot code and pass that to the relevant tool.++This, however, does provide a fortunate side effect where the ability+to print and parse Dot code means that _graphviz_ can be used for more+than just visualising graphs created solely in Haskell: it can also+import pre-defined graphs, or else generate Dot code for use with+other tools.++### What's the difference between the different DotGraph types? ###++_graphviz_ has four different "implementations" of Dot code:++**Canonical:**++:   matches the output of `dot -Tcanon`.  Recommended for use when+    converting existing data into Dot (especially with the+    `graphElemsToDot` function in `Data.GraphViz`).++**Generalised:**++:   most closely matches the layout of actual Dot code, as such this is+    preferred when parsing in arbitrary Dot graphs.  Also useful in+    cases where you want to use the common Graphviz "hack" of specifying+    global attributes that don't apply to sub-graphs _after_ the+    sub-graphs in question.++**Graph:**++:   provides common graph operations on Dot graphs, based upon those+    found in the [FGL].++**Monadic:**++:   a nicer way of defining relatively static Dot graphs to embed within+    Haskell code, etc.  Loosely based (with permission!) upon Andy+    Gill's [dotgen] library.++[dotgen]: http://hackage.haskell.org/package/dotgen++### What's the best way to parse Dot code? ###++In both cases below, you should use the `parseDotGraph` function to+parse the Dot code: this is because it will strip out comments and+pre-processor lines and join together split lines (if any of these+remain the parser will fail).  Also, if you are not sure what the type+of the nodes are, use either String or else the `GraphID` type as it+explicitly caters for both Strings and numbers (whereas just assuming+it being a String will result in numbers being stored internally as a+String).++If you can, first run `dot -Tcanon` on the Dot code and parse it as a+`DotGraph` value.  This is because `DotGraph` types are easier to deal+with.++If, however, this isn't possible (e.g. it uses an image that isn't in+the current working directory) then use the `GDotGraph` type.++### There are too many attributes!!! Which ones should I use? ###++The `Data.GraphViz.Attributes` module contains a cut-down list of+recommended and commonly used attributes.++The entire list of attributes can be found in+`Data.GraphViz.Attributes.Complete`.  In particular, the following+attributes are **not** recommended for use:++* `Color` for anything except edge colours or gradients for nodes,+  clusters and graphs when using Graphviz >= 2.29.0 (and if you must,+  the border colour for a node).++* `ColorScheme`: just stick with X11 colours.++* `Comment`: pretty useless.  Enough said.++### Can I use any attribute wherever I want? ###++No: attributes are all defined in one big datatype for the sake of+simplicity, but not all attributes are valid in all places.  Read the+documentation (either for Graphviz or _graphviz_) to determine which is+suitable where.++### How can I use _graphviz_ to visualise non-FGL graphs? ###++The `graphElemsToDot` function allows you to visualise any graph for+which you can specify a list of labelled nodes and a list of labelled+edges.++### How can I use/process multiple graphs like Graphviz does? ###++At one stage, _graphviz_ supported dealing with lists of `DotGraph`s;+however, it was found to be faster to deal with each graph+individually rather than try to get Graphviz to deal with them all in+one go.  In future, once the problem causing this has been tracked+down and fixed this feature will be returned.++### How can I use custom datatypes for node IDs? ###++The important thing here is to ensure that your custom datatype has+defined instances of `PrintDot` and `ParseDot`.  Probably the easiest+way of doing this is to have functions that convert between your type+and `String` or `Text` and let graphviz determine how to print and+parse those.  Here is an example of a more difficult type that should+be printed like `"1: Foo"`:++~~~~~~~~~~~~~~~~~~~~ {.haskell}+data MyType = MyType String Int++instance PrintDot MyType where+  unqtDot (MyType s i) = unqtDot i <> colon <+> unqtDot s++  -- We have a space in there, so we need quotes.+  toDot = doubleQuotes . unqtDot++instance ParseDot MyType where+  parseUnqt = MyType <$> parseUnqt+                     <*  character ':'+                     <*  whitespace1+                     <*> parseUnqt++  -- Has at least one space, so it will be quoted.+  parse = quotedParse parseUnqt+~~~~~~~~~~~~~~~~~~~~++Things to note from this example:++* Whilst `PrintDot` and `ParseDot` have default definitions for+  `toDot` and `parse`, they assume the datatype doesn't need quotes;+  as such if the value will+  [need quoting](http://www.graphviz.org/doc/info/lang.html), then you+  should do so explicitly.++* It is better to use the `PrintDot` instances for common types such+  as `Int` and `String` rather than using the pretty-printers inbuilt+  conversion functions (`int`, `text`, etc.) to ensure that+  quotations, etc. are dealt with correctly.++* Be as liberal as you can when parsing, especially with whitespace:+  when printing only one space is used, yet when parsing we use the+  `whitespace1` parsing combinator that will parse all whitespace+  characters (but it must consume _at least_ one; there is a variant+  that does not need to parse any).++### When parsing Dot code, do I have to worry about the case? ###++Not at all: _graphviz_'s parser is case-insensitive; however, the+correct case is checked first so there is a slight degradation in+performance when the wrong case is used.++### How do I set portPos values for nodes in edges? ###++Graphviz allows you to specify edges such as `from:a -> to:b` where+the nodes "from" and "to" are defined with either `RecordLabel` or+`Html.Label` labels and have different sections; the edge is then drawn+from the "a" section of the "from" node to the "b" section of the "to"+node.++Whilst _graphviz_ can parse this, you can't define this yourself;+instead, do it the manual way:++~~~~~~~~~~~~~~~~~~~~ {.haskell}+DotEdge "from" "to" True [ TailPort (LabelledPort (PN "a") Nothing)+                         , HeadPort (LabelledPort (PN "b") Nothing)+                         ]+~~~~~~~~~~~~~~~~~~~~++I realise that doing this manually isn't as convenient, but I am open+to suggestions on how this can be improved.++Note where `TailPort` and `HeadPort` are used; the next question+explains this.++### Is there anything else I should know? ###++A few other things of note that you should know about:++* For an edge `a -> b`, Graphviz terms "a" to be the _tail_ node and+  "b" to be the _head_ node.++* When creating `GraphID` values for the graphs and sub-graphs, you+  should ensure that they won't clash with any of the `nodeID` values+  when printed to avoid possible problems.++* It is a good idea to have unique IDs for sub-graphs to ensure that+  global attributes are applied only to items in that sub-graph and so+  that clusters aren't combined (it took me a _long_ time to find out+  that this was the case).++* You should specify an ID for the overall graph when outputting to a+  format such as SVG as it becomes the title of that image.++* Graphviz allows a node to be "defined" twice with different+  attributes; in practice they are combined into one node.  Running+  Dot code through `dot -Tcanon` before parsing removes this problem.++* Several attributes are defined with taking a list of items; all of+  these assume that the provided lists are non-empty (sub-values are a+  different story).++* If a particular Dot graph is not parseable, the parser throws an+  error rather than failing gracefully.++Design Decisions+----------------++### Why does _graphviz_ use Polyparse rather than Parsec? ###++Short answer: because _graphviz_ was already using [Polyparse] when I+started working on it (and I hadn't done any parsing before so I had+no preference either way).++[Polyparse]: http://www.cs.york.ac.uk/fp/polyparse/++Longer answer: Polyparse has several advantages I feel over [Parsec]:++* Simpler types.+* Avoids the whole "but Parsec-3 is slower than Parsec-2" debate (with+  its associated baggage/problems).+* Few inbuilt combinators: since there is no inbuilt `character`+  parsing combinator, there are no problems with _graphviz_ using its+  own case-less one.+* [Easier backtracking](http://www.cs.york.ac.uk/fp/polyparse/#how)++[Parsec]: http://hackage.haskell.org/package/parsec++### Why do you have four different representations of Dot graphs? ###++_graphviz_ has [four different representations] of Dot graphs.  Apart+from the reasons given before, the canonical implementation was the+original representation, whereas the generalised one was only+introduced in the 2999.8.0.0 release and the other two in the+2999.12.0.0 release.++Note, however, that I was thinking of adding something like the+generalised implementation back around the time of the+[2999.0.0.0 release](http://www.haskell.org/pipermail/haskell-cafe/2009-July/064436.html),+yet+[people didn't like the idea](http://www.haskell.org/pipermail/haskell-cafe/2009-July/064442.html).++The graph-based implementation was added solely so I could write as+(un-yet finished) tutorial, and thought others might find it useful.+The monadic implementation came about as an attempt to encourage more+people to use _graphviz_ rather than other libraries such as [dotgen],+and I thought a nicer way of writing Dot graphs might help (the+initial plans involved complicated type-hackery to try and almost make+it a DSL for actual Dot code; however it ended up being too+complicated and unwieldy).++### Why are only FGL graphs supported? ###++Love them or hate them, [FGL] currently provides the best graph+datatype and library available for Haskell at this time.  As such, if+any one graph type had to be chosen to have conversion functions+written for it then FGL is the best option.  Furthermore, I needed FGL+graph support (which is the much more important reason!).++### Why are the version numbers so high? ###++To make sure the latest release has the highest version number:+Matthew Sackman originally made releases with date-based versioning,+but when I switched to using the [package versioning policy] I had to+change this.  I could have started with 2010.x.y.z or so, but at the+time I had initial hopes of introducing compatibility with other+graphs (not just [FGL] ones) soon and wanted to make that the+3000.0.0.0 release; however that has not yet come to pass.++### Why do you use the American spelling of colour in _graphviz_? ###++Because that's how Graphviz spells it, and I was following upstream to+avoid confusion.++Bugs, Feature Requests and Development+--------------------------------------++### Do you have any future plans for _graphviz_? ###++Yes, I do!  See the TODO file for more information.++### Does _graphviz_ have a test suite? ###++Yes, there is, using the in-built support for test suites in Cabal:++~~~~~~~~~~~~~~~~~~~~ {.bash}+cabal install graphviz --enable-tests+~~~~~~~~~~~~~~~~~~~~++Then run the `graphviz-testsuite` executable.  This test suite uses+[QuickCheck] to ensure that _graphviz_ can parse the Dot code it+generates (as well as a few other things).  Note that it isn't+perfect: there are no guarantees that the Dot graphs that are+generated are indeed valid, and those more extensive tests are not yet+available.++[QuickCheck]: http://hackage.haskell.org/package/QuickCheck++Furthermore, you can do more controlled testing to try and track down+the source of a bug as the above flag will also expose several+testing modules which give you access to the various tests used as+well as the `Arbitrary` instances for use with [QuickCheck].++For proper testing of real-life Dot code, there is also the+`TestParsing.hs` script that comes in the _graphviz_ tarball (but is+not installed).  Once you have _graphviz_ installed you can just run+this script, passing it any files containing Dot graphs you wish to+test.  It will attempt to parse each Dot graph as a `GDotGraph`, and+then test to see if the canonicalised form is parseable as a+`DotGraph`.++### I've found a bug! ###++Oh-oh... please [email] me the specifics of what you were doing+(including the Dot file in question if it's a parsing problem) and+I'll get right on it.++### I have a feature request. ###++Is it in the TODO?  If not, [email] me and I'll consider implementing+it (depending on time and how well I think it will fit in the overall+library).++### I want to help out with developing _graphviz_. ###++Great!  Whether you have a specific feature in mind or want to help+clear the TODO list, please [email] me to check with what you're doing+(who knows, I could already be implementing that very feature).++Once we've discussed what you're going to do, first get yourself a+copy of the darcs repository:++~~~~~~~~~~~~~~~~~~~~ {.bash}+darcs get --lazy http://hub.darcs.net/ivanm/graphviz+~~~~~~~~~~~~~~~~~~~~++Once you've made your changes, make sure you build and run the+testsuite (and ensure it passes!).  Then record the patch[es] and+`darcs send` them.  I'll then review them and if I'm happy with them,+I'll apply them.++### What is the purpose of the AttributeGenerator.hs file? ###++Graphviz has a large number of attributes.  Rather than try to edit+everything manually each time I want to change how I use the large+`Attribute` datatype, the AttributeGenerator script generates the+datatype, instances, etc. for me.
− LICENSE
@@ -1,106 +0,0 @@-% License-% Ivan Lazar Miljenovic--Licensing Information-=====================--The overall graphviz library is covered by a [3-Clause BSD License].-However, the _ColorBrewer_ colours are licensed under their own-license.--[3-Clause BSD License]: http://www.opensource.org/licenses/bsd-license.php--License for graphviz-----------------------Copyright (c) 2008, Matthew Sackman--Copyright (c) 2008 - 2010, [Ivan Lazar Miljenovic](mailto:Ivan.Miljenovic+graphviz@gmail.com)--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.--   * The names of the contributors to this software may not 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.--The ColorBrewer license--------------------------> The _ColorBrewer_ colours and colour schemes found in-> `Data.GraphViz.Attributes.Colors` are covered by the following-> license.  This text is not part of the license.--Apache-Style Software License for ColorBrewer software and ColorBrewer-Color Schemes, Version 1.1--Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania-State University. All rights reserved.--Redistribution and use in source and binary forms, with or without-modification, are permitted provided that the following conditions are-met:--   1. Redistributions as source code must retain the above copyright-      notice, this list of conditions and the following disclaimer.--   2. The end-user documentation included with the redistribution, if-      any, must include the following acknowledgment:--      This product includes color specifications and designs developed-      by Cynthia Brewer (http://colorbrewer.org/).--      Alternately, this acknowledgment may appear in the software-      itself, if and wherever such third-party acknowledgments-      normally appear.--   3. The name "ColorBrewer" must not be used to endorse or promote-      products derived from this software without prior written-      permission. For written permission, please contact Cynthia-      Brewer at cbrewer@psu.edu.--   4. Products derived from this software may not be called-      "ColorBrewer", nor may "ColorBrewer" appear in their name,-      without prior written permission of Cynthia Brewer.--THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED 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 CYNTHIA BREWER, MARK HARROWER, OR THE-PENNSYLVANIA STATE UNIVERSITY 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.--<!---     Local Variables:-     mode:markdown-     End:-  -->
+ LICENSE.md view
@@ -0,0 +1,100 @@+% License+% Ivan Lazar Miljenovic++Licensing Information+=====================++The overall graphviz library is covered by a [3-Clause BSD License].+However, the _ColorBrewer_ colours are licensed under their own+license.++[3-Clause BSD License]: http://www.opensource.org/licenses/bsd-license.php++License for graphviz+--------------------++Copyright (c) 2008, Matthew Sackman++Copyright (c) 2008 - 2010, [Ivan Lazar Miljenovic](mailto:Ivan.Miljenovic+graphviz@gmail.com)++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.++   * The names of the contributors to this software may not 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.++The ColorBrewer license+-----------------------++> The _ColorBrewer_ colours and colour schemes found in+> `Data.GraphViz.Attributes.Colors` are covered by the following+> license.  This text is not part of the license.++Apache-Style Software License for ColorBrewer software and ColorBrewer+Color Schemes, Version 1.1++Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania+State University. All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++   1. Redistributions as source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++   2. The end-user documentation included with the redistribution, if+      any, must include the following acknowledgment:++      This product includes color specifications and designs developed+      by Cynthia Brewer (http://colorbrewer.org/).++      Alternately, this acknowledgment may appear in the software+      itself, if and wherever such third-party acknowledgments+      normally appear.++   3. The name "ColorBrewer" must not be used to endorse or promote+      products derived from this software without prior written+      permission. For written permission, please contact Cynthia+      Brewer at cbrewer@psu.edu.++   4. Products derived from this software may not be called+      "ColorBrewer", nor may "ColorBrewer" appear in their name,+      without prior written permission of Cynthia Brewer.++THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED 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 CYNTHIA BREWER, MARK HARROWER, OR THE+PENNSYLVANIA STATE UNIVERSITY 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
@@ -1,64 +0,0 @@-% Haskell bindings to the Graphviz toolkit-% Ivan Lazar Miljenovic--The graphviz Library-====================--The _graphviz_ library provides bindings to the [Graphviz] graph-visualisation suite of tools for the purely functional programming-language [Haskell].  It can be downloaded from [HackageDB] or - if you-have [cabal-install] - installing it is as simple as:--~~~~~~~~~~~~~~~~~~~~ {.bash}-cabal update-cabal install graphviz-~~~~~~~~~~~~~~~~~~~~--[Graphviz]: http://www.graphviz.org/-[Haskell]: http://haskell.org/-[HackageDB]: http://hackage.haskell.org/package/graphviz-[cabal-install]: http://haskell.org/haskellwiki/Cabal-Install--Library features-------------------Main features of the graphviz library include:--* Almost complete coverage of all Graphviz attributes and syntax.--* Support for specifying clusters.--* The ability to use a custom node type.--* Functions for running a Graphviz layout tool with all specified-  output types.--* The ability to not only generate but also parse Dot code with two-  options: strict and liberal (in terms of ordering of statements).--* Functions to convert [FGL] graphs and other graph-like data-  structures to Dot code - including support to group them into-  clusters - with a high degree of customisation by specifying which-  attributes to use and limited support for the inverse operation.--* Round-trip support for passing an [FGL] graph through Graphviz to-  augment node and edge labels with positional information, etc.--[FGL]: http://web.engr.oregonstate.edu/~erwig/fgl/haskell/--graphviz is free software licensed under a [3-Clause BSD License].--\(C\) 2008 [Matthew Sackman](http://www.wellquite.org/)--\(C\) 2008 - onwards [Ivan Lazar Miljenovic](http://ivanmiljenovic.wordpress.com/)--[3-Clause BSD License]: http://www.opensource.org/licenses/bsd-license.php--For more information, feel free to-[email](mailto:Ivan.Miljenovic+graphviz@gmail.com) me.--<!---     Local Variables:-     mode:markdown-     End:-  -->
+ README.md view
@@ -0,0 +1,58 @@+% Haskell bindings to the Graphviz toolkit+% Ivan Lazar Miljenovic++The graphviz Library+====================++The _graphviz_ library provides bindings to the [Graphviz] graph+visualisation suite of tools for the purely functional programming+language [Haskell].  It can be downloaded from [HackageDB] or - if you+have [cabal-install] - installing it is as simple as:++~~~~~~~~~~~~~~~~~~~~ {.bash}+cabal update+cabal install graphviz+~~~~~~~~~~~~~~~~~~~~++[Graphviz]: http://www.graphviz.org/+[Haskell]: http://haskell.org/+[HackageDB]: http://hackage.haskell.org/package/graphviz+[cabal-install]: http://haskell.org/haskellwiki/Cabal-Install++Library features+----------------++Main features of the graphviz library include:++* Almost complete coverage of all Graphviz attributes and syntax.++* Support for specifying clusters.++* The ability to use a custom node type.++* Functions for running a Graphviz layout tool with all specified+  output types.++* The ability to not only generate but also parse Dot code with two+  options: strict and liberal (in terms of ordering of statements).++* Functions to convert [FGL] graphs and other graph-like data+  structures to Dot code - including support to group them into+  clusters - with a high degree of customisation by specifying which+  attributes to use and limited support for the inverse operation.++* Round-trip support for passing an [FGL] graph through Graphviz to+  augment node and edge labels with positional information, etc.++[FGL]: http://web.engr.oregonstate.edu/~erwig/fgl/haskell/++graphviz is free software licensed under a [3-Clause BSD License].++\(C\) 2008 [Matthew Sackman](http://www.wellquite.org/)++\(C\) 2008 - onwards [Ivan Lazar Miljenovic](http://ivanmiljenovic.wordpress.com/)++[3-Clause BSD License]: http://www.opensource.org/licenses/bsd-license.php++For more information, feel free to+[email](mailto:Ivan.Miljenovic+graphviz@gmail.com) me.
− TODO
@@ -1,54 +0,0 @@-% TODO-% Ivan Lazar Miljenovic--Future Plans for graphviz-=========================--This is a list of planned feature improvements to graphviz along with-an indication of when it's likely to be implemented (note that these-time scales are in relation to releases, not actual time; however, it-is quite possible that the order will not be adhered to).--Short term-------------* Quickstart-style documentation to help users get going with graphviz-  quickly.--* Add nicer syntax for record labels, and specifying ports in Monadic-  Dot graphs.--* Define new classes to distinguish between printing/parsing Attribute-  values and other values (as only the former requires quoted-  variants).--* Clean up AttributeGenerator and get it to use a better-  pretty-printing library.--Medium term--------------* Improve the test suite such that the generated `DotGraph` values are-  valid (and thus can be passed to Graphviz proper).  This may not in-  fact be possible as guaranteeing an arbitrary `Attribute` is valid-  is rather tricky (as the value itself needs to be verified,-  especially stateful ones).--* Switch to a proper test-suite library rather than the hand-rolled-  one currently being used.--* Add support for clusters as endpoints of edges.--Long term------------* Allow usage of non-FGL graphs with graphviz.  This will require-  implementing a separate library to represent graphs (see initial-  discussions about this-  [here](http://www.haskell.org/pipermail/haskell-cafe/2009-June/063402.html)).--<!---     Local Variables:-     mode:markdown-     End:-  -->
+ TODO.md view
@@ -0,0 +1,48 @@+% TODO+% Ivan Lazar Miljenovic++Future Plans for graphviz+=========================++This is a list of planned feature improvements to graphviz along with+an indication of when it's likely to be implemented (note that these+time scales are in relation to releases, not actual time; however, it+is quite possible that the order will not be adhered to).++Short term+----------++* Quickstart-style documentation to help users get going with graphviz+  quickly.++* Add nicer syntax for record labels, and specifying ports in Monadic+  Dot graphs.++* Define new classes to distinguish between printing/parsing Attribute+  values and other values (as only the former requires quoted+  variants).++* Clean up AttributeGenerator and get it to use a better+  pretty-printing library.++Medium term+-----------++* Improve the test suite such that the generated `DotGraph` values are+  valid (and thus can be passed to Graphviz proper).  This may not in+  fact be possible as guaranteeing an arbitrary `Attribute` is valid+  is rather tricky (as the value itself needs to be verified,+  especially stateful ones).++* Switch to a proper test-suite library rather than the hand-rolled+  one currently being used.++* Add support for clusters as endpoints of edges.++Long term+---------++* Allow usage of non-FGL graphs with graphviz.  This will require+  implementing a separate library to represent graphs (see initial+  discussions about this+  [here](http://www.haskell.org/pipermail/haskell-cafe/2009-June/063402.html)).
graphviz.cabal view
@@ -1,5 +1,5 @@ Name:               graphviz-Version:            2999.14.1.0+Version:            2999.15.0.0 Stability:          Beta Synopsis:           Bindings to Graphviz for graph visualisation. Description: {@@ -33,22 +33,23 @@ Homepage:           http://projects.haskell.org/graphviz/ Category:           Graphs, Graphics License:            BSD3-License-File:       LICENSE+License-File:       LICENSE.md Copyright:          Matthew Sackman, Ivan Lazar Miljenovic Author:             Matthew Sackman, Ivan Lazar Miljenovic Maintainer:         Ivan.Miljenovic+graphviz@gmail.com+Bug-Reports:        http://hub.darcs.net/ivanm/graphviz/issues Build-Type:         Simple Cabal-Version:      >= 1.14-Extra-Source-Files: TODO-                    Changelog-                    README-                    FAQ+Extra-Source-Files: TODO.md+                    Changelog.md+                    README.md+                    FAQ.md                     utils/AttributeGenerator.hs                     utils/TestParsing.hs  Source-Repository head     Type:         darcs-    Location:     http://code.haskell.org/graphviz+    Location:     http://hub.darcs.net/ivanm/graphviz  Library {         Default-Language:  Haskell98@@ -60,7 +61,7 @@                            fgl == 5.4.*,                            filepath,                            polyparse >= 1.7 && < 1.9,-                           bytestring == 0.9.*,+                           bytestring >= 0.9 && < 0.11,                            colour == 2.3.*,                            transformers >= 0.2 && < 0.4,                            text,@@ -115,6 +116,7 @@         Build-Depends:     base,                            containers,                            process,+                           directory,                            fgl,                            filepath,                            polyparse,@@ -124,7 +126,7 @@                            text,                            wl-pprint-text,                            dlist,-                           QuickCheck >= 2.3 && < 2.5+                           QuickCheck >= 2.3 && < 2.6          hs-Source-Dirs:    . tests 
tests/Data/GraphViz/Testing/Instances/Attributes.hs view
@@ -439,6 +439,16 @@   shrink (DVal d) = map DVal $ shrink d   shrink (PVal p) = map PVal $ shrink p +instance Arbitrary SVGFontNames where+  arbitrary = arbBounded++instance Arbitrary GraphSize where+  arbitrary = liftM3 GSize arbitrary arbitrary arbitrary++  shrink gs = do w' <- shrink $ width gs+                 h' <- shrinkM $ height gs+                 return $ GSize w' h' False+ instance Arbitrary ModeType where   arbitrary = arbBounded 
utils/AttributeGenerator.hs view
@@ -67,6 +67,7 @@                    , parseNames   :: [Code]                    , valtype      :: VType                    , parseDef     :: Maybe Code+                   , emptyParse   :: Maybe Code -- ^ What the empty string gets parsed as.                    , defValue     :: Maybe Code                    , forGraphs    :: Bool                    , forClusters  :: Bool@@ -87,6 +88,7 @@                                    , valtype      = v -- just in case need to do fancy                                                       -- stuff                                    , parseDef     = liftM text df+                                   , emptyParse   = liftM text dfP                                    , defValue     = liftM text d                                    , forGraphs    = isFor 'G'                                    , forClusters  = isFor 'C' || forSG@@ -100,6 +102,11 @@       isFor f = f `elem` u       forSG = isFor 'S'       df' = if v == Bl then Just "'True'" else fmap ( \ t -> '\'' : t ++ "'") df+      isNumeric = case v of+                    Integ -> True+                    Dbl   -> True+                    _     -> False+      dfP = bool Nothing d isNumeric       mDoc (f,fc) = f <> colon <+> text fc       addF f = fmap (\ dc -> (wrap (char '/') (text f), dc))       cm' = hsep@@ -148,14 +155,14 @@                      . asRows                      . firstOthers equals (char '|')                      . (++ [defUnknown])-                     . map createDefn+                     . map createDf                      $ atts att       derivs = nest tab $ text "deriving (Eq, Ord, Show, Read)"-      createDefn a = [cnst a <+> vtypeCode a-                     , if isEmpty cm-                       then empty-                       else text "-- ^" <+> cm-                     ]+      createDf a = [cnst a <+> vtypeCode a+                   , if isEmpty cm+                     then empty+                     else text "-- ^" <+> cm+                   ]           where             cm = comment a       defUnknown = [ unknownAttr <+> unknownNameAlias <+> vtype Strng@@ -170,17 +177,19 @@     where       tp = tpNm att -nameAlias     :: Atts -> Code-nameAlias att = comment-                $$ (text "type"-                    <+> unknownNameAlias-                    <+> equals-                    <+> vtype Strng)+-- The Atts value isn't used; this is just to make it have the same+-- type as the other code-generating functions.+nameAlias   :: Atts -> Code+nameAlias _ = cmnt+              $$ (text "type"+                  <+> unknownNameAlias+                  <+> equals+                  <+> vtype Strng)   where-    comment = text "-- | The name for an" <+> unknownAttr-              <> text "; must satisfy "-              <+> quotes validUnknownName-              <> text "."+    cmnt = text "-- | The name for an" <+> unknownAttr+           <> text "; must satisfy "+           <+> quotes validUnknownName+           <> text "."  unknownNameAlias :: Code unknownNameAlias = text "AttributeName"@@ -191,7 +200,6 @@       hdr = text "instance" <+> text "PrintDot" <+> tpNm att <+> text "where"       var = char 'v'       sFunc = text "unqtDot"-      cnct = text "<>"       insts = asRows               . (++ [unknownInst])               . map mkInstance@@ -227,17 +235,27 @@             $ atts att       pFunc = text "parseUnqt"       pType b a-          | valtype a == Bl     = pFld <> text "Bool" <+> cnst a-          | isJust $ parseDef a = pFld <> text "Def"  <+> cnst a <+> fromJust (parseDef a)-          | otherwise           = pFld <+> cnst a+          | valtype a == Bl       = pFld <> text "Bool" <+> cnst a+          | isJust $ parseDef a   = pFld <> text "Def"  <+> cnst a <+> fromJust (parseDef a)+          | isJust $ emptyParse a = pFld <> text "NumDef" <+> cnst a <+> fromJust (emptyParse a)+          | otherwise             = pFld <+> cnst a           where             pFld = text "parseField" <> if b then char 's' else empty        parseAttr a = case map doubleQuotes $ parseNames a of                       [n] -> pType False a <+> n                       ns  -> pType True  a <+> docList ns-      pUnknown = text "liftM2" <+> unknownAttr <+> text "stringBlock"-                 <+> parens (text "parseEq >> parse")+      unknownName = text "attrName"+      pUnknown = text "do"+                 <+> (   (unknownName <+> text "<- stringBlock")+                      $$ (text "liftEqParse'"+                          <+> (parens (text "\"" <> unknownAttr <+> text "(\""+                                       <+> text "++ T.unpack" <+> unknownName+                                       <+> text "++ \")\"")+                               $$ parens (unknownAttr <+> unknownName)+                               )+                         )+                     )  arbitraryInstance     :: Atts -> Code arbitraryInstance att = hdr $+$ fns@@ -448,168 +466,356 @@  -- The actual attributes --- ColorScheme is put earlier so that when sorting, it comes before the various *Color attributes.+-- Don't edit this value directly; edit the table below instead.  attributes :: [Attribute]-attributes = [ makeAttr "Damping" ["Damping"] "G" Dbl Nothing (Just "0.99") (Just "@0.99@") (Just "@0.0@") (Just "neato only")-             , makeAttr "K" ["K"] "GC" Dbl Nothing (Just "0.3") (Just "@0.3@") (Just "@0@") (Just "sfdp, fdp only")-             , makeAttr "URL" ["URL", "href"] "ENGC" EStrng Nothing (Just "\"\"") (Just "none") Nothing (Just "svg, postscript, map only")-             , makeAttr "ArrowHead" ["arrowhead"] "E" (Cust "ArrowType") Nothing (Just "normal") (Just "@'normal'@") Nothing Nothing-             , makeAttr "ArrowSize" ["arrowsize"] "E" Dbl Nothing (Just "1") (Just "@1.0@") (Just "@0.0@") Nothing-             , makeAttr "ArrowTail" ["arrowtail"] "E" (Cust "ArrowType") Nothing (Just "normal") (Just "@'normal'@") Nothing Nothing-             , makeAttr "Aspect" ["aspect"] "G" (Cust "AspectType") Nothing Nothing Nothing Nothing (Just "dot only")-             , makeAttr "BoundingBox" ["bb"] "G" (Cust "Rect") Nothing Nothing Nothing Nothing (Just "write only")-             , makeAttr "ColorScheme" ["colorscheme"] "ENCG" (Cust "ColorScheme") Nothing (Just "X11") (Just "@'X11'@") Nothing Nothing-             , makeAttr "BgColor" ["bgcolor"] "GC" (Cust "[Color]") Nothing (Just "[X11Color Transparent]") (Just "@['X11Color' 'Transparent']@") Nothing Nothing-             , makeAttr "Center" ["center"] "G" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing-             , makeAttr "ClusterRank" ["clusterrank"] "G" (Cust "ClusterMode") Nothing (Just "Local") (Just "@'Local'@") Nothing (Just "dot only")-             , makeAttr "Color" ["color"] "ENC" (Cust "[Color]") Nothing (Just "[X11Color Black]") (Just "@['X11Color' 'Black']@") Nothing Nothing-             , makeAttr "Comment" ["comment"] "ENG" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing Nothing-             , makeAttr "Compound" ["compound"] "G" Bl (Just "True") (Just "False")(Just "@'False'@") Nothing (Just "dot only")-             , makeAttr "Concentrate" ["concentrate"] "G" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing-             , makeAttr "Constraint" ["constraint"] "E" Bl (Just "True") (Just "True") (Just "@'True'@") Nothing (Just "dot only")-             , makeAttr "Decorate" ["decorate"] "E" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing-             , makeAttr "DefaultDist" ["defaultdist"] "G" Dbl Nothing Nothing (Just "@1+(avg. len)*sqrt(|V|)@") (Just "@epsilon@") (Just "neato only, only if @'Pack' 'DontPack'@")-             , makeAttr "Dim" ["dim"] "G" Integ Nothing (Just "2") (Just "@2@") (Just "@2@") (Just "sfdp, fdp, neato only")-             , makeAttr "Dimen" ["dimen"] "G" Integ Nothing (Just "2") (Just "@2@") (Just "@2@") (Just "sfdp, fdp, neato only")-             , makeAttr "Dir" ["dir"] "E" (Cust "DirType") Nothing Nothing (Just "@'Forward'@ (directed), @'NoDir'@ (undirected)") Nothing Nothing-             , makeAttr "DirEdgeConstraints" ["diredgeconstraints"] "G" (Cust "DEConstraints") (Just "EdgeConstraints") (Just "NoConstraints") (Just "@'NoConstraints'@") Nothing (Just "neato only")-             , makeAttr "Distortion" ["distortion"] "N" Dbl Nothing (Just "0") (Just "@0.0@") (Just "@-100.0@") Nothing-             , makeAttr "DPI" ["dpi", "resolution"] "G" Dbl Nothing Nothing (Just "@96.0@, @0.0@") Nothing (Just "svg, bitmap output only; \\\"resolution\\\" is a synonym")-             , makeAttr "EdgeURL" ["edgeURL", "edgehref"] "E" EStrng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, map only")-             , makeAttr "EdgeTarget" ["edgetarget"] "E" EStrng Nothing Nothing (Just "none") Nothing (Just "svg, map only")-             , makeAttr "EdgeTooltip" ["edgetooltip"] "E" EStrng Nothing Nothing (Just "@\\\"\\\"@") Nothing (Just "svg, cmap only")-             , makeAttr "Epsilon" ["epsilon"] "G" Dbl Nothing Nothing (Just "@.0001 * # nodes@ (@mode == 'KK'@), @.0001@ (@mode == 'Major'@)") Nothing (Just "neato only")-             , makeAttr "ESep" ["esep"] "G" (Cust "DPoint") Nothing (Just "(DVal 3)") (Just "@'DVal' 3@") Nothing (Just "not dot")-             , makeAttr "FillColor" ["fillcolor"] "NEC" (Cust "[Color]") Nothing (Just "[X11Color Black]")(Just "@['X11Color' 'LightGray']@ (nodes), @['X11Color' 'Black']@ (clusters)") Nothing Nothing-             , makeAttr "FixedSize" ["fixedsize"] "N" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing-             , makeAttr "FontColor" ["fontcolor"] "ENGC" (Cust "Color") Nothing (Just "(X11Color Black)") (Just "@'X11Color' 'Black'@") Nothing Nothing-             , makeAttr "FontName" ["fontname"] "ENGC" Strng Nothing (Just "\"Times-Roman\"") (Just "@\\\"Times-Roman\\\"@") Nothing Nothing-             , makeAttr "FontNames" ["fontnames"] "G" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg only")-             , makeAttr "FontPath" ["fontpath"] "G" Strng Nothing Nothing (Just "system dependent") Nothing Nothing-             , makeAttr "FontSize" ["fontsize"] "ENGC" Dbl Nothing (Just "14") (Just "@14.0@") (Just "@1.0@") Nothing-             , makeAttr "ForceLabels" ["forcelabels"] "G" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "Only for 'XLabel' attributes, requires Graphviz >= 2.29.0")-             , makeAttr "GradientAngle" ["gradientangle"] "NCG" Integ Nothing (Just "0") (Just "0") Nothing (Just "requires Graphviz >= 2.29.0")-             , makeAttr "Group" ["group"] "N" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "dot only")-             , makeAttr "HeadURL" ["headURL", "headhref"] "E" EStrng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, map only")-             , makeAttr "HeadClip" ["headclip"] "E" Bl (Just "True") (Just "True") (Just "@'True'@") Nothing Nothing-             , makeAttr "HeadLabel" ["headlabel"] "E" (Cust "Label") Nothing (Just "(StrLabel \"\")") (Just "@'StrLabel' \\\"\\\"@") Nothing Nothing-             , makeAttr "HeadPort" ["headport"] "E" (Cust "PortPos") Nothing (Just "(CompassPoint CenterPoint)") (Just "@'CompassPoint' 'CenterPoint'@") Nothing Nothing-             , makeAttr "HeadTarget" ["headtarget"] "E" EStrng Nothing (Just "\"\"") (Just "none") Nothing (Just "svg, map only")-             , makeAttr "HeadTooltip" ["headtooltip"] "E" EStrng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, cmap only")-             , makeAttr "Height" ["height"] "N" Dbl Nothing (Just "0.5") (Just "@0.5@") (Just "@0.02@") Nothing-             , makeAttr "ID" ["id"] "GNE" EStrng Nothing (Just "\"\"") (Just "@\\\"\\\"") Nothing (Just "svg, postscript, map only")-             , makeAttr "Image" ["image"] "N" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing Nothing-             , makeAttr "ImagePath" ["imagepath"] "G" (Cust "Paths") Nothing (Just "(Paths [])") (Just "@'Paths' []@") Nothing (Just "Printing and parsing is OS-specific, requires Graphviz >= 2.29.0")-             , makeAttr "ImageScale" ["imagescale"] "N" (Cust "ScaleType") (Just "UniformScale") (Just "NoScale") (Just "@'NoScale'@") Nothing Nothing-             , makeAttr "Label" ["label"] "ENGC" (Cust "Label") Nothing (Just "(StrLabel \"\")") (Just "@'StrLabel' \\\"\\\\N\\\"@ (nodes), @'StrLabel' \\\"\\\"@ (otherwise)") Nothing Nothing-             , makeAttr "LabelURL" ["labelURL", "labelhref"] "E" EStrng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, map only")-             , makeAttr "LabelScheme" ["label_scheme"] "G" (Cust "LabelScheme") Nothing (Just "NotEdgeLabel") (Just "@'NotEdgeLabel'@") Nothing (Just "sfdp only, requires Graphviz >= 2.28.0")-             , makeAttr "LabelAngle" ["labelangle"] "E" Dbl Nothing (Just "(-25)") (Just "@-25.0@") (Just "@-180.0@") Nothing-             , makeAttr "LabelDistance" ["labeldistance"] "E" Dbl Nothing (Just "1") (Just "@1.0@") (Just "@0.0@") Nothing-             , makeAttr "LabelFloat" ["labelfloat"] "E" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing-             , makeAttr "LabelFontColor" ["labelfontcolor"] "E" (Cust "Color") Nothing (Just "(X11Color Black)") (Just "@'X11Color' 'Black'@") Nothing Nothing-             , makeAttr "LabelFontName" ["labelfontname"] "E" Strng Nothing (Just "\"Times-Roman\"") (Just "@\\\"Times-Roman\\\"@") Nothing Nothing-             , makeAttr "LabelFontSize" ["labelfontsize"] "E" Dbl Nothing (Just "14") (Just "@14.0@") (Just "@1.0@") Nothing-             , makeAttr "LabelJust" ["labeljust"] "GC" (Cust "Justification") Nothing (Just "JCenter") (Just "@'JCenter'@") Nothing Nothing-             , makeAttr "LabelLoc" ["labelloc"] "GCN" (Cust "VerticalPlacement") Nothing (Just "VTop") (Just "@'VTop'@ (clusters), @'VBottom'@ (root graphs), @'VCenter'@ (nodes)") Nothing Nothing-             , makeAttr "LabelTarget" ["labeltarget"] "E" EStrng Nothing (Just "\"\"") (Just "none") Nothing (Just "svg, map only")-             , makeAttr "LabelTooltip" ["labeltooltip"] "E" EStrng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, cmap only")-             , makeAttr "Landscape" ["landscape"] "G" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing-             , makeAttr "Layer" ["layer"] "EN" (Cust "LayerRange") Nothing Nothing Nothing Nothing Nothing-             , makeAttr "Layers" ["layers"] "G" (Cust "LayerList") Nothing (Just "(LL [])")  (Just "@'LL' []@") Nothing Nothing-             , makeAttr "LayerSep" ["layersep"] "G" (Cust "LayerSep") Nothing (Just "(LSep \" :\\t\")") (Just "@'LSep' \\\" :\\t\\\"@") Nothing Nothing-             , makeAttr "Layout" ["layout"] "G" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing Nothing-             , makeAttr "Len" ["len"] "E" Dbl Nothing Nothing (Just "@1.0@ (neato), @0.3@ (fdp)") Nothing (Just "fdp, neato only")-             , makeAttr "LevelsGap" ["levelsgap"] "G" Dbl Nothing (Just "0") (Just "@0.0@") Nothing (Just "neato only")-             , makeAttr "Levels" ["levels"] "G" Integ Nothing (Just "maxBound") (Just "@'maxBound'@") (Just "@0@") (Just "sfdp only")-             , makeAttr "LHead" ["lhead"] "E" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "dot only")-             , makeAttr "LHeight" ["LHeight"] "GC" Dbl Nothing Nothing Nothing Nothing (Just "write only, requires Graphviz >= 2.28.0")-             , makeAttr "LPos" ["lp"] "EGC" (Cust "Point") Nothing Nothing Nothing Nothing (Just "write only")-             , makeAttr "LTail" ["ltail"] "E" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "dot only")-             , makeAttr "LWidth" ["lwidth"] "GC" Dbl Nothing Nothing Nothing Nothing (Just "write only, requires Graphviz >= 2.28.0")-             , makeAttr "Margin" ["margin"] "NG" (Cust "DPoint") Nothing Nothing (Just "device dependent") Nothing Nothing-             , makeAttr "MaxIter" ["maxiter"] "G" Integ Nothing Nothing (Just "@100 * # nodes@ (@mode == 'KK'@), @200@ (@mode == 'Major'@), @600@ (fdp)") Nothing (Just "fdp, neato only")-             , makeAttr "MCLimit" ["mclimit"] "G" Dbl Nothing (Just "1") (Just "@1.0@") Nothing (Just "dot only")-             , makeAttr "MinDist" ["mindist"] "G" Dbl Nothing (Just "1") (Just "@1.0@") (Just "@0.0@") (Just "circo only")-             , makeAttr "MinLen" ["minlen"] "E" Integ Nothing (Just "1") (Just "@1@") (Just "@0@") (Just "dot only")-             , makeAttr "Mode" ["mode"] "G" (Cust "ModeType") Nothing (Just "Major") (Just "@'Major'@") Nothing (Just "neato only")-             , makeAttr "Model" ["model"] "G" (Cust "Model") Nothing (Just "ShortPath") (Just "@'ShortPath'@") Nothing (Just "neato only")-             , makeAttr "Mosek" ["mosek"] "G" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "neato only; requires the Mosek software")-             , makeAttr "NodeSep" ["nodesep"] "G" Dbl Nothing (Just "0.25") (Just "@0.25@") (Just "@0.02@") (Just "dot only")-             , makeAttr "NoJustify" ["nojustify"] "GCNE" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing-             , makeAttr "Normalize" ["normalize"] "G" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "not dot")-             , makeAttr "Nslimit" ["nslimit"] "G" Dbl Nothing Nothing Nothing Nothing (Just "dot only")-             , makeAttr "Nslimit1" ["nslimit1"] "G" Dbl Nothing Nothing Nothing Nothing (Just "dot only")-             , makeAttr "Ordering" ["ordering"] "GN" (Cust "Order") Nothing Nothing (Just "none") Nothing (Just "dot only")-             , makeAttr "Orientation" ["orientation"] "N" Dbl Nothing (Just "0") (Just "@0.0@") (Just "@360.0@") Nothing-             , makeAttr "OutputOrder" ["outputorder"] "G" (Cust "OutputMode") Nothing (Just "BreadthFirst") (Just "@'BreadthFirst'@") Nothing Nothing-             , makeAttr "Overlap" ["overlap"] "G" (Cust "Overlap") (Just "KeepOverlaps") (Just "KeepOverlaps") (Just "@'KeepOverlaps'@") Nothing (Just "not dot")-             , makeAttr "OverlapScaling" ["overlap_scaling"] "G" Dbl Nothing (Just "(-4)") (Just "@-4@") (Just "@-1.0e10@") (Just "prism only")-             , makeAttr "Pack" ["pack"] "G" (Cust "Pack") (Just "DoPack") (Just "DontPack") (Just "@'DontPack'@") Nothing (Just "not dot")-             , makeAttr "PackMode" ["packmode"] "G" (Cust "PackMode") Nothing (Just "PackNode") (Just "@'PackNode'@") Nothing (Just "not dot")-             , makeAttr "Pad" ["pad"] "G" (Cust "DPoint") Nothing (Just "(DVal 0.0555)") (Just "@'DVal' 0.0555@ (4 points)") Nothing Nothing-             , makeAttr "Page" ["page"] "G" (Cust "Point") Nothing Nothing Nothing Nothing Nothing-             , makeAttr "PageDir" ["pagedir"] "G" (Cust "PageDir") Nothing (Just "Bl") (Just "@'Bl'@") Nothing Nothing-             , makeAttr "PenColor" ["pencolor"] "C" (Cust "Color") Nothing (Just "(X11Color Black)") (Just "@'X11Color' 'Black'@") Nothing Nothing-             , makeAttr "PenWidth" ["penwidth"] "CNE" Dbl Nothing (Just "1") (Just "@1.0@") (Just "@0.0@") Nothing-             , makeAttr "Peripheries" ["peripheries"] "NC" Integ Nothing (Just "1") (Just "shape default (nodes), @1@ (clusters)") (Just "0") Nothing-             , makeAttr "Pin" ["pin"] "N" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "fdp, neato only")-             , makeAttr "Pos" ["pos"] "EN" (Cust "Pos") Nothing Nothing Nothing Nothing Nothing-             , makeAttr "QuadTree" ["quadtree"] "G" (Cust "QuadType") (Just "NormalQT") (Just "NormalQT") (Just "@'NormalQT'@") Nothing (Just "sfdp only")-             , makeAttr "Quantum" ["quantum"] "G" Dbl Nothing (Just "0") (Just "@0.0@") (Just "@0.0@") Nothing-             , makeAttr "Rank" ["rank"] "S" (Cust "RankType") Nothing Nothing Nothing Nothing (Just "dot only")-             , makeAttr "RankDir" ["rankdir"] "G" (Cust "RankDir") Nothing (Just "FromTop") (Just "@'FromTop'@") Nothing (Just "dot only")-             , makeAttr "RankSep" ["ranksep"] "G" (Cust "[Double]") Nothing Nothing (Just "@[0.5]@ (dot), @[1.0]@ (twopi)") (Just "[0.02]") (Just "twopi, dot only")-             , makeAttr "Ratio" ["ratio"] "G" (Cust "Ratios") Nothing Nothing Nothing Nothing Nothing-             , makeAttr "Rects" ["rects"] "N" (Cust "[Rect]") Nothing Nothing Nothing Nothing (Just "write only")-             , makeAttr "Regular" ["regular"] "N" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing-             , makeAttr "ReMinCross" ["remincross"] "G" Bl (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "dot only")-             , makeAttr "RepulsiveForce" ["repulsiveforce"] "G" Dbl Nothing (Just "1") (Just "@1.0@") (Just "@0.0@") (Just "sfdp only")-             , makeAttr "Root" ["root"] "GN" (Cust "Root") (Just "IsCentral") (Just "(NodeName \"\")") (Just "@'NodeName' \\\"\\\"@ (graphs), @'NotCentral'@ (nodes)") Nothing (Just "circo, twopi only")-             , makeAttr "Rotate" ["rotate"] "G" Integ Nothing (Just "0") (Just "@0@") Nothing Nothing-             , makeAttr "Rotation" ["rotation"] "G" Dbl Nothing (Just "0") (Just "@0@") Nothing (Just "sfdp only, requires Graphviz >= 2.28.0")-             , makeAttr "SameHead" ["samehead"] "E" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "dot only")-             , makeAttr "SameTail" ["sametail"] "E" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "dot only")-             , makeAttr "SamplePoints" ["samplepoints"] "N" Integ Nothing Nothing (Just "@8@ (output), @20@ (overlap and image maps)") Nothing Nothing-             , makeAttr "Scale" ["scale"] "G" (Cust "DPoint") Nothing Nothing Nothing Nothing (Just "twopi only, requires Graphviz >= 2.28.0")-             , makeAttr "SearchSize" ["searchsize"] "G" Integ Nothing (Just "30") (Just "@30@") Nothing (Just "dot only")-             , makeAttr "Sep" ["sep"] "G" (Cust "DPoint") Nothing (Just "(DVal 4)") (Just "@'DVal' 4@") Nothing (Just "not dot")-             , makeAttr "Shape" ["shape"] "N" (Cust "Shape") Nothing (Just "Ellipse") (Just "@'Ellipse'@") Nothing Nothing-             , makeAttr "ShapeFile" ["shapefile"] "N" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing Nothing-             , makeAttr "ShowBoxes" ["showboxes"] "ENG" Integ Nothing (Just "0") (Just "@0@") (Just "@0@") (Just "dot only")-             , makeAttr "Sides" ["sides"] "N" Integ Nothing (Just "4") (Just "@4@") (Just "@0@") Nothing-             , makeAttr "Size" ["size"] "G" (Cust "Point") Nothing Nothing Nothing Nothing Nothing-             , makeAttr "Skew" ["skew"] "N" Dbl Nothing (Just "0") (Just "@0.0@") (Just "@-100.0@") Nothing-             , makeAttr "Smoothing" ["smoothing"] "G" (Cust "SmoothType") Nothing (Just "NoSmooth") (Just "@'NoSmooth'@") Nothing (Just "sfdp only")-             , makeAttr "SortV" ["sortv"] "GCN" (Cust "Word16") Nothing (Just "0") (Just "@0@") (Just "@0@") Nothing-             , makeAttr "Splines" ["splines"] "G" (Cust "EdgeType") (Just "SplineEdges") (Just "SplineEdges") Nothing Nothing Nothing-             , makeAttr "Start" ["start"] "G" (Cust "StartType") Nothing Nothing Nothing Nothing (Just "fdp, neato only")-             , makeAttr "Style" ["style"] "ENC" (Cust "[StyleItem]") Nothing Nothing Nothing Nothing Nothing-             , makeAttr "StyleSheet" ["stylesheet"] "G" Strng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg only")-             , makeAttr "TailURL" ["tailURL", "tailhref"] "E" EStrng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, map only")-             , makeAttr "TailClip" ["tailclip"] "E" Bl (Just "True") (Just "True") (Just "@'True'@") Nothing Nothing-             , makeAttr "TailLabel" ["taillabel"] "E" (Cust "Label") Nothing (Just "(StrLabel \"\")") (Just "@'StrLabel' \\\"\\\"@") Nothing Nothing-             , makeAttr "TailPort" ["tailport"] "E" (Cust "PortPos") Nothing (Just "(CompassPoint CenterPoint)") (Just "@'CompassPoint' 'CenterPoint'@") Nothing Nothing-             , makeAttr "TailTarget" ["tailtarget"] "E" EStrng Nothing (Just "\"\"") (Just "none") Nothing (Just "svg, map only")-             , makeAttr "TailTooltip" ["tailtooltip"] "E" EStrng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, cmap only")-             , makeAttr "Target" ["target"] "ENGC" EStrng Nothing (Just "\"\"") (Just "none") Nothing (Just "svg, map only")-             , makeAttr "Tooltip" ["tooltip"] "NEC" EStrng Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, cmap only")-             , makeAttr "TrueColor" ["truecolor"] "G" Bl (Just "True") Nothing Nothing Nothing (Just "bitmap output only")-             , makeAttr "Vertices" ["vertices"] "N" (Cust "[Point]") Nothing Nothing Nothing Nothing (Just "write only")-             , makeAttr "ViewPort" ["viewport"] "G" (Cust "ViewPort") Nothing Nothing (Just "none") Nothing Nothing-             , makeAttr "VoroMargin" ["voro_margin"] "G" Dbl Nothing (Just "0.05") (Just "@0.05@") (Just "@0.0@") (Just "not dot")-             , makeAttr "Weight" ["weight"] "E" Dbl Nothing Nothing (Just "@1.0@") (Just "@0@ (dot), @1@ (neato,fdp,sfdp)") Nothing-             , makeAttr "Width" ["width"] "N" Dbl Nothing (Just "0.75") (Just "@0.75@") (Just "@0.01@") Nothing-             , makeAttr "XLabel" ["xlabel"] "EN" (Cust "Label") Nothing (Just "(StrLabel \"\")")  (Just "@'StrLabel' \\\"\\\"@") Nothing (Just "requires Graphviz >= 2.29.0")-             , makeAttr "Z" ["z"] "N" Dbl Nothing (Just "0") (Just "@0.0@") (Just "@-MAXFLOAT@, @-1000@") Nothing-             ]+attributes = [+  -- BEGIN RECEIVE ORGTBL Attributes+  makeAttr "Damping" ["Damping"] "G" (Dbl) Nothing (Just "0.99") (Just "@0.99@") (Just "@0.0@") (Just "neato only"),+  makeAttr "K" ["K"] "GC" (Dbl) Nothing (Just "0.3") (Just "@0.3@") (Just "@0@") (Just "sfdp, fdp only"),+  makeAttr "URL" ["URL", "href"] "ENGC" (EStrng) Nothing (Just "\"\"") (Just "none") Nothing (Just "svg, postscript, map only"),+  makeAttr "ArrowHead" ["arrowhead"] "E" (Cust "ArrowType") Nothing (Just "normal") (Just "@'normal'@") Nothing Nothing,+  makeAttr "ArrowSize" ["arrowsize"] "E" (Dbl) Nothing (Just "1") (Just "@1.0@") (Just "@0.0@") Nothing,+  makeAttr "ArrowTail" ["arrowtail"] "E" (Cust "ArrowType") Nothing (Just "normal") (Just "@'normal'@") Nothing Nothing,+  makeAttr "Aspect" ["aspect"] "G" (Cust "AspectType") Nothing Nothing Nothing Nothing (Just "dot only"),+  makeAttr "BoundingBox" ["bb"] "G" (Cust "Rect") Nothing Nothing Nothing Nothing (Just "write only"),+  makeAttr "ColorScheme" ["colorscheme"] "ENCG" (Cust "ColorScheme") Nothing (Just "X11") (Just "@'X11'@") Nothing Nothing,+  makeAttr "BgColor" ["bgcolor"] "GC" (Cust "[Color]") Nothing (Just "[X11Color Transparent]") (Just "@['X11Color' 'Transparent']@") Nothing Nothing,+  makeAttr "Center" ["center"] "G" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing,+  makeAttr "ClusterRank" ["clusterrank"] "G" (Cust "ClusterMode") Nothing (Just "Local") (Just "@'Local'@") Nothing (Just "dot only"),+  makeAttr "Color" ["color"] "ENC" (Cust "[Color]") Nothing (Just "[X11Color Black]") (Just "@['X11Color' 'Black']@") Nothing Nothing,+  makeAttr "Comment" ["comment"] "ENG" (Strng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing Nothing,+  makeAttr "Compound" ["compound"] "G" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "dot only"),+  makeAttr "Concentrate" ["concentrate"] "G" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing,+  makeAttr "Constraint" ["constraint"] "E" (Bl) (Just "True") (Just "True") (Just "@'True'@") Nothing (Just "dot only"),+  makeAttr "Decorate" ["decorate"] "E" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing,+  makeAttr "DefaultDist" ["defaultdist"] "G" (Dbl) Nothing Nothing (Just "@1+(avg. len)*sqrt(abs(V))@") (Just "@epsilon@") (Just "neato only, only if @'Pack' 'DontPack'@"),+  makeAttr "Dim" ["dim"] "G" (Integ) Nothing (Just "2") (Just "@2@") (Just "@2@") (Just "sfdp, fdp, neato only"),+  makeAttr "Dimen" ["dimen"] "G" (Integ) Nothing (Just "2") (Just "@2@") (Just "@2@") (Just "sfdp, fdp, neato only"),+  makeAttr "Dir" ["dir"] "E" (Cust "DirType") Nothing Nothing (Just "@'Forward'@ (directed), @'NoDir'@ (undirected)") Nothing Nothing,+  makeAttr "DirEdgeConstraints" ["diredgeconstraints"] "G" (Cust "DEConstraints") (Just "EdgeConstraints") (Just "NoConstraints") (Just "@'NoConstraints'@") Nothing (Just "neato only"),+  makeAttr "Distortion" ["distortion"] "N" (Dbl) Nothing (Just "0") (Just "@0.0@") (Just "@-100.0@") Nothing,+  makeAttr "DPI" ["dpi", "resolution"] "G" (Dbl) Nothing Nothing (Just "@96.0@, @0.0@") Nothing (Just "svg, bitmap output only; \\\"resolution\\\" is a synonym"),+  makeAttr "EdgeURL" ["edgeURL", "edgehref"] "E" (EStrng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, map only"),+  makeAttr "EdgeTarget" ["edgetarget"] "E" (EStrng) Nothing Nothing (Just "none") Nothing (Just "svg, map only"),+  makeAttr "EdgeTooltip" ["edgetooltip"] "E" (EStrng) Nothing Nothing (Just "@\\\"\\\"@") Nothing (Just "svg, cmap only"),+  makeAttr "Epsilon" ["epsilon"] "G" (Dbl) Nothing Nothing (Just "@.0001 * # nodes@ (@mode == 'KK'@), @.0001@ (@mode == 'Major'@)") Nothing (Just "neato only"),+  makeAttr "ESep" ["esep"] "G" (Cust "DPoint") Nothing (Just "(DVal 3)") (Just "@'DVal' 3@") Nothing (Just "not dot"),+  makeAttr "FillColor" ["fillcolor"] "NEC" (Cust "[Color]") Nothing (Just "[X11Color Black]") (Just "@['X11Color' 'LightGray']@ (nodes), @['X11Color' 'Black']@ (clusters)") Nothing Nothing,+  makeAttr "FixedSize" ["fixedsize"] "N" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing,+  makeAttr "FontColor" ["fontcolor"] "ENGC" (Cust "Color") Nothing (Just "(X11Color Black)") (Just "@'X11Color' 'Black'@") Nothing Nothing,+  makeAttr "FontName" ["fontname"] "ENGC" (Strng) Nothing (Just "\"Times-Roman\"") (Just "@\\\"Times-Roman\\\"@") Nothing Nothing,+  makeAttr "FontNames" ["fontnames"] "G" (Cust "SVGFontNames") Nothing (Just "SvgNames") (Just "@'SvgNames'@") Nothing (Just "svg only"),+  makeAttr "FontPath" ["fontpath"] "G" (Strng) Nothing Nothing (Just "system dependent") Nothing Nothing,+  makeAttr "FontSize" ["fontsize"] "ENGC" (Dbl) Nothing (Just "14") (Just "@14.0@") (Just "@1.0@") Nothing,+  makeAttr "ForceLabels" ["forcelabels"] "G" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "Only for 'XLabel' attributes, requires Graphviz >= 2.29.0"),+  makeAttr "GradientAngle" ["gradientangle"] "NCG" (Integ) Nothing (Just "0") (Just "0") Nothing (Just "requires Graphviz >= 2.29.0"),+  makeAttr "Group" ["group"] "N" (Strng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "dot only"),+  makeAttr "HeadURL" ["headURL", "headhref"] "E" (EStrng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, map only"),+  makeAttr "HeadClip" ["headclip"] "E" (Bl) (Just "True") (Just "True") (Just "@'True'@") Nothing Nothing,+  makeAttr "HeadLabel" ["headlabel"] "E" (Cust "Label") Nothing (Just "(StrLabel \"\")") (Just "@'StrLabel' \\\"\\\"@") Nothing Nothing,+  makeAttr "HeadPort" ["headport"] "E" (Cust "PortPos") Nothing (Just "(CompassPoint CenterPoint)") (Just "@'CompassPoint' 'CenterPoint'@") Nothing Nothing,+  makeAttr "HeadTarget" ["headtarget"] "E" (EStrng) Nothing (Just "\"\"") (Just "none") Nothing (Just "svg, map only"),+  makeAttr "HeadTooltip" ["headtooltip"] "E" (EStrng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, cmap only"),+  makeAttr "Height" ["height"] "N" (Dbl) Nothing (Just "0.5") (Just "@0.5@") (Just "@0.02@") Nothing,+  makeAttr "ID" ["id"] "GNE" (EStrng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, postscript, map only"),+  makeAttr "Image" ["image"] "N" (Strng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing Nothing,+  makeAttr "ImagePath" ["imagepath"] "G" (Cust "Paths") Nothing (Just "(Paths [])") (Just "@'Paths' []@") Nothing (Just "Printing and parsing is OS-specific, requires Graphviz >= 2.29.0"),+  makeAttr "ImageScale" ["imagescale"] "N" (Cust "ScaleType") (Just "UniformScale") (Just "NoScale") (Just "@'NoScale'@") Nothing Nothing,+  makeAttr "Label" ["label"] "ENGC" (Cust "Label") Nothing (Just "(StrLabel \"\")") (Just "@'StrLabel' \\\"\\\\N\\\"@ (nodes), @'StrLabel' \\\"\\\"@ (otherwise)") Nothing Nothing,+  makeAttr "LabelURL" ["labelURL", "labelhref"] "E" (EStrng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, map only"),+  makeAttr "LabelScheme" ["label_scheme"] "G" (Cust "LabelScheme") Nothing (Just "NotEdgeLabel") (Just "@'NotEdgeLabel'@") Nothing (Just "sfdp only, requires Graphviz >= 2.28.0"),+  makeAttr "LabelAngle" ["labelangle"] "E" (Dbl) Nothing (Just "(-25)") (Just "@-25.0@") (Just "@-180.0@") Nothing,+  makeAttr "LabelDistance" ["labeldistance"] "E" (Dbl) Nothing (Just "1") (Just "@1.0@") (Just "@0.0@") Nothing,+  makeAttr "LabelFloat" ["labelfloat"] "E" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing,+  makeAttr "LabelFontColor" ["labelfontcolor"] "E" (Cust "Color") Nothing (Just "(X11Color Black)") (Just "@'X11Color' 'Black'@") Nothing Nothing,+  makeAttr "LabelFontName" ["labelfontname"] "E" (Strng) Nothing (Just "\"Times-Roman\"") (Just "@\\\"Times-Roman\\\"@") Nothing Nothing,+  makeAttr "LabelFontSize" ["labelfontsize"] "E" (Dbl) Nothing (Just "14") (Just "@14.0@") (Just "@1.0@") Nothing,+  makeAttr "LabelJust" ["labeljust"] "GC" (Cust "Justification") Nothing (Just "JCenter") (Just "@'JCenter'@") Nothing Nothing,+  makeAttr "LabelLoc" ["labelloc"] "GCN" (Cust "VerticalPlacement") Nothing (Just "VTop") (Just "@'VTop'@ (clusters), @'VBottom'@ (root graphs), @'VCenter'@ (nodes)") Nothing Nothing,+  makeAttr "LabelTarget" ["labeltarget"] "E" (EStrng) Nothing (Just "\"\"") (Just "none") Nothing (Just "svg, map only"),+  makeAttr "LabelTooltip" ["labeltooltip"] "E" (EStrng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, cmap only"),+  makeAttr "Landscape" ["landscape"] "G" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing,+  makeAttr "Layer" ["layer"] "EN" (Cust "LayerRange") Nothing Nothing Nothing Nothing Nothing,+  makeAttr "Layers" ["layers"] "G" (Cust "LayerList") Nothing (Just "(LL [])") (Just "@'LL' []@") Nothing Nothing,+  makeAttr "LayerSep" ["layersep"] "G" (Cust "LayerSep") Nothing (Just "(LSep \" :\\t\")") (Just "@'LSep' \\\" :\\t\\\"@") Nothing Nothing,+  makeAttr "Layout" ["layout"] "G" (Strng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing Nothing,+  makeAttr "Len" ["len"] "E" (Dbl) Nothing Nothing (Just "@1.0@ (neato), @0.3@ (fdp)") Nothing (Just "fdp, neato only"),+  makeAttr "LevelsGap" ["levelsgap"] "G" (Dbl) Nothing (Just "0") (Just "@0.0@") Nothing (Just "neato only"),+  makeAttr "Levels" ["levels"] "G" (Integ) Nothing (Just "maxBound") (Just "@'maxBound'@") (Just "@0@") (Just "sfdp only"),+  makeAttr "LHead" ["lhead"] "E" (Strng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "dot only"),+  makeAttr "LHeight" ["LHeight"] "GC" (Dbl) Nothing Nothing Nothing Nothing (Just "write only, requires Graphviz >= 2.28.0"),+  makeAttr "LPos" ["lp"] "EGC" (Cust "Point") Nothing Nothing Nothing Nothing (Just "write only"),+  makeAttr "LTail" ["ltail"] "E" (Strng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "dot only"),+  makeAttr "LWidth" ["lwidth"] "GC" (Dbl) Nothing Nothing Nothing Nothing (Just "write only, requires Graphviz >= 2.28.0"),+  makeAttr "Margin" ["margin"] "NG" (Cust "DPoint") Nothing Nothing (Just "device dependent") Nothing Nothing,+  makeAttr "MaxIter" ["maxiter"] "G" (Integ) Nothing Nothing (Just "@100 * # nodes@ (@mode == 'KK'@), @200@ (@mode == 'Major'@), @600@ (fdp)") Nothing (Just "fdp, neato only"),+  makeAttr "MCLimit" ["mclimit"] "G" (Dbl) Nothing (Just "1") (Just "@1.0@") Nothing (Just "dot only"),+  makeAttr "MinDist" ["mindist"] "G" (Dbl) Nothing (Just "1") (Just "@1.0@") (Just "@0.0@") (Just "circo only"),+  makeAttr "MinLen" ["minlen"] "E" (Integ) Nothing (Just "1") (Just "@1@") (Just "@0@") (Just "dot only"),+  makeAttr "Mode" ["mode"] "G" (Cust "ModeType") Nothing (Just "Major") (Just "@'Major'@") Nothing (Just "neato only"),+  makeAttr "Model" ["model"] "G" (Cust "Model") Nothing (Just "ShortPath") (Just "@'ShortPath'@") Nothing (Just "neato only"),+  makeAttr "Mosek" ["mosek"] "G" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "neato only; requires the Mosek software"),+  makeAttr "NodeSep" ["nodesep"] "G" (Dbl) Nothing (Just "0.25") (Just "@0.25@") (Just "@0.02@") (Just "dot only"),+  makeAttr "NoJustify" ["nojustify"] "GCNE" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing,+  makeAttr "Normalize" ["normalize"] "G" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "not dot"),+  makeAttr "Nslimit" ["nslimit"] "G" (Dbl) Nothing Nothing Nothing Nothing (Just "dot only"),+  makeAttr "Nslimit1" ["nslimit1"] "G" (Dbl) Nothing Nothing Nothing Nothing (Just "dot only"),+  makeAttr "Ordering" ["ordering"] "GN" (Cust "Order") Nothing Nothing (Just "none") Nothing (Just "dot only"),+  makeAttr "Orientation" ["orientation"] "N" (Dbl) Nothing (Just "0") (Just "@0.0@") (Just "@360.0@") Nothing,+  makeAttr "OutputOrder" ["outputorder"] "G" (Cust "OutputMode") Nothing (Just "BreadthFirst") (Just "@'BreadthFirst'@") Nothing Nothing,+  makeAttr "Overlap" ["overlap"] "G" (Cust "Overlap") (Just "KeepOverlaps") (Just "KeepOverlaps") (Just "@'KeepOverlaps'@") Nothing (Just "not dot"),+  makeAttr "OverlapScaling" ["overlap_scaling"] "G" (Dbl) Nothing (Just "(-4)") (Just "@-4@") (Just "@-1.0e10@") (Just "prism only"),+  makeAttr "Pack" ["pack"] "G" (Cust "Pack") (Just "DoPack") (Just "DontPack") (Just "@'DontPack'@") Nothing (Just "not dot"),+  makeAttr "PackMode" ["packmode"] "G" (Cust "PackMode") Nothing (Just "PackNode") (Just "@'PackNode'@") Nothing (Just "not dot"),+  makeAttr "Pad" ["pad"] "G" (Cust "DPoint") Nothing (Just "(DVal 0.0555)") (Just "@'DVal' 0.0555@ (4 points)") Nothing Nothing,+  makeAttr "Page" ["page"] "G" (Cust "Point") Nothing Nothing Nothing Nothing Nothing,+  makeAttr "PageDir" ["pagedir"] "G" (Cust "PageDir") Nothing (Just "Bl") (Just "@'Bl'@") Nothing Nothing,+  makeAttr "PenColor" ["pencolor"] "C" (Cust "Color") Nothing (Just "(X11Color Black)") (Just "@'X11Color' 'Black'@") Nothing Nothing,+  makeAttr "PenWidth" ["penwidth"] "CNE" (Dbl) Nothing (Just "1") (Just "@1.0@") (Just "@0.0@") Nothing,+  makeAttr "Peripheries" ["peripheries"] "NC" (Integ) Nothing (Just "1") (Just "shape default (nodes), @1@ (clusters)") (Just "0") Nothing,+  makeAttr "Pin" ["pin"] "N" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "fdp, neato only"),+  makeAttr "Pos" ["pos"] "EN" (Cust "Pos") Nothing Nothing Nothing Nothing Nothing,+  makeAttr "QuadTree" ["quadtree"] "G" (Cust "QuadType") (Just "NormalQT") (Just "NormalQT") (Just "@'NormalQT'@") Nothing (Just "sfdp only"),+  makeAttr "Quantum" ["quantum"] "G" (Dbl) Nothing (Just "0") (Just "@0.0@") (Just "@0.0@") Nothing,+  makeAttr "Rank" ["rank"] "S" (Cust "RankType") Nothing Nothing Nothing Nothing (Just "dot only"),+  makeAttr "RankDir" ["rankdir"] "G" (Cust "RankDir") Nothing (Just "FromTop") (Just "@'FromTop'@") Nothing (Just "dot only"),+  makeAttr "RankSep" ["ranksep"] "G" (Cust "[Double]") Nothing Nothing (Just "@[0.5]@ (dot), @[1.0]@ (twopi)") (Just "[0.02]") (Just "twopi, dot only"),+  makeAttr "Ratio" ["ratio"] "G" (Cust "Ratios") Nothing Nothing Nothing Nothing Nothing,+  makeAttr "Rects" ["rects"] "N" (Cust "[Rect]") Nothing Nothing Nothing Nothing (Just "write only"),+  makeAttr "Regular" ["regular"] "N" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing Nothing,+  makeAttr "ReMinCross" ["remincross"] "G" (Bl) (Just "True") (Just "False") (Just "@'False'@") Nothing (Just "dot only"),+  makeAttr "RepulsiveForce" ["repulsiveforce"] "G" (Dbl) Nothing (Just "1") (Just "@1.0@") (Just "@0.0@") (Just "sfdp only"),+  makeAttr "Root" ["root"] "GN" (Cust "Root") (Just "IsCentral") (Just "(NodeName \"\")") (Just "@'NodeName' \\\"\\\"@ (graphs), @'NotCentral'@ (nodes)") Nothing (Just "circo, twopi only"),+  makeAttr "Rotate" ["rotate"] "G" (Integ) Nothing (Just "0") (Just "@0@") Nothing Nothing,+  makeAttr "Rotation" ["rotation"] "G" (Dbl) Nothing (Just "0") (Just "@0@") Nothing (Just "sfdp only, requires Graphviz >= 2.28.0"),+  makeAttr "SameHead" ["samehead"] "E" (Strng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "dot only"),+  makeAttr "SameTail" ["sametail"] "E" (Strng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "dot only"),+  makeAttr "SamplePoints" ["samplepoints"] "N" (Integ) Nothing Nothing (Just "@8@ (output), @20@ (overlap and image maps)") Nothing Nothing,+  makeAttr "Scale" ["scale"] "G" (Cust "DPoint") Nothing Nothing Nothing Nothing (Just "twopi only, requires Graphviz >= 2.28.0"),+  makeAttr "SearchSize" ["searchsize"] "G" (Integ) Nothing (Just "30") (Just "@30@") Nothing (Just "dot only"),+  makeAttr "Sep" ["sep"] "G" (Cust "DPoint") Nothing (Just "(DVal 4)") (Just "@'DVal' 4@") Nothing (Just "not dot"),+  makeAttr "Shape" ["shape"] "N" (Cust "Shape") Nothing (Just "Ellipse") (Just "@'Ellipse'@") Nothing Nothing,+  makeAttr "ShapeFile" ["shapefile"] "N" (Strng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing Nothing,+  makeAttr "ShowBoxes" ["showboxes"] "ENG" (Integ) Nothing (Just "0") (Just "@0@") (Just "@0@") (Just "dot only"),+  makeAttr "Sides" ["sides"] "N" (Integ) Nothing (Just "4") (Just "@4@") (Just "@0@") Nothing,+  makeAttr "Size" ["size"] "G" (Cust "GraphSize") Nothing Nothing Nothing Nothing Nothing,+  makeAttr "Skew" ["skew"] "N" (Dbl) Nothing (Just "0") (Just "@0.0@") (Just "@-100.0@") Nothing,+  makeAttr "Smoothing" ["smoothing"] "G" (Cust "SmoothType") Nothing (Just "NoSmooth") (Just "@'NoSmooth'@") Nothing (Just "sfdp only"),+  makeAttr "SortV" ["sortv"] "GCN" (Cust "Word16") Nothing (Just "0") (Just "@0@") (Just "@0@") Nothing,+  makeAttr "Splines" ["splines"] "G" (Cust "EdgeType") (Just "SplineEdges") (Just "SplineEdges") Nothing Nothing Nothing,+  makeAttr "Start" ["start"] "G" (Cust "StartType") Nothing Nothing Nothing Nothing (Just "fdp, neato only"),+  makeAttr "Style" ["style"] "ENC" (Cust "[StyleItem]") Nothing Nothing Nothing Nothing Nothing,+  makeAttr "StyleSheet" ["stylesheet"] "G" (Strng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg only"),+  makeAttr "TailURL" ["tailURL", "tailhref"] "E" (EStrng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, map only"),+  makeAttr "TailClip" ["tailclip"] "E" (Bl) (Just "True") (Just "True") (Just "@'True'@") Nothing Nothing,+  makeAttr "TailLabel" ["taillabel"] "E" (Cust "Label") Nothing (Just "(StrLabel \"\")") (Just "@'StrLabel' \\\"\\\"@") Nothing Nothing,+  makeAttr "TailPort" ["tailport"] "E" (Cust "PortPos") Nothing (Just "(CompassPoint CenterPoint)") (Just "@'CompassPoint' 'CenterPoint'@") Nothing Nothing,+  makeAttr "TailTarget" ["tailtarget"] "E" (EStrng) Nothing (Just "\"\"") (Just "none") Nothing (Just "svg, map only"),+  makeAttr "TailTooltip" ["tailtooltip"] "E" (EStrng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, cmap only"),+  makeAttr "Target" ["target"] "ENGC" (EStrng) Nothing (Just "\"\"") (Just "none") Nothing (Just "svg, map only"),+  makeAttr "Tooltip" ["tooltip"] "NEC" (EStrng) Nothing (Just "\"\"") (Just "@\\\"\\\"@") Nothing (Just "svg, cmap only"),+  makeAttr "TrueColor" ["truecolor"] "G" (Bl) (Just "True") Nothing Nothing Nothing (Just "bitmap output only"),+  makeAttr "Vertices" ["vertices"] "N" (Cust "[Point]") Nothing Nothing Nothing Nothing (Just "write only"),+  makeAttr "ViewPort" ["viewport"] "G" (Cust "ViewPort") Nothing Nothing (Just "none") Nothing Nothing,+  makeAttr "VoroMargin" ["voro_margin"] "G" (Dbl) Nothing (Just "0.05") (Just "@0.05@") (Just "@0.0@") (Just "not dot"),+  makeAttr "Weight" ["weight"] "E" (Dbl) Nothing Nothing (Just "@1.0@") (Just "@0@ (dot), @1@ (neato,fdp,sfdp)") Nothing,+  makeAttr "Width" ["width"] "N" (Dbl) Nothing (Just "0.75") (Just "@0.75@") (Just "@0.01@") Nothing,+  makeAttr "XLabel" ["xlabel"] "EN" (Cust "Label") Nothing (Just "(StrLabel \"\")") (Just "@'StrLabel' \\\"\\\"@") Nothing (Just "requires Graphviz >= 2.29.0"),+  makeAttr "Z" ["z"] "N" (Dbl) Nothing (Just "0") (Just "@0.0@") (Just "@-MAXFLOAT@, @-1000@") Nothing+  -- END RECEIVE ORGTBL Attributes+  ] +{-++When using Emacs with org-mode available, hitting ` C-c C-c ' inside+the table below should update the actual Haskell code above.++This way, you can more easily edit/update the appropriate values.++* Values in "Allowed names" should be space-separated (and are+  converted into a list of Strings).++* Used by should consist of a sub-set of `ENGCS'.++* The entries in "Type" should be a valid Haskell value of type+  'VType' (parens are added).++* An empty cell in the last five columns translates to a `Nothing'+  value; anything else is wrapped in quotes and then has Just applied to+  it.  As such, you still need to escape quotes.++* Any entries in 'Parsing default' or "Default value" should be a+  valid Haskell value (add parens if needed) with the exception that+  double-quotes should be escaped.++#+ORGTBL: SEND Attributes orgtbl-to-generic :skip 2 :splice t :hline nil :no-escape t :lstart "  makeAttr " :lend "," :llend "" :sep " " :fmt (1 cell-quote 2 cell-to-list 3 cell-quote 4 cell-parens 5 cell-to-maybe 6 cell-to-maybe 7 cell-to-maybe 8 cell-to-maybe 9 cell-to-maybe)+| Constructor        | Allowed names      | Used By | Type                     | Parsing default | Default value              | Default for Documentation                                                | Minimum                         | Comment notes                                                    |+|--------------------+--------------------+---------+--------------------------+-----------------+----------------------------+--------------------------------------------------------------------------+---------------------------------+------------------------------------------------------------------|+| Damping            | Damping            | G       | Dbl                      |                 | 0.99                       | @0.99@                                                                   | @0.0@                           | neato only                                                       |+| K                  | K                  | GC      | Dbl                      |                 | 0.3                        | @0.3@                                                                    | @0@                             | sfdp, fdp only                                                   |+| URL                | URL href           | ENGC    | EStrng                   |                 | \"\"                       | none                                                                     |                                 | svg, postscript, map only                                        |+| ArrowHead          | arrowhead          | E       | Cust "ArrowType"         |                 | normal                     | @'normal'@                                                               |                                 |                                                                  |+| ArrowSize          | arrowsize          | E       | Dbl                      |                 | 1                          | @1.0@                                                                    | @0.0@                           |                                                                  |+| ArrowTail          | arrowtail          | E       | Cust "ArrowType"         |                 | normal                     | @'normal'@                                                               |                                 |                                                                  |+| Aspect             | aspect             | G       | Cust "AspectType"        |                 |                            |                                                                          |                                 | dot only                                                         |+| BoundingBox        | bb                 | G       | Cust "Rect"              |                 |                            |                                                                          |                                 | write only                                                       |+| ColorScheme        | colorscheme        | ENCG    | Cust "ColorScheme"       |                 | X11                        | @'X11'@                                                                  |                                 |                                                                  |+| BgColor            | bgcolor            | GC      | Cust "[Color]"           |                 | [X11Color Transparent]     | @['X11Color' 'Transparent']@                                             |                                 |                                                                  |+| Center             | center             | G       | Bl                       | True            | False                      | @'False'@                                                                |                                 |                                                                  |+| ClusterRank        | clusterrank        | G       | Cust "ClusterMode"       |                 | Local                      | @'Local'@                                                                |                                 | dot only                                                         |+| Color              | color              | ENC     | Cust "[Color]"           |                 | [X11Color Black]           | @['X11Color' 'Black']@                                                   |                                 |                                                                  |+| Comment            | comment            | ENG     | Strng                    |                 | \"\"                       | @\\\"\\\"@                                                               |                                 |                                                                  |+| Compound           | compound           | G       | Bl                       | True            | False                      | @'False'@                                                                |                                 | dot only                                                         |+| Concentrate        | concentrate        | G       | Bl                       | True            | False                      | @'False'@                                                                |                                 |                                                                  |+| Constraint         | constraint         | E       | Bl                       | True            | True                       | @'True'@                                                                 |                                 | dot only                                                         |+| Decorate           | decorate           | E       | Bl                       | True            | False                      | @'False'@                                                                |                                 |                                                                  |+| DefaultDist        | defaultdist        | G       | Dbl                      |                 |                            | @1+(avg. len)*sqrt(abs(V))@                                              | @epsilon@                       | neato only, only if @'Pack' 'DontPack'@                          |+| Dim                | dim                | G       | Integ                    |                 | 2                          | @2@                                                                      | @2@                             | sfdp, fdp, neato only                                            |+| Dimen              | dimen              | G       | Integ                    |                 | 2                          | @2@                                                                      | @2@                             | sfdp, fdp, neato only                                            |+| Dir                | dir                | E       | Cust "DirType"           |                 |                            | @'Forward'@ (directed), @'NoDir'@ (undirected)                           |                                 |                                                                  |+| DirEdgeConstraints | diredgeconstraints | G       | Cust "DEConstraints"     | EdgeConstraints | NoConstraints              | @'NoConstraints'@                                                        |                                 | neato only                                                       |+| Distortion         | distortion         | N       | Dbl                      |                 | 0                          | @0.0@                                                                    | @-100.0@                        |                                                                  |+| DPI                | dpi resolution     | G       | Dbl                      |                 |                            | @96.0@, @0.0@                                                            |                                 | svg, bitmap output only; \\\"resolution\\\" is a synonym         |+| EdgeURL            | edgeURL edgehref   | E       | EStrng                   |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | svg, map only                                                    |+| EdgeTarget         | edgetarget         | E       | EStrng                   |                 |                            | none                                                                     |                                 | svg, map only                                                    |+| EdgeTooltip        | edgetooltip        | E       | EStrng                   |                 |                            | @\\\"\\\"@                                                               |                                 | svg, cmap only                                                   |+| Epsilon            | epsilon            | G       | Dbl                      |                 |                            | @.0001 * # nodes@ (@mode == 'KK'@), @.0001@ (@mode == 'Major'@)          |                                 | neato only                                                       |+| ESep               | esep               | G       | Cust "DPoint"            |                 | (DVal 3)                   | @'DVal' 3@                                                               |                                 | not dot                                                          |+| FillColor          | fillcolor          | NEC     | Cust "[Color]"           |                 | [X11Color Black]           | @['X11Color' 'LightGray']@ (nodes), @['X11Color' 'Black']@ (clusters)    |                                 |                                                                  |+| FixedSize          | fixedsize          | N       | Bl                       | True            | False                      | @'False'@                                                                |                                 |                                                                  |+| FontColor          | fontcolor          | ENGC    | Cust "Color"             |                 | (X11Color Black)           | @'X11Color' 'Black'@                                                     |                                 |                                                                  |+| FontName           | fontname           | ENGC    | Strng                    |                 | \"Times-Roman\"            | @\\\"Times-Roman\\\"@                                                    |                                 |                                                                  |+| FontNames          | fontnames          | G       | Cust "SVGFontNames"      |                 | SvgNames                   | @'SvgNames'@                                                             |                                 | svg only                                                         |+| FontPath           | fontpath           | G       | Strng                    |                 |                            | system dependent                                                         |                                 |                                                                  |+| FontSize           | fontsize           | ENGC    | Dbl                      |                 | 14                         | @14.0@                                                                   | @1.0@                           |                                                                  |+| ForceLabels        | forcelabels        | G       | Bl                       | True            | False                      | @'False'@                                                                |                                 | Only for 'XLabel' attributes, requires Graphviz >= 2.29.0        |+| GradientAngle      | gradientangle      | NCG     | Integ                    |                 | 0                          | 0                                                                        |                                 | requires Graphviz >= 2.29.0                                      |+| Group              | group              | N       | Strng                    |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | dot only                                                         |+| HeadURL            | headURL headhref   | E       | EStrng                   |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | svg, map only                                                    |+| HeadClip           | headclip           | E       | Bl                       | True            | True                       | @'True'@                                                                 |                                 |                                                                  |+| HeadLabel          | headlabel          | E       | Cust "Label"             |                 | (StrLabel \"\")            | @'StrLabel' \\\"\\\"@                                                    |                                 |                                                                  |+| HeadPort           | headport           | E       | Cust "PortPos"           |                 | (CompassPoint CenterPoint) | @'CompassPoint' 'CenterPoint'@                                           |                                 |                                                                  |+| HeadTarget         | headtarget         | E       | EStrng                   |                 | \"\"                       | none                                                                     |                                 | svg, map only                                                    |+| HeadTooltip        | headtooltip        | E       | EStrng                   |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | svg, cmap only                                                   |+| Height             | height             | N       | Dbl                      |                 | 0.5                        | @0.5@                                                                    | @0.02@                          |                                                                  |+| ID                 | id                 | GNE     | EStrng                   |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | svg, postscript, map only                                        |+| Image              | image              | N       | Strng                    |                 | \"\"                       | @\\\"\\\"@                                                               |                                 |                                                                  |+| ImagePath          | imagepath          | G       | Cust "Paths"             |                 | (Paths [])                 | @'Paths' []@                                                             |                                 | Printing and parsing is OS-specific, requires Graphviz >= 2.29.0 |+| ImageScale         | imagescale         | N       | Cust "ScaleType"         | UniformScale    | NoScale                    | @'NoScale'@                                                              |                                 |                                                                  |+| Label              | label              | ENGC    | Cust "Label"             |                 | (StrLabel \"\")            | @'StrLabel' \\\"\\\\N\\\"@ (nodes), @'StrLabel' \\\"\\\"@ (otherwise)    |                                 |                                                                  |+| LabelURL           | labelURL labelhref | E       | EStrng                   |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | svg, map only                                                    |+| LabelScheme        | label_scheme       | G       | Cust "LabelScheme"       |                 | NotEdgeLabel               | @'NotEdgeLabel'@                                                         |                                 | sfdp only, requires Graphviz >= 2.28.0                           |+| LabelAngle         | labelangle         | E       | Dbl                      |                 | (-25)                      | @-25.0@                                                                  | @-180.0@                        |                                                                  |+| LabelDistance      | labeldistance      | E       | Dbl                      |                 | 1                          | @1.0@                                                                    | @0.0@                           |                                                                  |+| LabelFloat         | labelfloat         | E       | Bl                       | True            | False                      | @'False'@                                                                |                                 |                                                                  |+| LabelFontColor     | labelfontcolor     | E       | Cust "Color"             |                 | (X11Color Black)           | @'X11Color' 'Black'@                                                     |                                 |                                                                  |+| LabelFontName      | labelfontname      | E       | Strng                    |                 | \"Times-Roman\"            | @\\\"Times-Roman\\\"@                                                    |                                 |                                                                  |+| LabelFontSize      | labelfontsize      | E       | Dbl                      |                 | 14                         | @14.0@                                                                   | @1.0@                           |                                                                  |+| LabelJust          | labeljust          | GC      | Cust "Justification"     |                 | JCenter                    | @'JCenter'@                                                              |                                 |                                                                  |+| LabelLoc           | labelloc           | GCN     | Cust "VerticalPlacement" |                 | VTop                       | @'VTop'@ (clusters), @'VBottom'@ (root graphs), @'VCenter'@ (nodes)      |                                 |                                                                  |+| LabelTarget        | labeltarget        | E       | EStrng                   |                 | \"\"                       | none                                                                     |                                 | svg, map only                                                    |+| LabelTooltip       | labeltooltip       | E       | EStrng                   |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | svg, cmap only                                                   |+| Landscape          | landscape          | G       | Bl                       | True            | False                      | @'False'@                                                                |                                 |                                                                  |+| Layer              | layer              | EN      | Cust "LayerRange"        |                 |                            |                                                                          |                                 |                                                                  |+| Layers             | layers             | G       | Cust "LayerList"         |                 | (LL [])                    | @'LL' []@                                                                |                                 |                                                                  |+| LayerSep           | layersep           | G       | Cust "LayerSep"          |                 | (LSep \" :\\t\")           | @'LSep' \\\" :\\t\\\"@                                                   |                                 |                                                                  |+| Layout             | layout             | G       | Strng                    |                 | \"\"                       | @\\\"\\\"@                                                               |                                 |                                                                  |+| Len                | len                | E       | Dbl                      |                 |                            | @1.0@ (neato), @0.3@ (fdp)                                               |                                 | fdp, neato only                                                  |+| LevelsGap          | levelsgap          | G       | Dbl                      |                 | 0                          | @0.0@                                                                    |                                 | neato only                                                       |+| Levels             | levels             | G       | Integ                    |                 | maxBound                   | @'maxBound'@                                                             | @0@                             | sfdp only                                                        |+| LHead              | lhead              | E       | Strng                    |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | dot only                                                         |+| LHeight            | LHeight            | GC      | Dbl                      |                 |                            |                                                                          |                                 | write only, requires Graphviz >= 2.28.0                          |+| LPos               | lp                 | EGC     | Cust "Point"             |                 |                            |                                                                          |                                 | write only                                                       |+| LTail              | ltail              | E       | Strng                    |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | dot only                                                         |+| LWidth             | lwidth             | GC      | Dbl                      |                 |                            |                                                                          |                                 | write only, requires Graphviz >= 2.28.0                          |+| Margin             | margin             | NG      | Cust "DPoint"            |                 |                            | device dependent                                                         |                                 |                                                                  |+| MaxIter            | maxiter            | G       | Integ                    |                 |                            | @100 * # nodes@ (@mode == 'KK'@), @200@ (@mode == 'Major'@), @600@ (fdp) |                                 | fdp, neato only                                                  |+| MCLimit            | mclimit            | G       | Dbl                      |                 | 1                          | @1.0@                                                                    |                                 | dot only                                                         |+| MinDist            | mindist            | G       | Dbl                      |                 | 1                          | @1.0@                                                                    | @0.0@                           | circo only                                                       |+| MinLen             | minlen             | E       | Integ                    |                 | 1                          | @1@                                                                      | @0@                             | dot only                                                         |+| Mode               | mode               | G       | Cust "ModeType"          |                 | Major                      | @'Major'@                                                                |                                 | neato only                                                       |+| Model              | model              | G       | Cust "Model"             |                 | ShortPath                  | @'ShortPath'@                                                            |                                 | neato only                                                       |+| Mosek              | mosek              | G       | Bl                       | True            | False                      | @'False'@                                                                |                                 | neato only; requires the Mosek software                          |+| NodeSep            | nodesep            | G       | Dbl                      |                 | 0.25                       | @0.25@                                                                   | @0.02@                          | dot only                                                         |+| NoJustify          | nojustify          | GCNE    | Bl                       | True            | False                      | @'False'@                                                                |                                 |                                                                  |+| Normalize          | normalize          | G       | Bl                       | True            | False                      | @'False'@                                                                |                                 | not dot                                                          |+| Nslimit            | nslimit            | G       | Dbl                      |                 |                            |                                                                          |                                 | dot only                                                         |+| Nslimit1           | nslimit1           | G       | Dbl                      |                 |                            |                                                                          |                                 | dot only                                                         |+| Ordering           | ordering           | GN      | Cust "Order"             |                 |                            | none                                                                     |                                 | dot only                                                         |+| Orientation        | orientation        | N       | Dbl                      |                 | 0                          | @0.0@                                                                    | @360.0@                         |                                                                  |+| OutputOrder        | outputorder        | G       | Cust "OutputMode"        |                 | BreadthFirst               | @'BreadthFirst'@                                                         |                                 |                                                                  |+| Overlap            | overlap            | G       | Cust "Overlap"           | KeepOverlaps    | KeepOverlaps               | @'KeepOverlaps'@                                                         |                                 | not dot                                                          |+| OverlapScaling     | overlap_scaling    | G       | Dbl                      |                 | (-4)                       | @-4@                                                                     | @-1.0e10@                       | prism only                                                       |+| Pack               | pack               | G       | Cust "Pack"              | DoPack          | DontPack                   | @'DontPack'@                                                             |                                 | not dot                                                          |+| PackMode           | packmode           | G       | Cust "PackMode"          |                 | PackNode                   | @'PackNode'@                                                             |                                 | not dot                                                          |+| Pad                | pad                | G       | Cust "DPoint"            |                 | (DVal 0.0555)              | @'DVal' 0.0555@ (4 points)                                               |                                 |                                                                  |+| Page               | page               | G       | Cust "Point"             |                 |                            |                                                                          |                                 |                                                                  |+| PageDir            | pagedir            | G       | Cust "PageDir"           |                 | Bl                         | @'Bl'@                                                                   |                                 |                                                                  |+| PenColor           | pencolor           | C       | Cust "Color"             |                 | (X11Color Black)           | @'X11Color' 'Black'@                                                     |                                 |                                                                  |+| PenWidth           | penwidth           | CNE     | Dbl                      |                 | 1                          | @1.0@                                                                    | @0.0@                           |                                                                  |+| Peripheries        | peripheries        | NC      | Integ                    |                 | 1                          | shape default (nodes), @1@ (clusters)                                    | 0                               |                                                                  |+| Pin                | pin                | N       | Bl                       | True            | False                      | @'False'@                                                                |                                 | fdp, neato only                                                  |+| Pos                | pos                | EN      | Cust "Pos"               |                 |                            |                                                                          |                                 |                                                                  |+| QuadTree           | quadtree           | G       | Cust "QuadType"          | NormalQT        | NormalQT                   | @'NormalQT'@                                                             |                                 | sfdp only                                                        |+| Quantum            | quantum            | G       | Dbl                      |                 | 0                          | @0.0@                                                                    | @0.0@                           |                                                                  |+| Rank               | rank               | S       | Cust "RankType"          |                 |                            |                                                                          |                                 | dot only                                                         |+| RankDir            | rankdir            | G       | Cust "RankDir"           |                 | FromTop                    | @'FromTop'@                                                              |                                 | dot only                                                         |+| RankSep            | ranksep            | G       | Cust "[Double]"          |                 |                            | @[0.5]@ (dot), @[1.0]@ (twopi)                                           | [0.02]                          | twopi, dot only                                                  |+| Ratio              | ratio              | G       | Cust "Ratios"            |                 |                            |                                                                          |                                 |                                                                  |+| Rects              | rects              | N       | Cust "[Rect]"            |                 |                            |                                                                          |                                 | write only                                                       |+| Regular            | regular            | N       | Bl                       | True            | False                      | @'False'@                                                                |                                 |                                                                  |+| ReMinCross         | remincross         | G       | Bl                       | True            | False                      | @'False'@                                                                |                                 | dot only                                                         |+| RepulsiveForce     | repulsiveforce     | G       | Dbl                      |                 | 1                          | @1.0@                                                                    | @0.0@                           | sfdp only                                                        |+| Root               | root               | GN      | Cust "Root"              | IsCentral       | (NodeName \"\")            | @'NodeName' \\\"\\\"@ (graphs), @'NotCentral'@ (nodes)                   |                                 | circo, twopi only                                                |+| Rotate             | rotate             | G       | Integ                    |                 | 0                          | @0@                                                                      |                                 |                                                                  |+| Rotation           | rotation           | G       | Dbl                      |                 | 0                          | @0@                                                                      |                                 | sfdp only, requires Graphviz >= 2.28.0                           |+| SameHead           | samehead           | E       | Strng                    |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | dot only                                                         |+| SameTail           | sametail           | E       | Strng                    |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | dot only                                                         |+| SamplePoints       | samplepoints       | N       | Integ                    |                 |                            | @8@ (output), @20@ (overlap and image maps)                              |                                 |                                                                  |+| Scale              | scale              | G       | Cust "DPoint"            |                 |                            |                                                                          |                                 | twopi only, requires Graphviz >= 2.28.0                          |+| SearchSize         | searchsize         | G       | Integ                    |                 | 30                         | @30@                                                                     |                                 | dot only                                                         |+| Sep                | sep                | G       | Cust "DPoint"            |                 | (DVal 4)                   | @'DVal' 4@                                                               |                                 | not dot                                                          |+| Shape              | shape              | N       | Cust "Shape"             |                 | Ellipse                    | @'Ellipse'@                                                              |                                 |                                                                  |+| ShapeFile          | shapefile          | N       | Strng                    |                 | \"\"                       | @\\\"\\\"@                                                               |                                 |                                                                  |+| ShowBoxes          | showboxes          | ENG     | Integ                    |                 | 0                          | @0@                                                                      | @0@                             | dot only                                                         |+| Sides              | sides              | N       | Integ                    |                 | 4                          | @4@                                                                      | @0@                             |                                                                  |+| Size               | size               | G       | Cust "GraphSize"         |                 |                            |                                                                          |                                 |                                                                  |+| Skew               | skew               | N       | Dbl                      |                 | 0                          | @0.0@                                                                    | @-100.0@                        |                                                                  |+| Smoothing          | smoothing          | G       | Cust "SmoothType"        |                 | NoSmooth                   | @'NoSmooth'@                                                             |                                 | sfdp only                                                        |+| SortV              | sortv              | GCN     | Cust "Word16"            |                 | 0                          | @0@                                                                      | @0@                             |                                                                  |+| Splines            | splines            | G       | Cust "EdgeType"          | SplineEdges     | SplineEdges                |                                                                          |                                 |                                                                  |+| Start              | start              | G       | Cust "StartType"         |                 |                            |                                                                          |                                 | fdp, neato only                                                  |+| Style              | style              | ENC     | Cust "[StyleItem]"       |                 |                            |                                                                          |                                 |                                                                  |+| StyleSheet         | stylesheet         | G       | Strng                    |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | svg only                                                         |+| TailURL            | tailURL tailhref   | E       | EStrng                   |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | svg, map only                                                    |+| TailClip           | tailclip           | E       | Bl                       | True            | True                       | @'True'@                                                                 |                                 |                                                                  |+| TailLabel          | taillabel          | E       | Cust "Label"             |                 | (StrLabel \"\")            | @'StrLabel' \\\"\\\"@                                                    |                                 |                                                                  |+| TailPort           | tailport           | E       | Cust "PortPos"           |                 | (CompassPoint CenterPoint) | @'CompassPoint' 'CenterPoint'@                                           |                                 |                                                                  |+| TailTarget         | tailtarget         | E       | EStrng                   |                 | \"\"                       | none                                                                     |                                 | svg, map only                                                    |+| TailTooltip        | tailtooltip        | E       | EStrng                   |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | svg, cmap only                                                   |+| Target             | target             | ENGC    | EStrng                   |                 | \"\"                       | none                                                                     |                                 | svg, map only                                                    |+| Tooltip            | tooltip            | NEC     | EStrng                   |                 | \"\"                       | @\\\"\\\"@                                                               |                                 | svg, cmap only                                                   |+| TrueColor          | truecolor          | G       | Bl                       | True            |                            |                                                                          |                                 | bitmap output only                                               |+| Vertices           | vertices           | N       | Cust "[Point]"           |                 |                            |                                                                          |                                 | write only                                                       |+| ViewPort           | viewport           | G       | Cust "ViewPort"          |                 |                            | none                                                                     |                                 |                                                                  |+| VoroMargin         | voro_margin        | G       | Dbl                      |                 | 0.05                       | @0.05@                                                                   | @0.0@                           | not dot                                                          |+| Weight             | weight             | E       | Dbl                      |                 |                            | @1.0@                                                                    | @0@ (dot), @1@ (neato,fdp,sfdp) |                                                                  |+| Width              | width              | N       | Dbl                      |                 | 0.75                       | @0.75@                                                                   | @0.01@                          |                                                                  |+| XLabel             | xlabel             | EN      | Cust "Label"             |                 | (StrLabel \"\")            | @'StrLabel' \\\"\\\"@                                                    |                                 | requires Graphviz >= 2.29.0                                      |+| Z                  | z                  | N       | Dbl                      |                 | 0                          | @0.0@                                                                    | @-MAXFLOAT@, @-1000@            |                                                                  |++-}+ unknownAttr :: Doc unknownAttr = text "UnknownAttribute" +-- For testing purposes+attrs :: [Attribute] attrs = take 10 $ drop 5 attributes +-- For testing purposes+attrs' :: Atts attrs' = AS (text "Attribute") attrs  bool       :: a -> a -> Bool -> a@@ -617,3 +823,12 @@  dollar :: Doc dollar = char '$'+++-- Local Variables:+-- eval: (turn-on-orgtbl)+-- eval: (defun cell-quote (s) (concat "\"" s "\""))+-- eval: (defun cell-parens (s) (concat "(" s ")"))+-- eval: (defun cell-to-maybe (s) (if (string= "" s) "Nothing" (cell-parens (concat "Just " (cell-quote s)))))+-- eval: (defun cell-to-list (s) (concat "[" (mapconcat 'cell-quote (split-string s) ", ") "]"))+-- END: