Add more documentation to BriDoc api

pull/35/head
Lennart Spitzner 2017-03-08 17:33:56 +01:00 committed by GitHub
parent 109163fc4d
commit 19a05d01c4
1 changed files with 153 additions and 9 deletions

View File

@ -66,18 +66,102 @@ types mean. This leaves us to explain the different `BriDoc`
Specify multiple alternative layouts. Take care to appropriately maintain Specify multiple alternative layouts. Take care to appropriately maintain
sharing for the documents representing the children of the current node. sharing for the documents representing the children of the current node.
See the "Controlling layouting" section below.
- docAltFilter - docAltFilter
simple utility wrapper around `docAlt`: Each alternative is accompanied by simple utility wrapper around `docAlt`: Each alternative is accompanied by
a boolean; if False the alternative is discarded. a boolean; if False the alternative is discarded.
- docPar/BDPar - docPar `:: m BriDocNumbered -> m BriDocNumbered -> m BriDocMumbered`
TODO (does not completely match `BDPar`, which has an extra argument.)
Describes a "paragraph" - a layout consisting of some headline (which must
be free of newlines) and content (that may contain newlines). Simple example
is a `do`-block:
~~~~.hs
do -- headline
stmt -- content
stmt -- content
stmt -- content
~~~~
But let us first consider the simplest case: `docPar fooDoc barDoc`
placed at the start of the line; it will be layouted like this:
~~~~.hs
foo
bar
~~~~
As you can see, the content is not indented by default. In this form,
`docPar a b` behaves like `docLines [a,b]`, and `docPar a (docLines bs)` like
`docLines (a:bs)`. What makes `docPar` special is that it allows differing
indentation of headline and content, where the lines of `docLines` are
supposed to have the same indentation.
This allows two common uses of `docPar`:
1. The pattern `docAddBaseY BrIndentRegular $ docPar _ _`. `docAddBaseY`
does not affect
the current line (i.e. the headline of `docPar`) but it _does_ indent the
content.
2. At the end of a sequence; the following is valid and common:
`docSeq [elem1, elem2, docPar elem3 content]` which looks like
~~~~.hs
elem1 elem2 elem3
content
~~~~
So the headline does not need occur at the start of the line.
This interaction between `docSeq`, `docAddBaseY`, and `docPar` allows us to
add indentation to the content of a childnode without even knowing if that
childnode will actually make use of `docPar`. We can simply use
`docAddBaseY BrIndentRegular $ docSeq [foo, bar, childNodeDoc]` and get
sensible layout including indentation of the _potential_ content-part of the
child node. Such a behaviour would not be possible without this interaction
unless we resorted to analysing the doc created for the childnode - which
would lead to complex special-casing.
~~~~.hs
foo bar child-oneline
-- or
foo bar child-headline
child-content
~~~~
This pattern does however require that we keep this interaction in mind
when writing the layouting of such parent/childnode relationships. For
example using `docLines` in the child node instead of `docPar` would
probably lead to bad results if the parent used `docAddBaseY`.
- docLines/BDLines - docLines/BDLines
TODO Where `docSeq` is horizontal sequence, `docLines` is the vertical sequence
operator. `docLines` has one important requirement: All lines must have the
same indentation. Violating this will lead to undefined layouting behaviour.
As a consequence, there are two valid usage patterns:
1. `docLines` is used at the start of a line, e.g. as the content of a
`docPar`.
2. The `docSetBaseY $ docLines _` or
`docSetBaseAndIndent $ docNonBottomSpacing $ docLines _` patterns allow
using `docLines` as a final element of a sequence; the `docSetBase~`
constructs ensure that the rest-lines are indented as much as the
headline. An example is:
~~~~.hs
foo | bar = 1
| baz = 2
~~~~
where "| bar = 1" and "| bar = 2" are two lines of a docLines.
- docSeparator/BDSeparator - docSeparator/BDSeparator
@ -86,6 +170,14 @@ types mean. This leaves us to explain the different `BriDoc`
(e.g. in the start of a line when indented) or if already indented due to (e.g. in the start of a line when indented) or if already indented due to
horizontal alignment. horizontal alignment.
Note also this helper:
~~~~.hs
appSep :: ToBriDocM BriDocNumbered -> ToBriDocM BriDocNumbered
appSep x = docSeq [x, docSeparator]
~~~~
### Creating horizontal alignment ### Creating horizontal alignment
- docCols/BDCols ColSig [BriDoc] - docCols/BDCols ColSig [BriDoc]
@ -138,9 +230,9 @@ types mean. This leaves us to explain the different `BriDoc`
~~~~ ~~~~
docLines docLines
docCols equation docCols equationSigToken
"func" "func"
docCols docCols patternSigToken
"(" "("
"MyLongFoo" "MyLongFoo"
"abc" "abc"
@ -151,7 +243,7 @@ types mean. This leaves us to explain the different `BriDoc`
"1" "1"
docCols equation docCols equation
"func" "func"
docCols docCols patternSigToken
"(" "("
"Bar" "Bar"
"a" "a"
@ -180,14 +272,66 @@ TODO
### Controlling layouting ### Controlling layouting
TODO The purpose of these nodes/modifiers is affecting the choices of alternatives
(see `docAlt`) made. For example in a bridoc tree like
~~~~
docAlt
docForceSingleLine
[stuff]
[otherOption]
~~~~
if stuff only returns layouts that use multiple lines, then this alternative
will not be considered, and this will be effectively simplified to just
`[otherOption]`.
- docNonBottomSpacing - docNonBottomSpacing
- docSetParSpacing
- docForceParSpacing Enforces that this node is _not_ discarded even when all considered layouts
use more space than available. This counteracts the fact that we consider
a limited amount of layouts in order to retain linear runtime. Bad usage
of this modifier will lead to unnecessary overflow over the max-columns (80
by default) even when other layoutings were available.
[TODO: consideration of valid usecases]
- docSetParSpacing and docForceParSpacing
We say a node has "ParSpacing" if it looks like a `docPar` result.. it has
a headline and (indented) content in new lines. This property can propagate
somewhat non-trivially upwards and is used by certain parents. It mainly
provides nice layouting choices in cases such as:
~~~~.hs
foo = abc $ def $ do
stmt
stmt
~~~~
Consider what we know when translating the equation: We have two
possibilites:
~~~~.hs
foo = child-node-doc -- note that child may contain a docPar.
-- or
foo =
child-node-doc
~~~~
As usual, we do not to inspect child-node-doc; this makes deciding between
the two choices hard. Looking at is-single/multi-line is not sufficient.
[TODO]
- docForceSingleline - docForceSingleline
Discards child layouts that contain newlines.
- docForceMultiline - docForceMultiline
Discards child layouts lacking newlines.
### Inserting comments / Controlling comment placement ### Inserting comments / Controlling comment placement
TODO TODO