diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..c0453d223 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive", + "java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx4G -Xms100m -Xlog:disable", + "maven.view": "hierarchical", + "[markdown]": { + "editor.defaultFormatter": null, + "editor.formatOnSave": false + } +} diff --git a/flexmark-ext-d2-diagrams/flexmark-ext-d2-diagrams.iml b/flexmark-ext-d2-diagrams/flexmark-ext-d2-diagrams.iml new file mode 100644 index 000000000..49f79a850 --- /dev/null +++ b/flexmark-ext-d2-diagrams/flexmark-ext-d2-diagrams.iml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/flexmark-ext-d2-diagrams/pom.xml b/flexmark-ext-d2-diagrams/pom.xml new file mode 100644 index 000000000..7bef254ef --- /dev/null +++ b/flexmark-ext-d2-diagrams/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + com.vladsch.flexmark + flexmark-java + 0.64.8 + + + flexmark-ext-d2-diagrams + flexmark-java extension d2 diagrams + flexmark-java extension for d2 diagrams + + + + com.vladsch.flexmark + flexmark-util + + + com.vladsch.flexmark + flexmark + + + com.vladsch.flexmark + flexmark-test-util + test + + + com.vladsch.flexmark + flexmark-core-test + test + + + diff --git a/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Block.java b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Block.java new file mode 100644 index 000000000..1df2b93f7 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Block.java @@ -0,0 +1,13 @@ +package com.vladsch.flexmark.ext.d2; + +import com.vladsch.flexmark.util.ast.Block; +import com.vladsch.flexmark.util.sequence.BasedSequence; +import org.jetbrains.annotations.NotNull; + +public class D2Block extends Block { + @NotNull + @Override + public BasedSequence[] getSegments() { + return EMPTY_SEGMENTS; + } +} diff --git a/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Extension.java b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Extension.java new file mode 100644 index 000000000..774c3a6d6 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Extension.java @@ -0,0 +1,42 @@ +package com.vladsch.flexmark.ext.d2; + +import com.vladsch.flexmark.ext.d2.internal.*; +import com.vladsch.flexmark.html.HtmlRenderer; +import com.vladsch.flexmark.parser.Parser; +import com.vladsch.flexmark.util.data.MutableDataHolder; + +import org.jetbrains.annotations.NotNull; + +/** + * Extension for d2 diagrams + */ +public class D2Extension implements Parser.ParserExtension, HtmlRenderer.HtmlRendererExtension { + private D2Extension() { + } + + public static D2Extension create() { + return new D2Extension(); + } + + @Override + public void rendererOptions(@NotNull MutableDataHolder options) { + + } + + @Override + public void parserOptions(MutableDataHolder options) { + + } + + @Override + public void extend(Parser.Builder parserBuilder) { + parserBuilder.customBlockParserFactory(new D2BlockParser.Factory()); + } + + @Override + public void extend(@NotNull HtmlRenderer.Builder htmlRendererBuilder, @NotNull String rendererType) { + if (htmlRendererBuilder.isRendererType("HTML") || htmlRendererBuilder.isRendererType("JIRA")) { + htmlRendererBuilder.nodeRendererFactory(new D2NodeRenderer.Factory()); + } + } +} diff --git a/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Node.java b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Node.java new file mode 100644 index 000000000..fa014778a --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Node.java @@ -0,0 +1,59 @@ +package com.vladsch.flexmark.ext.d2; + +import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.sequence.BasedSequence; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class D2Node extends Node { + private BasedSequence key; + //private List values; + + @NotNull + @Override + public BasedSequence[] getSegments() { + return new BasedSequence[] { key }; + } + + public D2Node(BasedSequence key, List values) { + this.key = key; + //this.values = values; + for (BasedSequence value : values) { + appendChild(new D2Value(value)); + } + } + + public String getKey() { + return key.toString(); + } + + public BasedSequence getKeySequence() { + return key; + } + + public void setKey(BasedSequence key) { + this.key = key; + } + + public List getValues() { + ArrayList list = new ArrayList<>(); + Node child = getFirstChild(); + while (child != null) { + list.add(child.getChars().toString()); + child = child.getNext(); + } + return list; + } + + public List getValuesSequences() { + ArrayList list = new ArrayList<>(); + Node child = getFirstChild(); + while (child != null) { + list.add(child.getChars()); + child = child.getNext(); + } + return list; + } +} diff --git a/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Value.java b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Value.java new file mode 100644 index 000000000..20bc0ea35 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/D2Value.java @@ -0,0 +1,20 @@ +package com.vladsch.flexmark.ext.d2; + +import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.sequence.BasedSequence; +import org.jetbrains.annotations.NotNull; + +public class D2Value extends Node { + @NotNull + @Override + public BasedSequence[] getSegments() { + return EMPTY_SEGMENTS; + } + + public D2Value() { + } + + public D2Value(BasedSequence chars) { + super(chars); + } +} diff --git a/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/internal/D2BlockParser.java b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/internal/D2BlockParser.java new file mode 100644 index 000000000..7d945eb50 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/internal/D2BlockParser.java @@ -0,0 +1,128 @@ +package com.vladsch.flexmark.ext.d2.internal; + +import com.vladsch.flexmark.ext.d2.D2Block; +import com.vladsch.flexmark.ext.d2.D2Node; +import com.vladsch.flexmark.parser.InlineParser; +import com.vladsch.flexmark.parser.block.*; +import com.vladsch.flexmark.parser.core.DocumentBlockParser; +import com.vladsch.flexmark.util.ast.Block; +import com.vladsch.flexmark.util.ast.BlockContent; +import com.vladsch.flexmark.util.data.DataHolder; +import com.vladsch.flexmark.util.sequence.BasedSequence; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +public class D2BlockParser extends AbstractBlockParser { + final private static Pattern REGEX_BEGIN = Pattern.compile("^`{3}d2(\\s.*)?"); + final private static Pattern REGEX_END = Pattern.compile("^`{3}(\\s.*)?"); + + private boolean inD2Block; + private BasedSequence currentKey; + private List currentValues; + private D2Block block; + private BlockContent content; + + public D2BlockParser() { + inD2Block = true; + currentKey = null; + currentValues = new ArrayList<>(); + block = new D2Block(); + content = new BlockContent(); + } + + @Override + public Block getBlock() { + return block; + } + + @Override + public boolean isContainer() { + return false; + } + + @Override + public void addLine(ParserState state, BasedSequence line) { + content.add(line, state.getIndent()); + } + + @Override + public void closeBlock(ParserState state) { + block.setContent(content.getLines().subList(0, content.getLineCount())); + block.setCharsFromContent(); + content = null; + } + + @Override + public BlockContinue tryContinue(ParserState state) { + final BasedSequence line = state.getLine(); + + if (inD2Block) { + if (REGEX_END.matcher(line).matches()) { + System.out.println("test"); + D2Node child = new D2Node(line, currentValues); + child.setCharsFromContent(); + block.appendChild(child); + return BlockContinue.finished(); + } else { + return BlockContinue.atIndex(state.getIndex()); + } + } else if (REGEX_BEGIN.matcher(line).matches()) { + inD2Block = true; + return BlockContinue.atIndex(state.getIndex()); + } + return BlockContinue.none(); + } + + @Override + public void parseInlines(InlineParser inlineParser) { + } + + public static class Factory implements CustomBlockParserFactory { + @Nullable + @Override + public Set> getAfterDependents() { + return null; + } + + @Nullable + @Override + public Set> getBeforeDependents() { + return null; + } + + @Override + public boolean affectsGlobalScope() { + return false; + } + + @NotNull + @Override + public BlockParserFactory apply(@NotNull DataHolder options) { + return new BlockFactory(options); + } + } + + private static class BlockFactory extends AbstractBlockParserFactory { + private BlockFactory(DataHolder options) { + super(options); + } + + @Override + public BlockStart tryStart(ParserState state, MatchedBlockParser matchedBlockParser) { + CharSequence line = state.getLine(); + BlockParser parentParser = matchedBlockParser.getBlockParser(); + // check whether this line is the first line of whole document or not + if (parentParser instanceof DocumentBlockParser && parentParser.getBlock().getFirstChild() == null && + REGEX_BEGIN.matcher(line).matches()) { + return BlockStart.of(new D2BlockParser()).atIndex(state.getNextNonSpaceIndex()); + } + + return BlockStart.none(); + } + } +} diff --git a/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/internal/D2NodeRenderer.java b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/internal/D2NodeRenderer.java new file mode 100644 index 000000000..0cc0acf95 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/internal/D2NodeRenderer.java @@ -0,0 +1,40 @@ +package com.vladsch.flexmark.ext.d2.internal; + +import com.vladsch.flexmark.ext.d2.D2Node; +import com.vladsch.flexmark.html.HtmlWriter; +import com.vladsch.flexmark.html.renderer.NodeRenderer; +import com.vladsch.flexmark.html.renderer.NodeRendererContext; +import com.vladsch.flexmark.html.renderer.NodeRendererFactory; +import com.vladsch.flexmark.html.renderer.NodeRenderingHandler; +import com.vladsch.flexmark.util.data.DataHolder; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Set; + +public class D2NodeRenderer implements NodeRenderer { + public D2NodeRenderer(DataHolder options) { + + } + + @Override + public Set> getNodeRenderingHandlers() { + HashSet> set = new HashSet<>(); + set.add(new NodeRenderingHandler<>(D2Node.class, this::render)); + return set; + } + + private void render(D2Node node, NodeRendererContext context, HtmlWriter html) { + html.tag("p"); + html.text("rendering d2 node"); + html.tag("/p"); + } + + public static class Factory implements NodeRendererFactory { + @NotNull + @Override + public NodeRenderer apply(@NotNull DataHolder options) { + return new D2NodeRenderer(options); + } + } +} diff --git a/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/internal/package-info.java b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/internal/package-info.java new file mode 100644 index 000000000..37aa02744 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/internal/package-info.java @@ -0,0 +1 @@ +package com.vladsch.flexmark.ext.d2.internal; diff --git a/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/package-info.java b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/package-info.java new file mode 100644 index 000000000..4d3df0552 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/main/java/com/vladsch/flexmark/ext/d2/package-info.java @@ -0,0 +1 @@ +package com.vladsch.flexmark.ext.d2; diff --git a/flexmark-ext-d2-diagrams/src/main/javadoc/overview.html b/flexmark-ext-d2-diagrams/src/main/javadoc/overview.html new file mode 100644 index 000000000..ffa4eeda6 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/main/javadoc/overview.html @@ -0,0 +1,8 @@ + + + + + +

flexmark-java extension for d2 diagrams

+ + diff --git a/flexmark-ext-d2-diagrams/src/main/javadoc/overview.md b/flexmark-ext-d2-diagrams/src/main/javadoc/overview.md new file mode 100644 index 000000000..28a211ee2 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/main/javadoc/overview.md @@ -0,0 +1 @@ +**flexmark-java extension for d2 diagrams** diff --git a/flexmark-ext-d2-diagrams/src/test/java/com/vladsch/flexmark/ext/d2/D2RendererSpecTest.java b/flexmark-ext-d2-diagrams/src/test/java/com/vladsch/flexmark/ext/d2/D2RendererSpecTest.java new file mode 100644 index 000000000..df407a00f --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/test/java/com/vladsch/flexmark/ext/d2/D2RendererSpecTest.java @@ -0,0 +1,31 @@ +package com.vladsch.flexmark.ext.d2; + +import com.vladsch.flexmark.core.test.util.RendererSpecTest; +import com.vladsch.flexmark.parser.Parser; +import com.vladsch.flexmark.test.util.spec.ResourceLocation; +import com.vladsch.flexmark.test.util.spec.SpecExample; +import com.vladsch.flexmark.util.data.DataHolder; +import com.vladsch.flexmark.util.data.MutableDataSet; +import org.jetbrains.annotations.NotNull; +import org.junit.runners.Parameterized; + +import java.util.Collections; +import java.util.List; + +public class D2RendererSpecTest extends RendererSpecTest { + final private static String SPEC_RESOURCE = "/d2_formatter_spec.md"; + final public static @NotNull ResourceLocation RESOURCE_LOCATION = ResourceLocation.of(SPEC_RESOURCE); + final private static DataHolder OPTIONS = new MutableDataSet() + .set(Parser.EXTENSIONS, Collections.singleton(D2Extension.create())) + .toImmutable(); + + public D2RendererSpecTest(@NotNull SpecExample example) { + super(example, null, OPTIONS); + } + + @Parameterized.Parameters(name = "{0}") + public static List data() { + List data = getTestData(RESOURCE_LOCATION); + return data; + } +} diff --git a/flexmark-ext-d2-diagrams/src/test/resources/com.vladsch.flexmark.ext.d2.txt b/flexmark-ext-d2-diagrams/src/test/resources/com.vladsch.flexmark.ext.d2.txt new file mode 100644 index 000000000..34dbc4597 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/test/resources/com.vladsch.flexmark.ext.d2.txt @@ -0,0 +1 @@ +java/ diff --git a/flexmark-ext-d2-diagrams/src/test/resources/d2_formatter_spec.md b/flexmark-ext-d2-diagrams/src/test/resources/d2_formatter_spec.md new file mode 100644 index 000000000..12a5f9b97 --- /dev/null +++ b/flexmark-ext-d2-diagrams/src/test/resources/d2_formatter_spec.md @@ -0,0 +1,26 @@ +--- +title: D2 Diagrams Extension Formatting Spec +author: Paweł Biegun +version: 1.0 +date: '2023.08.26' +license: '[CC-BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)' +... + +--- + +## D2 Diagrams + +Converts d2 diagram to svg + +```````````````````````````````` example D2 Diagrams: 1 +```d2 +A -> B +B -> A +``` +. +

rendering d2 node

+. +Document[0, 23] + D2Block[0, 23] + D2Node[20, 23] +```````````````````````````````` \ No newline at end of file diff --git a/flexmark-java.iml b/flexmark-java.iml index 0644c646e..221a6e598 100644 --- a/flexmark-java.iml +++ b/flexmark-java.iml @@ -26,6 +26,7 @@ + diff --git a/flexmark-test-util/src/main/java/com/vladsch/flexmark/test/util/FullSpecTestCase.java b/flexmark-test-util/src/main/java/com/vladsch/flexmark/test/util/FullSpecTestCase.java index 67f0b36ca..5c26470cf 100644 --- a/flexmark-test-util/src/main/java/com/vladsch/flexmark/test/util/FullSpecTestCase.java +++ b/flexmark-test-util/src/main/java/com/vladsch/flexmark/test/util/FullSpecTestCase.java @@ -10,7 +10,8 @@ public abstract class FullSpecTestCase extends RenderingTestCase implements SpecExampleProcessor { @NotNull public DumpSpecReader create(@NotNull ResourceLocation location) { - return SpecReader.create(location, (stream, fileUrl) -> new DumpSpecReader(stream, this, fileUrl, compoundSections())); + return SpecReader.create(location, + (stream, fileUrl) -> new DumpSpecReader(stream, this, fileUrl, compoundSections())); } protected boolean compoundSections() { @@ -30,7 +31,8 @@ protected void fullTestSpecComplete() { @Test public void testSpecExample() { ResourceLocation location = getSpecResourceLocation(); - if (location.isNull()) return; + if (location.isNull()) + return; fullTestSpecStarting(); DumpSpecReader reader = create(location); @@ -40,10 +42,10 @@ public void testSpecExample() { String actual = reader.getFullSpec(); String expected = reader.getExpectedFullSpec(); -// // NOTE: reading the full spec does not work when examples are modified by checkExample() -// String fullSpec = SpecReader.readSpec(location); -// assertEquals(reader.getFileUrl(), expected, fullSpec); - + // // NOTE: reading the full spec does not work when examples are modified by + // checkExample() + // String fullSpec = SpecReader.readSpec(location); + // assertEquals(reader.getFileUrl(), expected, fullSpec); if (!reader.getFileUrl().isEmpty()) { assertEquals(reader.getFileUrl(), expected, actual); } else { diff --git a/pom.xml b/pom.xml index 3a2a62832..9862faf65 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,7 @@ flexmark-ext-yaml-front-matter flexmark-ext-youtube-embedded flexmark-ext-zzzzzz + flexmark-ext-d2-diagrams flexmark-test-util flexmark-tree-iteration flexmark-util @@ -368,6 +369,11 @@ flexmark-ext-resizable-image ${project.version} + + com.vladsch.flexmark + flexmark-ext-d2-diagrams + ${project.version} + com.vladsch.flexmark flexmark-ext-xwiki-macros