GenericPretty 1.0.1 → 1.1.0
raw patch · 5 files changed
+346/−181 lines, 5 filesdep ~ghc
Dependency ranges changed: ghc
Files
- GenericPretty.cabal +91/−18
- README +81/−17
- TestSuite/CustomTest.hs +1/−1
- Text/PrettyPrint/GenericPretty.hs +128/−145
- Text/PrettyPrint/MyPretty.hs +45/−0
GenericPretty.cabal view
@@ -7,34 +7,107 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented. -Version: 1.0.1 +Version: 1.1.0 -- A short (one-line) description of the package. Synopsis: A generic, derivable, haskell pretty printer. -- A longer description of the package. -Description: GenericPretty is a haskell library that provides support for automatic +Description: + *GenericPretty is a haskell library that provides support for automatic derivation of pretty printing functions on user defined data types. - The Pretty library <http://www.haskell.org/ghc/docs/7.0.4/html/libraries/ghc-7.0.4/Pretty.html> + . + *The Pretty library <http://www.haskell.org/ghc/docs/7.0.4/html/libraries/ghc-7.0.4/Pretty.html> is used underneath, the work is done over 'Pretty.Doc' types. - . - The output provided by the library functions is identical to that of Prelude.show, + The library "MyPretty" is also provided. This library is a thin wrapper around the "Pretty" + library and implements only 'Style' related features. These features are planned to be added + to the Pretty library itself. + When that happens "MyPretty" will become obsolete and will be replaced by "Pretty". + . + *The output provided by the library functions is identical to that of Prelude.show, except it has extra whitespace. . - This requires the use of the new GHC.Generics features: <http://www.haskell.org/haskellwiki/Generics>. - As of 9.08.2011, these aren't present in the stable GHC releases, but - seem to be present in the GHC HEAD development snapshots >= 7.1.20110601. + *This package requires the use of the new GHC.Generics features: <http://www.haskell.org/haskellwiki/Generics>. + These features are present in versions of GHC >= 7.2. . - The Generics used are based on those described in the paper "A Generic Deriving Mechanism for Haskell" : - <http://dreixel.net/research/pdf/gdmh.pdf> . The changes from the original paper on the ghc implementation - are described here: <http://www.haskell.org/haskellwiki/Generics#Changes_from_the_paper>. + *The Generics used are based on those described in the paper "A Generic Deriving Mechanism for Haskell" - + by Magalhaes, Dijkstra, Jeuring and Loh in Proceedings of the third ACM Haskell symposium on Haskell + (Haskell'2010), pp. 37-48, ACM, 2010: <http://dreixel.net/research/pdf/gdmh.pdf> + There are several changes from the original paper in the ghc implementation which are described here: + <http://www.haskell.org/haskellwiki/Generics#Changes_from_the_paper>. . - For more info and examples of usage please see the README file included in the package - and the API at <http://haggismcmutton.github.com/GenericPretty/> + *This generics mechanism supports deriving for all haskell datatypes EXCEPT for + constrained datatypes. + That is to say, datatypes which have a context will fail. . - Installation of the package is straightforward, if needed, instructions can be found, - for instance, here: <http://www.haskell.org/haskellwiki/Cabal/How_to_install_a_Cabal_package>. - + For instance, + . + "data (Eq a) => Constr a = Constr a" + . + will fail because of the (Eq a) context. + . + *Instalation instructions + . + The package is installed in the same way as any other package. If needed, instructions are provided below. + . + 0. Make sure you have a version of ghc >= 7.2 installed and that you can use the 'runhaskell' command from the command line. + . + 1. Download the file "GenericPretty-1.1.0.tar.gz" from this page. + . + 2. Unpack the file. If using a UNIX system, run + . + tar xzf GenericPretty-1.1.0.tar.gz + . + If on windows use your preffered unpacking utility(for instance, 7zip : <http://www.7-zip.org/>) + . + 3. Move to the correct directory: + . + cd GenericPretty-1.0.1 + . + 4. Run the following haskell commands to install the library globally + . + runhaskell Setup configure + . + runhaskell Setup build + . + runhaskell Setup install + . + If something went wrong, you can check this page for more info, look at manual installation: + <http://www.haskell.org/haskellwiki/Cabal/How_to_install_a_Cabal_package> + . + *Basic example of usage + . + Here is a source file demonstrating the GenericPretty usage + . + import Text.PrettyPrint.GenericPretty + . + data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Generic) + . + instance (Out a) => Out (Tree a) where + docPrec = genOut + . + tree :: Tree Int + . + tree = Node (Node (Leaf 333333333) (Leaf (-555555555))) (Leaf 777777777) + . + main = pp tree + . + * For the above program to run the -XDeriveGeneric flag needs to be set. + . + This can be done either directly at the command line, by compiling with "ghc -XDeriveGeneric" or in + the source code by using the LANGUAGE pragma (it seems I can't demonstrate the LANGUAGE pragma since + cabal hates special characters. An example however is provided in the README file included in the package). + Alternatively, for more information on the LANGUAGE pragma see here: + <http://www.haskell.org/ghc/docs/7.0.4/html/users_guide/pragmas.html> + . + Besides setting the flag, one must derive "Generic" for the desired datatype + by typing "deriving (Generic)" and write an instance of "Out" defining docPrec as "docPrec = genOut". + Then the pretty printing functions such as "pp" can be used on any data of that type. + . + For more details about the above example as well as an example of custom pretty printing please + check the README file included in the package. For more information about the library itself and + what it exports check the API linked further down this page. + -- URL for the project homepage or repository. Homepage: https://github.com/HaggisMcMutton/GenericPretty @@ -68,10 +141,10 @@ Library -- Modules exported by the library. - Exposed-modules: Text.PrettyPrint.GenericPretty + Exposed-modules: Text.PrettyPrint.GenericPretty Text.PrettyPrint.MyPretty -- Packages needed in order to build this package. - Build-depends: base >= 3 && < 5, ghc-prim, ghc >= 7.1.20110601 + Build-depends: base >= 3 && < 5, ghc-prim, ghc >= 7.2 -- Modules not exported by this package. -- Other-modules:
README view
@@ -1,25 +1,41 @@-GenericPretty. A Generic, Derivable, Haskell Pretty Printer -=============================================================================== +******************************************************************************* +* GenericPretty. +* A Generic, Derivable, Haskell Pretty Printer +******************************************************************************* +========================== Description ======================================== + GenericPretty is a haskell library that provides support for automatic derivation of pretty printing functions on user defined data types. The Pretty library [1] is used underneath, the work is done over "Doc" types. +The library "MyPretty" is also provided. This library is a thin wrapper around +the "Pretty" library and implements only "Style" related features. +These features are planned to be added to the Pretty library itself. When +that happens "MyPretty" will become obsolete and will be replaced by "Pretty". + The output provided by the library functions is identical to that of Prelude.show, except it has extra whitespace. This library requires the use of the new GHC.Generics features [2] -As of 9.08.2011, these aren't present in the stable GHC releases, but -seem to be present in the GHC HEAD development snapshots >= 7.1.20110601. +These features are present in versions of GHC >= 7.2. -The Generics used are based on those described in the paper -"A Generic Deriving Mechanism for Haskell" [3]. -There are however several changes between the mechanism described in the -paper and the one implemented in GHC [4]. +The Generics used are based on those described in the paper "A Generic Deriving +Mechanism for Haskell" - by Magalhães, Dijkstra, Jeuring and Löh in Proceedings +of the third ACM Haskell symposium on Haskell (Haskell'2010), pp. 3748, ACM, +2010 [3]. +There are however several changes between the mechanism described in +the paper and the one implemented in GHC [4]. -I find examples are the best aid in understanding. So, here is a -haskell source file, called 'SimpleTest.hs' +This generics mechanism supports deriving for all haskell datatypes EXCEPT for +constrained datatypes. +That is to say, datatypes which have a context will fail. For instance, +"data (Eq a) => Constr a = Constr a" will fail because of the (Eq a) context. + +============================== Basic Example ================================== + +Here is a haskell source file, called 'SimpleTest.hs' ---------------------------------------------------- {-# LANGUAGE DeriveGeneric #-} @@ -66,13 +82,55 @@ In this case the output tries to remain under 30 characters/line, if possible, while always maintaining correct indentation. +There also is a 'ppStyle' function which lets you further customize the output +by giving a 'Style' which consists of the line length, the number of ribbons +per line and the mode to us. + +A ribbon length is the length of non-indentation text per line. +So if I used a line length of 80 and 2 ribbons per line than I would have a +maximum of 40 non-indentation characters on any line. + +The mode tells 'Pretty' how to render the result. There are 4 options: +1. PageMode - the default rendering +2. ZigZagMode - zig-zag cuts +3. LeftMode - there is no indentation and no maximum line length +4. OneLineMode - everything is put on one line + +The most interesting one is the ZigZagMode. Using the running example and adding: + +-------------------------------------- +zigStyle :: Style +zigStyle = Style {mode = ZigZagMode, lineLength = 30, ribbonsPerLine = 1.5} + +main = ppStyle zigStyle tree1 +-------------------------------------- + +We get the result: + +Node (Node (Leaf 333333) + +///// + (Leaf (-555555))) +(Node (Node (Node (Leaf 888888) + +///// + (Leaf 57575757)) + (Leaf (-14141414))) + (Leaf 7777777)) + +Notice that the "/" show us the direction in which the rows below have been moved +(left in this case) and the number of "/"s indicate the number of characters +that the rows were moved(in this case 5 characters to the left) + +========================== Customization Example ============================== + Customizing the pretty printed results is also straightforward, as in the following example called 'CustomTest.hs' ---------------------------- {-# LANGUAGE DeriveGeneric #-} import Text.PrettyPrint.GenericPretty -import Pretty +import Text.PrettyPrint.MyPretty data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Generic) @@ -87,7 +145,8 @@ main = pp tree1 ------------------------------ -Here we import the library 'Pretty' and use it directly to define docPrec. +Here we import the library 'MyPretty' and use it directly to define docPrec. +The syntax is the one used in both the Pretty[1] and the HughesPJ [5] libraries By running the above we get a tree with a minimum of indentation: (customNode @@ -103,20 +162,25 @@ (customLeaf 7777777))) ----------------------------------- + +========================= Further Info ======================================== + The above 'Tree' examples can be found in 'TestSuite/SimpleTest.hs' and 'TestSuite/CustomTest.hs'. More involved examples integrated with QuickCheck can be found in 'TestSuite/Tests.hs'. -Further information can be found in the API at -http://haggismcmutton.github.com/GenericPretty/ and in the source code itself. -=============================================================================== +Further information can be found in the API [6] and in the source code itself. +============================ Contact ========================================== + Please send any questions/suggestions to: Razvan Ranca <ranca.razvan@gmail.com> -=============================================================================== +============================= Links =========================================== [1] http://www.haskell.org/ghc/docs/7.0.4/html/libraries/ghc-7.0.4/Pretty.html [2] http://www.haskell.org/haskellwiki/Generics [3] http://dreixel.net/research/pdf/gdmh.pdf -[4] http://www.haskell.org/haskellwiki/Generics#Changes_from_the_paper+[4] http://www.haskell.org/haskellwiki/Generics#Changes_from_the_paper +[5] http://hackage.haskell.org/packages/archive/pretty/1.1.0.0/doc/html/Text-PrettyPrint-HughesPJ.html +[6] http://hackage.haskell.org/packages/archive/GenericPretty/1.0.1/doc/html/Text-PrettyPrint-GenericPretty.html
TestSuite/CustomTest.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE DeriveGeneric #-} import Text.PrettyPrint.GenericPretty -import Pretty +import Text.PrettyPrint.MyPretty data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Generic)
Text/PrettyPrint/GenericPretty.hs view
@@ -2,127 +2,135 @@ {-| GenericPretty is a haskell library that provides support for automatic - derivation of pretty printing functions on user defined data types. The "Pretty" library + derivation of pretty printing functions on user defined data types. The 'Pretty' library is used underneath, the work is done over 'Pretty.Doc' types. + + The library "MyPretty" is also provided. This library is a thin wrapper around the "Pretty" + library and implements only 'MyPretty.Style' related features. These features are planned to be added + to the Pretty library itself. + When that happens "MyPretty" will become obsolete and will be replaced by "Pretty". The output provided by the library functions is identical to that of 'Prelude.show', except it has extra whitespace. This requires the use of the new GHC.Generics features: <http://www.haskell.org/haskellwiki/Generics>. - As of 9.08.2011, these aren't present in the stable GHC releases, but - seem to be present in the GHC HEAD development snapshots >= 7.1.20110601. + These features are present in versions of GHC >= 7.2. - The Generics used are based on those described in the paper /"A Generic Deriving Mechanism for Haskell"/ : - <http://dreixel.net/research/pdf/gdmh.pdf> . - There are however several changes between the mechanism described in the paper and the one implemented - in GHC which are described here: <http://www.haskell.org/haskellwiki/Generics#Changes_from_the_paper>. + The Generics used are based on those described in the paper "A Generic Deriving Mechanism for Haskell" - + by Magalhães, Dijkstra, Jeuring and Löh in Proceedings of the third ACM Haskell symposium on Haskell + (Haskell'2010), pp. 3748, ACM, 2010: <http://dreixel.net/research/pdf/gdmh.pdf> . + + There are however several changes between the mechanism + described in the paper and the one implemented in GHC which are described here: + <http://www.haskell.org/haskellwiki/Generics#Changes_from_the_paper>. - For more info and examples of usage please see the README file included in the package -} + This generics mechanism supports deriving for all haskell datatypes EXCEPT for + constrained datatypes. + That is to say, datatypes which have a context will fail. For instance, + "data (Eq a) => Constr a = Constr a" will fail because of the (Eq a) context. -module Text.PrettyPrint.GenericPretty - (pp, ppLen, ppStyle, pretty, prettyLen, prettyStyle, fullPP, - genOut, outputIO, outputStr, wrapParens, defStyle, - Out(..), Style(..), Generic) where + For examples of usage please see the README file included in the package -} +module Text.PrettyPrint.GenericPretty(pp, ppLen, ppStyle, pretty, prettyLen, prettyStyle, fullPP, + genOut, wrapParens, outputIO, outputStr, + Out(..), Generic) where + import Data.List import GHC.Generics -import Pretty import Data.Char import FastString +import Text.PrettyPrint.MyPretty -- | The class 'Out' is the equivalent of 'Prelude.Show' --- --- Conversion of values to pretty printable 'Pretty.Doc's. --- --- Minimal complete definition: 'docPrec' or 'doc'. --- --- Derived instances of 'Out' have the following properties --- --- * The result of 'show' is a syntactically correct Haskell --- expression containing only constants, given the fixity --- declarations in force at the point where the type is declared. --- It contains only the constructor names defined in the data type, --- parentheses, and spaces. When labelled constructor fields are --- used, braces, commas, field names, and equal signs are also used. --- --- * If the constructor is defined to be an infix operator, then --- 'docPrec' will produce infix applications of the constructor. --- --- * the representation will be enclosed in parentheses if the --- precedence of the top-level constructor in @x@ is less than @d@ --- (associativity is ignored). Thus, if @d@ is @0@ then the result --- is never surrounded in parentheses; if @d@ is @11@ it is always --- surrounded in parentheses, unless it is an atomic expression. --- --- * If the constructor is defined using record syntax, then 'doc' --- will produce the record-syntax form, with the fields given in the --- same order as the original declaration. --- --- For example, given the declarations --- --- --- > data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Generic) --- --- The derived instance of 'Out' is equivalent to: --- --- > instance (Out a) => Out (Tree a) where --- > --- > docPrec d (Leaf m) = Pretty.sep $ wrapParens (d > appPrec) $ --- > text "Leaf" : [nest (constrLen + parenLen) (docPrec (appPrec+1) m)] --- > where appPrec = 10 --- > constrLen = 5; --- > parenLen = if(d > appPrec) then 1 else 0 --- > --- > docPrec d (Node u v) = Pretty.sep $ wrapParens (d > appPrec) $ --- > text "Node" : --- > nest (constrLen + parenLen) (docPrec (appPrec+1) u) : --- > [nest (constrLen + parenLen) (docPrec (appPrec+1) v)] --- > where appPrec = 10 --- > constrLen = 5 --- > parenLen = if(d > appPrec) then 1 else 0 + + -- Conversion of values to pretty printable 'Pretty.Doc's. + -- + -- Minimal complete definition: 'docPrec' or 'doc'. + -- + -- Derived instances of 'Out' have the following properties + -- + -- * The result of 'show' is a syntactically correct Haskell + -- expression containing only constants, given the fixity + -- declarations in force at the point where the type is declared. + -- It contains only the constructor names defined in the data type, + -- parentheses, and spaces. When labelled constructor fields are + -- used, braces, commas, field names, and equal signs are also used. + -- + -- * If the constructor is defined to be an infix operator, then + -- 'docPrec' will produce infix applications of the constructor. + -- + -- * the representation will be enclosed in parentheses if the + -- precedence of the top-level constructor in @x@ is less than @d@ + -- (associativity is ignored). Thus, if @d@ is @0@ then the result + -- is never surrounded in parentheses; if @d@ is @11@ it is always + -- surrounded in parentheses, unless it is an atomic expression. + -- + -- * If the constructor is defined using record syntax, then 'doc' + -- will produce the record-syntax form, with the fields given in the + -- same order as the original declaration. + -- + -- For example, given the declarations + -- + -- + -- > data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Generic) + -- + -- The derived instance of 'Out' is equivalent to: + -- + -- > instance (Out a) => Out (Tree a) where + -- > + -- > docPrec d (Leaf m) = Pretty.sep $ wrapParens (d > appPrec) $ + -- > text "Leaf" : [nest (constrLen + parenLen) (docPrec (appPrec+1) m)] + -- > where appPrec = 10 + -- > constrLen = 5; + -- > parenLen = if(d > appPrec) then 1 else 0 + -- > + -- > docPrec d (Node u v) = Pretty.sep $ wrapParens (d > appPrec) $ + -- > text "Node" : + -- > nest (constrLen + parenLen) (docPrec (appPrec+1) u) : + -- > [nest (constrLen + parenLen) (docPrec (appPrec+1) v)] + -- > where appPrec = 10 + -- > constrLen = 5 + -- > parenLen = if(d > appPrec) then 1 else 0 + class Out a where - -- | 'docPrec' is the equivalent of 'Prelude.showsPrec' - -- Convert a value to a pretty printable 'Pretty.Doc'. - docPrec :: Int -- ^ the operator precedence of the enclosing - -- context (a number from @0@ to @11@). - -- Function application has precedence @10@. - -> a -- ^ the value to be converted to a 'String' - -> Doc -- ^ the resulting 'Doc' - + -- | 'docPrec' is the equivalent of 'Prelude.showsPrec' + -- Convert a value to a pretty printable 'Pretty.Doc'. + docPrec :: Int -- ^ the operator precedence of the enclosing + -- context (a number from @0@ to @11@). + -- Function application has precedence @10@. + -> a -- ^ the value to be converted to a 'String' + -> Doc -- ^ the resulting 'Doc' -- | 'doc' is the equivalent of 'Prelude.show' - -- - -- A specialised variant of 'docPrec', using precedence context zero. + -- A specialised variant of 'docPrec', using precedence context zero. doc :: a -> Doc -- | 'docList' is the equivalent of 'Prelude.showList' - -- - -- The method 'docList' is provided to allow the programmer to - -- give a specialised way of showing lists of values. - -- For example, this is used by the predefined 'Out' instance of - -- the 'Char' type, where values of type 'String' should be shown - -- in double quotes, rather than between square brackets. + -- The method 'docList' is provided to allow the programmer to + -- give a specialised way of showing lists of values. + -- For example, this is used by the predefined 'Out' instance of + -- the 'Char' type, where values of type 'String' should be shown + -- in double quotes, rather than between square brackets. docList :: [a] -> Doc doc = docPrec 0 docPrec _ = doc docList = docListWith doc --- | The default generic out method, converts the type into a sum of products and passes it on to the generic --- pretty printing functions, finally it concatenates all of the SDoc's --- --- It needs to be used in code to define the instance for 'Out' --- --- For instance, given the declaration: --- --- > data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Generic) --- --- The user would need to write an instance declaration like: --- --- > instance (Out a) => Out (Tree a) where --- > docPrec = genOut --- --- After doing this, the user can now use pretty printing function like 'pp' and 'pretty' --- on data of type Tree +-- | default generic out method, converts the type into a sum of products and passes it on to the generic + -- pretty printing functions, finally it concatenates all of the SDoc's + -- needs to be used in code to define the instance for 'Out' + -- + -- For instance, given the declaration: + -- + -- > data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Generic) + -- + -- The user would need to write an instance declaration like: + -- + -- > instance (Out a) => Out (Tree a) where + -- > docPrec = genOut + -- + -- After doing this, the user can now pretty printing function like 'pp' and 'pretty' + -- on data of type Tree genOut :: (Generic a ,GOut (Rep a)) => Int -> a -> Doc genOut n x = sep $ out1 (from x) Pref n False @@ -138,8 +146,8 @@ middle (x:xs) = init xs -- |Utility function used to wrap the passed value in parens if the bool is true --- A single paren should never occupy a whole line, so they are concatenated --- to the first and last elements in the list, instead of just adding them to the list + -- A single paren should never occupy a whole line, so they are concatenated + -- to the first and last elements in the list, instead of just adding them to the list wrapParens :: Bool -> [Doc] -> [Doc] wrapParens _ [] = [] wrapParens False s = s @@ -270,23 +278,22 @@ isNullary _ = False -- | 'fullPP' is a fully customizable Pretty Printer --- Every other pretty printer just gives some default values to 'fullPP' -fullPP :: (Out a) => a -- ^The value to pretty print - -> Mode -- ^The "Pretty" mode to use /(eg: 'Pretty.PageMode')/ + -- Every other pretty printer just gives some default values to 'fullPP' +fullPP :: (Out a) => Mode -- ^The 'Pretty' mode to use /(eg: 'Pretty.PageMode')/ -> Int -- ^The maximum line length - -> Float -- ^The number of ribbons per line /(the fraction of line length over the/ - -- /max length of non-indentation text per line; eg: lineLength = 80 and/ - -- /ribbonsPerLine = 1.5 => max of 53 non-indentation characters per line)/ + -> Float -- ^The number of ribbons per line /(the fraction of line length over the + -- max length of non-indentation text per line; eg: lineLength = 80 and + -- ribbonsPerLine = 1.5 => max of 53 non-indentation characters per line)/ -> (TextDetails -> b -> b) -- ^Function that handles the text conversion /(eg: 'outputIO')/ -> b -- ^The end element of the result /( eg: "" or putChar('\n') )/ + -> a -- ^The value to pretty print -> b -- ^The pretty printed result -fullPP a mode len rib td end = fullRender mode len rib td end doc +fullPP mode len rib td end a = fullRender mode len rib td end doc where doc = docPrec 0 a - + -- | 'outputIO' transforms the text into strings and outputs it directly. --- -- This is one example of a function that can handle the text conversion for 'fullPP'. outputIO :: TextDetails -> IO() -> IO() outputIO td act = do @@ -299,9 +306,8 @@ decode (Chr c) = [c] decode (Str s) = s --- | 'outputStr' just leaves the text as a string. --- This is usefull if you want to further process the pretty printed result. --- +-- | 'outputStr' just leaves the text as a string, +--usefull is you want to further process the pretty printed result. -- This is another example of a function that can handle the text conversion for 'fullPP'. outputStr :: TextDetails -> String -> String outputStr td str = decode td ++ str @@ -312,58 +318,35 @@ decode (Chr c) = [c] decode (Str s) = s --- | Customizable pretty printer, takes a user defined 'Style' as a parameter and --- uses 'outputStr' to obtain the result +-- | Customizable pretty printer, takes a user defined 'Style' as a parameter + -- uses 'outputStr' to obtain the result prettyStyle :: (Out a) => Style -> a -> String -prettyStyle s a = fullPP a (mode s) (lineLength s) (ribbonsPerLine s) outputStr "" +prettyStyle s = fullPP (mode s) (lineLength s) (ribbonsPerLine s) outputStr "" -- | Semi-customizable pretty printer. Takes the lineLength as a parameter --- uses mode = 'Pretty.PageMode' and ribbonsPerLine = 1 + -- uses mode = 'Pretty.PageMode' and ribbonsPerLine = 1 prettyLen :: (Out a) => Int -> a -> String -prettyLen l a = fullPP a PageMode l 1 outputStr "" +prettyLen l = fullPP PageMode l 1 outputStr "" -- | The default pretty printer returning 'String's --- --- It uses the default style, 'defStyle' + -- uses the default 'MyPretty.Style', 'style' pretty :: (Out a) => a -> String -pretty = prettyStyle defStyle +pretty = prettyStyle style --- | Customizable pretty printer, takes a user defined 'Style' as a parameter and --- uses 'outputIO' to obtain the result +-- | Customizable pretty printer, takes a user defined 'MyPretty.Style' as a parameter + -- uses 'outputIO' to obtain the result ppStyle :: (Out a) => Style -> a -> IO() -ppStyle s a = fullPP a (mode s) (lineLength s) (ribbonsPerLine s) outputIO (putChar '\n') +ppStyle s = fullPP (mode s) (lineLength s) (ribbonsPerLine s) outputIO (putChar '\n') -- | Semi-customizable pretty printer. Takes the lineLength as a parameter --- uses mode = 'Pretty.PageMode' and ribbonsPerLine = 1 + -- uses mode = 'Pretty.PageMode' and ribbonsPerLine = 1 ppLen :: (Out a) => Int -> a -> IO() -ppLen l a = fullPP a PageMode l 1 outputIO (putChar '\n') +ppLen l = fullPP PageMode l 1 outputIO (putChar '\n') -- | The default Pretty Printer, --- --- It uses the default style, 'defStyle' + -- uses the default 'MyPretty.Style', 'style' pp :: (Out a) => a -> IO() -pp = ppStyle defStyle - --- | The default 'Style' used for 'pp' and 'pretty' --- (mode=PageMode, lineLength=100, ribbonsPerLine=1.5) -defStyle :: Style -defStyle = Style {mode = PageMode, lineLength = 80, ribbonsPerLine = 1} - --- | A rendering style -data Style - = Style { mode :: Mode -- ^ The rendering mode - , lineLength :: Int -- ^ Length of line, in chars - , ribbonsPerLine :: Float -- ^ Ratio of ribbon length to line length - } - -{- -prettyLenRib :: (Out a) => Int -> Float -> a -> String -prettyLenRib l r a = fullPP a PageMode l r outputStr "" - -ppLenRib :: (Out a) => Int -> Float -> a -> IO() -ppLenRib l r a = fullPP a PageMode l r outputIO (putChar '\n') - --} +pp = ppStyle style -- define some instances of Out making sure to generate output identical to 'show' modulo the extra whitespace instance Out Char where
+ Text/PrettyPrint/MyPretty.hs view
@@ -0,0 +1,45 @@+{-# MyPretty is a library that can be used in conjuncture with "Text.PrettyPrint.GenericPretty". + + This library is a thin wrapper around the "Pretty" library and implements only 'Style' related + features. + These features are planned to be added to the Pretty library itself. + When that happens "MyPretty" will become obsolete and will be replaced by "Pretty". + + This library can be imported if the user wants to make custom pretty printing definitions for + his types. The syntax used is that of "Pretty" and "Text.PrettyPrint.HughesPJ". + + For an example of a custom definition for a data type see the README file included in the package. +#-} +module Text.PrettyPrint.MyPretty( + module Pretty, + Style(..), renderStyle, style + )where + +import Pretty +import FastString + +-- | A rendering style +data Style + = Style { mode :: Mode -- ^ The rendering mode + , lineLength :: Int -- ^ Length of line, in chars + , ribbonsPerLine :: Float -- ^ Ratio of ribbon length to line length + } + +-- | Render a document using a particular style +-- internally calls 'Pretty.fullRender' +renderStyle :: Style -> Doc -> String +renderStyle s = fullRender (mode s) (lineLength s) (ribbonsPerLine s) outputStr "" + where + outputStr :: TextDetails -> String -> String + outputStr td str = decode td ++ str + where + decode :: TextDetails -> String + decode (PStr s1) = unpackFS s1 + decode (LStr s1 _) = unpackLitString s1 + decode (Chr c) = [c] + decode (Str s) = s + +-- | The default 'Style' used for "Text.PrettyPrint.GenericPretty" +-- (mode=PageMode, lineLength=80, ribbonsPerLine=1.5) +style :: Style +style = Style {mode = PageMode, lineLength = 80, ribbonsPerLine = 1.5}