jspwiki-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From juanpa...@apache.org
Subject [3/5] jspwiki git commit: JSPWIKI-802: initial markdown support
Date Fri, 08 Dec 2017 22:07:50 GMT
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 <juanpablo@apache.org>
Authored: Fri Dec 8 22:37:40 2017 +0100
Committer: juanpablo <juanpablo@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 );
+
+}


Mime
View raw message