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

Handle undefined/null urls in fix-links.mjs. #1464

Merged
merged 2 commits into from
Jun 22, 2022
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
35 changes: 26 additions & 9 deletions src/build/fix-links.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { unified } from "unified";
import rehypeParse from "rehype-parse";
import { visit } from "unist-util-visit";
import urlParse from "url-parse";
import { rmPrefix, rmSuffix, matchesPrefixes } from "../lib/utils.js";
import { repr, trunc, rmPrefix, rmSuffix, matchesPrefixes } from "../lib/utils.js";

// `verbose: true` makes the parser include position information for each property of each element.
// This is required for `editProperty()` to work.
Expand All @@ -20,7 +20,7 @@ let debug = false;
// Check if that happens in the codebase.
const PREFIX_WHITELIST = ["http://", "https://", "mailto:", "/images/", "//", "#"];
const LINK_PROPS = { img: "src", a: "href" };
const LINK_FIXERS = { img: fixImageLink, a: fixHyperLink };
const LINK_FIXERS = { image: fixImageLink, img: fixImageLink, link: fixHyperLink, a: fixHyperLink };

/**
* The unified plugin to transform links in parsed Markdown trees.
Expand Down Expand Up @@ -48,13 +48,24 @@ export default function attacher(options) {
} else {
console.error("No `bases` option received. Will not be able to convert image src paths to relative paths.");
}
visit(tree, "link", (node) => {
node.url = fixHyperLink(node.url);
});
visit(tree, "image", (node) => {
node.url = fixImageLink(node.url, dirPath);
});
visit(tree, "html", (node) => fixHtmlLinks(node, dirPath));
// Fix the urls in the 3 types of nodes we're targeting.
for (let nodeType of ["link", "image", "html"]) {
visit(tree, nodeType, (node) => {
try {
if (nodeType === "link" || nodeType === "image") {
node.url = LINK_FIXERS[nodeType](node.url, dirPath);
} else if (nodeType === "html") {
fixHtmlLinks(node, dirPath);
}
} catch (error) {
console.error(error);
console.error(
`Error fixing url in Markdown ${nodeType} in ${file.path}:\n`,
trunc(repr(node), 200)
);
}
});
}
}
return transformer;
}
Expand Down Expand Up @@ -152,6 +163,9 @@ function getElementsByTagNames(elem, tagNames) {

/** Perform all the editing appropriate for a hyperlink url (whether in HTML or Markdown). */
export function fixHyperLink(rawUrl) {
if (typeof rawUrl !== "string") {
throw repr`Error: rawUrl must be a String. Received: ${rawUrl}`;
}
// Skip certain types of links like external (https?://), static (/images/), intrapage (#).
if (matchesPrefixes(rawUrl, PREFIX_WHITELIST)) {
return rawUrl;
Expand Down Expand Up @@ -184,6 +198,9 @@ export function fixHyperLink(rawUrl) {
* events/gcc2013.
*/
export function fixImageLink(rawPath, dirPath = null) {
if (typeof rawPath !== "string") {
throw repr`Error: rawPath must be a String. Received: ${rawPath}`;
}
let path = rmPrefix(rawPath, "/src");
if (dirPath) {
path = toRelImagePath(dirPath, path, PREFIX_WHITELIST);
Expand Down
11 changes: 11 additions & 0 deletions src/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ function repr(strParts, ...values) {
}
module.exports.repr = repr;

/** Truncate long strings with an ellipsis, and leave alone strings that are already short enough.
*/
function trunc(str, maxLen, endChar = "…") {
if (str.length > maxLen) {
return str.slice(0, maxLen) + endChar;
} else {
return str;
}
}
module.exports.trunc = trunc;

function splitlines(text) {
return text.split(/\r\n|\r|\n/);
}
Expand Down