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

open links in new tab #79

Closed
hjjobs opened this issue Jun 5, 2018 · 7 comments
Closed

open links in new tab #79

hjjobs opened this issue Jun 5, 2018 · 7 comments
Labels
question Issue representing a how-to question

Comments

@hjjobs
Copy link

hjjobs commented Jun 5, 2018

When embedding a link using markdown it opens in the same tab. Is there any way through which we can open the link in a new tab ?

@jfcere
Copy link
Owner

jfcere commented Jun 6, 2018

Quickly there is two options that comes to my mind...

1. Use HTML directly

Since Markdown support HTML you could use HTML for the links you want to open with target="_blank"

<a href="http://example.com/" target="_blank">Hello, world!</a>

2. Extend renderer for link token

Marked renderer can be extended when initializing MarkdownModule or using MarkdownService (see README.md renderer section) to add target="_blank" on every anchors.

See marked.js related issue: markedjs/marked#655 (comment)

const linkRenderer = renderer.link;
renderer.link = (href, title, text) => {
  const html = linkRenderer.call(renderer, href, title, text);
  return html.replace(/^<a /, '<a target="_blank" rel="nofollow" ');
};

Let me know if this is of any help!

@jfcere jfcere added the question Issue representing a how-to question label Jun 6, 2018
@hjjobs
Copy link
Author

hjjobs commented Jun 6, 2018

thanks @jfcere . it did work for me.

@hjjobs hjjobs closed this as completed Jun 6, 2018
@beingbing
Copy link

beingbing commented Jul 30, 2018

thanks to @jfcere, I got an idea as how to approach this problem in Angular 5 and above in electron application and in web application too -

In app.module.ts -

import { MarkdownModule, MarkedOptions, MarkedRenderer } from 'ngx-markdown';

.
.
.

// function that returns `MarkedOptions` with renderer override
export function markedOptionsFactory(): MarkedOptions {
  const renderer = new MarkedRenderer();
  const linkRenderer = renderer.link;

  renderer.link = (href, title, text) => {
    const html = linkRenderer.call(renderer, href, title, text);
    return html.replace(/^<a /, '<a role="link" tabindex="0" target="_blank" rel="nofollow noopener noreferrer" ');
  };

  return {
    renderer,
    gfm: true,
    tables: true,
    breaks: false,
    pedantic: false,
    sanitize: false,
    smartLists: true,
    smartypants: false,
  };
}

.
.
.
.

@NgModule({
  imports: [
  MarkdownModule.forRoot({
      provide: MarkedOptions,
      useFactory: markedOptionsFactory,
    })
]
})

@petrskalicka
Copy link

Why not rewrite the renderer straight away?

renderer.link = (href: string, title: string) =>
``<a href="${href}" target="_blank" rel="nofollow">${title || href}</a>``;

Hm. How to escape backticks?

@umadesign
Copy link

thanks to @jfcere, I got an idea as how to approach this problem in Angular 5 and above in electron application and in web application too -

In app.module.ts -

.
.
.
@NgModule({
  imports: [
  MarkdownModule.forRoot({
      provide: MarkedOptions,
      useFactory: markedOptionsFactory,
    })
]
})

I was able to make this work, but had to change the import as shown here:

https://github.com/jfcere/ngx-markdown#markedoptionsrenderer

// using specific option with FactoryProvider
MarkdownModule.forRoot({
  loader: HttpClient,
  markedOptions: {
    provide: MarkedOptions,
    useFactory: markedOptionsFactory,
  },
}),

@genesiscz
Copy link

Today, this works

    MarkdownModule.forRoot({
      markedOptions: {
        provide: MARKED_OPTIONS,
        useFactory: markedOptionsFactory,
      },
      clipboardOptions: {
        provide: CLIPBOARD_OPTIONS,
        useValue: {
          buttonComponent: ClipboardButtonComponent,
        },
      },
    }),

with

// function that returns `MarkedOptions` with renderer override
import { MarkedOptions } from 'marked';
import { MarkedRenderer } from 'ngx-markdown';

export function markedOptionsFactory(): MarkedOptions {
  const renderer = new MarkedRenderer();
  const linkRenderer = renderer.link;

  renderer.link = (href, title, text) => {
    const html = linkRenderer.call(renderer, href, title, text);
    return html.replace(
      /^<a /,
      '<a role="link" tabindex="0" target="_blank" rel="nofollow noopener noreferrer" ',
    );
  };

  return {
    renderer,
    gfm: true, // Enables GitHub Flavored Markdown.
    breaks: false, // Disable line breaks on single line breaks.
    pedantic: false, // Disable pedantic mode.
  };
}

@NorseJedi
Copy link

For anyone finding this looking for a solution like I did, this is what works when using marked v15 (which I suppose isn't really supported by ngx-markdown, but I haven't had any problems using it so far).

export const markedOptionsFactory = (): MarkedOptions => {
  const renderer = new MarkedRenderer();

  renderer.link = ({href, text}): string => {
    return `<a target="_blank" href="${href}">${text}</a>`;
  };

  return {
    renderer: renderer,
    gfm: true,
    breaks: true,
    pedantic: false
  };
}

And of course, use it in the providers-array in app.config.ts (or I guess in app.module.ts if you're using modules):

export const appConfig: ApplicationConfig = {
  providers: [
    provideMarkdown({ markedOptions: { provide: MARKED_OPTIONS, useFactory: markedOptionsFactory } }),
  ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Issue representing a how-to question
Projects
None yet
Development

No branches or pull requests

7 participants