mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-28 09:47:48 +02:00
feat(mdx-loader): upgrade to MDX v3 + (#9451)
This commit is contained in:
parent
8d19054d91
commit
7e456ece3c
49 changed files with 37351 additions and 30469 deletions
20
jest.config.mjs
vendored
20
jest.config.mjs
vendored
|
@ -86,16 +86,20 @@ export default {
|
|||
// MDX packages are ESM-only and it is a pain to use in Jest
|
||||
// So we use them in Jest tests as CJS versions
|
||||
// see https://mdxjs.com/docs/troubleshooting-mdx/#problems-integrating-mdx
|
||||
'^unified$': '<rootDir>/jest/vendor/unified@10.1.2.js',
|
||||
'^@mdx-js/mdx$': '<rootDir>/jest/vendor/@mdx-js__mdx@2.1.5.js',
|
||||
'^remark$': '<rootDir>/jest/vendor/remark@14.0.2.js',
|
||||
'^remark-mdx$': '<rootDir>/jest/vendor/remark-mdx@2.1.5.js',
|
||||
'^remark-directive$': '<rootDir>/jest/vendor/remark-directive@2.0.1.js',
|
||||
'^remark-gfm$': '<rootDir>/jest/vendor/remark-gfm@3.0.1.js',
|
||||
'^@mdx-js/mdx$': '<rootDir>/jest/vendor/@mdx-js__mdx@3.0.0.js',
|
||||
'^remark$': '<rootDir>/jest/vendor/remark@15.0.1.js',
|
||||
'^remark-rehype$': '<rootDir>/jest/vendor/remark-rehype@11.0.0.js',
|
||||
'^remark-mdx$': '<rootDir>/jest/vendor/remark-mdx@3.0.0.js',
|
||||
'^remark-directive$': '<rootDir>/jest/vendor/remark-directive@3.0.0.js',
|
||||
'^remark-gfm$': '<rootDir>/jest/vendor/remark-gfm@4.0.0.js',
|
||||
'^estree-util-value-to-estree$':
|
||||
'<rootDir>/jest/vendor/estree-util-value-to-estree@2.1.0.js',
|
||||
'<rootDir>/jest/vendor/estree-util-value-to-estree@3.0.1.js',
|
||||
'^mdast-util-to-string$':
|
||||
'<rootDir>/jest/vendor/mdast-util-to-string@3.1.0.js',
|
||||
'<rootDir>/jest/vendor/mdast-util-to-string@4.0.0.js',
|
||||
'^unist-util-visit$': '<rootDir>/jest/vendor/unist-util-visit@5.0.0.js',
|
||||
'^unist-util-remove-position$':
|
||||
'<rootDir>/jest/vendor/unist-util-remove-position@5.0.0.js',
|
||||
'^rehype-stringify$': '<rootDir>/jest/vendor/rehype-stringify@10.0.0.js',
|
||||
},
|
||||
snapshotSerializers: [
|
||||
'<rootDir>/jest/snapshotPathNormalizer.ts',
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -23,7 +23,7 @@ __export(estree_util_value_to_estree_exports, {
|
|||
});
|
||||
module.exports = __toCommonJS(estree_util_value_to_estree_exports);
|
||||
|
||||
// node_modules/estree-util-value-to-estree/node_modules/is-plain-obj/index.js
|
||||
// node_modules/is-plain-obj/index.js
|
||||
function isPlainObject(value) {
|
||||
if (typeof value !== "object" || value === null) {
|
||||
return false;
|
||||
|
@ -49,7 +49,7 @@ function valueToEstree(value, options = {}) {
|
|||
};
|
||||
}
|
||||
if (typeof value === "number") {
|
||||
return value >= 0 ? { type: "Literal", value } : {
|
||||
return value >= 0 && !Object.is(value, -0) ? { type: "Literal", value } : {
|
||||
type: "UnaryExpression",
|
||||
operator: "-",
|
||||
prefix: true,
|
||||
|
@ -130,9 +130,7 @@ function valueToEstree(value, options = {}) {
|
|||
};
|
||||
}
|
||||
if (options.instanceAsObject || isPlainObject(value)) {
|
||||
return {
|
||||
type: "ObjectExpression",
|
||||
properties: Reflect.ownKeys(value).map((key) => ({
|
||||
const properties = Reflect.ownKeys(value).map((key) => ({
|
||||
type: "Property",
|
||||
method: false,
|
||||
shorthand: false,
|
||||
|
@ -140,7 +138,21 @@ function valueToEstree(value, options = {}) {
|
|||
kind: "init",
|
||||
key: valueToEstree(key, options),
|
||||
value: valueToEstree(value[key], options)
|
||||
}))
|
||||
}));
|
||||
if (Object.getPrototypeOf(value) == null) {
|
||||
properties.unshift({
|
||||
type: "Property",
|
||||
method: false,
|
||||
shorthand: false,
|
||||
computed: false,
|
||||
kind: "init",
|
||||
key: { type: "Identifier", name: "__proto__" },
|
||||
value: { type: "Literal", value: null }
|
||||
});
|
||||
}
|
||||
return {
|
||||
type: "ObjectExpression",
|
||||
properties
|
||||
};
|
||||
}
|
||||
throw new TypeError(`Unsupported value: ${String(value)}`);
|
|
@ -22,21 +22,43 @@ __export(mdast_util_to_string_exports, {
|
|||
toString: () => toString
|
||||
});
|
||||
module.exports = __toCommonJS(mdast_util_to_string_exports);
|
||||
function toString(node, options) {
|
||||
var { includeImageAlt = true } = options || {};
|
||||
return one(node, includeImageAlt);
|
||||
|
||||
// node_modules/mdast-util-to-string/lib/index.js
|
||||
var emptyOptions = {};
|
||||
function toString(value, options) {
|
||||
const settings = options || emptyOptions;
|
||||
const includeImageAlt = typeof settings.includeImageAlt === "boolean" ? settings.includeImageAlt : true;
|
||||
const includeHtml = typeof settings.includeHtml === "boolean" ? settings.includeHtml : true;
|
||||
return one(value, includeImageAlt, includeHtml);
|
||||
}
|
||||
function one(node, includeImageAlt) {
|
||||
return node && typeof node === "object" && (node.value || (includeImageAlt ? node.alt : "") || "children" in node && all(node.children, includeImageAlt) || Array.isArray(node) && all(node, includeImageAlt)) || "";
|
||||
function one(value, includeImageAlt, includeHtml) {
|
||||
if (node(value)) {
|
||||
if ("value" in value) {
|
||||
return value.type === "html" && !includeHtml ? "" : value.value;
|
||||
}
|
||||
if (includeImageAlt && "alt" in value && value.alt) {
|
||||
return value.alt;
|
||||
}
|
||||
if ("children" in value) {
|
||||
return all(value.children, includeImageAlt, includeHtml);
|
||||
}
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return all(value, includeImageAlt, includeHtml);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
function all(values, includeImageAlt) {
|
||||
var result = [];
|
||||
var index = -1;
|
||||
function all(values, includeImageAlt, includeHtml) {
|
||||
const result = [];
|
||||
let index = -1;
|
||||
while (++index < values.length) {
|
||||
result[index] = one(values[index], includeImageAlt);
|
||||
result[index] = one(values[index], includeImageAlt, includeHtml);
|
||||
}
|
||||
return result.join("");
|
||||
}
|
||||
function node(value) {
|
||||
return Boolean(value && typeof value === "object");
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
toString
|
2202
jest/vendor/rehype-stringify@10.0.0.js
vendored
Normal file
2202
jest/vendor/rehype-stringify@10.0.0.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
4907
jest/vendor/remark-gfm@3.0.1.js
vendored
4907
jest/vendor/remark-gfm@3.0.1.js
vendored
File diff suppressed because it is too large
Load diff
3457
jest/vendor/remark-gfm@4.0.0.js
vendored
Normal file
3457
jest/vendor/remark-gfm@4.0.0.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1334
jest/vendor/remark-rehype@11.0.0.js
vendored
Normal file
1334
jest/vendor/remark-rehype@11.0.0.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
779
jest/vendor/unified@10.1.2.js
vendored
779
jest/vendor/unified@10.1.2.js
vendored
|
@ -1,779 +0,0 @@
|
|||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __commonJS = (cb, mod) => function __require() {
|
||||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
||||
};
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// node_modules/is-buffer/index.js
|
||||
var require_is_buffer = __commonJS({
|
||||
"node_modules/is-buffer/index.js"(exports, module2) {
|
||||
module2.exports = function isBuffer2(obj) {
|
||||
return obj != null && obj.constructor != null && typeof obj.constructor.isBuffer === "function" && obj.constructor.isBuffer(obj);
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// node_modules/extend/index.js
|
||||
var require_extend = __commonJS({
|
||||
"node_modules/extend/index.js"(exports, module2) {
|
||||
"use strict";
|
||||
var hasOwn = Object.prototype.hasOwnProperty;
|
||||
var toStr = Object.prototype.toString;
|
||||
var defineProperty = Object.defineProperty;
|
||||
var gOPD = Object.getOwnPropertyDescriptor;
|
||||
var isArray = function isArray2(arr) {
|
||||
if (typeof Array.isArray === "function") {
|
||||
return Array.isArray(arr);
|
||||
}
|
||||
return toStr.call(arr) === "[object Array]";
|
||||
};
|
||||
var isPlainObject2 = function isPlainObject3(obj) {
|
||||
if (!obj || toStr.call(obj) !== "[object Object]") {
|
||||
return false;
|
||||
}
|
||||
var hasOwnConstructor = hasOwn.call(obj, "constructor");
|
||||
var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, "isPrototypeOf");
|
||||
if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
|
||||
return false;
|
||||
}
|
||||
var key;
|
||||
for (key in obj) {
|
||||
}
|
||||
return typeof key === "undefined" || hasOwn.call(obj, key);
|
||||
};
|
||||
var setProperty = function setProperty2(target, options) {
|
||||
if (defineProperty && options.name === "__proto__") {
|
||||
defineProperty(target, options.name, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: options.newValue,
|
||||
writable: true
|
||||
});
|
||||
} else {
|
||||
target[options.name] = options.newValue;
|
||||
}
|
||||
};
|
||||
var getProperty = function getProperty2(obj, name) {
|
||||
if (name === "__proto__") {
|
||||
if (!hasOwn.call(obj, name)) {
|
||||
return void 0;
|
||||
} else if (gOPD) {
|
||||
return gOPD(obj, name).value;
|
||||
}
|
||||
}
|
||||
return obj[name];
|
||||
};
|
||||
module2.exports = function extend2() {
|
||||
var options, name, src, copy, copyIsArray, clone;
|
||||
var target = arguments[0];
|
||||
var i = 1;
|
||||
var length = arguments.length;
|
||||
var deep = false;
|
||||
if (typeof target === "boolean") {
|
||||
deep = target;
|
||||
target = arguments[1] || {};
|
||||
i = 2;
|
||||
}
|
||||
if (target == null || typeof target !== "object" && typeof target !== "function") {
|
||||
target = {};
|
||||
}
|
||||
for (; i < length; ++i) {
|
||||
options = arguments[i];
|
||||
if (options != null) {
|
||||
for (name in options) {
|
||||
src = getProperty(target, name);
|
||||
copy = getProperty(options, name);
|
||||
if (target !== copy) {
|
||||
if (deep && copy && (isPlainObject2(copy) || (copyIsArray = isArray(copy)))) {
|
||||
if (copyIsArray) {
|
||||
copyIsArray = false;
|
||||
clone = src && isArray(src) ? src : [];
|
||||
} else {
|
||||
clone = src && isPlainObject2(src) ? src : {};
|
||||
}
|
||||
setProperty(target, { name, newValue: extend2(deep, clone, copy) });
|
||||
} else if (typeof copy !== "undefined") {
|
||||
setProperty(target, { name, newValue: copy });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// node_modules/unified/index.js
|
||||
var unified_exports = {};
|
||||
__export(unified_exports, {
|
||||
unified: () => unified1012
|
||||
});
|
||||
module.exports = __toCommonJS(unified_exports);
|
||||
|
||||
// node_modules/bail/index.js
|
||||
function bail(error) {
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/unified/lib/index.js
|
||||
var import_is_buffer2 = __toESM(require_is_buffer(), 1);
|
||||
var import_extend = __toESM(require_extend(), 1);
|
||||
|
||||
// node_modules/unified/node_modules/is-plain-obj/index.js
|
||||
function isPlainObject(value) {
|
||||
if (typeof value !== "object" || value === null) {
|
||||
return false;
|
||||
}
|
||||
const prototype = Object.getPrototypeOf(value);
|
||||
return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in value) && !(Symbol.iterator in value);
|
||||
}
|
||||
|
||||
// node_modules/trough/index.js
|
||||
function trough() {
|
||||
const fns = [];
|
||||
const pipeline = { run, use };
|
||||
return pipeline;
|
||||
function run(...values) {
|
||||
let middlewareIndex = -1;
|
||||
const callback = values.pop();
|
||||
if (typeof callback !== "function") {
|
||||
throw new TypeError("Expected function as last argument, not " + callback);
|
||||
}
|
||||
next(null, ...values);
|
||||
function next(error, ...output) {
|
||||
const fn = fns[++middlewareIndex];
|
||||
let index2 = -1;
|
||||
if (error) {
|
||||
callback(error);
|
||||
return;
|
||||
}
|
||||
while (++index2 < values.length) {
|
||||
if (output[index2] === null || output[index2] === void 0) {
|
||||
output[index2] = values[index2];
|
||||
}
|
||||
}
|
||||
values = output;
|
||||
if (fn) {
|
||||
wrap(fn, next)(...output);
|
||||
} else {
|
||||
callback(null, ...output);
|
||||
}
|
||||
}
|
||||
}
|
||||
function use(middelware) {
|
||||
if (typeof middelware !== "function") {
|
||||
throw new TypeError(
|
||||
"Expected `middelware` to be a function, not " + middelware
|
||||
);
|
||||
}
|
||||
fns.push(middelware);
|
||||
return pipeline;
|
||||
}
|
||||
}
|
||||
function wrap(middleware, callback) {
|
||||
let called;
|
||||
return wrapped;
|
||||
function wrapped(...parameters) {
|
||||
const fnExpectsCallback = middleware.length > parameters.length;
|
||||
let result;
|
||||
if (fnExpectsCallback) {
|
||||
parameters.push(done);
|
||||
}
|
||||
try {
|
||||
result = middleware.apply(this, parameters);
|
||||
} catch (error) {
|
||||
const exception = error;
|
||||
if (fnExpectsCallback && called) {
|
||||
throw exception;
|
||||
}
|
||||
return done(exception);
|
||||
}
|
||||
if (!fnExpectsCallback) {
|
||||
if (result instanceof Promise) {
|
||||
result.then(then, done);
|
||||
} else if (result instanceof Error) {
|
||||
done(result);
|
||||
} else {
|
||||
then(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
function done(error, ...output) {
|
||||
if (!called) {
|
||||
called = true;
|
||||
callback(error, ...output);
|
||||
}
|
||||
}
|
||||
function then(value) {
|
||||
done(null, value);
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/vfile/lib/index.js
|
||||
var import_is_buffer = __toESM(require_is_buffer(), 1);
|
||||
|
||||
// node_modules/unist-util-stringify-position/index.js
|
||||
function stringifyPosition(value) {
|
||||
if (!value || typeof value !== "object") {
|
||||
return "";
|
||||
}
|
||||
if ("position" in value || "type" in value) {
|
||||
return position(value.position);
|
||||
}
|
||||
if ("start" in value || "end" in value) {
|
||||
return position(value);
|
||||
}
|
||||
if ("line" in value || "column" in value) {
|
||||
return point(value);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
function point(point2) {
|
||||
return index(point2 && point2.line) + ":" + index(point2 && point2.column);
|
||||
}
|
||||
function position(pos) {
|
||||
return point(pos && pos.start) + "-" + point(pos && pos.end);
|
||||
}
|
||||
function index(value) {
|
||||
return value && typeof value === "number" ? value : 1;
|
||||
}
|
||||
|
||||
// node_modules/vfile-message/index.js
|
||||
var VFileMessage = class extends Error {
|
||||
constructor(reason, place, origin) {
|
||||
const parts = [null, null];
|
||||
let position2 = {
|
||||
start: { line: null, column: null },
|
||||
end: { line: null, column: null }
|
||||
};
|
||||
super();
|
||||
if (typeof place === "string") {
|
||||
origin = place;
|
||||
place = void 0;
|
||||
}
|
||||
if (typeof origin === "string") {
|
||||
const index2 = origin.indexOf(":");
|
||||
if (index2 === -1) {
|
||||
parts[1] = origin;
|
||||
} else {
|
||||
parts[0] = origin.slice(0, index2);
|
||||
parts[1] = origin.slice(index2 + 1);
|
||||
}
|
||||
}
|
||||
if (place) {
|
||||
if ("type" in place || "position" in place) {
|
||||
if (place.position) {
|
||||
position2 = place.position;
|
||||
}
|
||||
} else if ("start" in place || "end" in place) {
|
||||
position2 = place;
|
||||
} else if ("line" in place || "column" in place) {
|
||||
position2.start = place;
|
||||
}
|
||||
}
|
||||
this.name = stringifyPosition(place) || "1:1";
|
||||
this.message = typeof reason === "object" ? reason.message : reason;
|
||||
this.stack = "";
|
||||
if (typeof reason === "object" && reason.stack) {
|
||||
this.stack = reason.stack;
|
||||
}
|
||||
this.reason = this.message;
|
||||
this.fatal;
|
||||
this.line = position2.start.line;
|
||||
this.column = position2.start.column;
|
||||
this.position = position2;
|
||||
this.source = parts[0];
|
||||
this.ruleId = parts[1];
|
||||
this.file;
|
||||
this.actual;
|
||||
this.expected;
|
||||
this.url;
|
||||
this.note;
|
||||
}
|
||||
};
|
||||
VFileMessage.prototype.file = "";
|
||||
VFileMessage.prototype.name = "";
|
||||
VFileMessage.prototype.reason = "";
|
||||
VFileMessage.prototype.message = "";
|
||||
VFileMessage.prototype.stack = "";
|
||||
VFileMessage.prototype.fatal = null;
|
||||
VFileMessage.prototype.column = null;
|
||||
VFileMessage.prototype.line = null;
|
||||
VFileMessage.prototype.source = null;
|
||||
VFileMessage.prototype.ruleId = null;
|
||||
VFileMessage.prototype.position = null;
|
||||
|
||||
// node_modules/vfile/lib/minpath.js
|
||||
var import_path = __toESM(require("path"), 1);
|
||||
|
||||
// node_modules/vfile/lib/minproc.js
|
||||
var import_process = __toESM(require("process"), 1);
|
||||
|
||||
// node_modules/vfile/lib/minurl.js
|
||||
var import_url = require("url");
|
||||
|
||||
// node_modules/vfile/lib/minurl.shared.js
|
||||
function isUrl(fileURLOrPath) {
|
||||
return fileURLOrPath !== null && typeof fileURLOrPath === "object" && fileURLOrPath.href && fileURLOrPath.origin;
|
||||
}
|
||||
|
||||
// node_modules/vfile/lib/index.js
|
||||
var order = ["history", "path", "basename", "stem", "extname", "dirname"];
|
||||
var VFile = class {
|
||||
constructor(value) {
|
||||
let options;
|
||||
if (!value) {
|
||||
options = {};
|
||||
} else if (typeof value === "string" || (0, import_is_buffer.default)(value)) {
|
||||
options = { value };
|
||||
} else if (isUrl(value)) {
|
||||
options = { path: value };
|
||||
} else {
|
||||
options = value;
|
||||
}
|
||||
this.data = {};
|
||||
this.messages = [];
|
||||
this.history = [];
|
||||
this.cwd = import_process.default.cwd();
|
||||
this.value;
|
||||
this.stored;
|
||||
this.result;
|
||||
this.map;
|
||||
let index2 = -1;
|
||||
while (++index2 < order.length) {
|
||||
const prop2 = order[index2];
|
||||
if (prop2 in options && options[prop2] !== void 0) {
|
||||
this[prop2] = prop2 === "history" ? [...options[prop2]] : options[prop2];
|
||||
}
|
||||
}
|
||||
let prop;
|
||||
for (prop in options) {
|
||||
if (!order.includes(prop))
|
||||
this[prop] = options[prop];
|
||||
}
|
||||
}
|
||||
get path() {
|
||||
return this.history[this.history.length - 1];
|
||||
}
|
||||
set path(path) {
|
||||
if (isUrl(path)) {
|
||||
path = (0, import_url.fileURLToPath)(path);
|
||||
}
|
||||
assertNonEmpty(path, "path");
|
||||
if (this.path !== path) {
|
||||
this.history.push(path);
|
||||
}
|
||||
}
|
||||
get dirname() {
|
||||
return typeof this.path === "string" ? import_path.default.dirname(this.path) : void 0;
|
||||
}
|
||||
set dirname(dirname) {
|
||||
assertPath(this.basename, "dirname");
|
||||
this.path = import_path.default.join(dirname || "", this.basename);
|
||||
}
|
||||
get basename() {
|
||||
return typeof this.path === "string" ? import_path.default.basename(this.path) : void 0;
|
||||
}
|
||||
set basename(basename) {
|
||||
assertNonEmpty(basename, "basename");
|
||||
assertPart(basename, "basename");
|
||||
this.path = import_path.default.join(this.dirname || "", basename);
|
||||
}
|
||||
get extname() {
|
||||
return typeof this.path === "string" ? import_path.default.extname(this.path) : void 0;
|
||||
}
|
||||
set extname(extname) {
|
||||
assertPart(extname, "extname");
|
||||
assertPath(this.dirname, "extname");
|
||||
if (extname) {
|
||||
if (extname.charCodeAt(0) !== 46) {
|
||||
throw new Error("`extname` must start with `.`");
|
||||
}
|
||||
if (extname.includes(".", 1)) {
|
||||
throw new Error("`extname` cannot contain multiple dots");
|
||||
}
|
||||
}
|
||||
this.path = import_path.default.join(this.dirname, this.stem + (extname || ""));
|
||||
}
|
||||
get stem() {
|
||||
return typeof this.path === "string" ? import_path.default.basename(this.path, this.extname) : void 0;
|
||||
}
|
||||
set stem(stem) {
|
||||
assertNonEmpty(stem, "stem");
|
||||
assertPart(stem, "stem");
|
||||
this.path = import_path.default.join(this.dirname || "", stem + (this.extname || ""));
|
||||
}
|
||||
toString(encoding) {
|
||||
return (this.value || "").toString(encoding);
|
||||
}
|
||||
message(reason, place, origin) {
|
||||
const message = new VFileMessage(reason, place, origin);
|
||||
if (this.path) {
|
||||
message.name = this.path + ":" + message.name;
|
||||
message.file = this.path;
|
||||
}
|
||||
message.fatal = false;
|
||||
this.messages.push(message);
|
||||
return message;
|
||||
}
|
||||
info(reason, place, origin) {
|
||||
const message = this.message(reason, place, origin);
|
||||
message.fatal = null;
|
||||
return message;
|
||||
}
|
||||
fail(reason, place, origin) {
|
||||
const message = this.message(reason, place, origin);
|
||||
message.fatal = true;
|
||||
throw message;
|
||||
}
|
||||
};
|
||||
function assertPart(part, name) {
|
||||
if (part && part.includes(import_path.default.sep)) {
|
||||
throw new Error(
|
||||
"`" + name + "` cannot be a path: did not expect `" + import_path.default.sep + "`"
|
||||
);
|
||||
}
|
||||
}
|
||||
function assertNonEmpty(part, name) {
|
||||
if (!part) {
|
||||
throw new Error("`" + name + "` cannot be empty");
|
||||
}
|
||||
}
|
||||
function assertPath(path, name) {
|
||||
if (!path) {
|
||||
throw new Error("Setting `" + name + "` requires `path` to be set too");
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/unified/lib/index.js
|
||||
var unified1012 = base().freeze();
|
||||
var own = {}.hasOwnProperty;
|
||||
function base() {
|
||||
const transformers = trough();
|
||||
const attachers = [];
|
||||
let namespace = {};
|
||||
let frozen;
|
||||
let freezeIndex = -1;
|
||||
processor.data = data;
|
||||
processor.Parser = void 0;
|
||||
processor.Compiler = void 0;
|
||||
processor.freeze = freeze;
|
||||
processor.attachers = attachers;
|
||||
processor.use = use;
|
||||
processor.parse = parse;
|
||||
processor.stringify = stringify;
|
||||
processor.run = run;
|
||||
processor.runSync = runSync;
|
||||
processor.process = process;
|
||||
processor.processSync = processSync;
|
||||
return processor;
|
||||
function processor() {
|
||||
const destination = base();
|
||||
let index2 = -1;
|
||||
while (++index2 < attachers.length) {
|
||||
destination.use(...attachers[index2]);
|
||||
}
|
||||
destination.data((0, import_extend.default)(true, {}, namespace));
|
||||
return destination;
|
||||
}
|
||||
function data(key, value) {
|
||||
if (typeof key === "string") {
|
||||
if (arguments.length === 2) {
|
||||
assertUnfrozen("data", frozen);
|
||||
namespace[key] = value;
|
||||
return processor;
|
||||
}
|
||||
return own.call(namespace, key) && namespace[key] || null;
|
||||
}
|
||||
if (key) {
|
||||
assertUnfrozen("data", frozen);
|
||||
namespace = key;
|
||||
return processor;
|
||||
}
|
||||
return namespace;
|
||||
}
|
||||
function freeze() {
|
||||
if (frozen) {
|
||||
return processor;
|
||||
}
|
||||
while (++freezeIndex < attachers.length) {
|
||||
const [attacher, ...options] = attachers[freezeIndex];
|
||||
if (options[0] === false) {
|
||||
continue;
|
||||
}
|
||||
if (options[0] === true) {
|
||||
options[0] = void 0;
|
||||
}
|
||||
const transformer = attacher.call(processor, ...options);
|
||||
if (typeof transformer === "function") {
|
||||
transformers.use(transformer);
|
||||
}
|
||||
}
|
||||
frozen = true;
|
||||
freezeIndex = Number.POSITIVE_INFINITY;
|
||||
return processor;
|
||||
}
|
||||
function use(value, ...options) {
|
||||
let settings;
|
||||
assertUnfrozen("use", frozen);
|
||||
if (value === null || value === void 0) {
|
||||
} else if (typeof value === "function") {
|
||||
addPlugin(value, ...options);
|
||||
} else if (typeof value === "object") {
|
||||
if (Array.isArray(value)) {
|
||||
addList(value);
|
||||
} else {
|
||||
addPreset(value);
|
||||
}
|
||||
} else {
|
||||
throw new TypeError("Expected usable value, not `" + value + "`");
|
||||
}
|
||||
if (settings) {
|
||||
namespace.settings = Object.assign(namespace.settings || {}, settings);
|
||||
}
|
||||
return processor;
|
||||
function add(value2) {
|
||||
if (typeof value2 === "function") {
|
||||
addPlugin(value2);
|
||||
} else if (typeof value2 === "object") {
|
||||
if (Array.isArray(value2)) {
|
||||
const [plugin, ...options2] = value2;
|
||||
addPlugin(plugin, ...options2);
|
||||
} else {
|
||||
addPreset(value2);
|
||||
}
|
||||
} else {
|
||||
throw new TypeError("Expected usable value, not `" + value2 + "`");
|
||||
}
|
||||
}
|
||||
function addPreset(result) {
|
||||
addList(result.plugins);
|
||||
if (result.settings) {
|
||||
settings = Object.assign(settings || {}, result.settings);
|
||||
}
|
||||
}
|
||||
function addList(plugins) {
|
||||
let index2 = -1;
|
||||
if (plugins === null || plugins === void 0) {
|
||||
} else if (Array.isArray(plugins)) {
|
||||
while (++index2 < plugins.length) {
|
||||
const thing = plugins[index2];
|
||||
add(thing);
|
||||
}
|
||||
} else {
|
||||
throw new TypeError("Expected a list of plugins, not `" + plugins + "`");
|
||||
}
|
||||
}
|
||||
function addPlugin(plugin, value2) {
|
||||
let index2 = -1;
|
||||
let entry;
|
||||
while (++index2 < attachers.length) {
|
||||
if (attachers[index2][0] === plugin) {
|
||||
entry = attachers[index2];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry) {
|
||||
if (isPlainObject(entry[1]) && isPlainObject(value2)) {
|
||||
value2 = (0, import_extend.default)(true, entry[1], value2);
|
||||
}
|
||||
entry[1] = value2;
|
||||
} else {
|
||||
attachers.push([...arguments]);
|
||||
}
|
||||
}
|
||||
}
|
||||
function parse(doc) {
|
||||
processor.freeze();
|
||||
const file = vfile(doc);
|
||||
const Parser = processor.Parser;
|
||||
assertParser("parse", Parser);
|
||||
if (newable(Parser, "parse")) {
|
||||
return new Parser(String(file), file).parse();
|
||||
}
|
||||
return Parser(String(file), file);
|
||||
}
|
||||
function stringify(node, doc) {
|
||||
processor.freeze();
|
||||
const file = vfile(doc);
|
||||
const Compiler = processor.Compiler;
|
||||
assertCompiler("stringify", Compiler);
|
||||
assertNode(node);
|
||||
if (newable(Compiler, "compile")) {
|
||||
return new Compiler(node, file).compile();
|
||||
}
|
||||
return Compiler(node, file);
|
||||
}
|
||||
function run(node, doc, callback) {
|
||||
assertNode(node);
|
||||
processor.freeze();
|
||||
if (!callback && typeof doc === "function") {
|
||||
callback = doc;
|
||||
doc = void 0;
|
||||
}
|
||||
if (!callback) {
|
||||
return new Promise(executor);
|
||||
}
|
||||
executor(null, callback);
|
||||
function executor(resolve, reject) {
|
||||
transformers.run(node, vfile(doc), done);
|
||||
function done(error, tree, file) {
|
||||
tree = tree || node;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else if (resolve) {
|
||||
resolve(tree);
|
||||
} else {
|
||||
callback(null, tree, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function runSync(node, file) {
|
||||
let result;
|
||||
let complete;
|
||||
processor.run(node, file, done);
|
||||
assertDone("runSync", "run", complete);
|
||||
return result;
|
||||
function done(error, tree) {
|
||||
bail(error);
|
||||
result = tree;
|
||||
complete = true;
|
||||
}
|
||||
}
|
||||
function process(doc, callback) {
|
||||
processor.freeze();
|
||||
assertParser("process", processor.Parser);
|
||||
assertCompiler("process", processor.Compiler);
|
||||
if (!callback) {
|
||||
return new Promise(executor);
|
||||
}
|
||||
executor(null, callback);
|
||||
function executor(resolve, reject) {
|
||||
const file = vfile(doc);
|
||||
processor.run(processor.parse(file), file, (error, tree, file2) => {
|
||||
if (error || !tree || !file2) {
|
||||
done(error);
|
||||
} else {
|
||||
const result = processor.stringify(tree, file2);
|
||||
if (result === void 0 || result === null) {
|
||||
} else if (looksLikeAVFileValue(result)) {
|
||||
file2.value = result;
|
||||
} else {
|
||||
file2.result = result;
|
||||
}
|
||||
done(error, file2);
|
||||
}
|
||||
});
|
||||
function done(error, file2) {
|
||||
if (error || !file2) {
|
||||
reject(error);
|
||||
} else if (resolve) {
|
||||
resolve(file2);
|
||||
} else {
|
||||
callback(null, file2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function processSync(doc) {
|
||||
let complete;
|
||||
processor.freeze();
|
||||
assertParser("processSync", processor.Parser);
|
||||
assertCompiler("processSync", processor.Compiler);
|
||||
const file = vfile(doc);
|
||||
processor.process(file, done);
|
||||
assertDone("processSync", "process", complete);
|
||||
return file;
|
||||
function done(error) {
|
||||
complete = true;
|
||||
bail(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
function newable(value, name) {
|
||||
return typeof value === "function" && value.prototype && (keys(value.prototype) || name in value.prototype);
|
||||
}
|
||||
function keys(value) {
|
||||
let key;
|
||||
for (key in value) {
|
||||
if (own.call(value, key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function assertParser(name, value) {
|
||||
if (typeof value !== "function") {
|
||||
throw new TypeError("Cannot `" + name + "` without `Parser`");
|
||||
}
|
||||
}
|
||||
function assertCompiler(name, value) {
|
||||
if (typeof value !== "function") {
|
||||
throw new TypeError("Cannot `" + name + "` without `Compiler`");
|
||||
}
|
||||
}
|
||||
function assertUnfrozen(name, frozen) {
|
||||
if (frozen) {
|
||||
throw new Error(
|
||||
"Cannot call `" + name + "` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`."
|
||||
);
|
||||
}
|
||||
}
|
||||
function assertNode(node) {
|
||||
if (!isPlainObject(node) || typeof node.type !== "string") {
|
||||
throw new TypeError("Expected node, got `" + node + "`");
|
||||
}
|
||||
}
|
||||
function assertDone(name, asyncName, complete) {
|
||||
if (!complete) {
|
||||
throw new Error(
|
||||
"`" + name + "` finished async. Use `" + asyncName + "` instead"
|
||||
);
|
||||
}
|
||||
}
|
||||
function vfile(value) {
|
||||
return looksLikeAVFile(value) ? value : new VFile(value);
|
||||
}
|
||||
function looksLikeAVFile(value) {
|
||||
return Boolean(
|
||||
value && typeof value === "object" && "message" in value && "messages" in value
|
||||
);
|
||||
}
|
||||
function looksLikeAVFileValue(value) {
|
||||
return typeof value === "string" || (0, import_is_buffer2.default)(value);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
unified: unified1012
|
||||
});
|
||||
/*!
|
||||
* Determine if an object is a Buffer
|
||||
*
|
||||
* @author Feross Aboukhadijeh <https://feross.org>
|
||||
* @license MIT
|
||||
*/
|
240
jest/vendor/unist-util-remove-position@5.0.0.js
vendored
Normal file
240
jest/vendor/unist-util-remove-position@5.0.0.js
vendored
Normal file
|
@ -0,0 +1,240 @@
|
|||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// node_modules/unist-util-remove-position/index.js
|
||||
var unist_util_remove_position_exports = {};
|
||||
__export(unist_util_remove_position_exports, {
|
||||
removePosition: () => removePosition
|
||||
});
|
||||
module.exports = __toCommonJS(unist_util_remove_position_exports);
|
||||
|
||||
// node_modules/unist-util-is/lib/index.js
|
||||
var convert = (
|
||||
// Note: overloads in JSDoc can’t yet use different `@template`s.
|
||||
/**
|
||||
* @type {(
|
||||
* (<Condition extends string>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & {type: Condition}) &
|
||||
* (<Condition extends Props>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Condition) &
|
||||
* (<Condition extends TestFunction>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Predicate<Condition, Node>) &
|
||||
* ((test?: null | undefined) => (node?: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node) &
|
||||
* ((test?: Test) => Check)
|
||||
* )}
|
||||
*/
|
||||
/**
|
||||
* @param {Test} [test]
|
||||
* @returns {Check}
|
||||
*/
|
||||
function(test) {
|
||||
if (test === null || test === void 0) {
|
||||
return ok;
|
||||
}
|
||||
if (typeof test === "function") {
|
||||
return castFactory(test);
|
||||
}
|
||||
if (typeof test === "object") {
|
||||
return Array.isArray(test) ? anyFactory(test) : propsFactory(test);
|
||||
}
|
||||
if (typeof test === "string") {
|
||||
return typeFactory(test);
|
||||
}
|
||||
throw new Error("Expected function, string, or object as test");
|
||||
}
|
||||
);
|
||||
function anyFactory(tests) {
|
||||
const checks = [];
|
||||
let index = -1;
|
||||
while (++index < tests.length) {
|
||||
checks[index] = convert(tests[index]);
|
||||
}
|
||||
return castFactory(any);
|
||||
function any(...parameters) {
|
||||
let index2 = -1;
|
||||
while (++index2 < checks.length) {
|
||||
if (checks[index2].apply(this, parameters))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function propsFactory(check) {
|
||||
const checkAsRecord = (
|
||||
/** @type {Record<string, unknown>} */
|
||||
check
|
||||
);
|
||||
return castFactory(all);
|
||||
function all(node) {
|
||||
const nodeAsRecord = (
|
||||
/** @type {Record<string, unknown>} */
|
||||
/** @type {unknown} */
|
||||
node
|
||||
);
|
||||
let key;
|
||||
for (key in check) {
|
||||
if (nodeAsRecord[key] !== checkAsRecord[key])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function typeFactory(check) {
|
||||
return castFactory(type);
|
||||
function type(node) {
|
||||
return node && node.type === check;
|
||||
}
|
||||
}
|
||||
function castFactory(testFunction) {
|
||||
return check;
|
||||
function check(value, index, parent) {
|
||||
return Boolean(
|
||||
looksLikeANode(value) && testFunction.call(
|
||||
this,
|
||||
value,
|
||||
typeof index === "number" ? index : void 0,
|
||||
parent || void 0
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
function ok() {
|
||||
return true;
|
||||
}
|
||||
function looksLikeANode(value) {
|
||||
return value !== null && typeof value === "object" && "type" in value;
|
||||
}
|
||||
|
||||
// node_modules/unist-util-visit-parents/lib/color.node.js
|
||||
function color(d) {
|
||||
return "\x1B[33m" + d + "\x1B[39m";
|
||||
}
|
||||
|
||||
// node_modules/unist-util-visit-parents/lib/index.js
|
||||
var empty = [];
|
||||
var CONTINUE = true;
|
||||
var EXIT = false;
|
||||
var SKIP = "skip";
|
||||
function visitParents(tree, test, visitor, reverse) {
|
||||
let check;
|
||||
if (typeof test === "function" && typeof visitor !== "function") {
|
||||
reverse = visitor;
|
||||
visitor = test;
|
||||
} else {
|
||||
check = test;
|
||||
}
|
||||
const is2 = convert(check);
|
||||
const step = reverse ? -1 : 1;
|
||||
factory(tree, void 0, [])();
|
||||
function factory(node, index, parents) {
|
||||
const value = (
|
||||
/** @type {Record<string, unknown>} */
|
||||
node && typeof node === "object" ? node : {}
|
||||
);
|
||||
if (typeof value.type === "string") {
|
||||
const name = (
|
||||
// `hast`
|
||||
typeof value.tagName === "string" ? value.tagName : (
|
||||
// `xast`
|
||||
typeof value.name === "string" ? value.name : void 0
|
||||
)
|
||||
);
|
||||
Object.defineProperty(visit2, "name", {
|
||||
value: "node (" + color(node.type + (name ? "<" + name + ">" : "")) + ")"
|
||||
});
|
||||
}
|
||||
return visit2;
|
||||
function visit2() {
|
||||
let result = empty;
|
||||
let subresult;
|
||||
let offset;
|
||||
let grandparents;
|
||||
if (!test || is2(node, index, parents[parents.length - 1] || void 0)) {
|
||||
result = toResult(visitor(node, parents));
|
||||
if (result[0] === EXIT) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if ("children" in node && node.children) {
|
||||
const nodeAsParent = (
|
||||
/** @type {UnistParent} */
|
||||
node
|
||||
);
|
||||
if (nodeAsParent.children && result[0] !== SKIP) {
|
||||
offset = (reverse ? nodeAsParent.children.length : -1) + step;
|
||||
grandparents = parents.concat(nodeAsParent);
|
||||
while (offset > -1 && offset < nodeAsParent.children.length) {
|
||||
const child = nodeAsParent.children[offset];
|
||||
subresult = factory(child, offset, grandparents)();
|
||||
if (subresult[0] === EXIT) {
|
||||
return subresult;
|
||||
}
|
||||
offset = typeof subresult[1] === "number" ? subresult[1] : offset + step;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
function toResult(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "number") {
|
||||
return [CONTINUE, value];
|
||||
}
|
||||
return value === null || value === void 0 ? empty : [value];
|
||||
}
|
||||
|
||||
// node_modules/unist-util-visit/lib/index.js
|
||||
function visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {
|
||||
let reverse;
|
||||
let test;
|
||||
let visitor;
|
||||
if (typeof testOrVisitor === "function" && typeof visitorOrReverse !== "function") {
|
||||
test = void 0;
|
||||
visitor = testOrVisitor;
|
||||
reverse = visitorOrReverse;
|
||||
} else {
|
||||
test = testOrVisitor;
|
||||
visitor = visitorOrReverse;
|
||||
reverse = maybeReverse;
|
||||
}
|
||||
visitParents(tree, test, overload, reverse);
|
||||
function overload(node, parents) {
|
||||
const parent = parents[parents.length - 1];
|
||||
const index = parent ? parent.children.indexOf(node) : void 0;
|
||||
return visitor(node, index, parent);
|
||||
}
|
||||
}
|
||||
|
||||
// node_modules/unist-util-remove-position/lib/index.js
|
||||
function removePosition(tree, options) {
|
||||
const config = options || {};
|
||||
const force = config.force || false;
|
||||
visit(tree, remove);
|
||||
function remove(node) {
|
||||
if (force) {
|
||||
delete node.position;
|
||||
} else {
|
||||
node.position = void 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
removePosition
|
||||
});
|
232
jest/vendor/unist-util-visit@5.0.0.js
vendored
Normal file
232
jest/vendor/unist-util-visit@5.0.0.js
vendored
Normal file
|
@ -0,0 +1,232 @@
|
|||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// node_modules/unist-util-visit/index.js
|
||||
var unist_util_visit_exports = {};
|
||||
__export(unist_util_visit_exports, {
|
||||
CONTINUE: () => CONTINUE,
|
||||
EXIT: () => EXIT,
|
||||
SKIP: () => SKIP,
|
||||
visit: () => visit
|
||||
});
|
||||
module.exports = __toCommonJS(unist_util_visit_exports);
|
||||
|
||||
// node_modules/unist-util-is/lib/index.js
|
||||
var convert = (
|
||||
// Note: overloads in JSDoc can’t yet use different `@template`s.
|
||||
/**
|
||||
* @type {(
|
||||
* (<Condition extends string>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & {type: Condition}) &
|
||||
* (<Condition extends Props>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Condition) &
|
||||
* (<Condition extends TestFunction>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Predicate<Condition, Node>) &
|
||||
* ((test?: null | undefined) => (node?: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node) &
|
||||
* ((test?: Test) => Check)
|
||||
* )}
|
||||
*/
|
||||
/**
|
||||
* @param {Test} [test]
|
||||
* @returns {Check}
|
||||
*/
|
||||
function(test) {
|
||||
if (test === null || test === void 0) {
|
||||
return ok;
|
||||
}
|
||||
if (typeof test === "function") {
|
||||
return castFactory(test);
|
||||
}
|
||||
if (typeof test === "object") {
|
||||
return Array.isArray(test) ? anyFactory(test) : propsFactory(test);
|
||||
}
|
||||
if (typeof test === "string") {
|
||||
return typeFactory(test);
|
||||
}
|
||||
throw new Error("Expected function, string, or object as test");
|
||||
}
|
||||
);
|
||||
function anyFactory(tests) {
|
||||
const checks = [];
|
||||
let index = -1;
|
||||
while (++index < tests.length) {
|
||||
checks[index] = convert(tests[index]);
|
||||
}
|
||||
return castFactory(any);
|
||||
function any(...parameters) {
|
||||
let index2 = -1;
|
||||
while (++index2 < checks.length) {
|
||||
if (checks[index2].apply(this, parameters))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function propsFactory(check) {
|
||||
const checkAsRecord = (
|
||||
/** @type {Record<string, unknown>} */
|
||||
check
|
||||
);
|
||||
return castFactory(all);
|
||||
function all(node) {
|
||||
const nodeAsRecord = (
|
||||
/** @type {Record<string, unknown>} */
|
||||
/** @type {unknown} */
|
||||
node
|
||||
);
|
||||
let key;
|
||||
for (key in check) {
|
||||
if (nodeAsRecord[key] !== checkAsRecord[key])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function typeFactory(check) {
|
||||
return castFactory(type);
|
||||
function type(node) {
|
||||
return node && node.type === check;
|
||||
}
|
||||
}
|
||||
function castFactory(testFunction) {
|
||||
return check;
|
||||
function check(value, index, parent) {
|
||||
return Boolean(
|
||||
looksLikeANode(value) && testFunction.call(
|
||||
this,
|
||||
value,
|
||||
typeof index === "number" ? index : void 0,
|
||||
parent || void 0
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
function ok() {
|
||||
return true;
|
||||
}
|
||||
function looksLikeANode(value) {
|
||||
return value !== null && typeof value === "object" && "type" in value;
|
||||
}
|
||||
|
||||
// node_modules/unist-util-visit-parents/lib/color.node.js
|
||||
function color(d) {
|
||||
return "\x1B[33m" + d + "\x1B[39m";
|
||||
}
|
||||
|
||||
// node_modules/unist-util-visit-parents/lib/index.js
|
||||
var empty = [];
|
||||
var CONTINUE = true;
|
||||
var EXIT = false;
|
||||
var SKIP = "skip";
|
||||
function visitParents(tree, test, visitor, reverse) {
|
||||
let check;
|
||||
if (typeof test === "function" && typeof visitor !== "function") {
|
||||
reverse = visitor;
|
||||
visitor = test;
|
||||
} else {
|
||||
check = test;
|
||||
}
|
||||
const is2 = convert(check);
|
||||
const step = reverse ? -1 : 1;
|
||||
factory(tree, void 0, [])();
|
||||
function factory(node, index, parents) {
|
||||
const value = (
|
||||
/** @type {Record<string, unknown>} */
|
||||
node && typeof node === "object" ? node : {}
|
||||
);
|
||||
if (typeof value.type === "string") {
|
||||
const name = (
|
||||
// `hast`
|
||||
typeof value.tagName === "string" ? value.tagName : (
|
||||
// `xast`
|
||||
typeof value.name === "string" ? value.name : void 0
|
||||
)
|
||||
);
|
||||
Object.defineProperty(visit2, "name", {
|
||||
value: "node (" + color(node.type + (name ? "<" + name + ">" : "")) + ")"
|
||||
});
|
||||
}
|
||||
return visit2;
|
||||
function visit2() {
|
||||
let result = empty;
|
||||
let subresult;
|
||||
let offset;
|
||||
let grandparents;
|
||||
if (!test || is2(node, index, parents[parents.length - 1] || void 0)) {
|
||||
result = toResult(visitor(node, parents));
|
||||
if (result[0] === EXIT) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if ("children" in node && node.children) {
|
||||
const nodeAsParent = (
|
||||
/** @type {UnistParent} */
|
||||
node
|
||||
);
|
||||
if (nodeAsParent.children && result[0] !== SKIP) {
|
||||
offset = (reverse ? nodeAsParent.children.length : -1) + step;
|
||||
grandparents = parents.concat(nodeAsParent);
|
||||
while (offset > -1 && offset < nodeAsParent.children.length) {
|
||||
const child = nodeAsParent.children[offset];
|
||||
subresult = factory(child, offset, grandparents)();
|
||||
if (subresult[0] === EXIT) {
|
||||
return subresult;
|
||||
}
|
||||
offset = typeof subresult[1] === "number" ? subresult[1] : offset + step;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
function toResult(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "number") {
|
||||
return [CONTINUE, value];
|
||||
}
|
||||
return value === null || value === void 0 ? empty : [value];
|
||||
}
|
||||
|
||||
// node_modules/unist-util-visit/lib/index.js
|
||||
function visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {
|
||||
let reverse;
|
||||
let test;
|
||||
let visitor;
|
||||
if (typeof testOrVisitor === "function" && typeof visitorOrReverse !== "function") {
|
||||
test = void 0;
|
||||
visitor = testOrVisitor;
|
||||
reverse = visitorOrReverse;
|
||||
} else {
|
||||
test = testOrVisitor;
|
||||
visitor = visitorOrReverse;
|
||||
reverse = maybeReverse;
|
||||
}
|
||||
visitParents(tree, test, overload, reverse);
|
||||
function overload(node, parents) {
|
||||
const parent = parents[parents.length - 1];
|
||||
const index = parent ? parent.children.indexOf(node) : void 0;
|
||||
return visitor(node, index, parent);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CONTINUE,
|
||||
EXIT,
|
||||
SKIP,
|
||||
visit
|
||||
});
|
|
@ -62,9 +62,6 @@
|
|||
"lock:update": "npx --yes yarn-deduplicate",
|
||||
"update-translations": "yarn workspace @docusaurus/theme-translations update"
|
||||
},
|
||||
"dependencies": {
|
||||
"unified": "^10.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@crowdin/cli": "^3.13.0",
|
||||
"@swc/core": "1.2.197",
|
||||
|
@ -109,7 +106,6 @@
|
|||
"react-dom": "^18.0.0",
|
||||
"react-helmet-async": "^1.3.0",
|
||||
"react-test-renderer": "^18.0.0",
|
||||
"remark-parse": "^8.0.3",
|
||||
"rimraf": "^3.0.2",
|
||||
"sharp": "^0.32.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
"dependencies": {
|
||||
"@docusaurus/core": "3.0.0-rc.0",
|
||||
"@docusaurus/preset-classic": "3.0.0-rc.0",
|
||||
"@mdx-js/react": "^2.3.0",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
"prism-react-renderer": "^2.1.0",
|
||||
"react": "^18.0.0",
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"dependencies": {
|
||||
"@docusaurus/core": "3.0.0-rc.0",
|
||||
"@docusaurus/preset-classic": "3.0.0-rc.0",
|
||||
"@mdx-js/react": "^2.3.0",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
"prism-react-renderer": "^2.1.0",
|
||||
"react": "^18.0.0",
|
||||
|
|
|
@ -23,42 +23,41 @@
|
|||
"@docusaurus/logger": "3.0.0-rc.0",
|
||||
"@docusaurus/utils": "3.0.0-rc.0",
|
||||
"@docusaurus/utils-validation": "3.0.0-rc.0",
|
||||
"@mdx-js/mdx": "^2.1.5",
|
||||
"@mdx-js/mdx": "^3.0.0",
|
||||
"@slorber/remark-comment": "^1.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"estree-util-value-to-estree": "^2.1.0",
|
||||
"estree-util-value-to-estree": "^3.0.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"hastscript": "^7.1.0",
|
||||
"image-size": "^1.0.2",
|
||||
"mdast-util-mdx": "^2.0.0",
|
||||
"mdast-util-to-string": "^3.2.0",
|
||||
"rehype-raw": "^6.1.1",
|
||||
"remark-directive": "^2.0.1",
|
||||
"remark-emoji": "^2.2.0",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"mdast-util-to-string": "^4.0.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-directive": "^3.0.0",
|
||||
"remark-emoji": "^4.0.0",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tslib": "^2.6.0",
|
||||
"unified": "^10.1.2",
|
||||
"unist-util-visit": "^2.0.3",
|
||||
"unified": "^11.0.3",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"url-loader": "^4.1.1",
|
||||
"vfile": "^5.3.7",
|
||||
"vfile": "^6.0.1",
|
||||
"webpack": "^5.88.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/types": "3.0.0-rc.0",
|
||||
"@types/escape-html": "^1.0.2",
|
||||
"@types/mdast": "^3.0.12",
|
||||
"@types/mdast": "^4.0.2",
|
||||
"@types/stringify-object": "^3.3.1",
|
||||
"@types/unist": "^2.0.7",
|
||||
"rehype-stringify": "^8.0.0",
|
||||
"remark": "^14.0.3",
|
||||
"remark-mdx": "^2.1.5",
|
||||
"remark-rehype": "^8.1.0",
|
||||
"@types/unist": "^3.0.1",
|
||||
"rehype-stringify": "^10.0.0",
|
||||
"remark": "^15.0.1",
|
||||
"remark-mdx": "^3.0.0",
|
||||
"remark-rehype": "^11.0.0",
|
||||
"to-vfile": "^6.1.0",
|
||||
"unist-builder": "^2.0.3",
|
||||
"unist-util-remove-position": "^3.0.0"
|
||||
"unist-util-remove-position": "^5.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0",
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import emoji from 'remark-emoji';
|
||||
import headings from './remark/headings';
|
||||
import contentTitle from './remark/contentTitle';
|
||||
import toc from './remark/toc';
|
||||
|
@ -48,13 +47,10 @@ type SimpleProcessor = {
|
|||
}) => Promise<SimpleProcessorResult>;
|
||||
};
|
||||
|
||||
const DEFAULT_OPTIONS: MDXOptions = {
|
||||
admonitions: true,
|
||||
rehypePlugins: [],
|
||||
remarkPlugins: [headings, emoji, toc],
|
||||
beforeDefaultRemarkPlugins: [],
|
||||
beforeDefaultRehypePlugins: [],
|
||||
};
|
||||
async function getDefaultRemarkPlugins(): Promise<MDXPlugin[]> {
|
||||
const {default: emoji} = await import('remark-emoji');
|
||||
return [headings, emoji, toc];
|
||||
}
|
||||
|
||||
export type MDXPlugin = Pluggable;
|
||||
|
||||
|
@ -91,6 +87,8 @@ async function createProcessorFactory() {
|
|||
const {default: directive} = await import('remark-directive');
|
||||
const {VFile} = await import('vfile');
|
||||
|
||||
const defaultRemarkPlugins = await getDefaultRemarkPlugins();
|
||||
|
||||
// /!\ this method is synchronous on purpose
|
||||
// Using async code here can create cache entry race conditions!
|
||||
function createProcessorSync({
|
||||
|
@ -106,7 +104,7 @@ async function createProcessorFactory() {
|
|||
directive,
|
||||
[contentTitle, {removeContentTitle: options.removeContentTitle}],
|
||||
...getAdmonitionsPlugins(options.admonitions ?? false),
|
||||
...DEFAULT_OPTIONS.remarkPlugins,
|
||||
...defaultRemarkPlugins,
|
||||
details,
|
||||
head,
|
||||
...(options.markdownConfig.mermaid ? [mermaid] : []),
|
||||
|
@ -136,7 +134,6 @@ async function createProcessorFactory() {
|
|||
|
||||
const rehypePlugins: MDXPlugin[] = [
|
||||
...(options.beforeDefaultRehypePlugins ?? []),
|
||||
...DEFAULT_OPTIONS.rehypePlugins,
|
||||
...(options.rehypePlugins ?? []),
|
||||
];
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
import visit from 'unist-util-visit';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer, Processor} from 'unified';
|
||||
|
||||
|
@ -67,6 +66,7 @@ function parseDirective(directive: ContainerDirective): {
|
|||
contentNodes: DirectiveContent;
|
||||
} {
|
||||
const hasDirectiveLabel =
|
||||
// @ts-expect-error: fine
|
||||
directive.children?.[0]?.data?.directiveLabel === true;
|
||||
if (hasDirectiveLabel) {
|
||||
const [directiveLabel, ...contentNodes] = directive.children;
|
||||
|
@ -92,6 +92,8 @@ const plugin: Plugin = function plugin(
|
|||
const {keywords} = normalizeAdmonitionOptions(optionsInput);
|
||||
|
||||
return async (root) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
visit(root, (node) => {
|
||||
if (node.type === 'containerDirective') {
|
||||
const directive = node as ContainerDirective;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import visit, {EXIT} from 'unist-util-visit';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
import type {Heading} from 'mdast';
|
||||
|
@ -33,11 +32,13 @@ const plugin: Plugin = function plugin(
|
|||
|
||||
return async (root, vfile) => {
|
||||
const {toString} = await import('mdast-util-to-string');
|
||||
const {visit, EXIT} = await import('unist-util-visit');
|
||||
|
||||
visit(root, 'heading', (headingNode: Heading, index, parent) => {
|
||||
if (headingNode.depth === 1) {
|
||||
vfile.data.compilerName;
|
||||
vfile.data.contentTitle = toString(headingNode);
|
||||
if (removeContentTitle) {
|
||||
// @ts-expect-error: TODO how to fix?
|
||||
parent!.children.splice(index, 1);
|
||||
}
|
||||
return EXIT; // We only handle the very first heading
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import visit from 'unist-util-visit';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
|
||||
|
@ -15,7 +14,8 @@ import type {MdxJsxFlowElement} from 'mdast-util-mdx';
|
|||
// Transform <details> to <Details>
|
||||
// MDX 2 doesn't allow to substitute html elements with the provider anymore
|
||||
export default function plugin(): Transformer {
|
||||
return (root) => {
|
||||
return async (root) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
visit(root, 'mdxJsxFlowElement', (node: MdxJsxFlowElement) => {
|
||||
if (node.name === 'details') {
|
||||
node.name = 'Details';
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import visit from 'unist-util-visit';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
|
||||
|
@ -15,7 +14,8 @@ import type {MdxJsxFlowElement} from 'mdast-util-mdx';
|
|||
// Transform <head> to <Head>
|
||||
// MDX 2 doesn't allow to substitute html elements with the provider anymore
|
||||
export default function plugin(): Transformer {
|
||||
return (root) => {
|
||||
return async (root) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
visit(root, 'mdxJsxFlowElement', (node: MdxJsxFlowElement) => {
|
||||
if (node.name === 'head') {
|
||||
node.name = 'Head';
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
/* Based on remark-slug (https://github.com/remarkjs/remark-slug) and gatsby-remark-autolink-headers (https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-remark-autolink-headers) */
|
||||
|
||||
import u from 'unist-builder';
|
||||
import removePosition from 'unist-util-remove-position';
|
||||
import {removePosition} from 'unist-util-remove-position';
|
||||
import {toString} from 'mdast-util-to-string';
|
||||
import visit from 'unist-util-visit';
|
||||
import {visit} from 'unist-util-visit';
|
||||
import slug from '../index';
|
||||
import type {Plugin} from 'unified';
|
||||
import type {Parent} from 'unist';
|
||||
|
@ -18,7 +18,9 @@ import type {Parent} from 'unist';
|
|||
async function process(doc: string, plugins: Plugin[] = []) {
|
||||
const {remark} = await import('remark');
|
||||
const processor = await remark().use({plugins: [...plugins, slug]});
|
||||
return removePosition(await processor.run(processor.parse(doc)), true);
|
||||
const result = await processor.run(processor.parse(doc));
|
||||
removePosition(result, {force: true});
|
||||
return result;
|
||||
}
|
||||
|
||||
function heading(label: string | null, id: string) {
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
/* Based on remark-slug (https://github.com/remarkjs/remark-slug) and gatsby-remark-autolink-headers (https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-remark-autolink-headers) */
|
||||
|
||||
import {parseMarkdownHeadingId, createSlugger} from '@docusaurus/utils';
|
||||
import visit from 'unist-util-visit';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
import type {Heading, Text} from 'mdast';
|
||||
|
@ -16,6 +15,7 @@ import type {Heading, Text} from 'mdast';
|
|||
export default function plugin(): Transformer {
|
||||
return async (root) => {
|
||||
const {toString} = await import('mdast-util-to-string');
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
const slugs = createSlugger();
|
||||
visit(root, 'heading', (headingNode: Heading) => {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import visit from 'unist-util-visit';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer, Processor} from 'unified';
|
||||
import type {Code} from 'mdast';
|
||||
|
@ -18,19 +17,18 @@ import type {Code} from 'mdast';
|
|||
// To make theme-classic/src/theme/MDXComponents/Pre work
|
||||
// we need to fill two properties that mdx v2 doesn't provide anymore
|
||||
export default function codeCompatPlugin(this: Processor): Transformer {
|
||||
return (root) => {
|
||||
return async (root) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
visit(root, 'code', (node: Code) => {
|
||||
node.data = node.data || {};
|
||||
|
||||
node.data.hProperties = node.data.hProperties || {};
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(node.data.hProperties as any).metastring = node.meta;
|
||||
node.data.hProperties.metastring = node.meta;
|
||||
|
||||
// Retrocompatible support for live codeblock metastring
|
||||
// Not really the appropriate place to handle that :s
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(node.data.hProperties as any).live = node.meta
|
||||
?.split(' ')
|
||||
.includes('live');
|
||||
node.data.hProperties.live = node.meta?.split(' ').includes('live');
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import visit from 'unist-util-visit';
|
||||
import {transformNode} from '../utils';
|
||||
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
|
@ -17,7 +16,9 @@ import type {Code} from 'mdast';
|
|||
// https://github.com/facebook/docusaurus/issues/6370), this should be provided
|
||||
// by theme-mermaid itself
|
||||
export default function plugin(): Transformer {
|
||||
return (root) => {
|
||||
return async (root) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
visit(root, 'code', (node: Code) => {
|
||||
if (node.lang === 'mermaid') {
|
||||
// TODO migrate to mdxJsxFlowElement? cf admonitions
|
||||
|
|
|
@ -8,13 +8,16 @@
|
|||
import {parse, type ParserOptions} from '@babel/parser';
|
||||
import traverse from '@babel/traverse';
|
||||
import stringifyObject from 'stringify-object';
|
||||
import visit from 'unist-util-visit';
|
||||
import {toValue} from '../utils';
|
||||
import type {Identifier} from '@babel/types';
|
||||
import type {Node, Parent} from 'unist';
|
||||
import type {Heading, Literal} from 'mdast';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
import type {
|
||||
MdxjsEsm,
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
} from 'mdast-util-mdx';
|
||||
|
||||
// TODO as of April 2023, no way to import/re-export this ESM type easily :/
|
||||
// TODO upgrade to TS 5.3
|
||||
|
@ -88,6 +91,8 @@ const plugin: Plugin = function plugin(
|
|||
|
||||
return async (root) => {
|
||||
const {toString} = await import('mdast-util-to-string');
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
const headings: TOCItem[] = [];
|
||||
|
||||
visit(root, 'heading', (child: Heading) => {
|
||||
|
@ -100,11 +105,12 @@ const plugin: Plugin = function plugin(
|
|||
|
||||
headings.push({
|
||||
value: toValue(child, toString),
|
||||
id: child.data!.id as string,
|
||||
id: child.data!.id!,
|
||||
level: child.depth,
|
||||
});
|
||||
});
|
||||
const {children} = root as Parent<Literal>;
|
||||
|
||||
const {children} = root as Parent;
|
||||
const targetIndex = await getOrCreateExistingTargetIndex(children, name);
|
||||
|
||||
if (headings?.length) {
|
||||
|
@ -115,7 +121,7 @@ const plugin: Plugin = function plugin(
|
|||
|
||||
export default plugin;
|
||||
|
||||
async function createExportNode(name: string, object: any) {
|
||||
async function createExportNode(name: string, object: any): Promise<MdxjsEsm> {
|
||||
const {valueToEstree} = await import('estree-util-value-to-estree');
|
||||
|
||||
return {
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
getFileLoaderUtils,
|
||||
findAsyncSequential,
|
||||
} from '@docusaurus/utils';
|
||||
import visit from 'unist-util-visit';
|
||||
import escapeHtml from 'escape-html';
|
||||
import sizeOf from 'image-size';
|
||||
import logger from '@docusaurus/logger';
|
||||
|
@ -192,6 +191,8 @@ async function processImageNode(target: Target, context: Context) {
|
|||
|
||||
export default function plugin(options: PluginOptions): Transformer {
|
||||
return async (root, vfile) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
const promises: Promise<void>[] = [];
|
||||
visit(root, 'image', (node: Image, index, parent) => {
|
||||
promises.push(
|
||||
|
|
|
@ -15,7 +15,6 @@ import {
|
|||
getFileLoaderUtils,
|
||||
findAsyncSequential,
|
||||
} from '@docusaurus/utils';
|
||||
import visit from 'unist-util-visit';
|
||||
import escapeHtml from 'escape-html';
|
||||
import {assetRequireAttributeValue, transformNode} from '../utils';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
|
@ -175,6 +174,8 @@ async function processLinkNode(target: Target, context: Context) {
|
|||
|
||||
export default function plugin(options: PluginOptions): Transformer {
|
||||
return async (root, vfile) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
const promises: Promise<void>[] = [];
|
||||
visit(root, 'link', (node: Link, index, parent) => {
|
||||
promises.push(
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
import path from 'path';
|
||||
import process from 'process';
|
||||
import visit from 'unist-util-visit';
|
||||
import logger from '@docusaurus/logger';
|
||||
import {posixPath} from '@docusaurus/utils';
|
||||
import {transformNode} from '../utils';
|
||||
|
@ -14,7 +13,7 @@ import {transformNode} from '../utils';
|
|||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer, Processor, Parent} from 'unified';
|
||||
import type {
|
||||
Directive,
|
||||
Directives,
|
||||
TextDirective,
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
} from 'mdast-util-directive';
|
||||
|
@ -25,7 +24,7 @@ import type {
|
|||
// import type {Plugin} from 'unified';
|
||||
type Plugin = any; // TODO fix this asap
|
||||
|
||||
type DirectiveType = Directive['type'];
|
||||
type DirectiveType = Directives['type'];
|
||||
|
||||
const directiveTypes: DirectiveType[] = [
|
||||
'containerDirective',
|
||||
|
@ -39,7 +38,7 @@ const directivePrefixMap: {[key in DirectiveType]: string} = {
|
|||
containerDirective: ':::',
|
||||
};
|
||||
|
||||
function formatDirectiveName(directive: Directive) {
|
||||
function formatDirectiveName(directive: Directives) {
|
||||
const prefix = directivePrefixMap[directive.type];
|
||||
if (!prefix) {
|
||||
throw new Error(
|
||||
|
@ -50,13 +49,13 @@ function formatDirectiveName(directive: Directive) {
|
|||
return `${prefix}${directive.name}`;
|
||||
}
|
||||
|
||||
function formatDirectivePosition(directive: Directive): string | undefined {
|
||||
function formatDirectivePosition(directive: Directives): string | undefined {
|
||||
return directive.position?.start
|
||||
? logger.interpolate`number=${directive.position.start.line}:number=${directive.position.start.column}`
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function formatUnusedDirectiveMessage(directive: Directive) {
|
||||
function formatUnusedDirectiveMessage(directive: Directives) {
|
||||
const name = formatDirectiveName(directive);
|
||||
const position = formatDirectivePosition(directive);
|
||||
|
||||
|
@ -67,7 +66,7 @@ function formatUnusedDirectivesMessage({
|
|||
directives,
|
||||
filePath,
|
||||
}: {
|
||||
directives: Directive[];
|
||||
directives: Directives[];
|
||||
filePath: string;
|
||||
}): string {
|
||||
const supportUrl = 'https://github.com/facebook/docusaurus/pull/9394';
|
||||
|
@ -87,7 +86,7 @@ function logUnusedDirectivesWarning({
|
|||
directives,
|
||||
filePath,
|
||||
}: {
|
||||
directives: Directive[];
|
||||
directives: Directives[];
|
||||
filePath: string;
|
||||
}) {
|
||||
if (directives.length > 0) {
|
||||
|
@ -99,13 +98,13 @@ function logUnusedDirectivesWarning({
|
|||
}
|
||||
}
|
||||
|
||||
function isTextDirective(directive: Directive): directive is TextDirective {
|
||||
function isTextDirective(directive: Directives): directive is TextDirective {
|
||||
return directive.type === 'textDirective';
|
||||
}
|
||||
|
||||
// A simple text directive is one without any label/props
|
||||
function isSimpleTextDirective(
|
||||
directive: Directive,
|
||||
directive: Directives,
|
||||
): directive is TextDirective {
|
||||
if (isTextDirective(directive)) {
|
||||
// Attributes in MDAST = Directive props
|
||||
|
@ -118,25 +117,30 @@ function isSimpleTextDirective(
|
|||
return false;
|
||||
}
|
||||
|
||||
function transformSimpleTextDirectiveToString(textDirective: Directive) {
|
||||
function transformSimpleTextDirectiveToString(textDirective: Directives) {
|
||||
transformNode(textDirective, {
|
||||
type: 'text',
|
||||
value: `:${textDirective.name}`, // We ignore label/props on purpose here
|
||||
});
|
||||
}
|
||||
|
||||
function isUnusedDirective(directive: Directive) {
|
||||
function isUnusedDirective(directive: Directives) {
|
||||
// If directive data is set (notably hName/hProperties set by admonitions)
|
||||
// this usually means the directive has been handled by another plugin
|
||||
return !directive.data;
|
||||
}
|
||||
|
||||
const plugin: Plugin = function plugin(this: Processor): Transformer {
|
||||
return (tree, file) => {
|
||||
const unusedDirectives: Directive[] = [];
|
||||
return async (tree, file) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
visit<Parent>(tree, directiveTypes, (directive: Directive) => {
|
||||
// If directive data is set (notably hName/hProperties set by admonitions)
|
||||
const unusedDirectives: Directives[] = [];
|
||||
|
||||
visit<Parent, DirectiveType[]>(
|
||||
tree,
|
||||
directiveTypes,
|
||||
(directive: Directives) => {
|
||||
// If directive data is set (hName/hProperties set by admonitions)
|
||||
// this usually means the directive has been handled by another plugin
|
||||
if (isUnusedDirective(directive)) {
|
||||
if (isSimpleTextDirective(directive)) {
|
||||
|
@ -145,7 +149,8 @@ const plugin: Plugin = function plugin(this: Processor): Transformer {
|
|||
unusedDirectives.push(directive);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// We only enable these warnings for the client compiler
|
||||
// This avoids emitting duplicate warnings in prod mode
|
||||
|
|
|
@ -74,7 +74,7 @@ function mdxJsxTextElementToHtml(
|
|||
}
|
||||
|
||||
export function toValue(
|
||||
node: PhrasingContent | Heading,
|
||||
node: PhrasingContent | Heading | MdxJsxTextElement,
|
||||
toString: (param: unknown) => string, // TODO weird but works
|
||||
): string {
|
||||
switch (node.type) {
|
||||
|
|
|
@ -19,3 +19,16 @@ declare module 'vfile' {
|
|||
contentTitle?: string;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'unist' {
|
||||
interface Data {
|
||||
hName?: string;
|
||||
hProperties?: Record<string, unknown>;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'mdast' {
|
||||
interface HeadingData {
|
||||
id?: string;
|
||||
}
|
||||
}
|
|
@ -33,7 +33,7 @@
|
|||
"reading-time": "^1.5.0",
|
||||
"srcset": "^4.0.0",
|
||||
"tslib": "^2.6.0",
|
||||
"unist-util-visit": "^2.0.3",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"utility-types": "^3.10.0",
|
||||
"webpack": "^5.88.1"
|
||||
},
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`footnoteIDFixer remark plugin appends a hash to each footnote def/ref 1`] = `
|
||||
"/*@jsxRuntime automatic @jsxImportSource react*/
|
||||
import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
||||
function _createMdxContent(props) {
|
||||
const _components = Object.assign({
|
||||
p: "p",
|
||||
sup: "sup",
|
||||
const _components = {
|
||||
a: "a",
|
||||
section: "section",
|
||||
h2: "h2",
|
||||
li: "li",
|
||||
ol: "ol",
|
||||
li: "li"
|
||||
}, props.components);
|
||||
p: "p",
|
||||
section: "section",
|
||||
sup: "sup",
|
||||
...props.components
|
||||
};
|
||||
return _jsxs(_Fragment, {
|
||||
children: [_jsxs(_components.p, {
|
||||
children: ["foo", _jsx(_components.sup, {
|
||||
|
@ -57,9 +57,9 @@ function _createMdxContent(props) {
|
|||
children: ["/n", _jsxs(_components.p, {
|
||||
children: ["foo ", _jsx(_components.a, {
|
||||
href: "#user-content-fnref-1-[HASH]",
|
||||
"data-footnote-backref": true,
|
||||
"data-footnote-backref": "",
|
||||
"aria-label": "Back to reference 1",
|
||||
className: "data-footnote-backref",
|
||||
"aria-label": "Back to content",
|
||||
children: "↩"
|
||||
})]
|
||||
}), "/n"]
|
||||
|
@ -68,9 +68,9 @@ function _createMdxContent(props) {
|
|||
children: ["/n", _jsxs(_components.p, {
|
||||
children: ["foo ", _jsx(_components.a, {
|
||||
href: "#user-content-fnref-2-[HASH]",
|
||||
"data-footnote-backref": true,
|
||||
"data-footnote-backref": "",
|
||||
"aria-label": "Back to reference 2",
|
||||
className: "data-footnote-backref",
|
||||
"aria-label": "Back to content",
|
||||
children: "↩"
|
||||
})]
|
||||
}), "/n"]
|
||||
|
@ -79,9 +79,9 @@ function _createMdxContent(props) {
|
|||
children: ["/n", _jsxs(_components.p, {
|
||||
children: ["foo ", _jsx(_components.a, {
|
||||
href: "#user-content-fnref-3-[HASH]",
|
||||
"data-footnote-backref": true,
|
||||
"data-footnote-backref": "",
|
||||
"aria-label": "Back to reference 3",
|
||||
className: "data-footnote-backref",
|
||||
"aria-label": "Back to content",
|
||||
children: "↩"
|
||||
})]
|
||||
}), "/n"]
|
||||
|
@ -90,12 +90,14 @@ function _createMdxContent(props) {
|
|||
})]
|
||||
});
|
||||
}
|
||||
function MDXContent(props = {}) {
|
||||
export default function MDXContent(props = {}) {
|
||||
const {wrapper: MDXLayout} = props.components || ({});
|
||||
return MDXLayout ? _jsx(MDXLayout, Object.assign({}, props, {
|
||||
children: _jsx(_createMdxContent, props)
|
||||
})) : _createMdxContent(props);
|
||||
return MDXLayout ? _jsx(MDXLayout, {
|
||||
...props,
|
||||
children: _jsx(_createMdxContent, {
|
||||
...props
|
||||
})
|
||||
}) : _createMdxContent(props);
|
||||
}
|
||||
export default MDXContent;
|
||||
"
|
||||
`;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import visit from 'unist-util-visit';
|
||||
import {simpleHash} from '@docusaurus/utils';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
import type {Transformer} from 'unified';
|
||||
|
@ -18,7 +17,9 @@ import type {FootnoteReference, FootnoteDefinition} from 'mdast';
|
|||
* unique hash to each reference/definition.
|
||||
*/
|
||||
export default function plugin(): Transformer {
|
||||
return (root, vfile) => {
|
||||
return async (root, vfile) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
const suffix = `-${simpleHash(vfile.path!, 6)}`;
|
||||
visit(root, 'footnoteReference', (node: FootnoteReference) => {
|
||||
node.identifier += suffix;
|
||||
|
|
|
@ -17,16 +17,16 @@
|
|||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mdast-util-mdx": "^2.0.0",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"npm-to-yarn": "^2.0.0",
|
||||
"tslib": "^2.6.0",
|
||||
"unified": "^10.1.2",
|
||||
"unist-util-visit": "^2.0.3"
|
||||
"unified": "^11.0.3",
|
||||
"unist-util-visit": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mdast": "^3.0.12",
|
||||
"remark": "^14.0.3",
|
||||
"remark-mdx": "^2.1.5",
|
||||
"@types/mdast": "^4.0.2",
|
||||
"remark": "^15.0.1",
|
||||
"remark-mdx": "^3.0.0",
|
||||
"to-vfile": "^6.1.0"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import visit from 'unist-util-visit';
|
||||
import npmToYarn from 'npm-to-yarn';
|
||||
import type {Code, Literal} from 'mdast';
|
||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||
|
@ -173,7 +172,9 @@ function createImportNode() {
|
|||
const plugin: Plugin<[PluginOptions?]> = (options = {}): Transformer => {
|
||||
// @ts-expect-error: todo temporary
|
||||
const {sync = false, converters = ['yarn', 'pnpm']} = options;
|
||||
return (root) => {
|
||||
return async (root) => {
|
||||
const {visit} = await import('unist-util-visit');
|
||||
|
||||
let transformed = false;
|
||||
let alreadyImported = false;
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
"@docusaurus/utils": "3.0.0-rc.0",
|
||||
"@docusaurus/utils-common": "3.0.0-rc.0",
|
||||
"@docusaurus/utils-validation": "3.0.0-rc.0",
|
||||
"@mdx-js/react": "^2.1.5",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
"copy-text-to-clipboard": "^3.2.0",
|
||||
"infima": "0.2.0-alpha.43",
|
||||
|
|
|
@ -325,6 +325,7 @@ serializers
|
|||
setaf
|
||||
setext
|
||||
shiki
|
||||
shortcodes
|
||||
showinfo
|
||||
sida
|
||||
simen
|
||||
|
|
|
@ -11,7 +11,7 @@ image: ./img/social-card.png
|
|||
|
||||
Docusaurus v3 comes with a few **breaking changes**, many of which can be **handled today under Docusaurus v2**. Preparing your site ahead of time can be done incrementally, and will make it easier to upgrade to v3.
|
||||
|
||||
The most important Docusaurus v3 breaking change is the [**upgrade to MDX v2**](https://mdxjs.com/blog/v2/), which will compile your Markdown content more strictly and with subtle differences.
|
||||
The main breaking change is the upgrade from MDX v1 to MDX v3. Read the [**MDX v2**](https://mdxjs.com/blog/v2/) and [**MDX v3**](https://mdxjs.com/blog/v3/) release notes for details. MDX will now compile your Markdown content **more strictly** and with **subtle differences**.
|
||||
|
||||
This article will mostly focus on how to prepare your content for this new MDX version, and will also list a few other breaking changes that you can handle today.
|
||||
|
||||
|
@ -41,19 +41,19 @@ Depending on the complexity of your site, it may be a good idea to adopt the [vi
|
|||
|
||||
We also recommend using the `.mdx` extension whenever you use JSX, `import`, or `export` (i.e. MDX features) inside a Markdown file. It is semantically more correct and improves compatibility with external tools (IDEs, formatters, linters, etc.). In future versions of Docusaurus, `.md` files will be parsed as standard [CommonMark](https://commonmark.org/), which does not support these features. In Docusaurus v3, `.md` files keep being compiled as MDX files, but it will be possible to [opt-in for CommonMark](https://github.com/facebook/docusaurus/issues/3018).
|
||||
|
||||
## Preparing content for MDX v2
|
||||
## Preparing content for MDX v3
|
||||
|
||||
MDX is a major dependency of Docusaurus responsible for compiling your `.md` and `.mdx` files to React components.
|
||||
|
||||
MDX v2 is much better, but also comes with changes that probably require you to refactor your content a bit. MDX v2 is stricter, and some components that compiled fine under v1 might now fail to compile under v2, most likely because of `{` and `<` characters.
|
||||
MDX v3 is much better, but also comes with changes that probably require you to refactor your content a bit. MDX v3 is stricter, and some components that compiled fine under v1 might now fail to compile under v3, most likely because of `{` and `<` characters.
|
||||
|
||||
Upgrading MDX comes with all the breaking changes documented on the [MDX v2 release blog post](https://mdxjs.com/blog/v2/). The [MDX v2 migration guide](https://mdxjs.com/migrating/v2/) has a section on how to [update MDX files](https://mdxjs.com/migrating/v2/#update-mdx-files) that will be particularly relevant to us. Also make sure to read the [Troubleshooting MDX](https://mdxjs.com/docs/troubleshooting-mdx/) page that can help you interpret common MDX error messages.
|
||||
Upgrading MDX comes with all the breaking changes documented on the [MDX v2](https://mdxjs.com/blog/v2/) and [MDX v3](https://mdxjs.com/blog/v3/) release blog posts. Most breaking changes come from MDX v2. The [MDX v2 migration guide](https://mdxjs.com/migrating/v2/) has a section on how to [update MDX files](https://mdxjs.com/migrating/v2/#update-mdx-files) that will be particularly relevant to us. Also make sure to read the [Troubleshooting MDX](https://mdxjs.com/docs/troubleshooting-mdx/) page that can help you interpret common MDX error messages.
|
||||
|
||||
Make sure to also read our updated [**MDX and React**](/docs/3.0.0-rc.0/markdown-features/react) documentation page.
|
||||
|
||||
:::tip Ask for help
|
||||
|
||||
We have a dedicated [MDX v2 - Upgrade Support](https://github.com/facebook/docusaurus/discussions/9053) discussion.
|
||||
We have a dedicated [MDX v3 - Upgrade Support](https://github.com/facebook/docusaurus/discussions/9053) discussion.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -63,23 +63,23 @@ The MDX playground is your new best friend. It permits to understand how your co
|
|||
|
||||
Each MDX version comes with its own playground:
|
||||
|
||||
- [MDX v1 playground](https://mdx-git-renovate-babel-monorepo-mdx.vercel.app/playground/)
|
||||
- [MDX v2 playground](https://mdxjs.com/playground/)
|
||||
- [MDX playground - current version](https://mdxjs.com/playground/)
|
||||
- [MDX playground - v1](https://mdx-git-renovate-babel-monorepo-mdx.vercel.app/playground/)
|
||||
|
||||
<details>
|
||||
<summary>Configuring MDX v2 playground options for Docusaurus</summary>
|
||||
<summary>Configuring the MDX playground options for Docusaurus</summary>
|
||||
|
||||
To obtain a compilation behavior similar to what Docusaurus v2 uses, please turn on these options on the [MDX v2 playground](https://mdxjs.com/playground/):
|
||||
To obtain a compilation behavior similar to what Docusaurus v2 uses, please turn on these options on the [MDX playground](https://mdxjs.com/playground/):
|
||||
|
||||
- Use `MDX`
|
||||
- Use `remark-gfm`
|
||||
- Use `remark-directive`
|
||||
|
||||

|
||||

|
||||
|
||||
</details>
|
||||
|
||||
Using the two MDX playgrounds side-by-side, you will soon notice that some content is compiled differently or fails to compile in v2.
|
||||
Using the two MDX playgrounds side-by-side, you will soon notice that some content is compiled differently or fails to compile in v3.
|
||||
|
||||
:::tip Making your content future-proof
|
||||
|
||||
|
@ -89,7 +89,7 @@ The goal will be to refactor your problematic content so that it **works fine wi
|
|||
|
||||
### Using the MDX checker CLI
|
||||
|
||||
We provide a [docusaurus-mdx-checker](https://github.com/slorber/docusaurus-mdx-checker) CLI that permits to easily spot problematic content. Run this command today on your Docusaurus v2 site to obtain a list of files that will fail to compile under MDX v2.
|
||||
We provide a [docusaurus-mdx-checker](https://github.com/slorber/docusaurus-mdx-checker) CLI that permits to easily spot problematic content. Run this command today on your Docusaurus v2 site to obtain a list of files that will fail to compile under MDX v3.
|
||||
|
||||
```bash
|
||||
npx docusaurus-mdx-checker
|
||||
|
@ -101,7 +101,7 @@ For each compilation issue, the CLI will log the file path and a line number to
|
|||
|
||||
:::tip
|
||||
|
||||
Use this CLI to estimate of how much work will be required to make your content compatible with MDX v2.
|
||||
Use this CLI to estimate of how much work will be required to make your content compatible with MDX v3.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -115,7 +115,7 @@ It will not report subtle compilation changes that do not produce errors but can
|
|||
|
||||
### Common MDX problems
|
||||
|
||||
We upgraded a few Docusaurus sites to Docusaurus v3 and MDX v2:
|
||||
We upgraded a few Docusaurus sites to Docusaurus v3 and MDX v3:
|
||||
|
||||
- [Docusaurus PR](https://github.com/facebook/docusaurus/pull/8288)
|
||||
- [React-Native PR](https://github.com/facebook/react-native-website/pull/3780)
|
||||
|
@ -125,7 +125,7 @@ These upgrades permitted us to aggregate the most common content problems, and d
|
|||
|
||||
#### Bad usage of `{`
|
||||
|
||||
The `{` character is used for opening [JavaScript expressions](https://mdxjs.com/docs/what-is-mdx/#expressions). MDX v2 will now fail if what you put inside `{expression}` is not a valid expression.
|
||||
The `{` character is used for opening [JavaScript expressions](https://mdxjs.com/docs/what-is-mdx/#expressions). MDX will now fail if what you put inside `{expression}` is not a valid expression.
|
||||
|
||||
```md title="example.md"
|
||||
The object shape looks like {username: string, age: number}
|
||||
|
@ -149,7 +149,7 @@ Available options to fix this error:
|
|||
|
||||
#### Bad usage of `<`
|
||||
|
||||
The `<` character is used for opening [JSX tags](https://mdxjs.com/docs/what-is-mdx/#jsx). MDX v2 will now fail if it thinks your JSX is invalid.
|
||||
The `<` character is used for opening [JSX tags](https://mdxjs.com/docs/what-is-mdx/#jsx). MDX will now fail if it thinks your JSX is invalid.
|
||||
|
||||
```md title="example.md"
|
||||
Use Android version <5
|
||||
|
@ -181,7 +181,7 @@ Available options to fix this error:
|
|||
|
||||
#### Bad usage of GFM Autolink
|
||||
|
||||
Docusaurus supports [GitHub Flavored Markdown (GFM)](https://github.github.com/gfm/), but [autolink](https://github.github.com/gfm/#autolinks) using the `<link>` syntax is not supported anymore by MDX v2.
|
||||
Docusaurus supports [GitHub Flavored Markdown (GFM)](https://github.github.com/gfm/), but [autolink](https://github.github.com/gfm/#autolinks) using the `<link>` syntax is not supported anymore by MDX.
|
||||
|
||||
```md title="example.md"
|
||||
<sebastien@thisweekinreact.com>
|
||||
|
@ -246,11 +246,11 @@ For any other element, **use upper-case names**.
|
|||
|
||||
#### Unintended extra paragraphs
|
||||
|
||||
In MDX v2, it is now possible to interleave JSX and Markdown more easily without requiring extra line breaks. Writing content on multiple lines can also produce new expected `<p>` tags.
|
||||
In MDX, it is now possible to interleave JSX and Markdown more easily without requiring extra line breaks. Writing content on multiple lines can also produce new expected `<p>` tags.
|
||||
|
||||
:::danger visual difference
|
||||
|
||||
See how this content is rendered differently by MDX v1 and v2.
|
||||
See how this content is rendered differently by MDX v1 and v3.
|
||||
|
||||
```md title="example.md"
|
||||
<div>Some **Markdown** content</div>
|
||||
|
@ -266,7 +266,7 @@ See how this content is rendered differently by MDX v1 and v2.
|
|||
```
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```html title="MDX v2 output"
|
||||
```html title="MDX v3 output"
|
||||
<div>Some <strong>Markdown</strong> content</div>
|
||||
<div><p>Some <strong>Markdown</strong> content</p></div></div>
|
||||
```
|
||||
|
@ -334,7 +334,7 @@ conf is great
|
|||
|
||||
#### Unsupported indented code blocks
|
||||
|
||||
MDX v2 does not transform indented text as code blocks anymore.
|
||||
MDX does not transform indented text as code blocks anymore.
|
||||
|
||||
```md title="example.md"
|
||||
console.log("hello");
|
||||
|
@ -342,7 +342,7 @@ MDX v2 does not transform indented text as code blocks anymore.
|
|||
|
||||
:::danger Visual change
|
||||
|
||||
The upgrade does not generally produce new MDX v2 compilation errors, but can lead to content being rendered in an unexpected way because there isn't a code block anymore.
|
||||
The upgrade does not generally produce new MDX compilation errors, but can lead to content being rendered in an unexpected way because there isn't a code block anymore.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -543,7 +543,7 @@ For most sites, the upgrade should be easy. If you prepared your site ahead of t
|
|||
- "@mdx-js/react": "^1.6.22",
|
||||
+ "@docusaurus/core": "3.0.0-beta.0",
|
||||
+ "@docusaurus/preset-classic": "3.0.0-beta.0",
|
||||
+ "@mdx-js/react": "^2.3.0",
|
||||
+ "@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
"prism-react-renderer": "^1.3.5",
|
||||
- "react": "^17.0.2",
|
||||
|
@ -564,9 +564,9 @@ We will be there to help you upgrade through the following support channels:
|
|||
|
||||
- [Docusaurus v3 - Upgrade Support](https://github.com/facebook/docusaurus/discussions/9336)
|
||||
- [Docusaurus v3 - Discord channel #migration-v2-to-v3](https://discord.com/channels/398180168688074762/1154771869094912090)
|
||||
- [MDX v2 - Upgrade Support](https://github.com/facebook/docusaurus/discussions/9053)
|
||||
- [MDX v2 - Remark/Rehype Plugins Support](https://github.com/facebook/docusaurus/discussions/9337)
|
||||
- [MDX v2 - Discord channel #migration-mdx-v2](https://discord.com/channels/398180168688074762/1116724556976111616)
|
||||
- [MDX v3 - Upgrade Support](https://github.com/facebook/docusaurus/discussions/9053)
|
||||
- [MDX v3 - Remark/Rehype Plugins Support](https://github.com/facebook/docusaurus/discussions/9337)
|
||||
- [MDX v3 - Discord channel #migration-mdx-v3](https://discord.com/channels/398180168688074762/1116724556976111616)
|
||||
|
||||
Alternatively, you can look for a paid [Docusaurus Service Provider](https://github.com/facebook/docusaurus/discussions/9281) to execute this upgrade for you. If your site is open source, you can also ask our community for [free, benevolent help](https://github.com/facebook/docusaurus/discussions/9283).
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ This article introduces a **visual regression testing** workflow based on [**Git
|
|||
|
||||
This workflow has been tested while upgrading Docusaurus v2 to v3, and already helped catch a few visual regressions on sites such as [React Native](https://reactnative.dev/), [Jest](https://jestjs.io/), and the [Docusaurus](https://docusaurus.io/) site itself.
|
||||
|
||||
Docusaurus v3 comes with infrastructure changes and major dependency upgrades such as [MDX v2](https://mdxjs.com/blog/v2/) and [React 18](https://react.dev/blog/2022/03/29/react-v18), which can produce unexpected side effects. It would have been difficult to notice all the visual regressions without such a workflow. That's why we encourage site owners to consider adopting visual regression testing, especially for highly customized sites.
|
||||
Docusaurus v3 comes with infrastructure changes and major dependency upgrades such as [MDX v3](https://mdxjs.com/blog/v3/) and [React 18](https://react.dev/blog/2022/03/29/react-v18), which can produce unexpected side effects. It would have been difficult to notice all the visual regressions without such a workflow. That's why we encourage site owners to consider adopting visual regression testing, especially for highly customized sites.
|
||||
|
||||
## Workflow overview
|
||||
|
||||
|
|
|
@ -459,7 +459,7 @@ export default {
|
|||
| `format` | `'mdx' \| 'md' \| 'detect'` | `'mdx'` | The default parser format to use for Markdown content. Using 'detect' will select the appropriate format automatically based on file extensions: `.md` vs `.mdx`. |
|
||||
| `mermaid` | `boolean` | `false` | When `true`, allows Docusaurus to render Markdown code blocks with `mermaid` language as Mermaid diagrams. |
|
||||
| `preprocessor` | `MarkdownPreprocessor` | `undefined` | Gives you the ability to alter the Markdown content string before parsing. Use it as a last-resort escape hatch or workaround: it is almost always better to implement a Remark/Rehype plugin. |
|
||||
| `mdx1Compat` | `MDX1CompatOptions` | `{comments: true, admonitions: true, headingIds: true}` | Compatibility options to make it easier to upgrade to Docusaurus v3+. See the [MDX 2 PR for details](https://github.com/facebook/docusaurus/pull/8288). |
|
||||
| `mdx1Compat` | `MDX1CompatOptions` | `{comments: true, admonitions: true, headingIds: true}` | Compatibility options to make it easier to upgrade to Docusaurus v3+. |
|
||||
|
||||
```mdx-code-block
|
||||
</APITable>
|
||||
|
|
|
@ -54,12 +54,12 @@ $$
|
|||
To enable KaTeX, you need to install `remark-math` and `rehype-katex` plugins.
|
||||
|
||||
```bash npm2yarn
|
||||
npm install --save remark-math@5 rehype-katex@6
|
||||
npm install --save remark-math@6 rehype-katex@7
|
||||
```
|
||||
|
||||
:::warning
|
||||
|
||||
Make sure to use `remark-math >= 5` and `rehype-katex >= 6` for Docusaurus v3 (using MDX v2).
|
||||
Make sure to use `remark-math 6` and `rehype-katex 7` for Docusaurus v3 (using MDX v3). We can't guarantee other versions will work.
|
||||
|
||||
:::
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import TabItem from '@theme/TabItem';
|
|||
import styles from './markdown-features-react.module.css';
|
||||
```
|
||||
|
||||
Docusaurus has built-in support for [MDX v2](https://mdxjs.com/), which allows you to write JSX within your Markdown files and render them as React components.
|
||||
Docusaurus has built-in support for [MDX](https://mdxjs.com/), which allows you to write JSX within your Markdown files and render them as React components.
|
||||
|
||||
Check out the [MDX docs](https://mdxjs.com/) to see what fancy stuff you can do with MDX.
|
||||
|
||||
|
@ -194,7 +194,7 @@ I can conveniently use <Highlight color="#25c2a0">Docusaurus green</Highlight> e
|
|||
|
||||
We use **upper-case** tag names like `Highlight` on purpose.
|
||||
|
||||
From MDX v2+ onward (Docusaurus v3+), lower-case tag names are always rendered as native html elements, and will not use any component mapping you provide.
|
||||
From MDX v3+ onward (Docusaurus v3+), lower-case tag names are always rendered as native html elements, and will not use any component mapping you provide.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -227,7 +227,7 @@ If you don't wrap your imported MDX with `MDXContent`, the global scope will not
|
|||
|
||||
### Markdown and JSX interoperability {#markdown-and-jsx-interoperability}
|
||||
|
||||
Docusaurus v3 is using [MDX v2](https://mdxjs.com/blog/v2/).
|
||||
Docusaurus v3 is using [MDX v3](https://mdxjs.com/blog/v3/).
|
||||
|
||||
The [MDX syntax](https://mdxjs.com/docs/what-is-mdx/#mdx-syntax) is mostly compatible with [CommonMark](https://commonmark.org/), but is much stricter because your `.mdx` files can use JSX and are compiled into real React components (check the [playground](https://mdxjs.com/playground/)).
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ Docusaurus v3 is a new **major version**, including **breaking changes** requiri
|
|||
|
||||
This is not a full rewrite, and the breaking changes are relatively easy to handle. The simplest sites will eventually upgrade by simply updating their npm dependencies.
|
||||
|
||||
The main breaking change is the [**upgrade to MDX v2**](https://mdxjs.com/blog/v2/), which will compile your Markdown content **more strictly** and with **subtle differences**.
|
||||
The main breaking change is the upgrade from MDX v1 to MDX v3. Read the [**MDX v2**](https://mdxjs.com/blog/v2/) and [**MDX v3**](https://mdxjs.com/blog/v3/) release notes for details. MDX will now compile your Markdown content **more strictly** and with **subtle differences**.
|
||||
|
||||
:::tip Before upgrading
|
||||
|
||||
|
@ -35,10 +35,11 @@ Docusaurus v3 now uses the following dependencies:
|
|||
|
||||
- Node.js v18.0+
|
||||
- React v18.0+
|
||||
- MDX v2.0+
|
||||
- MDX v3.0+
|
||||
- TypeScript v5.0+
|
||||
- prism-react-renderer v2.0+
|
||||
- react-live v4.0+
|
||||
- remark-emoji v4.0+
|
||||
- mermaid v10.4+
|
||||
|
||||
:::warning Upgrading community plugins
|
||||
|
@ -61,7 +62,7 @@ A typical `package.json` dependency upgrade example:
|
|||
+ "@docusaurus/preset-classic": "3.0.0",
|
||||
// upgrade to MDX v2
|
||||
- "@mdx-js/react": "^1.6.22",
|
||||
+ "@mdx-js/react": "^2.3.0",
|
||||
+ "@mdx-js/react": "^3.0.0",
|
||||
// upgrade to prism-react-renderer v2.0+
|
||||
- "prism-react-renderer": "^1.3.5",
|
||||
+ "prism-react-renderer": "^2.1.0",
|
||||
|
@ -108,7 +109,7 @@ For TypeScript users:
|
|||
|
||||
MDX is a major dependency of Docusaurus responsible for compiling your `.md` and `.mdx` files to React components.
|
||||
|
||||
The transition from MDX v1 to MDX v2 is the **main challenge** to the adoption of Docusaurus v3.
|
||||
The transition from MDX v1 to MDX v3 is the **main challenge** to the adoption of Docusaurus v3. Most breaking changes come from MDX v2, and MDX v3 is a relatively small release.
|
||||
|
||||
Some documents that compiled successfully under Docusaurus v2 might now **fail to compile** under Docusaurus v3.
|
||||
|
||||
|
@ -128,7 +129,7 @@ For large sites where a manual review of all pages is complicated, we recommend
|
|||
|
||||
:::
|
||||
|
||||
Upgrading MDX comes with all the breaking changes documented on the [MDX v2 release blog post](https://mdxjs.com/blog/v2/). The [MDX v2 migration guide](https://mdxjs.com/migrating/v2/) has a section on how to [update MDX files](https://mdxjs.com/migrating/v2/#update-mdx-files) that will be particularly relevant to us. Also make sure to read the [Troubleshooting MDX](https://mdxjs.com/docs/troubleshooting-mdx/) page that can help you interpret common MDX error messages.
|
||||
Upgrading MDX comes with all the breaking changes documented on the [MDX v2](https://mdxjs.com/blog/v2/) and [MDX v3](https://mdxjs.com/blog/v3/) release blog posts. Most breaking changes come from MDX v2. The [MDX v2 migration guide](https://mdxjs.com/migrating/v2/) has a section on how to [update MDX files](https://mdxjs.com/migrating/v2/#update-mdx-files) that will be particularly relevant to us. Also make sure to read the [Troubleshooting MDX](https://mdxjs.com/docs/troubleshooting-mdx/) page that can help you interpret common MDX error messages.
|
||||
|
||||
Make sure to also read our updated [**MDX and React**](../guides/markdown-features/markdown-features-react.mdx) documentation page.
|
||||
|
||||
|
@ -136,21 +137,19 @@ Make sure to also read our updated [**MDX and React**](../guides/markdown-featur
|
|||
|
||||
The MDX playground is your new best friend. It permits to understand how your content is **compiled to React components**, and troubleshoot compilation or rendering issues in isolation.
|
||||
|
||||
Each MDX version comes with its own playground:
|
||||
|
||||
- [MDX v1 playground](https://mdx-git-renovate-babel-monorepo-mdx.vercel.app/playground/)
|
||||
- [MDX v2 playground](https://mdxjs.com/playground/)
|
||||
- [MDX playground - current version](https://mdxjs.com/playground/)
|
||||
- [MDX playground - v1](https://mdx-git-renovate-babel-monorepo-mdx.vercel.app/playground/)
|
||||
|
||||
<details>
|
||||
<summary>Configuring the MDX v2 playground options for Docusaurus</summary>
|
||||
<summary>Configuring the MDX playground options for Docusaurus</summary>
|
||||
|
||||
To obtain a compilation behavior similar to what Docusaurus v2 uses, please turn on these options on the [MDX v2 playground](https://mdxjs.com/playground/):
|
||||
To obtain a compilation behavior similar to what Docusaurus v2 uses, please turn on these options on the [MDX playground](https://mdxjs.com/playground/):
|
||||
|
||||
- Use `MDX`
|
||||
- Use `remark-gfm`
|
||||
- Use `remark-directive`
|
||||
|
||||

|
||||

|
||||
|
||||
</details>
|
||||
|
||||
|
@ -164,7 +163,7 @@ The goal will be to refactor your problematic content so that it **works fine wi
|
|||
|
||||
### Using the MDX checker CLI
|
||||
|
||||
We provide a [docusaurus-mdx-checker](https://github.com/slorber/docusaurus-mdx-checker) CLI that permits to easily spot problematic content. Run this command on your site to obtain a list of files that will fail to compile under MDX v2.
|
||||
We provide a [docusaurus-mdx-checker](https://github.com/slorber/docusaurus-mdx-checker) CLI that permits to easily spot problematic content. Run this command on your site to obtain a list of files that will fail to compile under MDX v3.
|
||||
|
||||
```bash
|
||||
npx docusaurus-mdx-checker
|
||||
|
@ -176,7 +175,7 @@ For each compilation issue, the CLI will log the file path and a line number to
|
|||
|
||||
:::tip
|
||||
|
||||
Use this CLI to estimate of how much work will be required to make your content compatible with MDX v2.
|
||||
Use this CLI to estimate of how much work will be required to make your content compatible with MDX v3.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -190,13 +189,13 @@ It will not report subtle compilation changes that do not produce errors but can
|
|||
|
||||
### Common MDX problems
|
||||
|
||||
Docusaurus cannot document exhaustively all the changes coming with MDX v2. That's the responsibility of the [MDX v2 migration guide](https://mdxjs.com/migrating/v2/).
|
||||
Docusaurus cannot document exhaustively all the changes coming with MDX. That's the responsibility of the [MDX v2](https://mdxjs.com/migrating/v2/) and [MDX v3](https://mdxjs.com/migrating/v3/) migration guides.
|
||||
|
||||
However, by upgrading a few Docusaurus sites, we noticed that most of the issues come down to only a few cases that we have documented for you.
|
||||
|
||||
#### Bad usage of `{`
|
||||
|
||||
The `{` character is used for opening [JavaScript expressions](https://mdxjs.com/docs/what-is-mdx/#expressions). MDX v2 will now fail if what you put inside `{expression}` is not a valid expression.
|
||||
The `{` character is used for opening [JavaScript expressions](https://mdxjs.com/docs/what-is-mdx/#expressions). MDX will now fail if what you put inside `{expression}` is not a valid expression.
|
||||
|
||||
```md title="example.md"
|
||||
The object shape looks like {username: string, age: number}
|
||||
|
@ -220,7 +219,7 @@ Available options to fix this error:
|
|||
|
||||
#### Bad usage of `<`
|
||||
|
||||
The `<` character is used for opening [JSX tags](https://mdxjs.com/docs/what-is-mdx/#jsx). MDX v2 will now fail if it thinks your JSX is invalid.
|
||||
The `<` character is used for opening [JSX tags](https://mdxjs.com/docs/what-is-mdx/#jsx). MDX will now fail if it thinks your JSX is invalid.
|
||||
|
||||
```md title="example.md"
|
||||
Use Android version <5
|
||||
|
@ -252,7 +251,7 @@ Available options to fix this error:
|
|||
|
||||
#### Bad usage of GFM Autolink
|
||||
|
||||
Docusaurus supports [GitHub Flavored Markdown (GFM)](https://github.github.com/gfm/), but [autolink](https://github.github.com/gfm/#autolinks) using the `<link>` syntax is not supported anymore by MDX v2.
|
||||
Docusaurus supports [GitHub Flavored Markdown (GFM)](https://github.github.com/gfm/), but [autolink](https://github.github.com/gfm/#autolinks) using the `<link>` syntax is not supported anymore by MDX.
|
||||
|
||||
```md title="example.md"
|
||||
<sebastien@thisweekinreact.com>
|
||||
|
@ -317,11 +316,11 @@ For any other element, **use upper-case names**.
|
|||
|
||||
#### Unintended extra paragraphs
|
||||
|
||||
In MDX v2, it is now possible to interleave JSX and Markdown more easily without requiring extra line breaks. Writing content on multiple lines can also produce new expected `<p>` tags.
|
||||
In MDX v3, it is now possible to interleave JSX and Markdown more easily without requiring extra line breaks. Writing content on multiple lines can also produce new expected `<p>` tags.
|
||||
|
||||
:::danger visual difference
|
||||
|
||||
See how this content is rendered differently by MDX v1 and v2.
|
||||
See how this content is rendered differently by MDX v1 and v3.
|
||||
|
||||
```md title="example.md"
|
||||
<div>Some **Markdown** content</div>
|
||||
|
@ -337,7 +336,7 @@ See how this content is rendered differently by MDX v1 and v2.
|
|||
```
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```html title="MDX v2 output"
|
||||
```html title="MDX v3 output"
|
||||
<div>Some <strong>Markdown</strong> content</div>
|
||||
<div><p>Some <strong>Markdown</strong> content</p></div></div>
|
||||
```
|
||||
|
@ -403,7 +402,7 @@ conf is great
|
|||
|
||||
#### Unsupported indented code blocks
|
||||
|
||||
MDX v2 does not transform indented text as code blocks anymore.
|
||||
MDX does not transform indented text as code blocks anymore.
|
||||
|
||||
```md title="example.md"
|
||||
console.log("hello");
|
||||
|
@ -411,7 +410,7 @@ MDX v2 does not transform indented text as code blocks anymore.
|
|||
|
||||
:::danger Visual change
|
||||
|
||||
The upgrade does not generally produce new MDX v2 compilation errors, but can lead to content being rendered in an unexpected way because there isn't a code block anymore.
|
||||
The upgrade does not generally produce new MDX compilation errors, but can lead to content being rendered in an unexpected way because there isn't a code block anymore.
|
||||
|
||||
:::
|
||||
|
||||
|
@ -467,7 +466,7 @@ If you created custom Remark or Rehype plugins, you may need to refactor those,
|
|||
|
||||
## Other Breaking Changes
|
||||
|
||||
Apart the MDX v2 upgrade, here is an exhaustive list of breaking changes coming with Docusaurus v3.
|
||||
Apart the MDX v3 upgrade, here is an exhaustive list of breaking changes coming with Docusaurus v3.
|
||||
|
||||
### Node.js v18.0
|
||||
|
||||
|
@ -578,6 +577,18 @@ However, this is a new major library version containing breaking changes, and we
|
|||
|
||||
:::
|
||||
|
||||
### remark-emoji v4.0+
|
||||
|
||||
Docusaurus v3 upgrades [`prism-react-renderer`](https://github.com/rhysd/remark-emoji) to v4.0+. This library is to support `:emoji:` shortcuts in Markdown.
|
||||
|
||||
:::info How to upgrade
|
||||
|
||||
Most Docusaurus users have nothing to do. Users of emoji shortcodes should read the [changelog](https://github.com/rhysd/remark-emoji/blob/master/CHANGELOG.md) and double-check their emojis keep rendering as expected.
|
||||
|
||||
> **Breaking Change** Update [node-emoji](https://www.npmjs.com/package/node-emoji) from v1 to v2. This change introduces support for many new emojis and removes old emoji short codes which are no longer valid on GitHub.
|
||||
|
||||
:::
|
||||
|
||||
### Mermaid v10.4+
|
||||
|
||||
For users of the `@docusaurus/theme-mermaid` package, Docusaurus v3 upgrades [`mermaid`](https://github.com/mermaid-js/mermaid) to v10.4+.
|
||||
|
@ -800,11 +811,26 @@ We recommend using the `.mdx` extension whenever you use JSX, `import`, or `expo
|
|||
|
||||
In future versions of Docusaurus, `.md` files will be parsed as standard [CommonMark](https://commonmark.org/), which does not support these features. In Docusaurus v3, `.md` files keep being compiled as MDX files, but it will be possible to [opt-in for CommonMark](https://github.com/facebook/docusaurus/issues/3018).
|
||||
|
||||
### Upgrading math packages
|
||||
|
||||
If you use Docusaurus to render [Math Equations](../guides/markdown-features/markdown-features-math-equations.mdx), you should upgrade the MDX plugins.
|
||||
|
||||
Make sure to use `remark-math 6` and `rehype-katex 7` for Docusaurus v3 (using MDX v3). We can't guarantee other versions will work.
|
||||
|
||||
```diff package.json
|
||||
{
|
||||
- "remark-math": "^3.0.0",
|
||||
+ "remark-math": "^6.0.0",
|
||||
- "rehype-katex": "^5.0.0"
|
||||
+ "rehype-katex": "^7.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
## Ask For Help
|
||||
|
||||
In case of any upgrade problem, the first things to try are:
|
||||
|
||||
- make sure all your docs compile in the [MDX v2 playground](https://mdxjs.com/playground/), or using [`npx docusaurus-mdx-checker`](https://github.com/slorber/docusaurus-mdx-checker)
|
||||
- make sure all your docs compile in the [MDX playground](https://mdxjs.com/playground/), or using [`npx docusaurus-mdx-checker`](https://github.com/slorber/docusaurus-mdx-checker)
|
||||
- delete `node_modules` and run `npm install` again
|
||||
- run `docusaurus clear` to clear the caches
|
||||
- remove third-party plugins that might not support Docusaurus v3
|
||||
|
@ -814,9 +840,9 @@ Once you have tried that, you can ask for support through the following support
|
|||
|
||||
- [Docusaurus v3 - Upgrade Support](https://github.com/facebook/docusaurus/discussions/9336)
|
||||
- [Docusaurus v3 - Discord channel #migration-v2-to-v3](https://discord.com/channels/398180168688074762/1154771869094912090)
|
||||
- [MDX v2 - Upgrade Support](https://github.com/facebook/docusaurus/discussions/9053)
|
||||
- [MDX v2 - Remark/Rehype Plugins Support](https://github.com/facebook/docusaurus/discussions/9337)
|
||||
- [MDX v2 - Discord channel #migration-mdx-v2](https://discord.com/channels/398180168688074762/1116724556976111616)
|
||||
- [MDX v3 - Upgrade Support](https://github.com/facebook/docusaurus/discussions/9053)
|
||||
- [MDX v3 - Remark/Rehype Plugins Support](https://github.com/facebook/docusaurus/discussions/9337)
|
||||
- [MDX v3 - Discord channel #migration-mdx-v3](https://discord.com/channels/398180168688074762/1116724556976111616)
|
||||
|
||||
Please consider **our time is precious**. To ensure that your support request is not ignored, we kindly ask you to:
|
||||
|
||||
|
|
|
@ -62,10 +62,10 @@
|
|||
"react-lite-youtube-embed": "^2.3.52",
|
||||
"react-medium-image-zoom": "^5.1.6",
|
||||
"react-popper": "^2.3.0",
|
||||
"rehype-katex": "^6.0.3",
|
||||
"remark-math": "^5.1.1",
|
||||
"rehype-katex": "^7.0.0",
|
||||
"remark-math": "^6.0.0",
|
||||
"swc-loader": "^0.2.3",
|
||||
"unist-util-visit": "^2.0.3",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"webpack": "^5.88.1",
|
||||
"workbox-routing": "^6.6.1",
|
||||
"workbox-strategies": "^6.6.1"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import visit from 'unist-util-visit';
|
||||
import {visit} from 'unist-util-visit';
|
||||
|
||||
/**
|
||||
* Turns a "```js config-tabs" code block into a "plugin options" and a "preset
|
||||
|
|
Loading…
Add table
Reference in a new issue