You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by ju...@apache.org on 2017/12/08 22:07:48 UTC

[1/5] jspwiki git commit: minor formatting

Repository: jspwiki
Updated Branches:
  refs/heads/master 719a1a1e3 -> 836db9f07


minor formatting


Project: http://git-wip-us.apache.org/repos/asf/jspwiki/repo
Commit: http://git-wip-us.apache.org/repos/asf/jspwiki/commit/746492fa
Tree: http://git-wip-us.apache.org/repos/asf/jspwiki/tree/746492fa
Diff: http://git-wip-us.apache.org/repos/asf/jspwiki/diff/746492fa

Branch: refs/heads/master
Commit: 746492fa7715751f286e34b365841cc991357cb4
Parents: 719a1a1
Author: juanpablo <ju...@apache.org>
Authored: Fri Dec 8 21:49:17 2017 +0100
Committer: juanpablo <ju...@apache.org>
Committed: Fri Dec 8 21:49:17 2017 +0100

----------------------------------------------------------------------
 jspwiki-war/pom.xml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jspwiki/blob/746492fa/jspwiki-war/pom.xml
----------------------------------------------------------------------
diff --git a/jspwiki-war/pom.xml b/jspwiki-war/pom.xml
index 74d3a15..324a5cf 100644
--- a/jspwiki-war/pom.xml
+++ b/jspwiki-war/pom.xml
@@ -17,7 +17,9 @@
   specific language governing permissions and limitations
   under the License.
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
   <parent>
     <groupId>org.apache.jspwiki</groupId>


[2/5] jspwiki git commit: JSPWIKI-802: initial markdown support

Posted by ju...@apache.org.
http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/NodePostProcessorStateCommonOperations.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/NodePostProcessorStateCommonOperations.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/NodePostProcessorStateCommonOperations.java
new file mode 100755
index 0000000..b6da8f9
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/NodePostProcessorStateCommonOperations.java
@@ -0,0 +1,79 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.MarkupParser;
+import org.apache.wiki.render.RenderingManager;
+
+import com.vladsch.flexmark.ast.HtmlInline;
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.ast.Node;
+import com.vladsch.flexmark.util.NodeTracker;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * Internal class with common post-processor operations.
+ */
+class NodePostProcessorStateCommonOperations {
+
+    static void addContent( final NodeTracker state, final Node node, final Node content ) {
+        final Node previous = node.getPrevious() != null ? node.getPrevious() : node.getNext();
+        if( previous != null ) {
+            previous.insertAfter( content );
+            node.unlink();
+            state.nodeRemoved( node );
+            content.takeChildren( node );
+            state.nodeAddedWithChildren( content );
+        } else {
+            node.getParent().appendChild( content );
+        }
+    }
+
+    static void addOutlinkImage( final NodeTracker state, final Node node, final WikiContext wikiContext, final boolean useOutlinkImage ) {
+        final Boolean wysiwygVariable = ( Boolean )wikiContext.getVariable( RenderingManager.WYSIWYG_EDITOR_MODE );
+        boolean wysiwygEditorMode = wysiwygVariable != null ? wysiwygVariable.booleanValue() : false;
+
+        if( useOutlinkImage && !wysiwygEditorMode ) {
+            final String m_outlinkImageURL = wikiContext.getURL( WikiContext.NONE, MarkupParser.OUTLINK_IMAGE );
+            final HtmlInline img = new HtmlInline( CharSubSequence.of( "<img class=\""+ MarkupParser.OUTLINK + "\" " +
+                                                                             "alt=\"\" src=\""+ m_outlinkImageURL + "\" />" ) );
+            node.insertAfter( img );
+            state.nodeAdded( img );
+        }
+    }
+
+    static String inlineLinkTextOnWysiwyg( final NodeTracker state, final Link link, final boolean wysiwygEditorMode ) {
+        final String line = link.getUrl().toString();
+        if( wysiwygEditorMode ) {
+            final HtmlInline content = new HtmlInline( CharSubSequence.of( "[" + line + "]()" ) );
+            addContent( state, link, content );
+        }
+        return line;
+    }
+
+    static void makeError( final NodeTracker state, final Node node, final String errMsg ) {
+        final HtmlInline error = new HtmlInline( CharSubSequence.of( "<span class=\"error\">" +
+                                                                     errMsg +
+                                                                     "</span>" ) );
+        addContent( state, node, error );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/PluginLinkNodePostProcessorState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/PluginLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/PluginLinkNodePostProcessorState.java
new file mode 100755
index 0000000..b9a79e5
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/PluginLinkNodePostProcessorState.java
@@ -0,0 +1,138 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+import org.apache.log4j.Logger;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.api.exceptions.PluginException;
+import org.apache.wiki.api.plugin.WikiPlugin;
+import org.apache.wiki.parser.PluginContent;
+import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.render.RenderingManager;
+
+import com.vladsch.flexmark.ast.HtmlInline;
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.ext.toc.TocBlock;
+import com.vladsch.flexmark.util.NodeTracker;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodePostProcessorState} which further post processes plugin links.
+ */
+public class PluginLinkNodePostProcessorState implements NodePostProcessorState< Link > {
+
+    private static final Logger LOG = Logger.getLogger( PluginLinkNodePostProcessorState.class );
+    private final WikiContext wikiContext;
+    private final boolean m_wysiwygEditorMode;
+
+    public PluginLinkNodePostProcessorState( final WikiContext wikiContext ) {
+        this.wikiContext = wikiContext;
+        final Boolean wysiwygVariable = ( Boolean )wikiContext.getVariable( RenderingManager.WYSIWYG_EDITOR_MODE );
+        m_wysiwygEditorMode = wysiwygVariable != null ? wysiwygVariable.booleanValue() : false;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodePostProcessorState#process(NodeTracker, Link)
+     */
+    @Override
+    public void process( final NodeTracker state, final Link link ) {
+        if( link.getText().toString().startsWith( "{TableOfContents" ) ) {
+            handleTableOfContentsPlugin( state, link );
+            return;
+        }
+        PluginContent pluginContent = null;
+        try {
+            pluginContent = PluginContent.parsePluginLine( wikiContext, link.getUrl().toString(), -1 ); // -1 == do not generate _bounds parameter
+            //
+            //  This might sometimes fail, especially if there is something which looks
+            //  like a plugin invocation but is really not.
+            //
+            if( pluginContent != null ) {
+                final String pluginInvocation = pluginInvocation( link.getText().toString(), pluginContent );
+                final HtmlInline content = new HtmlInline( CharSubSequence.of( pluginInvocation ) );
+                pluginContent.executeParse( wikiContext );
+                NodePostProcessorStateCommonOperations.addContent( state, link, content );
+            }
+        } catch( final PluginException e ) {
+            LOG.info( wikiContext.getRealPage().getWiki() + " : " + wikiContext.getRealPage().getName() + " - Failed to insert plugin: " + e.getMessage() );
+            if( !m_wysiwygEditorMode ) {
+                final ResourceBundle rbPlugin = Preferences.getBundle( wikiContext, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
+                NodePostProcessorStateCommonOperations.makeError( state, link, MessageFormat.format( rbPlugin.getString( "plugin.error.insertionfailed" ),
+                                                                                                                         wikiContext.getRealPage().getWiki(),
+                                                                                                                         wikiContext.getRealPage().getName(),
+                                                                                                                         e.getMessage() ) );
+            }
+        } finally {
+            if( pluginContent != null ) {
+                removeLink( state, link );
+            }
+        }
+    }
+
+    /**
+     * Return plugin execution. As plugin execution may not fire the plugin (i.e., on WYSIWYG editors), on those cases, the plugin line is returned.
+     *
+     * @param pluginMarkup plugin markup line
+     * @param pluginContent the plugin content.
+     * @return plugin execution, or plugin markup line if it wasn't executed.
+     */
+    String pluginInvocation( final String pluginMarkup, final PluginContent pluginContent ) {
+        final String pluginInvocation = pluginContent.invoke( wikiContext );
+        if( pluginMarkup.equals( pluginInvocation + "()" ) ) { // plugin line markup == plugin execution + "()" -> hasn't been executed
+            return pluginMarkup;
+        } else {
+            return pluginInvocation;
+        }
+    }
+
+    void handleTableOfContentsPlugin(final NodeTracker state, final Link link) {
+        if( !m_wysiwygEditorMode ) {
+            final ResourceBundle rb = Preferences.getBundle( wikiContext, WikiPlugin.CORE_PLUGINS_RESOURCEBUNDLE );
+            final HtmlInline divToc = new HtmlInline( CharSubSequence.of( "<div class=\"toc\">\n" ) );
+            final HtmlInline divCollapseBox = new HtmlInline( CharSubSequence.of( "<div class=\"collapsebox\">\n" ) );
+            final HtmlInline divsClosing = new HtmlInline( CharSubSequence.of( "</div>\n</div>\n" ) );
+            final HtmlInline h4Title = new HtmlInline( CharSubSequence.of( "<h4 id=\"section-TOC\">" + // FIXME proper plugin parameters handling
+                                                                           rb.getString( "tableofcontents.title" ) +
+                                                                           "</h4>\n" ) );
+            final TocBlock toc = new TocBlock( CharSubSequence.of( "[TOC]" ), CharSubSequence.of( "levels=1-3" ) );
+
+            link.insertAfter( divToc );
+            divToc.insertAfter( divCollapseBox );
+            divCollapseBox.insertAfter( h4Title );
+            h4Title.insertAfter( toc );
+            toc.insertAfter( divsClosing );
+
+        } else {
+            NodePostProcessorStateCommonOperations.inlineLinkTextOnWysiwyg( state, link, m_wysiwygEditorMode );
+        }
+        removeLink( state, link );
+    }
+
+    void removeLink(final NodeTracker state, final Link link) {
+        link.unlink();
+        state.nodeRemoved( link );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/VariableLinkNodePostProcessorState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/VariableLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/VariableLinkNodePostProcessorState.java
new file mode 100755
index 0000000..b15cfbd
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/VariableLinkNodePostProcessorState.java
@@ -0,0 +1,65 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.api.exceptions.NoSuchVariableException;
+import org.apache.wiki.render.RenderingManager;
+
+import com.vladsch.flexmark.ast.HtmlInline;
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.NodeTracker;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodePostProcessorState} which further post processes WikiVariable links.
+ */
+public class VariableLinkNodePostProcessorState implements NodePostProcessorState< Link > {
+
+    private final WikiContext wikiContext;
+    private final boolean m_wysiwygEditorMode;
+
+    public VariableLinkNodePostProcessorState( final WikiContext wikiContext ) {
+        this.wikiContext = wikiContext;
+        final Boolean wysiwygVariable = ( Boolean )wikiContext.getVariable( RenderingManager.WYSIWYG_EDITOR_MODE );
+        m_wysiwygEditorMode = wysiwygVariable != null ? wysiwygVariable.booleanValue() : false;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodePostProcessorState#process(NodeTracker, Link)
+     */
+    @Override
+    public void process( NodeTracker state, Link link ) {
+        final String variable = NodePostProcessorStateCommonOperations.inlineLinkTextOnWysiwyg( state, link, m_wysiwygEditorMode );
+        if( !m_wysiwygEditorMode ) {
+            try {
+                final String parsedVariable = wikiContext.getEngine().getVariableManager().parseAndGetValue( wikiContext, variable );
+                final HtmlInline content = new HtmlInline( CharSubSequence.of( StringEscapeUtils.escapeXml( parsedVariable ) ) );
+                NodePostProcessorStateCommonOperations.addContent( state, link, content );
+            } catch( final NoSuchVariableException e ) {
+                NodePostProcessorStateCommonOperations.makeError( state, link, "No such variable: " + variable + " (" + e.getMessage() + ")" );
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/package.html
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/package.html b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/package.html
new file mode 100755
index 0000000..a067a22
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/package.html
@@ -0,0 +1,34 @@
+<!--
+    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.
+-->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+Wikilinks' nodes custom post processing.
+
+<h3>Package Specification</h3>
+
+<h3>Related Documentation</h3>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/package.html
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/package.html b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/package.html
new file mode 100755
index 0000000..93bcd81
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/package.html
@@ -0,0 +1,34 @@
+<!--
+    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.
+-->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+Entry point for JSPWiki Flexmark's custom extensions.
+
+<h3>Package Specification</h3>
+
+<h3>Related Documentation</h3>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownDocument.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownDocument.java b/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownDocument.java
new file mode 100755
index 0000000..fb51dec
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownDocument.java
@@ -0,0 +1,73 @@
+/*
+    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.wiki.parser.markdown;
+
+import java.util.Arrays;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.markdown.MarkdownForJSPWikiExtension;
+import org.apache.wiki.parser.JSPWikiMarkupParser;
+import org.apache.wiki.parser.WikiDocument;
+
+import com.vladsch.flexmark.Extension;
+import com.vladsch.flexmark.ast.Node;
+import com.vladsch.flexmark.ext.footnotes.FootnoteExtension;
+import com.vladsch.flexmark.ext.toc.TocExtension;
+import com.vladsch.flexmark.parser.Parser;
+import com.vladsch.flexmark.parser.ParserEmulationProfile;
+import com.vladsch.flexmark.util.options.MutableDataSet;
+
+
+/**
+ * Simple placeholder for Markdown Nodes
+ */
+public class MarkdownDocument extends WikiDocument {
+
+	private static final long serialVersionUID = 1L;
+
+	private final Node md;
+
+	public MarkdownDocument( final WikiPage page, final Node md ) {
+		super( page );
+		this.md = md;
+	}
+
+	public Node getMarkdownNode() {
+		return md;
+	}
+
+	/**
+	 * configuration options for MarkdownRenderers.
+	 *
+	 * @param context current wikicontext
+	 * @return configuration options for MarkdownRenderers.
+	 */
+	public static MutableDataSet options( final WikiContext context ) {
+		MutableDataSet options = new MutableDataSet();
+		options.setFrom( ParserEmulationProfile.COMMONMARK );
+		// align style of Markdown's footnotes extension with jspwiki footnotes refs
+		options.set( FootnoteExtension.FOOTNOTE_LINK_REF_CLASS, JSPWikiMarkupParser.CLASS_FOOTNOTE_REF );
+		options.set( Parser.EXTENSIONS, Arrays.asList( new Extension[] { new MarkdownForJSPWikiExtension( context ),
+		                                                                 FootnoteExtension.create(),
+		                                                                 TocExtension.create() } ) );
+		return options;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownParser.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownParser.java b/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownParser.java
new file mode 100755
index 0000000..3c259e8
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/MarkdownParser.java
@@ -0,0 +1,59 @@
+/*
+    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.wiki.parser.markdown;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.MarkupParser;
+import org.apache.wiki.parser.WikiDocument;
+
+import com.vladsch.flexmark.ast.Node;
+import com.vladsch.flexmark.parser.Parser;
+
+
+/**
+ * Class handling the markdown parsing.
+ */
+public class MarkdownParser extends MarkupParser {
+
+	private final Parser parser;
+
+	public MarkdownParser( final WikiContext context, final Reader in ) {
+		super( context, in );
+		if( context.getEngine().getUserManager().getUserDatabase() == null || context.getEngine().getAuthorizationManager() == null ) {
+            disableAccessRules();
+        }
+		parser = Parser.builder( MarkdownDocument.options( context ) ).build();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public WikiDocument parse() throws IOException {
+		Node document = parser.parseReader( m_in );
+		MarkdownDocument md = new MarkdownDocument( m_context.getPage(), document );
+        md.setContext( m_context );
+
+		return md;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/package.html
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/package.html b/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/package.html
new file mode 100755
index 0000000..b54d53f
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/parser/markdown/package.html
@@ -0,0 +1,34 @@
+<!--
+    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.
+-->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+Markdown parsing.
+
+<h3>Package Specification</h3>
+
+<h3>Related Documentation</h3>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/render/markdown/MarkdownRenderer.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/render/markdown/MarkdownRenderer.java b/jspwiki-markdown/src/main/java/org/apache/wiki/render/markdown/MarkdownRenderer.java
new file mode 100755
index 0000000..bf13633
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/render/markdown/MarkdownRenderer.java
@@ -0,0 +1,56 @@
+/*
+    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.wiki.render.markdown;
+
+import java.io.IOException;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.WikiDocument;
+import org.apache.wiki.parser.markdown.MarkdownDocument;
+import org.apache.wiki.render.WikiRenderer;
+
+import com.vladsch.flexmark.html.HtmlRenderer;
+
+
+/**
+ * Class handling the markdown rendering.
+ */
+public class MarkdownRenderer extends WikiRenderer {
+
+	private final HtmlRenderer renderer;
+
+	public MarkdownRenderer( final WikiContext context, final WikiDocument doc ) {
+		super( context, doc );
+		renderer = HtmlRenderer.builder( MarkdownDocument.options( context ) ).build();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String getString() throws IOException {
+		m_document.setContext( m_context );
+		if( m_document instanceof MarkdownDocument ) {
+			return renderer.render( ( ( MarkdownDocument )m_document ).getMarkdownNode() );
+		} else {
+			throw new IOException( "MarkdownRenderer requires to be used with MarkdownParser" );
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/render/markdown/package.html
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/render/markdown/package.html b/jspwiki-markdown/src/main/java/org/apache/wiki/render/markdown/package.html
new file mode 100755
index 0000000..e1bb604
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/render/markdown/package.html
@@ -0,0 +1,34 @@
+<!--
+    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.
+-->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+Markdown rendering.
+
+<h3>Package Specification</h3>
+
+<h3>Related Documentation</h3>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/test/java/org/apache/wiki/render/MarkdownRendererTest.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/test/java/org/apache/wiki/render/MarkdownRendererTest.java b/jspwiki-markdown/src/test/java/org/apache/wiki/render/MarkdownRendererTest.java
new file mode 100755
index 0000000..d6f9be1
--- /dev/null
+++ b/jspwiki-markdown/src/test/java/org/apache/wiki/render/MarkdownRendererTest.java
@@ -0,0 +1,322 @@
+/*
+    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.wiki.render;
+
+import java.io.BufferedReader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.wiki.TestEngine;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.WikiEngine;
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.attachment.Attachment;
+import org.apache.wiki.parser.markdown.MarkdownParser;
+import org.apache.wiki.render.markdown.MarkdownRenderer;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import net.sf.ehcache.CacheManager;
+
+
+public class MarkdownRendererTest {
+
+    Properties props = TestEngine.getTestProperties();
+    List<String> created = new ArrayList<>();
+
+    static final String PAGE_NAME = "testpage";
+
+    TestEngine testEngine;
+
+    @Test
+    public void testMarkupSimpleMarkdown() throws Exception {
+        String src = "This should be a **bold**";
+
+        Assert.assertEquals( "<p>This should be a <strong>bold</strong></p>\n", translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionSelfViewLink() throws Exception {
+    	newPage( "MarkupExtensionSelfViewLink" );
+        String src = "This should be a [MarkupExtensionSelfViewLink]()";
+
+        Assert.assertEquals( "<p>This should be a <a href=\"/test/Wiki.jsp?page=MarkupExtensionSelfViewLink\" class=\"wikipage\">MarkupExtensionSelfViewLink</a></p>\n",
+                             translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionSelfEditLink() throws Exception {
+        String src = "This should be a [self<->link]()";
+
+        Assert.assertEquals( "<p>This should be a <a href=\"/test/Edit.jsp?page=self%3C-%3Elink\" title=\"Create &quot;self&lt;-&gt;link&quot;\" class=\"createpage\">self&lt;-&gt;link</a></p>\n",
+                             translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionExternalLink() throws Exception {
+        testEngine.getWikiProperties().setProperty( "jspwiki.translatorReader.useOutlinkImage", "true" );
+        String src = "This should be an [external link](https://jspwiki.apache.org)";
+
+        Assert.assertEquals( "<p>This should be an <a href=\"https://jspwiki.apache.org\" class=\"external\">external link</a><img class=\"outlink\" alt=\"\" src=\"/test/images/out.png\" /></p>\n",
+                             translate( src ) );
+        testEngine.getWikiProperties().remove( "jspwiki.translatorReader.useOutlinkImage" );
+    }
+
+    @Test
+    public void testMarkupExtensionInterWikiLink() throws Exception {
+        String src = "This should be an [interwiki link](JSPWiki:About)";
+
+        Assert.assertEquals( "<p>This should be an <a href=\"http://jspwiki-wiki.apache.org/Wiki.jsp?page=About\" class=\"interwiki\">interwiki link</a></p>\n",
+                             translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionWrongInterWikiLink() throws Exception {
+        String src = "This should be an [interwiki link](JSPWiko:About)";
+
+        Assert.assertEquals( "<p>This should be an <span class=\"error\">No InterWiki reference defined in properties for Wiki called \"JSPWiko\"!</span></p>\n",
+                             translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionACL() throws Exception {
+        String src = "[{ALLOW view PerryMason}]() This should be visible if the ACL allows you to see it";
+        // text is seen because although ACL is added to the page, it is not applied while parsing / rendering
+        Assert.assertEquals( "<p> This should be visible if the ACL allows you to see it</p>\n", translate( src ) );
+        // in any case, we also check that the created wikipage has the ACL added
+        Assert.assertEquals( "  user = PerryMason: ((\"org.apache.wiki.auth.permissions.PagePermission\",\"JSPWiki:testpage\",\"view\"))\n",
+        		             testEngine.getPage( PAGE_NAME ).getAcl().toString() );
+    }
+
+    @Test
+    public void testMarkupExtensionMetadata() throws Exception {
+        String src = "[{SET Perry='Mason'}]() Some text after setting metadata";
+        Assert.assertEquals( "<p> Some text after setting metadata</p>\n", translate( src ) );
+        Assert.assertEquals( "Mason", testEngine.getPage( PAGE_NAME ).getAttribute( "Perry" ) );
+    }
+
+    @Test
+    public void testMarkupExtensionPlugin() throws Exception {
+        String src = "[{SamplePlugin text=test}]()";
+        Assert.assertEquals( "<p>test</p>\n", translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionTOCPluginGetsSubstitutedWithMDTocExtension() throws Exception {
+        String src = "[{TableOfContents}]()\n" +
+                     "# Header 1\n" +
+                     "## Header 2\n" +
+                     "## Header 2\n";
+        Assert.assertEquals( "<p><div class=\"toc\">\n" +
+                             "<div class=\"collapsebox\">\n" +
+                             "<h4 id=\"section-TOC\">Table of Contents</h4>\n" +
+                             "<ul>\n" +
+                             "<li><a href=\"#header-1\">Header 1</a>\n" +
+                             "<ul>\n" +
+                             "<li><a href=\"#header-2\">Header 2</a></li>\n" +
+                             "<li><a href=\"#header-2-1\">Header 2</a></li>\n" +
+                             "</ul>\n" +
+                             "</li>\n" +
+                             "</ul>\n" +
+                             "</div>\n" +
+                             "</div>\n" +
+                             "</p>\n" +
+                             "<h1 id=\"header-1\">Header 1</h1>\n" +
+                             "<h2 id=\"header-2\">Header 2</h2>\n" +
+                             "<h2 id=\"header-2-1\">Header 2</h2>\n", translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionNonExistentPlugin() throws Exception {
+        String src = "[{PampleSlugin text=test}]()";
+        Assert.assertEquals( "<p><span class=\"error\">JSPWiki : testpage - Plugin insertion failed: Could not find plugin PampleSlugin</span></p>\n", translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionVariable0() throws Exception {
+        String src = "Some text with some pre-set variable: [{$applicationname}]()";
+        Assert.assertEquals( "<p>Some text with some pre-set variable: JSPWiki</p>\n", translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionVariable1() throws Exception {
+        String src = "[{SET Perry='Mason'}]() Some text after setting some metadata: [{$Perry}]()";
+        Assert.assertEquals( "<p> Some text after setting some metadata: Mason</p>\n", translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionFootnote0() throws Exception {
+        String src = "Footnote[1]()";
+        Assert.assertEquals( "<p>Footnote<a href=\"#ref-testpage-1\" class=\"footnoteref\">[1]</a></p>\n", translate( src ) );
+    }
+
+    @Test
+    public void testMarkupExtensionFootnoteMD() throws Exception {
+        String src = "text [^footnote] embedded.\n\n" +
+        		     "[^footnote]: footnote text\n" +
+        		     "with continuation";
+        Assert.assertEquals( "<p>text <sup id=\"fnref-1\"><a class=\"footnoteref\" href=\"#fn-1\">1</a></sup> embedded.</p>\n" +
+        		             "<div class=\"footnotes\">\n" +
+        		             "<hr />\n" +
+        		             "<ol>\n" +
+        		             "<li id=\"fn-1\">\n" +
+        		             "<p>footnote text\n" +
+        		             "with continuation</p>\n" +
+        		             "<a href=\"#fnref-1\" class=\"footnote-backref\">&#8617;</a>\n" +
+        		             "</li>\n" +
+        		             "</ol>\n" +
+        		             "</div>\n", translate( src ) );
+    }
+
+    @Test
+    public void testAttachmentLink() throws Exception {
+        String src = "This should be an [attachment link](Test/TestAtt.txt)";
+        newPage( "Test" );
+
+        Attachment att = new Attachment( testEngine, "Test", "TestAtt.txt" );
+        att.setAuthor( "FirstPost" );
+        testEngine.getAttachmentManager().storeAttachment( att, testEngine.makeAttachmentFile() );
+
+        Assert.assertEquals( "<p>This should be an <a href=\"/test/attach/Test/TestAtt.txt\" class=\"attachment\">attachment link</a>" +
+                             "<a href=\"/test/PageInfo.jsp?page=Test/TestAtt.txt\" class=\"infolink\">" +
+                               "<img src=\"/test/images/attachment_small.png\" border=\"0\" alt=\"(info)\" />" +
+                             "</a></p>\n",
+                translate( src ) );
+    }
+
+    @Test
+    public void testInlineImages() throws Exception {
+        String src = "Link [test](http://www.ecyrd.com/test.png)";
+
+        Assert.assertEquals( "<p>Link <img class=\"inline\" src=\"http://www.ecyrd.com/test.png\" alt=\"test\" /></p>\n", translate( src ) );
+    }
+
+    @Test
+    public void testInlineImages2() throws Exception {
+        String src = "Link [test](http://www.ecyrd.com/test.ppm)";
+
+        Assert.assertEquals( "<p>Link <a href=\"http://www.ecyrd.com/test.ppm\" class=\"external\">test</a></p>\n", translate( src ) );
+    }
+
+    @Test
+    public void testInlineImages3() throws Exception {
+        String src = "Link [test](http://images.com/testi)";
+
+        Assert.assertEquals( "<p>Link <img class=\"inline\" src=\"http://images.com/testi\" alt=\"test\" /></p>\n", translate( src ) );
+    }
+
+    @Test
+    public void testInlineImages4() throws Exception {
+        String src = "Link [test](http://foobar.jpg)";
+
+        Assert.assertEquals( "<p>Link <img class=\"inline\" src=\"http://foobar.jpg\" alt=\"test\" /></p>\n", translate( src ) );
+    }
+
+    // No link text should be just embedded link.
+    @Test
+    public void testInlineImagesLink2() throws Exception {
+        String src = "Link [http://foobar.jpg]()";
+
+        Assert.assertEquals( "<p>Link <img class=\"inline\" src=\"http://foobar.jpg\" alt=\"http://foobar.jpg\" /></p>\n", translate( src ) );
+    }
+
+    @Test
+    public void testInlineImagesLink() throws Exception {
+        String src = "Link [http://link.to/](http://foobar.jpg)";
+
+        Assert.assertEquals( "<p>Link <a href=\"http://link.to/\" class=\"external\"><img class=\"inline\" src=\"http://foobar.jpg\" alt=\"http://link.to/\" /></a></p>\n",
+                             translate( src ) );
+    }
+
+    @Test
+    public void testInlineImagesLink3() throws Exception {
+        String src = "Link [SandBox](http://foobar.jpg)";
+
+        newPage( "SandBox" );
+
+        Assert.assertEquals( "<p>Link <a href=\"/test/Wiki.jsp?page=SandBox\" class=\"wikipage\"><img class=\"inline\" src=\"http://foobar.jpg\" alt=\"SandBox\" /></a></p>\n",
+                             translate( src ) );
+    }
+
+    @Test
+    public void testHeadersWithSameNameGetIdWithCounter() throws Exception {
+        String src = "### Awesome H3\n" +
+                     "### Awesome H3";
+
+        Assert.assertEquals( "<h3 id=\"awesome-h3\">Awesome H3</h3>\n" +
+                             "<h3 id=\"awesome-h3-1\">Awesome H3</h3>\n",
+                             translate( src ) );
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        CacheManager.getInstance().removeAllCaches();
+        props.setProperty( "jspwiki.translatorReader.matchEnglishPlurals", "true" );
+        props.setProperty( "jspwiki.fileSystemProvider.pageDir", "./target/md-pageDir" );
+        props.setProperty( "jspwiki.renderingManager.markupParser", MarkdownParser.class.getName() );
+        props.setProperty( "jspwiki.renderingManager.renderer", MarkdownRenderer.class.getName() );
+        testEngine = new TestEngine( props );
+    }
+
+    @After
+    public void tearDown() {
+        for( String name : created ) {
+            testEngine.deleteTestPage(name);
+            TestEngine.deleteAttachments(name);
+        }
+
+        created.clear();
+    }
+
+    String translate( final String src ) throws Exception {
+        return translate( new WikiPage( testEngine, PAGE_NAME ), src );
+    }
+
+    String translate( final WikiEngine e, final String src) throws Exception {
+        return translate( e, new WikiPage( testEngine, PAGE_NAME ), src );
+    }
+
+    String translate( final WikiPage p, final String src ) throws Exception {
+        return translate( testEngine, p, src );
+    }
+
+    String translate( final WikiEngine e, final WikiPage p, final String src ) throws Exception {
+        WikiContext context = new WikiContext( e, testEngine.newHttpRequest(), p );
+        MarkdownParser tr = new MarkdownParser( context, new BufferedReader( new StringReader( src ) ) );
+        MarkdownRenderer conv = new MarkdownRenderer( context, tr.parse() );
+        newPage( p.getName(), src );
+
+        return conv.getString();
+    }
+
+    void newPage( final String name ) throws WikiException {
+        newPage( name, "<test>" );
+    }
+
+    void newPage( final String name, final String text ) throws WikiException {
+        testEngine.saveText( name, text );
+        created.add( name );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 8d59078..0c548c8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,9 @@
     specific language governing permissions and limitations
     under the License.
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 
   <parent>
     <groupId>org.apache</groupId>
@@ -39,6 +41,7 @@
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <flexmark.version>0.28.14</flexmark.version>
     <jdk.version>1.6</jdk.version>
     <lucene.version>4.7.0</lucene.version>
     <selenium.version>2.42.0</selenium.version>
@@ -68,6 +71,24 @@
     <dependencies>       <!-- ordered alphabetically by scope:groupId:artifactId                                     -->
       <!-- compile dependencies -->
       <dependency>
+        <groupId>com.vladsch.flexmark</groupId>
+        <artifactId>flexmark</artifactId>
+        <version>${flexmark.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>com.vladsch.flexmark</groupId>
+        <artifactId>flexmark-ext-footnotes</artifactId>
+        <version>${flexmark.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>com.vladsch.flexmark</groupId>
+        <artifactId>flexmark-ext-toc</artifactId>
+        <version>${flexmark.version}</version>
+      </dependency>
+
+      <dependency>
         <groupId>com.google.code.gson</groupId>
         <artifactId>gson</artifactId>
         <version>2.3.1</version>
@@ -228,7 +249,7 @@
       <dependency>
         <groupId>net.sourceforge.stripes</groupId>
         <artifactId>stripes</artifactId>
-        <version>1.5.8</version>
+        <version>1.6.0</version>
       </dependency>
 
       <!--
@@ -269,11 +290,11 @@
       </dependency>
 
       <!-- runtime dependencies -->
-        <dependency>
-            <groupId>net.sourceforge.nekohtml</groupId>
-            <artifactId>nekohtml</artifactId>
-            <version>1.9.21</version>
-        </dependency>
+      <dependency>
+        <groupId>net.sourceforge.nekohtml</groupId>
+        <artifactId>nekohtml</artifactId>
+        <version>1.9.21</version>
+      </dependency>
     </dependencies>
   </dependencyManagement>
 
@@ -668,6 +689,20 @@
         </plugins>
       </build>
     </profile>
+
+    <profile>
+      <id>markdown-support</id>
+      <activation>
+        <jdk>[1.7,)</jdk>
+      </activation>
+      <modules>
+        <module>jspwiki-wikipages</module>
+        <module>jspwiki-war</module>
+        <module>jspwiki-markdown</module>
+        <module>jspwiki-portable</module>
+        <module>jspwiki-it-tests</module><!-- IT tests are launched only if -Pintegration-tests is given -->
+      </modules>
+    </profile>
   </profiles>
 
   <organization>


[4/5] jspwiki git commit: 2.10.3-git-44: initial markdown support

Posted by ju...@apache.org.
2.10.3-git-44: initial markdown support


Project: http://git-wip-us.apache.org/repos/asf/jspwiki/repo
Commit: http://git-wip-us.apache.org/repos/asf/jspwiki/commit/05cad3c7
Tree: http://git-wip-us.apache.org/repos/asf/jspwiki/tree/05cad3c7
Diff: http://git-wip-us.apache.org/repos/asf/jspwiki/diff/05cad3c7

Branch: refs/heads/master
Commit: 05cad3c7f12c77763da0f344330f46638b7bdb92
Parents: c1793a1
Author: juanpablo <ju...@apache.org>
Authored: Fri Dec 8 22:38:25 2017 +0100
Committer: juanpablo <ju...@apache.org>
Committed: Fri Dec 8 22:38:25 2017 +0100

----------------------------------------------------------------------
 ChangeLog                                              | 8 ++++++++
 jspwiki-war/src/main/java/org/apache/wiki/Release.java | 2 +-
 2 files changed, 9 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jspwiki/blob/05cad3c7/ChangeLog
----------------------------------------------------------------------
diff --git a/ChangeLog b/ChangeLog
index f67f30a..6136842 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2017-12-08  Juan Pablo Santos (juanpablo AT apache DOT org)
+
+       * 2.10.3-git-44
+       
+       * JSPWIKI-802 - initial markdown support see 
+         https://jspwiki-wiki.apache.org/Wiki.jsp?page=Markdown%20Support
+         for details
+       
 2017-12-03  Juan Pablo Santos (juanpablo AT apache DOT org)
 
        * 2.10.3-git-43

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/05cad3c7/jspwiki-war/src/main/java/org/apache/wiki/Release.java
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/java/org/apache/wiki/Release.java b/jspwiki-war/src/main/java/org/apache/wiki/Release.java
index 1a1f509..3e70952 100644
--- a/jspwiki-war/src/main/java/org/apache/wiki/Release.java
+++ b/jspwiki-war/src/main/java/org/apache/wiki/Release.java
@@ -72,7 +72,7 @@ public final class Release {
      *  <p>
      *  If the build identifier is empty, it is not added.
      */
-    public static final String     BUILD         = "43";
+    public static final String     BUILD         = "44";
 
     /**
      *  This is the generic version string you should use when printing out the version.  It is of


[3/5] jspwiki git commit: JSPWIKI-802: initial markdown support

Posted by ju...@apache.org.
JSPWIKI-802: initial markdown support


Project: http://git-wip-us.apache.org/repos/asf/jspwiki/repo
Commit: http://git-wip-us.apache.org/repos/asf/jspwiki/commit/c1793a18
Tree: http://git-wip-us.apache.org/repos/asf/jspwiki/tree/c1793a18
Diff: http://git-wip-us.apache.org/repos/asf/jspwiki/diff/c1793a18

Branch: refs/heads/master
Commit: c1793a182361f2359ededea21af81fa6fb01cc98
Parents: 746492f
Author: juanpablo <ju...@apache.org>
Authored: Fri Dec 8 22:37:40 2017 +0100
Committer: juanpablo <ju...@apache.org>
Committed: Fri Dec 8 22:37:40 2017 +0100

----------------------------------------------------------------------
 jspwiki-markdown/pom.xml                        |  99 ++++++
 .../markdown/MarkdownForJSPWikiExtension.java   | 111 +++++++
 .../ExternalLinkAttributeProviderState.java     |  66 ++++
 .../ImageLinkAttributeProviderState.java        |  66 ++++
 .../InterWikiLinkAttributeProviderState.java    |  79 +++++
 .../LocalEditLinkAttributeProviderState.java    |  61 ++++
 ...LocalFootnoteLinkAttributeProviderState.java |  52 +++
 ...alFootnoteRefLinkAttributeProviderState.java |  52 +++
 .../LocalLinkAttributeProviderState.java        |  83 +++++
 .../LocalReadLinkAttributeProviderState.java    |  54 ++++
 .../MarkdownForJSPWikiAttributeProvider.java    |  78 +++++
 .../NodeAttributeProviderState.java             |  38 +++
 .../WysiwygEditingAttributeProviderState.java   |  90 ++++++
 .../jspwikilinks/attributeprovider/package.html |  34 ++
 .../AccessRuleLinkNodePostProcessorState.java   |  77 +++++
 .../ExternalLinkNodePostProcessorState.java     |  60 ++++
 .../FootnoteRefLinkNodePostProcessorState.java  |  47 +++
 .../ImageLinkNodePostProcessorState.java        |  65 ++++
 .../InterWikiLinkNodePostProcessorState.java    |  87 +++++
 .../JSPWikiLinkNodePostProcessor.java           |  91 ++++++
 .../LocalLinkNodePostProcessorState.java        |  76 +++++
 .../MetadataLinkNodePostProcessorState.java     |  88 +++++
 .../postprocessor/NodePostProcessorState.java   |  38 +++
 .../NodePostProcessorStateCommonOperations.java |  79 +++++
 .../PluginLinkNodePostProcessorState.java       | 138 ++++++++
 .../VariableLinkNodePostProcessorState.java     |  65 ++++
 .../jspwikilinks/postprocessor/package.html     |  34 ++
 .../java/org/apache/wiki/markdown/package.html  |  34 ++
 .../wiki/parser/markdown/MarkdownDocument.java  |  73 +++++
 .../wiki/parser/markdown/MarkdownParser.java    |  59 ++++
 .../apache/wiki/parser/markdown/package.html    |  34 ++
 .../wiki/render/markdown/MarkdownRenderer.java  |  56 ++++
 .../apache/wiki/render/markdown/package.html    |  34 ++
 .../wiki/render/MarkdownRendererTest.java       | 322 +++++++++++++++++++
 pom.xml                                         |  49 ++-
 35 files changed, 2562 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/pom.xml
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/pom.xml b/jspwiki-markdown/pom.xml
new file mode 100755
index 0000000..ffda979
--- /dev/null
+++ b/jspwiki-markdown/pom.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.apache.jspwiki</groupId>
+    <artifactId>jspwiki-builder</artifactId>
+    <version>2.10.3-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>jspwiki-markdown</artifactId>
+  <modelVersion>4.0.0</modelVersion>
+  <name>Apache JSPWiki markdown support</name>
+  <description>Apache JSPWiki markdown support</description>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>jspwiki-war</artifactId>
+      <version>${project.version}</version>
+      <classifier>classes</classifier>
+      <scope>provided</scope>
+    </dependency>
+    
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>jspwiki-war</artifactId>
+      <type>test-jar</type>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>com.vladsch.flexmark</groupId>
+      <artifactId>flexmark</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.vladsch.flexmark</groupId>
+      <artifactId>flexmark-ext-footnotes</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.vladsch.flexmark</groupId>
+      <artifactId>flexmark-ext-toc</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>net.sourceforge.stripes</groupId>
+      <artifactId>stripes</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <configuration>
+            <source>1.7</source>
+            <target>1.7</target>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/MarkdownForJSPWikiExtension.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/MarkdownForJSPWikiExtension.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/MarkdownForJSPWikiExtension.java
new file mode 100755
index 0000000..9533a9d
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/MarkdownForJSPWikiExtension.java
@@ -0,0 +1,111 @@
+/*
+    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.wiki.markdown;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.markdown.extensions.jspwikilinks.attributeprovider.MarkdownForJSPWikiAttributeProvider;
+import org.apache.wiki.markdown.extensions.jspwikilinks.postprocessor.JSPWikiLinkNodePostProcessor;
+
+import com.vladsch.flexmark.ast.Document;
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.html.AttributeProvider;
+import com.vladsch.flexmark.html.AttributeProviderFactory;
+import com.vladsch.flexmark.html.HtmlRenderer;
+import com.vladsch.flexmark.html.IndependentAttributeProviderFactory;
+import com.vladsch.flexmark.html.renderer.NodeRendererContext;
+import com.vladsch.flexmark.parser.Parser;
+import com.vladsch.flexmark.parser.block.NodePostProcessor;
+import com.vladsch.flexmark.parser.block.NodePostProcessorFactory;
+import com.vladsch.flexmark.util.options.DataHolder;
+import com.vladsch.flexmark.util.options.MutableDataHolder;
+
+
+/**
+ * Flexmark entry point for JSPWiki extensions
+ */
+public class MarkdownForJSPWikiExtension implements Parser.ParserExtension, HtmlRenderer.HtmlRendererExtension {
+
+	private final WikiContext context;
+
+	public MarkdownForJSPWikiExtension( final WikiContext context ) {
+		this.context = context;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void rendererOptions( final MutableDataHolder options ) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void parserOptions( final MutableDataHolder options ) {
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void extend( final HtmlRenderer.Builder rendererBuilder, final String rendererType ) {
+        rendererBuilder.attributeProviderFactory( jspWikiAttributeProviderFactory( context ) );
+	}
+
+    /**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void extend( final Parser.Builder parserBuilder ) {
+	    parserBuilder.postProcessorFactory( new JSPWikiNodePostProcessorFactory( context, parserBuilder ) );
+	}
+
+	AttributeProviderFactory jspWikiAttributeProviderFactory( final WikiContext wContext ) {
+		return new IndependentAttributeProviderFactory() {
+			/**
+			 * {@inheritDoc}
+			 */
+			@Override
+			public AttributeProvider create( final NodeRendererContext context ) {
+				return new MarkdownForJSPWikiAttributeProvider( wContext );
+			}
+		};
+	}
+
+    static class JSPWikiNodePostProcessorFactory extends NodePostProcessorFactory {
+
+        private final WikiContext m_context;
+
+        public JSPWikiNodePostProcessorFactory( final WikiContext m_context, final DataHolder options ) {
+            super( true );
+            addNodes( Link.class ); // needs to be called before create( Document )
+            this.m_context = m_context;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public NodePostProcessor create( final Document document ) {
+            return new JSPWikiLinkNodePostProcessor( m_context, document );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/ExternalLinkAttributeProviderState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/ExternalLinkAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/ExternalLinkAttributeProviderState.java
new file mode 100755
index 0000000..f76a8e8
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/ExternalLinkAttributeProviderState.java
@@ -0,0 +1,66 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.LinkParsingOperations;
+import org.apache.wiki.parser.MarkupParser;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.html.Attributes;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodeAttributeProviderState} which sets the attributes for external links.
+ */
+public class ExternalLinkAttributeProviderState implements NodeAttributeProviderState< Link > {
+
+    private final boolean hasRef;
+    private final boolean m_useRelNofollow;
+    private final WikiContext wikiContext;
+    private final LinkParsingOperations linkOperations;
+
+    public ExternalLinkAttributeProviderState( final WikiContext wikiContext, final boolean hasRef ) {
+        this.hasRef = hasRef;
+        this.wikiContext = wikiContext;
+        this.linkOperations = new LinkParsingOperations( wikiContext );
+        this.m_useRelNofollow = wikiContext.getBooleanWikiProperty( MarkupParser.PROP_USERELNOFOLLOW, false );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodeAttributeProviderState#setAttributes(Attributes, Link)
+     */
+    @Override
+    public void setAttributes( final Attributes attributes, final Link link ) {
+        if( linkOperations.isImageLink( link.getUrl().toString() ) ) {
+            new ImageLinkAttributeProviderState( wikiContext, link.getText().toString(), hasRef ).setAttributes( attributes, link );
+        } else {
+            attributes.replaceValue( "class", MarkupParser.CLASS_EXTERNAL );
+            link.setUrl( CharSubSequence.of( link.getUrl().toString() ) );
+            attributes.replaceValue( "href", link.getUrl().toString() );
+        }
+        if( m_useRelNofollow ) {
+            attributes.replaceValue( "rel", "nofollow" );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/ImageLinkAttributeProviderState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/ImageLinkAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/ImageLinkAttributeProviderState.java
new file mode 100755
index 0000000..2ef6aa7
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/ImageLinkAttributeProviderState.java
@@ -0,0 +1,66 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.LinkParsingOperations;
+import org.apache.wiki.parser.MarkupParser;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.html.Attributes;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodeAttributeProviderState} which sets the attributes for image links.
+ */
+public class ImageLinkAttributeProviderState implements NodeAttributeProviderState< Link > {
+
+    private final boolean isLinkFromText;
+    private final LinkParsingOperations linkOperations;
+    private final WikiContext wikiContext;
+    private final String urlRef;
+
+    public ImageLinkAttributeProviderState( final WikiContext wikiContext, final String urlRef, final boolean isLinkFromText ) {
+        this.isLinkFromText = isLinkFromText;
+        this.urlRef = urlRef;
+        this.wikiContext = wikiContext;
+        this.linkOperations = new LinkParsingOperations( wikiContext );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodeAttributeProviderState#setAttributes(Attributes, Link)
+     */
+    @Override
+    public void setAttributes( final Attributes attributes, final Link link ) {
+        if( isLinkFromText && linkOperations.isExternalLink( link.getText().toString() ) ) {
+            attributes.replaceValue( "class", MarkupParser.CLASS_EXTERNAL );
+            link.setUrl( CharSubSequence.of( urlRef ) );
+            attributes.replaceValue( "href", urlRef );
+        } else if ( isLinkFromText && linkOperations.linkExists( link.getText().toString() ) ) {
+            final String pagelink = wikiContext.getURL( WikiContext.VIEW, link.getText().toString() );
+            attributes.replaceValue( "class", MarkupParser.CLASS_WIKIPAGE );
+            link.setUrl( CharSubSequence.of( pagelink ) );
+            attributes.replaceValue( "href", pagelink );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/InterWikiLinkAttributeProviderState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/InterWikiLinkAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/InterWikiLinkAttributeProviderState.java
new file mode 100755
index 0000000..28e1ffa
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/InterWikiLinkAttributeProviderState.java
@@ -0,0 +1,79 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.LinkParsingOperations;
+import org.apache.wiki.parser.MarkupParser;
+import org.apache.wiki.render.RenderingManager;
+import org.apache.wiki.util.TextUtil;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.html.Attributes;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodeAttributeProviderState} which sets the attributes for interwiki links.
+ */
+public class InterWikiLinkAttributeProviderState implements NodeAttributeProviderState< Link > {
+
+    private final boolean hasRef;
+    private final boolean m_wysiwygEditorMode;
+    private final WikiContext wikiContext;
+    private final LinkParsingOperations linkOperations;
+
+    public InterWikiLinkAttributeProviderState( final WikiContext wikiContext, final boolean hasRef ) {
+        this.hasRef = hasRef;
+        this.wikiContext = wikiContext;
+        this.linkOperations = new LinkParsingOperations( wikiContext );
+        final Boolean wysiwygVariable = ( Boolean )wikiContext.getVariable( RenderingManager.WYSIWYG_EDITOR_MODE );
+        m_wysiwygEditorMode = wysiwygVariable != null ? wysiwygVariable.booleanValue() : false;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodeAttributeProviderState#setAttributes(Attributes, Link)
+     */
+    @Override
+    public void setAttributes( final Attributes attributes, final Link link ) {
+        final String[] refAndPage = link.getUrl().toString().split( ":" );
+        if( m_wysiwygEditorMode ) {
+            setInterWikiLinkAttrs( attributes, link, refAndPage[0] + ":" + refAndPage[1] );
+        } else {
+            String urlReference = wikiContext.getEngine().getInterWikiURL( refAndPage[ 0 ] );
+            if( urlReference != null ) {
+                urlReference = TextUtil.replaceString( urlReference, "%s", refAndPage[ 1 ] );
+                if( linkOperations.isImageLink( urlReference ) ) {
+                    new ImageLinkAttributeProviderState( wikiContext, urlReference, hasRef ).setAttributes( attributes, link );
+                } else {
+                    setInterWikiLinkAttrs( attributes, link, urlReference );
+                }
+            }
+        }
+    }
+
+    void setInterWikiLinkAttrs( final Attributes attributes, final Link link, final String url ) {
+        attributes.replaceValue( "class", MarkupParser.CLASS_INTERWIKI );
+        link.setUrl( CharSubSequence.of( url ) );
+        attributes.replaceValue( "href", url );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalEditLinkAttributeProviderState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalEditLinkAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalEditLinkAttributeProviderState.java
new file mode 100755
index 0000000..d7b1157
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalEditLinkAttributeProviderState.java
@@ -0,0 +1,61 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.parser.MarkupParser;
+import org.apache.wiki.preferences.Preferences;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.html.Attributes;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodeAttributeProviderState} which sets the attributes for local edit links.
+ */
+public class LocalEditLinkAttributeProviderState implements NodeAttributeProviderState< Link > {
+
+    private final WikiContext wikiContext;
+    private final String url;
+
+    public LocalEditLinkAttributeProviderState( final WikiContext wikiContext, final String url ) {
+        this.wikiContext = wikiContext;
+        this.url = url;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodeAttributeProviderState#setAttributes(Attributes, Link)
+     */
+    @Override
+    public void setAttributes( final Attributes attributes, final Link link ) {
+        final ResourceBundle rb = Preferences.getBundle( wikiContext, InternationalizationManager.CORE_BUNDLE );
+        attributes.replaceValue( "title", MessageFormat.format( rb.getString( "markupparser.link.create" ), url ) );
+        attributes.replaceValue( "class", MarkupParser.CLASS_EDITPAGE );
+        link.setUrl( CharSubSequence.of( wikiContext.getURL( WikiContext.EDIT, url ) ) );
+        attributes.replaceValue( "href", link.getUrl().toString() );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalFootnoteLinkAttributeProviderState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalFootnoteLinkAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalFootnoteLinkAttributeProviderState.java
new file mode 100755
index 0000000..63dbebb
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalFootnoteLinkAttributeProviderState.java
@@ -0,0 +1,52 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.MarkupParser;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.html.Attributes;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodeAttributeProviderState} which sets the attributes for local footnote links.
+ */
+public class LocalFootnoteLinkAttributeProviderState implements NodeAttributeProviderState< Link > {
+
+    private final WikiContext wikiContext;
+
+    public LocalFootnoteLinkAttributeProviderState( final WikiContext wikiContext ) {
+        this.wikiContext = wikiContext;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodeAttributeProviderState#setAttributes(Attributes, Link)
+     */
+    @Override
+    public void setAttributes( final Attributes attributes, final Link link ) {
+        attributes.replaceValue( "class", MarkupParser.CLASS_FOOTNOTE );
+        link.setUrl( CharSubSequence.of( wikiContext.getURL( WikiContext.VIEW, link.getUrl().toString() ) ) );
+        attributes.replaceValue( "href", link.getUrl().toString() );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalFootnoteRefLinkAttributeProviderState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalFootnoteRefLinkAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalFootnoteRefLinkAttributeProviderState.java
new file mode 100755
index 0000000..7389e02
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalFootnoteRefLinkAttributeProviderState.java
@@ -0,0 +1,52 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.MarkupParser;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.html.Attributes;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodeAttributeProviderState} which sets the attributes for local footnote reference links.
+ */
+public class LocalFootnoteRefLinkAttributeProviderState implements NodeAttributeProviderState< Link > {
+
+    private final WikiContext wikiContext;
+
+    public LocalFootnoteRefLinkAttributeProviderState( final WikiContext wikiContext ) {
+        this.wikiContext = wikiContext;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodeAttributeProviderState#setAttributes(Attributes, Link)
+     */
+    @Override
+    public void setAttributes( final Attributes attributes, final Link link ) {
+        attributes.replaceValue( "class", MarkupParser.CLASS_FOOTNOTE_REF );
+        link.setUrl( CharSubSequence.of( wikiContext.getURL( WikiContext.VIEW, link.getUrl().toString() ) ) );
+        attributes.replaceValue( "href", "#ref-" + wikiContext.getName() + "-" + link.getText().toString() );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalLinkAttributeProviderState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalLinkAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalLinkAttributeProviderState.java
new file mode 100755
index 0000000..5c21d07
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalLinkAttributeProviderState.java
@@ -0,0 +1,83 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.LinkParsingOperations;
+import org.apache.wiki.parser.MarkupParser;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.html.Attributes;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodeAttributeProviderState} which sets the attributes for local links.
+ */
+public class LocalLinkAttributeProviderState implements NodeAttributeProviderState< Link > {
+
+    private final boolean hasRef;
+    private final WikiContext wikiContext;
+    private final LinkParsingOperations linkOperations;
+
+    public LocalLinkAttributeProviderState( final WikiContext wikiContext, final boolean hasRef ) {
+        this.hasRef = hasRef;
+        this.wikiContext = wikiContext;
+        this.linkOperations = new LinkParsingOperations( wikiContext );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodeAttributeProviderState#setAttributes(Attributes, Link)
+     */
+    @Override
+    public void setAttributes( final Attributes attributes, final Link link ) {
+        final int hashMark = link.getUrl().toString().indexOf( '#' );
+        final String attachment = wikiContext.getEngine().getAttachmentManager().getAttachmentInfoName( wikiContext, link.getUrl().toString() );
+        if( attachment != null ) {
+            if( !linkOperations.isImageLink( link.getUrl().toString() ) ) {
+                attributes.replaceValue( "class", MarkupParser.CLASS_ATTACHMENT );
+                final String attlink = wikiContext.getURL( WikiContext.ATTACH, link.getUrl().toString() );
+                link.setUrl( CharSubSequence.of( attlink ) );
+                attributes.replaceValue( "href", attlink );
+            } else {
+                new ImageLinkAttributeProviderState( wikiContext, attachment, hasRef ).setAttributes( attributes, link );
+            }
+        } else if( hashMark != -1 ) { // It's an internal Wiki link, but to a named section
+            final String namedSection = link.getUrl().toString().substring( hashMark + 1 );
+            link.setUrl( CharSubSequence.of( link.getUrl().toString().substring( 0, hashMark ) ) );
+            final String matchedLink = linkOperations.linkIfExists( link.getUrl().toString() );
+            if( matchedLink != null ) {
+                String sectref = "#section-" + wikiContext.getEngine().encodeName( matchedLink + "-" + MarkupParser.wikifyLink( namedSection ) );
+                sectref = sectref.replace('%', '_');
+                new LocalReadLinkAttributeProviderState( wikiContext, link.getUrl().toString() + sectref ).setAttributes( attributes, link );
+            } else {
+                new LocalEditLinkAttributeProviderState( wikiContext, link.getUrl().toString() ).setAttributes( attributes, link );
+            }
+        } else {
+            if( linkOperations.linkExists( link.getUrl().toString() ) ) {
+                new LocalReadLinkAttributeProviderState( wikiContext, link.getUrl().toString() ).setAttributes( attributes, link );
+            } else {
+                new LocalEditLinkAttributeProviderState( wikiContext, link.getUrl().toString() ).setAttributes( attributes, link );
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalReadLinkAttributeProviderState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalReadLinkAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalReadLinkAttributeProviderState.java
new file mode 100755
index 0000000..aa81379
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/LocalReadLinkAttributeProviderState.java
@@ -0,0 +1,54 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.MarkupParser;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.html.Attributes;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodeAttributeProviderState} which sets the attributes for local read links.
+ */
+public class LocalReadLinkAttributeProviderState implements NodeAttributeProviderState< Link > {
+
+    private final WikiContext wikiContext;
+    private final String url;
+
+    public LocalReadLinkAttributeProviderState( final WikiContext wikiContext, final String url ) {
+        this.wikiContext = wikiContext;
+        this.url = url;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodeAttributeProviderState#setAttributes(Attributes, Link)
+     */
+    @Override
+    public void setAttributes( final Attributes attributes, final Link link ) {
+        attributes.replaceValue( "class", MarkupParser.CLASS_WIKIPAGE );
+        link.setUrl( CharSubSequence.of( wikiContext.getURL( WikiContext.VIEW, url ) ) );
+        attributes.replaceValue( "href", link.getUrl().toString() );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/MarkdownForJSPWikiAttributeProvider.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/MarkdownForJSPWikiAttributeProvider.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/MarkdownForJSPWikiAttributeProvider.java
new file mode 100755
index 0000000..a295397
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/MarkdownForJSPWikiAttributeProvider.java
@@ -0,0 +1,78 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.LinkParsingOperations;
+import org.apache.wiki.util.TextUtil;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.ast.Node;
+import com.vladsch.flexmark.html.AttributeProvider;
+import com.vladsch.flexmark.html.renderer.AttributablePart;
+import com.vladsch.flexmark.util.html.Attributes;
+
+
+/**
+ * {@link AttributeProvider} for JSPWiki links.
+ *
+ * Acts as a factory of {@link NodeAttributeProviderState}, which are the classes setting the attributes for each concrete type of link.
+ */
+public class MarkdownForJSPWikiAttributeProvider implements AttributeProvider {
+
+    protected final WikiContext wikiContext;
+    protected final LinkParsingOperations linkOperations;
+
+    public MarkdownForJSPWikiAttributeProvider( final WikiContext wikiContext ) {
+        this.wikiContext = wikiContext;
+        this.linkOperations = new LinkParsingOperations( wikiContext );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see AttributeProvider#setAttributes(Node, AttributablePart, Attributes)
+     */
+    @Override
+    public void setAttributes( final Node node, final AttributablePart part, final Attributes attributes ) {
+        if( node instanceof Link ) {
+            final Link link = ( Link )node;
+            boolean hasRef = true;
+            if( StringUtils.isEmpty( link.getUrl().toString() ) ) { // empty link == link.getText() is a wiki page
+                link.setUrl( link.getText() );
+                hasRef = false;
+            }
+            final NodeAttributeProviderState< Link > linkState;
+            if( linkOperations.isExternalLink( link.getUrl().toString() ) ) {
+                linkState = new ExternalLinkAttributeProviderState( wikiContext, hasRef );
+            } else if( linkOperations.isInterWikiLink( link.getUrl().toString() ) ) {
+                linkState = new InterWikiLinkAttributeProviderState( wikiContext, hasRef );
+            } else if( StringUtils.startsWith( link.getUrl().toString(), "#" ) ) {
+                linkState = new LocalFootnoteLinkAttributeProviderState( wikiContext );
+            } else if( TextUtil.isNumber( link.getUrl().toString() ) ) {
+                linkState = new LocalFootnoteRefLinkAttributeProviderState( wikiContext );
+            } else {
+                linkState = new LocalLinkAttributeProviderState( wikiContext, hasRef );
+            }
+            linkState.setAttributes( attributes, link );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/NodeAttributeProviderState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/NodeAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/NodeAttributeProviderState.java
new file mode 100755
index 0000000..134ce43
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/NodeAttributeProviderState.java
@@ -0,0 +1,38 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import com.vladsch.flexmark.ast.Node;
+import com.vladsch.flexmark.util.html.Attributes;
+
+
+/**
+ * Encapsulates different attribute's set for different kinds of nodes.
+ */
+public interface NodeAttributeProviderState < T extends Node > {
+
+    /**
+     * Sets node's attributes.
+     *
+     * @param attributes node attributes.
+     * @param node the specific node in which the attributes are going to be set.
+     */
+    void setAttributes( Attributes attributes, T node );
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/WysiwygEditingAttributeProviderState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/WysiwygEditingAttributeProviderState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/WysiwygEditingAttributeProviderState.java
new file mode 100755
index 0000000..eeb8034
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/WysiwygEditingAttributeProviderState.java
@@ -0,0 +1,90 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.attributeprovider;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.htmltowiki.XHtmlToWikiConfig;
+import org.apache.wiki.render.RenderingManager;
+import org.apache.wiki.render.WikiRenderer;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.html.Attributes;
+
+
+/**
+ * {@link NodeAttributeProviderState} to finish up polishing WYSIWYG editing mode. More or less equivalent to WysiwygEditingRenderer, the main difference
+ * being that in here there isn't any node removal, those nodes are simply not inserted elsewhere if WYSIWYG editing is detected.
+ */
+public class WysiwygEditingAttributeProviderState implements NodeAttributeProviderState< Link > {
+
+    private final WikiContext wikiContext;
+    private final boolean m_wysiwygEditorMode;
+
+    public WysiwygEditingAttributeProviderState( final WikiContext wikiContext ) {
+        this.wikiContext = wikiContext;
+        final Boolean wysiwygVariable = ( Boolean )wikiContext.getVariable( RenderingManager.WYSIWYG_EDITOR_MODE );
+        m_wysiwygEditorMode = wysiwygVariable != null ? wysiwygVariable.booleanValue() : false;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodeAttributeProviderState#setAttributes(Attributes, Link)
+     */
+    @Override
+    public void setAttributes( final Attributes attributes, final Link link ) {
+        if( m_wysiwygEditorMode ) {
+            if( attributes.getValue( "class" ) != null ) {
+                String href = attributes.getValue( "href" );
+                XHtmlToWikiConfig wikiConfig = new XHtmlToWikiConfig( wikiContext );
+                // Get the url for wiki page link - it's typically "Wiki.jsp?page=MyPage"
+                // or when using the ShortURLConstructor option, it's "wiki/MyPage" .
+                String wikiPageLinkUrl = wikiConfig.getWikiJspPage();
+                String editPageLinkUrl = wikiConfig.getEditJspPage();
+                if( href != null && href.startsWith( wikiPageLinkUrl ) ) {
+                    // Remove the leading url string so that users will only see the
+                    // wikipage's name when editing an existing wiki link.
+                    // For example, change "Wiki.jsp?page=MyPage" to just "MyPage".
+
+                    String newHref = href.substring( wikiPageLinkUrl.length() );
+
+                    // Convert "This%20Pagename%20Has%20Spaces" to "This Pagename Has Spaces"
+                    newHref = wikiContext.getEngine().decodeName( newHref );
+
+                    // Handle links with section anchors.
+                    // For example, we need to translate the html string "TargetPage#section-TargetPage-Heading2"
+                    // to this wiki string: "TargetPage#Heading2".
+                    attributes.replaceValue( "href", newHref.replaceFirst( WikiRenderer.LINKS_SOURCE, WikiRenderer.LINKS_TRANSLATION ) );
+                } else if( href != null && href.startsWith( editPageLinkUrl ) ) {
+                    String title = attributes.getValue( "title" );
+                    if( title != null ) {
+                        // remove the title since we don't want to eventually save the default undefined page title.
+                        attributes.replaceValue( "title", "" );
+                    }
+
+                    String newHref = href.substring( editPageLinkUrl.length() );
+                    newHref = wikiContext.getEngine().decodeName( newHref );
+
+                    attributes.replaceValue( "href", newHref );
+                }
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/package.html
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/package.html b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/package.html
new file mode 100755
index 0000000..2e5b025
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/attributeprovider/package.html
@@ -0,0 +1,34 @@
+<!--
+    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.
+-->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+Wikilinks' attributes custom decoration.
+
+<h3>Package Specification</h3>
+
+<h3>Related Documentation</h3>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/AccessRuleLinkNodePostProcessorState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/AccessRuleLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/AccessRuleLinkNodePostProcessorState.java
new file mode 100755
index 0000000..2f73048
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/AccessRuleLinkNodePostProcessorState.java
@@ -0,0 +1,77 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import org.apache.log4j.Logger;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.auth.WikiSecurityException;
+import org.apache.wiki.auth.acl.Acl;
+import org.apache.wiki.render.RenderingManager;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.NodeTracker;
+
+
+/**
+ * {@link NodePostProcessorState} which further post processes access rules links.
+ */
+public class AccessRuleLinkNodePostProcessorState implements NodePostProcessorState< Link > {
+
+    private static final Logger LOG = Logger.getLogger( AccessRuleLinkNodePostProcessorState.class );
+    private final WikiContext wikiContext;
+    private final boolean m_wysiwygEditorMode;
+
+    public AccessRuleLinkNodePostProcessorState( final WikiContext wikiContext ) {
+        this.wikiContext = wikiContext;
+        final Boolean wysiwygVariable = ( Boolean )wikiContext.getVariable( RenderingManager.WYSIWYG_EDITOR_MODE );
+        m_wysiwygEditorMode = wysiwygVariable != null ? wysiwygVariable.booleanValue() : false;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodePostProcessorState#process(NodeTracker, Link)
+     */
+    @Override
+    public void process( NodeTracker state, Link link ) {
+        String ruleLine = NodePostProcessorStateCommonOperations.inlineLinkTextOnWysiwyg( state, link, m_wysiwygEditorMode );
+        if( wikiContext.getEngine().getRenderingManager().getParser( wikiContext, link.getUrl().toString() ).isParseAccessRules() ) {
+            final WikiPage page = wikiContext.getRealPage();
+            if( ruleLine.startsWith( "{" ) ) {
+                ruleLine = ruleLine.substring( 1 );
+            }
+            if( ruleLine.endsWith( "}" ) ) {
+                ruleLine = ruleLine.substring( 0, ruleLine.length() - 1 );
+            }
+            LOG.debug( "page=" + page.getName() + ", ACL = " + ruleLine );
+
+            try {
+                final Acl acl = wikiContext.getEngine().getAclManager().parseAcl( page, ruleLine );
+                page.setAcl( acl );
+                link.unlink();
+                state.nodeRemoved( link );
+                LOG.debug( acl.toString() );
+            } catch( final WikiSecurityException wse ) {
+                NodePostProcessorStateCommonOperations.makeError( state, link, wse.getMessage() );
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/ExternalLinkNodePostProcessorState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/ExternalLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/ExternalLinkNodePostProcessorState.java
new file mode 100755
index 0000000..93089a3
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/ExternalLinkNodePostProcessorState.java
@@ -0,0 +1,60 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.LinkParsingOperations;
+import org.apache.wiki.parser.MarkupParser;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.NodeTracker;
+
+
+/**
+ * {@link NodePostProcessorState} which further post processes external links.
+ */
+public class ExternalLinkNodePostProcessorState implements NodePostProcessorState< Link > {
+
+    private final boolean hasRef;
+    private final WikiContext wikiContext;
+    private final LinkParsingOperations linkOperations;
+    private boolean m_useOutlinkImage = true;
+
+    public ExternalLinkNodePostProcessorState( final WikiContext wikiContext, final boolean hasRef ) {
+        this.hasRef = hasRef;
+        this.wikiContext = wikiContext;
+        this.linkOperations = new LinkParsingOperations( wikiContext );
+        this.m_useOutlinkImage = wikiContext.getBooleanWikiProperty( MarkupParser.PROP_USEOUTLINKIMAGE, m_useOutlinkImage );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodePostProcessorState#process(NodeTracker, Link)
+     */
+    @Override
+    public void process( NodeTracker state, Link link ) {
+        if( linkOperations.isImageLink( link.getUrl().toString() ) ) {
+            new ImageLinkNodePostProcessorState( wikiContext, link.getUrl().toString(), hasRef ).process( state, link );
+        } else {
+            NodePostProcessorStateCommonOperations.addOutlinkImage( state, link, wikiContext, m_useOutlinkImage );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/FootnoteRefLinkNodePostProcessorState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/FootnoteRefLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/FootnoteRefLinkNodePostProcessorState.java
new file mode 100755
index 0000000..9c929bb
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/FootnoteRefLinkNodePostProcessorState.java
@@ -0,0 +1,47 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.ast.Text;
+import com.vladsch.flexmark.util.NodeTracker;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodePostProcessorState} which further post processes footnote reference links.
+ */
+public class FootnoteRefLinkNodePostProcessorState implements NodePostProcessorState< Link > {
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodePostProcessorState#process(NodeTracker, Link)
+     */
+    @Override
+    public void process( NodeTracker state, Link link ) {
+        final Text opBracket = new Text( CharSubSequence.of( "[" ) );
+        final Text clBracket = new Text( CharSubSequence.of( "]" ) );
+        link.prependChild( opBracket );
+        link.appendChild( clBracket );
+        state.nodeAdded( opBracket );
+        state.nodeAdded( clBracket );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/ImageLinkNodePostProcessorState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/ImageLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/ImageLinkNodePostProcessorState.java
new file mode 100755
index 0000000..df564ec
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/ImageLinkNodePostProcessorState.java
@@ -0,0 +1,65 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.LinkParsingOperations;
+
+import com.vladsch.flexmark.ast.HtmlInline;
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.NodeTracker;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodePostProcessorState} which further post processes image links.
+ */
+public class ImageLinkNodePostProcessorState implements NodePostProcessorState< Link > {
+
+    private final boolean isLinkFromText;
+    private final String urlRef;
+    private final LinkParsingOperations linkOperations;
+
+    public ImageLinkNodePostProcessorState( final WikiContext wikiContext, final String urlRef, final boolean isLinkFromText ) {
+        this.isLinkFromText = isLinkFromText;
+        this.urlRef = urlRef;
+        this.linkOperations = new LinkParsingOperations( wikiContext );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodePostProcessorState#process(NodeTracker, Link)
+     */
+    @Override
+    public void process( NodeTracker state, Link link ) {
+        final HtmlInline img = new HtmlInline( CharSubSequence.of( "<img class=\"inline\" " +
+                                                                        "src=\"" + urlRef + "\" " +
+                                                                        "alt=\"" + link.getText().toString() + "\" />" ) );
+        if( ( isLinkFromText && linkOperations.isExternalLink( link.getText().toString() ) ) ||
+                ( isLinkFromText && linkOperations.linkExists( link.getText().toString() ) ) ) {
+            link.removeChildren();
+            link.appendChild( img );
+            state.nodeAdded( img );
+        } else {
+            NodePostProcessorStateCommonOperations.addContent( state, link, img );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/InterWikiLinkNodePostProcessorState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/InterWikiLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/InterWikiLinkNodePostProcessorState.java
new file mode 100755
index 0000000..378bada
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/InterWikiLinkNodePostProcessorState.java
@@ -0,0 +1,87 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+import org.apache.log4j.Logger;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.parser.LinkParsingOperations;
+import org.apache.wiki.parser.MarkupParser;
+import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.render.RenderingManager;
+
+import com.vladsch.flexmark.ast.Document;
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.NodeTracker;
+
+
+/**
+ * {@link NodePostProcessorState} which further post processes interwiki links.
+ */
+public class InterWikiLinkNodePostProcessorState implements NodePostProcessorState< Link > {
+
+    private static final Logger LOG = Logger.getLogger( InterWikiLinkNodePostProcessorState.class );
+    private final WikiContext wikiContext;
+    private final LinkParsingOperations linkOperations;
+    private final Document document;
+    private final boolean m_wysiwygEditorMode;
+    private final boolean hasRef;
+    private boolean m_useOutlinkImage = true;
+
+    public InterWikiLinkNodePostProcessorState( final WikiContext wikiContext, final Document document, final boolean hasRef ) {
+        this.wikiContext = wikiContext;
+        this.linkOperations = new LinkParsingOperations( wikiContext );
+        this.document = document;
+        this.hasRef = hasRef;
+        this.m_useOutlinkImage = wikiContext.getBooleanWikiProperty( MarkupParser.PROP_USEOUTLINKIMAGE, m_useOutlinkImage );
+        final Boolean wysiwygVariable = ( Boolean )wikiContext.getVariable( RenderingManager.WYSIWYG_EDITOR_MODE );
+        m_wysiwygEditorMode = wysiwygVariable != null ? wysiwygVariable.booleanValue() : false;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodePostProcessorState#process(NodeTracker, Link)
+     */
+    @Override
+    public void process( NodeTracker state, Link link ) {
+        if( !m_wysiwygEditorMode ) {
+            final String[] refAndPage = link.getUrl().toString().split( ":" );
+            final String urlReference = wikiContext.getEngine().getInterWikiURL( refAndPage[ 0 ] );
+            if( urlReference != null ) {
+                if( linkOperations.isImageLink( urlReference ) ) {
+                    new ImageLinkNodePostProcessorState( wikiContext, urlReference, hasRef ).process( state, link );
+                }
+                if( linkOperations.isExternalLink( urlReference ) ) {
+                    NodePostProcessorStateCommonOperations.addOutlinkImage( state, link, wikiContext, m_useOutlinkImage );
+                }
+            } else {
+                LOG.debug( refAndPage[0] + " not recognized as InterWiki link [document node: " + document + "]" );
+                final Object[] args = { refAndPage[ 0 ] };
+                final ResourceBundle rb = Preferences.getBundle( wikiContext, InternationalizationManager.CORE_BUNDLE );
+                final String errMsg = MessageFormat.format( rb.getString( "markupparser.error.nointerwikiref" ), args );
+                NodePostProcessorStateCommonOperations.makeError( state, link, errMsg );
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/JSPWikiLinkNodePostProcessor.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/JSPWikiLinkNodePostProcessor.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/JSPWikiLinkNodePostProcessor.java
new file mode 100755
index 0000000..680de26
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/JSPWikiLinkNodePostProcessor.java
@@ -0,0 +1,91 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.LinkParsingOperations;
+import org.apache.wiki.parser.MarkupParser;
+import org.apache.wiki.util.TextUtil;
+
+import com.vladsch.flexmark.ast.Document;
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.ast.Node;
+import com.vladsch.flexmark.parser.PostProcessor;
+import com.vladsch.flexmark.parser.block.NodePostProcessor;
+import com.vladsch.flexmark.util.NodeTracker;
+
+
+/**
+ * {@link NodePostProcessor} for JSPWiki links.
+ *
+ * Acts as a factory of {@link NodePostProcessorState}, which are the classes generating the extra markup for each concrete type of link.
+ */
+public class JSPWikiLinkNodePostProcessor extends NodePostProcessor {
+
+    protected final WikiContext m_context;
+    protected final LinkParsingOperations linkOperations;
+    protected boolean m_useOutlinkImage = true;
+    protected final Document document;
+
+    public JSPWikiLinkNodePostProcessor( final WikiContext m_context, final Document document ) {
+        this.m_context = m_context;
+        this.document = document;
+        linkOperations = new LinkParsingOperations( m_context );
+        m_useOutlinkImage = m_context.getBooleanWikiProperty( MarkupParser.PROP_USEOUTLINKIMAGE, m_useOutlinkImage );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see PostProcessor#process(NodeTracker, Node)
+     */
+    @Override
+    public void process( final NodeTracker state, final Node node ) {
+        if( node instanceof Link ) {
+            final Link link = ( Link )node;
+            boolean hasRef = true;
+            if( StringUtils.isEmpty( link.getUrl().toString() ) ) { // empty link == link.getText() is a wiki page
+                link.setUrl( link.getText() );
+                hasRef = false;
+            }
+
+            final NodePostProcessorState< Link > linkPostProcessor;
+            if( linkOperations.isAccessRule( link.getUrl().toString() ) ) {
+                linkPostProcessor = new AccessRuleLinkNodePostProcessorState( m_context );
+            } else if( linkOperations.isMetadata( link.getUrl().toString() ) ) {
+                linkPostProcessor = new MetadataLinkNodePostProcessorState( m_context );
+            } else if( linkOperations.isPluginLink( link.getUrl().toString() ) ) {
+                linkPostProcessor = new PluginLinkNodePostProcessorState( m_context );
+            } else if( linkOperations.isVariableLink( link.getUrl().toString() ) ) {
+                linkPostProcessor = new VariableLinkNodePostProcessorState( m_context );
+            } else if( linkOperations.isExternalLink( link.getUrl().toString() ) ) {
+                linkPostProcessor = new ExternalLinkNodePostProcessorState( m_context, hasRef );
+            } else if( linkOperations.isInterWikiLink( link.getUrl().toString() ) ) {
+                linkPostProcessor = new InterWikiLinkNodePostProcessorState( m_context, document, hasRef );
+            } else if( TextUtil.isNumber( link.getUrl().toString() ) ) {
+                linkPostProcessor = new FootnoteRefLinkNodePostProcessorState();
+            } else {
+                linkPostProcessor = new LocalLinkNodePostProcessorState( m_context, hasRef );
+            }
+            linkPostProcessor.process( state, link );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/LocalLinkNodePostProcessorState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/LocalLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/LocalLinkNodePostProcessorState.java
new file mode 100755
index 0000000..1832dfb
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/LocalLinkNodePostProcessorState.java
@@ -0,0 +1,76 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.parser.LinkParsingOperations;
+
+import com.vladsch.flexmark.ast.HtmlInline;
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.NodeTracker;
+import com.vladsch.flexmark.util.sequence.CharSubSequence;
+
+
+/**
+ * {@link NodePostProcessorState} which further post processes local links.
+ */
+public class LocalLinkNodePostProcessorState implements NodePostProcessorState< Link > {
+
+    private final boolean hasRef;
+    private final WikiContext wikiContext;
+    private final LinkParsingOperations linkOperations;
+
+    public LocalLinkNodePostProcessorState( final WikiContext wikiContext, final boolean hasRef ) {
+        this.hasRef = hasRef;
+        this.wikiContext = wikiContext;
+        this.linkOperations = new LinkParsingOperations( wikiContext );
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodePostProcessorState#process(NodeTracker, Link)
+     */
+    @Override
+    public void process( NodeTracker state, Link link ) {
+        final String attachment = wikiContext.getEngine().getAttachmentManager().getAttachmentInfoName( wikiContext, link.getUrl().toString() );
+        if( attachment != null  ) {
+            if( linkOperations.isImageLink( link.getUrl().toString() ) ) {
+                new ImageLinkNodePostProcessorState( wikiContext, attachment, hasRef ).process( state, link );
+            } else {
+                link.removeChildren();
+                final HtmlInline content = new HtmlInline( CharSubSequence.of( link.getText().toString() ) );
+                link.appendChild( content );
+                state.nodeAddedWithChildren( content );
+                addAttachmentLink( state, link );
+            }
+        }
+    }
+
+    void addAttachmentLink( final NodeTracker state, final Link link ) {
+        final String infolink = wikiContext.getURL( WikiContext.INFO, link.getUrl().toString() );
+        final String imglink = wikiContext.getURL( WikiContext.NONE, "images/attachment_small.png" );
+        final HtmlInline aimg = new HtmlInline( CharSubSequence.of( "<a href=\""+ infolink + "\" class=\"infolink\">" +
+                                                                       "<img src=\""+ imglink + "\" border=\"0\" alt=\"(info)\" />" +
+                                                                     "</a>" ) );
+        link.insertAfter( aimg );
+        state.nodeAdded( aimg );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/MetadataLinkNodePostProcessorState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/MetadataLinkNodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/MetadataLinkNodePostProcessorState.java
new file mode 100755
index 0000000..0708f04
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/MetadataLinkNodePostProcessorState.java
@@ -0,0 +1,88 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+import org.apache.log4j.Logger;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.render.RenderingManager;
+
+import com.vladsch.flexmark.ast.Link;
+import com.vladsch.flexmark.util.NodeTracker;
+
+
+/**
+ * {@link NodePostProcessorState} which further post processes metadata links.
+ */
+public class MetadataLinkNodePostProcessorState implements NodePostProcessorState< Link > {
+
+    private static final Logger LOG = Logger.getLogger( MetadataLinkNodePostProcessorState.class );
+    private final WikiContext wikiContext;
+    private final boolean m_wysiwygEditorMode;
+
+    public MetadataLinkNodePostProcessorState( final WikiContext wikiContext ) {
+        this.wikiContext = wikiContext;
+        final Boolean wysiwygVariable = ( Boolean )wikiContext.getVariable( RenderingManager.WYSIWYG_EDITOR_MODE );
+        m_wysiwygEditorMode = wysiwygVariable != null ? wysiwygVariable.booleanValue() : false;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see NodePostProcessorState#process(NodeTracker, Link)
+     */
+    @Override
+    public void process( NodeTracker state, Link link ) {
+        final String metadataLine = NodePostProcessorStateCommonOperations.inlineLinkTextOnWysiwyg( state, link, m_wysiwygEditorMode );
+        try {
+            final String args = metadataLine.substring( metadataLine.indexOf(' '), metadataLine.length() - 1 );
+            String name = args.substring( 0, args.indexOf( '=' ) );
+            String val = args.substring( args.indexOf( '=' ) + 1, args.length() );
+
+            name = name.trim();
+            val = val.trim();
+
+            if( val.startsWith( "'" ) ) {
+                val = val.substring( 1 );
+            }
+            if( val.endsWith( "'" ) ) {
+                val = val.substring( 0, val.length()-1 );
+            }
+
+            LOG.debug( "page=" + wikiContext.getRealPage().getName() + " SET name='" + name + "', value='" + val + "'" );
+
+            if( name.length() > 0 && val.length() > 0 ) {
+                val = wikiContext.getEngine().getVariableManager().expandVariables( wikiContext, val );
+                wikiContext.getPage().setAttribute( name, val );
+                link.unlink();
+                state.nodeRemoved( link );
+            }
+        } catch( final Exception e ) {
+            final ResourceBundle rb = Preferences.getBundle( wikiContext, InternationalizationManager.CORE_BUNDLE );
+            NodePostProcessorStateCommonOperations.makeError( state,
+                                                                  link,
+                                                                  MessageFormat.format( rb.getString( "markupparser.error.invalidset" ), metadataLine ) );
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/c1793a18/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/NodePostProcessorState.java
----------------------------------------------------------------------
diff --git a/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/NodePostProcessorState.java b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/NodePostProcessorState.java
new file mode 100755
index 0000000..d4c4a6f
--- /dev/null
+++ b/jspwiki-markdown/src/main/java/org/apache/wiki/markdown/extensions/jspwikilinks/postprocessor/NodePostProcessorState.java
@@ -0,0 +1,38 @@
+/*
+    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.wiki.markdown.extensions.jspwikilinks.postprocessor;
+
+import com.vladsch.flexmark.ast.Node;
+import com.vladsch.flexmark.util.NodeTracker;
+
+
+/**
+ * Encapsulates different node's post-process for different kinds of nodes.
+ */
+public interface NodePostProcessorState < T extends Node > {
+
+    /**
+     * performs further processing before rendering.
+     *
+     * @param state to record node addition/deletion
+     * @param link the specific node in which the post-processing is taking place.
+     */
+    void process( NodeTracker state, T node );
+
+}


[5/5] jspwiki git commit: NOTICE and LICENSE needed to comlpy with Flexmark distribution in binary form

Posted by ju...@apache.org.
NOTICE and LICENSE needed to comlpy with Flexmark distribution in binary form


Project: http://git-wip-us.apache.org/repos/asf/jspwiki/repo
Commit: http://git-wip-us.apache.org/repos/asf/jspwiki/commit/836db9f0
Tree: http://git-wip-us.apache.org/repos/asf/jspwiki/tree/836db9f0
Diff: http://git-wip-us.apache.org/repos/asf/jspwiki/diff/836db9f0

Branch: refs/heads/master
Commit: 836db9f07552a1e97ab594b6a0388bbe979df5d5
Parents: 05cad3c
Author: juanpablo <ju...@apache.org>
Authored: Fri Dec 8 23:06:46 2017 +0100
Committer: juanpablo <ju...@apache.org>
Committed: Fri Dec 8 23:06:46 2017 +0100

----------------------------------------------------------------------
 NOTICE                                          |  4 ++-
 .../src/main/config/doc/LICENSE.flexmark        | 26 ++++++++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jspwiki/blob/836db9f0/NOTICE
----------------------------------------------------------------------
diff --git a/NOTICE b/NOTICE
index b9a842d..6aed70b 100644
--- a/NOTICE
+++ b/NOTICE
@@ -14,4 +14,6 @@ Slimbox, adapted for JSPWiki, original by Christophe Bleys. (see http://www.digi
 fckconfig.js Copyright (C) 2003-2008 Frederico Caldeira Knabben licensed under 
 the terms of Mozilla Public License Version 2.0 http://http://www.mozilla.org/MPL/2.0
 
-Launch4J (c) 2012 MinGW.org project (see http://www.mingw.org/license)
\ No newline at end of file
+Launch4J (c) 2012 MinGW.org project (see http://www.mingw.org/license)
+
+Flexmark (https://github.com/vsch/flexmark-java/blob/master/LICENSE.txt)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jspwiki/blob/836db9f0/jspwiki-war/src/main/config/doc/LICENSE.flexmark
----------------------------------------------------------------------
diff --git a/jspwiki-war/src/main/config/doc/LICENSE.flexmark b/jspwiki-war/src/main/config/doc/LICENSE.flexmark
new file mode 100755
index 0000000..c5e6ce0
--- /dev/null
+++ b/jspwiki-war/src/main/config/doc/LICENSE.flexmark
@@ -0,0 +1,26 @@
+Copyright (c) 2015-2016, Atlassian Pty Ltd
+All rights reserved.
+
+Copyright (c) 2016, Vladimir Schneider,
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.