# Visitor
Starting with _visiting_ of parsed markdown
nodes does not require creating own instance of commonmark-java `Visitor`,
instead a composable/configurable `MarkwonVisitor` is used.
## Visitor.Builder
There is no need to create own instance of `MarkwonVisitor.Builder` as
it is done by `Markwon` itself. One still can configure it as one wishes:
```java
final Markwon markwon = Markwon.builder(contex)
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
builder.on(SoftLineBreak.class, new MarkwonVisitor.NodeVisitor() {
@Override
public void visit(@NonNull MarkwonVisitor visitor, @NonNull SoftLineBreak softLineBreak) {
visitor.forceNewLine();
}
});
}
});
```
---
`MarkwonVisitor` encapsulates most of the functionality of rendering parsed markdown.
It holds rendering configuration:
* `MarkwonVisitor#configuration` - getter for current [MarkwonConfiguration](/docs/v3/core/configuration.md)
* `MarkwonVisitor#renderProps` - getter for current [RenderProps](/docs/v3/core/render-props.md)
* `MarkwonVisitor#builder` - getter for current `SpannableBuilder`
It contains also a number of utility functions:
* `visitChildren(Node)` - will visit all children of supplied Node
* `hasNext(Node)` - utility function to check if supplied Node has a Node after it (useful for white-space management, so there should be no blank new line after last BlockNode)
* `ensureNewLine` - will insert a new line at current `SpannableBuilder` position only if current (last) character is not a new-line
* `forceNewLine` - will insert a new line character without any condition checking
* `length` - helper function to call `visitor.builder().length()`, returns current length of `SpannableBuilder`
* `clear` - will clear state for `RenderProps` and `SpannableBuilder`, this is done by `Markwon` automatically after each render call
And some utility functions to control the spans:
* `setSpans(int start, Object spans)` - will apply supplied `spans` on `SpannableBuilder` starting at `start` position and ending at `SpannableBuilder#length`. `spans` can be `null` (no spans will be applied) or an array of spans (each span of this array will be applied)
* `setSpansForNodeOptional(N node, int start)` - helper method to set spans for specified `node` (internally obtains `SpanFactory` for that node and uses it to apply spans)
* `setSpansForNode(N node, int start)` - almost the same as `setSpansForNodeOptional` but instead of silently ignoring call if none `SpanFactory` is registered, this method will throw an exception.
```java
@Override
public void configureVisitor(@NonNull MarkwonVisitor.Builder builder) {
builder.on(Heading.class, new MarkwonVisitor.NodeVisitor() {
@Override
public void visit(@NonNull MarkwonVisitor visitor, @NonNull Heading heading) {
// or just `visitor.length()`
final int start = visitor.builder().length();
visitor.visitChildren(heading);
// or just `visitor.setSpansForNodeOptional(heading, start)`
final SpanFactory factory = visitor.configuration().spansFactory().get(heading.getClass());
if (factory != null) {
visitor.setSpans(start, factory.getSpans(visitor.configuration(), visitor.renderProps()));
}
if (visitor.hasNext(heading)) {
visitor.ensureNewLine();
visitor.forceNewLine();
}
}
});
}
```