Showdown: Option to make links open in new tab

Created on 3 Feb 2017  路  10Comments  路  Source: showdownjs/showdown

When using the "simple links" option it'd be nice if there was another option that would add target="_blank" (or whatever target of your choice) to all links.

duplicate

Most helpful comment

I know that this issue has been resolved a long time ago, but since I found this result on google prior to the documentation, I think it's good to mention here that this feature is now implemented in showdown itself since v1.7.0 (as you can actually see in the reference from the commit implementing it above).

new showdown.Converter({
  openLinksInNewWindow: true,
});

All 10 comments

Duplicate of #249 #247 #222

Adding extra syntax to the link element is not a good idea as it diverts from the markdown spec and breks compatibility.

However, there are 2 easy ways to add this to links:

Using embeded html

fiddle

some text with a link <a href="http://www.google.com" target="blank">google</a>

Create an extension

Syntax

[adjustable](http://google.com "Giiidd"){:target="_blank"}

Test online

fiddle

Code

showdown.extension('targetlink', function() {
  return [{
    type: 'lang',
    regex: /\[((?:\[[^\]]*]|[^\[\]])*)]\([ \t]*<?(.*?(?:\(.*?\).*?)?)>?[ \t]*((['"])(.*?)\4[ \t]*)?\)\{\:target=(["'])(.*)\6}/g,
    replace: function(wholematch, linkText, url, a, b, title, c, target) {

      var result = '<a href="' + url + '"';

      if (typeof title != 'undefined' && title !== '' && title !== null) {
        title = title.replace(/"/g, '&quot;');
        title = showdown.helper.escapeCharacters(title, '*_', false);
        result += ' title="' + title + '"';
      }

      if (typeof target != 'undefined' && target !== '' && target !== null) {
        result += ' target="' + target + '"';
      }

      result += '>' + linkText + '</a>';
      return result;
    }
  }];
});

Would that extension work with the auto-parsed simple-url (i.e., not [blahblah](http://example.com) etc, but just http://example.com)?

this specific extension no. But this one will make all links in the page open as target="_blank":

fiddle

Code:

showdown.extension('targetlink', function() {
  return [{
    type: 'html',
    regex: /(<a [^>]+?)(>.*<\/a>)/g,
    replace: '$1 target="_blank"$2'
  }];
});

I have installed both (I hope) extensions (named one 'targetlink2' to keep them unique - is that the right thing to do?) and neither seem to be actually doing anything.

I assume I have to just call those showdown.extension(...) bits during my startup?

Here is how I use it:

        showdown.setFlavor('github');
        showdown.extension('targetlink', function() {
          return [{
            type: 'html',
            regex: /(<a [^>]+?)(>.*<\/a>)/g,
            replace: '$1 target="_blank"$2'
          }];
        });
        showdown.extension('targetlink2', function() {
          return [{
            type: 'lang',
            regex: /\[((?:\[[^\]]*]|[^\[\]])*)]\([ \t]*<?(.*?(?:\(.*?\).*?)?)>?[ \t]*((['"])(.*?)\4[ \t]*)?\)\{\:target=(["'])(.*)\6}/g,
            replace: function(wholematch, linkText, url, a, b, title, c, target) {

              var result = '<a href="' + url + '"';

              if (typeof title != 'undefined' && title !== '' && title !== null) {
                title = title.replace(/"/g, '&quot;');
                title = showdown.helper.escapeCharacters(title, '*_', false);
                result += ' title="' + title + '"';
              }

              if (typeof target != 'undefined' && target !== '' && target !== null) {
                result += ' target="' + target + '"';
              }

              result += '>' + linkText + '</a>';
              return result;
            }
          }];
        });
        this.converter = new showdown.Converter({
            simplifiedAutoLink: true,
            excludeTrailingPunctuationFromURLs: true,
            strikethrough: true,
            tables: true,
            tasklists: true,
            encodeEmails: true
        });

My test block:

Link test:

* www.google.com
* http://www.google.com
* [Google](http://www.google.com)
* [Google][1]

   [1]: http://www.google.com

You SHOULD NOT enable both, enable just one since they will colide.

You also have to activate them:

var conv = new showdown.Converter({extensions: ['targetlink']});

Hmmm... I was hoping the activating was all I was missing, but it seems not. This is now all I have to initialize:

        showdown.setFlavor('github');
        showdown.extension('targetlink', function() {
          return [{
            type: 'html',
            regex: /(<a [^>]+?)(>.*<\/a>)/g,
            replace: '$1 target="_blank"$2'
          }];
        });
        this.converter = new showdown.Converter({
            simplifiedAutoLink: true,
            excludeTrailingPunctuationFromURLs: true,
            strikethrough: true,
            tables: true,
            tasklists: true,
            encodeEmails: true,
            extension: ['targetlink']
        });

and it's not doing anything.

I guess it's no biggie - I can write a recursive function to traverse the DOM tree and find any A tags adding the target attribute. I just thought it would be simpler if showdown could do it for me...

you're missing an s in extensions. it's:

showdown.Converter({extensions: ['targetlink']});

Also you don't need to set all those options if you use showdown.setFlavor('github'), since github flavor sets the following options to true:

        omitExtraWLInCodeBlocks:              true,
        prefixHeaderId:                       'user-content-',
        simplifiedAutoLink:                   true,
        excludeTrailingPunctuationFromURLs:   true,
        literalMidWordUnderscores:            true,
        strikethrough:                        true,
        tables:                               true,
        tablesHeaderId:                       true,
        ghCodeBlocks:                         true,
        tasklists:                            true,
        disableForced4SpacesIndentedSublists: true,
        simpleLineBreaks:                     true,
        requireSpaceBeforeHeadingText:        true,
        ghCompatibleHeaderId:                 true,
        ghMentions:                           true

and encodeEmails is set to true by default

The above solution does not work for more than 1 link in the markup. Just in case anyone stumbles upon this issue, here's how I got it to work for ALL hyperlinks -

showdown.extension('targetlink', function() {
  return [{
    type: 'html',
    filter: function (text) {
        return (''+text).replace(/<a\s+href=/gi, '<a target="_blank" href=');
    }
  }];
});

I know that this issue has been resolved a long time ago, but since I found this result on google prior to the documentation, I think it's good to mention here that this feature is now implemented in showdown itself since v1.7.0 (as you can actually see in the reference from the commit implementing it above).

new showdown.Converter({
  openLinksInNewWindow: true,
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

thisconnect picture thisconnect  路  4Comments

subodhpareek18 picture subodhpareek18  路  5Comments

reisraff picture reisraff  路  5Comments

xduseko picture xduseko  路  3Comments

jonaskello picture jonaskello  路  4Comments