external-link-icon.ts 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. import type MarkdownIt from 'markdown-it'
  2. import type Renderer from 'markdown-it/lib/renderer'
  3. export default (md: MarkdownIt): void => {
  4. const renderToken: Renderer.RenderRule = (tokens, idx, options, env, self) =>
  5. self.renderToken(tokens, idx, options)
  6. const defaultLinkOpenRenderer = md.renderer.rules.link_open || renderToken
  7. const defaultLinkCloseRenderer = md.renderer.rules.link_close || renderToken
  8. let isExternalLink = false
  9. md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
  10. const token = tokens[idx]
  11. const href = token.attrGet('href')
  12. if (href) {
  13. token.attrJoin('class', 'vp-link')
  14. if (/^((ht|f)tps?):\/\/?/.test(href)) {
  15. isExternalLink = true
  16. }
  17. }
  18. return defaultLinkOpenRenderer(tokens, idx, options, env, self)
  19. }
  20. md.renderer.rules.link_close = (tokens, idx, options, env, self) => {
  21. if (isExternalLink) {
  22. isExternalLink = false
  23. return `<i-ri-external-link-line class="link-icon" />${self.renderToken(
  24. tokens,
  25. idx,
  26. options
  27. )}`
  28. }
  29. return defaultLinkCloseRenderer(tokens, idx, options, env, self)
  30. }
  31. }