@podlite/to-jsx
Version:
Render Podlite markup as React JSX components
139 lines • 5.29 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractPlainAndDecorations = void 0;
const react_1 = __importStar(require("react"));
const schema_1 = require("@podlite/schema");
const shiki_1 = require("./shiki");
const fcodeToTag = {
B: 'strong',
I: 'em',
C: 'code',
U: 'u',
K: 'kbd',
};
const extractPlainAndDecorations = (nodes) => {
const decorations = [];
let plain = '';
const walk = (input) => {
if (input == null)
return;
if (typeof input === 'string') {
plain += input;
return;
}
if (Array.isArray(input)) {
for (const child of input)
walk(child);
return;
}
const node = input;
if (node.type === 'text' && typeof node.value === 'string') {
plain += node.value;
return;
}
if (node.type === 'verbatim' && typeof node.value === 'string') {
plain += node.value;
return;
}
if (node.type === 'fcode' && typeof node.name === 'string') {
const tagName = fcodeToTag[node.name] || 'span';
const start = plain.length;
walk(node.content);
const end = plain.length;
if (end > start) {
decorations.push({
start,
end,
tagName,
properties: { class: `fc-${node.name}` },
});
}
return;
}
if (node.content !== undefined) {
walk(node.content);
}
else if (typeof node.text === 'string') {
plain += node.text;
}
};
walk(nodes);
return { plain, decorations };
};
exports.extractPlainAndDecorations = extractPlainAndDecorations;
const HighlightedCode = react_1.default.memo(({ node, children, keyProp, ctx, id, wrap = 'pre-code' }) => {
const conf = (0, schema_1.makeAttrs)(node, ctx);
const caption = conf.exists('caption') ? conf.getFirstValue('caption') : null;
const lang = conf.getFirstValue('lang');
const [html, setHtml] = (0, react_1.useState)(null);
(0, react_1.useEffect)(() => {
if (!lang)
return;
let cancelled = false;
const highlight = async () => {
try {
const isDark = typeof document !== 'undefined' && document.body && document.body.className.toLowerCase().includes('dark');
const { plain, decorations } = (0, exports.extractPlainAndDecorations)(node.content);
const result = await (0, shiki_1.codeToThemedHtml)({
code: plain,
language: lang,
theme: isDark ? 'dark' : 'light',
decorations,
});
if (!cancelled)
setHtml(result);
}
catch (e) {
console.error('[podlite] shiki highlight error:', e);
}
};
highlight();
return () => {
cancelled = true;
};
}, [lang, node.content]);
const codeBody = html ? (react_1.default.createElement("code", { key: keyProp, className: "shiki", dangerouslySetInnerHTML: { __html: html } })) : (react_1.default.createElement("pre", { key: `${keyProp}-pre`, id: id },
react_1.default.createElement("code", { key: keyProp }, children)));
if (wrap === 'block') {
return (react_1.default.createElement("div", { className: "code-block", key: `${keyProp}-code-div` },
codeBody,
caption ? (react_1.default.createElement("div", { key: `${keyProp}-caption`, className: "caption" }, caption)) : null));
}
return codeBody;
});
HighlightedCode.displayName = 'HighlightedCode';
exports.default = HighlightedCode;
//# sourceMappingURL=HighlightedCode.js.map