parens :: Doc -> Doc; -- ^ Wrap document in @(...)@
brackets :: Doc -> Doc; -- ^ Wrap document in @[...]@
braces :: Doc -> Doc; -- ^ Wrap document in @{...}@
-quotes :: Doc -> Doc; -- ^ Wrap document in @'...'@
+quotes :: Doc -> Doc; -- ^ Wrap document in @\'...\'@
doubleQuotes :: Doc -> Doc; -- ^ Wrap document in @\"...\"@
-- Combining @Doc@ values
($$) :: Doc -> Doc -> Doc; -- ^Above; if there is no
-- overlap it \"dovetails\" the two
+($+$) :: Doc -> Doc -> Doc; -- ^Above, without dovetailing.
vcat :: [Doc] -> Doc; -- ^List version of '$$'
cat :: [Doc] -> Doc; -- ^ Either hcat or vcat
-- SIGBJORN wrote instead:
-- rational n = text (show (fromRationalX n))
-quotes p = char '`' <> p <> char '\''
+quotes p = char '\'' <> p <> char '\''
doubleQuotes p = char '"' <> p <> char '"'
parens p = char '(' <> p <> char ')'
brackets p = char '[' <> p <> char ']'
lay (NilAbove p) no_doc = nl_text `txt` lay p cant_fail -- NoDoc always on first line
lay (TextBeside s sl p) no_doc = s `txt` lay p no_doc
-indent n | n >= 8 = '\t' : indent (n - 8)
- | otherwise = spaces n
+-- OLD version: we shouldn't rely on tabs being 8 columns apart in the output.
+-- indent n | n >= 8 = '\t' : indent (n - 8)
+-- | otherwise = spaces n
+indent n = spaces n
multi_ch 0 ch = ""
multi_ch n ch = ch : multi_ch (n - 1) ch
-spaces 0 = ""
-spaces n = ' ' : spaces (n - 1)
-
+-- (spaces n) generates a list of n spaces
+--
+-- It should never be called with 'n' < 0, but that can happen for reasons I don't understand
+-- Here's a test case:
+-- ncat x y = nest 4 $ cat [ x, y ]
+-- d1 = foldl1 ncat $ take 50 $ repeat $ char 'a'
+-- d2 = parens $ sep [ d1, text "+" , d1 ]
+-- main = print d2
+-- I don't feel motivated enough to find the Real Bug, so meanwhile we just test for n<=0
+spaces n | n <= 0 = ""
+ | otherwise = ' ' : spaces (n - 1)
+
+{- Comments from Johannes Waldmann about what the problem might be:
+
+ In the example above, d2 and d1 are deeply nested, but `text "+"' is not,
+ so the layout function tries to "out-dent" it.
+
+ when I look at the Doc values that are generated, there are lots of
+ Nest constructors with negative arguments. see this sample output of
+ d1 (obtained with hugs, :s -u)
+
+ tBeside (TextDetails_Chr 'a') 1 Doc_Empty) (Doc_NilAbove (Doc_Nest
+ (-241) (Doc_TextBeside (TextDetails_Chr 'a') 1 Doc_Empty)))))
+ (Doc_NilAbove (Doc_Nest (-236) (Doc_TextBeside (TextDetails_Chr 'a') 1
+ (Doc_NilAbove (Doc_Nest (-5) (Doc_TextBeside (TextDetails_Chr 'a') 1
+ Doc_Empty)))))))) (Doc_NilAbove (Doc_Nest (-231) (Doc_TextBeside
+ (TextDetails_Chr 'a') 1 (Doc_NilAbove (Doc_Nest (-5) (Doc_TextBeside
+ (TextDetails_Chr 'a') 1 (Doc_NilAbove (Doc_Nest (-5) (Doc_TextBeside
+ (TextDetails_Chr 'a') 1 Doc_Empty))))))))))) (Doc_NilAbove (Doc_Nest
+-}