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?
Community moderators have prevented the ability to post new answers.
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.
Correction: The input String is before rendering, it's the markdown source. The replacements have to be HTML.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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).
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you Michael, this is very useful. I'm going to try this out.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.