From 4723b5cc8bfc53535019ee19f3d6e4375f0249ce Mon Sep 17 00:00:00 2001 From: Mark Meyer Date: Thu, 6 Jul 2023 16:52:37 -0800 Subject: [PATCH] refactor plugin for links to process raw links an images that are inline html --- astro.config.mjs | 10 +++-- src/plugins/process_anchors.js | 66 +++++++++++++++++++++++++++++++ src/plugins/process_image_urls.js | 52 ++++++++++++++++++++++++ src/plugins/uswds_links.js | 28 ------------- 4 files changed, 124 insertions(+), 32 deletions(-) create mode 100644 src/plugins/process_anchors.js create mode 100644 src/plugins/process_image_urls.js delete mode 100644 src/plugins/uswds_links.js diff --git a/astro.config.mjs b/astro.config.mjs index 37706361..2b0f80aa 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,7 +1,7 @@ import { defineConfig } from 'astro/config'; import mdx from '@astrojs/mdx'; -import uswds_links from "./src/plugins/uswds_links"; -import prefix_links from './src/plugins/prefix_links'; +import process_anchors from "./src/plugins/process_anchors"; +import process_image_urls from './src/plugins/process_image_urls'; import sitemap from "@astrojs/sitemap"; // https://astro.build/config @@ -11,7 +11,9 @@ export default defineConfig({ integrations: [mdx(), sitemap()], outDir: '_site', markdown: { - rehypePlugins: [uswds_links], - remarkPlugins: [[prefix_links, {baseURL: process.env.BASEURL || '/'}]] + rehypePlugins: [ + [process_anchors, {baseURL: process.env.BASEURL || '/'}], + [process_image_urls, {baseURL: process.env.BASEURL || '/'}] + ], } }); \ No newline at end of file diff --git a/src/plugins/process_anchors.js b/src/plugins/process_anchors.js new file mode 100644 index 00000000..c5ed7155 --- /dev/null +++ b/src/plugins/process_anchors.js @@ -0,0 +1,66 @@ +/* + * The purpose of this is to process links in content sources to prevent + * local links on cloud.gov pages feature branches from breaking. + * Markdown links like [some text](somelink) will be prefixed with the + * Base_URL and have the class `usa-link` added. If the link is a + * non-smartpay link it will additionally get the usa-link--external class + * + * Inline html links like some text + * will only be prefixed with the baseURL. Classes can be added inline + */ + + +import {visit} from 'unist-util-visit' + +import path from 'path' + +function isInternalDomain(url) { + try { + const domain = new URL(url) + return domain.hostname.endsWith('smartpay.gsa.gov') + } catch(e) { + // this represents urls like "/some/path" without domain + return true + } +} + +function process_mdx_anchor(node, baseURL) { + /** + * Process raw links in source content + * like text + */ + + node.attributes.forEach(attr => { + if (attr.name === 'href' && attr.value.startsWith('/') && !attr.value.startsWith('//')) { + attr.value = path.join('/', baseURL, attr.value) + } + }); +} + +function process_markdown_link(node, baseURL) { + /** + * Process raw links in source content + * like [some text](/some_link) + */ + + const properties = node.properties + properties.className = isInternalDomain(properties.href) + ? 'usa-link' + : 'usa-link usa-link--external'; + + if (properties.href.startsWith('/') && !properties.href.startsWith('//')) { + properties.href = path.join('/', baseURL, properties.href) + } +} +export default (options) => { + return tree => { + visit(tree, [{"type": "element", "tagName": "a"}, {"type":'mdxJsxTextElement', "name": "a"}], (node, index, parent) => { + if (node.type === 'mdxJsxTextElement') { + process_mdx_anchor(node, options.baseURL) + } else { + process_markdown_link(node, options.baseURL) + } + }) + } +}; + diff --git a/src/plugins/process_image_urls.js b/src/plugins/process_image_urls.js new file mode 100644 index 00000000..bf83d4d5 --- /dev/null +++ b/src/plugins/process_image_urls.js @@ -0,0 +1,52 @@ +/* + * The purpose of this is to process image in content sources to prevent + * local srcs (those starting with `/`) on cloud.gov pages feature branches from breaking. + * This should work for both markdown image like ![some text](somelink) as well as + * inline html image like some text + */ + + +import {visit} from 'unist-util-visit' + +import path from 'path' + + +function process_mdx_image(node, baseURL) { + /** + * Process raw img tags in source content + * like + */ + + node.attributes.forEach(attr => { + if (attr.name === 'src' && attr.value.startsWith('/') && !attr.value.startsWith('//')) { + attr.value = path.join('/', baseURL, attr.value) + } + }); + } + + function process_markdown_image(node, baseURL) { + /** + * Process raw links in source content + * like ![some text](/some_link) + */ + + const properties = node.properties + + if (properties.src.startsWith('/') && !properties.src.startsWith('//')) { + properties.src = path.join('/', baseURL, properties.src) + } + } + export default (options) => { + return tree => { + visit(tree, [{"type": "element", "tagName": "img"}, {"type":'mdxJsxFlowElement', "name": "img"}], (node, index, parent) => { + console.log(node) + if (node.type === 'mdxJsxFlowElement') { + process_mdx_image(node, options.baseURL) + } else { + process_markdown_image(node, options.baseURL) + } + }) + } + }; + + \ No newline at end of file diff --git a/src/plugins/uswds_links.js b/src/plugins/uswds_links.js deleted file mode 100644 index 589a6574..00000000 --- a/src/plugins/uswds_links.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * The purpose of this is to apply the appropriate class to links - * it will add uswds usa-link--external for non gsa.gov links - */ -import selector from 'hast-util-select'; - -const { selectAll } = selector; - -export default () => { - return node => selectAll('a', node).forEach(node => { - const properties = node.properties - properties.className = 'usa-link' - - let domain; - try { - domain = new URL(properties.href) - } catch(e) { - // Exceptions will be raised with relative links - // these will all be local, so ignore - return - } - - if (! domain.hostname.endsWith('smartpay.gsa.gov')) { - properties.className += ' usa-link--external' - } - }); -}; -