Reputation: 7078
I have a pretty-printer like that:
somefun = text "woo" $+$ nest 4 (text "nested text") $+$ text "text without indent"
fun = text "------" $+$ somefun
What I want from it is to print this:
------ woo
nested text
text without indent
But it prints:
------
woo
nested text
text without indent
I can understand why it prints like this, but I'm having trouble to do what I want. One solution I find was this:
somefun p = p <+> text "woo" $+$ nest 4 (text "nested text") $+$ text "text without indent"
fun = somefun (text "------")
That is, I'm passing the Doc which I want my next Doc's indentation to be based on. This solves my problem but I'm looking for better ways to do this.
Upvotes: 0
Views: 466
Reputation: 32455
Your pass-the-Doc-as-an-argument solution is good. Once you've combined into a single Doc, you can't split it apart again, so here are two ways that use lists instead:
Another way of doing this is to use [Doc]
instead of Doc
for your subsequent text, if you want to treat the lines differently, then recombine using something like
(<+$) :: Doc -> [Doc] -> Doc
doc <+$ [] = doc
doc <+$ (d:ds) = (doc <+> d) $+$ foldr ($+$) empty ds
somefun :: [Doc]
somefun = [text "woo",
nest 4 (text "nested text"),
text "text without indent"]
fun :: Doc
fun = text "------" <+$ somefun
This gives you
*Main> fun
------ woo
nested text
text without indent
You could rewrite this solution another way keeping lists, if you like to keep indenting the top line:
(<+:) :: Doc -> [Doc] -> [Doc]
doc <+: [] = [doc]
doc <+: (d:ds) = (doc <+> d) : ds -- pop doc in front.
We'll need to put those together into a single Doc
at some stage:
vsep = foldr ($+$) empty
Now you can use :
to put a line above, and <+:
to push a bit in front of the top line:
start = [text "text without indent"]
next = nest 4 (text "nested text") : start
more = text "woo" : next
fun = text "------" <+: more
extra = text "-- extra! --" <+: fun
Test this with
*Main> vsep fun
------ woo
nested text
text without indent
*Main> vsep extra
-- extra! -- ------ woo
nested text
text without indent
The main issue is that if you use [Doc]
instead of Doc
it's almost as if you're not using the pretty-print library! It doesn't matter, though, if it's what you need.
Upvotes: 2