Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

1.13.3.

  • Loading branch information...
commit 31d062a462434ec7058e79789d03c01f5264709b 1 parent a6dd0d3
Marco Túlio Gontijo authored

Showing 93 changed files with 27,943 additions and 0 deletions. Show diff stats Hide diff stats

  1. +375 0 CHANGELOG
  2. +99 0 LICENSE
  3. +8 0 Setup.hs
  4. +74 0 Test/Runner.hs
  5. +7 0 Test/examples/ArrowLayout.hs
  6. +2,181 0 Test/examples/Attributes.hs
  7. +8 0 Test/examples/BangPatterns.hs
  8. +2 0  Test/examples/Bug.hs
  9. +541 0 Test/examples/ByteStringUtils.hs
  10. +6,323 0 Test/examples/CParser.hs
  11. +17 0 Test/examples/ClassInstType.hs
  12. +4 0 Test/examples/DataHeadParen.hs
  13. +913 0 Test/examples/Directory.hs
  14. +1 0  Test/examples/EmptyAnn.hs
  15. +1 0  Test/examples/EmptyContext.hs
  16. +4 0 Test/examples/EmptyInstance.hs
  17. +3 0  Test/examples/EmptyList.hs
  18. +1 0  Test/examples/Ex1.hs
  19. +4 0 Test/examples/FamilyKindSig.hs
  20. +3 0  Test/examples/FixityTests.hs
  21. +4 0 Test/examples/ForeignImport.hs
  22. +5 0 Test/examples/GadtDeriving.hs
  23. +7 0 Test/examples/GenericTree.hs
  24. +4 0 Test/examples/GhcDeriving.hs
  25. +4 0 Test/examples/GroupKeyword.hs
  26. +30 0 Test/examples/HappyDoAction.hs
  27. +16 0 Test/examples/HaskellParser.hs
  28. +6 0 Test/examples/HexPrec.hs
  29. +2 0  Test/examples/Hyphen.hs
  30. +12 0 Test/examples/IfThenElseLayout.hs
  31. +1 0  Test/examples/ImportSymbol.hs
  32. +4 0 Test/examples/IndentedWhere.hs
  33. +6 0 Test/examples/InfixParser.hs
  34. +1 0  Test/examples/LanguagePragma.hs
  35. +3 0  Test/examples/LineOptionsPragma.hs
  36. +5 0 Test/examples/LinePragma.hs
  37. +1 0  Test/examples/ListComp1.hs
  38. +12 0 Test/examples/MagicHash.hs
  39. +6 0 Test/examples/MultiCtxt.hs
  40. +3 0  Test/examples/NPlusK.hs
  41. +3 0  Test/examples/NestedAsPat.hs
  42. +5 0 Test/examples/PackageImport.hs
  43. +3 0  Test/examples/ParenFunBind.hs
  44. +7 0 Test/examples/Pragma.hs
  45. +3 0  Test/examples/QualifiedDot.hs
  46. +12 0 Test/examples/QuasiQuoteLines.hs
  47. +4 0 Test/examples/Rank2Types.hs
  48. +2 0  Test/examples/ReadP.hs
  49. +913 0 Test/examples/RealGHC.lhs
  50. +898 0 Test/examples/RealHSE.hs
  51. +254 0 Test/examples/RealHoogle.hs
  52. +395 0 Test/examples/RealTagSoup.hs
  53. +3 0  Test/examples/RecordInfixSelector.hs
  54. +5 0 Test/examples/RecordWildcards.hs
  55. +13 0 Test/examples/RelaxedDo.hs
  56. +3 0  Test/examples/SCCPragmas.hs
  57. +12 0 Test/examples/ScopedTypeVariables.hs
  58. +1 0  Test/examples/SimpleDeriving.hs
  59. +4 0 Test/examples/SingleClassAsst.hs
  60. +4 0 Test/examples/SpecializeInstance.hs
  61. +2 0  Test/examples/Testing.hs
  62. +3 0  Test/examples/TupleSections.hs
  63. +7 0 Test/examples/TypeFunctions.hs
  64. +4 0 Test/examples/TypeOperatorsTest.hs
  65. +118 0 Test/examples/Unicode.hs
  66. +12 0 Test/examples/UnicodeSyntax.hs
  67. +4 0 Test/examples/UnindentedPragmaClose.hs
  68. +3 0  Test/examples/WhereBlock.hs
  69. +1 0  Test/examples/WithKeyword.hs
  70. +9 0 Test/failing.txt
  71. +6 0 Test/printFail.txt
  72. +146 0 haskell-src-exts.cabal
  73. +114 0 src/Language/Haskell/Exts.hs
  74. +124 0 src/Language/Haskell/Exts/Annotated.hs
  75. +290 0 src/Language/Haskell/Exts/Annotated/Build.hs
  76. +1,790 0 src/Language/Haskell/Exts/Annotated/ExactPrint.hs
  77. +344 0 src/Language/Haskell/Exts/Annotated/Fixity.hs
  78. +520 0 src/Language/Haskell/Exts/Annotated/Simplify.hs
  79. +2,225 0 src/Language/Haskell/Exts/Annotated/Syntax.hs
  80. +290 0 src/Language/Haskell/Exts/Build.hs
  81. +20 0 src/Language/Haskell/Exts/Comments.hs
  82. +37 0 src/Language/Haskell/Exts/ExtScheme.hs
  83. +264 0 src/Language/Haskell/Exts/Extension.hs
  84. +402 0 src/Language/Haskell/Exts/Fixity.hs
  85. +1,841 0 src/Language/Haskell/Exts/InternalParser.ly
  86. +1,289 0 src/Language/Haskell/Exts/Lexer.hs
  87. +428 0 src/Language/Haskell/Exts/ParseMonad.hs
  88. +440 0 src/Language/Haskell/Exts/ParseSyntax.hs
  89. +961 0 src/Language/Haskell/Exts/ParseUtils.hs
  90. +174 0 src/Language/Haskell/Exts/Parser.hs
  91. +1,650 0 src/Language/Haskell/Exts/Pretty.hs
  92. +180 0 src/Language/Haskell/Exts/SrcLoc.hs
  93. +1,000 0 src/Language/Haskell/Exts/Syntax.hs
375 CHANGELOG
... ... @@ -0,0 +1,375 @@
  1 +** 1.13.x
  2 +
  3 +1.13.2 --> 1.13.3
  4 +===============
  5 +
  6 +* Fundep premises are now allowed to be empty.
  7 +
  8 +* Fix the bug where the lexer would crash on a LINE pragma
  9 + that did not include a line number.
  10 +
  11 +* Fix the bug where the lexer would require the # of a
  12 + MagicHash-style type constructor to be succeeded by at
  13 + least one character in the file.
  14 +
  15 +* Fix long-standing bug where the parser would crash with
  16 + an ugly "Internal error" error message if encountering
  17 + an extra }.
  18 +
  19 +* Report errors at the right place for function arity
  20 + mismatches. Earlier they were reported at end of file,
  21 + now they are reported where the function is declared.
  22 +
  23 +* Lexer now properly fails on line-breaks in string literals.
  24 +
  25 +* Lexer now handles character escapes up to 0x10FFFF (unicode).
  26 +
  27 +
  28 +1.13.1 --> 1.13.2
  29 +===============
  30 +
  31 +* Fix the bug with the precedence of unary prefix minus.
  32 + Previously it was resolved as binding more tightly
  33 + than any infix operator, now it is correctly treated
  34 + as having the same fixity as binary infix minus.
  35 +
  36 +
  37 +1.13.0 --> 1.13.1
  38 +===============
  39 +
  40 +* Allow an optional semi before the closing tag of
  41 + an element. This achieves a similar effect for
  42 + XmlSyntax in do blocks as DoAndIfThenElse does for
  43 + the if construct. No more need to indent the closing
  44 + tag one step further than the opening tag.
  45 +
  46 +* Add a dummy 'noLoc :: SrcLoc' to L.H.E.SrcLoc, to
  47 + use when generating code. It could definitely be
  48 + done more elegantly, but not without inducing another
  49 + major version bump, so later.
  50 +
  51 +* Fix a regression from 1.11.x where the parser would crash
  52 + upon encountering non-simple class/data declaration
  53 + heads, e.g. 'data A [a]'. Now fails with a parse error
  54 + as intended.
  55 +
  56 +
  57 +1.12.0 --> 1.13.0
  58 +===============
  59 +
  60 +* Add extensions DoAndIfThenElse and NPlusKPatterns to
  61 + Language.Haskell.Exts.Extensions.
  62 +
  63 +* DoAndIfThenElse is now supported, at long last,
  64 + making HSE compatible with Haskell2010
  65 +
  66 +* Introduce haskell98 and haskell2010 extension groups,
  67 + exported from Language.Haskell.Exts.Extensions.
  68 +
  69 +* Backwards-incompatible change: default parse mode
  70 + is now to use haskell2010, which means the following
  71 + features are recognized by default: DoAndIfThenElse,
  72 + PatternGuards, ForeignFunctionInterface, EmptyDataDecls.
  73 + NPlusKPatterns is no longer recognized by default.
  74 +
  75 +
  76 +** 1.12.x
  77 +
  78 +1.11.1 --> 1.12.0
  79 +===============
  80 +
  81 +* Move from old [$...| quasi-quote syntax to the new [...| one.
  82 + The old syntax is still recognized while parsing.
  83 +
  84 +* Allow symbols as variables when TypeOperators is enabled.
  85 +
  86 +* Rename ExplicitForall in ExplicitForAll, to be consistent
  87 + with GHC and the Haskell' process.
  88 +
  89 +
  90 +** 1.11.x
  91 +
  92 +1.10.2 --> 1.11.1
  93 +===============
  94 +
  95 +* API change: the fixities field in ParseMode is now of type
  96 + Maybe [Fixity]. If the field is Nothing the parsing will
  97 + not try to do any fixity resolution whatsoever, otherwise
  98 + it behaves as before.
  99 +
  100 +* API change, bug fix: The Fixity type contains a QName rather
  101 + than an Op to name the operator. The operator must match
  102 + the given QName exactly (i.e., unqualified names only match
  103 + unqualified names, and qualified names only match qualified
  104 + names) for applyFixities to perform fixups.
  105 +
  106 +* Bug fix: End-of-file inside an OPTIONS pragma no longer loops.
  107 +
  108 +
  109 +
  110 +** 1.10.x
  111 +
  112 +1.10.1 --> 1.10.2
  113 +===============
  114 +
  115 +* Fix a missing case in the Functor declaration for Decl. Thanks
  116 + to Malcolm Wallace for the patch!
  117 +
  118 +1.10.0 --> 1.10.1
  119 +===============
  120 +
  121 +* Enable the unicode version of DoubleColon (x2237). Thanks
  122 + to Andr�s Sicard-Ram�rez for the patch!
  123 +
  124 +1.9.6 --> 1.10.0
  125 +===============
  126 +
  127 +* Ensure that implied extensions are always picked up, not only
  128 + when using the parseFile* family of functions as previously.
  129 +
  130 +* Add the newly devised <%>...</%> syntax to the XmlSyntax support.
  131 + This causes changes to pretty much everything, including adding
  132 + a case to the AST which prompts the major version bump.
  133 +
  134 +
  135 +** 1.9.x
  136 +
  137 +1.9.5 --> 1.9.6
  138 +===============
  139 +
  140 +* Fix a bug (#203) where the lexer loops on malformed quasi-quoters.
  141 +
  142 +* Fix a bug with pretty-printing RULES pragmas.
  143 +
  144 +1.9.4 --> 1.9.5
  145 +===============
  146 +
  147 +* Fix a bug where deriving clauses for GADT-style data declarations
  148 + were not properly indented.
  149 +
  150 +* Pretty-printing patterns is now more accurate in inserting (and not
  151 + inserting) parentheses when needed.
  152 +
  153 +1.9.3 --> 1.9.4
  154 +===============
  155 +
  156 +* Pretty-printer now inserts parentheses in clever places when
  157 + printing kinds.
  158 +
  159 +* Pretty-printing expressions is now far more accurate in inserting
  160 + (and not inserting) parentheses when needed.
  161 +
  162 +* Pretty-printing negative expressions no longer inserts a superfluous
  163 + space between the - and the expression.
  164 +
  165 +1.9.2 --> 1.9.3
  166 +===============
  167 +
  168 +* Constructors for newtype declarations must now have exactly one
  169 + argument. This is only when using the classic syntax, not with
  170 + GADT-style syntax.
  171 +
  172 +* Fix a bug where preceding commas in tuple sections were counted
  173 + one too few.
  174 +
  175 +1.9.1 --> 1.9.2
  176 +===============
  177 +
  178 +* Fix a bug with pretty-printing lexer tokens.
  179 +
  180 +* Fix a bug where non-colon TypeOperators could not be used in
  181 + prefix mode.
  182 +
  183 +1.9.0 --> 1.9.1
  184 +===============
  185 +
  186 +* Export parseFileContentsWithExts from .Exts.
  187 +
  188 +1.8.2 --> 1.9.0
  189 +===============
  190 +
  191 +* OptionPragma is renamed to the more descriptive ModulePragma,
  192 + and adds a constructor AnnModulePragma for handling ANN pragmas
  193 + preceding module header.
  194 +
  195 +* Add instances for Eq/Ord/Data/Typeable for Fixity.
  196 +
  197 +* Add 'parseFileWithComments' and 'parseFileContentsWithComments'
  198 + to L.H.Exts .
  199 +
  200 +* More informative error messages when HSX tags are mismatched.
  201 +
  202 +
  203 +
  204 +** 1.8.x
  205 +
  206 +1.8.1 --> 1.8.2
  207 +===============
  208 +
  209 +* Don't insert redundant parentheses around record constructions
  210 + and updates.
  211 +
  212 +1.8.0 --> 1.8.1
  213 +===============
  214 +
  215 +* Fix three bugs with the handling of ANN. I must have been really
  216 + tired when implementing that support.
  217 +
  218 +1.7.2 --> 1.8.0
  219 +===============
  220 +
  221 +* Add an instance Show Fixity (derived).
  222 +
  223 +* Support for the new ANN and INLINE_CONLIKE pragmas.
  224 +
  225 +* Export knownExtensions from .Extension.
  226 +
  227 +* Remove support for CFILES and INCLUDE pragmas. The support wasn't
  228 + correct anyway, as it assumed the pragmas appeared at the top of
  229 + files. As CFILES/INCLUDE pragmas can (and do) appear anywhere,
  230 + there's no hope to support them in the AST. Better to remove the
  231 + support altogether. Files with CFILES/INCLUDE pragmas can still
  232 + be parsed of course, but those pragmas will be handled as comments.
  233 +
  234 +* Parsing with ignoreLinePragmas = False now correctly updates the
  235 + file name.
  236 +
  237 +* Allow the whole SPECIALISE/INLINE family of pragmas in instance
  238 + declarations. The InsInline constructor is removed, and is now
  239 + represented by InsDecl (InlineSig ...).
  240 +
  241 +* Fix a bug with line numbering and quasi quotes, and a similar one
  242 + with line numbering and CDATA.
  243 +
  244 +* Fix a few minor bugs in the exactPrinter.
  245 +
  246 +* Fix the strange handling of so called strings in LINE pragmas.
  247 +
  248 +** 1.7.x
  249 +
  250 +1.7.1 --> 1.7.2
  251 +===============
  252 +
  253 +* Fixes a bug in lexing LINE pragmas (used when ignoreLinePragmas
  254 + is set to False).
  255 +
  256 +1.7.0 --> 1.7.1
  257 +===============
  258 +
  259 +* UnicodeSyntax now also enables the forall symbol (U+2200).
  260 +
  261 +1.6.1 --> 1.7.0
  262 +===============
  263 +
  264 +* Operators defined on the form
  265 +
  266 + (a `op` b) c = ...
  267 +
  268 + could not be handled by the (annotated) AST, nor the parser. I had to
  269 + change the definition of the AST node for InfixMatch to allow a list
  270 + of right-hand subpatterns, i.e.
  271 +
  272 + InfixMatch l (Pat l) (Name l) (Pat l) ...
  273 +
  274 + has become
  275 +
  276 + InfixMatch l (Pat l) (Name l) [Pat l] ...
  277 +
  278 + I also had an epiphany and fixed the issue that would arise with
  279 + exact printing of prefix definitions including parentheses, so
  280 + that now works too!
  281 +
  282 +** 1.6.x
  283 +
  284 +1.6.0 --> 1.6.1
  285 +===============
  286 +
  287 +* UnicodeSyntax now works not only for identifiers, but also for
  288 + ->, <- and =>, as well as Arrows arrows and kind stars.
  289 +
  290 +1.5.3 --> 1.6.0
  291 +===============
  292 +
  293 +* (=~=) turns out to be too general at Functor (for intuitive and not
  294 + technical reasons), so is specialised to Annotated to closer mirror
  295 + the original intention.
  296 +
  297 +* applyFixities is hoisted to a monad, and now fails on ambiguous infix
  298 + expressions.
  299 +
  300 +** 1.5.x
  301 +
  302 +1.5.2 --> 1.5.3
  303 +===============
  304 +
  305 +* Several small bug fixes in the exact printer, and fail more gracefully
  306 + if the number of srcInfoPoints doesn't match the needs of the node.
  307 +
  308 +1.5.1 --> 1.5.2
  309 +===============
  310 +
  311 +* Fix a bug in the exact printer that made it always print the first token
  312 + at position (0,0).
  313 +
  314 +* In fixing the above, Annotated is now a superclass of ExactP. It was already
  315 + a superclass in spirit, and nothing can break from this since ExactP is only
  316 + exported abstractly.
  317 +
  318 +1.5.0 --> 1.5.1
  319 +===============
  320 +
  321 +* The pretty printer now introduces parentheses for non-atomic arguments to
  322 + function application. Note that infix applications are left untouched, no
  323 + parentheses will be inserted there, as it is assumed that fixities are
  324 + already properly resolved.
  325 +
  326 +* Fix a bug in the pretty printer where view patterns and n+k patterns were
  327 + not properly parenthesised.
  328 +
  329 +1.4.0 --> 1.5.0
  330 +===============
  331 +
  332 +* Add support for acting on LINE pragmas while parsing, i.e. updating the source
  333 + position according to info given in LINE pragmas. This is done conditionally
  334 + based on a new flag ignoreLinePragmas in the ParseMode, hence the need to
  335 + increase the major version.
  336 +
  337 +** 1.4.x
  338 +
  339 +1.3.5 --> 1.4.0
  340 +===============
  341 +
  342 +* The AST node for Proc in the simple AST is changed to include a SrcLoc argument,
  343 + to make it consistent with similar nodes e.g. Lambda. This is specifically needed
  344 + for transformation of patterns in HSX.
  345 +
  346 +
  347 +** 1.3.x
  348 +
  349 +1.3.4 --> 1.3.5
  350 +===============
  351 +
  352 +* Added an entry point in the parser for statements, and an instance Parseable Stmt
  353 + to go with it.
  354 +
  355 +* Ensured that .Annotated exports all relevant parseXXX(WithYYY) functions.
  356 +
  357 +1.3.3 --> 1.3.4
  358 +===============
  359 +
  360 +* Operator fixities are now resolved in patterns.
  361 +
  362 +1.3.2 --> 1.3.3
  363 +===============
  364 +
  365 +* Fixes a bug where qualified keywords are rejected even if the extension that
  366 + enables the keyword in question is not turned on.
  367 +
  368 +
  369 +1.3.0 --> 1.3.2
  370 +===============
  371 +
  372 +(Let's forget 1.3.1 ever existed.)
  373 +
  374 +* Fix a bug where declarations of infix operators were not properly merged as FunBinds.
  375 +
99 LICENSE
... ... @@ -0,0 +1,99 @@
  1 +This library (Haskell Source eXtensions) is derived from code from several
  2 +sources:
  3 +
  4 + * Code from the GHC project which is largely (c) The University of
  5 + Glasgow, and distributable under a BSD-style license (see below),
  6 +
  7 + * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
  8 + and freely redistributable (but see the full license for
  9 + restrictions).
  10 +
  11 +The full text of these licenses is reproduced below. All of the
  12 +licenses are BSD-style or compatible.
  13 +
  14 +-----------------------------------------------------------------------------
  15 +The haskell-src-exts package itself is distributable under the
  16 +modified BSD license:
  17 +
  18 +Copyright (c) 2005, Niklas Broberg
  19 +All rights reserved.
  20 +
  21 +Redistribution and use in source and binary forms, with or without
  22 +modification, are permitted provided that the following conditions are
  23 +met:
  24 +
  25 + * Redistributions of source code must retain the above copyright
  26 + notice, this list of conditions and the following disclaimer.
  27 +
  28 + * Redistributions in binary form must reproduce the above
  29 + copyright notice, this list of conditions and the following
  30 + disclaimer in the documentation and/or other materials provided
  31 + with the distribution.
  32 +
  33 + * The names of its contributors may not be used to endorse or
  34 + promote products derived from this software without specific prior
  35 + written permission.
  36 +
  37 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  38 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  39 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  40 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  41 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  42 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  43 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  44 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  45 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  46 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  47 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48 +
  49 +-----------------------------------------------------------------------------
  50 +
  51 +The Glasgow Haskell Compiler License
  52 +
  53 +Copyright 2004, The University Court of the University of Glasgow.
  54 +All rights reserved.
  55 +
  56 +Redistribution and use in source and binary forms, with or without
  57 +modification, are permitted provided that the following conditions are met:
  58 +
  59 +- Redistributions of source code must retain the above copyright notice,
  60 +this list of conditions and the following disclaimer.
  61 +
  62 +- Redistributions in binary form must reproduce the above copyright notice,
  63 +this list of conditions and the following disclaimer in the documentation
  64 +and/or other materials provided with the distribution.
  65 +
  66 +- Neither name of the University nor the names of its contributors may be
  67 +used to endorse or promote products derived from this software without
  68 +specific prior written permission.
  69 +
  70 +THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
  71 +GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  72 +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  73 +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  74 +UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
  75 +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  76 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  77 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  78 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  79 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  80 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  81 +DAMAGE.
  82 +
  83 +-----------------------------------------------------------------------------
  84 +
  85 +Code derived from the document "Report on the Programming Language
  86 +Haskell 98", is distributed under the following license:
  87 +
  88 + Copyright (c) 2002 Simon Peyton Jones
  89 +
  90 + The authors intend this Report to belong to the entire Haskell
  91 + community, and so we grant permission to copy and distribute it for
  92 + any purpose, provided that it is reproduced in its entirety,
  93 + including this Notice. Modified versions of this Report may also be
  94 + copied and distributed for any purpose, provided that the modified
  95 + version is clearly presented as such, and that it does not claim to
  96 + be a definition of the Haskell 98 Language.
  97 +
  98 +-----------------------------------------------------------------------------
  99 +
8 Setup.hs
... ... @@ -0,0 +1,8 @@
  1 +import Distribution.Simple
  2 +import System.Process (rawSystem)
  3 +import System.Exit (ExitCode(..))
  4 +import System.FilePath ((</>))
  5 +main = defaultMainWithHooks $ simpleUserHooks { runTests = \args _ _ _ -> do
  6 + ExitSuccess <- rawSystem "runhaskell" (("Test" </> "Runner.hs") : args)
  7 + return ()
  8 + }
74 Test/Runner.hs
... ... @@ -0,0 +1,74 @@
  1 +-- | Use "runhaskell Setup.hs test" or "cabal test" to run these tests.
  2 +-- Particular files may be selected by supplying their names as arguments.
  3 +module Main where
  4 +
  5 +import Language.Haskell.Exts.Annotated
  6 +import System.IO
  7 +import Control.Monad
  8 +import Data.List
  9 +import Data.Char
  10 +import System.Directory
  11 +import System.Environment (getArgs)
  12 +import System.Exit (exitFailure)
  13 +import System.FilePath
  14 +
  15 +
  16 +main :: IO ()
  17 +main = go =<< getArgs
  18 +
  19 +
  20 +-- | Run the selected tests - or all of them if the supplied list is empty
  21 +go :: [FilePath] -> IO ()
  22 +go testsToRun = do
  23 + hSetBuffering stdout NoBuffering
  24 + files <- if null testsToRun then getDirectoryContents examplesDir else return testsToRun
  25 + putStrLn "Testing parser:"
  26 + src <- liftM (map (head . words) . lines) . readFile $ "Test" </> "failing.txt"
  27 + results <- sequence [check (x `elem` src) (examplesDir </> x) | x <- files, not $ "." `isPrefixOf` x]
  28 + putStrLn "\nAll parsing tests completed!\n"
  29 + putStrLn "Testing exact printer:"
  30 + pSrc <- liftM (map (head . words) . lines) . readFile $ "Test" </> "printFail.txt"
  31 + pResults <- sequence [roundTrip (x `elem` pSrc) (examplesDir </> x)
  32 + | x <- files, x `notElem` src, not $ "." `isPrefixOf` x]
  33 + putStrLn "\nAll printing tests completed!\n"
  34 + unless (all id $ results ++ pResults) exitFailure
  35 +
  36 +
  37 +-- | Where all the tests are to be found
  38 +examplesDir :: FilePath
  39 +examplesDir = "Test" </> "examples"
  40 +
  41 +
  42 +-- | Runs the test, and returns True unless there is an unexpected result
  43 +check :: Bool -> FilePath -> IO Bool
  44 +check expected file = do
  45 + res <- parseFile file
  46 + case res of
  47 + ParseOk x | expected -> putStrLn ("\n<unexpected pass for " ++ file ++ ">") >> return False
  48 + | otherwise -> putChar '.' >> return True
  49 + err | expected -> putChar '!' >> return True
  50 + | otherwise -> putStrLn ("\nFailure when parsing " ++ show file ++ "\n" ++ show err) >> return False
  51 +
  52 +
  53 +roundTrip :: Bool -> FilePath -> IO Bool
  54 +roundTrip expected file = do
  55 + fc <- readFile file
  56 + pr <- parseFileWithComments (defaultParseMode { parseFilename = file }) file
  57 + case pr of
  58 + ParseOk (ast,cs) -> do
  59 + let res = exactPrint ast cs
  60 + xs = dropWhile (uncurry (==))
  61 + $ zip (map (reverse . dropWhile isSpace . reverse) $ lines fc)
  62 + (map (reverse . dropWhile isSpace . reverse) $ lines res)
  63 + case xs of
  64 + [] | expected -> putStrLn ("\n<unexpected pass for " ++ file ++ ">") >> return False
  65 + | otherwise -> putChar '.' >> return True
  66 + (lfc, lres):_
  67 + | expected -> putChar '!' >> return True
  68 + | otherwise -> do
  69 + putStrLn $ "Result of print does not match input when printing " ++ show file
  70 + putStrLn $ "First unmatching lines are (line length):"
  71 + putStrLn $ " Input (" ++ show (length lfc) ++ "): " ++ lfc
  72 + putStrLn $ " Result (" ++ show (length lres) ++ "): " ++ lres
  73 + return False
  74 + err -> putStrLn ("\nFailure when parsing " ++ show file ++ "\n" ++ show err) >> return False
7 Test/examples/ArrowLayout.hs
... ... @@ -0,0 +1,7 @@
  1 +{-# LANGUAGE Arrows #-}
  2 +module ArrowLayout where
  3 +
  4 +exp = proc () -> do
  5 + rec let e = 1 + i
  6 + i <- integral -< e
  7 + returnA -< e
2,181 Test/examples/Attributes.hs
... ... @@ -0,0 +1,2181 @@
  1 +{- |
  2 + Module : Data.GraphViz.Attributes
  3 + Description : Definition of the Graphviz attributes.
  4 + Copyright : (c) Matthew Sackman, Ivan Lazar Miljenovic
  5 + License : 3-Clause BSD-style
  6 + Maintainer : Ivan.Miljenovic@gmail.com
  7 +
  8 + This module defines the various attributes that different parts of
  9 + a Graphviz graph can have. These attributes are based on the
  10 + documentation found at:
  11 + <http://graphviz.org/doc/info/attrs.html>
  12 +
  13 + For more information on usage, etc. please see that document.
  14 +
  15 + A summary of known current constraints\/limitations\/differences:
  16 +
  17 + * There might still be a few cases where quotes are still not
  18 + escaped/parsed correctly; if you find such a situation, please
  19 + let me know; however, you should be able to use 'String' values
  20 + directly without having to worry about when quotes are required
  21 + or extra escaping of quote characters as 'PrintDot' and
  22 + 'ParseDot' instances for 'String' should take care of that
  23 + for you.
  24 +
  25 + * Note that for an edge, in /Dot/ parlance if the edge goes from
  26 + /A/ to /B/, then /A/ is the tail node and /B/ is the head node
  27 + (since /A/ is at the tail end of the arrow).
  28 +
  29 + * ColorList and PointfList are defined as actual lists (but
  30 + 'LayerList' is not). Note that for the Color 'Attribute' for
  31 + node values, only a single Color is valid; edges are allowed
  32 + multiple colors with one spline/arrow per color in the list (but
  33 + you must have at least one 'Color' in the list). This might be
  34 + changed in future.
  35 +
  36 + * Style is implemented as a list of 'StyleItem' values; note that
  37 + empty lists are not allowed.
  38 +
  39 + * A lot of values have a possible value of @none@. These now
  40 + have custom constructors. In fact, most constructors have been
  41 + expanded upon to give an idea of what they represent rather than
  42 + using generic terms.
  43 +
  44 + * @PointF@ and 'Point' have been combined, and feature support for pure
  45 + 'Int'-based co-ordinates as well as 'Double' ones (i.e. no floating
  46 + point-only points for Point). The optional '!' and third value
  47 + for Point are not available.
  48 +
  49 + * 'Rect' uses two 'Point' values to denote the lower-left and
  50 + top-right corners.
  51 +
  52 + * The two 'LabelLoc' attributes have been combined.
  53 +
  54 + * The defined 'LayerSep' is not used to parse 'LayerRange' or
  55 + 'LayerList'; the default (@[' ', ':', '\t']@) is instead used.
  56 +
  57 + * @SplineType@ has been replaced with @['Spline']@.
  58 +
  59 + * Only polygon-based 'Shape's are available.
  60 +
  61 + * 'PortPos' only has the 'CompassPoint' option, not
  62 + @PortName[:CompassPoint]@ (since record shapes aren't allowed,
  63 + and parsing HTML-like labels could be problematic).
  64 +
  65 + * Not every 'Attribute' is fully documented/described. However,
  66 + all those which have specific allowed values should be covered.
  67 +
  68 + * Deprecated 'Overlap' algorithms are not defined.
  69 +
  70 + * The global @Orientation@ attribute is not defined, as it is
  71 + difficult to distinguish from the node-based 'Orientation'
  72 + 'Attribute'; also, its behaviour is duplicated by 'Rotate'.
  73 +
  74 + -}
  75 +module Data.GraphViz.Attributes
  76 + ( -- * The actual /Dot/ attributes.
  77 + Attribute(..)
  78 + , Attributes
  79 + -- ** Validity functions on @Attribute@ values.
  80 + , usedByGraphs
  81 + , usedBySubGraphs
  82 + , usedByClusters
  83 + , usedByNodes
  84 + , usedByEdges
  85 + -- * Value types for @Attribute@s.
  86 + , EscString
  87 + , URL(..)
  88 + , ArrowType(..)
  89 + , AspectType(..)
  90 + , Rect(..)
  91 + , ClusterMode(..)
  92 + , DirType(..)
  93 + , DEConstraints(..)
  94 + , DPoint(..)
  95 + , ModeType(..)
  96 + , Model(..)
  97 + , Label(..)
  98 + , Point(..)
  99 + , Overlap(..)
  100 + , LayerRange(..)
  101 + , LayerID(..)
  102 + , LayerList(..)
  103 + , OutputMode(..)
  104 + , Pack(..)
  105 + , PackMode(..)
  106 + , Pos(..)
  107 + , EdgeType(..)
  108 + , PageDir(..)
  109 + , Spline(..)
  110 + , QuadType(..)
  111 + , Root(..)
  112 + , RankType(..)
  113 + , RankDir(..)
  114 + , Shape(..)
  115 + , SmoothType(..)
  116 + , StartType(..)
  117 + , STStyle(..)
  118 + , StyleItem(..)
  119 + , StyleName(..)
  120 + , PortPos(..)
  121 + , CompassPoint(..)
  122 + , ViewPort(..)
  123 + , FocusType(..)
  124 + , VerticalPlacement(..)
  125 + , ScaleType(..)
  126 + , Justification(..)
  127 + , Ratios(..)
  128 + , module Data.GraphViz.Attributes.Colors
  129 + -- * Types representing the Dot grammar for @ArrowType@.
  130 + , ArrowShape(..)
  131 + , ArrowModifier(..)
  132 + , ArrowFill(..)
  133 + , ArrowSide(..)
  134 + -- ** Default @ArrowType@ aliases.
  135 + -- *** The 9 primitive @ArrowShape@s.
  136 + , box
  137 + , crow
  138 + , diamond
  139 + , dotArrow
  140 + , inv
  141 + , noArrow
  142 + , normal
  143 + , tee
  144 + , vee
  145 + -- *** 5 derived Arrows.
  146 + , oDot
  147 + , invDot
  148 + , invODot
  149 + , oBox
  150 + , oDiamond
  151 + -- *** 5 supported cases for backwards compatibility
  152 + , eDiamond
  153 + , openArr
  154 + , halfOpen
  155 + , emptyArr
  156 + , invEmpty
  157 + -- ** @ArrowModifier@ instances
  158 + , noMods
  159 + , openMod
  160 + -- * Other exported functions\/values
  161 + , defLayerSep
  162 + , notLayerSep
  163 + ) where
  164 +
  165 +import Data.GraphViz.Attributes.Colors
  166 +import Data.GraphViz.Util
  167 +import Data.GraphViz.Parsing
  168 +import Data.GraphViz.Printing
  169 +
  170 +import Data.Char(toLower)
  171 +import Data.Maybe(isJust)
  172 +import Control.Arrow(first)
  173 +import Control.Monad(liftM, liftM2)
  174 +
  175 +-- -----------------------------------------------------------------------------
  176 +
  177 +{- |
  178 +
  179 + These attributes have been implemented in a /permissive/ manner:
  180 + that is, rather than split them up based on which type of value
  181 + they are allowed, they have all been included in the one data type,
  182 + with functions to determine if they are indeed valid for what
  183 + they're being applied to.
  184 +
  185 + To interpret the /Valid for/ listings:
  186 +
  187 + [@G@] Valid for Graphs.
  188 +
  189 + [@C@] Valid for Clusters.
  190 +
  191 + [@S@] Valid for Sub-Graphs (and also Clusters).
  192 +
  193 + [@N@] Valid for Nodes.
  194 +
  195 + [@E@] Valid for Edges.
  196 +
  197 + The /Default/ listings are those that the various Graphviz commands
  198 + use if that 'Attribute' isn't specified (in cases where this is
  199 + /none/, this is equivalent to a 'Nothing' value; that is, no value
  200 + is used). The /Parsing Default/ listings represent what value is
  201 + used (i.e. corresponds to 'True') when the 'Attribute' name is
  202 + listed on its own in /Dot/ source code.
  203 +-}
  204 +data Attribute
  205 + = Damping Double -- ^ /Valid for/: G; /Default/: @0.99@; /Minimum/: @0.0@; /Notes/: neato only
  206 + | K Double -- ^ /Valid for/: GC; /Default/: @0.3@; /Minimum/: @0@; /Notes/: sfdp, fdp only
  207 + | URL URL -- ^ /Valid for/: ENGC; /Default/: none; /Notes/: svg, postscript, map only
  208 + | ArrowHead ArrowType -- ^ /Valid for/: E; /Default/: @'normal'@
  209 + | ArrowSize Double -- ^ /Valid for/: E; /Default/: @1.0@; /Minimum/: @0.0@
  210 + | ArrowTail ArrowType -- ^ /Valid for/: E; /Default/: @'normal'@
  211 + | Aspect AspectType -- ^ /Valid for/: G; /Notes/: dot only
  212 + | Bb Rect -- ^ /Valid for/: G; /Notes/: write only
  213 + | BgColor Color -- ^ /Valid for/: GC; /Default/: X11Color 'Transparent'
  214 + | Center Bool -- ^ /Valid for/: G; /Default/: @'False'@; /Parsing Default/: 'True'
  215 + | Charset String -- ^ /Valid for/: G; /Default/: @\"UTF-8\"@
  216 + | ClusterRank ClusterMode -- ^ /Valid for/: G; /Default/: @'Local'@; /Notes/: dot only
  217 + | ColorScheme ColorScheme -- ^ /Valid for/: ENCG; /Default/: @'X11'@
  218 + | Color [Color] -- ^ /Valid for/: ENC; /Default/: @X11Color 'Black'@
  219 + | Comment String -- ^ /Valid for/: ENG; /Default/: @\"\"@
  220 + | Compound Bool -- ^ /Valid for/: G; /Default/: @'False'@; /Parsing Default/: 'True'; /Notes/: dot only
  221 + | Concentrate Bool -- ^ /Valid for/: G; /Default/: @'False'@; /Parsing Default/: 'True'
  222 + | Constraint Bool -- ^ /Valid for/: E; /Default/: @'True'@; /Parsing Default/: 'True'; /Notes/: dot only
  223 + | Decorate Bool -- ^ /Valid for/: E; /Default/: @'False'@; /Parsing Default/: 'True'
  224 + | DefaultDist Double -- ^ /Valid for/: G; /Default/: @1+(avg. len)*sqrt(|V|)@; /Minimum/: @epsilon@; /Notes/: neato only
  225 + | Dimen Int -- ^ /Valid for/: G; /Default/: @2@; /Minimum/: @2@; /Notes/: sfdp, fdp, neato only
  226 + | Dim Int -- ^ /Valid for/: G; /Default/: @2@; /Minimum/: @2@; /Notes/: sfdp, fdp, neato only
  227 + | Dir DirType -- ^ /Valid for/: E; /Default/: @'Forward'@ (directed), @'NoDir'@ (undirected)
  228 + | DirEdgeConstraints DEConstraints -- ^ /Valid for/: G; /Default/: @'NoConstraints'@; /Parsing Default/: 'EdgeConstraints'; /Notes/: neato only
  229 + | Distortion Double -- ^ /Valid for/: N; /Default/: @0.0@; /Minimum/: @-100.0@
  230 + | DPI Double -- ^ /Valid for/: G; /Default/: @96.0@, @0.0@; /Notes/: svg, bitmap output only; \"resolution\" is a synonym
  231 + | EdgeURL URL -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: svg, map only
  232 + | EdgeTarget EscString -- ^ /Valid for/: E; /Default/: none; /Notes/: svg, map only
  233 + | EdgeTooltip EscString -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: svg, cmap only
  234 + | Epsilon Double -- ^ /Valid for/: G; /Default/: @.0001 * # nodes@ (@mode == 'KK'@), @.0001@ (@mode == 'Major'@); /Notes/: neato only
  235 + | ESep DPoint -- ^ /Valid for/: G; /Default/: @+3@; /Notes/: not dot
  236 + | FillColor Color -- ^ /Valid for/: NC; /Default/: @X11Color 'LightGray'@ (nodes), @X11Color 'Black'@ (clusters)
  237 + | FixedSize Bool -- ^ /Valid for/: N; /Default/: @'False'@; /Parsing Default/: 'True'
  238 + | FontColor Color -- ^ /Valid for/: ENGC; /Default/: @X11Color 'Black'@
  239 + | FontName String -- ^ /Valid for/: ENGC; /Default/: @\"Times-Roman\"@
  240 + | FontNames String -- ^ /Valid for/: G; /Default/: @\"\"@; /Notes/: svg only
  241 + | FontPath String -- ^ /Valid for/: G; /Default/: system-dependent
  242 + | FontSize Double -- ^ /Valid for/: ENGC; /Default/: @14.0@; /Minimum/: @1.0@
  243 + | Group String -- ^ /Valid for/: N; /Default/: @\"\"@; /Notes/: dot only
  244 + | HeadURL URL -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: svg, map only
  245 + | HeadClip Bool -- ^ /Valid for/: E; /Default/: @'True'@; /Parsing Default/: 'True'
  246 + | HeadLabel Label -- ^ /Valid for/: E; /Default/: @\"\"@
  247 + | HeadPort PortPos -- ^ /Valid for/: E; /Default/: @'PP' 'CenterPoint'@
  248 + | HeadTarget EscString -- ^ /Valid for/: E; /Default/: none; /Notes/: svg, map only
  249 + | HeadTooltip EscString -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: svg, cmap only
  250 + | Height Double -- ^ /Valid for/: N; /Default/: @0.5@; /Minimum/: @0.02@
  251 + | ID Label -- ^ /Valid for/: GNE; /Default/: @\"\"@; /Notes/: svg, postscript, map only
  252 + | Image String -- ^ /Valid for/: N; /Default/: @\"\"@
  253 + | ImageScale ScaleType -- ^ /Valid for/: N; /Default/: @'NoScale'@; /Parsing Default/: 'UniformScale'
  254 + | LabelURL URL -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: svg, map only
  255 + | LabelAngle Double -- ^ /Valid for/: E; /Default/: @-25.0@; /Minimum/: @-180.0@
  256 + | LabelDistance Double -- ^ /Valid for/: E; /Default/: @1.0@; /Minimum/: @0.0@
  257 + | LabelFloat Bool -- ^ /Valid for/: E; /Default/: @'False'@; /Parsing Default/: 'True'
  258 + | LabelFontColor Color -- ^ /Valid for/: E; /Default/: @X11Color 'Black'@
  259 + | LabelFontName String -- ^ /Valid for/: E; /Default/: @\"Times-Roman\"@
  260 + | LabelFontSize Double -- ^ /Valid for/: E; /Default/: @14.0@; /Minimum/: @1.0@
  261 + | LabelJust Justification -- ^ /Valid for/: GC; /Default/: @'JCenter'@
  262 + | LabelLoc VerticalPlacement -- ^ /Valid for/: GCN; /Default/: @'VTop'@ (clusters), @'VBottom'@ (root graphs), @'VCenter'@ (nodes)
  263 + | LabelTarget EscString -- ^ /Valid for/: E; /Default/: none; /Notes/: svg, map only
  264 + | LabelTooltip EscString -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: svg, cmap only
  265 + | Label Label -- ^ /Valid for/: ENGC; /Default/: @'StrLabel' \"\N\"@ (nodes), @'StrLabel' \"\"@ (otherwise)
  266 + | Landscape Bool -- ^ /Valid for/: G; /Default/: @'False'@; /Parsing Default/: 'True'
  267 + | LayerSep String -- ^ /Valid for/: G; /Default/: @\" :\t\"@
  268 + | Layers LayerList -- ^ /Valid for/: G; /Default/: @\"\"@
  269 + | Layer LayerRange -- ^ /Valid for/: EN; /Default/: @\"\"@
  270 + | Layout String -- ^ /Valid for/: G; /Default/: @\"\"@
  271 + | Len Double -- ^ /Valid for/: E; /Default/: @1.0@ (neato), @0.3@ (fdp); /Notes/: fdp, neato only
  272 + | LevelsGap Double -- ^ /Valid for/: G; /Default/: @0.0@; /Notes/: neato only
  273 + | Levels Int -- ^ /Valid for/: G; /Default/: @MAXINT@; /Minimum/: @0@; /Notes/: sfdp only
  274 + | LHead String -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: dot only
  275 + | LPos Point -- ^ /Valid for/: EGC; /Notes/: write only
  276 + | LTail String -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: dot only
  277 + | Margin DPoint -- ^ /Valid for/: NG; /Default/: device-dependent
  278 + | MaxIter Int -- ^ /Valid for/: G; /Default/: @100 * # nodes@ (@mode == 'KK'@), @200@ (@mode == 'Major'@), @600@ (fdp); /Notes/: fdp, neato only
  279 + | MCLimit Double -- ^ /Valid for/: G; /Default/: @1.0@; /Notes/: dot only
  280 + | MinDist Double -- ^ /Valid for/: G; /Default/: @1.0@; /Minimum/: @0.0@; /Notes/: circo only
  281 + | MinLen Int -- ^ /Valid for/: E; /Default/: @1@; /Minimum/: @0@; /Notes/: dot only
  282 + | Model Model -- ^ /Valid for/: G; /Default/: @'ShortPath'@; /Notes/: neato only
  283 + | Mode ModeType -- ^ /Valid for/: G; /Default/: @'Major'@; /Notes/: neato only
  284 + | Mosek Bool -- ^ /Valid for/: G; /Default/: @'False'@; /Parsing Default/: 'True'; /Notes/: neato only; requires the Mosek software
  285 + | NodeSep Double -- ^ /Valid for/: G; /Default/: @0.25@; /Minimum/: @0.02@; /Notes/: dot only
  286 + | NoJustify Bool -- ^ /Valid for/: GCNE; /Default/: @'False'@; /Parsing Default/: 'True'
  287 + | Normalize Bool -- ^ /Valid for/: G; /Default/: @'False'@; /Parsing Default/: 'True'; /Notes/: not dot
  288 + | Nslimit1 Double -- ^ /Valid for/: G; /Notes/: dot only
  289 + | Nslimit Double -- ^ /Valid for/: G; /Notes/: dot only
  290 + | Ordering String -- ^ /Valid for/: G; /Default/: @\"\"@; /Notes/: dot only
  291 + | Orientation Double -- ^ /Valid for/: N; /Default/: @0.0@; /Minimum/: @360.0@
  292 + | OutputOrder OutputMode -- ^ /Valid for/: G; /Default/: @'BreadthFirst'@
  293 + | OverlapScaling Double -- ^ /Valid for/: G; /Default/: @-4@; /Minimum/: @-1.0e10@; /Notes/: prism only
  294 + | Overlap Overlap -- ^ /Valid for/: G; /Default/: @'KeepOverlaps'@; /Parsing Default/: 'KeepOverlaps'; /Notes/: not dot
  295 + | PackMode PackMode -- ^ /Valid for/: G; /Default/: @'PackNode'@; /Notes/: not dot
  296 + | Pack Pack -- ^ /Valid for/: G; /Default/: @'False'@; /Parsing Default/: 'DoPack'; /Notes/: not dot
  297 + | Pad DPoint -- ^ /Valid for/: G; /Default/: @'DVal' 0.0555@ (4 points)
  298 + | PageDir PageDir -- ^ /Valid for/: G; /Default/: @'BL'@
  299 + | Page Point -- ^ /Valid for/: G
  300 + | PenColor Color -- ^ /Valid for/: C; /Default/: @X11Color 'Black'@
  301 + | PenWidth Double -- ^ /Valid for/: CNE; /Default/: @1.0@; /Minimum/: @0.0@
  302 + | Peripheries Int -- ^ /Valid for/: NC; /Default/: shape default (nodes), @1@ (clusters); /Minimum/: 0
  303 + | Pin Bool -- ^ /Valid for/: N; /Default/: @'False'@; /Parsing Default/: 'True'; /Notes/: fdp, neato only
  304 + | Pos Pos -- ^ /Valid for/: EN
  305 + | QuadTree QuadType -- ^ /Valid for/: G; /Default/: @'NormalQT'@; /Parsing Default/: 'NormalQT'; /Notes/: sfdp only
  306 + | Quantum Double -- ^ /Valid for/: G; /Default/: @0.0@; /Minimum/: @0.0@
  307 + | RankDir RankDir -- ^ /Valid for/: G; /Default/: @'TB'@; /Notes/: dot only
  308 + | RankSep Double -- ^ /Valid for/: G; /Default/: @0.5@ (dot), @1.0@ (twopi); /Minimum/: 0.02; /Notes/: twopi, dot only
  309 + | Rank RankType -- ^ /Valid for/: S; /Notes/: dot only
  310 + | Ratio Ratios -- ^ /Valid for/: G
  311 + | Rects Rect -- ^ /Valid for/: N; /Notes/: write only
  312 + | Regular Bool -- ^ /Valid for/: N; /Default/: @'False'@; /Parsing Default/: 'True'
  313 + | ReMinCross Bool -- ^ /Valid for/: G; /Default/: @'False'@; /Parsing Default/: 'True'; /Notes/: dot only
  314 + | RepulsiveForce Double -- ^ /Valid for/: G; /Default/: @1.0@; /Minimum/: @0.0@; /Notes/: sfdp only
  315 + | Root Root -- ^ /Valid for/: GN; /Default/: @'NodeName' \"\"@ (graphs), @'NotCentral'@ (nodes); /Parsing Default/: 'IsCentral'; /Notes/: circo, twopi only
  316 + | Rotate Int -- ^ /Valid for/: G; /Default/: @0@
  317 + | SameHead String -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: dot only
  318 + | SameTail String -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: dot only
  319 + | SamplePoints Int -- ^ /Valid for/: N; /Default/: @8@ (output), @20@ (overlap and image maps)
  320 + | SearchSize Int -- ^ /Valid for/: G; /Default/: @30@; /Notes/: dot only
  321 + | Sep DPoint -- ^ /Valid for/: G; /Default/: @+4@; /Notes/: not dot
  322 + | ShapeFile String -- ^ /Valid for/: N; /Default/: @\"\"@
  323 + | Shape Shape -- ^ /Valid for/: N; /Default/: @'Ellipse'@
  324 + | ShowBoxes Int -- ^ /Valid for/: ENG; /Default/: @0@; /Minimum/: @0@; /Notes/: dot only
  325 + | Sides Int -- ^ /Valid for/: N; /Default/: @4@; /Minimum/: @0@
  326 + | Size Point -- ^ /Valid for/: G
  327 + | Skew Double -- ^ /Valid for/: N; /Default/: @0.0@; /Minimum/: @-100.0@
  328 + | Smoothing SmoothType -- ^ /Valid for/: G; /Default/: @'NoSmooth'@; /Notes/: sfdp only
  329 + | SortV Int -- ^ /Valid for/: GCN; /Default/: @0@; /Minimum/: @0@
  330 + | Splines EdgeType -- ^ /Valid for/: G; /Parsing Default/: 'SplineEdges'
  331 + | Start StartType -- ^ /Valid for/: G; /Default/: @\"\"@; /Notes/: fdp, neato only
  332 + | StyleSheet String -- ^ /Valid for/: G; /Default/: @\"\"@; /Notes/: svg only
  333 + | Style [StyleItem] -- ^ /Valid for/: ENC
  334 + | TailURL URL -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: svg, map only
  335 + | TailClip Bool -- ^ /Valid for/: E; /Default/: @'True'@; /Parsing Default/: 'True'
  336 + | TailLabel Label -- ^ /Valid for/: E; /Default/: @\"\"@
  337 + | TailPort PortPos -- ^ /Valid for/: E; /Default/: center
  338 + | TailTarget EscString -- ^ /Valid for/: E; /Default/: none; /Notes/: svg, map only
  339 + | TailTooltip EscString -- ^ /Valid for/: E; /Default/: @\"\"@; /Notes/: svg, cmap only
  340 + | Target EscString -- ^ /Valid for/: ENGC; /Default/: none; /Notes/: svg, map only
  341 + | Tooltip EscString -- ^ /Valid for/: NEC; /Default/: @\"\"@; /Notes/: svg, cmap only
  342 + | TrueColor Bool -- ^ /Valid for/: G; /Parsing Default/: 'True'; /Notes/: bitmap output only
  343 + | Vertices [Point] -- ^ /Valid for/: N; /Notes/: write only
  344 + | ViewPort ViewPort -- ^ /Valid for/: G; /Default/: none
  345 + | VoroMargin Double -- ^ /Valid for/: G; /Default/: @0.05@; /Minimum/: @0.0@; /Notes/: not dot
  346 + | Weight Double -- ^ /Valid for/: E; /Default/: @1.0@; /Minimum/: @0@ (dot), @1@ (neato,fdp,sfdp)
  347 + | Width Double -- ^ /Valid for/: N; /Default/: @0.75@; /Minimum/: @0.01@
  348 + | Z Double -- ^ /Valid for/: N; /Default/: @0.0@; /Minimum/: @-MAXFLOAT@, @-1000@
  349 + deriving (Eq, Ord, Show, Read)
  350 +
  351 +type Attributes = [Attribute]
  352 +
  353 +instance PrintDot Attribute where
  354 + unqtDot (Damping v) = printField "Damping" v
  355 + unqtDot (K v) = printField "K" v
  356 + unqtDot (URL v) = printField "URL" v
  357 + unqtDot (ArrowHead v) = printField "arrowhead" v
  358 + unqtDot (ArrowSize v) = printField "arrowsize" v
  359 + unqtDot (ArrowTail v) = printField "arrowtail" v
  360 + unqtDot (Aspect v) = printField "aspect" v
  361 + unqtDot (Bb v) = printField "bb" v
  362 + unqtDot (BgColor v) = printField "bgcolor" v
  363 + unqtDot (Center v) = printField "center" v
  364 + unqtDot (Charset v) = printField "charset" v
  365 + unqtDot (ClusterRank v) = printField "clusterrank" v
  366 + unqtDot (ColorScheme v) = printField "colorscheme" v
  367 + unqtDot (Color v) = printField "color" v
  368 + unqtDot (Comment v) = printField "comment" v
  369 + unqtDot (Compound v) = printField "compound" v
  370 + unqtDot (Concentrate v) = printField "concentrate" v
  371 + unqtDot (Constraint v) = printField "constraint" v
  372 + unqtDot (Decorate v) = printField "decorate" v
  373 + unqtDot (DefaultDist v) = printField "defaultdist" v
  374 + unqtDot (Dimen v) = printField "dimen" v
  375 + unqtDot (Dim v) = printField "dim" v
  376 + unqtDot (Dir v) = printField "dir" v
  377 + unqtDot (DirEdgeConstraints v) = printField "diredgeconstraints" v
  378 + unqtDot (Distortion v) = printField "distortion" v
  379 + unqtDot (DPI v) = printField "dpi" v
  380 + unqtDot (EdgeURL v) = printField "edgeURL" v
  381 + unqtDot (EdgeTarget v) = printField "edgetarget" v
  382 + unqtDot (EdgeTooltip v) = printField "edgetooltip" v
  383 + unqtDot (Epsilon v) = printField "epsilon" v
  384 + unqtDot (ESep v) = printField "esep" v
  385 + unqtDot (FillColor v) = printField "fillcolor" v
  386 + unqtDot (FixedSize v) = printField "fixedsize" v
  387 + unqtDot (FontColor v) = printField "fontcolor" v
  388 + unqtDot (FontName v) = printField "fontname" v
  389 + unqtDot (FontNames v) = printField "fontnames" v
  390 + unqtDot (FontPath v) = printField "fontpath" v
  391 + unqtDot (FontSize v) = printField "fontsize" v
  392 + unqtDot (Group v) = printField "group" v
  393 + unqtDot (HeadURL v) = printField "headURL" v
  394 + unqtDot (HeadClip v) = printField "headclip" v
  395 + unqtDot (HeadLabel v) = printField "headlabel" v
  396 + unqtDot (HeadPort v) = printField "headport" v
  397 + unqtDot (HeadTarget v) = printField "headtarget" v
  398 + unqtDot (HeadTooltip v) = printField "headtooltip" v
  399 + unqtDot (Height v) = printField "height" v
  400 + unqtDot (ID v) = printField "id" v
  401 + unqtDot (Image v) = printField "image" v
  402 + unqtDot (ImageScale v) = printField "imagescale" v
  403 + unqtDot (LabelURL v) = printField "labelURL" v
  404 + unqtDot (LabelAngle v) = printField "labelangle" v
  405 + unqtDot (LabelDistance v) = printField "labeldistance" v
  406 + unqtDot (LabelFloat v) = printField "labelfloat" v
  407 + unqtDot (LabelFontColor v) = printField "labelfontcolor" v
  408 + unqtDot (LabelFontName v) = printField "labelfontname" v
  409 + unqtDot (LabelFontSize v) = printField "labelfontsize" v
  410 + unqtDot (LabelJust v) = printField "labeljust" v
  411 + unqtDot (LabelLoc v) = printField "labelloc" v
  412 + unqtDot (LabelTarget v) = printField "labeltarget" v
  413 + unqtDot (LabelTooltip v) = printField "labeltooltip" v
  414 + unqtDot (Label v) = printField "label" v
  415 + unqtDot (Landscape v) = printField "landscape" v
  416 + unqtDot (LayerSep v) = printField "layersep" v
  417 + unqtDot (Layers v) = printField "layers" v
  418 + unqtDot (Layer v) = printField "layer" v
  419 + unqtDot (Layout v) = printField "layout" v
  420 + unqtDot (Len v) = printField "len" v
  421 + unqtDot (LevelsGap v) = printField "levelsgap" v
  422 + unqtDot (Levels v) = printField "levels" v
  423 + unqtDot (LHead v) = printField "lhead" v
  424 + unqtDot (LPos v) = printField "lp" v
  425 + unqtDot (LTail v) = printField "ltail" v
  426 + unqtDot (Margin v) = printField "margin" v
  427 + unqtDot (MaxIter v) = printField "maxiter" v
  428 + unqtDot (MCLimit v) = printField "mclimit" v
  429 + unqtDot (MinDist v) = printField "mindist" v
  430 + unqtDot (MinLen v) = printField "minlen" v
  431 + unqtDot (Model v) = printField "model" v
  432 + unqtDot (Mode v) = printField "mode" v
  433 + unqtDot (Mosek v) = printField "mosek" v
  434 + unqtDot (NodeSep v) = printField "nodesep" v
  435 + unqtDot (NoJustify v) = printField "nojustify" v
  436 + unqtDot (Normalize v) = printField "normalize" v
  437 + unqtDot (Nslimit1 v) = printField "nslimit1" v
  438 + unqtDot (Nslimit v) = printField "nslimit" v
  439 + unqtDot (Ordering v) = printField "ordering" v
  440 + unqtDot (Orientation v) = printField "orientation" v
  441 + unqtDot (OutputOrder v) = printField "outputorder" v
  442 + unqtDot (OverlapScaling v) = printField "overlap_scaling" v
  443 + unqtDot (Overlap v) = printField "overlap" v
  444 + unqtDot (PackMode v) = printField "packmode" v
  445 + unqtDot (Pack v) = printField "pack" v
  446 + unqtDot (Pad v) = printField "pad" v
  447 + unqtDot (PageDir v) = printField "pagedir" v
  448 + unqtDot (Page v) = printField "page" v
  449 + unqtDot (PenColor v) = printField "pencolor" v
  450 + unqtDot (PenWidth v) = printField "penwidth" v
  451 + unqtDot (Peripheries v) = printField "peripheries" v
  452 + unqtDot (Pin v) = printField "pin" v
  453 + unqtDot (Pos v) = printField "pos" v
  454 + unqtDot (QuadTree v) = printField "quadtree" v
  455 + unqtDot (Quantum v) = printField "quantum" v
  456 + unqtDot (RankDir v) = printField "rankdir" v
  457 + unqtDot (RankSep v) = printField "ranksep" v
  458 + unqtDot (Rank v) = printField "rank" v
  459 + unqtDot (Ratio v) = printField "ratio" v
  460 + unqtDot (Rects v) = printField "rects" v
  461 + unqtDot (Regular v) = printField "regular" v
  462 + unqtDot (ReMinCross v) = printField "remincross" v
  463 + unqtDot (RepulsiveForce v) = printField "repulsiveforce" v
  464 + unqtDot (Root v) = printField "root" v
  465 + unqtDot (Rotate v) = printField "rotate" v
  466 + unqtDot (SameHead v) = printField "samehead" v
  467 + unqtDot (SameTail v) = printField "sametail" v
  468 + unqtDot (SamplePoints v) = printField "samplepoints" v
  469 + unqtDot (SearchSize v) = printField "searchsize" v
  470 + unqtDot (Sep v) = printField "sep" v
  471 + unqtDot (ShapeFile v) = printField "shapefile" v
  472 + unqtDot (Shape v) = printField "shape" v
  473 + unqtDot (ShowBoxes v) = printField "showboxes" v
  474 + unqtDot (Sides v) = printField "sides" v
  475 + unqtDot (Size v) = printField "size" v
  476 + unqtDot (Skew v) = printField "skew" v
  477 + unqtDot (Smoothing v) = printField "smoothing" v
  478 + unqtDot (SortV v) = printField "sortv" v
  479 + unqtDot (Splines v) = printField "splines" v
  480 + unqtDot (Start v) = printField "start" v
  481 + unqtDot (StyleSheet v) = printField "stylesheet" v
  482 + unqtDot (Style v) = printField "style" v
  483 + unqtDot (TailURL v) = printField "tailURL" v
  484 + unqtDot (TailClip v) = printField "tailclip" v
  485 + unqtDot (TailLabel v) = printField "taillabel" v
  486 + unqtDot (TailPort v) = printField "tailport" v
  487 + unqtDot (TailTarget v) = printField "tailtarget" v
  488 + unqtDot (TailTooltip v) = printField "tailtooltip" v
  489 + unqtDot (Target v) = printField "target" v
  490 + unqtDot (Tooltip v) = printField "tooltip" v
  491 + unqtDot (TrueColor v) = printField "truecolor" v
  492 + unqtDot (Vertices v) = printField "vertices" v
  493 + unqtDot (ViewPort v) = printField "viewport" v
  494 + unqtDot (VoroMargin v) = printField "voro_margin" v
  495 + unqtDot (Weight v) = printField "weight" v
  496 + unqtDot (Width v) = printField "width" v
  497 + unqtDot (Z v) = printField "z" v
  498 +
  499 + listToDot = unqtListToDot
  500 +
  501 +instance ParseDot Attribute where
  502 + parseUnqt = oneOf [ liftM Damping $ parseField "Damping"
  503 + , liftM K $ parseField "K"
  504 + , liftM URL $ parseFields ["URL", "href"]
  505 + , liftM ArrowHead $ parseField "arrowhead"
  506 + , liftM ArrowSize $ parseField "arrowsize"
  507 + , liftM ArrowTail $ parseField "arrowtail"
  508 + , liftM Aspect $ parseField "aspect"
  509 + , liftM Bb $ parseField "bb"
  510 + , liftM BgColor $ parseField "bgcolor"
  511 + , liftM Center $ parseFieldBool "center"
  512 + , liftM Charset $ parseField "charset"
  513 + , liftM ClusterRank $ parseField "clusterrank"
  514 + , liftM ColorScheme $ parseField "colorscheme"
  515 + , liftM Color $ parseField "color"
  516 + , liftM Comment $ parseField "comment"
  517 + , liftM Compound $ parseFieldBool "compound"
  518 + , liftM Concentrate $ parseFieldBool "concentrate"
  519 + , liftM Constraint $ parseFieldBool "constraint"
  520 + , liftM Decorate $ parseFieldBool "decorate"
  521 + , liftM DefaultDist $ parseField "defaultdist"
  522 + , liftM Dimen $ parseField "dimen"
  523 + , liftM Dim $ parseField "dim"
  524 + , liftM Dir $ parseField "dir"
  525 + , liftM DirEdgeConstraints $ parseFieldDef EdgeConstraints "diredgeconstraints"
  526 + , liftM Distortion $ parseField "distortion"
  527 + , liftM DPI $ parseFields ["dpi", "resolution"]
  528 + , liftM EdgeURL $ parseFields ["edgeURL", "edgehref"]