mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #15198 from CorpGlory/azure-monitor-refactor-#15087
Azure Monitor: refactor #15087
This commit is contained in:
123
public/app/features/explore/slate-plugins/prism/index.tsx
Normal file
123
public/app/features/explore/slate-plugins/prism/index.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import React from 'react';
|
||||
import Prism from 'prismjs';
|
||||
|
||||
const TOKEN_MARK = 'prism-token';
|
||||
|
||||
export function setPrismTokens(language, field, values, alias = 'variable') {
|
||||
Prism.languages[language][field] = {
|
||||
alias,
|
||||
pattern: new RegExp(`(?:^|\\s)(${values.join('|')})(?:$|\\s)`),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Code-highlighting plugin based on Prism and
|
||||
* https://github.com/ianstormtaylor/slate/blob/master/examples/code-highlighting/index.js
|
||||
*
|
||||
* (Adapted to handle nested grammar definitions.)
|
||||
*/
|
||||
|
||||
export default function PrismPlugin({ definition, language }) {
|
||||
if (definition) {
|
||||
// Don't override exising modified definitions
|
||||
Prism.languages[language] = Prism.languages[language] || definition;
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Render a Slate mark with appropiate CSS class names
|
||||
*
|
||||
* @param {Object} props
|
||||
* @return {Element}
|
||||
*/
|
||||
|
||||
renderMark(props) {
|
||||
const { children, mark } = props;
|
||||
// Only apply spans to marks identified by this plugin
|
||||
if (mark.type !== TOKEN_MARK) {
|
||||
return undefined;
|
||||
}
|
||||
const className = `token ${mark.data.get('types')}`;
|
||||
return <span className={className}>{children}</span>;
|
||||
},
|
||||
|
||||
/**
|
||||
* Decorate code blocks with Prism.js highlighting.
|
||||
*
|
||||
* @param {Node} node
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
decorateNode(node) {
|
||||
if (node.type !== 'paragraph') {
|
||||
return [];
|
||||
}
|
||||
|
||||
const texts = node.getTexts().toArray();
|
||||
const tstring = texts.map(t => t.text).join('\n');
|
||||
const grammar = Prism.languages[language];
|
||||
const tokens = Prism.tokenize(tstring, grammar);
|
||||
const decorations: any[] = [];
|
||||
let startText = texts.shift();
|
||||
let endText = startText;
|
||||
let startOffset = 0;
|
||||
let endOffset = 0;
|
||||
let start = 0;
|
||||
|
||||
function processToken(token, acc?) {
|
||||
// Accumulate token types down the tree
|
||||
const types = `${acc || ''} ${token.type || ''} ${token.alias || ''}`;
|
||||
|
||||
// Add mark for token node
|
||||
if (typeof token === 'string' || typeof token.content === 'string') {
|
||||
startText = endText;
|
||||
startOffset = endOffset;
|
||||
|
||||
const content = typeof token === 'string' ? token : token.content;
|
||||
const newlines = content.split('\n').length - 1;
|
||||
const length = content.length - newlines;
|
||||
const end = start + length;
|
||||
|
||||
let available = startText.text.length - startOffset;
|
||||
let remaining = length;
|
||||
|
||||
endOffset = startOffset + remaining;
|
||||
|
||||
while (available < remaining) {
|
||||
endText = texts.shift();
|
||||
remaining = length - available;
|
||||
available = endText.text.length;
|
||||
endOffset = remaining;
|
||||
}
|
||||
|
||||
// Inject marks from up the tree (acc) as well
|
||||
if (typeof token !== 'string' || acc) {
|
||||
const range = {
|
||||
anchorKey: startText.key,
|
||||
anchorOffset: startOffset,
|
||||
focusKey: endText.key,
|
||||
focusOffset: endOffset,
|
||||
marks: [{ type: TOKEN_MARK, data: { types } }],
|
||||
};
|
||||
|
||||
decorations.push(range);
|
||||
}
|
||||
|
||||
start = end;
|
||||
} else if (token.content && token.content.length) {
|
||||
// Tokens can be nested
|
||||
for (const subToken of token.content) {
|
||||
processToken(subToken, types);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process top-level tokens
|
||||
for (const token of tokens) {
|
||||
processToken(token);
|
||||
}
|
||||
|
||||
return decorations;
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user