- Doc <A>
- Append (Doc<A> d)
- Empty = DocEmpty<A>.Default
- + (Doc<A> x, Doc<A> y)
- + (string x, Doc<A> y)
- + (Doc<A> x, string y)
- | (Doc<A> x, Doc<A> y)
- | (string x, Doc<A> y)
- | (Doc<A> x, string y)
- Select <B> (Func<A, B> f)
- Map <B> (Func<A, B> f)
- ReAnnotate <B> (Func<A, B> f)
- ChangesUponFlattening ()
- Flatten ()
- Show ()
- DocFail <A>
- DocEmpty <A>
- Default = new DocEmpty<A>()
- ReAnnotate <B> (Func<A, B> f)
- ChangesUponFlattening ()
- Flatten ()
- Append (Doc<A> d)
- DocChar <A> (char Value)
- DocText <A> (string Text)
- DocLine <A>
- DocFlatAlt <A> (Doc<A> Primary, Doc<A> Alt)
- DocUnion <A> (Doc<A> DocA, Doc<A> DocB)
- DocCat <A> (Doc<A> DocA, Doc<A> DocB)
- DocNest <A> (int Indent, Doc<A> Doc)
- DocColumn <A> (Func<int, Doc<A>> React)
- DocPageWidth <A> (Func<PageWidth, Doc<A>> React)
- DocNesting <A> (Func<int, Doc<A>> React)
- DocAnnotate <A> (A Annotation, Doc<A> Doc)
- Doc
- Fail = DocAnn.Fail<Unit>()
- Empty = DocAnn.Empty<Unit>()
- Char (char c)
- Text (string text)
- FlatAlt (Doc<Unit> da, Doc<Unit> db)
- Union (Doc<Unit> da, Doc<Unit> db)
- Cat (Doc<Unit> da, Doc<Unit> db)
- Nest (int indent, Doc<Unit> doc)
- Column (Func<int, Doc<Unit>> f)
- PageWidth (Func<PageWidth, Doc<Unit>> f)
- Nesting (Func<int, Doc<Unit>> f)
- HardLine = DocLine<Unit>.Default
- LineOrSpace = DocAnn.LineOrSpace<Unit>()
- LineOrEmpty = DocAnn.LineOrEmpty<Unit>()
- SoftLineOrSpace = DocAnn.SoftLineOrSpace<Unit>()
- SoftLineOrEmpty = DocAnn.SoftLineOrEmpty<Unit>()
- Group (Doc<Unit> doc)
- Align (Doc<Unit> doc)
- Hang (int offset, Doc<Unit> doc)
- Indent (int indent, Doc<Unit> doc)
- EncloseSep (Doc<Unit> leftDelim, Doc<Unit> rightDelim, Doc<Unit> sep, Seq<Doc<Unit>> docs)
- EncloseSep (Doc<Unit> leftDelim, Doc<Unit> rightDelim, Doc<Unit> sep, params Doc<Unit>[] docs)
- List (Seq<Doc<Unit>> docs)
- Tuple (Seq<Doc<Unit>> docs)
- List (params Doc<Unit>[] docs)
- Tuple (params Doc<Unit>[] docs)
- Spaces (int n)
- HorizSep (Seq<Doc<Unit>> docs)
- VertSep (Seq<Doc<Unit>> docs)
- Sep (Doc<Unit> sep, Seq<Doc<Unit>> docs)
- Sep (Seq<Doc<Unit>> docs)
- FillSep (Seq<Doc<Unit>> docs)
- HardSep (Seq<Doc<Unit>> docs)
- HorizCat (Seq<Doc<Unit>> docs)
- VertCat (Seq<Doc<Unit>> docs)
- Width (Doc<Unit> doc, Func<int, Doc<Unit>> f)
- Fill (int width, Doc<Unit> doc)
- Between (Doc<Unit> left, Doc<Unit> right, Doc<Unit> middle)
- DocAnn
- Annotate <A> (A annotation, Doc<A> doc)
- Fail <A> ()
- Empty <A> ()
- Char <A> (char c)
- Text <A> (string text)
- FlatAlt <A> (Doc<A> da, Doc<A> db)
- Union <A> (Doc<A> da, Doc<A> db)
- Cat <A> (Doc<A> da, Doc<A> db)
- Nest <A> (int indent, Doc<A> doc)
- Column <A> (Func<int, Doc<A>> f)
- PageWidth <A> (Func<PageWidth, Doc<A>> f)
- Nesting <A> (Func<int, Doc<A>> f)
- HardLine <A> ()
- LineOrSpace <A> ()
- LineOrEmpty <A> ()
- SoftLineOrSpace <A> ()
- SoftLineOrEmpty <A> ()
- Group <A> (Doc<A> doc)
- Align <A> (Doc<A> doc)
- Hang <A> (int offset, Doc<A> doc)
- Indent <A> (int indent, Doc<A> doc)
- Sep <A> (Doc<A> sep, Seq<Doc<A>> docs)
- BetweenSep <A> (Doc<A> leftDelim, Doc<A> rightDelim, Doc<A> sep, Seq<Doc<A>> docs)
- BetweenSep <A> (Doc<A> leftDelim, Doc<A> rightDelim, Doc<A> sep, params Doc<A>[] docs)
- List <A> (Seq<Doc<A>> docs)
- Tuple <A> (Seq<Doc<A>> docs)
- List <A> (params Doc<A>[] docs)
- Tuple <A> (params Doc<A>[] docs)
- Spaces <A> (int n)
- HorizSep <A> (Seq<Doc<A>> docs)
- VertSep <A> (Seq<Doc<A>> docs)
- Sep <A> (Seq<Doc<A>> docs)
- FillSep <A> (Seq<Doc<A>> docs)
- HardSep <A> (Seq<Doc<A>> docs)
- HorizCat <A> (Seq<Doc<A>> docs)
- VertCat <A> (Seq<Doc<A>> docs)
- Width <A> (Doc<A> doc, Func<int, Doc<A>> f)
- Fill <A> (int width, Doc<A> doc)
- Between <A> (Doc<A> left, Doc<A> middle, Doc<A> right)
- DocStream <A>
- SFail <A>
- SEmpty <A>
- SChar <A> (char Value, DocStream<A> Next)
- SText <A> (string Value, DocStream<A> Next)
- SLine <A> (int Indent, DocStream<A> Next)
- SAnnPush <A> (A Ann, DocStream<A> Next)
- SAnnPop <A> (DocStream<A> Next)
- FittingPredicate <A> (Func<PageWidth, int, Option<int>, DocStream<A>, bool> FP)
- FlattenResult <A>
- Flattened <A> (A Value)
- AlreadyFlat <A>
- NeverFlat <A>
- Layout
- pretty <A> (LayoutOptions options, Doc<A> doc)
- smart <A> (LayoutOptions options, Doc<A> doc)
- layout <A> ( FittingPredicate<A> fittingPredicate, LayoutOptions options, Doc<A> doc)
- LayoutOptions (PageWidth PageWidth)
- LayoutPipeline <A>
- Nil <A>
- Cons <A> (int Value, Doc<A> Doc, LayoutPipeline<A> Pipeline)
- UndoAnn <A> (LayoutPipeline<A> Pipeline)
- PageWidth
- AvailablePerLine (int LineLength = 120, double RibbonFraction = 0.4)
- Unbounded ()
Base document record
Construct documents using the Doc and DocAnn static types
field Doc<A> Empty = DocEmpty<A>.Default Source #
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
field Doc<A> Default = new DocFail<A>() Source #
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
field Doc<A> Default = new DocEmpty<A>() Source #
record DocChar <A> (char Value) Source #
Invariant: not '\n'
type | A |
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
record DocText <A> (string Text) Source #
At least two characters long, does not contain '\n'. For
empty documents, there is DocEmpty
; for singleton documents, there is
DocChar
; newlines should be replaced by e.g. DocLine
.
type | A |
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
Hard line break
field Doc<A> Default = new DocLine<A>() Source #
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
record DocFlatAlt <A> (Doc<A> Primary, Doc<A> Alt) Source #
Lay out the first 'Doc', but when flattened (via 'group'), prefer the second.
The layout algorithms work under the assumption that the first alternative is less wide than the flattened second alternative.
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
record DocUnion <A> (Doc<A> DocA, Doc<A> DocB) Source #
The first lines of first document should be longer than the first lines of the second one, so the layout algorithm can pick the one that fits best. Used to implement layout alternatives for 'group'.
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
record DocCat <A> (Doc<A> DocA, Doc<A> DocB) Source #
Concat two documents
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
record DocColumn <A> (Func<int, Doc<A>> React) Source #
React on the current cursor position,
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
record DocPageWidth <A> (Func<PageWidth, Doc<A>> React) Source #
React on the document's page width
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
record DocNesting <A> (Func<int, Doc<A>> React) Source #
React on the current nesting level
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
record DocAnnotate <A> (A Annotation, Doc<A> Doc) Source #
dd an annotation to the enclosed 'Doc'. Can be used for example to add styling directives or alt texts that can then be used by the renderer.
method Doc<B> ReAnnotate <B> (Func<A, B> f) Source #
method FlattenResult<Doc<A>> ChangesUponFlattening () Source #
Document building functions
No annotation (unit only), use DocAnn
for annotated documents
field Doc<Unit> Fail = DocAnn.Fail<Unit>() Source #
field Doc<Unit> Empty = DocAnn.Empty<Unit>() Source #
field Doc<Unit> HardLine = DocLine<Unit>.Default Source #
A hardline is always laid out as a line break, even when 'grouped or when there is plenty of space. Note that it might still be simply discarded if it is part of a 'FlatAlt' inside a 'Group'.
field Doc<Unit> LineOrSpace = DocAnn.LineOrSpace<Unit>() Source #
LineOrSpace is a line-break, but behaves like Char(' ') if the line break is undone by Group
field Doc<Unit> LineOrEmpty = DocAnn.LineOrEmpty<Unit>() Source #
LineOrEmpty is a line-break, but behaves like Empty if the line break is undone by Group
field Doc<Unit> SoftLineOrSpace = DocAnn.SoftLineOrSpace<Unit>() Source #
softline behaves like space if the resulting output fits the page, otherwise like line
field Doc<Unit> SoftLineOrEmpty = DocAnn.SoftLineOrEmpty<Unit>() Source #
softline behaves like Empty if the resulting output fits the page, otherwise like line
method Doc<Unit> Group (Doc<Unit> doc) Source #
Group tries laying out doc into a single line by removing the contained line breaks; if this does not fit the page, or when a 'hardline' within doc prevents it from being flattened, doc is laid out without any changes.
The 'group' function is key to layouts that adapt to available space nicely.
method Doc<Unit> Align (Doc<Unit> doc) Source #
Align lays out the document with the nesting level set to the current column. It is used for example to implement 'hang'.
As an example, we will put a document right above another one, regardless of the current nesting level. Without alignment, the second line is put simply below everything we've had so far,
Text("lorem") + VertSep(["ipsum", "dolor"])
lorem ipsum dolor
If we add an Align to the mix, the VertSep contents all start in the same column,
Text("lorem") + Align (VertSep(["ipsum", "dolor"])) lorem ipsum dolor
method Doc<Unit> Hang (int offset, Doc<Unit> doc) Source #
Hang lays out the document with a nesting level set to the /current column/ plus offset. Negative values are allowed, and decrease the nesting level accordingly.
var doc = Reflow("Indenting these words with hang") PutDocW(24, ("prefix" + Hang(4, doc))) prefix Indenting these words with hang
This differs from Nest, which is based on the /current nesting level/ plus offset. When you're not sure, try the more efficient 'nest' first. In our example, this would yield
var doc = Reflow("Indenting these words with nest") PutDocW(24, "prefix" + Nest(4, doc)) prefix Indenting these words with nest
method Doc<Unit> Indent (int indent, Doc<Unit> doc) Source #
Indents document indent
columns, starting from the
current cursor position.
var doc = Reflow("The indent function indents these words!") PutDocW(24, ("prefix" + Indent(4, doc)) prefix The indent function indents these words!
method Doc<Unit> EncloseSep (Doc<Unit> leftDelim, Doc<Unit> rightDelim, Doc<Unit> sep, Seq<Doc<Unit>> docs) Source #
Delimit and intersperse the documents with a separator
method Doc<Unit> EncloseSep (Doc<Unit> leftDelim, Doc<Unit> rightDelim, Doc<Unit> sep, params Doc<Unit>[] docs) Source #
Delimit and intersperse the documents with a separator
method Doc<Unit> HorizSep (Seq<Doc<Unit>> docs) Source #
HorizSep concatenates all documents horizontally with +
i.e. it puts a space between all entries.
HorizSep does not introduce line breaks on its own, even when the page is too narrow:
For automatic line breaks, consider using 'fillSep' instead.
method Doc<Unit> VertSep (Seq<Doc<Unit>> docs) Source #
VertSep concatenates all documents above each other. If a Group undoes the line breaks inserted by VertSep, the documents are separated with a 'space' instead.
Grouping a VertSep separates the documents with a 'space' if it fits the page (and does nothing otherwise). See the Sep convenience function for this use case.
The Align function can be used to align the documents under their first element:
Since Grouping a VertSep is rather common, Sep is a built-in for doing that.
method Doc<Unit> Sep (Doc<Unit> sep, Seq<Doc<Unit>> docs) Source #
Intersperse the documents with a separator
method Doc<Unit> Sep (Seq<Doc<Unit>> docs) Source #
Sep tries laying out the documents separated with 'space's, and if this does not fit the page, separates them with newlines. This is what differentiates it from VerSep, which always lays out its contents beneath each other.
method Doc<Unit> FillSep (Seq<Doc<Unit>> docs) Source #
FillSep concatenates the documents horizontally with +
(inserting a space)
as long as it fits the page, then inserts a Line and continues doing that
for all documents in (Line means that if Grouped, the documents
are separated with a Space instead of newlines. Use 'FillCat' if you do not
want a 'space'.)
method Doc<Unit> HorizCat (Seq<Doc<Unit>> docs) Source #
HorizCat concatenates all documents horizontally with | (i.e. without any spacing).
It is provided only for consistency, since it is identical to 'Cat'.
method Doc<Unit> VertCat (Seq<Doc<Unit>> docs) Source #
VertCat vertically concatenates the documents. If it is Grouped, the line breaks are removed.
In other words VertCat is like VertSep, with newlines removed instead of replaced by spaces.
method Doc<Unit> Width (Doc<Unit> doc, Func<int, Doc<Unit>> f) Source #
Width lays out the document 'doc', and makes the column width of it available to a function.
Document building functions
Carries annotation, for unit only annotations, use Doc
method Doc<A> HardLine <A> () Source #
A hardline is always laid out as a line break, even when 'grouped or when there is plenty of space. Note that it might still be simply discarded if it is part of a 'FlatAlt' inside a 'Group'.
method Doc<A> LineOrSpace <A> () Source #
LineOrSpace is a line-break, but behaves like space if the line break is undone by Group
method Doc<A> LineOrEmpty <A> () Source #
LineOrEmpty is a line-break, but behaves like Empty if the line break is undone by Group
method Doc<A> SoftLineOrSpace <A> () Source #
softline behaves like space if the resulting output fits the page, otherwise like line
method Doc<A> SoftLineOrEmpty <A> () Source #
softline behaves like Empty if the resulting output fits the page, otherwise like line
method Doc<A> Group <A> (Doc<A> doc) Source #
Group tries laying out doc into a single line by removing the contained line breaks; if this does not fit the page, or when a 'hardline' within doc prevents it from being flattened, doc is laid out without any changes.
The 'group' function is key to layouts that adapt to available space nicely.
method Doc<A> Align <A> (Doc<A> doc) Source #
Align lays out the document with the nesting level set to the current column. It is used for example to implement 'hang'.
As an example, we will put a document right above another one, regardless of the current nesting level. Without alignment, the second line is put simply below everything we've had so far,
Text("lorem") + VertSep(["ipsum", "dolor"])
lorem ipsum dolor
If we add an 'Align' to the mix, the VertSep's contents all start in the same column,
Text("lorem") + Align (VertSep(["ipsum", "dolor"])) lorem ipsum dolor
method Doc<A> Hang <A> (int offset, Doc<A> doc) Source #
Hang lays out the document with a nesting level set to the /current column/ plus offset. Negative values are allowed, and decrease the nesting level accordingly.
var doc = Reflow("Indenting these words with hang") PutDocW(24, ("prefix" + Hang(4, doc))) prefix Indenting these words with hang
This differs from Nest, which is based on the /current nesting level/ plus offset. When you're not sure, try the more efficient 'nest' first. In our example, this would yield
var doc = Reflow("Indenting these words with nest") PutDocW(24, "prefix" + Nest(4, doc)) prefix Indenting these words with nest
method Doc<A> Indent <A> (int indent, Doc<A> doc) Source #
Indents document indent
columns, starting from the
current cursor position.
var doc = Reflow("The indent function indents these words!") PutDocW(24, ("prefix" + Indent(4, doc)) prefix The indent function indents these words!
method Doc<A> Sep <A> (Doc<A> sep, Seq<Doc<A>> docs) Source #
Intersperse the documents with a separator
method Doc<A> BetweenSep <A> (Doc<A> leftDelim, Doc<A> rightDelim, Doc<A> sep, Seq<Doc<A>> docs) Source #
Delimit and intersperse the documents with a separator
method Doc<A> BetweenSep <A> (Doc<A> leftDelim, Doc<A> rightDelim, Doc<A> sep, params Doc<A>[] docs) Source #
Delimit and intersperse the documents with a separator
method Doc<A> HorizSep <A> (Seq<Doc<A>> docs) Source #
HorizSep concatenates all documents horizontally with +
i.e. it puts a space between all entries.
HorizSep does not introduce line breaks on its own, even when the page is too narrow:
For automatic line breaks, consider using 'fillSep' instead.
method Doc<A> VertSep <A> (Seq<Doc<A>> docs) Source #
VertSep concatenates all documents above each other. If a Group undoes the line breaks inserted by VertSep, the documents are separated with a 'space' instead.
Grouping a VertSep separates the documents with a 'space' if it fits the page (and does nothing otherwise). See the Sep convenience function for this use case.
The Align function can be used to align the documents under their first element:
Since Grouping a VertSep is rather common, Sep is a built-in for doing that.
method Doc<A> Sep <A> (Seq<Doc<A>> docs) Source #
Sep tries laying out the documents separated with 'space's, and if this does not fit the page, separates them with newlines. This is what differentiates it from VerSep, which always lays out its contents beneath each other.
method Doc<A> FillSep <A> (Seq<Doc<A>> docs) Source #
FillSep concatenates the documents horizontally with +
(inserting a space)
as long as it fits the page, then inserts a Line and continues doing that
for all documents in (Line means that if Grouped, the documents
are separated with a Space instead of newlines. Use 'FillCat' if you do not
want a 'space'.)
method Doc<A> HorizCat <A> (Seq<Doc<A>> docs) Source #
HorizCat concatenates all documents horizontally with | (i.e. without any spacing).
It is provided only for consistency, since it is identical to 'Cat'.
method Doc<A> VertCat <A> (Seq<Doc<A>> docs) Source #
VertCat vertically concatenates the documents. If it is Grouped, the line breaks are removed.
In other words VertCat is like VertSep, with newlines removed instead of replaced by spaces.
method Doc<A> Width <A> (Doc<A> doc, Func<int, Doc<A>> f) Source #
Width lays out the document 'doc', and makes the column width of it available to a function.
field DocStream<A> Default = new SFail<A>() Source #
method DocStream<B> ReAnnotate <B> (Func<A, B> f) Source #
field DocStream<A> Default = new SEmpty<A>() Source #
method DocStream<B> ReAnnotate <B> (Func<A, B> f) Source #
record SChar <A> (char Value, DocStream<A> Next) Source #
method DocStream<B> ReAnnotate <B> (Func<A, B> f) Source #
record SText <A> (string Value, DocStream<A> Next) Source #
method DocStream<B> ReAnnotate <B> (Func<A, B> f) Source #
record SLine <A> (int Indent, DocStream<A> Next) Source #
method DocStream<B> ReAnnotate <B> (Func<A, B> f) Source #
record SAnnPush <A> (A Ann, DocStream<A> Next) Source #
method DocStream<B> ReAnnotate <B> (Func<A, B> f) Source #
record SAnnPop <A> (DocStream<A> Next) Source #
method DocStream<B> ReAnnotate <B> (Func<A, B> f) Source #
record FittingPredicate <A> (Func<PageWidth, int, Option<int>, DocStream<A>, bool> FP) Source #
FittingPredicate
FP: PageWidth, Nesting Level, Width for fist line (None is unbounded(
record FlattenResult <A> Source #
field FlattenResult<A> Default = new NeverFlat<A>() Source #
record LayoutOptions (PageWidth PageWidth) Source #
field LayoutOptions Default = new LayoutOptions(PageWidth.Default) Source #
record LayoutPipeline <A> Source #
List of nesting level/document pairs yet to be laid out.
record AvailablePerLine (int LineLength = 120, double RibbonFraction = 0.4) Source #
The 'Int' is the number of characters, including whitespace, that fit in a line. A typical value is 80.
The 'Double' is the ribbon with, i.e. the fraction of the total page width that can be printed on. This allows limiting the length of printable text per line. Values must be between 0 and 1, and 0.4 to 1 is typical.