diff --git a/README.md b/README.md index 507a7f6..8b48d83 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,34 @@ package system, module will add itself globally as `window.markdownitFootnote`. ### Customize +#### Custom href prefix + +You can customize the `href` attribute in footnote links by providing a `footnoteHrefPrefix` in the `env` parameter when calling `render()`. This is useful when you want footnotes to link to a different page or use a custom URL structure: + +```js +const md = require('markdown-it')().use(require('markdown-it-footnote')); + +// Custom href prefix for footnote links +md.render('Here is a footnote[^1]\n\n[^1]: Footnote text', { + footnoteHrefPrefix: '/docs/page#' +}); + +// Output includes: +``` + +You can also combine this with `docId` to customize both the IDs and href prefix: + +```js +md.render('Here is a footnote[^1]\n\n[^1]: Footnote text', { + docId: 'my-doc', + footnoteHrefPrefix: '/docs/page#' +}); + +// Output includes: +``` + +#### Renderer customization + If you want to customize the output, you'll need to replace the template functions. To see which templates exist and their default implementations, look in [`index.js`](index.js). The API of these template functions is out of diff --git a/index.mjs b/index.mjs index 48277ca..1485545 100644 --- a/index.mjs +++ b/index.mjs @@ -14,6 +14,14 @@ function render_footnote_anchor_name (tokens, idx, options, env/*, slf */) { return prefix + n } +function render_footnote_href_prefix (tokens, idx, options, env/*, slf */) { + let prefix = '#' + + if (typeof env.footnoteHrefPrefix === 'string') prefix = env.footnoteHrefPrefix + + return prefix +} + function render_footnote_caption (tokens, idx/*, options, env, slf */) { let n = Number(tokens[idx].meta.id + 1).toString() @@ -25,11 +33,12 @@ function render_footnote_caption (tokens, idx/*, options, env, slf */) { function render_footnote_ref (tokens, idx, options, env, slf) { const id = slf.rules.footnote_anchor_name(tokens, idx, options, env, slf) const caption = slf.rules.footnote_caption(tokens, idx, options, env, slf) + const hrefPrefix = slf.rules.footnote_href_prefix(tokens, idx, options, env, slf) let refid = id if (tokens[idx].meta.subId > 0) refid += `:${tokens[idx].meta.subId}` - return `${caption}` + return `${caption}` } function render_footnote_block_open (tokens, idx, options) { @@ -56,11 +65,12 @@ function render_footnote_close () { function render_footnote_anchor (tokens, idx, options, env, slf) { let id = slf.rules.footnote_anchor_name(tokens, idx, options, env, slf) + const hrefPrefix = slf.rules.footnote_href_prefix(tokens, idx, options, env, slf) if (tokens[idx].meta.subId > 0) id += `:${tokens[idx].meta.subId}` /* ↩ with escape code to prevent display as Apple Emoji on iOS */ - return ` \u21a9\uFE0E` + return ` \u21a9\uFE0E` } export default function footnote_plugin (md) { @@ -77,6 +87,7 @@ export default function footnote_plugin (md) { // helpers (only used in other rules, no tokens are attached to those) md.renderer.rules.footnote_caption = render_footnote_caption md.renderer.rules.footnote_anchor_name = render_footnote_anchor_name + md.renderer.rules.footnote_href_prefix = render_footnote_href_prefix // Process footnote block definition function footnote_def (state, startLine, endLine, silent) { diff --git a/test/fixtures/footnote-combined.txt b/test/fixtures/footnote-combined.txt new file mode 100644 index 0000000..19fda8d --- /dev/null +++ b/test/fixtures/footnote-combined.txt @@ -0,0 +1,19 @@ +Both docId and custom href prefix: +. +Here is a footnote reference,[^1] and another.[^longnote] + +[^1]: Here is the footnote. + +[^longnote]: Here's one with multiple blocks. +. +

Here is a footnote reference,[1] and another.[2]

+
+
+
    +
  1. Here is the footnote.

    +
  2. +
  3. Here's one with multiple blocks.

    +
  4. +
+
+. diff --git a/test/fixtures/footnote-custom-href.txt b/test/fixtures/footnote-custom-href.txt new file mode 100644 index 0000000..9dc00a8 --- /dev/null +++ b/test/fixtures/footnote-custom-href.txt @@ -0,0 +1,57 @@ +Custom href prefix: +. +Here is a footnote reference,[^1] and another.[^longnote] + +[^1]: Here is the footnote. + +[^longnote]: Here's one with multiple blocks. +. +

Here is a footnote reference,[1] and another.[2]

+
+
+
    +
  1. Here is the footnote.

    +
  2. +
  3. Here's one with multiple blocks.

    +
  4. +
+
+. + + +Inline footnote with custom href: +. +Here is an inline note.^[Inlines notes are easier to write.] +. +

Here is an inline note.[1]

+
+
+
    +
  1. Inlines notes are easier to write.

    +
  2. +
+
+. + + +Multiple references with custom href: +. +[^1][^2][^3] + +[^1]: foo +[^2]: bar +[^3]: baz +. +

[1][2][3]

+
+
+
    +
  1. foo

    +
  2. +
  3. bar

    +
  4. +
  5. baz

    +
  6. +
+
+. diff --git a/test/test.mjs b/test/test.mjs index da74c5c..5ead086 100644 --- a/test/test.mjs +++ b/test/test.mjs @@ -42,3 +42,17 @@ describe('custom docId in env', function () { // Now check that using `env.documentId` works to prefix IDs generate(fileURLToPath(new URL('fixtures/footnote-prefixed.txt', import.meta.url)), md, { docId: 'test-doc-id' }) }) + +describe('custom href prefix in env', function () { + const md = markdownit().use(footnote) + + // Check that using `env.footnoteHrefPrefix` works to customize href + generate(fileURLToPath(new URL('fixtures/footnote-custom-href.txt', import.meta.url)), md, { footnoteHrefPrefix: '/custom/path#' }) +}) + +describe('combined docId and custom href prefix in env', function () { + const md = markdownit().use(footnote) + + // Check that both env.docId and env.footnoteHrefPrefix work together + generate(fileURLToPath(new URL('fixtures/footnote-combined.txt', import.meta.url)), md, { docId: 'my-doc', footnoteHrefPrefix: '/docs#' }) +})