import path from 'path'; import hljs from 'highlight.js'; import getContentType from './getContentType.js'; function escapeHTML(code) { return code .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } // These should probably be added to highlight.js auto-detection. const extLanguages = { map: 'json', mjs: 'javascript', tsbuildinfo: 'json', tsx: 'typescript', vue: 'html' }; function getLanguage(file) { // Try to guess the language based on the file extension. const ext = path.extname(file).substr(1); if (ext) { return extLanguages[ext] || ext; } const contentType = getContentType(file); if (contentType === 'text/plain') { return 'text'; } return null; } function getLines(code) { return code .split('\n') .map((line, index, array) => index === array.length - 1 ? line : line + '\n' ); } /** * Returns an array of HTML strings that highlight the given source code. */ export default function getHighlights(code, file) { const language = getLanguage(file); if (!language) { return null; } if (language === 'text') { return getLines(code).map(escapeHTML); } try { let continuation = false; const hi = getLines(code).map(line => { const result = hljs.highlight(language, line, false, continuation); continuation = result.top; return result; }); return hi.map(result => result.value.replace( //g, '' ) ); } catch (error) { // Probably an "unknown language" error. // console.error(error); return null; } }