Commit 7f198c38 authored by Michael Hanus 's avatar Michael Hanus
Browse files

CPM updated

parent 5a640009
......@@ -24,7 +24,8 @@ import FilePath ((</>))
import Function (both)
import List (nub)
import Maybe (listToMaybe, catMaybes)
import Pretty (pPrint, text, (<+>), vcat, empty, red, ($$))
import Text.Pretty (pPrint, text, (<+>), vcat, empty, red, ($$))
import CPM.AbstractCurry (readAbstractCurryFromPackagePath)
import CPM.Config (Config)
......
......@@ -33,7 +33,6 @@ import Function (both)
import List ( intercalate, intersect, nub, splitOn, isPrefixOf, isInfixOf
, find, delete, (\\), nubBy )
import Maybe ( isJust, fromJust, fromMaybe, listToMaybe )
import Pretty ( pPrint, text, indent, vcat, (<+>), (<$$>) )
import System ( getEnviron, setEnviron, unsetEnviron )
import Analysis.Types ( Analysis )
......@@ -42,6 +41,7 @@ import Analysis.ProgInfo ( ProgInfo, emptyProgInfo, combineProgInfo
import Analysis.Termination ( productivityAnalysis, Productivity(..) )
import Analysis.TypeUsage ( typesInValuesAnalysis )
import CASS.Server ( analyzeGeneric )
import Text.Pretty ( pPrint, text, indent, vcat, (<+>), (<$$>) )
import CPM.AbstractCurry ( readAbstractCurryFromDeps, loadPathForPackage
, tcArgsOfType )
......
......@@ -22,10 +22,11 @@ module CPM.ErrorLogger
) where
import Global
import Pretty
import Profile -- for show run-time
import System (exitWith, system)
import Text.Pretty
infixl 0 |>=, |>, |>>, |->
--- An error logger.
......
......@@ -17,16 +17,17 @@ module CPM.PackageCopy
) where
import Debug
import Directory (doesFileExist, getAbsolutePath, createDirectoryIfMissing
import Directory ( doesFileExist, getAbsolutePath, createDirectoryIfMissing
, doesDirectoryExist, getTemporaryDirectory
, getCurrentDirectory, setCurrentDirectory, createDirectory
, removeDirectory, getDirectoryContents, copyFile)
import FilePath ((</>), takeExtension, takeBaseName, joinPath, takeDirectory)
, removeDirectory, getDirectoryContents, copyFile )
import FilePath ((</>), takeExtension, takeBaseName, joinPath, takeDirectory )
import AbstractCurry.Types (CurryProg)
import List (intercalate, splitOn)
import Maybe (mapMaybe, fromJust)
import System (system)
import Pretty hiding ((</>))
import List ( intercalate, splitOn )
import Maybe ( mapMaybe, fromJust )
import System ( system )
import Text.Pretty hiding ( (</>) )
import CPM.AbstractCurry
import CPM.Config (Config, packageInstallDir)
......
......@@ -18,9 +18,9 @@ module CPM.Resolution
import Either
import List
import Pretty
import Sort
import Maybe
import Text.Pretty
import Test.EasyCheck
import CPM.Config (Config, defaultConfig, compilerVersion)
......
......@@ -7,6 +7,7 @@
"license": "BSD-3-Clause",
"licenseFile": "LICENSE",
"dependencies": {
"wl-pprint": ">= 0.0.1"
},
"compilerCompatibility": {
"pakcs": ">= 2.0.0",
......
......@@ -27,8 +27,6 @@ module AbstractCurry.Pretty
, ppCStatement, ppQFunc, ppFunc, ppQType, ppType)
where
import Pretty hiding ( list, listSpaced, tupled, tupledSpaced, set
, setSpaced )
import AbstractCurry.Select hiding (varsOfLDecl, varsOfFDecl, varsOfStat)
import AbstractCurry.Types
import AbstractCurry.Transform (typesOfCurryProg, funcsOfCurryProg)
......@@ -36,6 +34,9 @@ import Function (on)
import List (partition, union, scanl, last, nub, (\\))
import Maybe (isJust, fromJust)
import Text.Pretty hiding ( list, listSpaced, tupled, tupledSpaced, set
, setSpaced )
type Collection a = [a]
data Qualification
......@@ -199,7 +200,7 @@ showCProg = prettyCurryProg defaultOptions
--- Pretty-print the document generated by 'ppCurryProg', using the page width
--- specified by given options.
prettyCurryProg :: Options -> CurryProg -> String
prettyCurryProg opts cprog = pretty (pageWidth opts) $ ppCurryProg opts cprog
prettyCurryProg opts cprog = showWidth (pageWidth opts) $ ppCurryProg opts cprog
--- Pretty-print a CurryProg (the representation of a program, written in Curry,
--- using AbstractCurry) according to given options.
......
......@@ -7,7 +7,8 @@
"license": "BSD-3-Clause",
"licenseFile": "LICENSE",
"dependencies": {
"xml": ">= 2.0.0"
"wl-pprint": ">= 0.0.1",
"xml" : ">= 2.0.0"
},
"compilerCompatibility": {
"pakcs": ">= 2.0.0",
......
......@@ -515,7 +515,7 @@ readCurrentFlatCurry modname = do
processPrimitives :: String -> Prog -> IO Prog
processPrimitives progname prog = do
pspecs <- readPrimSpec (moduleName prog)
(stripCurrySuffix progname ++ ".prim_c2p")
(stripCurrySuffix progname ++ ".pakcs")
return (mergePrimSpecIntoModule pspecs prog)
mergePrimSpecIntoModule :: [(QName,QName)] -> Prog -> Prog
......
......@@ -8,7 +8,7 @@
module FlatCurry.Pretty where
import Pretty
import Text.Pretty
import FlatCurry.Types
......
......@@ -6,7 +6,8 @@
"synopsis": "A JSON library for Curry",
"category": [ "Data", "Web" ],
"dependencies": {
"det-parse": "= 0.0.1"
"det-parse": "= 0.0.1",
"wl-pprint": ">= 0.0.1"
},
"compilerCompatibility": {
"pakcs": ">= 2.0.0",
......
module JSON.Pretty (ppJSON, ppJValue) where
import JSON.Data
import Pretty
import Text.Pretty
--- Pretty print a JSON value with the default options of Curry's Pretty module.
ppJSON :: JValue -> String
......
......@@ -29,7 +29,6 @@ import Debug
import Char (isAscii)
import List (intercalate)
import qualified DetParse as P
import Pretty
import qualified Boxes as B
--- A command line argument. Used to represent a parsed command line.
......
Copyright (c) 2017, <AUTHOR NAME>
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 of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. Neither the names of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER 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.
wl-pprint
=========
This package provides pretty printing combinators for Curry.
It uses the interface of Daan Leijen's library for Haskell
(http://www.cs.uu.nl/~daan/download/pprint/pprint.html).
The linear-time bounded implementation is based on an approach by Olaf Chitil
(http://www.cs.kent.ac.uk/pubs/2006/2381/index.html).
Note that the implementation of `fill` and `fillBreak` is not linear-time bounded
Besides well-known pretty printing combinators, this library also supports ANSI
escape codes for formatting and colorisation of documents in text terminals
(see https://en.wikipedia.org/wiki/ANSI_escape_code).
{
"name": "wl-pprint",
"version": "0.0.1",
"author": "Sebastian Fischer <sebf@informatik.uni-kiel.de>, Bjoern Peemoeller <bjp@informatik.uni-kiel.de>, Jan Rasmus Tikovsky <jrt@informatik.uni-kiel.de>",
"synopsis": "Pretty printing combinators for Curry (inspired by Leijen's library for Haskell)",
"category": [ "Printing" ],
"description": "This package includes a library providing general combinators for pretty printing. The interface is inspired by Daan Leijen's pretty printing library for Haskell and the linear-time bounded implementation is based on an approach by Olaf Chitil.",
"license": "BSD-3-Clause",
"licenseFile": "LICENSE",
"dependencies": {
},
"compilerCompatibility": {
"pakcs": ">= 2.0.0",
"kics2": ">= 2.0.0"
},
"exportedModules": [ "Text.Pretty" ],
"source": {
"git": "https://git.ps.informatik.uni-kiel.de/curry-packages/wl-pprint.git",
"tag": "$version"
}
}
This diff is collapsed.
--- Implementation of the Pretty library using
--- [linear-time, bounded implementation](http://www.cs.kent.ac.uk/pubs/2006/2381/index.html)
--- by Olaf Chitil.
---
--- @author Sebastian Fischer, Bjoern Peemoeller, Jan Tikovsky
--- @version October 2017
--- @category general
------------------------------------------------------------------------------
module Text.PrettyImpl where
import qualified Dequeue as Q (Queue, cons, empty, matchHead, matchLast)
-- The abstract data type Doc represents pretty documents.
data Doc = Doc (Tokens -> Tokens)
-- Extract the internal representation from a document.
deDoc :: Doc -> Tokens -> Tokens
deDoc (Doc d) = d
type Horizontal = Bool
type Remaining = Int
type Width = Int
type Position = Int
type StartPosition = Position
type EndPosition = Position
type Out = Remaining -> Margins -> FormatHistory -> String
-- Type of a `group output function`: Takes information whether group content
-- should be formatted horizontally or vertically and a continuation to output
-- parts of the document which come after the group
type OutGroupPrefix = Horizontal -> Out -> Out
type Margins = [Int]
-- A nesting is either an alignment or a relative indentation
data Nesting = Align | Inc Int
-- text colorisation
data Color
= Black
| Red
| Green
| Yellow
| Blue
| Magenta
| Cyan
| White
| Default
-- console intensity
data Intensity = Faint | Normal | Bold
-- support of blinking text
data BlinkMode = Off | Slow | Rapid
-- text formatting statement
data FormatStm
= SetForeground Color
| SetBackground Color
| SetIntensity Intensity
| SetBlinkMode BlinkMode
| SetItalicized Bool
| SetUnderlined Bool
| SetCrossedout Bool
| InverseColoring Bool
type FormatHistory = [FormatStm]
resetFormat :: FormatHistory -> (FormatStm, FormatHistory)
resetFormat [] = error "Pretty.resetFormat2: illegal format history"
resetFormat (stm:stms) = case stm of
SetForeground _ -> (SetForeground (prevFGColor stms), stms)
SetBackground _ -> (SetBackground (prevBGColor stms), stms)
SetIntensity _ -> (SetIntensity (prevIntensity stms), stms)
SetBlinkMode _ -> (SetBlinkMode (prevBlinkMode stms), stms)
SetItalicized b -> (SetItalicized (not b), stms)
SetUnderlined b -> (SetUnderlined (not b), stms)
SetCrossedout b -> (SetCrossedout (not b), stms)
InverseColoring b -> (InverseColoring (not b), stms)
-- Find previous foreground color in history
prevFGColor :: FormatHistory -> Color
prevFGColor history = case history of
[] -> Default
(SetForeground c : _ ) -> c
(_ : hs) -> prevFGColor hs
-- Find previous background color in history
prevBGColor :: FormatHistory -> Color
prevBGColor history = case history of
[] -> Default
(SetBackground c : _ ) -> c
(_ : hs) -> prevBGColor hs
-- Find previous text intensity in history
prevIntensity :: FormatHistory -> Intensity
prevIntensity history = case history of
[] -> Normal
(SetIntensity i : _ ) -> i
(_ : hs) -> prevIntensity hs
-- Find previous blinking mode in history
prevBlinkMode :: FormatHistory -> BlinkMode
prevBlinkMode history = case history of
[] -> Off
(SetBlinkMode b : _ ) -> b
(_ : hs) -> prevBlinkMode hs
applyFormat :: FormatStm -> String
applyFormat (SetForeground c) = txtMode (colorMode c)
applyFormat (SetBackground c) = txtMode (colorMode c + 10)
applyFormat (SetIntensity i) = txtMode (intensityMode i)
applyFormat (SetBlinkMode b) = txtMode (blinkMode b)
applyFormat (SetItalicized b) = txtMode (if b then 3 else 23)
applyFormat (SetUnderlined b) = txtMode (if b then 4 else 24)
applyFormat (SetCrossedout b) = txtMode (if b then 9 else 29)
applyFormat (InverseColoring b) = txtMode (if b then 7 else 27)
-- Text mode
txtMode :: Int -> String
txtMode m = csiCmd ++ show m ++ "m"
where
csiCmd :: String
csiCmd = '\ESC' : '[' : ""
-- Color mode
colorMode :: Color -> Int
colorMode c = case c of
Black -> 30
Red -> 31
Green -> 32
Yellow -> 33
Blue -> 34
Magenta -> 35
Cyan -> 36
White -> 37
Default -> 39
-- Intensity mode
intensityMode :: Intensity -> Int
intensityMode i = case i of
Faint -> 2
Normal -> 22
Bold -> 1
-- Blink mode
blinkMode :: BlinkMode -> Int
blinkMode b = case b of
Off -> 25
Slow -> 5
Rapid -> 6
-- Token sequence. Note that the data type linearizes a document so that
-- a fragment is usually followed by a remaining document.
data Tokens
= EOD -- end of document
| Empty Tokens -- empty document
| Text String Tokens -- string
| LineBreak (Maybe String) Tokens -- linebreak that will be replaced by the
-- separator if the linebreak is undone
| OpenGroup Tokens -- Beginning of a group
| CloseGroup Tokens -- End of a group
| OpenNest Nesting Tokens -- Beginning of a nesting
| CloseNest Tokens -- End of a nesting
| OpenFormat FormatStm Tokens -- Beginning of a formatting statement
| CloseFormat Tokens -- End of a formatting statement
applyNesting :: Nesting -> Width -> Remaining -> Margins -> Margins
applyNesting Align w r ms = (w - r) : ms
applyNesting (Inc i) _ _ ms = case ms of
m:_ -> (m + i) : ms
_ -> error "Pretty.applyNesting: empty margin list"
unApplyNesting :: Margins -> Margins
unApplyNesting [] = error "Pretty.unApplyNesting: empty margin list"
unApplyNesting (_:ms) = ms
addSpaces :: Int -> Tokens -> String
addSpaces m ts = case ts of
LineBreak _ _ -> ""
EOD -> ""
Empty ts' -> addSpaces m ts'
OpenGroup ts' -> addSpaces m ts'
CloseGroup ts' -> addSpaces m ts'
OpenNest _ ts' -> addSpaces m ts'
CloseNest ts' -> addSpaces m ts'
OpenFormat _ ts' -> addSpaces m ts'
CloseFormat ts' -> addSpaces m ts'
Text _ _ -> replicate m ' '
-- Normalise a token sequence using the following rewriting rules:
--
-- CloseGroup (Text s ts) => Text s (CloseGroup ts)
-- OpenGroup (Text s ts) => Text s (OpenGroup ts)
-- OpenGroup (CloseGroup ts) => ts
--
-- Rewriting moves `Text` tokens in and out of groups. The set of `lines`
-- "belonging" to each group, i.e., the set of layouts, is left unchanged.
normalise :: Tokens -> Tokens
normalise = go id
where
go co EOD = co EOD
go co (Empty ts) = go co ts
-- there should be no deferred opening brackets
go co (OpenGroup ts) = go (co . open) ts
go co (CloseGroup ts) = go (co . CloseGroup) ts
go co (LineBreak ms ts) = (co . LineBreak ms . go id) ts
go co (Text s ts) = Text s (go co ts)
go co (OpenNest n ts) = OpenNest n (go co ts)
go co (CloseNest ts) = CloseNest (go co ts)
go co (OpenFormat f ts) = OpenFormat f (go co ts)
go co (CloseFormat ts) = CloseFormat (go co ts)
open t = case t of
CloseGroup ts -> ts
_ -> OpenGroup t
-- Transform a document into a group-closed document by normalising its token
-- sequence.
-- A document is called group-closed, if between the end of every `group` and
-- the next `text` document there is always a `line` document.
doc2Tokens :: Doc -> Tokens
doc2Tokens (Doc d) = normalise (d EOD)
--- `(showWidth w d)` pretty prints document `d` with a page width of `w` characters
--- @param w - width of page
--- @param d - a document
--- @return pretty printed document
showWidth :: Width -> Doc -> String
showWidth w d = noGroup (doc2Tokens d) w 1 w [0] []
-- Compute number of visible ASCII characters
lengthVis :: String -> Int
lengthVis = Prelude.length . filter isVisible
where
isVisible c = ord c `notElem` ([5, 6, 7] ++ [16 .. 31])
-- Basic pretty printing algorithm:
--
-- 1. Determine for each group in the document its width, i.e. the space it
-- requires for printing if it was printed horizontally, all in one line.
-- 2. Traverse document tree and keep track of remaining free space in current
-- output line.
-- At the start of a group compare remaining space with width of the group:
-- If the width is smaller or equal, the group is formatted horizontally,
-- otherwise vertically.
-- Determine widths of all groups and produce actual layout by traversing token
-- sequence a single time using continuations:
-- At the start of each group construct a `group output function` which receives
-- formate information and information about the remaining space at the
-- beginning of the group.
-- Since groups can be nested we don't want to update a width value for each
-- surrounding group when processing a token. Instead we introduce an absolute
-- measure of a token's position: The width of a group is the difference between
-- the position of its `CloseGroup` token and the position of its `OpenGroup` token.
-- When traversing the document only the `group output function` of the
-- innermost group is extended. All the other `group output function`s are
-- passed on unchanged. When we come across a `CloseGroup` token we merge the
-- function for the innermost group with the function for the next inner group.
-- noGroup is used when there is currently no deferred group
noGroup :: Tokens -> Width -> Position -> Out
noGroup EOD _ _ _ _ _ = ""
-- should not occur:
noGroup (Empty ts) w p r ms fs = noGroup ts w p r ms fs
noGroup (Text t ts) w p r ms fs = t ++ noGroup ts w (p + l) (r - l) ms fs
where l = lengthVis t
noGroup (LineBreak _ ts) w p _ ms fs = case ms of
[] -> error "Pretty.noGroup: illegal line"
m:_ -> '\n' : addSpaces m ts ++ noGroup ts w (p + 1) (w - m) ms fs
noGroup (OpenGroup ts) w p r ms fs = oneGroup ts w p (p + r) (\_ c -> c) r ms fs
noGroup (CloseGroup ts) w p r ms fs = noGroup ts w p r ms fs -- may have been pruned
noGroup (OpenNest n ts) w p r ms fs = noGroup ts w p r (applyNesting n w r ms) fs
noGroup (CloseNest ts) w p r ms fs = noGroup ts w p r (unApplyNesting ms) fs
noGroup (OpenFormat f ts) w p r ms fs = applyFormat f ++ noGroup ts w p r ms (f:fs)
noGroup (CloseFormat ts) w p r ms fs = applyFormat f ++ noGroup ts w p r ms ofs
where
(f, ofs) = resetFormat fs
-- oneGroup is used when there is one deferred group
-- Whenever the tokens `Text` or `LineBreak` are processed,
-- i.e. the current position is increased,
-- pruneOne checks whether whether the group still fits the line
-- Furthermore the `group output function` is extended with the current token
oneGroup :: Tokens -> Width -> Position -> EndPosition -> OutGroupPrefix -> Out
oneGroup EOD _ _ _ _ = error "Pretty.oneGroup: EOD"
-- should not occur:
oneGroup (Empty ts) w p e outGrpPre = oneGroup ts w p e outGrpPre
oneGroup (Text s ts) w p e outGrpPre =
pruneOne ts w (p + l) e (\h cont -> outGrpPre h (outText cont))
where
l = lengthVis s
outText cont r ms fs = s ++ cont (r - l) ms fs
oneGroup (LineBreak Nothing ts) w p _ outGrpPre = outGrpPre False (outLine (noGroup ts w p))
where
outLine _ _ [] _ = error "Pretty.oneGroup.outLine: empty margins"
outLine cont _ ms@(m:_) fs = '\n' : addSpaces m ts ++ cont (w - m) ms fs
oneGroup (LineBreak (Just s) ts) w p e outGrpPre =
pruneOne ts w (p + l) e (\h cont -> outGrpPre h (outLine h cont))
where
l = lengthVis s
outLine _ _ _ [] _ = error "Pretty.oneGroup.outLine: empty margins"
outLine h cont r ms@(m:_) fs =
if h then s ++ cont (r - l) ms fs
else '\n' : addSpaces m ts ++ cont (w - m) ms fs
oneGroup (OpenGroup ts) w p e outGrpPre =
multiGroup ts w p e outGrpPre Q.empty p (\_ cont -> cont)
oneGroup (CloseGroup ts) w p e outGrpPre = outGrpPre (p <= e) (noGroup ts w p)
oneGroup (OpenNest n ts) w p e outGrpPre = oneGroup ts w p e
(\h cont -> outGrpPre h (\r ms fs -> cont r (applyNesting n w r ms) fs))
oneGroup (CloseNest ts) w p e outGrpPre = oneGroup ts w p e
(\h cont -> outGrpPre h (\r ms fs -> cont r (unApplyNesting ms) fs))
oneGroup (OpenFormat f ts) w p e outGrpPre = oneGroup ts w p e
(\h cont -> outGrpPre h (outFormat cont))
where
outFormat cont r ms fs = applyFormat f ++ cont r ms (f:fs)
oneGroup (CloseFormat ts) w p e outGrpPre = oneGroup ts w p e
(\h cont -> outGrpPre h (outUnformat cont))
where
outUnformat cont r ms fs = applyFormat f ++ cont r ms ofs
where
(f, ofs) = resetFormat fs
-- multiGroup is used when there are at least two deferred groups
-- Whenever the tokens `Text` or `LineBreak` are processed, i.e. the current position
-- is increased, pruneMulti checks whether whether the outermost group still
-- fits the line.
-- Furthermore the `group output function` of the innermost group is extended
-- with the current token.
-- When we come across a `OpenGroup` token during traversal of the token sequence,
-- the current innermost `group output function` is added to the queue.
-- Reaching a `CloseGroup` token it is checked whether the queue still contains a
-- deferred `group output function`: If the queue is empty, there is only one
-- group left, otherwise there are at least two groups left.
-- In both cases the function for the innermost group is merged with the
-- function for the next inner group
multiGroup :: Tokens -> Width -> Position -> EndPosition -> OutGroupPrefix
-> Q.Queue (StartPosition, OutGroupPrefix)
-> StartPosition -> OutGroupPrefix -> Out
multiGroup EOD _ _ _ _ _ _ _
= error "Pretty.multiGroup: EOD"
-- should not occur:
multiGroup (Empty ts) w p e outGrpPreOuter qs s outGrpPreInner
= multiGroup ts w p e outGrpPreOuter qs s outGrpPreInner
multiGroup (Text t ts) w p e outGrpPreOuter qs s outGrpPreInner
= pruneMulti ts w (p+l) e outGrpPreOuter qs s
(\h cont -> outGrpPreInner h (outText cont))
where
l = lengthVis t
outText cont r ms fs = t ++ cont (r-l) ms fs
multiGroup (LineBreak Nothing ts) w p _ outGrpPreOuter qs _ outGrpPreInner
= pruneAll outGrpPreOuter qs
where
pruneAll outGrpPreOuter' qs' = outGrpPreOuter' False (\r ->
(case Q.matchLast qs' of
Nothing -> outGrpPreInner False (outLine (noGroup ts w p))
Just ((_,outGrpPre),qss) -> pruneAll outGrpPre qss)
r)
outLine _ _ [] _ = error "Pretty.oneGroup.outLine: empty margins"
outLine cont _ ms@(m:_) fs = '\n' : addSpaces m ts ++ cont (w - m) ms fs
multiGroup (LineBreak (Just s) ts) w p e outGrpPreOuter qs si outGrpPreInner =
pruneMulti ts w (p + l) e outGrpPreOuter qs si
(\h cont -> outGrpPreInner h (outLine h cont))
where
l = lengthVis s
outLine _ _ _ [] _ = error "Pretty.multiGroup.outLine: empty margins"
outLine h cont r ms@(m:_) fs =
if h then s ++ cont (r-l) ms fs else '\n': addSpaces m ts ++ cont (w-m) ms fs
multiGroup (OpenGroup ts) w p e outGrpPreOuter qs si outGrpPreInner =
multiGroup ts w p e outGrpPreOuter (Q.cons (si,outGrpPreInner) qs) p (\_ cont -> cont)
multiGroup (CloseGroup ts) w p e outGrpPreOuter qs si outGrpPreInner =
case Q.matchHead qs of
Nothing -> oneGroup ts w p e
(\h cont -> outGrpPreOuter h
(\ri -> outGrpPreInner (p<=si+ri) cont ri))
Just ((s,outGrpPre),qs') ->
multiGroup ts w p e outGrpPreOuter qs' s
(\h cont -> outGrpPre h (\ri -> outGrpPreInner (p<=si+ri) cont ri))
multiGroup (OpenNest n ts) w p e outGrpPreOuter qs si outGrpPreInner =
multiGroup ts w p e outGrpPreOuter qs si
(\h cont -> outGrpPreInner h (\r ms fs -> cont r (applyNesting n w r ms) fs))
multiGroup (CloseNest ts) w p e outGrpPreOuter qs si outGrpPreInner =
multiGroup ts w p e outGrpPreOuter qs si
(\h cont -> outGrpPreInner h (\r ms fs -> cont r (unApplyNesting ms) fs))
multiGroup (OpenFormat f ts) w p e outGrpPreOuter qs si outGrpPreInner =