Skip to content

Commit 3e9716d

Browse files
committed
feat: Yuml markdown plugin
1 parent 3247c67 commit 3e9716d

File tree

3 files changed

+178
-2
lines changed

3 files changed

+178
-2
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.zeppelin.markdown;
19+
20+
import org.parboiled.support.Var;
21+
22+
import java.util.HashMap;
23+
import java.util.Map;
24+
25+
public class ParamVar<K, V> extends Var<Map<K, V>> {
26+
27+
public ParamVar() {
28+
super(new HashMap<K, V>());
29+
}
30+
31+
public boolean put(K key, V value) {
32+
get().put(key, value);
33+
return true;
34+
}
35+
}

markdown/src/main/java/org/apache/zeppelin/markdown/PegdownParser.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import org.pegdown.PegDownProcessor;
2222
import org.pegdown.plugins.PegDownPlugins;
2323

24-
/** Markdown Parser using pegdown processor. */
24+
/**
25+
* Markdown Parser using pegdown processor.
26+
*/
2527
public class PegdownParser implements MarkdownParser {
2628
private PegDownProcessor processor;
2729

@@ -49,7 +51,9 @@ public String render(String markdownText) {
4951
return html;
5052
}
5153

52-
/** wrap with markdown class div to styling DOM using css. */
54+
/**
55+
* wrap with markdown class div to styling DOM using css.
56+
*/
5357
public static String wrapWithMarkdownClassDiv(String html) {
5458
return new StringBuilder()
5559
.append("<div class=\"markdown-body\">\n")
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.zeppelin.markdown;
19+
20+
import static org.apache.commons.lang3.StringUtils.defaultString;
21+
22+
import org.parboiled.BaseParser;
23+
import org.parboiled.Rule;
24+
import org.parboiled.support.StringBuilderVar;
25+
import org.pegdown.Parser;
26+
import org.pegdown.ast.ExpImageNode;
27+
import org.pegdown.ast.TextNode;
28+
import org.pegdown.plugins.BlockPluginParser;
29+
import org.pegdown.plugins.PegDownPlugins;
30+
31+
import java.io.UnsupportedEncodingException;
32+
import java.net.URLEncoder;
33+
import java.util.Map;
34+
35+
public class PegdownYumlPlugin extends Parser implements BlockPluginParser {
36+
37+
public PegdownYumlPlugin() {
38+
super(PegdownParser.OPTIONS,
39+
PegdownParser.PARSING_TIMEOUT_AS_MILLIS,
40+
DefaultParseRunnerProvider);
41+
}
42+
43+
public PegdownYumlPlugin(Integer options,
44+
Long maxParsingTimeInMillis,
45+
ParseRunnerProvider parseRunnerProvider,
46+
PegDownPlugins plugins) {
47+
super(options, maxParsingTimeInMillis, parseRunnerProvider, plugins);
48+
}
49+
50+
public static final String TAG = "%%%";
51+
52+
Rule StartMarker() {
53+
return Sequence(Spn1(), TAG, Sp(), "yuml", Sp());
54+
}
55+
56+
String EndMarker() {
57+
return TAG;
58+
}
59+
60+
Rule ParameterName() {
61+
return FirstOf("type", "style", "scale", "format", "dir");
62+
}
63+
64+
Rule Body() {
65+
return OneOrMore(TestNot(TAG), BaseParser.ANY);
66+
}
67+
68+
Rule BlockRule() {
69+
ParamVar<String, String> params = new ParamVar<String, String>();
70+
StringBuilderVar name = new StringBuilderVar();
71+
StringBuilderVar value = new StringBuilderVar();
72+
StringBuilderVar body = new StringBuilderVar();
73+
74+
return NodeSequence(
75+
StartMarker(),
76+
ZeroOrMore(
77+
Sequence(
78+
ParameterName(), name.append(match()),
79+
String("="),
80+
OneOrMore(Alphanumeric()), value.append(match())
81+
),
82+
Sp(),
83+
params.put(name.getString(), value.getString()),
84+
name.clear(), value.clear()
85+
)
86+
, Body(), body.append(match())
87+
, EndMarker()
88+
, push(new ExpImageNode("title", createYumlUrl(params.get(), body.getString()), new TextNode("")))
89+
);
90+
}
91+
92+
public static String createYumlUrl(Map<String, String> params, String body) {
93+
StringBuilder inlined = new StringBuilder();
94+
for (String line : body.split("\\r?\\n")) {
95+
line = line.trim();
96+
if (line.length() > 0) {
97+
if (inlined.length() > 0) {
98+
inlined.append(", ");
99+
}
100+
inlined.append(line);
101+
}
102+
}
103+
104+
String encodedBody = null;
105+
try {
106+
encodedBody = URLEncoder.encode(inlined.toString(), "UTF-8");
107+
} catch (UnsupportedEncodingException e) {
108+
new RuntimeException("Failed to encode YUML markdown body");
109+
}
110+
111+
StringBuilder mergedStyle = new StringBuilder();
112+
String style = defaultString(params.get("style"), "scruffy");
113+
String type = defaultString(params.get("type"), "class");
114+
String format = defaultString(params.get("format"), "svg");
115+
116+
mergedStyle.append(style);
117+
118+
if (null != params.get("dir"))
119+
mergedStyle.append(";dir:" + params.get("dir"));
120+
121+
if (null != params.get("scale"))
122+
mergedStyle.append(";scale:" + params.get("scale"));
123+
124+
return new StringBuilder()
125+
.append("http://yuml.me/diagram/")
126+
.append(mergedStyle.toString() + "/")
127+
.append(type + "/")
128+
.append(encodedBody)
129+
.append("." + format)
130+
.toString();
131+
}
132+
133+
@Override
134+
public Rule[] blockPluginRules() {
135+
return new Rule[]{BlockRule()};
136+
}
137+
}

0 commit comments

Comments
 (0)