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

[Feature Request] Dynamic Link Rendering #59

Open
3 tasks done
zojize opened this issue Jan 10, 2025 · 0 comments
Open
3 tasks done

[Feature Request] Dynamic Link Rendering #59

zojize opened this issue Jan 10, 2025 · 0 comments
Labels
enhancement New feature or request

Comments

@zojize
Copy link

zojize commented Jan 10, 2025

Clear and concise description of the problem

I'm migrating a Jeykll project to a Vue-SSG project and a common pattern I encounter in the markdown in the Jeykll project is templated links. For example:

[Foo bar]({{ site.foo }}/bar)

Which gets replaced by the foo variable defined in a config file during build/dev time by Jekyll. However, this plugin does no transformation to links like this, and markdown-it outputs them raw. It would be nice if this could be supported by this plugin directly allowing dynamically rendered links/images.

Suggested solution

[Foo bar]({{ foo }}/bar)

should be transformed to

<a :href="`${foo}/bar`">Foo bar</a>

Optional title:

[Foo bar]({{ foo }}/bar "the {{ title }}")

should be transformed to

<a :href="`${foo}/bar`" :title="`the ${title}`">Foo bar</a>

Alternative

Currently I accomplish this by using the before transformation to raw markdown to replace items at build/dev time, this solution does not work for dynamic variables but good enough for my usage:

Markdown({
  transforms: {
    before: (code) => {
      const data = {
         frontmatter: matter(code).data,
         // others
      }
      return code.replaceAll(
        new RegExp(`\{\{ *(${Object.keys(data).join('|')})( *\. *([$_\p{ID_Start}][$\p{ID_Continue}]*))+ *\}\}`, 'gu'),
        (match, key) => {
          const keys = match.slice(2, -2).split('.').slice(1).map(key => key.trim())
          let value = data[key]
          for (const key of keys) {
            if (key in value)
              value = value[key]
            else
              return match
          }
          return value === data ? match : `${value}`
        },
      )
    },
  },
})

Additional context

I'd love to help implement this feature! let me know what you think of this idea.

Validations

@zojize zojize added the enhancement New feature or request label Jan 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant