chore: roll highlightjs (#18382)

This commit is contained in:
Pavel Feldman 2022-10-27 16:49:54 -07:00 committed by GitHub
parent ce63a9b206
commit a3f30674d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 1590 additions and 1277 deletions

View file

@ -18,7 +18,7 @@ import type { StackFrame } from '@protocol/channels';
import type { ActionTraceEvent } from '@trace/trace';
import { Source as SourceView } from '@web/components/source';
import { SplitView } from '@web/components/splitView';
import '@web/third_party/highlightjs/highlightjs/tomorrow.css';
import '@web/third_party/highlightjs/highlightjs/github.css';
import * as React from 'react';
import { useAsyncMemo } from './helpers';
import './sourceTab.css';

View file

@ -17,7 +17,7 @@
import './source.css';
import * as React from 'react';
import highlightjs from '../third_party/highlightjs/highlightjs';
import '../third_party/highlightjs/highlightjs/tomorrow.css';
import '../third_party/highlightjs/highlightjs/github.css';
export type SourceHighlight = {
line: number;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
Theme: GitHub Dark
Description: Dark theme as seen on github.com
Author: github.com
Maintainer: @Hirse
Updated: 2021-05-15
Outdated base version: https://github.com/primer/github-syntax-dark
Current colors taken from GitHub's CSS
*/.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c}

View file

@ -0,0 +1,10 @@
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
Theme: GitHub
Description: Light theme as seen on github.com
Author: github.com
Maintainer: @Hirse
Updated: 2021-05-15
Outdated base version: https://github.com/primer/github-syntax-light
Current colors taken from GitHub's CSS
*/.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}

View file

@ -1,243 +0,0 @@
/* eslint-disable no-unused-vars */
/* eslint-disable no-use-before-define */
// For TS consumers who use Node and don't have dom in their tsconfig lib, import the necessary types here.
/// <reference lib="dom" />
/* Public API */
// eslint-disable-next-line
declare const hljs : HLJSApi;
type HLJSApi = PublicApi & ModesAPI
interface VuePlugin {
install: (vue: any) => void
}
interface PublicApi {
highlight: (languageName: string, code: string, ignoreIllegals?: boolean, continuation?: Mode) => HighlightResult
highlightAuto: (code: string, languageSubset?: string[]) => AutoHighlightResult
fixMarkup: (html: string) => string
highlightBlock: (element: HTMLElement) => void
configure: (options: Partial<HLJSOptions>) => void
initHighlighting: () => void
initHighlightingOnLoad: () => void
registerLanguage: (languageName: string, language: LanguageFn) => void
listLanguages: () => string[]
registerAliases: (aliasList: string | string[], { languageName } : {languageName: string}) => void
getLanguage: (languageName: string) => Language | undefined
requireLanguage: (languageName: string) => Language | never
autoDetection: (languageName: string) => boolean
inherit: <T>(original: T, ...args: Record<string, any>[]) => T
addPlugin: (plugin: HLJSPlugin) => void
debugMode: () => void
safeMode: () => void
versionString: string
vuePlugin: () => VuePlugin
}
interface ModesAPI {
SHEBANG: (mode?: Partial<Mode> & {binary?: string | RegExp}) => Mode
BACKSLASH_ESCAPE: Mode
QUOTE_STRING_MODE: Mode
APOS_STRING_MODE: Mode
PHRASAL_WORDS_MODE: Mode
COMMENT: (begin: string | RegExp, end: string | RegExp, modeOpts?: Mode | {}) => Mode
C_LINE_COMMENT_MODE: Mode
C_BLOCK_COMMENT_MODE: Mode
HASH_COMMENT_MODE: Mode
NUMBER_MODE: Mode
C_NUMBER_MODE: Mode
BINARY_NUMBER_MODE: Mode
CSS_NUMBER_MODE: Mode
REGEXP_MODE: Mode
TITLE_MODE: Mode
UNDERSCORE_TITLE_MODE: Mode
METHOD_GUARD: Mode
END_SAME_AS_BEGIN: (mode: Mode) => Mode
// built in regex
IDENT_RE: string
UNDERSCORE_IDENT_RE: string
NUMBER_RE: string
C_NUMBER_RE: string
BINARY_NUMBER_RE: string
RE_STARTERS_RE: string
}
type LanguageFn = (hljs?: HLJSApi) => Language
type CompilerExt = (mode: Mode, parent: Mode | Language | null) => void
interface HighlightResult {
relevance : number
value : string
language? : string
emitter : Emitter
illegal : boolean
top? : Language | CompiledMode
illegalBy? : illegalData
sofar? : string
errorRaised? : Error
// * for auto-highlight
second_best? : Omit<HighlightResult, 'second_best'>
code?: string
}
interface AutoHighlightResult extends HighlightResult {}
interface illegalData {
msg: string
context: string
mode: CompiledMode
}
type BeforeHighlightContext = {
code: string,
language: string,
result?: HighlightResult
}
type PluginEvent = keyof HLJSPlugin;
type HLJSPlugin = {
'after:highlight'?: (result: HighlightResult) => void,
'before:highlight'?: (context: BeforeHighlightContext) => void,
'after:highlightBlock'?: (data: { result: HighlightResult}) => void,
'before:highlightBlock'?: (data: { block: Element, language: string}) => void,
}
interface EmitterConstructor {
new (opts: any): Emitter
}
interface HLJSOptions {
noHighlightRe: RegExp
languageDetectRe: RegExp
classPrefix: string
tabReplace?: string
useBR: boolean
languages?: string[]
__emitter: EmitterConstructor
}
interface CallbackResponse {
data: Record<string, any>
ignoreMatch: () => void
}
/************
PRIVATE API
************/
/* for jsdoc annotations in the JS source files */
type AnnotatedError = Error & {mode?: Mode | Language, languageName?: string, badRule?: Mode}
type ModeCallback = (match: RegExpMatchArray, response: CallbackResponse) => void
type HighlightedHTMLElement = HTMLElement & {result?: object, second_best?: object, parentNode: HTMLElement}
type EnhancedMatch = RegExpMatchArray & {rule: CompiledMode, type: MatchType}
type MatchType = "begin" | "end" | "illegal"
interface Emitter {
addKeyword(text: string, kind: string): void
addText(text: string): void
toHTML(): string
finalize(): void
closeAllNodes(): void
openNode(kind: string): void
closeNode(): void
addSublanguage(emitter: Emitter, subLanguageName: string): void
}
/* modes */
interface ModeCallbacks {
"on:end"?: Function,
"on:begin"?: ModeCallback
}
interface Mode extends ModeCallbacks, ModeDetails {
}
interface LanguageDetail {
name?: string
rawDefinition?: () => Language
aliases?: string[]
disableAutodetect?: boolean
contains: (Mode)[]
case_insensitive?: boolean
keywords?: Record<string, any> | string
compiled?: boolean,
exports?: any,
classNameAliases?: Record<string, string>
compilerExtensions?: CompilerExt[]
supersetOf?: string
}
type Language = LanguageDetail & Partial<Mode>
interface CompiledLanguage extends LanguageDetail, CompiledMode {
compiled: true
contains: CompiledMode[]
keywords: Record<string, any>
}
type KeywordData = [string, number];
type KeywordDict = Record<string, KeywordData>
type CompiledMode = Omit<Mode, 'contains'> &
{
contains: CompiledMode[]
keywords: KeywordDict
data: Record<string, any>
terminatorEnd: string
keywordPatternRe: RegExp
beginRe: RegExp
endRe: RegExp
illegalRe: RegExp
matcher: any
compiled: true
starts?: CompiledMode
parent?: CompiledMode
}
interface ModeDetails {
begin?: RegExp | string
match?: RegExp | string
end?: RegExp | string
className?: string
contains?: ("self" | Mode)[]
endsParent?: boolean
endsWithParent?: boolean
endSameAsBegin?: boolean
skip?: boolean
excludeBegin?: boolean
excludeEnd?: boolean
returnBegin?: boolean
returnEnd?: boolean
__beforeBegin?: Function
parent?: Mode
starts?:Mode
lexemes?: string | RegExp
keywords?: Record<string, any> | string
beginKeywords?: string
relevance?: number
illegal?: string | RegExp | Array<string | RegExp>
variants?: Mode[]
cachedVariants?: Mode[]
// parsed
subLanguage?: string | string[]
compiled?: boolean
label?: string
}
// deprecated API since v10
// declare module 'highlight.js/lib/highlight.js';
declare module 'highlight.js' {
export = hljs;
}
declare module 'highlight.js/lib/languages/*' {
export default function(hljs?: HLJSApi): LanguageDetail;
}
export = hljs;

View file

@ -2,35 +2,35 @@
Language: C#
Author: Jason Diamond <jason@diamond.name>
Contributor: Nicolas LLOBERA <nllobera@gmail.com>, Pieter Vantorre <pietervantorre@gmail.com>, David Pine <david.pine@microsoft.com>
Website: https://docs.microsoft.com/en-us/dotnet/csharp/
Website: https://docs.microsoft.com/dotnet/csharp/
Category: common
*/
/** @type LanguageFn */
export default function csharp(hljs) {
var BUILT_IN_KEYWORDS = [
'bool',
'byte',
'char',
'decimal',
'delegate',
'double',
'dynamic',
'enum',
'float',
'int',
'long',
'nint',
'nuint',
'object',
'sbyte',
'short',
'string',
'ulong',
'unit',
'ushort'
const BUILT_IN_KEYWORDS = [
'bool',
'byte',
'char',
'decimal',
'delegate',
'double',
'dynamic',
'enum',
'float',
'int',
'long',
'nint',
'nuint',
'object',
'sbyte',
'short',
'string',
'ulong',
'uint',
'ushort'
];
var FUNCTION_MODIFIERS = [
const FUNCTION_MODIFIERS = [
'public',
'private',
'protected',
@ -47,18 +47,19 @@ export default function csharp(hljs) {
'sealed',
'partial'
];
var LITERAL_KEYWORDS = [
'default',
'false',
'null',
'true'
const LITERAL_KEYWORDS = [
'default',
'false',
'null',
'true'
];
var NORMAL_KEYWORDS = [
const NORMAL_KEYWORDS = [
'abstract',
'as',
'base',
'break',
'case',
'catch',
'class',
'const',
'continue',
@ -92,6 +93,7 @@ export default function csharp(hljs) {
'record',
'ref',
'return',
'scoped',
'sealed',
'sizeof',
'stackalloc',
@ -110,7 +112,7 @@ export default function csharp(hljs) {
'volatile',
'while'
];
var CONTEXTUAL_KEYWORDS = [
const CONTEXTUAL_KEYWORDS = [
'add',
'alias',
'and',
@ -147,13 +149,13 @@ export default function csharp(hljs) {
'yield'
];
var KEYWORDS = {
keyword: NORMAL_KEYWORDS.concat(CONTEXTUAL_KEYWORDS).join(' '),
built_in: BUILT_IN_KEYWORDS.join(' '),
literal: LITERAL_KEYWORDS.join(' ')
const KEYWORDS = {
keyword: NORMAL_KEYWORDS.concat(CONTEXTUAL_KEYWORDS),
built_in: BUILT_IN_KEYWORDS,
literal: LITERAL_KEYWORDS
};
var TITLE_MODE = hljs.inherit(hljs.TITLE_MODE, {begin: '[a-zA-Z](\\.?\\w)*'});
var NUMBERS = {
const TITLE_MODE = hljs.inherit(hljs.TITLE_MODE, { begin: '[a-zA-Z](\\.?\\w)*' });
const NUMBERS = {
className: 'number',
variants: [
{ begin: '\\b(0b[01\']+)' },
@ -162,32 +164,51 @@ export default function csharp(hljs) {
],
relevance: 0
};
var VERBATIM_STRING = {
const VERBATIM_STRING = {
className: 'string',
begin: '@"', end: '"',
contains: [{begin: '""'}]
begin: '@"',
end: '"',
contains: [ { begin: '""' } ]
};
var VERBATIM_STRING_NO_LF = hljs.inherit(VERBATIM_STRING, {illegal: /\n/});
var SUBST = {
const VERBATIM_STRING_NO_LF = hljs.inherit(VERBATIM_STRING, { illegal: /\n/ });
const SUBST = {
className: 'subst',
begin: /\{/, end: /\}/,
begin: /\{/,
end: /\}/,
keywords: KEYWORDS
};
var SUBST_NO_LF = hljs.inherit(SUBST, {illegal: /\n/});
var INTERPOLATED_STRING = {
const SUBST_NO_LF = hljs.inherit(SUBST, { illegal: /\n/ });
const INTERPOLATED_STRING = {
className: 'string',
begin: /\$"/, end: '"',
begin: /\$"/,
end: '"',
illegal: /\n/,
contains: [{begin: /\{\{/}, {begin: /\}\}/}, hljs.BACKSLASH_ESCAPE, SUBST_NO_LF]
contains: [
{ begin: /\{\{/ },
{ begin: /\}\}/ },
hljs.BACKSLASH_ESCAPE,
SUBST_NO_LF
]
};
var INTERPOLATED_VERBATIM_STRING = {
const INTERPOLATED_VERBATIM_STRING = {
className: 'string',
begin: /\$@"/, end: '"',
contains: [{begin: /\{\{/}, {begin: /\}\}/}, {begin: '""'}, SUBST]
begin: /\$@"/,
end: '"',
contains: [
{ begin: /\{\{/ },
{ begin: /\}\}/ },
{ begin: '""' },
SUBST
]
};
var INTERPOLATED_VERBATIM_STRING_NO_LF = hljs.inherit(INTERPOLATED_VERBATIM_STRING, {
const INTERPOLATED_VERBATIM_STRING_NO_LF = hljs.inherit(INTERPOLATED_VERBATIM_STRING, {
illegal: /\n/,
contains: [{begin: /\{\{/}, {begin: /\}\}/}, {begin: '""'}, SUBST_NO_LF]
contains: [
{ begin: /\{\{/ },
{ begin: /\}\}/ },
{ begin: '""' },
SUBST_NO_LF
]
});
SUBST.contains = [
INTERPOLATED_VERBATIM_STRING,
@ -205,28 +226,26 @@ export default function csharp(hljs) {
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
NUMBERS,
hljs.inherit(hljs.C_BLOCK_COMMENT_MODE, {illegal: /\n/})
hljs.inherit(hljs.C_BLOCK_COMMENT_MODE, { illegal: /\n/ })
];
var STRING = {
variants: [
INTERPOLATED_VERBATIM_STRING,
INTERPOLATED_STRING,
VERBATIM_STRING,
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE
]
};
const STRING = { variants: [
INTERPOLATED_VERBATIM_STRING,
INTERPOLATED_STRING,
VERBATIM_STRING,
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE
] };
var GENERIC_MODIFIER = {
const GENERIC_MODIFIER = {
begin: "<",
end: ">",
contains: [
{ beginKeywords: "in out"},
{ beginKeywords: "in out" },
TITLE_MODE
]
};
var TYPE_IDENT_RE = hljs.IDENT_RE + '(<' + hljs.IDENT_RE + '(\\s*,\\s*' + hljs.IDENT_RE + ')*>)?(\\[\\])?';
var AT_IDENTIFIER = {
const TYPE_IDENT_RE = hljs.IDENT_RE + '(<' + hljs.IDENT_RE + '(\\s*,\\s*' + hljs.IDENT_RE + ')*>)?(\\[\\])?';
const AT_IDENTIFIER = {
// prevents expressions like `@class` from incorrect flagging
// `class` as a keyword
begin: "@" + hljs.IDENT_RE,
@ -235,7 +254,10 @@ export default function csharp(hljs) {
return {
name: 'C#',
aliases: ['cs', 'c#'],
aliases: [
'cs',
'c#'
],
keywords: KEYWORDS,
illegal: /::/,
contains: [
@ -249,13 +271,13 @@ export default function csharp(hljs) {
className: 'doctag',
variants: [
{
begin: '///', relevance: 0
begin: '///',
relevance: 0
},
{ begin: '<!--|-->' },
{
begin: '<!--|-->'
},
{
begin: '</?', end: '>'
begin: '</?',
end: '>'
}
]
}
@ -266,10 +288,9 @@ export default function csharp(hljs) {
hljs.C_BLOCK_COMMENT_MODE,
{
className: 'meta',
begin: '#', end: '$',
keywords: {
'meta-keyword': 'if else elif endif define undef warning error line region endregion pragma checksum'
}
begin: '#',
end: '$',
keywords: { keyword: 'if else elif endif define undef warning error line region endregion pragma checksum' }
},
STRING,
NUMBERS,
@ -312,9 +333,16 @@ export default function csharp(hljs) {
{
// [Attributes("")]
className: 'meta',
begin: '^\\s*\\[', excludeBegin: true, end: '\\]', excludeEnd: true,
begin: '^\\s*\\[(?=[\\w])',
excludeBegin: true,
end: '\\]',
excludeEnd: true,
contains: [
{className: 'meta-string', begin: /"/, end: /"/}
{
className: 'string',
begin: /"/,
end: /"/
}
]
},
{
@ -325,8 +353,10 @@ export default function csharp(hljs) {
},
{
className: 'function',
begin: '(' + TYPE_IDENT_RE + '\\s+)+' + hljs.IDENT_RE + '\\s*(<.+>\\s*)?\\(', returnBegin: true,
end: /\s*[{;=]/, excludeEnd: true,
begin: '(' + TYPE_IDENT_RE + '\\s+)+' + hljs.IDENT_RE + '\\s*(<[^=]+>\\s*)?\\(',
returnBegin: true,
end: /\s*[{;=]/,
excludeEnd: true,
keywords: KEYWORDS,
contains: [
// prevents these from being highlighted `title`
@ -335,16 +365,19 @@ export default function csharp(hljs) {
relevance: 0
},
{
begin: hljs.IDENT_RE + '\\s*(<.+>\\s*)?\\(', returnBegin: true,
begin: hljs.IDENT_RE + '\\s*(<[^=]+>\\s*)?\\(',
returnBegin: true,
contains: [
hljs.TITLE_MODE,
GENERIC_MODIFIER
],
relevance: 0
},
{ match: /\(\)/ },
{
className: 'params',
begin: /\(/, end: /\)/,
begin: /\(/,
end: /\)/,
excludeBegin: true,
excludeEnd: true,
keywords: KEYWORDS,

View file

@ -40,31 +40,127 @@ Category: common, enterprise
Website: https://www.java.com/
*/
export default function java(hljs) {
var JAVA_IDENT_RE = '[\u00C0-\u02B8a-zA-Z_$][\u00C0-\u02B8a-zA-Z_$0-9]*';
var GENERIC_IDENT_RE = JAVA_IDENT_RE + '(<' + JAVA_IDENT_RE + '(\\s*,\\s*' + JAVA_IDENT_RE + ')*>)?';
var KEYWORDS = 'false synchronized int abstract float private char boolean var static null if const ' +
'for true while long strictfp finally protected import native final void ' +
'enum else break transient catch instanceof byte super volatile case assert short ' +
'package default double public try this switch continue throws protected public private ' +
'module requires exports do';
/**
* Allows recursive regex expressions to a given depth
*
* ie: recurRegex("(abc~~~)", /~~~/g, 2) becomes:
* (abc(abc(abc)))
*
* @param {string} re
* @param {RegExp} substitution (should be a g mode regex)
* @param {number} depth
* @returns {string}``
*/
function recurRegex(re, substitution, depth) {
if (depth === -1) return "";
var ANNOTATION = {
return re.replace(substitution, _ => {
return recurRegex(re, substitution, depth - 1);
});
}
/** @type LanguageFn */
export default function java(hljs) {
const regex = hljs.regex;
const JAVA_IDENT_RE = '[\u00C0-\u02B8a-zA-Z_$][\u00C0-\u02B8a-zA-Z_$0-9]*';
const GENERIC_IDENT_RE = JAVA_IDENT_RE
+ recurRegex('(?:<' + JAVA_IDENT_RE + '~~~(?:\\s*,\\s*' + JAVA_IDENT_RE + '~~~)*>)?', /~~~/g, 2);
const MAIN_KEYWORDS = [
'synchronized',
'abstract',
'private',
'var',
'static',
'if',
'const ',
'for',
'while',
'strictfp',
'finally',
'protected',
'import',
'native',
'final',
'void',
'enum',
'else',
'break',
'transient',
'catch',
'instanceof',
'volatile',
'case',
'assert',
'package',
'default',
'public',
'try',
'switch',
'continue',
'throws',
'protected',
'public',
'private',
'module',
'requires',
'exports',
'do',
'sealed'
];
const BUILT_INS = [
'super',
'this'
];
const LITERALS = [
'false',
'true',
'null'
];
const TYPES = [
'char',
'boolean',
'long',
'float',
'int',
'byte',
'short',
'double'
];
const KEYWORDS = {
keyword: MAIN_KEYWORDS,
literal: LITERALS,
type: TYPES,
built_in: BUILT_INS
};
const ANNOTATION = {
className: 'meta',
begin: '@' + JAVA_IDENT_RE,
contains: [
{
begin: /\(/,
end: /\)/,
contains: ["self"] // allow nested () inside our annotation
},
contains: [ "self" ] // allow nested () inside our annotation
}
]
};
const NUMBER = NUMERIC;
const PARAMS = {
className: 'params',
begin: /\(/,
end: /\)/,
keywords: KEYWORDS,
relevance: 0,
contains: [ hljs.C_BLOCK_COMMENT_MODE ],
endsParent: true
};
return {
name: 'Java',
aliases: ['jsp'],
aliases: [ 'jsp' ],
keywords: KEYWORDS,
illegal: /<\/|#/,
contains: [
@ -76,7 +172,8 @@ export default function java(hljs) {
contains: [
{
// eat up @'s in emails to prevent them to be recognized as doctags
begin: /\w+@/, relevance: 0
begin: /\w+@/,
relevance: 0
},
{
className: 'doctag',
@ -93,16 +190,58 @@ export default function java(hljs) {
},
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE,
{
begin: /"""/,
end: /"""/,
className: "string",
contains: [ hljs.BACKSLASH_ESCAPE ]
},
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
{
className: 'class',
beginKeywords: 'class interface enum', end: /[{;=]/, excludeEnd: true,
keywords: 'class interface enum',
illegal: /[:"\[\]]/,
match: [
/\b(?:class|interface|enum|extends|implements|new)/,
/\s+/,
JAVA_IDENT_RE
],
className: {
1: "keyword",
3: "title.class"
}
},
{
// Exceptions for hyphenated keywords
match: /non-sealed/,
scope: "keyword"
},
{
begin: [
regex.concat(/(?!else)/, JAVA_IDENT_RE),
/\s+/,
JAVA_IDENT_RE,
/\s+/,
/=(?!=)/
],
className: {
1: "type",
3: "variable",
5: "operator"
}
},
{
begin: [
/record/,
/\s+/,
JAVA_IDENT_RE
],
className: {
1: "keyword",
3: "title.class"
},
contains: [
{ beginKeywords: 'extends implements' },
hljs.UNDERSCORE_TITLE_MODE
PARAMS,
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
]
},
{
@ -112,54 +251,25 @@ export default function java(hljs) {
relevance: 0
},
{
className: 'class',
begin: 'record\\s+' + hljs.UNDERSCORE_IDENT_RE + '\\s*\\(',
returnBegin: true,
excludeEnd: true,
end: /[{;=]/,
keywords: KEYWORDS,
contains: [
{ beginKeywords: "record" },
{
begin: hljs.UNDERSCORE_IDENT_RE + '\\s*\\(',
returnBegin: true,
relevance: 0,
contains: [hljs.UNDERSCORE_TITLE_MODE]
},
{
className: 'params',
begin: /\(/, end: /\)/,
keywords: KEYWORDS,
relevance: 0,
contains: [
hljs.C_BLOCK_COMMENT_MODE
]
},
hljs.C_LINE_COMMENT_MODE,
hljs.C_BLOCK_COMMENT_MODE
]
},
{
className: 'function',
begin: '(' + GENERIC_IDENT_RE + '\\s+)+' + hljs.UNDERSCORE_IDENT_RE + '\\s*\\(', returnBegin: true, end: /[{;=]/,
excludeEnd: true,
begin: [
'(?:' + GENERIC_IDENT_RE + '\\s+)',
hljs.UNDERSCORE_IDENT_RE,
/\s*(?=\()/
],
className: { 2: "title.function" },
keywords: KEYWORDS,
contains: [
{
begin: hljs.UNDERSCORE_IDENT_RE + '\\s*\\(', returnBegin: true,
relevance: 0,
contains: [hljs.UNDERSCORE_TITLE_MODE]
},
{
className: 'params',
begin: /\(/, end: /\)/,
begin: /\(/,
end: /\)/,
keywords: KEYWORDS,
relevance: 0,
contains: [
ANNOTATION,
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
NUMBER,
NUMERIC,
hljs.C_BLOCK_COMMENT_MODE
]
},
@ -167,7 +277,7 @@ export default function java(hljs) {
hljs.C_BLOCK_COMMENT_MODE
]
},
NUMBER,
NUMERIC,
ANNOTATION
]
};

View file

@ -51,41 +51,61 @@ const LITERALS = [
"Infinity"
];
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
const TYPES = [
"Intl",
"DataView",
"Number",
"Math",
"Date",
"String",
"RegExp",
// Fundamental objects
"Object",
"Function",
"Boolean",
"Error",
"Symbol",
// numbers and dates
"Math",
"Date",
"Number",
"BigInt",
// text
"String",
"RegExp",
// Indexed collections
"Array",
"Float32Array",
"Float64Array",
"Int8Array",
"Uint8Array",
"Uint8ClampedArray",
"Int16Array",
"Int32Array",
"Uint16Array",
"Uint32Array",
"BigInt64Array",
"BigUint64Array",
// Keyed collections
"Set",
"Map",
"WeakSet",
"WeakMap",
"Proxy",
"Reflect",
// Structured data
"ArrayBuffer",
"SharedArrayBuffer",
"Atomics",
"DataView",
"JSON",
// Control abstraction objects
"Promise",
"Float64Array",
"Int16Array",
"Int32Array",
"Int8Array",
"Uint16Array",
"Uint32Array",
"Float32Array",
"Array",
"Uint8Array",
"Uint8ClampedArray",
"ArrayBuffer"
"Generator",
"GeneratorFunction",
"AsyncFunction",
// Reflection
"Reflect",
"Proxy",
// Internationalization
"Intl",
// WebAssembly
"WebAssembly"
];
const ERROR_TYPES = [
"Error",
"EvalError",
"InternalError",
"RangeError",
@ -131,53 +151,20 @@ const BUILT_IN_VARIABLES = [
const BUILT_INS = [].concat(
BUILT_IN_GLOBALS,
BUILT_IN_VARIABLES,
TYPES,
ERROR_TYPES
);
/**
* @param {string} value
* @returns {RegExp}
* */
/**
* @param {RegExp | string } re
* @returns {string}
*/
function source(re) {
if (!re) return null;
if (typeof re === "string") return re;
return re.source;
}
/**
* @param {RegExp | string } re
* @returns {string}
*/
function lookahead(re) {
return concat('(?=', re, ')');
}
/**
* @param {...(RegExp | string) } args
* @returns {string}
*/
function concat(...args) {
const joined = args.map((x) => source(x)).join("");
return joined;
}
/*
Language: JavaScript
Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.
Category: common, scripting
Category: common, scripting, web
Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript
*/
/** @type LanguageFn */
export default function javascript(hljs) {
const regex = hljs.regex;
/**
* Takes a string like "<Booger" and checks to see
* if we can find a matching "</Booger" later in the
@ -196,6 +183,8 @@ export default function javascript(hljs) {
begin: '<>',
end: '</>'
};
// to avoid some special cases inside isTrulyOpeningTag
const XML_SELF_CLOSING = /<[A-Za-z0-9\\._:-]+\s*\/>/;
const XML_TAG = {
begin: /<[A-Za-z0-9\\._:-]+/,
end: /\/[A-Za-z0-9\\._:-]+>|\/>/,
@ -206,15 +195,20 @@ export default function javascript(hljs) {
isTrulyOpeningTag: (match, response) => {
const afterMatchIndex = match[0].length + match.index;
const nextChar = match.input[afterMatchIndex];
// nested type?
// HTML should not include another raw `<` inside a tag
// But a type might: `<Array<Array<number>>`, etc.
if (nextChar === "<") {
if (
// HTML should not include another raw `<` inside a tag
// nested type?
// `<Array<Array<number>>`, etc.
nextChar === "<" ||
// the , gives away that this is not HTML
// `<T, A extends keyof T, V>`
nextChar === ",") {
response.ignoreMatch();
return;
}
// <something>
// This is now either a tag or a type.
// `<something>`
// Quite possibly a tag, lets look for a matching closing tag...
if (nextChar === ">") {
// if we cannot find a matching closing tag, then we
// will ignore it
@ -222,13 +216,30 @@ export default function javascript(hljs) {
response.ignoreMatch();
}
}
// `<blah />` (self-closing)
// handled by simpleSelfClosing rule
// `<From extends string>`
// technically this could be HTML, but it smells like a type
let m;
const afterMatch = match.input.substring(afterMatchIndex);
// NOTE: This is ugh, but added specifically for https://github.com/highlightjs/highlight.js/issues/3276
if ((m = afterMatch.match(/^\s+extends\s+/))) {
if (m.index === 0) {
response.ignoreMatch();
// eslint-disable-next-line no-useless-return
return;
}
}
}
};
const KEYWORDS$1 = {
$pattern: IDENT_RE,
keyword: KEYWORDS.join(" "),
literal: LITERALS.join(" "),
built_in: BUILT_INS.join(" ")
keyword: KEYWORDS,
literal: LITERALS,
built_in: BUILT_INS,
"variable.language": BUILT_IN_VARIABLES
};
// https://tc39.es/ecma262/#sec-literals-numeric-literals
@ -309,13 +320,19 @@ export default function javascript(hljs) {
relevance: 0,
contains: [
{
className: 'doctag',
begin: '@[A-Za-z]+',
begin: '(?=@[A-Za-z]+)',
relevance: 0,
contains: [
{
className: 'doctag',
begin: '@[A-Za-z]+'
},
{
className: 'type',
begin: '\\{',
end: '\\}',
excludeEnd: true,
excludeBegin: true,
relevance: 0
},
{
@ -350,7 +367,9 @@ export default function javascript(hljs) {
CSS_TEMPLATE,
TEMPLATE_STRING,
NUMBER,
hljs.REGEXP_MODE
// This is intentional:
// See https://github.com/highlightjs/highlight.js/issues/3288
// hljs.REGEXP_MODE
];
SUBST.contains = SUBST_INTERNALS
.concat({
@ -383,12 +402,188 @@ export default function javascript(hljs) {
contains: PARAMS_CONTAINS
};
// ES6 classes
const CLASS_OR_EXTENDS = {
variants: [
// class Car extends vehicle
{
match: [
/class/,
/\s+/,
IDENT_RE$1,
/\s+/,
/extends/,
/\s+/,
regex.concat(IDENT_RE$1, "(", regex.concat(/\./, IDENT_RE$1), ")*")
],
scope: {
1: "keyword",
3: "title.class",
5: "keyword",
7: "title.class.inherited"
}
},
// class Car
{
match: [
/class/,
/\s+/,
IDENT_RE$1
],
scope: {
1: "keyword",
3: "title.class"
}
},
]
};
const CLASS_REFERENCE = {
relevance: 0,
match:
regex.either(
// Hard coded exceptions
/\bJSON/,
// Float32Array, OutT
/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,
// CSSFactory, CSSFactoryT
/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,
// FPs, FPsT
/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/,
// P
// single letters are not highlighted
// BLAH
// this will be flagged as a UPPER_CASE_CONSTANT instead
),
className: "title.class",
keywords: {
_: [
// se we still get relevance credit for JS library classes
...TYPES,
...ERROR_TYPES
]
}
};
const USE_STRICT = {
label: "use_strict",
className: 'meta',
relevance: 10,
begin: /^\s*['"]use (strict|asm)['"]/
};
const FUNCTION_DEFINITION = {
variants: [
{
match: [
/function/,
/\s+/,
IDENT_RE$1,
/(?=\s*\()/
]
},
// anonymous function
{
match: [
/function/,
/\s*(?=\()/
]
}
],
className: {
1: "keyword",
3: "title.function"
},
label: "func.def",
contains: [ PARAMS ],
illegal: /%/
};
const UPPER_CASE_CONSTANT = {
relevance: 0,
match: /\b[A-Z][A-Z_0-9]+\b/,
className: "variable.constant"
};
function noneOf(list) {
return regex.concat("(?!", list.join("|"), ")");
}
const FUNCTION_CALL = {
match: regex.concat(
/\b/,
noneOf([
...BUILT_IN_GLOBALS,
"super"
]),
IDENT_RE$1, regex.lookahead(/\(/)),
className: "title.function",
relevance: 0
};
const PROPERTY_ACCESS = {
begin: regex.concat(/\./, regex.lookahead(
regex.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/)
)),
end: IDENT_RE$1,
excludeBegin: true,
keywords: "prototype",
className: "property",
relevance: 0
};
const GETTER_OR_SETTER = {
match: [
/get|set/,
/\s+/,
IDENT_RE$1,
/(?=\()/
],
className: {
1: "keyword",
3: "title.function"
},
contains: [
{ // eat to avoid empty params
begin: /\(\)/
},
PARAMS
]
};
const FUNC_LEAD_IN_RE = '(\\(' +
'[^()]*(\\(' +
'[^()]*(\\(' +
'[^()]*' +
'\\)[^()]*)*' +
'\\)[^()]*)*' +
'\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>';
const FUNCTION_VARIABLE = {
match: [
/const|var|let/, /\s+/,
IDENT_RE$1, /\s*/,
/=\s*/,
/(async\s*)?/, // async is optional
regex.lookahead(FUNC_LEAD_IN_RE)
],
keywords: "async",
className: {
1: "keyword",
3: "title.function"
},
contains: [
PARAMS
]
};
return {
name: 'Javascript',
aliases: ['js', 'jsx', 'mjs', 'cjs'],
keywords: KEYWORDS$1,
// this will be extended by TypeScript
exports: { PARAMS_CONTAINS },
exports: { PARAMS_CONTAINS, CLASS_REFERENCE },
illegal: /#(?![$_A-z])/,
contains: [
hljs.SHEBANG({
@ -396,12 +591,7 @@ export default function javascript(hljs) {
binary: "node",
relevance: 5
}),
{
label: "use_strict",
className: 'meta',
relevance: 10,
begin: /^\s*['"]use (strict|asm)['"]/
},
USE_STRICT,
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE,
HTML_TEMPLATE,
@ -409,35 +599,17 @@ export default function javascript(hljs) {
TEMPLATE_STRING,
COMMENT,
NUMBER,
{ // object attr container
begin: concat(/[{,\n]\s*/,
// we need to look ahead to make sure that we actually have an
// attribute coming up so we don't steal a comma from a potential
// "value" container
//
// NOTE: this might not work how you think. We don't actually always
// enter this mode and stay. Instead it might merely match `,
// <comments up next>` and then immediately end after the , because it
// fails to find any actual attrs. But this still does the job because
// it prevents the value contain rule from grabbing this instead and
// prevening this rule from firing when we actually DO have keys.
lookahead(concat(
// we also need to allow for multiple possible comments inbetween
// the first key:value pairing
/(((\/\/.*$)|(\/\*(\*[^/]|[^*])*\*\/))\s*)*/,
IDENT_RE$1 + '\\s*:'))),
relevance: 0,
contains: [
{
className: 'attr',
begin: IDENT_RE$1 + lookahead('\\s*:'),
relevance: 0
}
]
CLASS_REFERENCE,
{
className: 'attr',
begin: IDENT_RE$1 + regex.lookahead(':'),
relevance: 0
},
FUNCTION_VARIABLE,
{ // "value" container
begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
keywords: 'return throw case',
relevance: 0,
contains: [
COMMENT,
hljs.REGEXP_MODE,
@ -446,13 +618,7 @@ export default function javascript(hljs) {
// we have to count the parens to make sure we actually have the
// correct bounding ( ) before the =>. There could be any number of
// sub-expressions inside also surrounded by parens.
begin: '(\\(' +
'[^()]*(\\(' +
'[^()]*(\\(' +
'[^()]*' +
'\\)[^()]*)*' +
'\\)[^()]*)*' +
'\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>',
begin: FUNC_LEAD_IN_RE,
returnBegin: true,
end: '\\s*=>',
contains: [
@ -481,17 +647,17 @@ export default function javascript(hljs) {
]
},
{ // could be a comma delimited list of params to a function call
begin: /,/, relevance: 0
begin: /,/,
relevance: 0
},
{
className: '',
begin: /\s/,
end: /\s*/,
skip: true
match: /\s+/,
relevance: 0
},
{ // JSX
variants: [
{ begin: FRAGMENT.begin, end: FRAGMENT.end },
{ match: XML_SELF_CLOSING },
{
begin: XML_TAG.begin,
// we carefully check the opening tag to see if it truly
@ -511,32 +677,18 @@ export default function javascript(hljs) {
]
}
],
relevance: 0
},
{
className: 'function',
beginKeywords: 'function',
end: /[{;]/,
excludeEnd: true,
keywords: KEYWORDS$1,
contains: [
'self',
hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),
PARAMS
],
illegal: /%/
},
FUNCTION_DEFINITION,
{
// prevent this from getting swallowed up by function
// since they appear "function like"
beginKeywords: "while if switch catch for"
},
{
className: 'function',
// we have to count the parens to make sure we actually have the correct
// bounding ( ). There could be any number of sub-expressions inside
// also surrounded by parens.
begin: hljs.UNDERSCORE_IDENT_RE +
begin: '\\b(?!function)' + hljs.UNDERSCORE_IDENT_RE +
'\\(' + // first parens
'[^()]*(\\(' +
'[^()]*(\\(' +
@ -545,54 +697,36 @@ export default function javascript(hljs) {
'\\)[^()]*)*' +
'\\)\\s*\\{', // end parens
returnBegin:true,
label: "func.def",
contains: [
PARAMS,
hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),
hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1, className: "title.function" })
]
},
// catch ... so it won't trigger the property rule below
{
match: /\.\.\./,
relevance: 0
},
PROPERTY_ACCESS,
// hack: prevents detection of keywords in some circumstances
// .keyword()
// $keyword = x
{
variants: [
{ begin: '\\.' + IDENT_RE$1 },
{ begin: '\\$' + IDENT_RE$1 }
],
match: '\\$' + IDENT_RE$1,
relevance: 0
},
{ // ES6 class
className: 'class',
beginKeywords: 'class',
end: /[{;=]/,
excludeEnd: true,
illegal: /[:"[\]]/,
contains: [
{ beginKeywords: 'extends' },
hljs.UNDERSCORE_TITLE_MODE
]
},
{
begin: /\b(?=constructor)/,
end: /[{;]/,
excludeEnd: true,
contains: [
hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),
'self',
PARAMS
]
match: [ /\bconstructor(?=\s*\()/ ],
className: { 1: "title.function" },
contains: [ PARAMS ]
},
FUNCTION_CALL,
UPPER_CASE_CONSTANT,
CLASS_OR_EXTENDS,
GETTER_OR_SETTER,
{
begin: '(get|set)\\s+(?=' + IDENT_RE$1 + '\\()',
end: /\{/,
keywords: "get set",
contains: [
hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1 }),
{ begin: /\(\)/ }, // eat to avoid empty params
PARAMS
]
},
{
begin: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
match: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
}
]
};

View file

@ -6,6 +6,8 @@ Category: common
*/
export default function python(hljs) {
const regex = hljs.regex;
const IDENT_RE = /[\p{XID_Start}_]\p{XID_Continue}*/u;
const RESERVED_WORDS = [
'and',
'as',
@ -13,6 +15,7 @@ export default function python(hljs) {
'async',
'await',
'break',
'case',
'class',
'continue',
'def',
@ -22,7 +25,6 @@ export default function python(hljs) {
'except',
'finally',
'for',
'',
'from',
'global',
'if',
@ -30,6 +32,7 @@ export default function python(hljs) {
'in',
'is',
'lambda',
'match',
'nonlocal|10',
'not',
'or',
@ -39,7 +42,7 @@ export default function python(hljs) {
'try',
'while',
'with',
'yield',
'yield'
];
const BUILT_INS = [
@ -111,7 +114,7 @@ export default function python(hljs) {
'tuple',
'type',
'vars',
'zip',
'zip'
];
const LITERALS = [
@ -120,22 +123,45 @@ export default function python(hljs) {
'False',
'None',
'NotImplemented',
'True',
'True'
];
// https://docs.python.org/3/library/typing.html
// TODO: Could these be supplemented by a CamelCase matcher in certain
// contexts, leaving these remaining only for relevance hinting?
const TYPES = [
"Any",
"Callable",
"Coroutine",
"Dict",
"List",
"Literal",
"Generic",
"Optional",
"Sequence",
"Set",
"Tuple",
"Type",
"Union"
];
const KEYWORDS = {
keyword: RESERVED_WORDS.join(' '),
built_in: BUILT_INS.join(' '),
literal: LITERALS.join(' ')
$pattern: /[A-Za-z]\w+|__\w+__/,
keyword: RESERVED_WORDS,
built_in: BUILT_INS,
literal: LITERALS,
type: TYPES
};
const PROMPT = {
className: 'meta', begin: /^(>>>|\.\.\.) /
className: 'meta',
begin: /^(>>>|\.\.\.) /
};
const SUBST = {
className: 'subst',
begin: /\{/, end: /\}/,
begin: /\{/,
end: /\}/,
keywords: KEYWORDS,
illegal: /#/
};
@ -147,47 +173,81 @@ export default function python(hljs) {
const STRING = {
className: 'string',
contains: [hljs.BACKSLASH_ESCAPE],
contains: [ hljs.BACKSLASH_ESCAPE ],
variants: [
{
begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/, end: /'''/,
contains: [hljs.BACKSLASH_ESCAPE, PROMPT],
begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,
end: /'''/,
contains: [
hljs.BACKSLASH_ESCAPE,
PROMPT
],
relevance: 10
},
{
begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/, end: /"""/,
contains: [hljs.BACKSLASH_ESCAPE, PROMPT],
begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,
end: /"""/,
contains: [
hljs.BACKSLASH_ESCAPE,
PROMPT
],
relevance: 10
},
{
begin: /([fF][rR]|[rR][fF]|[fF])'''/, end: /'''/,
contains: [hljs.BACKSLASH_ESCAPE, PROMPT, LITERAL_BRACKET, SUBST]
begin: /([fF][rR]|[rR][fF]|[fF])'''/,
end: /'''/,
contains: [
hljs.BACKSLASH_ESCAPE,
PROMPT,
LITERAL_BRACKET,
SUBST
]
},
{
begin: /([fF][rR]|[rR][fF]|[fF])"""/, end: /"""/,
contains: [hljs.BACKSLASH_ESCAPE, PROMPT, LITERAL_BRACKET, SUBST]
begin: /([fF][rR]|[rR][fF]|[fF])"""/,
end: /"""/,
contains: [
hljs.BACKSLASH_ESCAPE,
PROMPT,
LITERAL_BRACKET,
SUBST
]
},
{
begin: /([uU]|[rR])'/, end: /'/,
begin: /([uU]|[rR])'/,
end: /'/,
relevance: 10
},
{
begin: /([uU]|[rR])"/, end: /"/,
begin: /([uU]|[rR])"/,
end: /"/,
relevance: 10
},
{
begin: /([bB]|[bB][rR]|[rR][bB])'/, end: /'/
begin: /([bB]|[bB][rR]|[rR][bB])'/,
end: /'/
},
{
begin: /([bB]|[bB][rR]|[rR][bB])"/, end: /"/
begin: /([bB]|[bB][rR]|[rR][bB])"/,
end: /"/
},
{
begin: /([fF][rR]|[rR][fF]|[fF])'/, end: /'/,
contains: [hljs.BACKSLASH_ESCAPE, LITERAL_BRACKET, SUBST]
begin: /([fF][rR]|[rR][fF]|[fF])'/,
end: /'/,
contains: [
hljs.BACKSLASH_ESCAPE,
LITERAL_BRACKET,
SUBST
]
},
{
begin: /([fF][rR]|[rR][fF]|[fF])"/, end: /"/,
contains: [hljs.BACKSLASH_ESCAPE, LITERAL_BRACKET, SUBST]
begin: /([fF][rR]|[rR][fF]|[fF])"/,
end: /"/,
contains: [
hljs.BACKSLASH_ESCAPE,
LITERAL_BRACKET,
SUBST
]
},
hljs.APOS_STRING_MODE,
hljs.QUOTE_STRING_MODE
@ -197,8 +257,15 @@ export default function python(hljs) {
// https://docs.python.org/3.9/reference/lexical_analysis.html#numeric-literals
const digitpart = '[0-9](_?[0-9])*';
const pointfloat = `(\\b(${digitpart}))?\\.(${digitpart})|\\b(${digitpart})\\.`;
// Whitespace after a number (or any lexical token) is needed only if its absence
// would change the tokenization
// https://docs.python.org/3.9/reference/lexical_analysis.html#whitespace-between-tokens
// We deviate slightly, requiring a word boundary or a keyword
// to avoid accidentally recognizing *prefixes* (e.g., `0` in `0x41` or `08` or `0__1`)
const lookahead = `\\b|${RESERVED_WORDS.join('|')}`;
const NUMBER = {
className: 'number', relevance: 0,
className: 'number',
relevance: 0,
variants: [
// exponentfloat, pointfloat
// https://docs.python.org/3.9/reference/lexical_analysis.html#floating-point-literals
@ -210,8 +277,12 @@ export default function python(hljs) {
// and we don't want to mishandle e.g. `0..hex()`; this should be safe
// because both MUST contain a decimal point and so cannot be confused with
// the interior part of an identifier
{ begin: `(\\b(${digitpart})|(${pointfloat}))[eE][+-]?(${digitpart})[jJ]?\\b` },
{ begin: `(${pointfloat})[jJ]?` },
{
begin: `(\\b(${digitpart})|(${pointfloat}))[eE][+-]?(${digitpart})[jJ]?(?=${lookahead})`
},
{
begin: `(${pointfloat})[jJ]?`
},
// decinteger, bininteger, octinteger, hexinteger
// https://docs.python.org/3.9/reference/lexical_analysis.html#integer-literals
@ -219,68 +290,142 @@ export default function python(hljs) {
// https://docs.python.org/2.7/reference/lexical_analysis.html#integer-and-long-integer-literals
// decinteger is optionally imaginary
// https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals
{ begin: '\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?\\b' },
{ begin: '\\b0[bB](_?[01])+[lL]?\\b' },
{ begin: '\\b0[oO](_?[0-7])+[lL]?\\b' },
{ begin: '\\b0[xX](_?[0-9a-fA-F])+[lL]?\\b' },
{
begin: `\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${lookahead})`
},
{
begin: `\\b0[bB](_?[01])+[lL]?(?=${lookahead})`
},
{
begin: `\\b0[oO](_?[0-7])+[lL]?(?=${lookahead})`
},
{
begin: `\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${lookahead})`
},
// imagnumber (digitpart-based)
// https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals
{ begin: `\\b(${digitpart})[jJ]\\b` },
{
begin: `\\b(${digitpart})[jJ](?=${lookahead})`
}
]
};
const COMMENT_TYPE = {
className: "comment",
begin: regex.lookahead(/# type:/),
end: /$/,
keywords: KEYWORDS,
contains: [
{ // prevent keywords from coloring `type`
begin: /# type:/
},
// comment within a datatype comment includes no keywords
{
begin: /#/,
end: /\b\B/,
endsWithParent: true
}
]
};
const PARAMS = {
className: 'params',
variants: [
// Exclude params at functions without params
{begin: /\(\s*\)/, skip: true, className: null },
// Exclude params in functions without params
{
begin: /\(/, end: /\)/, excludeBegin: true, excludeEnd: true,
keywords: KEYWORDS,
contains: ['self', PROMPT, NUMBER, STRING, hljs.HASH_COMMENT_MODE],
className: "",
begin: /\(\s*\)/,
skip: true
},
],
{
begin: /\(/,
end: /\)/,
excludeBegin: true,
excludeEnd: true,
keywords: KEYWORDS,
contains: [
'self',
PROMPT,
NUMBER,
STRING,
hljs.HASH_COMMENT_MODE
]
}
]
};
SUBST.contains = [STRING, NUMBER, PROMPT];
SUBST.contains = [
STRING,
NUMBER,
PROMPT
];
return {
name: 'Python',
aliases: ['py', 'gyp', 'ipython'],
aliases: [
'py',
'gyp',
'ipython'
],
unicodeRegex: true,
keywords: KEYWORDS,
illegal: /(<\/|->|\?)|=>/,
contains: [
PROMPT,
NUMBER,
// eat "if" prior to string so that it won't accidentally be
// labeled as an f-string as in:
{ begin: /\bself\b/, }, // very common convention
{ beginKeywords: "if", relevance: 0 },
{
// very common convention
begin: /\bself\b/
},
{
// eat "if" prior to string so that it won't accidentally be
// labeled as an f-string
beginKeywords: "if",
relevance: 0
},
STRING,
COMMENT_TYPE,
hljs.HASH_COMMENT_MODE,
{
variants: [
{className: 'function', beginKeywords: 'def'},
{className: 'class', beginKeywords: 'class'}
match: [
/\bdef/, /\s+/,
IDENT_RE,
],
end: /:/,
illegal: /[${=;\n,]/,
contains: [
hljs.UNDERSCORE_TITLE_MODE,
PARAMS,
scope: {
1: "keyword",
3: "title.function"
},
contains: [ PARAMS ]
},
{
variants: [
{
begin: /->/, endsWithParent: true,
keywords: 'None'
match: [
/\bclass/, /\s+/,
IDENT_RE, /\s*/,
/\(\s*/, IDENT_RE,/\s*\)/
],
},
{
match: [
/\bclass/, /\s+/,
IDENT_RE
],
}
]
],
scope: {
1: "keyword",
3: "title.class",
6: "title.class.inherited",
}
},
{
className: 'meta',
begin: /^[\t ]*@/, end: /(?=#)|$/,
contains: [NUMBER, PARAMS, STRING]
},
{
begin: /\b(print|exec)\(/ // dont highlight keywords-turned-functions in Python 3
begin: /^[\t ]*@/,
end: /(?=#)|$/,
contains: [
NUMBER,
PARAMS,
STRING
]
}
]
};

View file

@ -1,72 +0,0 @@
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
color: #8e908c;
}
/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
color: #c82829;
}
/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
color: #f5871f;
}
/* Tomorrow Yellow */
.hljs-attribute {
color: #eab700;
}
/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #718c00;
}
/* Tomorrow Blue */
.hljs-title,
.hljs-section {
color: #4271ae;
}
/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #8959a8;
}
.hljs {
display: block;
overflow-x: auto;
background: white;
color: #4d4d4c;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -4,9 +4,9 @@ set +x
# Pick a stable release revision from here:
# https://github.com/highlightjs/highlight.js/releases
RELEASE_REVISION="af20048d5c601d6e30016d8171317bfdf8a6c242"
RELEASE_REVISION="bed790f3f3515ebcb92896ab23a518f835008233"
LANGUAGES="javascript python csharp java"
STYLES="tomorrow.css"
STYLES="github*.css"
trap "cd $(pwd -P)" EXIT
SCRIPT_PATH="$(cd "$(dirname "$0")" ; pwd -P)"