ts-markdown-parser
Version:
TypeScript library that converts markdown to HTML (with code support).
96 lines • 4.73 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.highlightJSX = void 0;
const keywords_1 = require("../javascript/keywords");
const keywords_2 = require("../html/keywords");
const keywords_3 = require("./keywords");
const reservedKeywords = [...keywords_1.reservedKeywords, ...keywords_2.reservedKeywords];
/**
* Highlights JSX/TSX attributes within a JSX tag.
*
* @param {string} attributes - The string containing JSX attributes.
* @returns {string} - The highlighted attributes string.
*/
const highlightJSXAttributes = (attributes) => {
// Highlight attribute names
const attrNameRegex = /(\w+)=/g;
let highlightedAttrs = attributes.replace(attrNameRegex, '<span class="md-special">$1</span>=');
// Highlight attribute values (strings and expressions)
const attrValueRegex = /=(["'])(.*?)\1/g;
highlightedAttrs = highlightedAttrs.replace(attrValueRegex, '="<span class="md-special">$2</span>"');
// Highlight expressions within attribute values
const exprValueRegex = /=\{(.*?)\}/g;
highlightedAttrs = highlightedAttrs.replace(exprValueRegex, '={<span class="md-special">$1</span>}');
return highlightedAttrs;
};
/**
* Replaces reserved JavaScript and JSX keywords with highlighted spans.
*
* @param {string} text - The text to process.
* @returns {string} - The text with highlighted keywords.
*/
const replaceKeywords = (text) => {
return text.replace(/(<span[^>]*>.*?<\/span>)|(\b\w+\b)/g, (match, span, word) => {
if (span)
return span; // Skip already highlighted spans
if (word && reservedKeywords.includes(word)) {
return `<span class="md-keyword">${word}</span>`;
}
else if (word && keywords_3.reservedKeywords.includes(word)) {
return `<span class="md-decorator">${word}</span>`;
}
return word;
});
};
/**
* Highlights JSX (React/Next.js) code blocks with syntax highlighting.
*
* @param {string} code - The JSX code as a string.
* @returns {string} - The highlighted HTML string.
*/
const highlightJSX = (code) => {
// Step 1: Escape HTML entities
code = code.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/'/g, "'").replace(/"/g, """);
// Step 2: Check for incomplete comments
const hasOpenComment = /\/\*/.test(code);
const hasCloseComment = /\*\//.test(code);
if ((hasOpenComment && !hasCloseComment) || (!hasOpenComment && hasCloseComment)) {
return code; // Return early if comments are incomplete
}
// Step 3: Highlight comments (both single-line and multi-line)
const commentRegex = /(\/\/.*|\/\*[\s\S]*?\*\/)/g;
let highlighted = code.replace(commentRegex, '<span class="md-comment">$1</span>');
// Step 4: Highlight strings not inside comments
highlighted = highlighted.replace(/<span class="md-comment">.*?<\/span>|(["'`])(.*?)(\1)/g, (match, p1, p2, p3) => {
if (match.startsWith('<span class="md-comment">'))
return match;
return `<span class="md-string">${p1}${p2}${p3}</span>`;
});
// Step 5: Highlight regular expressions
const regexEqualsPattern = /=([\s+]?\/.*?\/[gimuy]*)/g;
highlighted = highlighted.replace(regexEqualsPattern, '=<span class="md-regex">$1</span>');
const regexTestPattern = /([\s+]?\/.*?\/[gimuy]*)\.test/g;
highlighted = highlighted.replace(regexTestPattern, '<span class="md-regex">$1</span>.test');
// Step 6: Highlight decorators (e.g., @Component)
const decoratorRegex = /(^|\s)@[\w]+/gm;
highlighted = highlighted.replace(decoratorRegex, '$1<span class="md-decorator">$&</span>');
// Step 7: Highlight JSX tags and attributes
// a. Highlight opening and closing tags
const jsxTagRegex = /<\/?([A-Z][A-Za-z0-9_]*)\b([^&]*?)>/g;
highlighted = highlighted.replace(jsxTagRegex, (match, p1, p2) => {
return `<<span class="md-decorator">${p1}</span>${highlightJSXAttributes(p2)}>`;
});
// b. Highlight self-closing tags
const jsxSelfClosingTagRegex = /<([A-Z][A-Za-z0-9_]*)\b([^&]*?)\/>/g;
highlighted = highlighted.replace(jsxSelfClosingTagRegex, (match, p1, p2) => {
return `<<span class="md-decorator">${p1}</span>${highlightJSXAttributes(p2)} />`;
});
// Step 8: Highlight embedded JavaScript expressions within JSX
const jsxExpressionRegex = /{([^}]+)}/g;
highlighted = highlighted.replace(jsxExpressionRegex, '<span class="md-special">{$1}</span>');
// Step 9: Highlight reserved keywords
highlighted = replaceKeywords(highlighted);
return highlighted;
};
exports.highlightJSX = highlightJSX;
//# sourceMappingURL=highlight.js.map