Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support wiki links with special characters and fix links to headings #1040

Merged
merged 4 commits into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/many-ligers-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@portaljs/remark-wiki-link': patch
---

Changed regex to permit any symbols other than #
4 changes: 2 additions & 2 deletions packages/remark-wiki-link/src/lib/fromMarkdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function fromMarkdown(opts: FromMarkdownOptions = {}) {
data: { isEmbed, target, alias },
} = wikiLink;
// eslint-disable-next-line no-useless-escape
const wikiLinkWithHeadingPattern = /([\p{Letter}\d\s\/\.-_]*)(#.*)?/u;
const wikiLinkWithHeadingPattern = /^(.*?)(#.*)?$/u;
const [, path, heading = ""] = target.match(wikiLinkWithHeadingPattern);

const possibleWikiLinkPermalinks = wikiLinkResolver(path);
Expand Down Expand Up @@ -116,7 +116,7 @@ function fromMarkdown(opts: FromMarkdownOptions = {}) {

// remove leading # if the target is a heading on the same page
const displayName = alias || target.replace(/^#/, "");
const headingId = heading.replace(/\s+/, "-").toLowerCase();
const headingId = heading.replace(/\s+/g, "-").toLowerCase();
let classNames = wikiLinkClassName;
if (!matchingPermalink) {
classNames += " " + newClassName;
Expand Down
4 changes: 2 additions & 2 deletions packages/remark-wiki-link/src/lib/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function html(opts: HtmlOptions = {}) {
const { target, alias } = wikiLink;
const isEmbed = token.isType === "embed";
// eslint-disable-next-line no-useless-escape
const wikiLinkWithHeadingPattern = /([\w\s\/\.-]*)(#.*)?/;
const wikiLinkWithHeadingPattern = /^(.*?)(#.*)?$/u;
const [, path, heading = ""] = target.match(wikiLinkWithHeadingPattern);

const possibleWikiLinkPermalinks = wikiLinkResolver(path);
Expand Down Expand Up @@ -99,7 +99,7 @@ function html(opts: HtmlOptions = {}) {
// remove leading # if the target is a heading on the same page
const displayName = alias || target.replace(/^#/, "");
// replace spaces with dashes and lowercase headings
const headingId = heading.replace(/\s+/, "-").toLowerCase();
const headingId = heading.replace(/\s+/g, "-").toLowerCase();
let classNames = wikiLinkClassName;
if (!matchingPermalink) {
classNames += " " + newClassName;
Expand Down
2 changes: 1 addition & 1 deletion packages/remark-wiki-link/test/getPermalinks.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getPermalinks } from "../src/utils";
// const markdownFolder = path.join(__dirname, "/fixtures/content");
const markdownFolder = path.join(
".",
"/packages/remark-wiki-link/test/fixtures/content"
"test/fixtures/content"
);

describe("getPermalinks", () => {
Expand Down
10 changes: 10 additions & 0 deletions packages/remark-wiki-link/test/micromarkExtensionWikiLink.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,4 +321,14 @@ describe("micromark-extension-wiki-link", () => {
);
});
});

describe("Links with special characters", () => {
test("parses a link with special characters and symbols", () => {
const serialized = micromark("[[li nk-w(i)th-àcèô íã_a(n)d_underline!:ª%@'*º$ °~./\\#LI NK-W(i)th-àcèô íã_a(n)d_uNdErlinE!:ª%@'*º$ °~./\\]]", "ascii", {
extensions: [syntax()],
htmlExtensions: [html() as any],
});
expect(serialized).toBe(`<p><a href="li nk-w(i)th-àcèô íã_a(n)d_underline!:ª%@'*º$ °~./\\#li-nk-w(i)th-àcèô-íã_a(n)d_underline!:ª%@'*º$-°~./\\" class="internal new">li nk-w(i)th-àcèô íã_a(n)d_underline!:ª%@'*º$ °~./\\#LI NK-W(i)th-àcèô íã_a(n)d_uNdErlinE!:ª%@'*º$ °~./\\</a></p>`);
});
})
});
27 changes: 27 additions & 0 deletions packages/remark-wiki-link/test/remarkWikiLink.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,32 @@ describe("remark-wiki-link", () => {
});
});

describe("Links with special characters", () => {
Gutts-n marked this conversation as resolved.
Show resolved Hide resolved
test("parses a link with special characters and symbols", () => {
const processor = unified().use(markdown).use(wikiLinkPlugin);

let ast = processor.parse("[[li nk-w(i)th-àcèô íã_a(n)d_underline!:ª%@'*º$ °~./\\#li-nk-w(i)th-àcèô íã_a(n)D_UNDERLINE!:ª%@'*º$ °~./\\]]");
ast = processor.runSync(ast);
expect(select("wikiLink", ast)).not.toEqual(null);

visit(ast, "wikiLink", (node: Node) => {
expect(node.data?.exists).toEqual(false);
expect(node.data?.permalink).toEqual("li nk-w(i)th-àcèô íã_a(n)d_underline!:ª%@'*º$ °~./\\");
expect(node.data?.alias).toEqual(null);
expect(node.data?.hName).toEqual("a");
expect((node.data?.hProperties as any).className).toEqual(
"internal new"
);
expect((node.data?.hProperties as any).href).toEqual(
"li nk-w(i)th-àcèô íã_a(n)d_underline!:ª%@'*º$ °~./\\#li-nk-w(i)th-àcèô-íã_a(n)d_underline!:ª%@'*º$-°~./\\"
);
expect((node.data?.hChildren as any)[0].value).toEqual(
"li nk-w(i)th-àcèô íã_a(n)d_underline!:ª%@'*º$ °~./\\#li-nk-w(i)th-àcèô íã_a(n)D_UNDERLINE!:ª%@'*º$ °~./\\"
);
})
});
})

describe("invalid wiki links", () => {
test("doesn't parse a wiki link with two missing closing brackets", () => {
const processor = unified().use(markdown).use(wikiLinkPlugin);
Expand Down Expand Up @@ -560,3 +586,4 @@ describe("remark-wiki-link", () => {
});
});
});