Skip to content

actuallysomecat/markdown-it-wikilinks-plus

Repository files navigation

markdown-it-wikilinks-plus


An 11ty plugin for markdown-it to use (Obsidian style) wikilinks and image embeds, like [[some page]] and ![[image.png]].

Includes support for alt text and link labels via pipe | in the markdown image embed or wikilink, as well as dimensions on image embeds (this plugin can add an inline style to the <img> with width and height taken from the dimensions in the markdown):

  • [[some page|see here]] for a link to some page with link text see here
  • ![[image.png|some cat]] for an image embed with alt="some cat"
  • ![[image.png|200x200]] for an image embed with display size 200x200:
    • the image would get an inline style attribute of style="width: 200px; height: 200px;"
  • both alt text and dimension attributes can be added by using another pipe and making the dimensions the last piped section on an image embed:
    • ![[image.png|some cat|200x200]] results in the attributes:
      • alt="some cat" style="width: 200px; height: 200px;"

This plugin can also create an alt attribute for image embeds with missing alt text:

  • using the image name as the alt attribute (for each image embed missing alt text)
  • using a given string as the alt attribute (for each image embed missing alt text)

Tip

this can be an empty string, to get alt="" attributes on image embeds with missing alt text


Installation

Install in your project with:

npm install github:actuallysomecat/markdown-it-wikilinks-plus

or manually by adding to your package.json dependencies:

{
  "dependencies": {
    "markdown-it-wikilinks-plus": "github:actuallysomecat/markdown-it-wikilinks-plus"
  }
}

then do npm install in the project.


Usage

In your 11ty config (eleventy.config.js), .use() this plugin with your markdown-it instance:

import MarkdownIt from 'markdown-it'
import wikilinksPlus from 'markdown-it-wikilinks-plus'

// default options for wikilinksPlus (see README)
const wikilinksPlusOptions = { /* default options */ }

// use wikilinksPlus with the markdown-it instance
const md = new MarkdownIt(mdOptions)
  .use(wikilinksPlus, wikilinksPlusOptions)
  // ... any additional plugins ...

// setting the markdown library:
eleventyConfig.setLibrary("md", md)

// ... rest of eleventy.config.js ...

Options

Group Option Type Default
pageLink absoluteBaseURL string '/'
pageLink relativeBaseURL string './'
pageLink forceAllLinksAbsolute boolean false
pageLink postProcessLinkTarget function{} (target) => target.trim()
pageLink postProcessLinkLabel function{} (label) => label.trim()
pageLink allowLinkLabelFormatting boolean true
pageLink uriSuffix string ''
pageLink htmlAttributes function or object {}
- - - -
imageEmbed absoluteBaseURL string '/'
imageEmbed relativeBaseURL string './'
imageEmbed forceAllImageUrlsAbsolute boolean false
imageEmbed uriSuffix string ''
imageEmbed htmlAttributes function or object {}
imageEmbed postProcessImageTarget function{} (imageTarget) => imageTarget.trim().split('/').map(sanitize).join('/')
imageEmbed postProcessAltText function{} (altText) => altText.trim()
imageEmbed imageFileExt string[] ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'svg', 'webp']
imageEmbed defaultAltText boolean or string false

Default Options

Tip

Copypaste-friendly default options object template

(any options omitted will use their default value)

// default markdown-it-wikilinks-plus options
const wikilinksPlusOptions = {
  pageLink: {
    absoluteBaseURL: '/',
    relativeBaseURL: './',
    forceAllLinksAbsolute: false,
    postProcessLinkTarget: (target) => target.trim(),
    postProcessLinkLabel: (label) => label.trim(),
    allowLinkLabelFormatting: true,
    uriSuffix: '',
    htmlAttributes: {},
  },
  imageEmbed: {
    absoluteBaseURL: '/',
    relativeBaseURL: './',
    forceAllImageUrlsAbsolute: false,
    uriSuffix: '',
    htmlAttributes: {},
    postProcessImageTarget: (imageTarget) =>
      imageTarget.trim().split('/').map(sanitize).join('/'),
    postProcessAltText: (altText) => altText.trim(),
    imageFileExt: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'svg', 'webp'],
    defaultAltText: false,
  }
}

Options Details

pageLink

pageLink.absoluteBaseURL

Default: /

absolute base URL for pages

back to Options 🔼 | back to top

pageLink.relativeBaseURL

Default: ./

relative base URL for pages, if needed

back to Options 🔼 | back to top

pageLink.forceAllLinksAbsolute

Default: false

make all the page links absolute

back to Options 🔼 | back to top

pageLink.postProcessLinkTarget

Default: (target) => target.trim()

process the wikilink target (the part before a pipe (if present)). default is to trim. might be a good place to do a slugify or toLowerCase or something. (the target will be escaped internally when the href is made)

back to Options 🔼 | back to top

pageLink.postProcessLinkLabel

Default: (label) => label.trim()

process the wikilink label (the part after a pipe (if present)).

back to Options 🔼 | back to top

pageLink.allowLinkLabelFormatting

Default: true

whether to format markdown in link labels

  • if true, a link label like [[test|*testing*]] would be in italics ('testing'), etc
  • if false, the same link label would be plaintext *testing*, unformatted

back to Options 🔼 | back to top

pageLink.uriSuffix

Default: ''

suffix to add to the link target (like .html)

back to Options 🔼 | back to top

pageLink.htmlAttributes

Default: {}

html attributes to add to the <a>

Note

href from htmlAttributes overrides derived href

back to Options 🔼 | back to top

pageLink.htmlAttributes example function
const customPageLinkAttributes: ({ originalHref, label }) => {
  let attrs = {}
  // give wikilinks a class 'internal-link'
  attrs = { class: `internal-link` }

  // give wikilinks a title referencing their originalHref
  attrs.title = `internal link to ${originalHref}`
  
  // console log the link label for some reason
  console.log(`link label: ${label}`)

  return attrs
}
pageLink.htmlAttributes example object
const customPageLinkAttributes = {
  // give wikilinks a class 'internal-link'
  class: `internal-link`,
  // and some other attribute
  'custom-attribute': 'meow'
}

back to Options 🔼 | back to top

imageEmbed

imageEmbed.absoluteBaseURL

Default: '/'

absolute base URL for images

back to Options 🔼 | back to top

imageEmbed.relativeBaseURL

Default: './'

relative base URL for images, if needed

back to Options 🔼 | back to top

imageEmbed.forceAllImageUrlsAbsolute

Default: false

whether to force all the image URLs to be absolute

back to Options 🔼 | back to top

imageEmbed.uriSuffix

Default: ''

suffix to add to the image URL (like '?v=123')

back to Options 🔼 | back to top

imageEmbed.htmlAttributes

Default: {}

html attributes to add to the <img>

Note

alt text returned from htmlAttributes overrides any originally provided or computed alt text from the image

back to Options 🔼 | back to top

imageEmbed.htmlAttributes example function
const customImageEmbedAttributes: ({ embedType, dimensions, originalHref, altText }) => {
  let attrs = {}
  // give image embeds a class 'image-embed'
  attrs = { class: `${embedType}-embed` }

  // use the provided or computed alt text, if available, for title attribute
  if (altText) {
    attrs.title = altText
  }

  // console log originalHref and dimensions for some reason
  console.log(`originalHref: ${originalHref}`)
  console.log(`dimensions: ${dimensions}`)

  return attrs
}
imageEmbed.htmlAttributes example object
const customImageEmbedAttributes = {
  // give image embeds a custom class
  class: 'image-embed--class',
  // and some other attribute
  'custom-attribute': 'meow'
}

back to Options 🔼 | back to top

imageEmbed.postProcessImageTarget

Default:

(imageTarget) => imageTarget.trim().split('/').map(sanitize).join('/')

process the image target (the filename). default is to trim, split, sanitize each section of the full image target, then rejoin. might be a good place to do a slugify or toLowerCase or something. (the target will be escaped internally when the href is made)

back to Options 🔼 | back to top

imageEmbed.postProcessAltText

Default:

(altText) => altText.trim()

process the alt text from the label (the bit after the first pipe, if it's not dimensions) (default is to trim)

back to Options 🔼 | back to top

imageEmbed.imageFileExt

Default:

['bmp', 'gif', 'jpeg', 'jpg', 'png', 'svg', 'webp']

allowed file extensions to be considered an image (embed) to be processed

back to Options 🔼 | back to top

imageEmbed.defaultAltText

Default: false

boolean to generate a default alt attribute for any image embed without alt text:

  • true: use the image name to create an alt attribute for any image embed without alt text
    • example: /img/cat/meow.png would get alt="meow"
  • false: do not generate any alt attribute for image embeds without alt text

or a string to use as the alt attribute on any image embeds without alt text:

  • example: defaultAltText: 'PLACEHOLDER' would give all image embeds without alt text an alt="PLACEHOLDER" attribute
  • example: defaultAltText: '' would give all image embeds without alt text alt="" attribute

Warning

if this is anything other than a boolean or string, the image name will be used as the default alt text for any image embeds missing alt text

back to Options 🔼 | back to top


Meow

meow

About

wikilinks and wikilink-format image embeds in markdown-it (in 11ty)

Topics

Resources

License

Stars

Watchers

Forks