shrink syntax highlighting bundle size

This commit is contained in:
Nathan Wang 2020-07-15 21:47:49 -07:00
parent f80171f6ed
commit 7dd4d4833a
6 changed files with 1006 additions and 27 deletions

View file

@ -11,8 +11,8 @@ The most popular languages that USACO supports are [C++11](https://en.wikipedia.
- If you already know one of these languages, just use it.
- If you know multiple languages, we recommend you pick C++ over Java, and Java over Python.
- For Bronze and Silver, any language will do.
- For Gold and Platinum, Python is not recommended, because it is a slow language and lacks an ordered map.
- For Bronze, any language will do.
- For Silver<Asterisk>However, if Python is the only language you know / you really want to use Python, you can still pass Silver with Python.</Asterisk>, Gold, and Platinum, Python is not recommended, because it is a slow language and lacks an ordered map.
- Check "Factors to Consider When Choosing a Language" for more information.
Keep in mind that it's easy to switch languages down the road. Don't get caught up on which language to choose. Just pick the one you feel most comfortable with!

View file

@ -30,8 +30,8 @@ It's okay to skip over these. Some material in these boxes might not be useful f
Code should compile by itself, example input / output should be provided. Macros should generally be avoided.
- For Bronze and Silver, we will provide code snippets in C++, Java, and Python.
- For Gold, we will provide code snippets in C++ and Java and (sometimes) Python.
- For Bronze, we will provide code snippets in C++, Java, and Python.
- For Silver and Gold, we will provide code snippets in C++ and Java and (sometimes) Python.
- For Platinum, code snippets might only be provided in C++.
<warning-block>

View file

@ -1,8 +1,9 @@
// File taken from https://github.com/FormidableLabs/prism-react-renderer/issues/54
import * as React from 'react';
import Highlight, { defaultProps } from 'prism-react-renderer';
import Highlight from './SyntaxHighlighting/Highlight';
import vsDark from 'prism-react-renderer/themes/vsDark';
import Prism from './SyntaxHighlighting/prism';
export default ({ children, className }) => {
if (className === undefined) {
@ -15,8 +16,9 @@ export default ({ children, className }) => {
}
const language = className.replace(/language-/, '');
return (
// @ts-ignore
<Highlight
{...defaultProps}
Prism={Prism as any}
code={children.trim()}
language={language}
theme={vsDark}

View file

@ -1,21 +0,0 @@
// import * as React from 'react';
// import renderMathInElement from 'katex/contrib/auto-render/auto-render';
//
// type KatexRendererProps = {
// children?: React.ReactNode;
// };
//
// export function KatexRenderer(props: KatexRendererProps) {
// const ref = React.useRef();
//
// React.useEffect(() => {
// renderMathInElement(ref.current, {
// delimiters: [
// { left: '$$', right: '$$', display: true },
// { left: '$', right: '$', display: false },
// ],
// });
// }, [props.children]);
//
// return <span ref={ref}>{props.children}</span>;
// }

View file

@ -0,0 +1,353 @@
/* eslint-disable */
// taken from https://github.com/FormidableLabs/prism-react-renderer
// really dumb issue: when importing from node_modules, gatsby/webpack doesn't tree-shake properly...
import { Component } from 'react';
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true,
});
} else {
obj[key] = value;
}
return obj;
}
function _extends() {
_extends =
Object.assign ||
function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
var newlineRe = /\r\n|\r|\n/; // Empty lines need to contain a single empty token, denoted with { empty: true }
var normalizeEmptyLines = function (line) {
if (line.length === 0) {
line.push({
types: ['plain'],
content: '',
empty: true,
});
} else if (line.length === 1 && line[0].content === '') {
line[0].empty = true;
}
};
var appendTypes = function (types, add) {
var typesSize = types.length;
if (typesSize > 0 && types[typesSize - 1] === add) {
return types;
}
return types.concat(add);
}; // Takes an array of Prism's tokens and groups them by line, turning plain
// strings into tokens as well. Tokens can become recursive in some cases,
// which means that their types are concatenated. Plain-string tokens however
// are always of type "plain".
// This is not recursive to avoid exceeding the call-stack limit, since it's unclear
// how nested Prism's tokens can become
var normalizeTokens = function (tokens) {
var typeArrStack = [[]];
var tokenArrStack = [tokens];
var tokenArrIndexStack = [0];
var tokenArrSizeStack = [tokens.length];
var i = 0;
var stackIndex = 0;
var currentLine = [];
var acc = [currentLine];
while (stackIndex > -1) {
while (
(i = tokenArrIndexStack[stackIndex]++) < tokenArrSizeStack[stackIndex]
) {
var content = void 0;
var types = typeArrStack[stackIndex];
var tokenArr = tokenArrStack[stackIndex];
var token = tokenArr[i]; // Determine content and append type to types if necessary
if (typeof token === 'string') {
types = stackIndex > 0 ? types : ['plain'];
content = token;
} else {
types = appendTypes(types, token.type);
if (token.alias) {
types = appendTypes(types, token.alias);
}
content = token.content;
} // If token.content is an array, increase the stack depth and repeat this while-loop
if (typeof content !== 'string') {
stackIndex++;
typeArrStack.push(types);
tokenArrStack.push(content);
tokenArrIndexStack.push(0);
tokenArrSizeStack.push(content.length);
continue;
} // Split by newlines
var splitByNewlines = content.split(newlineRe);
var newlineCount = splitByNewlines.length;
currentLine.push({
types: types,
content: splitByNewlines[0],
}); // Create a new line for each string on a new line
for (var i$1 = 1; i$1 < newlineCount; i$1++) {
normalizeEmptyLines(currentLine);
acc.push((currentLine = []));
currentLine.push({
types: types,
content: splitByNewlines[i$1],
});
}
} // Decreate the stack depth
stackIndex--;
typeArrStack.pop();
tokenArrStack.pop();
tokenArrIndexStack.pop();
tokenArrSizeStack.pop();
}
normalizeEmptyLines(currentLine);
return acc;
};
var themeToDict = function (theme, language) {
var plain = theme.plain; // $FlowFixMe
var base = Object.create(null);
var themeDict = theme.styles.reduce(function (acc, themeEntry) {
var languages = themeEntry.languages;
var style = themeEntry.style;
if (languages && !languages.includes(language)) {
return acc;
}
themeEntry.types.forEach(function (type) {
// $FlowFixMe
var accStyle = _extends({}, acc[type], style);
acc[type] = accStyle;
});
return acc;
}, base); // $FlowFixMe
themeDict.root = plain; // $FlowFixMe
themeDict.plain = _extends({}, plain, {
backgroundColor: null,
});
return themeDict;
};
function objectWithoutProperties(obj, exclude) {
var target = {};
for (var k in obj)
if (
Object.prototype.hasOwnProperty.call(obj, k) &&
exclude.indexOf(k) === -1
)
target[k] = obj[k];
return target;
}
var Highlight =
/*@__PURE__*/
(function (Component) {
function Highlight() {
var this$1 = this;
var args = [],
len = arguments.length;
while (len--) args[len] = arguments[len];
Component.apply(this, args);
_defineProperty(this, 'getThemeDict', function (props) {
if (
this$1.themeDict !== undefined &&
props.theme === this$1.prevTheme &&
props.language === this$1.prevLanguage
) {
return this$1.themeDict;
}
this$1.prevTheme = props.theme;
this$1.prevLanguage = props.language;
var themeDict = props.theme
? themeToDict(props.theme, props.language)
: undefined;
return (this$1.themeDict = themeDict);
});
_defineProperty(this, 'getLineProps', function (ref) {
var key = ref.key;
var className = ref.className;
var style = ref.style;
var rest$1 = objectWithoutProperties(ref, [
'key',
'className',
'style',
'line',
]);
var rest = rest$1;
var output = _extends({}, rest, {
className: 'token-line',
style: undefined,
key: undefined,
});
var themeDict = this$1.getThemeDict(this$1.props);
if (themeDict !== undefined) {
output.style = themeDict.plain;
}
if (style !== undefined) {
output.style =
output.style !== undefined
? _extends({}, output.style, style)
: style;
}
if (key !== undefined) {
output.key = key;
}
if (className) {
output.className += ' ' + className;
}
return output;
});
_defineProperty(this, 'getStyleForToken', function (ref) {
var types = ref.types;
var empty = ref.empty;
var typesSize = types.length;
var themeDict = this$1.getThemeDict(this$1.props);
if (themeDict === undefined) {
return undefined;
} else if (typesSize === 1 && types[0] === 'plain') {
return empty
? {
display: 'inline-block',
}
: undefined;
} else if (typesSize === 1 && !empty) {
return themeDict[types[0]];
}
var baseStyle = empty
? {
display: 'inline-block',
}
: {}; // $FlowFixMe
var typeStyles = types.map(function (type) {
return themeDict[type];
});
return Object.assign.apply(Object, [baseStyle].concat(typeStyles));
});
_defineProperty(this, 'getTokenProps', function (ref) {
var key = ref.key;
var className = ref.className;
var style = ref.style;
var token = ref.token;
var rest$1 = objectWithoutProperties(ref, [
'key',
'className',
'style',
'token',
]);
var rest = rest$1;
var output = _extends({}, rest, {
className: 'token ' + token.types.join(' '),
children: token.content,
style: this$1.getStyleForToken(token),
key: undefined,
});
if (style !== undefined) {
output.style =
output.style !== undefined
? _extends({}, output.style, style)
: style;
}
if (key !== undefined) {
output.key = key;
}
if (className) {
output.className += ' ' + className;
}
return output;
});
}
if (Component) Highlight.__proto__ = Component;
Highlight.prototype = Object.create(Component && Component.prototype);
Highlight.prototype.constructor = Highlight;
Highlight.prototype.render = function render() {
var ref = this.props;
var Prism = ref.Prism;
var language = ref.language;
var code = ref.code;
var children = ref.children;
var themeDict = this.getThemeDict(this.props);
var grammar = Prism.languages[language];
var mixedTokens =
grammar !== undefined
? Prism.tokenize(code, grammar, language)
: [code];
var tokens = normalizeTokens(mixedTokens);
return children({
tokens: tokens,
className: 'prism-code language-' + language,
style: themeDict !== undefined ? themeDict.root : {},
getLineProps: this.getLineProps,
getTokenProps: this.getTokenProps,
});
};
return Highlight;
})(Component);
export default Highlight;
// export { defaultProps };

View file

@ -0,0 +1,645 @@
/* eslint-disable */
/**
* Prism: Lightweight, robust, elegant syntax highlighting
* MIT license http://www.opensource.org/licenses/mit-license.php/
* @author Lea Verou http://lea.verou.me
*/
/**
* prism-react-renderer:
* This file has been modified to remove:
* - globals and window dependency
* - worker support
* - highlightAll and other element dependent methods
* - _.hooks helpers
* - UMD/node-specific hacks
* It has also been run through prettier
*/
/**
* me (thecodingwizard):
* - added C++, Java, Python syntax highlighting manually
* - oops this is really dumb but I couldn't get tree-shaking to work properly when importing from node_modules >:-(
*/
var Prism = (function () {
// Private helper vars
var lang = /\blang(?:uage)?-([\w-]+)\b/i;
var uniqueId = 0;
var _ = {
util: {
encode: function (tokens) {
if (tokens instanceof Token) {
return new Token(
tokens.type,
_.util.encode(tokens.content),
tokens.alias
);
} else if (_.util.type(tokens) === 'Array') {
return tokens.map(_.util.encode);
} else {
return tokens
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/\u00a0/g, ' ');
}
},
type: function (o) {
return Object.prototype.toString.call(o).match(/\[object (\w+)\]/)[1];
},
objId: function (obj) {
if (!obj['__id']) {
Object.defineProperty(obj, '__id', { value: ++uniqueId });
}
return obj['__id'];
},
// Deep clone a language definition (e.g. to extend it)
clone: function (o, visited) {
var type = _.util.type(o);
visited = visited || {};
switch (type) {
case 'Object':
if (visited[_.util.objId(o)]) {
return visited[_.util.objId(o)];
}
var clone = {};
visited[_.util.objId(o)] = clone;
for (var key in o) {
if (o.hasOwnProperty(key)) {
clone[key] = _.util.clone(o[key], visited);
}
}
return clone;
case 'Array':
if (visited[_.util.objId(o)]) {
return visited[_.util.objId(o)];
}
var clone = [];
visited[_.util.objId(o)] = clone;
o.forEach(function (v, i) {
clone[i] = _.util.clone(v, visited);
});
return clone;
}
return o;
},
},
languages: {
extend: function (id, redef) {
var lang = _.util.clone(_.languages[id]);
for (var key in redef) {
lang[key] = redef[key];
}
return lang;
},
/**
* Insert a token before another token in a language literal
* As this needs to recreate the object (we cannot actually insert before keys in object literals),
* we cannot just provide an object, we need anobject and a key.
* @param inside The key (or language id) of the parent
* @param before The key to insert before. If not provided, the function appends instead.
* @param insert Object with the key/value pairs to insert
* @param root The object that contains `inside`. If equal to Prism.languages, it can be omitted.
*/
insertBefore: function (inside, before, insert, root) {
root = root || _.languages;
var grammar = root[inside];
if (arguments.length == 2) {
insert = arguments[1];
for (var newToken in insert) {
if (insert.hasOwnProperty(newToken)) {
grammar[newToken] = insert[newToken];
}
}
return grammar;
}
var ret = {};
for (var token in grammar) {
if (grammar.hasOwnProperty(token)) {
if (token == before) {
for (var newToken in insert) {
if (insert.hasOwnProperty(newToken)) {
ret[newToken] = insert[newToken];
}
}
}
ret[token] = grammar[token];
}
}
// Update references in other language definitions
_.languages.DFS(_.languages, function (key, value) {
if (value === root[inside] && key != inside) {
this[key] = ret;
}
});
return (root[inside] = ret);
},
// Traverse a language definition with Depth First Search
DFS: function (o, callback, type, visited) {
visited = visited || {};
for (var i in o) {
if (o.hasOwnProperty(i)) {
callback.call(o, i, o[i], type || i);
if (
_.util.type(o[i]) === 'Object' &&
!visited[_.util.objId(o[i])]
) {
visited[_.util.objId(o[i])] = true;
_.languages.DFS(o[i], callback, null, visited);
} else if (
_.util.type(o[i]) === 'Array' &&
!visited[_.util.objId(o[i])]
) {
visited[_.util.objId(o[i])] = true;
_.languages.DFS(o[i], callback, i, visited);
}
}
}
},
},
plugins: {},
highlight: function (text, grammar, language) {
var env = {
code: text,
grammar: grammar,
language: language,
};
env.tokens = _.tokenize(env.code, env.grammar);
return Token.stringify(_.util.encode(env.tokens), env.language);
},
matchGrammar: function (
text,
strarr,
grammar,
index,
startPos,
oneshot,
target
) {
var Token = _.Token;
for (var token in grammar) {
if (!grammar.hasOwnProperty(token) || !grammar[token]) {
continue;
}
if (token == target) {
return;
}
var patterns = grammar[token];
patterns = _.util.type(patterns) === 'Array' ? patterns : [patterns];
for (var j = 0; j < patterns.length; ++j) {
var pattern = patterns[j],
inside = pattern.inside,
lookbehind = !!pattern.lookbehind,
greedy = !!pattern.greedy,
lookbehindLength = 0,
alias = pattern.alias;
if (greedy && !pattern.pattern.global) {
// Without the global flag, lastIndex won't work
var flags = pattern.pattern.toString().match(/[imuy]*$/)[0];
pattern.pattern = RegExp(pattern.pattern.source, flags + 'g');
}
pattern = pattern.pattern || pattern;
// Dont cache length as it changes during the loop
for (
var i = index, pos = startPos;
i < strarr.length;
pos += strarr[i].length, ++i
) {
var str = strarr[i];
if (strarr.length > text.length) {
// Something went terribly wrong, ABORT, ABORT!
return;
}
if (str instanceof Token) {
continue;
}
if (greedy && i != strarr.length - 1) {
pattern.lastIndex = pos;
var match = pattern.exec(text);
if (!match) {
break;
}
var from = match.index + (lookbehind ? match[1].length : 0),
to = match.index + match[0].length,
k = i,
p = pos;
for (
var len = strarr.length;
k < len &&
(p < to || (!strarr[k].type && !strarr[k - 1].greedy));
++k
) {
p += strarr[k].length;
// Move the index i to the element in strarr that is closest to from
if (from >= p) {
++i;
pos = p;
}
}
// If strarr[i] is a Token, then the match starts inside another Token, which is invalid
if (strarr[i] instanceof Token) {
continue;
}
// Number of tokens to delete and replace with the new match
delNum = k - i;
str = text.slice(pos, p);
match.index -= pos;
} else {
pattern.lastIndex = 0;
var match = pattern.exec(str),
delNum = 1;
}
if (!match) {
if (oneshot) {
break;
}
continue;
}
if (lookbehind) {
lookbehindLength = match[1] ? match[1].length : 0;
}
var from = match.index + lookbehindLength,
match = match[0].slice(lookbehindLength),
to = from + match.length,
before = str.slice(0, from),
after = str.slice(to);
var args = [i, delNum];
if (before) {
++i;
pos += before.length;
args.push(before);
}
var wrapped = new Token(
token,
inside ? _.tokenize(match, inside) : match,
alias,
match,
greedy
);
args.push(wrapped);
if (after) {
args.push(after);
}
Array.prototype.splice.apply(strarr, args);
if (delNum != 1)
_.matchGrammar(text, strarr, grammar, i, pos, true, token);
if (oneshot) break;
}
}
}
},
hooks: {
add: function () {},
},
tokenize: function (text, grammar, language) {
var strarr = [text];
var rest = grammar.rest;
if (rest) {
for (var token in rest) {
grammar[token] = rest[token];
}
delete grammar.rest;
}
_.matchGrammar(text, strarr, grammar, 0, 0, false);
return strarr;
},
};
var Token = (_.Token = function (type, content, alias, matchedStr, greedy) {
this.type = type;
this.content = content;
this.alias = alias;
// Copy of the full string this token was created from
this.length = (matchedStr || '').length | 0;
this.greedy = !!greedy;
});
Token.stringify = function (o, language, parent) {
if (typeof o == 'string') {
return o;
}
if (_.util.type(o) === 'Array') {
return o
.map(function (element) {
return Token.stringify(element, language, o);
})
.join('');
}
var env = {
type: o.type,
content: Token.stringify(o.content, language, parent),
tag: 'span',
classes: ['token', o.type],
attributes: {},
language: language,
parent: parent,
};
if (o.alias) {
var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias];
Array.prototype.push.apply(env.classes, aliases);
}
var attributes = Object.keys(env.attributes)
.map(function (name) {
return (
name +
'="' +
(env.attributes[name] || '').replace(/"/g, '&quot;') +
'"'
);
})
.join(' ');
return (
'<' +
env.tag +
' class="' +
env.classes.join(' ') +
'"' +
(attributes ? ' ' + attributes : '') +
'>' +
env.content +
'</' +
env.tag +
'>'
);
};
return _;
})();
/* "prismjs/components/prism-clike" */
Prism.languages.clike = {
comment: [
{
pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
lookbehind: true,
},
{
pattern: /(^|[^\\:])\/\/.*/,
lookbehind: true,
greedy: true,
},
],
string: {
pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
greedy: true,
},
'class-name': {
pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,
lookbehind: true,
inside: {
punctuation: /[.\\]/,
},
},
keyword: /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,
boolean: /\b(?:true|false)\b/,
function: /\w+(?=\()/,
number: /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
operator: /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,
punctuation: /[{}[\];(),.:]/,
};
/* "prismjs/components/prism-c" */
Prism.languages.c = Prism.languages.extend('clike', {
'class-name': {
pattern: /(\b(?:enum|struct)\s+)\w+/,
lookbehind: true,
},
keyword: /\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,
operator: />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/,
number: /(?:\b0x(?:[\da-f]+\.?[\da-f]*|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i,
});
Prism.languages.insertBefore('c', 'string', {
macro: {
// allow for multiline macro definitions
// spaces after the # character compile fine with gcc
pattern: /(^\s*)#\s*[a-z]+(?:[^\r\n\\]|\\(?:\r\n|[\s\S]))*/im,
lookbehind: true,
alias: 'property',
inside: {
// highlight the path of the include statement as a string
string: {
pattern: /(#\s*include\s*)(?:<.+?>|("|')(?:\\?.)+?\2)/,
lookbehind: true,
},
// highlight macro directives as keywords
directive: {
pattern: /(#\s*)\b(?:define|defined|elif|else|endif|error|ifdef|ifndef|if|import|include|line|pragma|undef|using)\b/,
lookbehind: true,
alias: 'keyword',
},
},
},
// highlight predefined macros as constants
constant: /\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/,
});
delete Prism.languages.c['boolean'];
/* "prismjs/components/prism-cpp" */
Prism.languages.cpp = Prism.languages.extend('c', {
'class-name': {
pattern: /(\b(?:class|enum|struct)\s+)\w+/,
lookbehind: true,
},
keyword: /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,
number: {
pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i,
greedy: true,
},
operator: />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,
boolean: /\b(?:true|false)\b/,
});
Prism.languages.insertBefore('cpp', 'string', {
'raw-string': {
pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,
alias: 'string',
greedy: true,
},
});
/* "prismjs/components/prism-java" */
(function (Prism) {
var keywords = /\b(?:abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while|var|null|exports|module|open|opens|provides|requires|to|transitive|uses|with)\b/; // based on the java naming conventions
var className = /\b[A-Z](?:\w*[a-z]\w*)?\b/;
Prism.languages.java = Prism.languages.extend('clike', {
'class-name': [
className, // variables and parameters
// this to support class names (or generic parameters) which do not contain a lower case letter (also works for methods)
/\b[A-Z]\w*(?=\s+\w+\s*[;,=())])/,
],
keyword: keywords,
function: [
Prism.languages.clike.function,
{
pattern: /(\:\:)[a-z_]\w*/,
lookbehind: true,
},
],
number: /\b0b[01][01_]*L?\b|\b0x[\da-f_]*\.?[\da-f_p+-]+\b|(?:\b\d[\d_]*\.?[\d_]*|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,
operator: {
pattern: /(^|[^.])(?:<<=?|>>>?=?|->|([-+&|])\2|[?:~]|[-+*/%&|^!=<>]=?)/m,
lookbehind: true,
},
});
Prism.languages.insertBefore('java', 'class-name', {
annotation: {
alias: 'punctuation',
pattern: /(^|[^.])@\w+/,
lookbehind: true,
},
namespace: {
pattern: /(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)[a-z]\w*(\.[a-z]\w*)+/,
lookbehind: true,
inside: {
punctuation: /\./,
},
},
generics: {
pattern: /<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,
inside: {
'class-name': className,
keyword: keywords,
punctuation: /[<>(),.:]/,
operator: /[?&|]/,
},
},
});
})(Prism);
/* "prismjs/components/prism-python" */
Prism.languages.python = {
comment: {
pattern: /(^|[^\\])#.*/,
lookbehind: true,
},
'string-interpolation': {
pattern: /(?:f|rf|fr)(?:("""|''')[\s\S]+?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
greedy: true,
inside: {
interpolation: {
// "{" <expression> <optional "!s", "!r", or "!a"> <optional ":" format specifier> "}"
pattern: /((?:^|[^{])(?:{{)*){(?!{)(?:[^{}]|{(?!{)(?:[^{}]|{(?!{)(?:[^{}])+})+})+}/,
lookbehind: true,
inside: {
'format-spec': {
pattern: /(:)[^:(){}]+(?=}$)/,
lookbehind: true,
},
'conversion-option': {
pattern: /![sra](?=[:}]$)/,
alias: 'punctuation',
},
rest: null,
},
},
string: /[\s\S]+/,
},
},
'triple-quoted-string': {
pattern: /(?:[rub]|rb|br)?("""|''')[\s\S]+?\1/i,
greedy: true,
alias: 'string',
},
string: {
pattern: /(?:[rub]|rb|br)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,
greedy: true,
},
function: {
pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,
lookbehind: true,
},
'class-name': {
pattern: /(\bclass\s+)\w+/i,
lookbehind: true,
},
decorator: {
pattern: /(^\s*)@\w+(?:\.\w+)*/i,
lookbehind: true,
alias: ['annotation', 'punctuation'],
inside: {
punctuation: /\./,
},
},
keyword: /\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,
builtin: /\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,
boolean: /\b(?:True|False|None)\b/,
number: /(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,
operator: /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
punctuation: /[{}[\];(),.:]/,
};
Prism.languages.python['string-interpolation'].inside[
'interpolation'
].inside.rest = Prism.languages.python;
Prism.languages.py = Prism.languages.python;
export default Prism;