Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

Is it possible to extend stash markdown with configurable links?

Wayne Wylupski March 11, 2015

I'd like to be able to have links to an external system available in the markdown, not unlike what happens when you include a JIRA issue key.  Is there a plugin that does this, or is it even possible to add this?

I see the following feature request: https://jira.atlassian.com/browse/STASH-4434; this would help, but are there alternatives available today?

3 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

4 votes
Answer accepted
Michael Heemskerk
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
March 27, 2015

Hi Wayne, 

It is possible to do this - our JIRA integration that transforms the JIRA key into a link is a plugin itself. The plugin module type to do it is however currently undocumented. 

The short version is that you'd have to create a plugin and add the following to your atlassian-plugin.xml:

<markup-renderer-component key="myFancyRenderer" class="com.yourcompany.FancyRendererComponent"/>

Also add the following dependency to your pom.xml:

<dependency>
            <groupId>com.atlassian.markup</groupId>
            <artifactId>atlassian-markup-renderer-api</artifactId>
            <scope>provided</scope>
        </dependency>

Then create your fancy renderer:

package com.yourcompany;

import com.atlassian.markup.renderer.MarkupRendererComponent;
import com.atlassian.markup.renderer.RenderContext;
import com.atlassian.markup.renderer.RenderTransform;

import javax.annotation.Nonnull;
import java.util.Map;

public class FancyRendererComponent implements MarkupRendererComponent {

    public FancyRendererComponent() {
    }

    @Nonnull
    @Override
    public RenderTransform process(CharSequence input, @Nonnull RenderContext context) {
        RenderTransform.TransformBuilder builder = RenderTransform.builder();

        int searchIndex = 0;
        while (searchIndex != -1 && searchIndex < input.length()) {
            searchIndex = findNextTokenStart(input, searchIndex)
            if (searchIndex == -1) {
                break;
            }

            int end = findTokenEnd(input, searchIndex);
            if (end != -1) {
                String replacement = render(new StringBuilder().append(input.subSequence(searchIndex + 1, end));
                builder.add(searchIndex, end, replacement);
            }
            searchIndex = end;
        }

        return builder.build();
    }


    private int findNextTokenStart(CharSequence input, int fromIndex) {
        ....
    }
 
    private int findTokenEnd(CharSequence input, int startIndex) {
        ....
    }
 
    private String render(String source) {
        ....
    }
}

This example isn't complete but should give you a good idea of how to set it up. input in the example above is the String after markdown rendering has been done. The MarkupRenderComponent that you register gets to post-process the rendered fragment and can provide a list of replacements/transforms for the parts of the fragment.

A word of warning. Make sure that your renderer-component is fast as it can be called many times for the a single HTTP request. Consider for instance the overview tab of a pull request. All comments are fed through all registered renderers and if the processing is inefficient, the page will become slow.

Robin Stocker
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
April 14, 2015

Correction: The input String is before rendering, it's the markdown source. The replacements have to be HTML.

0 votes
Wayne Wylupski May 12, 2015

Thank you, this is working for us.  Is there be documentation for the MarkupRendererComponent and the RenderTransform.TransformBuilder classes?  And will all these classes be supported through Stash 4.0, or do we have to worry about deprecation?

Thanks!

Michael Heemskerk
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
May 12, 2015

atlassian-markup-renderer is used internally for intercepting and transforming the markup rendering pipeline and has not been publicly documented, so I can't point you to public page with javadoc (most of our javadocs for shared libraries is found on https://docs.atlassian.com). The sources are available through maven though, so a {{mvn dependency:sources}} call should pull them into your local maven repo and make the sources (and javadoc) available in your IDE. With respect to backwards compatibility: we have a policy to only make backwards compatible changes in our minor releases (e.g. 3.x). We save up the backwards compatibility breaking changes for major releases such as 4.0. So I cannot guarantee that this API will not be broken. We do not currently have any plans to overhaul the atlassian-markup-renderer APIs though and I don't expect us to break it in the 4.0 (no guarantees though).

0 votes
Wayne Wylupski March 27, 2015

Thank you Michael, this is very useful.  I'm going to try this out.

TAGS
AUG Leaders

Atlassian Community Events