Skip to content

Instantly share code, notes, and snippets.

@Alexs7zzh
Created April 24, 2021 04:44
Show Gist options
  • Save Alexs7zzh/d92ae991ad05ed585d072074ea527b5c to your computer and use it in GitHub Desktop.
Save Alexs7zzh/d92ae991ad05ed585d072074ea527b5c to your computer and use it in GitHub Desktop.
eleventy-img in markdown
const Image = require('@11ty/eleventy-img')
const { parseHTML } = require('linkedom')
module.exports = eleventyConfig => {
if (process.env.ELEVENTY_ENV)
eleventyConfig.addTransform('transform', (content, outputPath) => {
if (outputPath && outputPath.endsWith('.html')) {
let { document } = parseHTML(content)
const options = {
widths: [768, 1280, 1600, 1920, null],
sizes: '', // your responsive sizes here
formats: ['webp', 'jpeg'],
urlPath: '/assets/',
outputDir: './_site/assets/'
}
const images = [...document.querySelectorAll('figure img')]
images.forEach((i, index) => {
const src = '.' + i.getAttribute('src')
const meta = Image.statsSync(src, options)
const last = meta.jpeg[meta.jpeg.length - 1]
if (last.width < 500) return
Image(src, options)
i.setAttribute('width', last.width)
i.setAttribute('height', last.height)
if (index !== 0) {
i.setAttribute('loading', 'lazy')
i.setAttribute('decoding', 'async')
}
i.outerHTML = `
<picture>
<source type="image/webp" sizes="${options.sizes}" srcset="${meta.webp.map(p => p.srcset).join(', ')}">
<source type="image/jpeg" sizes="${options.sizes}" srcset="${meta.jpeg.map(p => p.srcset).join(', ')}">
${i.outerHTML}
</picture>`
})
return `<!DOCTYPE html>${document.documentElement.outerHTML}`
}
return content
})
}
const Token = require('markdown-it/lib/token')
const arrayReplaceAt = (src, pos, newElements) => {
return [].concat(src.slice(0, pos), newElements, src.slice(pos + 1))
}
module.exports = md => {
const figure_def = state => {
let nesting = 0
for (let idx = state.tokens.length - 1; idx >= 0; idx--) {
nesting += state.tokens[idx].nesting
if (state.tokens[idx].type !== 'inline') continue
if (nesting !== -1) continue
let token = state.tokens[idx]
if (token.children.length !== 1) continue
if (token.children[0].type !== 'image') continue
if (state.tokens[idx + 1].type !== 'paragraph_close') continue
if (state.tokens[idx - 1].type !== 'paragraph_open') continue
state.tokens[idx + 1] = new Token('figure_close', 'figure', -1)
state.tokens[idx + 1].block = true
state.tokens[idx - 1] = new Token('figure_open', 'figure', 1)
state.tokens[idx - 1].block = true
let img = token.children[0],
caption = img.attrGet('title')
if (!caption) continue
let inline = new Token('inline', '', 0)
inline.content = caption
inline.block = true
let text = new Token('text', '', 0)
text.content = caption
inline.children = [text]
let figcaption_open = new Token('figcaption_open', 'figcaption', 1)
figcaption_open.block = true
let figcaption_close = new Token('figcaption_close', 'figcaption', -1)
figcaption_close.block = true
state.tokens = arrayReplaceAt(state.tokens, idx, [
img,
figcaption_open,
inline,
figcaption_close
])
}
}
md.core.ruler.push('figure', figure_def)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment