From 4777bbc82cce296a49572b0ff6a427edc330fd3b Mon Sep 17 00:00:00 2001 From: Eben Eliason Date: Tue, 4 Jan 2022 12:49:19 -0800 Subject: [PATCH 1/2] [APT-1575] Add support for image captions via plugin The plugin identifies image content in the page with alt text specified, and injects a new emphasis node immediately following containing that text. --- docusaurus.config.js | 3 +++ src/css/custom.css | 16 ++++++++++++++++ src/plugins/captions.js | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 src/plugins/captions.js diff --git a/docusaurus.config.js b/docusaurus.config.js index e1b4733f07..8a3b362948 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -5,6 +5,8 @@ const lightCodeTheme = require("prism-react-renderer/themes/github") const darkCodeTheme = require("prism-react-renderer/themes/dracula") const cfg = require("config") +const captionsPlugin = require("./src/plugins/captions") + const googleAnalyticsConfig = cfg.has("googleAnalytics") ? cfg.get("googleAnalytics") : undefined @@ -32,6 +34,7 @@ const config = { sidebarPath: require.resolve("./sidebars.js"), // Please change this to your repo. // editUrl: "https://github.com/facebook/docusaurus/edit/main/website/", + beforeDefaultRemarkPlugins: [captionsPlugin], }, theme: { customCss: require.resolve("./src/css/custom.css"), diff --git a/src/css/custom.css b/src/css/custom.css index dfa0334d98..1d7e8275b9 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -69,6 +69,22 @@ main { margin-top: 2em; } +/* IMAGES & CAPTIONS */ + +p > img { + display: block; + margin: auto; +} + +p > img + em { + color: gray; + font-size: 0.9rem; + display: block; + text-align: center; + max-width: 80%; + margin: 1rem auto 2rem auto; +} + /* HOME PAGE */ .hero--primary .button--lg { diff --git a/src/plugins/captions.js b/src/plugins/captions.js new file mode 100644 index 0000000000..87eff71963 --- /dev/null +++ b/src/plugins/captions.js @@ -0,0 +1,36 @@ +const visit = require("unist-util-visit") + +const plugin = (options) => { + const transformer = async (ast) => { + visit(ast, "paragraph", (node) => { + if ( + node.children && + node.children.length === 1 && // exactly one child + node.children[0].type === "image" && // that is an image + node.children[0].alt // with a specified alt attribute + ) { + // replace the existing paragraph node with a newly + // constructed one which contains the origin image node + // and a new emphasis node containing its alt text + return Object.assign(node, { + type: "paragraph", + children: [ + node.children[0], + { + type: "emphasis", + children: [ + { + type: "text", + value: node.children[0].alt, + }, + ], + }, + ], + }) + } + }) + } + return transformer +} + +module.exports = plugin From 435fd427992bc6f5b59f8f2bd1c6caf4e2ffa00e Mon Sep 17 00:00:00 2001 From: Eben Eliason Date: Tue, 4 Jan 2022 15:28:57 -0800 Subject: [PATCH 2/2] Better documentation for captions plugin --- src/plugins/captions.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/plugins/captions.js b/src/plugins/captions.js index 87eff71963..a6d5c036f2 100644 --- a/src/plugins/captions.js +++ b/src/plugins/captions.js @@ -1,5 +1,20 @@ const visit = require("unist-util-visit") +// This plugin repurposes the alt text specified for images to +// automatically generate captions for them. For example: +// +// ![This alt text will also appear as a caption](/img/example.png) +// +// The caption is injected as an element in the output, which can +// then be styled using an `img + em` selector. +// +// Note that it's also possible to override the automated behavior +// of this plugin by proving a custom caption in an emphasis block +// immediately following the image in the markdown, e.g. +// +// ![Alt text, overridden by the caption below](/img/example.png) +// _A custom caption, which overrides the alt text above_ + const plugin = (options) => { const transformer = async (ast) => { visit(ast, "paragraph", (node) => { @@ -9,9 +24,9 @@ const plugin = (options) => { node.children[0].type === "image" && // that is an image node.children[0].alt // with a specified alt attribute ) { - // replace the existing paragraph node with a newly - // constructed one which contains the origin image node - // and a new emphasis node containing its alt text + // Replace the existing paragraph node with a newly + // constructed one which contains the original image node + // and a new emphasis node containing its alt text. return Object.assign(node, { type: "paragraph", children: [