From da02026d876530b0b5b28230e2caa8dba1efaf7e Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Mon, 8 Jan 2024 14:10:21 +0100 Subject: [PATCH 01/13] #51 gfm alert extension --- .../io/github/gitbucket/markedj/Lexer.java | 24 ++-- .../io/github/gitbucket/markedj/Options.java | 7 +- .../extension/gfm/alert/GFMAlertEndToken.java | 32 +++++ .../gfm/alert/GFMAlertExtension.java | 110 ++++++++++++++++++ .../gfm/alert/GFMAlertStartToken.java | 41 +++++++ .../extension/gfm/alert/GFMAlerts.java | 72 ++++++++++++ .../gitbucket/markedj/GFMAlertsTest.java | 90 ++++++++++++++ src/test/resources/gfm/alerts/caution.html | 7 ++ src/test/resources/gfm/alerts/caution.md | 2 + src/test/resources/gfm/alerts/important.html | 7 ++ src/test/resources/gfm/alerts/important.md | 2 + src/test/resources/gfm/alerts/note.html | 7 ++ src/test/resources/gfm/alerts/note.md | 3 + src/test/resources/gfm/alerts/tip.html | 7 ++ src/test/resources/gfm/alerts/tip.md | 2 + src/test/resources/gfm/alerts/warning.html | 7 ++ src/test/resources/gfm/alerts/warning.md | 2 + .../resources/gfm/alerts/warning_custom.html | 7 ++ 18 files changed, 415 insertions(+), 14 deletions(-) create mode 100644 src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertEndToken.java create mode 100644 src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java create mode 100644 src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertStartToken.java create mode 100644 src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java create mode 100644 src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java create mode 100644 src/test/resources/gfm/alerts/caution.html create mode 100644 src/test/resources/gfm/alerts/caution.md create mode 100644 src/test/resources/gfm/alerts/important.html create mode 100644 src/test/resources/gfm/alerts/important.md create mode 100644 src/test/resources/gfm/alerts/note.html create mode 100644 src/test/resources/gfm/alerts/note.md create mode 100644 src/test/resources/gfm/alerts/tip.html create mode 100644 src/test/resources/gfm/alerts/tip.md create mode 100644 src/test/resources/gfm/alerts/warning.html create mode 100644 src/test/resources/gfm/alerts/warning.md create mode 100644 src/test/resources/gfm/alerts/warning_custom.html diff --git a/src/main/java/io/github/gitbucket/markedj/Lexer.java b/src/main/java/io/github/gitbucket/markedj/Lexer.java index 7690b54..418e1ee 100644 --- a/src/main/java/io/github/gitbucket/markedj/Lexer.java +++ b/src/main/java/io/github/gitbucket/markedj/Lexer.java @@ -159,18 +159,6 @@ protected void token(String src, boolean top, boolean bq, LexerContext context){ } } - // blockquote - { - List cap = rules.get("blockquote").exec(src); - if(!cap.isEmpty()){ - src = src.substring(cap.get(0).length()); - context.pushToken(new BlockquoteStartToken()); - token(cap.get(0).replaceAll("(?m)^ *> ?", ""), top, true, context); - context.pushToken(new BlockquoteEndToken()); - continue; - } - } - { Extension.LexResult result = null; for (Extension extension : options.getExtensions()) { @@ -185,6 +173,18 @@ protected void token(String src, boolean top, boolean bq, LexerContext context){ } } + // blockquote + { + List cap = rules.get("blockquote").exec(src); + if(!cap.isEmpty()){ + src = src.substring(cap.get(0).length()); + context.pushToken(new BlockquoteStartToken()); + token(cap.get(0).replaceAll("(?m)^ *> ?", ""), top, true, context); + context.pushToken(new BlockquoteEndToken()); + continue; + } + } + // list { List cap = rules.get("list").exec(src); diff --git a/src/main/java/io/github/gitbucket/markedj/Options.java b/src/main/java/io/github/gitbucket/markedj/Options.java index cb10bc2..a7e8e98 100644 --- a/src/main/java/io/github/gitbucket/markedj/Options.java +++ b/src/main/java/io/github/gitbucket/markedj/Options.java @@ -19,7 +19,7 @@ public class Options { "colgroup", "dd", "div", "dl", "dt", "em", "h1", "h2", "h3", "h4", "h5", "h6", "i", "img", "li", "ol", "p", "pre", "q", "small", "span", "strike", "strong", "sub", "sup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "u", - "ul", "input", "del", "hr") + "ul", "input", "del", "hr", "svg", "path") .addAttributes("a", "href", "title") .addProtocols("a", "href", "http", "https", "mailto", "ftp", "#") .addAttributes("blockquote", "cite") @@ -34,7 +34,10 @@ public class Options { .addAttributes("th", "abbr", "axis", "colspan", "rowspan", "scope", "width") .addAttributes("ul", "type") .addAttributes("input", "type", "checked", "name", "value", "disabled") - .addAttributes(":all", "id", "class", "style"); + .addAttributes("svg", "class", "viewBox", "version", "width", "height", "aria-hidden") + .addAttributes("path", "d") + .addAttributes(":all", "id", "class", "style") + ; private List extensions = new ArrayList<>(); diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertEndToken.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertEndToken.java new file mode 100644 index 0000000..60f215a --- /dev/null +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertEndToken.java @@ -0,0 +1,32 @@ +/* + * Copyright 2023 GitBucket. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.gitbucket.markedj.extension.gfm.alert; + +import io.github.gitbucket.markedj.token.Token; + +/** + * + * @author t.marx + */ +public class GFMAlertEndToken implements Token { + + public static String TYPE = "GFMAlertEndToken"; + + @Override + public String getType() { + return TYPE; + } +} diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java new file mode 100644 index 0000000..54703c6 --- /dev/null +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java @@ -0,0 +1,110 @@ +/* + * Copyright 2023 GitBucket. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.gitbucket.markedj.extension.gfm.alert; + +import io.github.gitbucket.markedj.Lexer; +import io.github.gitbucket.markedj.Parser; +import io.github.gitbucket.markedj.extension.Extension; +import io.github.gitbucket.markedj.extension.TokenConsumer; +import io.github.gitbucket.markedj.rule.FindFirstRule; +import io.github.gitbucket.markedj.rule.Rule; +import io.github.gitbucket.markedj.token.Token; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.function.Function; + +/** + * + * @author t.marx + */ +public class GFMAlertExtension implements Extension { + + public static String EXPRESSION = "(?s)(?m)^> \\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\](.+?)(^\n|\\Z)"; + + private static final Rule RULE = new FindFirstRule(EXPRESSION); + + private final Map titles = new HashMap<>(); + + public GFMAlertExtension () { + titles.put(GFMAlerts.Alert.TIP, "Tip"); + titles.put(GFMAlerts.Alert.NOTE, "Note"); + titles.put(GFMAlerts.Alert.IMPORTANT, "Important"); + titles.put(GFMAlerts.Alert.WARNING, "Warning"); + titles.put(GFMAlerts.Alert.CAUTION, "Caution"); + } + + public void addTitle (final GFMAlerts.Alert alert, final String title ) { + titles.put(alert, title); + } + + @Override + public LexResult lex(String source, final Lexer.LexerContext context, final TokenConsumer consumer) { + List cap = RULE.exec(source); + boolean tokenFound = false; + if (!cap.isEmpty()) { + // we have detected several contiguous lines of notifications + // ensure that all are of same kind + String allNotificationsLines = cap.get(0); + + String content = cap.get(2); + + content = content.replaceAll("(?m)^ *> ?", ""); + + source = source.substring(allNotificationsLines.length()); + context.pushToken(new GFMAlertStartToken(cap.get(1))); + consumer.token(content, false, false, context); + context.pushToken(new GFMAlertEndToken()); + + tokenFound = true; + } + return new LexResult(source, tokenFound); + } + + @Override + public boolean handlesToken(String token) { + return GFMAlertStartToken.TYPE.equals(token); + } + + @Override + public String parse(Parser.ParserContext context, Function tok) { + GFMAlertStartToken t = (GFMAlertStartToken) context.currentToken(); + StringBuilder body = new StringBuilder(); + while (true) { + Token n = context.nextToken(); + if (n == null || n.getType().equals(GFMAlertEndToken.TYPE)) { + break; + } + body.append(tok.apply(context)); + } + return render(body.toString(), t.getNotification()); + } + + private String render(String message, GFMAlerts.Alert alert) { + + if (!message.startsWith("

")) { + message = "

%s

".formatted(message); + } + + return String.format("

%s%s

\n%s
", + alert.name().toLowerCase(Locale.ENGLISH), + GFMAlerts.alertToSVG(alert), + titles.get(alert), + message + ); + } +} diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertStartToken.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertStartToken.java new file mode 100644 index 0000000..56fb787 --- /dev/null +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertStartToken.java @@ -0,0 +1,41 @@ +/* + * Copyright 2023 GitBucket. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.gitbucket.markedj.extension.gfm.alert; + +import io.github.gitbucket.markedj.token.Token; + +/** + * + * @author t.marx + */ +public class GFMAlertStartToken implements Token { + protected static String TYPE = "GFMAlertStartToken"; + + private GFMAlerts.Alert alert; + + public GFMAlertStartToken(String type) { + this.alert = GFMAlerts.Alert.fromString(type); + } + + @Override + public String getType() { + return TYPE; + } + + public GFMAlerts.Alert getNotification() { + return alert; + } +} diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java new file mode 100644 index 0000000..43d389b --- /dev/null +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java @@ -0,0 +1,72 @@ +/* + * Copyright 2023 GitBucket. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.gitbucket.markedj.extension.gfm.alert; + +/** + * + * @author t.marx + */ +public class GFMAlerts { + public static String exceptGivenNotificationClass(String notificationClassCharacter) { + switch (notificationClassCharacter) { + case "": + return "[xv!]"; + case "x": + return "[v!]?"; + case "v": + return "[x!]?"; + case "!": + return "[xv]?"; + } + throw new IllegalArgumentException("unknown character [" + notificationClassCharacter+ "] to define a notification charcater class"); + } + + public enum Alert { + NOTE, TIP, IMPORTANT, WARNING, CAUTION; + + public static Alert fromString(String s) { + switch (s) { + case "TIP": + return Alert.TIP; + case "IMPORTANT": + return Alert.IMPORTANT; + case "WARNING": + return Alert.WARNING; + case "CAUTION": + return Alert.CAUTION; + default: + return Alert.NOTE; + } + } + } + + public static String alertToSVG (GFMAlerts.Alert alert) { + switch (alert) { + case NOTE: + return ""; + case TIP: + return ""; + case CAUTION: + return ""; + case IMPORTANT: + return ""; + case WARNING: + return ""; + default: + throw new IllegalArgumentException("unknown alert"); + } + } +} diff --git a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java new file mode 100644 index 0000000..82fec84 --- /dev/null +++ b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2024 GitBucket. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.gitbucket.markedj; + +import static io.github.gitbucket.markedj.Resources.loadResourceAsString; +import io.github.gitbucket.markedj.extension.gfm.alert.GFMAlertExtension; +import io.github.gitbucket.markedj.extension.gfm.alert.GFMAlerts; +import org.assertj.core.api.Assertions; +import org.junit.Test; + +/** + * + * @author t.marx + */ +public class GFMAlertsTest { + + + private Options createOptions () { + Options options = new Options(); + options.addExtension(new GFMAlertExtension()); + return options; + } + + @Test + public void testNoteAlert() throws Exception { + String md = loadResourceAsString("gfm/alerts/note.md"); + String result = Marked.marked(md, createOptions()); + String expect = loadResourceAsString("gfm/alerts/note.html"); + Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); + } + + @Test + public void testTipAlert() throws Exception { + String md = loadResourceAsString("gfm/alerts/tip.md"); + String result = Marked.marked(md, createOptions()); + String expect = loadResourceAsString("gfm/alerts/tip.html"); + Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); + } + + @Test + public void testImportantAlert() throws Exception { + String md = loadResourceAsString("gfm/alerts/important.md"); + String result = Marked.marked(md, createOptions()); + String expect = loadResourceAsString("gfm/alerts/important.html"); + Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); + } + + @Test + public void testCautionAlert() throws Exception { + String md = loadResourceAsString("gfm/alerts/caution.md"); + String result = Marked.marked(md, createOptions()); + String expect = loadResourceAsString("gfm/alerts/caution.html"); + Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); + } + + @Test + public void testWarningAlert() throws Exception { + String md = loadResourceAsString("gfm/alerts/warning.md"); + String result = Marked.marked(md, createOptions()); + String expect = loadResourceAsString("gfm/alerts/warning.html"); + Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); + } + + @Test + public void testWithCustomTitles() throws Exception { + String md = loadResourceAsString("gfm/alerts/warning.md"); + + Options options = new Options(); + final GFMAlertExtension gfmAlertExtension = new GFMAlertExtension(); + gfmAlertExtension.addTitle(GFMAlerts.Alert.WARNING, "Attention!!!"); + options.addExtension(gfmAlertExtension); + + String result = Marked.marked(md, options); + String expect = loadResourceAsString("gfm/alerts/warning_custom.html"); + Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); + } +} diff --git a/src/test/resources/gfm/alerts/caution.html b/src/test/resources/gfm/alerts/caution.html new file mode 100644 index 0000000..85c9cdc --- /dev/null +++ b/src/test/resources/gfm/alerts/caution.html @@ -0,0 +1,7 @@ +
+

+ + Caution +

+

Advises about risks or negative outcomes of certain actions.

+
\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/caution.md b/src/test/resources/gfm/alerts/caution.md new file mode 100644 index 0000000..425f438 --- /dev/null +++ b/src/test/resources/gfm/alerts/caution.md @@ -0,0 +1,2 @@ +> [!CAUTION] +> Advises about risks or negative outcomes of certain actions. \ No newline at end of file diff --git a/src/test/resources/gfm/alerts/important.html b/src/test/resources/gfm/alerts/important.html new file mode 100644 index 0000000..8416ebd --- /dev/null +++ b/src/test/resources/gfm/alerts/important.html @@ -0,0 +1,7 @@ +
+

+ + Important +

+

Key information users need to know to achieve their goal.

+
\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/important.md b/src/test/resources/gfm/alerts/important.md new file mode 100644 index 0000000..81f711d --- /dev/null +++ b/src/test/resources/gfm/alerts/important.md @@ -0,0 +1,2 @@ +> [!IMPORTANT] +> Key information users need to know to achieve their goal. \ No newline at end of file diff --git a/src/test/resources/gfm/alerts/note.html b/src/test/resources/gfm/alerts/note.html new file mode 100644 index 0000000..7182779 --- /dev/null +++ b/src/test/resources/gfm/alerts/note.html @@ -0,0 +1,7 @@ +
+

+ + Note +

+

Useful information that users should know, even when skimming content.

+
\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/note.md b/src/test/resources/gfm/alerts/note.md new file mode 100644 index 0000000..c2cc523 --- /dev/null +++ b/src/test/resources/gfm/alerts/note.md @@ -0,0 +1,3 @@ +> [!NOTE] +> Useful information that users should know, +> even when skimming content. \ No newline at end of file diff --git a/src/test/resources/gfm/alerts/tip.html b/src/test/resources/gfm/alerts/tip.html new file mode 100644 index 0000000..6c5fbc8 --- /dev/null +++ b/src/test/resources/gfm/alerts/tip.html @@ -0,0 +1,7 @@ +
+

+ + Tip +

+

Helpful advice for doing things better or more easily.

+
\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/tip.md b/src/test/resources/gfm/alerts/tip.md new file mode 100644 index 0000000..bbec8a1 --- /dev/null +++ b/src/test/resources/gfm/alerts/tip.md @@ -0,0 +1,2 @@ +> [!TIP] +> Helpful advice for doing things better or more easily. \ No newline at end of file diff --git a/src/test/resources/gfm/alerts/warning.html b/src/test/resources/gfm/alerts/warning.html new file mode 100644 index 0000000..f1df732 --- /dev/null +++ b/src/test/resources/gfm/alerts/warning.html @@ -0,0 +1,7 @@ +
+

+ + Warning +

+

Urgent info that needs immediate user attention to avoid problems.

+
\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/warning.md b/src/test/resources/gfm/alerts/warning.md new file mode 100644 index 0000000..76301ba --- /dev/null +++ b/src/test/resources/gfm/alerts/warning.md @@ -0,0 +1,2 @@ +> [!WARNING] +> Urgent info that needs immediate user attention to avoid problems. \ No newline at end of file diff --git a/src/test/resources/gfm/alerts/warning_custom.html b/src/test/resources/gfm/alerts/warning_custom.html new file mode 100644 index 0000000..4bd41d8 --- /dev/null +++ b/src/test/resources/gfm/alerts/warning_custom.html @@ -0,0 +1,7 @@ +
+

+ + Attention!!! +

+

Urgent info that needs immediate user attention to avoid problems.

+
\ No newline at end of file From f4366357ab9b63707c3bca4924c505561f5fb4cc Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Mon, 8 Jan 2024 15:22:44 +0100 Subject: [PATCH 02/13] #51 basic tests for all types --- .../gfm/alert/GFMAlertExtension.java | 28 +++++++- .../extension/gfm/alert/GFMAlerts.java | 67 +++++++------------ .../gitbucket/markedj/GFMAlertsTest.java | 18 ++++- .../gfm/alerts/warning_custom_icon.html | 6 ++ ..._custom.html => warning_custom_title.html} | 0 5 files changed, 72 insertions(+), 47 deletions(-) create mode 100644 src/test/resources/gfm/alerts/warning_custom_icon.html rename src/test/resources/gfm/alerts/{warning_custom.html => warning_custom_title.html} (100%) diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java index 54703c6..9d36d1b 100644 --- a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java @@ -39,19 +39,45 @@ public class GFMAlertExtension implements Extension { private static final Rule RULE = new FindFirstRule(EXPRESSION); private final Map titles = new HashMap<>(); + + private final Map icons = new HashMap<>(); + /** + * Creates the extension with default titles and icons. + */ public GFMAlertExtension () { titles.put(GFMAlerts.Alert.TIP, "Tip"); titles.put(GFMAlerts.Alert.NOTE, "Note"); titles.put(GFMAlerts.Alert.IMPORTANT, "Important"); titles.put(GFMAlerts.Alert.WARNING, "Warning"); titles.put(GFMAlerts.Alert.CAUTION, "Caution"); + + icons.put(GFMAlerts.Alert.TIP, GFMAlerts.Icons.TIP); + icons.put(GFMAlerts.Alert.NOTE, GFMAlerts.Icons.NOTE); + icons.put(GFMAlerts.Alert.IMPORTANT, GFMAlerts.Icons.IMPORTANT); + icons.put(GFMAlerts.Alert.WARNING, GFMAlerts.Icons.WARNING); + icons.put(GFMAlerts.Alert.CAUTION, GFMAlerts.Icons.CAUTION); } + /** + * Adds the title for an alert. + * + * @param alert + * @param title + */ public void addTitle (final GFMAlerts.Alert alert, final String title ) { titles.put(alert, title); } + /** + * Adds a avg icon for a alert. + * @param alert + * @param icon + */ + public void addIcon (final GFMAlerts.Alert alert, final String icon ) { + icons.put(alert, icon); + } + @Override public LexResult lex(String source, final Lexer.LexerContext context, final TokenConsumer consumer) { List cap = RULE.exec(source); @@ -102,7 +128,7 @@ private String render(String message, GFMAlerts.Alert alert) { return String.format("

%s%s

\n%s
", alert.name().toLowerCase(Locale.ENGLISH), - GFMAlerts.alertToSVG(alert), + icons.get(alert), titles.get(alert), message ); diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java index 43d389b..a84a535 100644 --- a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java @@ -20,53 +20,32 @@ * @author t.marx */ public class GFMAlerts { - public static String exceptGivenNotificationClass(String notificationClassCharacter) { - switch (notificationClassCharacter) { - case "": - return "[xv!]"; - case "x": - return "[v!]?"; - case "v": - return "[x!]?"; - case "!": - return "[xv]?"; - } - throw new IllegalArgumentException("unknown character [" + notificationClassCharacter+ "] to define a notification charcater class"); - } - - public enum Alert { - NOTE, TIP, IMPORTANT, WARNING, CAUTION; - - public static Alert fromString(String s) { - switch (s) { - case "TIP": - return Alert.TIP; - case "IMPORTANT": - return Alert.IMPORTANT; + + public static class Icons { + + public static final String NOTE = ""; + public static final String TIP = ""; + public static final String CAUTION = ""; + public static final String IMPORTANT = ""; + public static final String WARNING = ""; + } + + public enum Alert { + NOTE, TIP, IMPORTANT, WARNING, CAUTION; + + public static Alert fromString(String s) { + switch (s) { + case "TIP": + return Alert.TIP; + case "IMPORTANT": + return Alert.IMPORTANT; case "WARNING": - return Alert.WARNING; + return Alert.WARNING; case "CAUTION": return Alert.CAUTION; - default: - return Alert.NOTE; - } - } - } - - public static String alertToSVG (GFMAlerts.Alert alert) { - switch (alert) { - case NOTE: - return ""; - case TIP: - return ""; - case CAUTION: - return ""; - case IMPORTANT: - return ""; - case WARNING: - return ""; - default: - throw new IllegalArgumentException("unknown alert"); + default: + return Alert.NOTE; + } } } } diff --git a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java index 82fec84..80366f0 100644 --- a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java +++ b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java @@ -75,7 +75,7 @@ public void testWarningAlert() throws Exception { } @Test - public void testWithCustomTitles() throws Exception { + public void testWithCustomTitle() throws Exception { String md = loadResourceAsString("gfm/alerts/warning.md"); Options options = new Options(); @@ -84,7 +84,21 @@ public void testWithCustomTitles() throws Exception { options.addExtension(gfmAlertExtension); String result = Marked.marked(md, options); - String expect = loadResourceAsString("gfm/alerts/warning_custom.html"); + String expect = loadResourceAsString("gfm/alerts/warning_custom_title.html"); + Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); + } + + @Test + public void testWithCustomIcon() throws Exception { + String md = loadResourceAsString("gfm/alerts/warning.md"); + + Options options = new Options(); + final GFMAlertExtension gfmAlertExtension = new GFMAlertExtension(); + gfmAlertExtension.addIcon(GFMAlerts.Alert.WARNING, ""); + options.addExtension(gfmAlertExtension); + + String result = Marked.marked(md, options); + String expect = loadResourceAsString("gfm/alerts/warning_custom_icon.html"); Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); } } diff --git a/src/test/resources/gfm/alerts/warning_custom_icon.html b/src/test/resources/gfm/alerts/warning_custom_icon.html new file mode 100644 index 0000000..0ef45df --- /dev/null +++ b/src/test/resources/gfm/alerts/warning_custom_icon.html @@ -0,0 +1,6 @@ +
+

+ Warning +

+

Urgent info that needs immediate user attention to avoid problems.

+
\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/warning_custom.html b/src/test/resources/gfm/alerts/warning_custom_title.html similarity index 100% rename from src/test/resources/gfm/alerts/warning_custom.html rename to src/test/resources/gfm/alerts/warning_custom_title.html From a413d7a541093700a996940c9bbfb690f5f04363 Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Tue, 9 Jan 2024 09:18:16 +0100 Subject: [PATCH 03/13] #51 add test for multiple elements --- .../extension/gfm/alert/GFMAlertExtension.java | 2 +- .../io/github/gitbucket/markedj/GFMAlertsTest.java | 13 +++++++++++++ .../gfm/alerts/testWithParagraphBeforeAndAfter.html | 9 +++++++++ .../gfm/alerts/testWithParagraphBeforeAndAfter.md | 7 +++++++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.html create mode 100644 src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.md diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java index 9d36d1b..3ba7acd 100644 --- a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java @@ -34,7 +34,7 @@ */ public class GFMAlertExtension implements Extension { - public static String EXPRESSION = "(?s)(?m)^> \\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\](.+?)(^\n|\\Z)"; + public static String EXPRESSION = "(?s)(?m)\\A^> \\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\](.+?)(^\n|\\Z)"; private static final Rule RULE = new FindFirstRule(EXPRESSION); diff --git a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java index 80366f0..414f4f8 100644 --- a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java +++ b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java @@ -101,4 +101,17 @@ public void testWithCustomIcon() throws Exception { String expect = loadResourceAsString("gfm/alerts/warning_custom_icon.html"); Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); } + + @Test + public void testWithParagraphBeforeAndAfter() throws Exception { + String md = loadResourceAsString("gfm/alerts/testWithParagraphBeforeAndAfter.md"); + + Options options = new Options(); + final GFMAlertExtension gfmAlertExtension = new GFMAlertExtension(); + options.addExtension(gfmAlertExtension); + + String result = Marked.marked(md, options); + String expect = loadResourceAsString("gfm/alerts/testWithParagraphBeforeAndAfter.html"); + Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); + } } diff --git a/src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.html b/src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.html new file mode 100644 index 0000000..d21d95c --- /dev/null +++ b/src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.html @@ -0,0 +1,9 @@ +

A simple paragraph before.

+
+

+ + Note +

+

Useful information that users should know, even when skimming content.

+
+

Another paragraph after.

\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.md b/src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.md new file mode 100644 index 0000000..9b2a11b --- /dev/null +++ b/src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.md @@ -0,0 +1,7 @@ +A simple paragraph before. + +> [!NOTE] +> Useful information that users should know, +> even when skimming content. + +Another paragraph after. \ No newline at end of file From 165694585d7a8e6aee1aae5dfb0d44b81426c240 Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Tue, 9 Jan 2024 09:22:55 +0100 Subject: [PATCH 04/13] #51 add test for multiple elements --- .../io/github/gitbucket/markedj/GFMAlertsTest.java | 13 +++++++++++++ .../gfm/alerts/testWithMultipleAlerts.html | 14 ++++++++++++++ .../resources/gfm/alerts/testWithMultipleAlerts.md | 6 ++++++ 3 files changed, 33 insertions(+) create mode 100644 src/test/resources/gfm/alerts/testWithMultipleAlerts.html create mode 100644 src/test/resources/gfm/alerts/testWithMultipleAlerts.md diff --git a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java index 414f4f8..2d438f8 100644 --- a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java +++ b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java @@ -114,4 +114,17 @@ public void testWithParagraphBeforeAndAfter() throws Exception { String expect = loadResourceAsString("gfm/alerts/testWithParagraphBeforeAndAfter.html"); Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); } + + @Test + public void testWithMultipleAlerts() throws Exception { + String md = loadResourceAsString("gfm/alerts/testWithMultipleAlerts.md"); + + Options options = new Options(); + final GFMAlertExtension gfmAlertExtension = new GFMAlertExtension(); + options.addExtension(gfmAlertExtension); + + String result = Marked.marked(md, options); + String expect = loadResourceAsString("gfm/alerts/testWithMultipleAlerts.html"); + Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); + } } diff --git a/src/test/resources/gfm/alerts/testWithMultipleAlerts.html b/src/test/resources/gfm/alerts/testWithMultipleAlerts.html new file mode 100644 index 0000000..3359d85 --- /dev/null +++ b/src/test/resources/gfm/alerts/testWithMultipleAlerts.html @@ -0,0 +1,14 @@ +
+

+ Note

+

Useful information that users should know, even when skimming content.

+
+
+

+ Tip

+

A tip!

+
\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/testWithMultipleAlerts.md b/src/test/resources/gfm/alerts/testWithMultipleAlerts.md new file mode 100644 index 0000000..514ab4b --- /dev/null +++ b/src/test/resources/gfm/alerts/testWithMultipleAlerts.md @@ -0,0 +1,6 @@ +> [!NOTE] +> Useful information that users should know, +> even when skimming content. + +> [!TIP] +> A tip! \ No newline at end of file From 1d239b959e483ad1b2acdcfb5e917dc32888038c Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Tue, 9 Jan 2024 10:17:35 +0100 Subject: [PATCH 05/13] #51 update readme --- README.md | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/README.md b/README.md index 413ef60..27f4335 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,70 @@ String html = Marked.marked("! This is an info message", options); // =>

This is an info message

``` +### GFMAlert extension + +Support for github like [alerts](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts). + +#### Usage + +```java +Options options = new Options(); +GFMAlertExtension gfmAlerts = new GFMAlertExtension(); +// Override default title for note alert +gfmAlerts.addTitle(GFMAlerts.Alert.NOTE, "Notice"); +// Override default icon for note alert +gfmAlerts.setIcon(GFMAlerts.Alert.NOTE, ""); +options.addExtension(gfmAlerts); +String html = Marked.marked("> [!NOTE]\n>", options); +``` + +#### Support alert types + +**Note** +```markdown +> [!NOTE] +> Useful information that users should know, even when skimming content. +``` +**Note HTML** +> [!NOTE] +> Useful information that users should know, even when skimming content. + +**Tip** +```markdown +> [!TIP] +> Helpful advice for doing things better or more easily. +``` +**Note HTML** +> [!TIP] +> Helpful advice for doing things better or more easily. + +**Important** +```markdown +> [!IMPORTANT] +> Key information users need to know to achieve their goal. +``` +**Important HTML** +> [!IMPORTANT] +> Key information users need to know to achieve their goal. + +**Warning** +```markdown +> [!WARNING] +> Urgent info that needs immediate user attention to avoid problems. +``` +**Warning HTML** +> [!WARNING] +> Urgent info that needs immediate user attention to avoid problems. + +**Caution** +```markdown +> [!CAUTION] +> Advises about risks or negative outcomes of certain actions. +``` +**Caution HTML** +> [!CAUTION] +> Advises about risks or negative outcomes of certain actions. + ### Notification extension The notification extension helps you to add information messages to your markdown content. From 2090c4c10f7dfaa7dc9f5869d4d173c1473e365b Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Tue, 9 Jan 2024 10:26:20 +0100 Subject: [PATCH 06/13] #51 update readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 27f4335..e82655a 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,8 @@ String html = Marked.marked("! This is an info message", options); Support for github like [alerts](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts). +For styling, some project-specific CSS is required. SVG icons are embedded but can be replaced by configuration. + #### Usage ```java @@ -89,7 +91,7 @@ options.addExtension(gfmAlerts); String html = Marked.marked("> [!NOTE]\n>", options); ``` -#### Support alert types +#### Supported alert types **Note** ```markdown From 4ec3c337b5e788c8b81ceae2b44a45bae02dbc65 Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Tue, 9 Jan 2024 10:29:52 +0100 Subject: [PATCH 07/13] #51 remove unsupported java language feature --- .../markedj/extension/gfm/alert/GFMAlertExtension.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java index 3ba7acd..dc21804 100644 --- a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java @@ -123,7 +123,7 @@ public String parse(Parser.ParserContext context, Function")) { - message = "

%s

".formatted(message); + message = String.format("

%s

", message); } return String.format("

%s%s

\n%s
", From 08ee167e6bd901ce5287f03e7f9a8f8b66f90d54 Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Wed, 10 Jan 2024 08:15:11 +0100 Subject: [PATCH 08/13] #51 remove old notification extension --- README.md | 65 +----------- .../notification/NotificationEndToken.java | 29 ------ .../notification/NotificationExtension.java | 98 ------------------- .../notification/NotificationStartToken.java | 41 -------- .../extension/notification/Notifications.java | 53 ---------- .../gitbucket/markedj/NotificationsTest.java | 88 ----------------- 6 files changed, 3 insertions(+), 371 deletions(-) delete mode 100644 src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationEndToken.java delete mode 100644 src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationExtension.java delete mode 100644 src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationStartToken.java delete mode 100644 src/main/java/io/github/gitbucket/markedj/extension/notification/Notifications.java delete mode 100644 src/test/java/io/github/gitbucket/markedj/NotificationsTest.java diff --git a/README.md b/README.md index e82655a..b08a2b5 100644 --- a/README.md +++ b/README.md @@ -67,9 +67,8 @@ Extensions can be used by adding them to the options. ```java Options options = new Options(); -options.addExtension(new NotificationExtension()); -String html = Marked.marked("! This is an info message", options); - // =>

This is an info message

+options.addExtension(new GFMAlertExtension()); +String html = Marked.marked("> [!NOTE]\n> This is a note!", options); ``` ### GFMAlert extension @@ -88,7 +87,7 @@ gfmAlerts.addTitle(GFMAlerts.Alert.NOTE, "Notice"); // Override default icon for note alert gfmAlerts.setIcon(GFMAlerts.Alert.NOTE, ""); options.addExtension(gfmAlerts); -String html = Marked.marked("> [!NOTE]\n>", options); +String html = Marked.marked("> [!NOTE]\n> This is a note!", options); ``` #### Supported alert types @@ -138,64 +137,6 @@ String html = Marked.marked("> [!NOTE]\n>", options); > [!CAUTION] > Advises about risks or negative outcomes of certain actions. -### Notification extension - -The notification extension helps you to add information messages to your markdown content. -Keep in mind, you still need the CSS to style the messages as desired. - -#### Info message -```text -! This is an info message -``` -```html -
-

This is an info message

-
-``` - -#### Success message -```text -!v This is a success message -``` -```html -
-

This is a success message

-
-``` - -#### Warning message -```text -!! This is a warning message -``` -```html -
-

This is a warning message

-
-``` - -#### Error message -```text -!x This is an error message -``` -```html -
-

This is an error message

-
-``` - -#### Multiline notifications -Notifications can span multiple lines. - -```text -! This is an info message -! That spans over several lines -``` -```html -
-

This is an info message -That spans over several lines

-
-``` ## for Developers diff --git a/src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationEndToken.java b/src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationEndToken.java deleted file mode 100644 index c3e8c8f..0000000 --- a/src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationEndToken.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2023 GitBucket. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.gitbucket.markedj.extension.notification; - -import io.github.gitbucket.markedj.token.Token; - -/** - * - * @author t.marx - */ -public class NotificationEndToken implements Token { - @Override - public String getType() { - return "NotificationEndToken"; - } -} diff --git a/src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationExtension.java b/src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationExtension.java deleted file mode 100644 index de322c4..0000000 --- a/src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationExtension.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2023 GitBucket. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.gitbucket.markedj.extension.notification; - -import io.github.gitbucket.markedj.Lexer; -import io.github.gitbucket.markedj.Parser; -import io.github.gitbucket.markedj.extension.Extension; -import io.github.gitbucket.markedj.extension.TokenConsumer; -import io.github.gitbucket.markedj.rule.FindFirstRule; -import io.github.gitbucket.markedj.rule.Rule; -import io.github.gitbucket.markedj.token.Token; -import java.util.List; -import java.util.Locale; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * - * @author t.marx - */ -public class NotificationExtension implements Extension { - - public static String BLOCK_NOTIFICATION = "^((?:(!([xv!]?))[^\n]*(?!^!)\n?)+)"; - - private Rule notificationRule() { - return new FindFirstRule(BLOCK_NOTIFICATION); - } - - @Override - public LexResult lex(String source, final Lexer.LexerContext context, final TokenConsumer consumer) { - List cap = notificationRule().exec(source); - boolean tokenFound = false; - if (!cap.isEmpty()) { - // we have detected several contiguous lines of notifications - // ensure that all are of same kind - String allNotificationsLines = cap.get(0); - - // if other kind of notifications lines are detected - // let's split them so that they are handled separately - String findOtherLinesPattern = "(?m)^(!" + Notifications.exceptGivenNotificationClass(cap.get(3)) + " .*)"; - Matcher otherLinesMatcher = Pattern.compile(findOtherLinesPattern).matcher(cap.get(1)); - - if (otherLinesMatcher.find()) { - String otherLinesSeparated = otherLinesMatcher.replaceAll("\n$1\n"); - - // change the source to parse - // replace all the notifications lines with separated notifications lines - // and reparse the string - source = otherLinesSeparated + source.substring(allNotificationsLines.length()); - } else { - source = source.substring(allNotificationsLines.length()); - context.pushToken(new NotificationStartToken(cap.get(3))); - consumer.token(allNotificationsLines.replaceAll("(?m)^" + cap.get(2) + "[ ]?", ""), false, false, context); - context.pushToken(new NotificationEndToken()); - } - - tokenFound = true; - } - return new LexResult(source, tokenFound); - } - - @Override - public boolean handlesToken(String token) { - return NotificationStartToken.TYPE.equals(token); - } - - @Override - public String parse(Parser.ParserContext context, Function tok) { - NotificationStartToken t = (NotificationStartToken) context.currentToken(); - StringBuilder body = new StringBuilder(); - while (true) { - Token n = context.nextToken(); - if (n == null || n.getType().equals("NotificationEndToken")) { - break; - } - body.append(tok.apply(context)); - } - return render(body.toString(), t.getNotification()); - } - - private String render(String info, Notifications.Notification notification) { - return String.format("
\n%s
\n", notification.name().toLowerCase(Locale.ENGLISH), info); - } -} diff --git a/src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationStartToken.java b/src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationStartToken.java deleted file mode 100644 index bc8be7f..0000000 --- a/src/main/java/io/github/gitbucket/markedj/extension/notification/NotificationStartToken.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2023 GitBucket. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.gitbucket.markedj.extension.notification; - -import io.github.gitbucket.markedj.token.Token; - -/** - * - * @author t.marx - */ -public class NotificationStartToken implements Token { - protected static String TYPE = "NotificationStartToken"; - - private Notifications.Notification notification; - - public NotificationStartToken(String type) { - this.notification = Notifications.Notification.fromString(type); - } - - @Override - public String getType() { - return TYPE; - } - - public Notifications.Notification getNotification() { - return notification; - } -} diff --git a/src/main/java/io/github/gitbucket/markedj/extension/notification/Notifications.java b/src/main/java/io/github/gitbucket/markedj/extension/notification/Notifications.java deleted file mode 100644 index f1fbedf..0000000 --- a/src/main/java/io/github/gitbucket/markedj/extension/notification/Notifications.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2023 GitBucket. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.github.gitbucket.markedj.extension.notification; - -/** - * - * @author t.marx - */ -public class Notifications { - public static String exceptGivenNotificationClass(String notificationClassCharacter) { - switch (notificationClassCharacter) { - case "": - return "[xv!]"; - case "x": - return "[v!]?"; - case "v": - return "[x!]?"; - case "!": - return "[xv]?"; - } - throw new IllegalArgumentException("unknown character [" + notificationClassCharacter+ "] to define a notification charcater class"); - } - - public enum Notification { - INFO, SUCCESS, WARNING, ERROR; - - public static Notification fromString(String s) { - switch (s) { - case "x": - return Notification.ERROR; - case "!": - return Notification.WARNING; - case "v": - return Notification.SUCCESS; - default: - return Notification.INFO; - } - } - } -} diff --git a/src/test/java/io/github/gitbucket/markedj/NotificationsTest.java b/src/test/java/io/github/gitbucket/markedj/NotificationsTest.java deleted file mode 100644 index 8223fd7..0000000 --- a/src/test/java/io/github/gitbucket/markedj/NotificationsTest.java +++ /dev/null @@ -1,88 +0,0 @@ -package io.github.gitbucket.markedj; - -import static io.github.gitbucket.markedj.Resources.loadResourceAsString; -import io.github.gitbucket.markedj.extension.notification.NotificationExtension; -import org.assertj.core.api.Assertions; - -import org.junit.Test; - -public class NotificationsTest { - - private Options createOptions () { - Options options = new Options(); - options.addExtension(new NotificationExtension()); - return options; - } - - @Test - public void testInfoNotification() throws Exception { - String md = loadResourceAsString("notifications/info.md"); - String result = Marked.marked(md, createOptions()); - String expect = loadResourceAsString("notifications/info.html"); - Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); - } - - @Test - public void testSuccessNotification() throws Exception { - String md = loadResourceAsString("notifications/success.md"); - String result = Marked.marked(md, createOptions()); - String expect = loadResourceAsString("notifications/success.html"); - Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); - } - - @Test - public void testWarningNotification() throws Exception { - String md = loadResourceAsString("notifications/warning.md"); - String result = Marked.marked(md, createOptions()); - String expect = loadResourceAsString("notifications/warning.html"); - Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); - } - - @Test - public void testErrorNotification() throws Exception { - String md = loadResourceAsString("notifications/error.md"); - String result = Marked.marked(md, createOptions()); - String expect = loadResourceAsString("notifications/error.html"); - Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); - } - - @Test - public void testMultipleNotifications1() throws Exception { - String md = loadResourceAsString("notifications/multiple_notifications_1.md"); - String result = Marked.marked(md, createOptions()); - String expect = loadResourceAsString("notifications/multiple_notifications_1.html"); - Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); - } - - @Test - public void testMultipleNotifications2() throws Exception { - String md = loadResourceAsString("notifications/multiple_notifications_2.md"); - String result = Marked.marked(md, createOptions()); - String expect = loadResourceAsString("notifications/multiple_notifications_2.html"); - Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); - } - - @Test - public void testMultipleNotifications3() throws Exception { - String md = loadResourceAsString("notifications/multiple_notifications_3.md"); - String result = Marked.marked(md, createOptions()); - String expect = loadResourceAsString("notifications/multiple_notifications_3.html"); - Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); - } - - @Test - public void testMultipleNotificationsWithTypeChange() throws Exception { - String md = loadResourceAsString("notifications/multiple_notifications_type_change.md"); - String result = Marked.marked(md, createOptions()); - String expect = loadResourceAsString("notifications/multiple_notifications_type_change.html"); - Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); - } - - @Test - public void testEmbeddedNotifications() throws Exception { - String md = loadResourceAsString("notifications/embedded_notifications.md"); - String result = Marked.marked(md, createOptions()); - String expect = loadResourceAsString("notifications/embedded_notifications.html"); - Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); - } -} From e42dc1496b6f5317b992b45ab33d2d044261da18 Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Mon, 22 Jan 2024 11:14:45 +0100 Subject: [PATCH 09/13] remove markup and add renderer to allow custom markup --- README.md | 34 ++++++++++------ .../gfm/alert/DefaultGFMAlertRenderer.java | 40 +++++++++++++++++++ .../gfm/alert/GFMAlertExtension.java | 32 +++------------ .../extension/gfm/alert/GFMAlertRenderer.java | 26 ++++++++++++ .../extension/gfm/alert/GFMAlerts.java | 9 ----- .../gitbucket/markedj/GFMAlertsTest.java | 13 ++++-- src/test/resources/gfm/alerts/caution.html | 5 +-- src/test/resources/gfm/alerts/important.html | 5 +-- src/test/resources/gfm/alerts/note.html | 5 +-- .../gfm/alerts/testWithMultipleAlerts.html | 10 +---- .../testWithParagraphBeforeAndAfter.html | 5 +-- src/test/resources/gfm/alerts/tip.html | 5 +-- src/test/resources/gfm/alerts/warning.html | 5 +-- .../gfm/alerts/warning_custom_icon.html | 6 --- .../gfm/alerts/warning_custom_renderer.html | 4 ++ .../gfm/alerts/warning_custom_title.html | 5 +-- .../notifications/embedded_notifications.html | 8 ---- .../notifications/embedded_notifications.md | 6 --- src/test/resources/notifications/error.html | 4 -- src/test/resources/notifications/error.md | 2 - src/test/resources/notifications/info.html | 4 -- src/test/resources/notifications/info.md | 2 - .../multiple_notifications_1.html | 9 ----- .../notifications/multiple_notifications_1.md | 5 --- .../multiple_notifications_2.html | 5 --- .../notifications/multiple_notifications_2.md | 4 -- .../multiple_notifications_3.html | 5 --- .../notifications/multiple_notifications_3.md | 5 --- .../multiple_notifications_type_change.html | 11 ----- .../multiple_notifications_type_change.md | 6 --- src/test/resources/notifications/success.html | 4 -- src/test/resources/notifications/success.md | 2 - src/test/resources/notifications/warning.html | 4 -- src/test/resources/notifications/warning.md | 2 - 34 files changed, 117 insertions(+), 180 deletions(-) create mode 100644 src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/DefaultGFMAlertRenderer.java create mode 100644 src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertRenderer.java delete mode 100644 src/test/resources/gfm/alerts/warning_custom_icon.html create mode 100644 src/test/resources/gfm/alerts/warning_custom_renderer.html delete mode 100644 src/test/resources/notifications/embedded_notifications.html delete mode 100644 src/test/resources/notifications/embedded_notifications.md delete mode 100644 src/test/resources/notifications/error.html delete mode 100644 src/test/resources/notifications/error.md delete mode 100644 src/test/resources/notifications/info.html delete mode 100644 src/test/resources/notifications/info.md delete mode 100644 src/test/resources/notifications/multiple_notifications_1.html delete mode 100644 src/test/resources/notifications/multiple_notifications_1.md delete mode 100644 src/test/resources/notifications/multiple_notifications_2.html delete mode 100644 src/test/resources/notifications/multiple_notifications_2.md delete mode 100644 src/test/resources/notifications/multiple_notifications_3.html delete mode 100644 src/test/resources/notifications/multiple_notifications_3.md delete mode 100644 src/test/resources/notifications/multiple_notifications_type_change.html delete mode 100644 src/test/resources/notifications/multiple_notifications_type_change.md delete mode 100644 src/test/resources/notifications/success.html delete mode 100644 src/test/resources/notifications/success.md delete mode 100644 src/test/resources/notifications/warning.html delete mode 100644 src/test/resources/notifications/warning.md diff --git a/README.md b/README.md index b08a2b5..815025e 100644 --- a/README.md +++ b/README.md @@ -84,8 +84,6 @@ Options options = new Options(); GFMAlertExtension gfmAlerts = new GFMAlertExtension(); // Override default title for note alert gfmAlerts.addTitle(GFMAlerts.Alert.NOTE, "Notice"); -// Override default icon for note alert -gfmAlerts.setIcon(GFMAlerts.Alert.NOTE, ""); options.addExtension(gfmAlerts); String html = Marked.marked("> [!NOTE]\n> This is a note!", options); ``` @@ -98,8 +96,12 @@ String html = Marked.marked("> [!NOTE]\n> This is a note!", options); > Useful information that users should know, even when skimming content. ``` **Note HTML** -> [!NOTE] -> Useful information that users should know, even when skimming content. +```html +
+

Note

+

Useful information that users should know, even when skimming content.

+
+``` **Tip** ```markdown @@ -107,8 +109,10 @@ String html = Marked.marked("> [!NOTE]\n> This is a note!", options); > Helpful advice for doing things better or more easily. ``` **Note HTML** -> [!TIP] -> Helpful advice for doing things better or more easily. +
+

Tip

+

Helpful advice for doing things better or more easily.

+
**Important** ```markdown @@ -116,8 +120,10 @@ String html = Marked.marked("> [!NOTE]\n> This is a note!", options); > Key information users need to know to achieve their goal. ``` **Important HTML** -> [!IMPORTANT] -> Key information users need to know to achieve their goal. +
+

Important

+

Key information users need to know to achieve their goal.

+
**Warning** ```markdown @@ -125,8 +131,10 @@ String html = Marked.marked("> [!NOTE]\n> This is a note!", options); > Urgent info that needs immediate user attention to avoid problems. ``` **Warning HTML** -> [!WARNING] -> Urgent info that needs immediate user attention to avoid problems. +
+

Warning

+

Urgent info that needs immediate user attention to avoid problems.

+
**Caution** ```markdown @@ -134,8 +142,10 @@ String html = Marked.marked("> [!NOTE]\n> This is a note!", options); > Advises about risks or negative outcomes of certain actions. ``` **Caution HTML** -> [!CAUTION] -> Advises about risks or negative outcomes of certain actions. +
+

Caution

+

Advises about risks or negative outcomes of certain actions.

+
## for Developers diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/DefaultGFMAlertRenderer.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/DefaultGFMAlertRenderer.java new file mode 100644 index 0000000..fbc064a --- /dev/null +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/DefaultGFMAlertRenderer.java @@ -0,0 +1,40 @@ +/* + * Copyright 2024 GitBucket. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.gitbucket.markedj.extension.gfm.alert; + +import java.util.Locale; +import java.util.Map; + +/** + * + * @author t.marx + */ +public class DefaultGFMAlertRenderer implements GFMAlertRenderer { + + @Override + public String render(Map titles, String message, GFMAlerts.Alert alert) { + if (!message.startsWith("

")) { + message = String.format("

%s

", message); + } + + return String.format("

%s

\n%s
", + alert.name().toLowerCase(Locale.ENGLISH), + titles.get(alert), + message + ); + } + +} diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java index dc21804..5089c62 100644 --- a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java @@ -40,7 +40,7 @@ public class GFMAlertExtension implements Extension { private final Map titles = new HashMap<>(); - private final Map icons = new HashMap<>(); + private GFMAlertRenderer renderer = new DefaultGFMAlertRenderer(); /** * Creates the extension with default titles and icons. @@ -51,12 +51,10 @@ public GFMAlertExtension () { titles.put(GFMAlerts.Alert.IMPORTANT, "Important"); titles.put(GFMAlerts.Alert.WARNING, "Warning"); titles.put(GFMAlerts.Alert.CAUTION, "Caution"); - - icons.put(GFMAlerts.Alert.TIP, GFMAlerts.Icons.TIP); - icons.put(GFMAlerts.Alert.NOTE, GFMAlerts.Icons.NOTE); - icons.put(GFMAlerts.Alert.IMPORTANT, GFMAlerts.Icons.IMPORTANT); - icons.put(GFMAlerts.Alert.WARNING, GFMAlerts.Icons.WARNING); - icons.put(GFMAlerts.Alert.CAUTION, GFMAlerts.Icons.CAUTION); + } + + public void setRenderer (GFMAlertRenderer renderer) { + this.renderer = renderer; } /** @@ -69,14 +67,6 @@ public void addTitle (final GFMAlerts.Alert alert, final String title ) { titles.put(alert, title); } - /** - * Adds a avg icon for a alert. - * @param alert - * @param icon - */ - public void addIcon (final GFMAlerts.Alert alert, final String icon ) { - icons.put(alert, icon); - } @Override public LexResult lex(String source, final Lexer.LexerContext context, final TokenConsumer consumer) { @@ -121,16 +111,6 @@ public String parse(Parser.ParserContext context, Function")) { - message = String.format("

%s

", message); - } - - return String.format("

%s%s

\n%s
", - alert.name().toLowerCase(Locale.ENGLISH), - icons.get(alert), - titles.get(alert), - message - ); + return renderer.render(titles, message, alert); } } diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertRenderer.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertRenderer.java new file mode 100644 index 0000000..0049453 --- /dev/null +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertRenderer.java @@ -0,0 +1,26 @@ +/* + * Copyright 2024 GitBucket. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.gitbucket.markedj.extension.gfm.alert; + +import java.util.Map; + +/** + * + * @author t.marx + */ +public interface GFMAlertRenderer { + String render (final Map titles, final String message, GFMAlerts.Alert alert); +} diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java index a84a535..b5408f3 100644 --- a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlerts.java @@ -21,15 +21,6 @@ */ public class GFMAlerts { - public static class Icons { - - public static final String NOTE = ""; - public static final String TIP = ""; - public static final String CAUTION = ""; - public static final String IMPORTANT = ""; - public static final String WARNING = ""; - } - public enum Alert { NOTE, TIP, IMPORTANT, WARNING, CAUTION; diff --git a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java index 2d438f8..ac9735c 100644 --- a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java +++ b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java @@ -18,6 +18,7 @@ import static io.github.gitbucket.markedj.Resources.loadResourceAsString; import io.github.gitbucket.markedj.extension.gfm.alert.GFMAlertExtension; import io.github.gitbucket.markedj.extension.gfm.alert.GFMAlerts; +import java.util.Locale; import org.assertj.core.api.Assertions; import org.junit.Test; @@ -89,16 +90,22 @@ public void testWithCustomTitle() throws Exception { } @Test - public void testWithCustomIcon() throws Exception { + public void testWithCustomRenderer() throws Exception { String md = loadResourceAsString("gfm/alerts/warning.md"); Options options = new Options(); final GFMAlertExtension gfmAlertExtension = new GFMAlertExtension(); - gfmAlertExtension.addIcon(GFMAlerts.Alert.WARNING, ""); + gfmAlertExtension.setRenderer((titles, message, alert) -> { + return String.format("

%s

\n%s
", + alert.name().toLowerCase(Locale.ENGLISH), + titles.get(alert), + message + ); + }); options.addExtension(gfmAlertExtension); String result = Marked.marked(md, options); - String expect = loadResourceAsString("gfm/alerts/warning_custom_icon.html"); + String expect = loadResourceAsString("gfm/alerts/warning_custom_renderer.html"); Assertions.assertThat(result).isEqualToIgnoringWhitespace(expect); } diff --git a/src/test/resources/gfm/alerts/caution.html b/src/test/resources/gfm/alerts/caution.html index 85c9cdc..8df52ee 100644 --- a/src/test/resources/gfm/alerts/caution.html +++ b/src/test/resources/gfm/alerts/caution.html @@ -1,7 +1,4 @@
-

- - Caution -

+

Caution

Advises about risks or negative outcomes of certain actions.

\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/important.html b/src/test/resources/gfm/alerts/important.html index 8416ebd..96f6d83 100644 --- a/src/test/resources/gfm/alerts/important.html +++ b/src/test/resources/gfm/alerts/important.html @@ -1,7 +1,4 @@
-

- - Important -

+

Important

Key information users need to know to achieve their goal.

\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/note.html b/src/test/resources/gfm/alerts/note.html index 7182779..9a0614e 100644 --- a/src/test/resources/gfm/alerts/note.html +++ b/src/test/resources/gfm/alerts/note.html @@ -1,7 +1,4 @@
-

- - Note -

+

Note

Useful information that users should know, even when skimming content.

\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/testWithMultipleAlerts.html b/src/test/resources/gfm/alerts/testWithMultipleAlerts.html index 3359d85..16f7b0e 100644 --- a/src/test/resources/gfm/alerts/testWithMultipleAlerts.html +++ b/src/test/resources/gfm/alerts/testWithMultipleAlerts.html @@ -1,14 +1,8 @@
-

- Note

+

Note

Useful information that users should know, even when skimming content.

-

- Tip

+

Tip

A tip!

\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.html b/src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.html index d21d95c..8c522a0 100644 --- a/src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.html +++ b/src/test/resources/gfm/alerts/testWithParagraphBeforeAndAfter.html @@ -1,9 +1,6 @@

A simple paragraph before.

-

- - Note -

+

Note

Useful information that users should know, even when skimming content.

Another paragraph after.

\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/tip.html b/src/test/resources/gfm/alerts/tip.html index 6c5fbc8..509561f 100644 --- a/src/test/resources/gfm/alerts/tip.html +++ b/src/test/resources/gfm/alerts/tip.html @@ -1,7 +1,4 @@
-

- - Tip -

+

Tip

Helpful advice for doing things better or more easily.

\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/warning.html b/src/test/resources/gfm/alerts/warning.html index f1df732..9921bfd 100644 --- a/src/test/resources/gfm/alerts/warning.html +++ b/src/test/resources/gfm/alerts/warning.html @@ -1,7 +1,4 @@
-

- - Warning -

+

Warning

Urgent info that needs immediate user attention to avoid problems.

\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/warning_custom_icon.html b/src/test/resources/gfm/alerts/warning_custom_icon.html deleted file mode 100644 index 0ef45df..0000000 --- a/src/test/resources/gfm/alerts/warning_custom_icon.html +++ /dev/null @@ -1,6 +0,0 @@ -
-

- Warning -

-

Urgent info that needs immediate user attention to avoid problems.

-
\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/warning_custom_renderer.html b/src/test/resources/gfm/alerts/warning_custom_renderer.html new file mode 100644 index 0000000..0863eab --- /dev/null +++ b/src/test/resources/gfm/alerts/warning_custom_renderer.html @@ -0,0 +1,4 @@ +
+

Warning

+

Urgent info that needs immediate user attention to avoid problems.

+
\ No newline at end of file diff --git a/src/test/resources/gfm/alerts/warning_custom_title.html b/src/test/resources/gfm/alerts/warning_custom_title.html index 4bd41d8..707581c 100644 --- a/src/test/resources/gfm/alerts/warning_custom_title.html +++ b/src/test/resources/gfm/alerts/warning_custom_title.html @@ -1,7 +1,4 @@
-

- - Attention!!! -

+

Attention!!!

Urgent info that needs immediate user attention to avoid problems.

\ No newline at end of file diff --git a/src/test/resources/notifications/embedded_notifications.html b/src/test/resources/notifications/embedded_notifications.html deleted file mode 100644 index 67dacf1..0000000 --- a/src/test/resources/notifications/embedded_notifications.html +++ /dev/null @@ -1,8 +0,0 @@ -
-

Info message. -Written using multiple lines.

-
-

Embedding a warning

-
-

Initial info message continues afterwards.

-
diff --git a/src/test/resources/notifications/embedded_notifications.md b/src/test/resources/notifications/embedded_notifications.md deleted file mode 100644 index c42e29f..0000000 --- a/src/test/resources/notifications/embedded_notifications.md +++ /dev/null @@ -1,6 +0,0 @@ -! Info message. -! Written using multiple lines. -! -! !! Embedding a warning -! -! Initial info message continues afterwards. diff --git a/src/test/resources/notifications/error.html b/src/test/resources/notifications/error.html deleted file mode 100644 index 6dcb069..0000000 --- a/src/test/resources/notifications/error.html +++ /dev/null @@ -1,4 +0,0 @@ -
-

This is an error message -That spans over several lines

-
diff --git a/src/test/resources/notifications/error.md b/src/test/resources/notifications/error.md deleted file mode 100644 index 67d156c..0000000 --- a/src/test/resources/notifications/error.md +++ /dev/null @@ -1,2 +0,0 @@ -!x This is an error message -!x That spans over several lines \ No newline at end of file diff --git a/src/test/resources/notifications/info.html b/src/test/resources/notifications/info.html deleted file mode 100644 index 15ca4e6..0000000 --- a/src/test/resources/notifications/info.html +++ /dev/null @@ -1,4 +0,0 @@ -
-

This is an info message -That spans over several lines

-
diff --git a/src/test/resources/notifications/info.md b/src/test/resources/notifications/info.md deleted file mode 100644 index be22ac8..0000000 --- a/src/test/resources/notifications/info.md +++ /dev/null @@ -1,2 +0,0 @@ -! This is an info message -! That spans over several lines \ No newline at end of file diff --git a/src/test/resources/notifications/multiple_notifications_1.html b/src/test/resources/notifications/multiple_notifications_1.html deleted file mode 100644 index 17f1358..0000000 --- a/src/test/resources/notifications/multiple_notifications_1.html +++ /dev/null @@ -1,9 +0,0 @@ -
-

This is info message 1

-
-
-

This is info message 2

-
-
-

This is info message 3

-
diff --git a/src/test/resources/notifications/multiple_notifications_1.md b/src/test/resources/notifications/multiple_notifications_1.md deleted file mode 100644 index 58017f2..0000000 --- a/src/test/resources/notifications/multiple_notifications_1.md +++ /dev/null @@ -1,5 +0,0 @@ -! This is info message 1 - -! This is info message 2 - -! This is info message 3 diff --git a/src/test/resources/notifications/multiple_notifications_2.html b/src/test/resources/notifications/multiple_notifications_2.html deleted file mode 100644 index 9c82bc6..0000000 --- a/src/test/resources/notifications/multiple_notifications_2.html +++ /dev/null @@ -1,5 +0,0 @@ -
-

This is info message 1 -This is info message 2 -This is info message 3

-
diff --git a/src/test/resources/notifications/multiple_notifications_2.md b/src/test/resources/notifications/multiple_notifications_2.md deleted file mode 100644 index a80f636..0000000 --- a/src/test/resources/notifications/multiple_notifications_2.md +++ /dev/null @@ -1,4 +0,0 @@ -! This is info message 1 -! This is info message 2 -! This is info message 3 - diff --git a/src/test/resources/notifications/multiple_notifications_3.html b/src/test/resources/notifications/multiple_notifications_3.html deleted file mode 100644 index e9bc640..0000000 --- a/src/test/resources/notifications/multiple_notifications_3.html +++ /dev/null @@ -1,5 +0,0 @@ -
-

This is info message 1 -This is info message 2

-

This is info message 3

-
diff --git a/src/test/resources/notifications/multiple_notifications_3.md b/src/test/resources/notifications/multiple_notifications_3.md deleted file mode 100644 index f227777..0000000 --- a/src/test/resources/notifications/multiple_notifications_3.md +++ /dev/null @@ -1,5 +0,0 @@ -! This is info message 1 -! This is info message 2 -! -! This is info message 3 - diff --git a/src/test/resources/notifications/multiple_notifications_type_change.html b/src/test/resources/notifications/multiple_notifications_type_change.html deleted file mode 100644 index 35e6566..0000000 --- a/src/test/resources/notifications/multiple_notifications_type_change.html +++ /dev/null @@ -1,11 +0,0 @@ -
-

line 1 - line 2

-
-
-

line 3

-
-
-

line 4 - line 5

-
diff --git a/src/test/resources/notifications/multiple_notifications_type_change.md b/src/test/resources/notifications/multiple_notifications_type_change.md deleted file mode 100644 index 11656ba..0000000 --- a/src/test/resources/notifications/multiple_notifications_type_change.md +++ /dev/null @@ -1,6 +0,0 @@ -!x line 1 -!x line 2 - -! line 3 -!x line 4 -!x line 5 diff --git a/src/test/resources/notifications/success.html b/src/test/resources/notifications/success.html deleted file mode 100644 index d297c56..0000000 --- a/src/test/resources/notifications/success.html +++ /dev/null @@ -1,4 +0,0 @@ -
-

This is a success message -That spans over several lines

-
diff --git a/src/test/resources/notifications/success.md b/src/test/resources/notifications/success.md deleted file mode 100644 index f2979c0..0000000 --- a/src/test/resources/notifications/success.md +++ /dev/null @@ -1,2 +0,0 @@ -!v This is a success message -!v That spans over several lines \ No newline at end of file diff --git a/src/test/resources/notifications/warning.html b/src/test/resources/notifications/warning.html deleted file mode 100644 index e0c0bb4..0000000 --- a/src/test/resources/notifications/warning.html +++ /dev/null @@ -1,4 +0,0 @@ -
-

This is a warning message -That spans over several lines

-
diff --git a/src/test/resources/notifications/warning.md b/src/test/resources/notifications/warning.md deleted file mode 100644 index b10aab1..0000000 --- a/src/test/resources/notifications/warning.md +++ /dev/null @@ -1,2 +0,0 @@ -!! This is a warning message -!! That spans over several lines \ No newline at end of file From 05eebbdb4deb0e41596bcc0cce7caec74b51d75a Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Mon, 22 Jan 2024 11:16:19 +0100 Subject: [PATCH 10/13] update readme --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 815025e..fb261c1 100644 --- a/README.md +++ b/README.md @@ -109,10 +109,12 @@ String html = Marked.marked("> [!NOTE]\n> This is a note!", options); > Helpful advice for doing things better or more easily. ``` **Note HTML** +```html

Tip

Helpful advice for doing things better or more easily.

+``` **Important** ```markdown @@ -120,10 +122,12 @@ String html = Marked.marked("> [!NOTE]\n> This is a note!", options); > Key information users need to know to achieve their goal. ``` **Important HTML** +```html

Important

Key information users need to know to achieve their goal.

+``` **Warning** ```markdown @@ -131,10 +135,12 @@ String html = Marked.marked("> [!NOTE]\n> This is a note!", options); > Urgent info that needs immediate user attention to avoid problems. ``` **Warning HTML** +```html

Warning

Urgent info that needs immediate user attention to avoid problems.

+``` **Caution** ```markdown @@ -142,11 +148,12 @@ String html = Marked.marked("> [!NOTE]\n> This is a note!", options); > Advises about risks or negative outcomes of certain actions. ``` **Caution HTML** +```html

Caution

Advises about risks or negative outcomes of certain actions.

- +``` ## for Developers From d13b9354e915fedfa5bac470aeddcc95dd3dd143 Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Mon, 22 Jan 2024 11:18:50 +0100 Subject: [PATCH 11/13] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fb261c1..b702144 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ String html = Marked.marked("> [!NOTE]\n> This is a note!", options); > [!TIP] > Helpful advice for doing things better or more easily. ``` -**Note HTML** +**Tip HTML** ```html

Tip

From a9071ad1350ba7923bb8e28a3bf8ac19f30c2517 Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Wed, 24 Jan 2024 08:44:46 +0100 Subject: [PATCH 12/13] add options to handle custom titles --- .../gfm/alert/DefaultGFMAlertRenderer.java | 5 +- .../gfm/alert/GFMAlertExtension.java | 31 +++++------- .../extension/gfm/alert/GFMAlertOptions.java | 48 +++++++++++++++++++ .../extension/gfm/alert/GFMAlertRenderer.java | 3 +- .../gitbucket/markedj/GFMAlertsTest.java | 12 +++-- 5 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertOptions.java diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/DefaultGFMAlertRenderer.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/DefaultGFMAlertRenderer.java index fbc064a..623b918 100644 --- a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/DefaultGFMAlertRenderer.java +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/DefaultGFMAlertRenderer.java @@ -16,7 +16,6 @@ package io.github.gitbucket.markedj.extension.gfm.alert; import java.util.Locale; -import java.util.Map; /** * @@ -25,14 +24,14 @@ public class DefaultGFMAlertRenderer implements GFMAlertRenderer { @Override - public String render(Map titles, String message, GFMAlerts.Alert alert) { + public String render(GFMAlertOptions options, String message, GFMAlerts.Alert alert) { if (!message.startsWith("

")) { message = String.format("

%s

", message); } return String.format("

%s

\n%s
", alert.name().toLowerCase(Locale.ENGLISH), - titles.get(alert), + options.getTitle(alert), message ); } diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java index 5089c62..d05e80f 100644 --- a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertExtension.java @@ -36,35 +36,26 @@ public class GFMAlertExtension implements Extension { public static String EXPRESSION = "(?s)(?m)\\A^> \\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\](.+?)(^\n|\\Z)"; - private static final Rule RULE = new FindFirstRule(EXPRESSION); - - private final Map titles = new HashMap<>(); + private static final Rule RULE = new FindFirstRule(EXPRESSION); private GFMAlertRenderer renderer = new DefaultGFMAlertRenderer(); + + private GFMAlertOptions options; - /** - * Creates the extension with default titles and icons. - */ public GFMAlertExtension () { - titles.put(GFMAlerts.Alert.TIP, "Tip"); - titles.put(GFMAlerts.Alert.NOTE, "Note"); - titles.put(GFMAlerts.Alert.IMPORTANT, "Important"); - titles.put(GFMAlerts.Alert.WARNING, "Warning"); - titles.put(GFMAlerts.Alert.CAUTION, "Caution"); + this(new GFMAlertOptions()); + } + + public GFMAlertExtension (GFMAlertOptions options) { + this.options = options; } public void setRenderer (GFMAlertRenderer renderer) { this.renderer = renderer; } - /** - * Adds the title for an alert. - * - * @param alert - * @param title - */ - public void addTitle (final GFMAlerts.Alert alert, final String title ) { - titles.put(alert, title); + public void setOptions (GFMAlertOptions options) { + this.options = options; } @@ -111,6 +102,6 @@ public String parse(Parser.ParserContext context, Function titles = new HashMap<>(); + + /** + * Creates the options with default titles. + */ + public GFMAlertOptions () { + titles.put(GFMAlerts.Alert.TIP, "Tip"); + titles.put(GFMAlerts.Alert.NOTE, "Note"); + titles.put(GFMAlerts.Alert.IMPORTANT, "Important"); + titles.put(GFMAlerts.Alert.WARNING, "Warning"); + titles.put(GFMAlerts.Alert.CAUTION, "Caution"); + } + + public String getTitle (GFMAlerts.Alert alert) { + return titles.get(alert); + } + + public void setTitle (GFMAlerts.Alert alert, String title) { + titles.put(alert, title); + } + +} diff --git a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertRenderer.java b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertRenderer.java index 0049453..62da109 100644 --- a/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertRenderer.java +++ b/src/main/java/io/github/gitbucket/markedj/extension/gfm/alert/GFMAlertRenderer.java @@ -15,12 +15,11 @@ */ package io.github.gitbucket.markedj.extension.gfm.alert; -import java.util.Map; /** * * @author t.marx */ public interface GFMAlertRenderer { - String render (final Map titles, final String message, GFMAlerts.Alert alert); + String render (final GFMAlertOptions options, final String message, GFMAlerts.Alert alert); } diff --git a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java index ac9735c..1f3daef 100644 --- a/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java +++ b/src/test/java/io/github/gitbucket/markedj/GFMAlertsTest.java @@ -17,6 +17,7 @@ import static io.github.gitbucket.markedj.Resources.loadResourceAsString; import io.github.gitbucket.markedj.extension.gfm.alert.GFMAlertExtension; +import io.github.gitbucket.markedj.extension.gfm.alert.GFMAlertOptions; import io.github.gitbucket.markedj.extension.gfm.alert.GFMAlerts; import java.util.Locale; import org.assertj.core.api.Assertions; @@ -80,8 +81,11 @@ public void testWithCustomTitle() throws Exception { String md = loadResourceAsString("gfm/alerts/warning.md"); Options options = new Options(); - final GFMAlertExtension gfmAlertExtension = new GFMAlertExtension(); - gfmAlertExtension.addTitle(GFMAlerts.Alert.WARNING, "Attention!!!"); + + + GFMAlertOptions alertOptions = new GFMAlertOptions(); + alertOptions.setTitle(GFMAlerts.Alert.WARNING, "Attention!!!"); + final GFMAlertExtension gfmAlertExtension = new GFMAlertExtension(alertOptions); options.addExtension(gfmAlertExtension); String result = Marked.marked(md, options); @@ -95,10 +99,10 @@ public void testWithCustomRenderer() throws Exception { Options options = new Options(); final GFMAlertExtension gfmAlertExtension = new GFMAlertExtension(); - gfmAlertExtension.setRenderer((titles, message, alert) -> { + gfmAlertExtension.setRenderer((alertOptions, message, alert) -> { return String.format("

%s

\n%s
", alert.name().toLowerCase(Locale.ENGLISH), - titles.get(alert), + alertOptions.getTitle(alert), message ); }); From fc652394a3b79046ec7d69c0a655299bf53d6437 Mon Sep 17 00:00:00 2001 From: Thorsten Marx Date: Wed, 24 Jan 2024 08:46:48 +0100 Subject: [PATCH 13/13] update readme --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b702144..a170c0c 100644 --- a/README.md +++ b/README.md @@ -81,9 +81,10 @@ For styling, some project-specific CSS is required. SVG icons are embedded but c ```java Options options = new Options(); -GFMAlertExtension gfmAlerts = new GFMAlertExtension(); // Override default title for note alert -gfmAlerts.addTitle(GFMAlerts.Alert.NOTE, "Notice"); +GFMAlertOptions alertOptions = new GFMAlertOptions(); +alertOptions.setTitle(GFMAlerts.Alert.WARNING, "Attention!!!"); +GFMAlertExtension gfmAlerts = new GFMAlertExtension(alertOptions); options.addExtension(gfmAlerts); String html = Marked.marked("> [!NOTE]\n> This is a note!", options); ```