Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
with the exception that 0.x versions can break between minor versions.

## [Unreleased]
### Added
### Changed
### Fixed
- `MarkdownRenderer`: Fix precedence for `nodeRendererFactory`: Factories passed
to the builder can now override rendering for core node types.

## [0.24.0] - 2024-10-21
### Added
- `SourceSpan` on nodes now have a `getInputIndex` to get the index within the
Expand Down Expand Up @@ -459,6 +466,7 @@ API breaking changes (caused by changes in spec):
Initial release of commonmark-java, a port of commonmark.js with extensions
for autolinking URLs, GitHub flavored strikethrough and tables.

[Unreleased]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.24.0...main
[0.24.0]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.23.0...commonmark-parent-0.24.0
[0.23.0]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.22.0...commonmark-parent-0.23.0
[0.22.0]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.21.0...commonmark-parent-0.22.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public class NodeRendererMap {
private final List<NodeRenderer> nodeRenderers = new ArrayList<>();
private final Map<Class<? extends Node>, NodeRenderer> renderers = new HashMap<>(32);

/**
* Set the renderer for each {@link NodeRenderer#getNodeTypes()}, unless there was already a renderer set (first wins).
*/
public void add(NodeRenderer nodeRenderer) {
nodeRenderers.add(nodeRenderer);
for (var nodeType : nodeRenderer.getNodeTypes()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,10 @@ private RendererContext(MarkdownWriter writer) {
}
additionalTextEscapes = Collections.unmodifiableSet(escapes);

// The first node renderer for a node type "wins".
for (int i = nodeRendererFactories.size() - 1; i >= 0; i--) {
MarkdownNodeRendererFactory nodeRendererFactory = nodeRendererFactories.get(i);
for (var factory : nodeRendererFactories) {
// Pass in this as context here, which uses the fields set above
NodeRenderer nodeRenderer = nodeRendererFactory.create(this);
nodeRendererMap.add(nodeRenderer);
var renderer = factory.create(this);
nodeRendererMap.add(renderer);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@

import org.commonmark.node.*;
import org.commonmark.parser.Parser;
import org.commonmark.renderer.NodeRenderer;
import org.commonmark.renderer.html.HtmlNodeRendererContext;
import org.commonmark.renderer.html.HtmlNodeRendererFactory;
import org.commonmark.renderer.html.HtmlRenderer;
import org.junit.Test;

import java.util.Set;

import static org.commonmark.testutil.Asserts.assertRendering;
import static org.junit.Assert.assertEquals;

Expand Down Expand Up @@ -300,6 +306,35 @@ public void testSoftLineBreaks() {
assertRoundTrip("foo\nbar\n");
}

@Test
public void overrideNodeRender() {
var nodeRendererFactory = new MarkdownNodeRendererFactory() {
@Override
public NodeRenderer create(MarkdownNodeRendererContext context) {
return new NodeRenderer() {
@Override
public Set<Class<? extends Node>> getNodeTypes() {
return Set.of(Heading.class);
}

@Override
public void render(Node node) {
context.getWriter().raw("# Custom heading");
}
};
}

@Override
public Set<Character> getSpecialCharacters() {
return Set.of();
}
};

MarkdownRenderer renderer = MarkdownRenderer.builder().nodeRendererFactory(nodeRendererFactory).build();
String rendered = renderer.render(parse("# Hello"));
assertEquals("# Custom heading\n", rendered);
}

private void assertRoundTrip(String input) {
String rendered = parseAndRender(input);
assertEquals(input, rendered);
Expand Down