Skip to content
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
24 changes: 18 additions & 6 deletions src/utilities/process-readme.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,23 @@ const fragmentLinkMap = {
"/guides/shimming/#provideplugin": "/plugins/provide-plugin/",
};

/**
* The page a raw README url is rendered at. A raw url names the branch where a
* rendered one names `blob` and then the branch, and the branch is whatever the
* repository calls its default one.
* @param {string} sourceUrl where the readme was read from
* @returns {string} what its relative links resolve against
*/
function renderedUrlOf(sourceUrl) {
const raw = new URL(sourceUrl);

if (raw.hostname !== "raw.githubusercontent.com") return sourceUrl;

const [, owner, repository, ...rest] = raw.pathname.split("/");

return `https://github.com/${owner}/${repository}/blob/${rest.join("/")}`;
}

function linkFixerFactory(sourceUrl) {
return function linkFixer(markdownLink, href) {
const oldHref = href;
Expand All @@ -34,12 +51,7 @@ function linkFixerFactory(sourceUrl) {

// Only resolve non-absolute urls from their source if they are not a document fragment link
if (!href.startsWith("#")) {
// Convert Github raw links to rendered links
const renderedUrl = sourceUrl
.replace(/raw.githubusercontent.com/, "github.com")
.replace(/master/, "blob/master");

href = new URL(href, renderedUrl).href;
href = new URL(href, renderedUrlOf(sourceUrl)).href;
}

// Modify absolute documentation links to be root relative
Expand Down
16 changes: 15 additions & 1 deletion src/utilities/process-readme.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ describe("processReadme", () => {
);
});

it("renders a relative link against the branch the readme was read from", () => {
// A raw url names the branch where a rendered one names `blob` and then
// the branch, whatever the repository calls its default one.
for (const branch of ["master", "main", "next"]) {
const options = {
source: `https://raw.githubusercontent.com/webpack/html-loader/${branch}/README.md`,
};

expect(processReadme("[LICENSE](./LICENSE)", options)).toBe(
`[LICENSE](https://github.com/webpack/html-loader/blob/${branch}/LICENSE)`,
);
}
});

it("keeps the github link when the site builds no page for the package", () => {
const options = {
source: url,
Expand Down Expand Up @@ -80,7 +94,7 @@ describe("processReadme", () => {
const loaderMDData =
"See the file [`./src/config.d.ts`](./src/config.d.ts).";
expect(processReadme(loaderMDData, options)).toBe(
"See the file [`https://github.com/webpack/postcss-loader/main/src/config.d.ts`](https://github.com/webpack/postcss-loader/main/src/config.d.ts).",
"See the file [`https://github.com/webpack/postcss-loader/blob/main/src/config.d.ts`](https://github.com/webpack/postcss-loader/blob/main/src/config.d.ts).",
);
});

Expand Down
Loading