diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d18fbf..8d612d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,18 @@ ## [Unreleased] -### Changed +### Added -- Upgrade Node.js and dependent packages to the latest version ([#369](https://github.com/marp-team/marpit/pull/369)) +- Advanced background: Render the image's alt text to `
` ([#368](https://github.com/marp-team/marpit/issues/368), [#371](https://github.com/marp-team/marpit/pull/371)) ### Fixed - Begin the page number from 1 even if used `paginate: hold` at the first page ([#365](https://github.com/marp-team/marpit/issues/365), [#370](https://github.com/marp-team/marpit/pull/370)) +### Changed + +- Upgrade Node.js and dependent packages to the latest version ([#369](https://github.com/marp-team/marpit/pull/369)) + ## v2.5.0 - 2023-06-06 ### Added diff --git a/src/markdown/background_image/advanced.js b/src/markdown/background_image/advanced.js index 12a4184..d3b44aa 100644 --- a/src/markdown/background_image/advanced.js +++ b/src/markdown/background_image/advanced.js @@ -99,6 +99,13 @@ function _advancedBackground(md) { { tag: 'figure', style: style.toString(), + open: { + meta: { + // For getting better alt text, we should store + // the reference of the original image token. + marpitBackgroundSource: img.source, + }, + }, }, ), ) @@ -155,6 +162,37 @@ function _advancedBackground(md) { state.tokens = newTokens }, ) + + // Renderer for advanced background image + md.renderer.rules.marpit_advanced_background_image_open = ( + tokens, + idx, + options, + env, + self, + ) => { + const token = tokens[idx] + const open = self.renderToken(tokens, idx, options) + + if (token.meta && token.meta.marpitBackgroundSource) { + // Try to render figcaption for background image + // (Image token after parsed has text children without Marpit keywords) + const figcaption = self + .renderInlineAsText( + token.meta.marpitBackgroundSource.children, + options, + env, + ) + .trim() + + if (figcaption) + return `${open}
${md.utils.escapeHtml( + figcaption, + )}
` + } + + return open + } } export const advancedBackground = marpitPlugin(_advancedBackground) diff --git a/src/markdown/background_image/apply.js b/src/markdown/background_image/apply.js index f672b0a..0da6d19 100644 --- a/src/markdown/background_image/apply.js +++ b/src/markdown/background_image/apply.js @@ -100,6 +100,7 @@ function _backgroundImageApply(md) { })(), url, width, + source: t, }, ] } diff --git a/src/postcss/advanced_background.js b/src/postcss/advanced_background.js index dba82bb..7faaf4d 100644 --- a/src/postcss/advanced_background.js +++ b/src/postcss/advanced_background.js @@ -56,6 +56,18 @@ section[data-marpit-advanced-background="background"] > div[data-marpit-advanced margin: 0; } +section[data-marpit-advanced-background="background"] > div[data-marpit-advanced-background-container] > figure > figcaption { + position: absolute; + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + white-space: nowrap; + width: 1px; +} + section[data-marpit-advanced-background="content"], section[data-marpit-advanced-background="pseudo"] { background: transparent !important; diff --git a/test/markdown/background_image.js b/test/markdown/background_image.js index 4f05fd7..4d866b8 100644 --- a/test/markdown/background_image.js +++ b/test/markdown/background_image.js @@ -1,4 +1,5 @@ import { load } from 'cheerio' +import dedent from 'dedent' import MarkdownIt from 'markdown-it' import { backgroundImage } from '../../src/markdown/background_image' import { comment } from '../../src/markdown/comment' @@ -205,6 +206,33 @@ describe('Marpit background image plugin', () => { expect(figures.eq(1).attr('style')).toBe('background-image:url("B");') }) + it('renders alternative text as
, without Marpit specific keywords', () => { + const $ = $load( + mdSVG().render(dedent` + ![bg fit The background image](A) + ![This is bg 20% w:40% xxxxx](B) + ![ bg ](C) + ![bg should
escape
](D) + `), + ) + const figures = $('figure') + + expect(figures.eq(0).is(':has(figcaption)')).toBe(true) + expect(figures.eq(0).find('figcaption').text()).toBe( + 'The background image', + ) + expect(figures.eq(1).is(':has(figcaption)')).toBe(true) + expect(figures.eq(1).find('figcaption').text()).toBe('This is xxxxx') + + // Ignore whitespaces + expect(figures.eq(2).is(':has(figcaption)')).toBe(false) + + // XSS + expect(figures.eq(3).is(':has(figcaption)')).toBe(true) + expect(figures.eq(3).is(':has(b)')).toBe(false) + expect(figures.eq(3).is(':has(br)')).toBe(false) + }) + it('assigns background-size style with resizing keyword / scale', () => { const markdown = '![bg fit](A) ![bg 50%](B) ![bg w:40px](C) ![bg 10% h:20%](D)'