diff --git a/src/plugins/rehype/external-links.ts b/src/plugins/rehype/external-links.ts index 68039f18f0fc919..8c7d19196333ee0 100644 --- a/src/plugins/rehype/external-links.ts +++ b/src/plugins/rehype/external-links.ts @@ -1,9 +1,22 @@ import rehypeExternalLinks, { type Options } from "rehype-external-links"; +import type { Element } from "hast"; + +function hasImgChild(node: Element): boolean { + return node.children.some( + (child) => child.type === "element" && child.tagName === "img", + ); +} + +export const externalLinkArrow = " ↗"; export const rehypeExternalLinksOptions = { - content: { - type: "text", - value: " ↗", + content: (element) => { + if (!hasImgChild(element)) { + return { + type: "text", + value: externalLinkArrow, + }; + } }, contentProperties: { class: "external-link", diff --git a/src/plugins/rehype/heading-slugs.ts b/src/plugins/rehype/heading-slugs.ts index c7f4ae3da308618..eee76801b6f0159 100644 --- a/src/plugins/rehype/heading-slugs.ts +++ b/src/plugins/rehype/heading-slugs.ts @@ -1,7 +1,7 @@ import { toString } from "hast-util-to-string"; import { visit } from "unist-util-visit"; import GithubSlugger from "github-slugger"; -import { rehypeExternalLinksOptions } from "./external-links"; +import { externalLinkArrow } from "./external-links"; import type { Root } from "hast"; import type { MdxTextExpression } from "mdast-util-mdx-expression"; @@ -34,7 +34,7 @@ export default function () { } else { if (!element.properties.id) { const string = toString(element) - .replaceAll(rehypeExternalLinksOptions.content.value, "") + .replaceAll(externalLinkArrow, "") .trimEnd(); element.properties.id = slugs.slug(string); diff --git a/src/plugins/rehype/index.node.test.ts b/src/plugins/rehype/index.node.test.ts index 48024d1878439e6..163923e7539bbf4 100644 --- a/src/plugins/rehype/index.node.test.ts +++ b/src/plugins/rehype/index.node.test.ts @@ -15,7 +15,12 @@ describe("heading-slugs", () => { .data("settings", { fragment: true, }) - .use([rehypeParse, rehypeHeadingSlugs, rehypeStringify]) + .use([ + rehypeParse, + rehypeExternalLinks, + rehypeHeadingSlugs, + rehypeStringify, + ]) .process(html); return file.toString(); @@ -32,6 +37,16 @@ describe("heading-slugs", () => { expect(text).toMatchInlineSnapshot(`"
',
+ );
+
+ expect(text).toMatchInlineSnapshot(
+ `"
"`,
+ );
+ });
});
describe("autolink-headings", () => {
diff --git a/src/util/props.node.test.ts b/src/util/props.node.test.ts
index c30e4af9a2427c7..a02e7b8a3b5da11 100644
--- a/src/util/props.node.test.ts
+++ b/src/util/props.node.test.ts
@@ -1,6 +1,6 @@
import { describe, expect, test } from "vitest";
import { generateDescription } from "./props";
-import { rehypeExternalLinksOptions } from "~/plugins/rehype/external-links";
+import { externalLinkArrow } from "~/plugins/rehype/external-links";
describe("description", () => {
describe("markdown", () => {
@@ -13,10 +13,8 @@ describe("description", () => {
});
test("removes external link icon", async () => {
- const icon = rehypeExternalLinksOptions.content.value;
-
const desc = await generateDescription({
- markdown: `[links${icon}](/) and **${icon}stuff**`,
+ markdown: `[links${externalLinkArrow}](/) and **${externalLinkArrow}stuff**`,
});
expect(desc).toEqual("links and \\*\\*stuff\\*\\*");
diff --git a/src/util/props.ts b/src/util/props.ts
index 1e50c57a72d43cf..cf6a24b38794886 100644
--- a/src/util/props.ts
+++ b/src/util/props.ts
@@ -3,7 +3,7 @@ import { parse } from "node-html-parser";
import he from "he";
import { remark } from "remark";
import strip from "strip-markdown";
-import { rehypeExternalLinksOptions } from "~/plugins/rehype/external-links";
+import { externalLinkArrow } from "~/plugins/rehype/external-links";
type TableOfContentsItems = NonNullable