You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by jo...@apache.org on 2021/09/20 09:25:16 UTC

[zeppelin] branch master updated: [ZEPPELIN-5529] Removal of the pegdown parser because it's EOL

This is an automated email from the ASF dual-hosted git repository.

jongyoul pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git


The following commit(s) were added to refs/heads/master by this push:
     new 056f952  [ZEPPELIN-5529] Removal of the pegdown parser because it's EOL
056f952 is described below

commit 056f952095b7c363ba72dab73c1d5a23b012fd58
Author: Philipp Dallig <ph...@gmail.com>
AuthorDate: Mon Sep 20 08:18:53 2021 +0200

    [ZEPPELIN-5529] Removal of the pegdown parser because it's EOL
    
    ### What is this PR for?
    This PR removes pegdown, because it's EOL
    
    ### What type of PR is it?
     - Improvement
    
    ### What is the Jira issue?
    * https://issues.apache.org/jira/browse/ZEPPELIN-5529
    
    ### How should this be tested?
    * CI
    
    ### Questions:
    * Does the licenses files need update? No
    * Is there breaking changes for older versions? No
    * Does this needs documentation? No
    
    Author: Philipp Dallig <ph...@gmail.com>
    
    Closes #4229 from Reamer/remove_pegdown and squashes the following commits:
    
    df7a693e8 [Philipp Dallig] Removal of the pegdown parser because it reached the end of its life a long time ago.
---
 markdown/pom.xml                                   |   6 -
 .../org/apache/zeppelin/markdown/Markdown.java     |  12 +-
 .../org/apache/zeppelin/markdown/ParamVar.java     |  41 ---
 .../apache/zeppelin/markdown/PegdownParser.java    |  66 ----
 .../markdown/PegdownWebSequencelPlugin.java        |  81 -----
 .../zeppelin/markdown/PegdownYumlPlugin.java       | 142 --------
 .../src/main/resources/interpreter-setting.json    |   2 +-
 .../zeppelin/markdown/PegdownParserTest.java       | 404 ---------------------
 .../org/apache/zeppelin/jupyter/JupyterUtil.java   |   4 +-
 .../zeppelin/jupyter/nbformat/JupyterUtilTest.java |   2 +-
 10 files changed, 5 insertions(+), 755 deletions(-)

diff --git a/markdown/pom.xml b/markdown/pom.xml
index 25bf942..4b4ef64 100644
--- a/markdown/pom.xml
+++ b/markdown/pom.xml
@@ -47,12 +47,6 @@
     </dependency>
 
     <dependency>
-      <groupId>org.pegdown</groupId>
-      <artifactId>pegdown</artifactId>
-      <version>${pegdown.version}</version>
-    </dependency>
-
-    <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
     </dependency>
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/Markdown.java b/markdown/src/main/java/org/apache/zeppelin/markdown/Markdown.java
index f88e5e2..d0f896a 100644
--- a/markdown/src/main/java/org/apache/zeppelin/markdown/Markdown.java
+++ b/markdown/src/main/java/org/apache/zeppelin/markdown/Markdown.java
@@ -46,13 +46,6 @@ public class Markdown extends Interpreter {
    * Markdown Parser Type.
    */
   public enum MarkdownParserType {
-    PEGDOWN {
-      @Override
-      public String toString() {
-        return PARSER_TYPE_PEGDOWN;
-      }
-    },
-
     MARKDOWN4j {
       @Override
       public String toString() {
@@ -70,7 +63,6 @@ public class Markdown extends Interpreter {
   }
 
   public static final String MARKDOWN_PARSER_TYPE = "markdown.parser.type";
-  public static final String PARSER_TYPE_PEGDOWN = "pegdown";
   public static final String PARSER_TYPE_MARKDOWN4J = "markdown4j";
   public static final String PARSER_TYPE_FLEXMARK = "flexmark";
 
@@ -81,9 +73,7 @@ public class Markdown extends Interpreter {
   public static MarkdownParser createMarkdownParser(String parserType) {
     LOGGER.debug("Creating {} markdown interpreter", parserType);
 
-    if (MarkdownParserType.PEGDOWN.toString().equals(parserType)) {
-      return new PegdownParser();
-    } else if (MarkdownParserType.FLEXMARK.toString().equals(parserType)) {
+    if (MarkdownParserType.FLEXMARK.toString().equals(parserType)) {
       return new FlexmarkParser();
     } else {
       // default parser
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/ParamVar.java b/markdown/src/main/java/org/apache/zeppelin/markdown/ParamVar.java
deleted file mode 100644
index e8fc5ed..0000000
--- a/markdown/src/main/java/org/apache/zeppelin/markdown/ParamVar.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.zeppelin.markdown;
-
-import org.parboiled.support.Var;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Implementation of Var to support parameter parsing.
- *
- * @param <K> Key
- * @param <V> Value
- */
-public class ParamVar<K, V> extends Var<Map<K, V>> {
-
-  public ParamVar() {
-    super(new HashMap<>());
-  }
-
-  public boolean put(K key, V value) {
-    get().put(key, value);
-    return true;
-  }
-}
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownParser.java b/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownParser.java
deleted file mode 100644
index fb99f05..0000000
--- a/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownParser.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.zeppelin.markdown;
-
-import org.pegdown.Extensions;
-import org.pegdown.PegDownProcessor;
-import org.pegdown.plugins.PegDownPlugins;
-
-/**
- * Markdown Parser using pegdown processor.
- */
-public class PegdownParser implements MarkdownParser {
-  private PegDownProcessor processor;
-
-  public static final long PARSING_TIMEOUT_AS_MILLIS = 10000;
-  public static final int OPTIONS = Extensions.ALL_WITH_OPTIONALS - Extensions.ANCHORLINKS;
-
-  public PegdownParser() {
-    PegDownPlugins plugins = new PegDownPlugins.Builder()
-        .withPlugin(PegdownYumlPlugin.class)
-        .withPlugin(PegdownWebSequencelPlugin.class)
-        .build();
-    processor = new PegDownProcessor(OPTIONS, PARSING_TIMEOUT_AS_MILLIS, plugins);
-  }
-
-  @Override
-  public String render(String markdownText) {
-    String html = "";
-    String parsed;
-    synchronized (processor) {
-      parsed = processor.markdownToHtml(markdownText);
-    }
-    if (null == parsed) {
-      throw new RuntimeException("Cannot parse markdown text to HTML using pegdown");
-    }
-
-    html = wrapWithMarkdownClassDiv(parsed);
-    return html;
-  }
-
-  /**
-   * wrap with markdown class div to styling DOM using css.
-   */
-  public static String wrapWithMarkdownClassDiv(String html) {
-    return new StringBuilder()
-        .append("<div class=\"markdown-body\">\n")
-        .append(html)
-        .append("\n</div>")
-        .toString();
-  }
-}
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownWebSequencelPlugin.java b/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownWebSequencelPlugin.java
deleted file mode 100644
index 47e3a23..0000000
--- a/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownWebSequencelPlugin.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.zeppelin.markdown;
-
-import org.parboiled.BaseParser;
-import org.parboiled.Rule;
-import org.parboiled.support.StringBuilderVar;
-import org.pegdown.Parser;
-import org.pegdown.ast.ExpImageNode;
-import org.pegdown.ast.TextNode;
-import org.pegdown.plugins.BlockPluginParser;
-import org.pegdown.plugins.PegDownPlugins;
-
-/**
- * Pegdown plugin for Websequence diagram.
- */
-public class PegdownWebSequencelPlugin extends Parser implements BlockPluginParser {
-
-  public PegdownWebSequencelPlugin() {
-    super(PegdownParser.OPTIONS,
-        PegdownParser.PARSING_TIMEOUT_AS_MILLIS,
-        DefaultParseRunnerProvider);
-  }
-
-  public PegdownWebSequencelPlugin(Integer opts, Long millis, ParseRunnerProvider provider,
-                                   PegDownPlugins plugins) {
-    super(opts, millis, provider, plugins);
-  }
-
-  public static final String TAG = "%%%";
-
-  Rule startMarker() {
-    return Sequence(Spn1(), TAG, Sp(), "sequence", Sp());
-  }
-
-  String endMarker() {
-    return TAG;
-  }
-
-  Rule body() {
-    return OneOrMore(TestNot(TAG), BaseParser.ANY);
-  }
-
-  Rule blockRule() {
-    StringBuilderVar style = new StringBuilderVar();
-    StringBuilderVar body = new StringBuilderVar();
-
-    return NodeSequence(
-        startMarker(),
-        Optional(
-            String("style="),
-            Sequence(OneOrMore(Letter()), style.append(match()), Spn1())),
-        Sequence(body(), body.append(match())),
-        endMarker(),
-        push(
-            new ExpImageNode("title",
-                MarkdownUtils.createWebsequenceUrl(style.getString(), body.getString()),
-                new TextNode("")))
-    );
-  }
-
-  @Override
-  public Rule[] blockPluginRules() {
-    return new Rule[]{blockRule()};
-  }
-}
diff --git a/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownYumlPlugin.java b/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownYumlPlugin.java
deleted file mode 100644
index c9e942a..0000000
--- a/markdown/src/main/java/org/apache/zeppelin/markdown/PegdownYumlPlugin.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.zeppelin.markdown;
-
-import static org.apache.commons.lang3.StringUtils.defaultString;
-
-import org.parboiled.BaseParser;
-import org.parboiled.Rule;
-import org.parboiled.support.StringBuilderVar;
-import org.pegdown.Parser;
-import org.pegdown.ast.ExpImageNode;
-import org.pegdown.ast.TextNode;
-import org.pegdown.plugins.BlockPluginParser;
-import org.pegdown.plugins.PegDownPlugins;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.Map;
-
-/**
- * Pegdown plugin for YUML.
- */
-public class PegdownYumlPlugin extends Parser implements BlockPluginParser {
-  public PegdownYumlPlugin() {
-    super(PegdownParser.OPTIONS,
-        PegdownParser.PARSING_TIMEOUT_AS_MILLIS,
-        DefaultParseRunnerProvider);
-  }
-
-  public PegdownYumlPlugin(Integer options,
-                           Long maxParsingTimeInMillis,
-                           ParseRunnerProvider parseRunnerProvider,
-                           PegDownPlugins plugins) {
-    super(options, maxParsingTimeInMillis, parseRunnerProvider, plugins);
-  }
-
-  public static final String TAG = "%%%";
-
-  Rule startMarker() {
-    return Sequence(Spn1(), TAG, Sp(), "yuml", Sp());
-  }
-
-  String endMarker() {
-    return TAG;
-  }
-
-  Rule parameterName() {
-    return FirstOf("type", "style", "scale", "format", "dir");
-  }
-
-  Rule body() {
-    return OneOrMore(TestNot(TAG), BaseParser.ANY);
-  }
-
-  Rule blockRule() {
-    ParamVar<String, String> params = new ParamVar<>();
-    StringBuilderVar name = new StringBuilderVar();
-    StringBuilderVar value = new StringBuilderVar();
-    StringBuilderVar body = new StringBuilderVar();
-
-    return NodeSequence(
-        startMarker(),
-        ZeroOrMore(
-            Sequence(
-                parameterName(), name.append(match()),
-                String("="),
-                OneOrMore(Alphanumeric()), value.append(match())),
-            Sp(),
-            params.put(name.getString(), value.getString()),
-            name.clear(), value.clear()),
-        body(),
-        body.append(match()),
-        endMarker(),
-        push(
-            new ExpImageNode(
-                "title", createYumlUrl(params.get(), body.getString()), new TextNode("")))
-    );
-  }
-
-  public static String createYumlUrl(Map<String, String> params, String body) {
-    StringBuilder inlined = new StringBuilder();
-    for (String line : body.split("\\r?\\n")) {
-      line = line.trim();
-      if (line.length() > 0) {
-        if (inlined.length() > 0) {
-          inlined.append(", ");
-        }
-        inlined.append(line);
-      }
-    }
-
-    String encodedBody = null;
-    try {
-      encodedBody = URLEncoder.encode(inlined.toString(), "UTF-8");
-    } catch (UnsupportedEncodingException e) {
-      new RuntimeException("Failed to encode YUML markdown body", e);
-    }
-
-    StringBuilder mergedStyle = new StringBuilder();
-    String style = defaultString(params.get("style"), "scruffy");
-    String type = defaultString(params.get("type"), "class");
-    String format = defaultString(params.get("format"), "svg");
-
-    mergedStyle.append(style);
-
-    if (null != params.get("dir")) {
-      mergedStyle.append(";dir:" + params.get("dir"));
-    }
-
-    if (null != params.get("scale")) {
-      mergedStyle.append(";scale:" + params.get("scale"));
-    }
-
-    return new StringBuilder()
-        .append("http://yuml.me/diagram/")
-        .append(mergedStyle.toString() + "/")
-        .append(type + "/")
-        .append(encodedBody)
-        .append("." + format)
-        .toString();
-  }
-
-  @Override
-  public Rule[] blockPluginRules() {
-    return new Rule[]{blockRule()};
-  }
-}
diff --git a/markdown/src/main/resources/interpreter-setting.json b/markdown/src/main/resources/interpreter-setting.json
index da4b59b..91750d3 100644
--- a/markdown/src/main/resources/interpreter-setting.json
+++ b/markdown/src/main/resources/interpreter-setting.json
@@ -8,7 +8,7 @@
         "envName": "MARKDOWN_PARSER_TYPE",
         "propertyName": "markdown.parser.type",
         "defaultValue": "flexmark",
-        "description": "Markdown Parser Type. Available values: pegdown, markdown4j, flexmark. Default = flexmark",
+        "description": "Markdown Parser Type. Available values: markdown4j, flexmark. Default = flexmark",
         "type": "string"
       }
     },
diff --git a/markdown/src/test/java/org/apache/zeppelin/markdown/PegdownParserTest.java b/markdown/src/test/java/org/apache/zeppelin/markdown/PegdownParserTest.java
deleted file mode 100644
index ec12bb8..0000000
--- a/markdown/src/test/java/org/apache/zeppelin/markdown/PegdownParserTest.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 org.apache.zeppelin.markdown;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
-import static org.apache.zeppelin.markdown.PegdownParser.wrapWithMarkdownClassDiv;
-
-import org.hamcrest.CoreMatchers;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ErrorCollector;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.Properties;
-
-import org.apache.zeppelin.interpreter.InterpreterResult;
-
-public class PegdownParserTest {
-  private static final Logger LOGGER = LoggerFactory.getLogger(PegdownParserTest.class);
-  Markdown md;
-
-  @Rule
-  public ErrorCollector collector = new ErrorCollector();
-
-  @Before
-  public void setUp() {
-    Properties props = new Properties();
-    props.put(Markdown.MARKDOWN_PARSER_TYPE, Markdown.PARSER_TYPE_PEGDOWN);
-    md = new Markdown(props);
-    md.open();
-  }
-
-  @After
-  public void tearDown() {
-    md.close();
-  }
-
-  @Test
-  public void testMultipleThread() {
-    ArrayList<Thread> arrThreads = new ArrayList<>();
-    for (int i = 0; i < 10; i++) {
-      Thread t = new Thread() {
-        @Override
-        public void run() {
-          String r1 = null;
-          try {
-            r1 = md.interpret("# H1", null).code().name();
-          } catch (Exception e) {
-            LOGGER.error("testTestMultipleThread failed to interpret", e);
-          }
-          collector.checkThat("SUCCESS",
-              CoreMatchers.containsString(r1));
-        }
-      };
-      t.start();
-      arrThreads.add(t);
-    }
-
-    for (int i = 0; i < 10; i++) {
-      try {
-        arrThreads.get(i).join();
-      } catch (InterruptedException e) {
-        LOGGER.error("testTestMultipleThread failed to join threads", e);
-      }
-    }
-  }
-
-  @Test
-  public void testHeader() {
-    InterpreterResult r1 = md.interpret("# H1", null);
-    assertEquals(wrapWithMarkdownClassDiv("<h1>H1</h1>"), r1.message().get(0).getData());
-
-    InterpreterResult r2 = md.interpret("## H2", null);
-    assertEquals(wrapWithMarkdownClassDiv("<h2>H2</h2>"), r2.message().get(0).getData());
-
-    InterpreterResult r3 = md.interpret("### H3", null);
-    assertEquals(wrapWithMarkdownClassDiv("<h3>H3</h3>"), r3.message().get(0).getData());
-
-    InterpreterResult r4 = md.interpret("#### H4", null);
-    assertEquals(wrapWithMarkdownClassDiv("<h4>H4</h4>"), r4.message().get(0).getData());
-
-    InterpreterResult r5 = md.interpret("##### H5", null);
-    assertEquals(wrapWithMarkdownClassDiv("<h5>H5</h5>"), r5.message().get(0).getData());
-
-    InterpreterResult r6 = md.interpret("###### H6", null);
-    assertEquals(wrapWithMarkdownClassDiv("<h6>H6</h6>"), r6.message().get(0).getData());
-
-    InterpreterResult r7 = md.interpret("Alt-H1\n" + "======", null);
-    assertEquals(wrapWithMarkdownClassDiv("<h1>Alt-H1</h1>"), r7.message().get(0).getData());
-
-    InterpreterResult r8 = md.interpret("Alt-H2\n" + "------", null);
-    assertEquals(wrapWithMarkdownClassDiv("<h2>Alt-H2</h2>"), r8.message().get(0).getData());
-  }
-
-  @Test
-  public void testStrikethrough() {
-    InterpreterResult result = md.interpret("This is ~~deleted~~ text", null);
-    assertEquals(
-        wrapWithMarkdownClassDiv("<p>This is <del>deleted</del> text</p>"),
-            result.message().get(0).getData());
-  }
-
-  @Test
-  public void testItalics() {
-    InterpreterResult result = md.interpret("This is *italics* text", null);
-    assertEquals(
-        wrapWithMarkdownClassDiv("<p>This is <em>italics</em> text</p>"),
-            result.message().get(0).getData());
-  }
-
-  @Test
-  public void testStrongEmphasis() {
-    InterpreterResult result = md.interpret("This is **strong emphasis** text", null);
-    assertEquals(
-        wrapWithMarkdownClassDiv("<p>This is <strong>strong emphasis</strong> text</p>"),
-        result.message().get(0).getData());
-  }
-
-  @Test
-  public void testOrderedList() {
-    String input =
-        new StringBuilder()
-            .append("1. First ordered list item\n")
-            .append("2. Another item")
-            .toString();
-
-    String expected =
-        new StringBuilder()
-            .append("<ol>\n")
-            .append("  <li>First ordered list item</li>\n")
-            .append("  <li>Another item</li>\n")
-            .append("</ol>")
-            .toString();
-
-    InterpreterResult result = md.interpret(input, null);
-    assertEquals(wrapWithMarkdownClassDiv(expected), result.message().get(0).getData());
-  }
-
-  @Test
-  public void testUnorderedList() {
-    String input =
-        new StringBuilder()
-            .append("* Unordered list can use asterisks\n")
-            .append("- Or minuses\n")
-            .append("+ Or pluses")
-            .toString();
-
-    String expected =
-        new StringBuilder()
-            .append("<ul>\n")
-            .append("  <li>Unordered list can use asterisks</li>\n")
-            .append("  <li>Or minuses</li>\n")
-            .append("  <li>Or pluses</li>\n")
-            .append("</ul>")
-            .toString();
-
-    InterpreterResult result = md.interpret(input, null);
-    assertEquals(wrapWithMarkdownClassDiv(expected), result.message().get(0).getData());
-  }
-
-  @Test
-  public void testLinks() {
-    String input =
-        new StringBuilder()
-            .append("[I'm an inline-style link](https://www.google.com)\n")
-            .append("\n")
-            .append(
-                "[I'm an inline-style link with title](https://www.google.com "
-                        + "\"Google's Homepage\")\n")
-            .append("\n")
-            .append("[I'm a reference-style link][Arbitrary case-insensitive reference text]\n")
-            .append("\n")
-            .append("[I'm a relative reference to a repository file](../blob/master/LICENSE)\n")
-            .append("\n")
-            .append("[You can use numbers for reference-style link definitions][1]\n")
-            .append("\n")
-            .append("Or leave it empty and use the [link text itself].\n")
-            .append("\n")
-            .append("URLs and URLs in angle brackets will automatically get turned into links. \n")
-            .append("http://www.example.com or <http://www.example.com> and sometimes \n")
-            .append("example.com (but not on Github, for example).\n")
-            .append("\n")
-            .append("Some text to show that the reference links can follow later.\n")
-            .append("\n")
-            .append("[arbitrary case-insensitive reference text]: https://www.mozilla.org\n")
-            .append("[1]: http://slashdot.org\n")
-            .append("[link text itself]: http://www.reddit.com")
-            .toString();
-
-    String expected =
-        new StringBuilder()
-            .append(
-                "<p><a href=\"https://www.google.com\">I&rsquo;m an inline-style link</a></p>\n")
-            .append(
-                "<p><a href=\"https://www.google.com\" title=\"Google&#39;s Homepage\">I&rsquo;m "
-                        + "an inline-style link with title</a></p>\n")
-            .append(
-                "<p><a href=\"https://www.mozilla.org\">I&rsquo;m a reference-style link</a></p>\n")
-            .append(
-                "<p><a href=\"../blob/master/LICENSE\">I&rsquo;m a relative reference to a "
-                        + "repository file</a></p>\n")
-            .append(
-                "<p><a href=\"http://slashdot.org\">You can use numbers for reference-style link "
-                        + "definitions</a></p>\n")
-            .append(
-                "<p>Or leave it empty and use the <a href=\"http://www.reddit.com\">link text "
-                        + "itself</a>.</p>\n")
-            .append(
-                "<p>URLs and URLs in angle brackets will automatically get turned into links."
-                        + "<br/><a href=\"http://www.example.com\">http://www.example.com</a> or "
-                        + "<a href=\"http://www.example.com\">http://www.example.com</a> and "
-                        + "sometimes<br/>example.com (but not on Github, for example).</p>\n")
-            .append("<p>Some text to show that the reference links can follow later.</p>")
-            .toString();
-
-    InterpreterResult result = md.interpret(input, null);
-    assertEquals(wrapWithMarkdownClassDiv(expected), result.message().get(0).getData());
-  }
-
-  @Test
-  public void testInlineCode() {
-    InterpreterResult result = md.interpret("Inline `code` has `back-ticks around` it.", null);
-    assertEquals(
-        wrapWithMarkdownClassDiv(
-            "<p>Inline <code>code</code> has <code>back-ticks around</code> it.</p>"),
-        result.message().get(0).getData());
-  }
-
-  @Test
-  public void testBlockQuotes() {
-    InterpreterResult r1 =
-        md.interpret(
-            "> Blockquotes are very handy in email to emulate reply text.\n"
-                + "> This line is part of the same quote.",
-            null);
-    assertEquals(
-        wrapWithMarkdownClassDiv(
-            "<blockquote>\n"
-                    + "  <p>Blockquotes are very handy in email to emulate reply text.<br/>This "
-                    + "line is part of the same quote.</p>\n"
-                    + "</blockquote>"),
-        r1.message().get(0).getData());
-
-    InterpreterResult r2 =
-        md.interpret(
-            "> This is a very long line that will still be quoted properly when it "
-                    + "wraps. Oh boy let's keep writing to make sure this is long enough to "
-                    + "actually wrap for everyone. Oh, you can *put* **MarkdownInterpreter** "
-                    + "into a blockquote. ",
-            null);
-    assertEquals(
-        wrapWithMarkdownClassDiv(
-            "<blockquote>\n"
-                    + "  <p>This is a very long line that will still be quoted properly when "
-                    + "it wraps. Oh boy let&rsquo;s keep writing to make sure this is long enough "
-                    + "to actually wrap for everyone. Oh, you can <em>put</em> "
-                    + "<strong>MarkdownInterpreter</strong> into a blockquote. </p>\n"
-                    + "</blockquote>"),
-        r2.message().get(0).getData());
-  }
-
-  @Test
-  public void testSimpleTable() {
-    String input =
-        new StringBuilder()
-            .append("MarkdownInterpreter | Less | Pretty\n")
-            .append("--- | --- | ---\n")
-            .append("*Still* | `renders` | **nicely**\n")
-            .append("1 | 2 | 3")
-            .toString();
-
-    String expected =
-        new StringBuilder()
-            .append("<table>\n")
-            .append("  <thead>\n")
-            .append("    <tr>\n")
-            .append("      <th>MarkdownInterpreter </th>\n")
-            .append("      <th>Less </th>\n")
-            .append("      <th>Pretty</th>\n")
-            .append("    </tr>\n")
-            .append("  </thead>\n")
-            .append("  <tbody>\n")
-            .append("    <tr>\n")
-            .append("      <td><em>Still</em> </td>\n")
-            .append("      <td><code>renders</code> </td>\n")
-            .append("      <td><strong>nicely</strong></td>\n")
-            .append("    </tr>\n")
-            .append("    <tr>\n")
-            .append("      <td>1 </td>\n")
-            .append("      <td>2 </td>\n")
-            .append("      <td>3</td>\n")
-            .append("    </tr>\n")
-            .append("  </tbody>\n")
-            .append("</table>")
-            .toString();
-
-    InterpreterResult result = md.interpret(input, null);
-    assertEquals(wrapWithMarkdownClassDiv(expected), result.message().get(0).getData());
-  }
-
-  @Test
-  public void testAlignedTable() {
-    String input =
-        new StringBuilder()
-            .append("| First Header | Second Header |         Third Header |\n")
-            .append("| :----------- | :-----------: | -------------------: |\n")
-            .append("| First row    |      Data     | Very long data entry |\n")
-            .append("| Second row   |    **Cell**   |               *Cell* |")
-            .toString();
-
-    String expected =
-        new StringBuilder()
-            .append("<table>\n")
-            .append("  <thead>\n")
-            .append("    <tr>\n")
-            .append("      <th align=\"left\">First Header </th>\n")
-            .append("      <th align=\"center\">Second Header </th>\n")
-            .append("      <th align=\"right\">Third Header </th>\n")
-            .append("    </tr>\n")
-            .append("  </thead>\n")
-            .append("  <tbody>\n")
-            .append("    <tr>\n")
-            .append("      <td align=\"left\">First row </td>\n")
-            .append("      <td align=\"center\">Data </td>\n")
-            .append("      <td align=\"right\">Very long data entry </td>\n")
-            .append("    </tr>\n")
-            .append("    <tr>\n")
-            .append("      <td align=\"left\">Second row </td>\n")
-            .append("      <td align=\"center\"><strong>Cell</strong> </td>\n")
-            .append("      <td align=\"right\"><em>Cell</em> </td>\n")
-            .append("    </tr>\n")
-            .append("  </tbody>\n")
-            .append("</table>")
-            .toString();
-
-    InterpreterResult result = md.interpret(input, null);
-    assertEquals(wrapWithMarkdownClassDiv(expected), result.message().get(0).getData());
-  }
-
-  @Test
-  public void testWebsequencePlugin() {
-    String input =
-        new StringBuilder()
-            .append("\n \n %%% sequence style=modern-blue\n")
-            .append("title Authentication Sequence\n")
-            .append("Alice->Bob: Authentication Request\n")
-            .append("note right of Bob: Bob thinks about it\n")
-            .append("Bob->Alice: Authentication Response\n")
-            .append("  %%%  ")
-            .toString();
-
-    InterpreterResult result = md.interpret(input, null);
-
-    // assert statement below can fail depends on response of websequence service.
-    // To make unittest independent from websequence service,
-    // catch exception, log and pass instead of assert.
-    //
-    // assertThat(result.message().get(0).getData(),
-    // CoreMatchers.containsString("<img src=\"http://www.websequencediagrams.com/?png="));
-
-    System.err.println(result.message().get(0).getData());
-    if (!result.message().get(0).getData().contains(
-        "<img src=\"http://www.websequencediagrams.com/?png=")) {
-      LOGGER.error("Expected {} but found {}",
-          "<img src=\"http://www.websequencediagrams.com/?png=", result.message().get(0).getData());
-    }
-  }
-
-  @Test
-  public void testYumlPlugin() {
-    String input = new StringBuilder()
-        .append("\n \n %%% yuml style=nofunky scale=120 format=svg\n")
-        .append("[Customer]<>-orders>[Order]\n")
-        .append("[Order]++-0..>[LineItem]\n")
-        .append("[Order]-[note:Aggregate root.]\n")
-        .append("  %%%  ")
-        .toString();
-
-    InterpreterResult result = md.interpret(input, null);
-    assertThat(result.message().get(0).getData(),
-            CoreMatchers.containsString("<img src=\"http://yuml.me/diagram/"));
-  }
-}
diff --git a/zeppelin-jupyter/src/main/java/org/apache/zeppelin/jupyter/JupyterUtil.java b/zeppelin-jupyter/src/main/java/org/apache/zeppelin/jupyter/JupyterUtil.java
index cc6d1bd..4ec841e 100644
--- a/zeppelin-jupyter/src/main/java/org/apache/zeppelin/jupyter/JupyterUtil.java
+++ b/zeppelin-jupyter/src/main/java/org/apache/zeppelin/jupyter/JupyterUtil.java
@@ -43,8 +43,8 @@ import org.apache.zeppelin.jupyter.zformat.Note;
 import org.apache.zeppelin.jupyter.zformat.Paragraph;
 import org.apache.zeppelin.jupyter.zformat.Result;
 import org.apache.zeppelin.jupyter.zformat.TypeData;
+import org.apache.zeppelin.markdown.FlexmarkParser;
 import org.apache.zeppelin.markdown.MarkdownParser;
-import org.apache.zeppelin.markdown.PegdownParser;
 
 import java.io.BufferedReader;
 import java.io.FileReader;
@@ -78,7 +78,7 @@ public class JupyterUtil {
         .registerSubtype(ExecuteResult.class, "execute_result")
         .registerSubtype(DisplayData.class, "display_data").registerSubtype(Stream.class, "stream")
         .registerSubtype(Error.class, "error");
-    this.markdownProcessor = new PegdownParser();
+    this.markdownProcessor = new FlexmarkParser();
   }
 
   public Nbformat getNbformat(Reader in) {
diff --git a/zeppelin-jupyter/src/test/java/org/apache/zeppelin/jupyter/nbformat/JupyterUtilTest.java b/zeppelin-jupyter/src/test/java/org/apache/zeppelin/jupyter/nbformat/JupyterUtilTest.java
index 033aa0b..cb436dd 100644
--- a/zeppelin-jupyter/src/test/java/org/apache/zeppelin/jupyter/nbformat/JupyterUtilTest.java
+++ b/zeppelin-jupyter/src/test/java/org/apache/zeppelin/jupyter/nbformat/JupyterUtilTest.java
@@ -96,7 +96,7 @@ public class JupyterUtilTest {
             "    <div class=\"col-sm-1\"><img src=\"https://knowledgeanyhow.org/static/images/favicon_32x32.png\" style=\"margin-top: -6px\"/></div>\n" +
             "    <div class=\"col-sm-11\">This notebook was created using <a href=\"https://knowledgeanyhow.org\">IBM Knowledge Anyhow Workbench</a>.  To learn more, visit us at <a href=\"https://knowledgeanyhow.org\">https://knowledgeanyhow.org</a>.</div>\n" +
             "    </div>\n" +
-            "</div>\n" +
+            "</div>\n\n" +
             "</div>" , results.get(0).getData());
     assertEquals("HTML", results.get(0).getType());
   }