Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to make links open in new tab #337

Closed
majenkotech opened this issue Feb 2, 2017 · 10 comments
Closed

Option to make links open in new tab #337

majenkotech opened this issue Feb 2, 2017 · 10 comments
Assignees

Comments

@majenkotech
Copy link

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.

@tivie tivie self-assigned this Feb 3, 2017
@tivie tivie added the duplicate label Feb 3, 2017
@tivie
Copy link
Member

tivie commented Feb 3, 2017

Duplicate of #249 #247 #222

@tivie
Copy link
Member

tivie commented Feb 3, 2017

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;
    }
  }];
});

@tivie tivie closed this as completed Feb 3, 2017
@majenkotech
Copy link
Author

majenkotech commented Feb 3, 2017

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

@tivie
Copy link
Member

tivie commented Feb 3, 2017

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'
  }];
});

@majenkotech
Copy link
Author

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

@tivie
Copy link
Member

tivie commented Feb 3, 2017

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']});

@majenkotech
Copy link
Author

majenkotech commented Feb 3, 2017

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...

@tivie
Copy link
Member

tivie commented Feb 4, 2017

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

@paambaati
Copy link

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=');
    }
  }];
});

paambaati added a commit to indix/indix-radar that referenced this issue Mar 15, 2017
sulthan-ahmed added a commit to UKHomeOffice-attic/right-to-rent-check that referenced this issue Jan 2, 2018
- This has been done in the way recommended by showdown showdownjs/showdown#337
JoeChapman pushed a commit to UKHomeOffice-attic/right-to-rent-check that referenced this issue Jan 3, 2018
* Format privacy-policy & cookies headers

- Make main heading be a h1
- Make the text a large heading.  This has not been done for all h1s because h1s in other pages have a different styling

* Declaration page: privacy-policy link opens new tab

- This has been done in the way recommended by showdown showdownjs/showdown#337
@paullaffitte
Copy link

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,
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants