1 |
|
2 |
|
3 |
|
4 |
|
5 | var __rest = (this && this.__rest) || function (s, e) {
|
6 | var t = {};
|
7 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
8 | t[p] = s[p];
|
9 | if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
10 | for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
11 | if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
12 | t[p[i]] = s[p[i]];
|
13 | }
|
14 | return t;
|
15 | };
|
16 | import { CodeMirrorEditor, Mode } from '@jupyterlab/codemirror';
|
17 | import { URLExt } from '@jupyterlab/coreutils';
|
18 | import { nullTranslator } from '@jupyterlab/translation';
|
19 | import { toArray } from '@lumino/algorithm';
|
20 | import escape from 'lodash.escape';
|
21 | import { marked } from 'marked';
|
22 | import { removeMath, replaceMath } from './latex';
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 | export function renderHTML(options) {
|
31 |
|
32 | let { host, source, trusted, sanitizer, resolver, linkHandler, shouldTypeset, latexTypesetter, translator } = options;
|
33 | translator = translator || nullTranslator;
|
34 | const trans = translator === null || translator === void 0 ? void 0 : translator.load('jupyterlab');
|
35 | let originalSource = source;
|
36 |
|
37 | if (!source) {
|
38 | host.textContent = '';
|
39 | return Promise.resolve(undefined);
|
40 | }
|
41 |
|
42 |
|
43 | if (!trusted) {
|
44 | originalSource = `${source}`;
|
45 | source = sanitizer.sanitize(source);
|
46 | }
|
47 |
|
48 | host.innerHTML = source;
|
49 | if (host.getElementsByTagName('script').length > 0) {
|
50 |
|
51 |
|
52 |
|
53 | if (trusted) {
|
54 | Private.evalInnerHTMLScriptTags(host);
|
55 | }
|
56 | else {
|
57 | const container = document.createElement('div');
|
58 | const warning = document.createElement('pre');
|
59 | warning.textContent = trans.__('This HTML output contains inline scripts. Are you sure that you want to run arbitrary Javascript within your JupyterLab session?');
|
60 | const runButton = document.createElement('button');
|
61 | runButton.textContent = trans.__('Run');
|
62 | runButton.onclick = event => {
|
63 | host.innerHTML = originalSource;
|
64 | Private.evalInnerHTMLScriptTags(host);
|
65 | if (host.firstChild) {
|
66 | host.removeChild(host.firstChild);
|
67 | }
|
68 | };
|
69 | container.appendChild(warning);
|
70 | container.appendChild(runButton);
|
71 | host.insertBefore(container, host.firstChild);
|
72 | }
|
73 | }
|
74 |
|
75 | Private.handleDefaults(host, resolver);
|
76 |
|
77 | let promise;
|
78 | if (resolver) {
|
79 | promise = Private.handleUrls(host, resolver, linkHandler);
|
80 | }
|
81 | else {
|
82 | promise = Promise.resolve(undefined);
|
83 | }
|
84 |
|
85 | return promise.then(() => {
|
86 | if (shouldTypeset && latexTypesetter) {
|
87 | latexTypesetter.typeset(host);
|
88 | }
|
89 | });
|
90 | }
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 | export function renderImage(options) {
|
99 |
|
100 | const { host, mimeType, source, width, height, needsBackground, unconfined } = options;
|
101 |
|
102 | host.textContent = '';
|
103 |
|
104 | const img = document.createElement('img');
|
105 |
|
106 | img.src = `data:${mimeType};base64,${source}`;
|
107 |
|
108 | if (typeof height === 'number') {
|
109 | img.height = height;
|
110 | }
|
111 | if (typeof width === 'number') {
|
112 | img.width = width;
|
113 | }
|
114 | if (needsBackground === 'light') {
|
115 | img.classList.add('jp-needs-light-background');
|
116 | }
|
117 | else if (needsBackground === 'dark') {
|
118 | img.classList.add('jp-needs-dark-background');
|
119 | }
|
120 | if (unconfined === true) {
|
121 | img.classList.add('jp-mod-unconfined');
|
122 | }
|
123 |
|
124 | host.appendChild(img);
|
125 |
|
126 | return Promise.resolve(undefined);
|
127 | }
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 | export function renderLatex(options) {
|
136 |
|
137 | const { host, source, shouldTypeset, latexTypesetter } = options;
|
138 |
|
139 | host.textContent = source;
|
140 |
|
141 | if (shouldTypeset && latexTypesetter) {
|
142 | latexTypesetter.typeset(host);
|
143 | }
|
144 |
|
145 | return Promise.resolve(undefined);
|
146 | }
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 | export async function renderMarkdown(options) {
|
155 |
|
156 | const { host, source } = options, others = __rest(options, ["host", "source"]);
|
157 |
|
158 | if (!source) {
|
159 | host.textContent = '';
|
160 | return;
|
161 | }
|
162 |
|
163 | const parts = removeMath(source);
|
164 |
|
165 | let html = await Private.renderMarked(parts['text']);
|
166 |
|
167 | html = replaceMath(html, parts['math']);
|
168 |
|
169 | await renderHTML(Object.assign({ host, source: html }, others));
|
170 |
|
171 | Private.headerAnchors(host);
|
172 | }
|
173 |
|
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 | export function renderSVG(options) {
|
181 |
|
182 | let { host, source, trusted, unconfined } = options;
|
183 |
|
184 | if (!source) {
|
185 | host.textContent = '';
|
186 | return Promise.resolve(undefined);
|
187 | }
|
188 |
|
189 | if (!trusted) {
|
190 | host.textContent =
|
191 | 'Cannot display an untrusted SVG. Maybe you need to run the cell?';
|
192 | return Promise.resolve(undefined);
|
193 | }
|
194 |
|
195 | const patt = '<svg[^>]+xmlns=[^>]+svg';
|
196 | if (source.search(patt) < 0) {
|
197 | source = source.replace('<svg', '<svg xmlns="http://www.w3.org/2000/svg"');
|
198 | }
|
199 |
|
200 | const img = new Image();
|
201 | img.src = `data:image/svg+xml,${encodeURIComponent(source)}`;
|
202 | host.appendChild(img);
|
203 | if (unconfined === true) {
|
204 | host.classList.add('jp-mod-unconfined');
|
205 | }
|
206 | return Promise.resolve();
|
207 | }
|
208 |
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 | function autolink(content) {
|
216 |
|
217 |
|
218 | const controlCodes = '\\u0000-\\u0020\\u007f-\\u009f';
|
219 | const webLinkRegex = new RegExp('(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' +
|
220 | controlCodes +
|
221 | '"]{2,}[^\\s' +
|
222 | controlCodes +
|
223 | '"\'(){}\\[\\],:;.!?]', 'ug');
|
224 | const nodes = [];
|
225 | let lastIndex = 0;
|
226 | let match;
|
227 | while (null != (match = webLinkRegex.exec(content))) {
|
228 | if (match.index !== lastIndex) {
|
229 | nodes.push(document.createTextNode(content.slice(lastIndex, match.index)));
|
230 | }
|
231 | let url = match[0];
|
232 |
|
233 | const lastChars = url.slice(-1);
|
234 | const endsWithGtLt = ['>', '<'].indexOf(lastChars) !== -1;
|
235 | const len = endsWithGtLt ? url.length - 1 : url.length;
|
236 | const anchor = document.createElement('a');
|
237 | url = url.slice(0, len);
|
238 | anchor.href = url.startsWith('www.') ? 'https://' + url : url;
|
239 | anchor.rel = 'noopener';
|
240 | anchor.target = '_blank';
|
241 | anchor.appendChild(document.createTextNode(url.slice(0, len)));
|
242 | nodes.push(anchor);
|
243 | lastIndex = match.index + len;
|
244 | }
|
245 | if (lastIndex !== content.length) {
|
246 | nodes.push(document.createTextNode(content.slice(lastIndex, content.length)));
|
247 | }
|
248 | return nodes;
|
249 | }
|
250 |
|
251 |
|
252 |
|
253 |
|
254 |
|
255 |
|
256 | function splitShallowNode(node, at) {
|
257 | var _a, _b;
|
258 | const pre = node.cloneNode();
|
259 | pre.textContent = (_a = node.textContent) === null || _a === void 0 ? void 0 : _a.substr(0, at);
|
260 | const post = node.cloneNode();
|
261 | post.textContent = (_b = node.textContent) === null || _b === void 0 ? void 0 : _b.substr(at);
|
262 | return {
|
263 | pre: pre,
|
264 | post: post
|
265 | };
|
266 | }
|
267 |
|
268 |
|
269 |
|
270 |
|
271 |
|
272 |
|
273 |
|
274 | export function renderText(options) {
|
275 | var _a, _b;
|
276 |
|
277 | const { host, sanitizer, source } = options;
|
278 |
|
279 | const content = sanitizer.sanitize(Private.ansiSpan(source), {
|
280 | allowedTags: ['span']
|
281 | });
|
282 |
|
283 | const pre = document.createElement('pre');
|
284 | pre.innerHTML = content;
|
285 | const preTextContent = pre.textContent;
|
286 | if (preTextContent) {
|
287 |
|
288 | const linkedNodes = autolink(preTextContent);
|
289 | let inAnchorElement = false;
|
290 | const combinedNodes = [];
|
291 | const preNodes = Array.from(pre.childNodes);
|
292 | while (preNodes.length && linkedNodes.length) {
|
293 |
|
294 |
|
295 | let preNode = preNodes.shift();
|
296 | let linkNode = linkedNodes.shift();
|
297 |
|
298 |
|
299 | if (typeof preNode === 'undefined') {
|
300 | combinedNodes.push(linkNode);
|
301 | break;
|
302 | }
|
303 | if (typeof linkNode === 'undefined') {
|
304 | combinedNodes.push(preNode);
|
305 | break;
|
306 | }
|
307 | let preLen = (_a = preNode.textContent) === null || _a === void 0 ? void 0 : _a.length;
|
308 | let linkLen = (_b = linkNode.textContent) === null || _b === void 0 ? void 0 : _b.length;
|
309 | if (preLen && linkLen) {
|
310 | if (preLen > linkLen) {
|
311 |
|
312 | let { pre: keep, post: postpone } = splitShallowNode(preNode, linkLen);
|
313 | preNodes.unshift(postpone);
|
314 | preNode = keep;
|
315 | }
|
316 | else if (linkLen > preLen) {
|
317 | let { pre: keep, post: postpone } = splitShallowNode(linkNode, preLen);
|
318 | linkedNodes.unshift(postpone);
|
319 | linkNode = keep;
|
320 | }
|
321 | }
|
322 | const lastCombined = combinedNodes[combinedNodes.length - 1];
|
323 |
|
324 |
|
325 |
|
326 | if (inAnchorElement &&
|
327 | linkNode.href ===
|
328 | lastCombined.href) {
|
329 | lastCombined.appendChild(preNode);
|
330 | }
|
331 | else {
|
332 |
|
333 | const isAnchor = linkNode.nodeType !== Node.TEXT_NODE;
|
334 |
|
335 | if (!isAnchor) {
|
336 | combinedNodes.push(preNode);
|
337 | inAnchorElement = false;
|
338 | }
|
339 | else {
|
340 |
|
341 |
|
342 |
|
343 | linkNode.textContent = '';
|
344 | linkNode.appendChild(preNode);
|
345 | combinedNodes.push(linkNode);
|
346 | inAnchorElement = true;
|
347 | }
|
348 | }
|
349 | }
|
350 |
|
351 | pre.innerHTML = '';
|
352 | for (const child of combinedNodes) {
|
353 | pre.appendChild(child);
|
354 | }
|
355 | }
|
356 | host.appendChild(pre);
|
357 |
|
358 | return Promise.resolve(undefined);
|
359 | }
|
360 |
|
361 |
|
362 |
|
363 | var Private;
|
364 | (function (Private) {
|
365 | |
366 |
|
367 |
|
368 |
|
369 |
|
370 |
|
371 |
|
372 |
|
373 | function evalInnerHTMLScriptTags(host) {
|
374 |
|
375 | const scripts = toArray(host.getElementsByTagName('script'));
|
376 |
|
377 | for (const script of scripts) {
|
378 |
|
379 | if (!script.parentNode) {
|
380 | continue;
|
381 | }
|
382 |
|
383 | const clone = document.createElement('script');
|
384 |
|
385 | const attrs = script.attributes;
|
386 | for (let i = 0, n = attrs.length; i < n; ++i) {
|
387 | const { name, value } = attrs[i];
|
388 | clone.setAttribute(name, value);
|
389 | }
|
390 |
|
391 | clone.textContent = script.textContent;
|
392 |
|
393 | script.parentNode.replaceChild(clone, script);
|
394 | }
|
395 | }
|
396 | Private.evalInnerHTMLScriptTags = evalInnerHTMLScriptTags;
|
397 | |
398 |
|
399 |
|
400 |
|
401 |
|
402 |
|
403 |
|
404 | function renderMarked(content) {
|
405 | initializeMarked();
|
406 | return new Promise((resolve, reject) => {
|
407 | marked(content, (err, content) => {
|
408 | if (err) {
|
409 | reject(err);
|
410 | }
|
411 | else {
|
412 | resolve(content);
|
413 | }
|
414 | });
|
415 | });
|
416 | }
|
417 | Private.renderMarked = renderMarked;
|
418 | |
419 |
|
420 |
|
421 | function handleDefaults(node, resolver) {
|
422 |
|
423 | const anchors = node.getElementsByTagName('a');
|
424 | for (let i = 0; i < anchors.length; i++) {
|
425 | const el = anchors[i];
|
426 |
|
427 |
|
428 | if (!(el instanceof HTMLAnchorElement)) {
|
429 | continue;
|
430 | }
|
431 | const path = el.href;
|
432 | const isLocal = resolver && resolver.isLocal
|
433 | ? resolver.isLocal(path)
|
434 | : URLExt.isLocal(path);
|
435 |
|
436 | if (!el.target) {
|
437 | el.target = isLocal ? '_self' : '_blank';
|
438 | }
|
439 |
|
440 | if (!isLocal) {
|
441 | el.rel = 'noopener';
|
442 | }
|
443 | }
|
444 |
|
445 | const imgs = node.getElementsByTagName('img');
|
446 | for (let i = 0; i < imgs.length; i++) {
|
447 | if (!imgs[i].alt) {
|
448 | imgs[i].alt = 'Image';
|
449 | }
|
450 | }
|
451 | }
|
452 | Private.handleDefaults = handleDefaults;
|
453 | |
454 |
|
455 |
|
456 |
|
457 |
|
458 |
|
459 |
|
460 |
|
461 |
|
462 |
|
463 |
|
464 | function handleUrls(node, resolver, linkHandler) {
|
465 |
|
466 | const promises = [];
|
467 |
|
468 | const nodes = node.querySelectorAll('*[src]');
|
469 | for (let i = 0; i < nodes.length; i++) {
|
470 | promises.push(handleAttr(nodes[i], 'src', resolver));
|
471 | }
|
472 |
|
473 | const anchors = node.getElementsByTagName('a');
|
474 | for (let i = 0; i < anchors.length; i++) {
|
475 | promises.push(handleAnchor(anchors[i], resolver, linkHandler));
|
476 | }
|
477 |
|
478 | const links = node.getElementsByTagName('link');
|
479 | for (let i = 0; i < links.length; i++) {
|
480 | promises.push(handleAttr(links[i], 'href', resolver));
|
481 | }
|
482 |
|
483 | return Promise.all(promises).then(() => undefined);
|
484 | }
|
485 | Private.handleUrls = handleUrls;
|
486 | |
487 |
|
488 |
|
489 | function headerAnchors(node) {
|
490 | var _a;
|
491 | const headerNames = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
492 | for (const headerType of headerNames) {
|
493 | const headers = node.getElementsByTagName(headerType);
|
494 | for (let i = 0; i < headers.length; i++) {
|
495 | const header = headers[i];
|
496 | header.id = ((_a = header.textContent) !== null && _a !== void 0 ? _a : '').replace(/ /g, '-');
|
497 | const anchor = document.createElement('a');
|
498 | anchor.target = '_self';
|
499 | anchor.textContent = '¶';
|
500 | anchor.href = '#' + header.id;
|
501 | anchor.classList.add('jp-InternalAnchorLink');
|
502 | header.appendChild(anchor);
|
503 | }
|
504 | }
|
505 | }
|
506 | Private.headerAnchors = headerAnchors;
|
507 | |
508 |
|
509 |
|
510 | async function handleAttr(node, name, resolver) {
|
511 | const source = node.getAttribute(name) || '';
|
512 | const isLocal = resolver.isLocal
|
513 | ? resolver.isLocal(source)
|
514 | : URLExt.isLocal(source);
|
515 | if (!source || !isLocal) {
|
516 | return;
|
517 | }
|
518 | try {
|
519 | const urlPath = await resolver.resolveUrl(source);
|
520 | let url = await resolver.getDownloadUrl(urlPath);
|
521 | if (URLExt.parse(url).protocol !== 'data:') {
|
522 |
|
523 |
|
524 | url += (/\?/.test(url) ? '&' : '?') + new Date().getTime();
|
525 | }
|
526 | node.setAttribute(name, url);
|
527 | }
|
528 | catch (err) {
|
529 |
|
530 |
|
531 | node.setAttribute(name, '');
|
532 | throw err;
|
533 | }
|
534 | }
|
535 | |
536 |
|
537 |
|
538 | function handleAnchor(anchor, resolver, linkHandler) {
|
539 |
|
540 |
|
541 | let href = anchor.getAttribute('href') || '';
|
542 | const isLocal = resolver.isLocal
|
543 | ? resolver.isLocal(href)
|
544 | : URLExt.isLocal(href);
|
545 |
|
546 | if (!href || !isLocal) {
|
547 | return Promise.resolve(undefined);
|
548 | }
|
549 |
|
550 | const hash = anchor.hash;
|
551 | if (hash) {
|
552 |
|
553 | if (hash === href) {
|
554 | anchor.target = '_self';
|
555 | return Promise.resolve(undefined);
|
556 | }
|
557 |
|
558 | href = href.replace(hash, '');
|
559 | }
|
560 |
|
561 | return resolver
|
562 | .resolveUrl(href)
|
563 | .then(urlPath => {
|
564 |
|
565 | const path = decodeURIComponent(urlPath);
|
566 |
|
567 | if (linkHandler) {
|
568 | linkHandler.handleLink(anchor, path, hash);
|
569 | }
|
570 |
|
571 | return resolver.getDownloadUrl(urlPath);
|
572 | })
|
573 | .then(url => {
|
574 |
|
575 | anchor.href = url + hash;
|
576 | })
|
577 | .catch(err => {
|
578 |
|
579 |
|
580 | anchor.href = '';
|
581 | });
|
582 | }
|
583 | let markedInitialized = false;
|
584 | |
585 |
|
586 |
|
587 | function initializeMarked() {
|
588 | if (markedInitialized) {
|
589 | return;
|
590 | }
|
591 | markedInitialized = true;
|
592 | marked.setOptions({
|
593 | gfm: true,
|
594 | sanitize: false,
|
595 |
|
596 | langPrefix: `cm-s-${CodeMirrorEditor.defaultConfig.theme} language-`,
|
597 | highlight: (code, lang, callback) => {
|
598 | const cb = (err, code) => {
|
599 | if (callback) {
|
600 | callback(err, code);
|
601 | }
|
602 | return code;
|
603 | };
|
604 | if (!lang) {
|
605 |
|
606 | return cb(null, code);
|
607 | }
|
608 | Mode.ensure(lang)
|
609 | .then(spec => {
|
610 | const el = document.createElement('div');
|
611 | if (!spec) {
|
612 | console.error(`No CodeMirror mode: ${lang}`);
|
613 | return cb(null, code);
|
614 | }
|
615 | try {
|
616 | Mode.run(code, spec.mime, el);
|
617 | return cb(null, el.innerHTML);
|
618 | }
|
619 | catch (err) {
|
620 | console.error(`Failed to highlight ${lang} code`, err);
|
621 | return cb(err, code);
|
622 | }
|
623 | })
|
624 | .catch(err => {
|
625 | console.error(`No CodeMirror mode: ${lang}`);
|
626 | console.error(`Require CodeMirror mode error: ${err}`);
|
627 | return cb(null, code);
|
628 | });
|
629 | return code;
|
630 | }
|
631 | });
|
632 | }
|
633 | const ANSI_COLORS = [
|
634 | 'ansi-black',
|
635 | 'ansi-red',
|
636 | 'ansi-green',
|
637 | 'ansi-yellow',
|
638 | 'ansi-blue',
|
639 | 'ansi-magenta',
|
640 | 'ansi-cyan',
|
641 | 'ansi-white',
|
642 | 'ansi-black-intense',
|
643 | 'ansi-red-intense',
|
644 | 'ansi-green-intense',
|
645 | 'ansi-yellow-intense',
|
646 | 'ansi-blue-intense',
|
647 | 'ansi-magenta-intense',
|
648 | 'ansi-cyan-intense',
|
649 | 'ansi-white-intense'
|
650 | ];
|
651 | |
652 |
|
653 |
|
654 |
|
655 | function pushColoredChunk(chunk, fg, bg, bold, underline, inverse, out) {
|
656 | if (chunk) {
|
657 | const classes = [];
|
658 | const styles = [];
|
659 | if (bold && typeof fg === 'number' && 0 <= fg && fg < 8) {
|
660 | fg += 8;
|
661 | }
|
662 | if (inverse) {
|
663 | [fg, bg] = [bg, fg];
|
664 | }
|
665 | if (typeof fg === 'number') {
|
666 | classes.push(ANSI_COLORS[fg] + '-fg');
|
667 | }
|
668 | else if (fg.length) {
|
669 | styles.push(`color: rgb(${fg})`);
|
670 | }
|
671 | else if (inverse) {
|
672 | classes.push('ansi-default-inverse-fg');
|
673 | }
|
674 | if (typeof bg === 'number') {
|
675 | classes.push(ANSI_COLORS[bg] + '-bg');
|
676 | }
|
677 | else if (bg.length) {
|
678 | styles.push(`background-color: rgb(${bg})`);
|
679 | }
|
680 | else if (inverse) {
|
681 | classes.push('ansi-default-inverse-bg');
|
682 | }
|
683 | if (bold) {
|
684 | classes.push('ansi-bold');
|
685 | }
|
686 | if (underline) {
|
687 | classes.push('ansi-underline');
|
688 | }
|
689 | if (classes.length || styles.length) {
|
690 | out.push('<span');
|
691 | if (classes.length) {
|
692 | out.push(` class="${classes.join(' ')}"`);
|
693 | }
|
694 | if (styles.length) {
|
695 | out.push(` style="${styles.join('; ')}"`);
|
696 | }
|
697 | out.push('>');
|
698 | out.push(chunk);
|
699 | out.push('</span>');
|
700 | }
|
701 | else {
|
702 | out.push(chunk);
|
703 | }
|
704 | }
|
705 | }
|
706 | |
707 |
|
708 |
|
709 | function getExtendedColors(numbers) {
|
710 | let r;
|
711 | let g;
|
712 | let b;
|
713 | const n = numbers.shift();
|
714 | if (n === 2 && numbers.length >= 3) {
|
715 |
|
716 | r = numbers.shift();
|
717 | g = numbers.shift();
|
718 | b = numbers.shift();
|
719 | if ([r, g, b].some(c => c < 0 || 255 < c)) {
|
720 | throw new RangeError('Invalid range for RGB colors');
|
721 | }
|
722 | }
|
723 | else if (n === 5 && numbers.length >= 1) {
|
724 |
|
725 | const idx = numbers.shift();
|
726 | if (idx < 0) {
|
727 | throw new RangeError('Color index must be >= 0');
|
728 | }
|
729 | else if (idx < 16) {
|
730 |
|
731 | return idx;
|
732 | }
|
733 | else if (idx < 232) {
|
734 |
|
735 | r = Math.floor((idx - 16) / 36);
|
736 | r = r > 0 ? 55 + r * 40 : 0;
|
737 | g = Math.floor(((idx - 16) % 36) / 6);
|
738 | g = g > 0 ? 55 + g * 40 : 0;
|
739 | b = (idx - 16) % 6;
|
740 | b = b > 0 ? 55 + b * 40 : 0;
|
741 | }
|
742 | else if (idx < 256) {
|
743 |
|
744 | r = g = b = (idx - 232) * 10 + 8;
|
745 | }
|
746 | else {
|
747 | throw new RangeError('Color index must be < 256');
|
748 | }
|
749 | }
|
750 | else {
|
751 | throw new RangeError('Invalid extended color specification');
|
752 | }
|
753 | return [r, g, b];
|
754 | }
|
755 | |
756 |
|
757 |
|
758 |
|
759 |
|
760 |
|
761 |
|
762 | function ansiSpan(str) {
|
763 | const ansiRe = /\x1b\[(.*?)([@-~])/g;
|
764 | let fg = [];
|
765 | let bg = [];
|
766 | let bold = false;
|
767 | let underline = false;
|
768 | let inverse = false;
|
769 | let match;
|
770 | const out = [];
|
771 | const numbers = [];
|
772 | let start = 0;
|
773 | str = escape(str);
|
774 | str += '\x1b[m';
|
775 |
|
776 | while ((match = ansiRe.exec(str))) {
|
777 | if (match[2] === 'm') {
|
778 | const items = match[1].split(';');
|
779 | for (let i = 0; i < items.length; i++) {
|
780 | const item = items[i];
|
781 | if (item === '') {
|
782 | numbers.push(0);
|
783 | }
|
784 | else if (item.search(/^\d+$/) !== -1) {
|
785 | numbers.push(parseInt(item, 10));
|
786 | }
|
787 | else {
|
788 |
|
789 | numbers.length = 0;
|
790 | break;
|
791 | }
|
792 | }
|
793 | }
|
794 | else {
|
795 |
|
796 | }
|
797 | const chunk = str.substring(start, match.index);
|
798 | pushColoredChunk(chunk, fg, bg, bold, underline, inverse, out);
|
799 | start = ansiRe.lastIndex;
|
800 | while (numbers.length) {
|
801 | const n = numbers.shift();
|
802 | switch (n) {
|
803 | case 0:
|
804 | fg = bg = [];
|
805 | bold = false;
|
806 | underline = false;
|
807 | inverse = false;
|
808 | break;
|
809 | case 1:
|
810 | case 5:
|
811 | bold = true;
|
812 | break;
|
813 | case 4:
|
814 | underline = true;
|
815 | break;
|
816 | case 7:
|
817 | inverse = true;
|
818 | break;
|
819 | case 21:
|
820 | case 22:
|
821 | bold = false;
|
822 | break;
|
823 | case 24:
|
824 | underline = false;
|
825 | break;
|
826 | case 27:
|
827 | inverse = false;
|
828 | break;
|
829 | case 30:
|
830 | case 31:
|
831 | case 32:
|
832 | case 33:
|
833 | case 34:
|
834 | case 35:
|
835 | case 36:
|
836 | case 37:
|
837 | fg = n - 30;
|
838 | break;
|
839 | case 38:
|
840 | try {
|
841 | fg = getExtendedColors(numbers);
|
842 | }
|
843 | catch (e) {
|
844 | numbers.length = 0;
|
845 | }
|
846 | break;
|
847 | case 39:
|
848 | fg = [];
|
849 | break;
|
850 | case 40:
|
851 | case 41:
|
852 | case 42:
|
853 | case 43:
|
854 | case 44:
|
855 | case 45:
|
856 | case 46:
|
857 | case 47:
|
858 | bg = n - 40;
|
859 | break;
|
860 | case 48:
|
861 | try {
|
862 | bg = getExtendedColors(numbers);
|
863 | }
|
864 | catch (e) {
|
865 | numbers.length = 0;
|
866 | }
|
867 | break;
|
868 | case 49:
|
869 | bg = [];
|
870 | break;
|
871 | case 90:
|
872 | case 91:
|
873 | case 92:
|
874 | case 93:
|
875 | case 94:
|
876 | case 95:
|
877 | case 96:
|
878 | case 97:
|
879 | fg = n - 90 + 8;
|
880 | break;
|
881 | case 100:
|
882 | case 101:
|
883 | case 102:
|
884 | case 103:
|
885 | case 104:
|
886 | case 105:
|
887 | case 106:
|
888 | case 107:
|
889 | bg = n - 100 + 8;
|
890 | break;
|
891 | default:
|
892 |
|
893 | }
|
894 | }
|
895 | }
|
896 | return out.join('');
|
897 | }
|
898 | Private.ansiSpan = ansiSpan;
|
899 | })(Private || (Private = {}));
|
900 |
|
\ | No newline at end of file |