Karya, built on 2023-08-29T07:47:28 (patch 7a412d5d6ba4968ca4155ef276a062ccdeb9109a)
Safe HaskellSafe-Inferred

Util.Format

Description

This is a library to lay out text with line wrapping and indenting.

The basic theory is that you concatenate text with BreakTypes. In addition, you can increment the indent level with withIndent. When render wraps the text, it will break on the lowest indent level, or as soon as the indent level decreases.

A further wrinkle is that you can mark alternate layouts with shortForm.

Synopsis

Documentation

data Doc Source #

Instances

Instances details
String.IsString Doc Source # 
Instance details

Defined in Util.Format

Monoid Doc Source # 
Instance details

Defined in Util.Format

Methods

mempty :: Doc #

mappend :: Doc -> Doc -> Doc #

mconcat :: [Doc] -> Doc #

Semigroup Doc Source # 
Instance details

Defined in Util.Format

Methods

(<>) :: Doc -> Doc -> Doc #

sconcat :: NonEmpty Doc -> Doc #

stimes :: Integral b => b -> Doc -> Doc #

Show Doc Source # 
Instance details

Defined in Util.Format

Methods

showsPrec :: Int -> Doc -> ShowS #

show :: Doc -> String.String #

showList :: [Doc] -> ShowS #

Eq Doc Source # 
Instance details

Defined in Util.Format

Methods

(==) :: Doc -> Doc -> Bool #

(/=) :: Doc -> Doc -> Bool #

Pretty Doc Source # 
Instance details

Defined in Util.Pretty

shortForm :: Doc -> Doc -> Doc Source #

The first Doc is the short form, which will be used if it doesn't have to wrap. So you can give a compact form which will render if it can fit without breaking, and then a form with more fancy layout that will be used if it does have to break. For example, [1, 2, 3] for short lists, and [1\n, 2\n, 3\n] for long ones.

Prepending text to a shortForm will distribute over both short and long forms. Otherwise, if you write "prefix " <> x, and x happens to be a shortForm, the long form loses the prefix.

Appending two shortForms will make you lose the long form of the second one. So don't do that. TODO I'd rather both short and long forms be appended, but haven't figured out how to do that yet.

(</>) :: Doc -> Doc -> Doc infixr 5 Source #

Soft break with no space.

(<+/>) :: Doc -> Doc -> Doc infixr 5 Source #

Soft break with a space.

(<//>) :: Doc -> Doc -> Doc infixr 4 Source #

Hard break with a single newline.

(<+>) :: Doc -> Doc -> Doc infixr 6 Source #

Join two docs with a space.

newline :: Int -> Doc Source #

Insert a number of newlines.

Consecutive breaks are merged together, and a hard break always wins. Also, multiple hard breaks are merged into one, and ones with greater newlines win other those with fewer. The rationale is that if you are formatting a list of sub-Docs, and you want to put each on its own line, you need a hard break after each one, but if one of them does the same thing, you wind up with two breaks in a row.

unlines :: [Doc] -> Doc Source #

Analogous to unlines, terminate each Doc with a newline.

paragraphs :: [Doc] -> Doc Source #

This is just like unlines, but separate docs with two newlines, and terminate the last with one.

wrap :: [Doc] -> Doc Source #

withIndent :: Doc -> Doc Source #

Increase the indent level for the given Doc. The indent change only takes effect after the first break, so if you want it to take effect immediately, use one of indent, indent_, or indentLine.

The reason indent is delayed is that this way you can do a hanging indent, where the current line is unindented, but it will be indented if it wraps. Otherwise you don't know where to put the indent, since you don't know where the break will happen.

indent :: Doc -> Doc Source #

Change the indent level and add a no-space break so it takes effect immediately.

indent_ :: Doc -> Doc Source #

Change the indent level and add a spaced break so it takes effect immediately.

indentLine :: Doc -> Doc Source #

Change the indent level and add a hard break so it takes effect immediately.

type Width = Int Source #

Width of monospace text, in characters.

render :: Text -> Width -> Doc -> Lazy.Text Source #

Render a Doc, wrapping after the given Width.

renderFlat :: Doc -> Lazy.Text Source #

Render the Doc all on one line, with no newlines.

simplify :: Doc -> Doc Source #

Merge Texts so the Doc is easier to read.

denest :: Doc -> Text Source #

Reduce the Doc to a flattened easier to read version.