diff --git a/.editorconfig b/.editorconfig
index 6fbe6bf..b0589e0 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -15,3 +15,11 @@ insert_final_newline = unset
trim_trailing_whitespace = unset
indent_style = unset
indent_size = unset
+
+[/resources/syntaxhighlight-*]
+end_of_line = lf
+insert_final_newline = true
+charset = utf-8
+indent_style = space
+indent_size = 4
+trim_trailing_whitespace = true
diff --git a/README.md b/README.md
index c8d7dd6..f9bd576 100644
--- a/README.md
+++ b/README.md
@@ -4,4 +4,4 @@ SyntaxHighlight but with PrismJS.
## Licenses
SyntaxHighlight_PrismJS is licensed under GPL v3.0 or later.
-Files under /resources are copyrighted by PrismJS and licensed under conditions written at https://github.com/PrismJS/prism/blob/master/LICENSE.
+Some files under /resources are copyrighted by PrismJS and licensed under conditions written at https://github.com/PrismJS/prism/blob/master/LICENSE.
diff --git a/extension.json b/extension.json
index 48d2be0..10169e2 100644
--- a/extension.json
+++ b/extension.json
@@ -13,11 +13,16 @@
},
"Hooks": {
"ParserFirstCallInit": "main",
- "EditPage::showEditForm:initial": "main"
+ "EditPage::showEditForm:initial": "main",
+ "GetPreferences": "main",
+ "ParserOptionsRegister": "main"
},
"HookHandlers": {
"main": {
- "class": "SyntaxHighlight"
+ "class": "SyntaxHighlight",
+ "services": [
+ "UserOptionsLookup"
+ ]
}
},
"MessagesDirs": {
@@ -25,10 +30,12 @@
"i18n"
]
},
+ "DefaultUserOptions": {
+ "syntaxhighlight-theme": "default"
+ },
"manifest_version": 2,
"ResourceModules": {
"ext.SyntaxHighlight.core": {
- "styles": "prism.css",
"packageFiles": "prism-core.min.js",
"localBasePath": "resources",
"remoteExtPath": "SyntaxHighlight_PrismJS/resources"
@@ -54,8 +61,48 @@
"syntaxhighlight-wikieditor-button"
]
},
+ "ext.SyntaxHighlight.theme.prism": {
+ "styles": "prism.min.css",
+ "localBasePath": "resources",
+ "remoteExtPath": "SyntaxHighlight_PrismJS/resources",
+ "dependencies": [
+ "ext.SyntaxHighlight.core.css"
+ ]
+ },
+ "ext.SyntaxHighlight.theme.prismOkaidia": {
+ "styles": "prism-okaidia.min.css",
+ "localBasePath": "resources",
+ "remoteExtPath": "SyntaxHighlight_PrismJS/resources",
+ "dependencies": [
+ "ext.SyntaxHighlight.core.css"
+ ]
+ },
+ "ext.SyntaxHighlight.theme.prismCoy": {
+ "styles": "prism-coy.min.css",
+ "localBasePath": "resources",
+ "remoteExtPath": "SyntaxHighlight_PrismJS/resources",
+ "dependencies": [
+ "ext.SyntaxHighlight.core.css"
+ ]
+ },
+ "ext.SyntaxHighlight.theme.prismSolarizedlight": {
+ "styles": "prism-solarizedlight.min.css",
+ "localBasePath": "resources",
+ "remoteExtPath": "SyntaxHighlight_PrismJS/resources",
+ "dependencies": [
+ "ext.SyntaxHighlight.core.css"
+ ]
+ },
+ "ext.SyntaxHighlight.theme.prismTomorrow": {
+ "styles": "prism-tomorrow.min.css",
+ "localBasePath": "resources",
+ "remoteExtPath": "SyntaxHighlight_PrismJS/resources",
+ "dependencies": [
+ "ext.SyntaxHighlight.core.css"
+ ]
+ },
"ext.SyntaxHighlight.lineHighlight": {
- "styles": "prism-line-highlight.css",
+ "styles": "prism-line-highlight.min.css",
"packageFiles": "prism-line-highlight.min.js",
"localBasePath": "resources",
"remoteExtPath": "SyntaxHighlight_PrismJS/resources",
@@ -64,7 +111,7 @@
]
},
"ext.SyntaxHighlight.lineNumbers": {
- "styles": "prism-line-numbers.css",
+ "styles": "prism-line-numbers.min.css",
"packageFiles": "prism-line-numbers.min.js",
"localBasePath": "resources",
"remoteExtPath": "SyntaxHighlight_PrismJS/resources",
@@ -72,6 +119,25 @@
"ext.SyntaxHighlight.core"
]
},
+ "ext.SyntaxHighlight.toolbar": {
+ "styles": "prism-toolbar.min.css",
+ "packageFiles": "prism-toolbar.min.js",
+ "localBasePath": "resources",
+ "remoteExtPath": "SyntaxHighlight_PrismJS/resources",
+ "dependencies": [
+ "ext.SyntaxHighlight.core"
+ ]
+ },
+ "ext.SyntaxHighlight.copyToClipboard": {
+ "styles": "prism-copy-to-clipboard.min.css",
+ "packageFiles": "prism-copy-to-clipboard.min.js",
+ "localBasePath": "resources",
+ "remoteExtPath": "SyntaxHighlight_PrismJS/resources",
+ "dependencies": [
+ "ext.SyntaxHighlight.core",
+ "ext.SyntaxHighlight.toolbar"
+ ]
+ },
"ext.SyntaxHighlight.apacheconf": {
"packageFiles": [
"prism-apacheconf.min.js"
diff --git a/extension_base.json b/extension_base.json
index 7d21422..945c8a1 100644
--- a/extension_base.json
+++ b/extension_base.json
@@ -1,8 +1,6 @@
{
"name": "SyntaxHighlight_PrismJS",
- "author": [
- "apple502j"
- ],
+ "author": ["apple502j"],
"descriptionmsg": "syntaxhighlight-desc",
"license-name": "GPL-3.0-or-later",
"type": "parserhook",
@@ -13,17 +11,21 @@
},
"Hooks": {
"ParserFirstCallInit": "main",
- "EditPage::showEditForm:initial": "main"
+ "EditPage::showEditForm:initial": "main",
+ "GetPreferences": "main",
+ "ParserOptionsRegister": "main"
},
"HookHandlers": {
"main": {
- "class": "SyntaxHighlight"
+ "class": "SyntaxHighlight",
+ "services": ["UserOptionsLookup"]
}
},
"MessagesDirs": {
- "SyntaxHighlight_PrismJS": [
- "i18n"
- ]
+ "SyntaxHighlight_PrismJS": ["i18n"]
+ },
+ "DefaultUserOptions": {
+ "syntaxhighlight-theme": "default"
},
"manifest_version": 2
}
diff --git a/i18n/en.json b/i18n/en.json
index 1d135c2..19e96e3 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -1,5 +1,12 @@
{
"syntaxhighlight-desc": "PrismJS-based syntax highlighter for MediaWiki.",
"syntaxhighlight-error-category": "Pages with syntax highlighting errors",
- "syntaxhighlight-wikieditor-button": "Syntax highlight"
+ "syntaxhighlight-wikieditor-button": "Syntax highlight",
+ "syntaxhighlight-theme-default": "Use default theme",
+ "syntaxhighlight-theme-prism": "Prism (light)",
+ "syntaxhighlight-theme-coy": "Coy (light)",
+ "syntaxhighlight-theme-okaidia": "Okaidia (dark)",
+ "syntaxhighlight-theme-solarizedlight": "Solarized Light (light)",
+ "syntaxhighlight-theme-tomorrow": "Tomorrow Night (dark)",
+ "syntaxhighlight-preference-theme": "Syntax highlight theme:"
}
diff --git a/i18n/ja.json b/i18n/ja.json
index cfe43ae..1a06eeb 100644
--- a/i18n/ja.json
+++ b/i18n/ja.json
@@ -1,5 +1,12 @@
{
"syntaxhighlight-desc": "PrismJSベースのMediaWiki用構文強調拡張機能。",
"syntaxhighlight-error-category": "構文強調エラーのあるページ",
- "syntaxhighlight-wikieditor-button": "構文強調"
+ "syntaxhighlight-wikieditor-button": "構文強調",
+ "syntaxhighlight-theme-default": "既定のテーマを使用",
+ "syntaxhighlight-theme-prism": "Prism (ライト)",
+ "syntaxhighlight-theme-coy": "Coy (ライト)",
+ "syntaxhighlight-theme-okaidia": "Okaidia (ダーク)",
+ "syntaxhighlight-theme-solarizedlight": "Solarized Light (ライト)",
+ "syntaxhighlight-theme-tomorrow": "Tomorrow Night (ダーク)",
+ "syntaxhighlight-preference-theme": "構文強調テーマ:"
}
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 83f9bd1..f03f111 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -1,5 +1,12 @@
{
"syntaxhighlight-desc": "Description of extension",
"syntaxhighlight-error-category": "Name of the tracking category added to pages with highlighting errors",
- "syntaxhighlight-wikieditor-button": "Name of the button on WikiEditor to add syntax highlight tag"
+ "syntaxhighlight-wikieditor-button": "Name of the button on WikiEditor to add syntax highlight tag",
+ "syntaxhighlight-theme-default": "Theme preference option to use the default theme",
+ "syntaxhighlight-theme-prism": "Theme preference option to use the Prism light theme",
+ "syntaxhighlight-theme-coy": "Theme preference option to use the Coy light theme",
+ "syntaxhighlight-theme-okaidia": "Theme preference option to use the Okaidia dark theme",
+ "syntaxhighlight-theme-solarizedlight": "Theme preference option to use the Solarized Light light theme",
+ "syntaxhighlight-theme-tomorrow": "Theme preference option to use the Tomorrow Night dark theme",
+ "syntaxhighlight-preference-theme": "Theme preference option label"
}
diff --git a/includes/SyntaxHighlight.php b/includes/SyntaxHighlight.php
index d188aed..0103f69 100644
--- a/includes/SyntaxHighlight.php
+++ b/includes/SyntaxHighlight.php
@@ -1,6 +1,6 @@
.
*/
+use MediaWiki\Hook\ParserOptionsRegisterHook;
use MediaWiki\Hook\ParserFirstCallInitHook;
use MediaWiki\Hook\EditPage__showEditForm_initialHook;
+use MediaWiki\Preferences\Hook\GetPreferencesHook;
+
+class SyntaxHighlight implements ParserFirstCallInitHook, EditPage__showEditForm_initialHook, GetPreferencesHook, ParserOptionsRegisterHook {
+ private $userOptionsLookup;
+
+ public function __construct($userOptionsLookup) {
+ $this->userOptionsLookup = $userOptionsLookup;
+ }
-class SyntaxHighlight implements ParserFirstCallInitHook {
/* Mapping of PrismJS language to ResourceLoader name */
const AVAILABLE_LANGUAGES = array(
'apacheconf' => 'apacheconf',
@@ -76,6 +84,14 @@ class SyntaxHighlight implements ParserFirstCallInitHook {
'mediawiki' => 'wiki',
'mw' => 'wiki'
);
+ /* Mapping of SyntaxHighlight name to PrismJS name */
+ const AVAILABLE_THEMES = array(
+ 'prism' => 'prism',
+ 'coy' => 'prismCoy',
+ 'okaidia' => 'prismOkaidia',
+ 'solarizedlight' => 'prismSolarizedlight',
+ 'tomorrow' => 'prismTomorrow'
+ );
public function onParserFirstCallInit($parser) {
$parser->setHook('syntaxhighlight', array('SyntaxHighlight', 'onSyntaxHighlight'));
@@ -88,6 +104,28 @@ public function onEditPage__showEditForm_initial($editor, $out) {
}
}
+ public function onGetPreferences($user, &$preferences) {
+ $themes = array_combine(array_map(function ($name) {
+ return 'syntaxhighlight-theme-' . $name;
+ }, array_keys(self::AVAILABLE_THEMES)), array_keys(self::AVAILABLE_THEMES));
+ $themes = array_merge(array('syntaxhighlight-theme-default' => 'default'), $themes);
+ $preferences['syntaxhighlight-theme'] = array(
+ 'type' => 'select',
+ 'options-messages' => $themes,
+ 'label-message' => 'syntaxhighlight-preference-theme',
+ 'section' => 'rendering/advancedrendering',
+ 'tooltip' => 'hoge'
+ );
+ }
+
+ public function onParserOptionsRegister(&$defaults, &$inCacheKey, &$lazyLoad) {
+ $defaults['syntaxhighlight-theme'] = self::getDefaultTheme();
+ $inCacheKey['syntaxhighlight-theme'] = true;
+ $lazyLoad['syntaxhighlight-theme'] = function ($options) {
+ return $this->getThemeForUser($options->getUserIdentity());
+ };
+ }
+
private static function addError(Parser $parser): void {
$parser->addTrackingCategory('syntaxhighlight-error-category');
}
@@ -114,6 +152,7 @@ public static function onSyntaxHighlight(string $code, array $argv, Parser $pars
$inline = isset($argv['inline']);
$showLineNum = isset($argv['line']) && !$inline;
+ $clipboard = isset($argv['clipboard']);
$highlight = null;
if (isset($argv['highlight']) && !$inline) {
$highlight = strval($argv['highlight']);
@@ -138,7 +177,7 @@ public static function onSyntaxHighlight(string $code, array $argv, Parser $pars
if (!$inline) {
$preTagAttrs = array(
- 'class' => 'mw-syntaxhighlight mw-content-ltr ' . ($showLineNum ? 'line-numbers' : 'no-line-numbers'),
+ 'class' => 'mw-syntaxhighlight mw-content-ltr ' . ($showLineNum ? 'line-numbers' : 'no-line-numbers') . ($clipboard ? ' clipboard' : ''),
'dir' => 'ltr'
);
if ($highlight) {
@@ -148,6 +187,31 @@ public static function onSyntaxHighlight(string $code, array $argv, Parser $pars
}
$out->addModuleStyles(['ext.SyntaxHighlight.core.css']);
+ // cannot use addModuleStyles
+ $out->addModules(['ext.SyntaxHighlight.theme.' . self::AVAILABLE_THEMES[$parser->getOptions()->getOption('syntaxhighlight-theme')]]);
+
return array($outputCode, 'markerType' => 'nowiki');
}
+
+ public static function getDefaultTheme() {
+ global $wgDefaultUserOptions, $wgSWS2ForceDarkTheme;
+ return ((isset($wgSWS2ForceDarkTheme) && $wgSWS2ForceDarkTheme) || !empty($wgDefaultUserOptions['scratchwikiskin-dark-theme'])) ? 'okaidia' : 'prism';
+ }
+
+ public function getThemeForUser($user = null) {
+ global $wgSWS2ForceDarkTheme;
+ if (!$user) $user = RequestContext::getMain()->getUser();
+ if (!$user) {
+ return self::getDefaultTheme();
+ }
+ $lookup = $this->userOptionsLookup;
+ $theme = $lookup->getOption($user, 'syntaxhighlight-theme');
+ if (!$theme || $theme === 'default' || !array_key_exists($theme, self::AVAILABLE_THEMES)) {
+ if ((isset($wgSWS2ForceDarkTheme) && $wgSWS2ForceDarkTheme) || $lookup->getOption($user, 'scratchwikiskin-dark-theme')) {
+ return 'okaidia';
+ }
+ return 'prism';
+ }
+ return $theme;
+ }
}
diff --git a/pull-latest.mjs b/pull-latest.mjs
index 41d8a5b..e480ad4 100644
--- a/pull-latest.mjs
+++ b/pull-latest.mjs
@@ -3,7 +3,7 @@ import fetch from "node-fetch";
import { camelCase } from "camel-case";
/*
- Copyright (C) 2020 apple502j All rights reversed.
+ Copyright (C) 2020-2023 apple502j All rights reversed.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
@@ -16,7 +16,19 @@ import { camelCase } from "camel-case";
along with this program. If not, see .
*/
-const PLUGINS = ["line-highlight", "line-numbers"];
+const THEMES = [
+ "prism",
+ "prism-okaidia",
+ "prism-coy",
+ "prism-solarizedlight",
+ "prism-tomorrow",
+];
+const PLUGINS = [
+ "line-highlight",
+ "line-numbers",
+ "toolbar",
+ "copy-to-clipboard",
+];
const LANGUAGES = [
"apacheconf",
"core",
@@ -56,12 +68,12 @@ const LANGUAGES = [
"vbnet",
"vim",
"wiki",
- "yaml"
+ "yaml",
];
const EXTRAS = {
css: "css-extras",
javascript: "js-extras",
- php: "php-extras"
+ php: "php-extras",
};
const DEPENDENCIES = {
c: ["clike"],
@@ -76,33 +88,45 @@ const DEPENDENCIES = {
"shell-session": ["bash"],
swift: ["clike"],
vbnet: ["basic"],
- wiki: ["markup"]
+ wiki: ["markup"],
+
+ "copy-to-clipboard": ["toolbar"],
};
if (process.argv[2] !== "-Nd") {
// Part 1: Download
const write = (fn, data) => {
console.log("Writing:", fn);
- return fs.writeFile(`./resources/${fn}`, data, { encoding: "utf8" })
+ return fs.writeFile(`./resources/${fn}`, data, { encoding: "utf8" });
};
await Promise.all([
- fetch("https://raw.githubusercontent.com/PrismJS/prism/master/themes/prism.css")
- .then(resp => resp.text())
- .then(txt => write("prism.css", txt)),
- ...PLUGINS.flatMap(name => [
- fetch(`https://raw.githubusercontent.com/PrismJS/prism/master/plugins/${name}/prism-${name}.min.js`)
- .then(resp => resp.text())
- .then(txt => write(`prism-${name}.min.js`, txt)),
- fetch(`https://raw.githubusercontent.com/PrismJS/prism/master/plugins/${name}/prism-${name}.css`)
- .then(resp => resp.text())
- .then(txt => write(`prism-${name}.css`, txt)),
+ ...THEMES.map((name) =>
+ fetch(
+ `https://raw.githubusercontent.com/PrismJS/prism/master/themes/${name}.min.css`
+ )
+ .then((resp) => resp.text())
+ .then((txt) => write(`${name}.min.css`, txt))
+ ),
+ ...PLUGINS.flatMap((name) => [
+ fetch(
+ `https://raw.githubusercontent.com/PrismJS/prism/master/plugins/${name}/prism-${name}.min.js`
+ )
+ .then((resp) => resp.text())
+ .then((txt) => write(`prism-${name}.min.js`, txt)),
+ fetch(
+ `https://raw.githubusercontent.com/PrismJS/prism/master/plugins/${name}/prism-${name}.min.css`
+ )
+ .then((resp) => resp.text())
+ .then((txt) => write(`prism-${name}.min.css`, txt)),
]),
- ...LANGUAGES.map(
- name => fetch(`https://raw.githubusercontent.com/PrismJS/prism/master/components/prism-${name}.min.js`)
- .then(resp => resp.text())
- .then(txt => write(`prism-${name}.min.js`, txt))
- )
+ ...LANGUAGES.map((name) =>
+ fetch(
+ `https://raw.githubusercontent.com/PrismJS/prism/master/components/prism-${name}.min.js`
+ )
+ .then((resp) => resp.text())
+ .then((txt) => write(`prism-${name}.min.js`, txt))
+ ),
]);
}
@@ -111,59 +135,88 @@ const extensionJSONBase = await fs.readFile("./extension_base.json", "utf8");
const extensionJSON = JSON.parse(extensionJSONBase);
extensionJSON.ResourceModules = {
"ext.SyntaxHighlight.core": {
- styles: "prism.css",
packageFiles: "prism-core.min.js",
localBasePath: "resources",
- remoteExtPath: "SyntaxHighlight_PrismJS/resources"
+ remoteExtPath: "SyntaxHighlight_PrismJS/resources",
},
"ext.SyntaxHighlight.core.css": {
styles: "syntaxhighlight-core.css",
localBasePath: "resources",
- remoteExtPath: "SyntaxHighlight_PrismJS/resources"
+ remoteExtPath: "SyntaxHighlight_PrismJS/resources",
},
"ext.SyntaxHighlight.core.js": {
packageFiles: "syntaxhighlight-core.js",
localBasePath: "resources",
- remoteExtPath: "SyntaxHighlight_PrismJS/resources"
+ remoteExtPath: "SyntaxHighlight_PrismJS/resources",
},
"ext.SyntaxHighlight.wikiEditor": {
packageFiles: "syntaxhighlight-wikieditor.js",
localBasePath: "resources",
remoteExtPath: "SyntaxHighlight_PrismJS/resources",
dependencies: ["ext.wikiEditor"],
- messages: ["syntaxhighlight-wikieditor-button"]
- }
+ messages: ["syntaxhighlight-wikieditor-button"],
+ },
};
-const solveDependencies = langName =>
- DEPENDENCIES.hasOwnProperty(langName) ?
- DEPENDENCIES[langName].map(dependency => `ext.SyntaxHighlight.${camelCase(dependency)}`) :
- [];
+const solveDependencies = (name) =>
+ DEPENDENCIES.hasOwnProperty(name)
+ ? DEPENDENCIES[name].map(
+ (dependency) => `ext.SyntaxHighlight.${camelCase(dependency)}`
+ )
+ : [];
+
+THEMES.forEach((themeName) => {
+ extensionJSON.ResourceModules[
+ `ext.SyntaxHighlight.theme.${camelCase(themeName)}`
+ ] = {
+ styles: `${themeName}.min.css`,
+ localBasePath: "resources",
+ remoteExtPath: "SyntaxHighlight_PrismJS/resources",
+ dependencies: [
+ "ext.SyntaxHighlight.core.css",
+ ...solveDependencies(themeName),
+ ],
+ };
+});
-PLUGINS.forEach(pluginName => {
- extensionJSON.ResourceModules[`ext.SyntaxHighlight.${camelCase(pluginName)}`] = {
- styles: `prism-${pluginName}.css`,
+PLUGINS.forEach((pluginName) => {
+ extensionJSON.ResourceModules[
+ `ext.SyntaxHighlight.${camelCase(pluginName)}`
+ ] = {
+ styles: `prism-${pluginName}.min.css`,
packageFiles: `prism-${pluginName}.min.js`,
localBasePath: "resources",
remoteExtPath: "SyntaxHighlight_PrismJS/resources",
- dependencies: ["ext.SyntaxHighlight.core"]
- }
+ dependencies: [
+ "ext.SyntaxHighlight.core",
+ ...solveDependencies(pluginName),
+ ],
+ };
});
-LANGUAGES.forEach(langName => {
+LANGUAGES.forEach((langName) => {
if (langName === "core" || langName.endsWith("-extras")) return;
const packageFiles = [`prism-${langName}.min.js`];
- const dependencies = ["ext.SyntaxHighlight.core", ...solveDependencies(langName)];
+ const dependencies = [
+ "ext.SyntaxHighlight.core",
+ ...solveDependencies(langName),
+ ];
if (EXTRAS.hasOwnProperty(langName)) {
packageFiles.push(`prism-${EXTRAS[langName]}.min.js`);
}
- extensionJSON.ResourceModules[`ext.SyntaxHighlight.${camelCase(langName)}`] = {
+ extensionJSON.ResourceModules[
+ `ext.SyntaxHighlight.${camelCase(langName)}`
+ ] = {
packageFiles,
dependencies,
localBasePath: "resources",
- remoteExtPath: "SyntaxHighlight_PrismJS/resources"
- }
+ remoteExtPath: "SyntaxHighlight_PrismJS/resources",
+ };
});
console.log("Generated extension.json");
-await fs.writeFile("extension.json", JSON.stringify(extensionJSON, null, 4), "utf8");
+await fs.writeFile(
+ "extension.json",
+ JSON.stringify(extensionJSON, null, 4),
+ "utf8"
+);
diff --git a/resources/prism-basic.min.js b/resources/prism-basic.min.js
deleted file mode 100644
index 991e81f..0000000
--- a/resources/prism-basic.min.js
+++ /dev/null
@@ -1 +0,0 @@
-Prism.languages.basic={comment:{pattern:/(?:!|REM\b).+/i,inside:{keyword:/^REM/i}},string:{pattern:/"(?:""|[!#$%&'()*,\/:;<=>?^\w +\-.])*"/,greedy:!0},number:/(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:E[+-]?\d+)?/i,keyword:/\b(?:AS|BEEP|BLOAD|BSAVE|CALL(?: ABSOLUTE)?|CASE|CHAIN|CHDIR|CLEAR|CLOSE|CLS|COM|COMMON|CONST|DATA|DECLARE|DEF(?: FN| SEG|DBL|INT|LNG|SNG|STR)|DIM|DO|DOUBLE|ELSE|ELSEIF|END|ENVIRON|ERASE|ERROR|EXIT|FIELD|FILES|FOR|FUNCTION|GET|GOSUB|GOTO|IF|INPUT|INTEGER|IOCTL|KEY|KILL|LINE INPUT|LOCATE|LOCK|LONG|LOOP|LSET|MKDIR|NAME|NEXT|OFF|ON(?: COM| ERROR| KEY| TIMER)?|OPEN|OPTION BASE|OUT|POKE|PUT|READ|REDIM|REM|RESTORE|RESUME|RETURN|RMDIR|RSET|RUN|SELECT CASE|SHARED|SHELL|SINGLE|SLEEP|STATIC|STEP|STOP|STRING|SUB|SWAP|SYSTEM|THEN|TIMER|TO|TROFF|TRON|TYPE|UNLOCK|UNTIL|USING|VIEW PRINT|WAIT|WEND|WHILE|WRITE)(?:\$|\b)/i,function:/\b(?:ABS|ACCESS|ACOS|ANGLE|AREA|ARITHMETIC|ARRAY|ASIN|ASK|AT|ATN|BASE|BEGIN|BREAK|CAUSE|CEIL|CHR|CLIP|COLLATE|COLOR|CON|COS|COSH|COT|CSC|DATE|DATUM|DEBUG|DECIMAL|DEF|DEG|DEGREES|DELETE|DET|DEVICE|DISPLAY|DOT|ELAPSED|EPS|ERASABLE|EXLINE|EXP|EXTERNAL|EXTYPE|FILETYPE|FIXED|FP|GO|GRAPH|HANDLER|IDN|IMAGE|IN|INT|INTERNAL|IP|IS|KEYED|LBOUND|LCASE|LEFT|LEN|LENGTH|LET|LINE|LINES|LOG|LOG10|LOG2|LTRIM|MARGIN|MAT|MAX|MAXNUM|MID|MIN|MISSING|MOD|NATIVE|NUL|NUMERIC|OF|OPTION|ORD|ORGANIZATION|OUTIN|OUTPUT|PI|POINT|POINTER|POINTS|POS|PRINT|PROGRAM|PROMPT|RAD|RADIANS|RANDOMIZE|RECORD|RECSIZE|RECTYPE|RELATIVE|REMAINDER|REPEAT|REST|RETRY|REWRITE|RIGHT|RND|ROUND|RTRIM|SAME|SEC|SELECT|SEQUENTIAL|SET|SETTER|SGN|SIN|SINH|SIZE|SKIP|SQR|STANDARD|STATUS|STR|STREAM|STYLE|TAB|TAN|TANH|TEMPLATE|TEXT|THERE|TIME|TIMEOUT|TRACE|TRANSFORM|TRUNCATE|UBOUND|UCASE|USE|VAL|VARIABLE|VIEWPORT|WHEN|WINDOW|WITH|ZER|ZONEWIDTH)(?:\$|\b)/i,operator:/<[=>]?|>=?|[+\-*\/^=&]|\b(?:AND|EQV|IMP|NOT|OR|XOR)\b/i,punctuation:/[,;:()]/};
\ No newline at end of file
diff --git a/resources/prism-copy-to-clipboard.min.css b/resources/prism-copy-to-clipboard.min.css
new file mode 100644
index 0000000..1becba2
--- /dev/null
+++ b/resources/prism-copy-to-clipboard.min.css
@@ -0,0 +1 @@
+404: Not Found
\ No newline at end of file
diff --git a/resources/prism-copy-to-clipboard.min.js b/resources/prism-copy-to-clipboard.min.js
new file mode 100644
index 0000000..7915ce9
--- /dev/null
+++ b/resources/prism-copy-to-clipboard.min.js
@@ -0,0 +1 @@
+!function(){function t(t){var e=document.createElement("textarea");e.value=t.getText(),e.style.top="0",e.style.left="0",e.style.position="fixed",document.body.appendChild(e),e.focus(),e.select();try{var o=document.execCommand("copy");setTimeout((function(){o?t.success():t.error()}),1)}catch(e){setTimeout((function(){t.error(e)}),1)}document.body.removeChild(e)}"undefined"!=typeof Prism&&"undefined"!=typeof document&&(Prism.plugins.toolbar?Prism.plugins.toolbar.registerButton("copy-to-clipboard",(function(e){var o=e.element,n=function(t){var e={copy:"Copy","copy-error":"Press Ctrl+C to copy","copy-success":"Copied!","copy-timeout":5e3};for(var o in e){for(var n="data-prismjs-"+o,c=t;c&&!c.hasAttribute(n);)c=c.parentElement;c&&(e[o]=c.getAttribute(n))}return e}(o),c=document.createElement("button");c.className="copy-to-clipboard-button",c.setAttribute("type","button");var r=document.createElement("span");return c.appendChild(r),u("copy"),function(e,o){e.addEventListener("click",(function(){!function(e){navigator.clipboard?navigator.clipboard.writeText(e.getText()).then(e.success,(function(){t(e)})):t(e)}(o)}))}(c,{getText:function(){return o.textContent},success:function(){u("copy-success"),i()},error:function(){u("copy-error"),setTimeout((function(){!function(t){window.getSelection().selectAllChildren(t)}(o)}),1),i()}}),c;function i(){setTimeout((function(){u("copy")}),n["copy-timeout"])}function u(t){r.textContent=n[t],c.setAttribute("data-copy-state",t)}})):console.warn("Copy to Clipboard plugin loaded before Toolbar plugin."))}();
\ No newline at end of file
diff --git a/resources/prism-coy.min.css b/resources/prism-coy.min.css
new file mode 100644
index 0000000..62495e5
--- /dev/null
+++ b/resources/prism-coy.min.css
@@ -0,0 +1 @@
+code[class*=language-],pre[class*=language-]{color:#000;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{position:relative;margin:.5em 0;overflow:visible;padding:1px}pre[class*=language-]>code{position:relative;z-index:1;border-left:10px solid #358ccb;box-shadow:-1px 0 0 0 #358ccb,0 0 0 1px #dfdfdf;background-color:#fdfdfd;background-image:linear-gradient(transparent 50%,rgba(69,142,209,.04) 50%);background-size:3em 3em;background-origin:content-box;background-attachment:local}code[class*=language-]{max-height:inherit;height:inherit;padding:0 1em;display:block;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background-color:#fdfdfd;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin-bottom:1em}:not(pre)>code[class*=language-]{position:relative;padding:.2em;border-radius:.3em;color:#c92c2c;border:1px solid rgba(0,0,0,.1);display:inline;white-space:normal}pre[class*=language-]:after,pre[class*=language-]:before{content:'';display:block;position:absolute;bottom:.75em;left:.18em;width:40%;height:20%;max-height:13em;box-shadow:0 13px 8px #979797;-webkit-transform:rotate(-2deg);-moz-transform:rotate(-2deg);-ms-transform:rotate(-2deg);-o-transform:rotate(-2deg);transform:rotate(-2deg)}pre[class*=language-]:after{right:.75em;left:auto;-webkit-transform:rotate(2deg);-moz-transform:rotate(2deg);-ms-transform:rotate(2deg);-o-transform:rotate(2deg);transform:rotate(2deg)}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#7d8b99}.token.punctuation{color:#5f6364}.token.boolean,.token.constant,.token.deleted,.token.function-name,.token.number,.token.property,.token.symbol,.token.tag{color:#c92c2c}.token.attr-name,.token.builtin,.token.char,.token.function,.token.inserted,.token.selector,.token.string{color:#2f9c0a}.token.entity,.token.operator,.token.url,.token.variable{color:#a67f59;background:rgba(255,255,255,.5)}.token.atrule,.token.attr-value,.token.class-name,.token.keyword{color:#1990b8}.token.important,.token.regex{color:#e90}.language-css .token.string,.style .token.string{color:#a67f59;background:rgba(255,255,255,.5)}.token.important{font-weight:400}.token.bold{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.namespace{opacity:.7}@media screen and (max-width:767px){pre[class*=language-]:after,pre[class*=language-]:before{bottom:14px;box-shadow:none}}pre[class*=language-].line-numbers.line-numbers{padding-left:0}pre[class*=language-].line-numbers.line-numbers code{padding-left:3.8em}pre[class*=language-].line-numbers.line-numbers .line-numbers-rows{left:0}pre[class*=language-][data-line]{padding-top:0;padding-bottom:0;padding-left:0}pre[data-line] code{position:relative;padding-left:4em}pre .line-highlight{margin-top:0}
\ No newline at end of file
diff --git a/resources/prism-line-highlight.css b/resources/prism-line-highlight.css
deleted file mode 100644
index ae47c89..0000000
--- a/resources/prism-line-highlight.css
+++ /dev/null
@@ -1,70 +0,0 @@
-pre[data-line] {
- position: relative;
- padding: 1em 0 1em 3em;
-}
-
-.line-highlight {
- position: absolute;
- left: 0;
- right: 0;
- padding: inherit 0;
- margin-top: 1em; /* Same as .prism’s padding-top */
-
- background: hsla(24, 20%, 50%,.08);
- background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
-
- pointer-events: none;
-
- line-height: inherit;
- white-space: pre;
-}
-
-@media print {
- .line-highlight {
- /*
- * This will prevent browsers from replacing the background color with white.
- * It's necessary because the element is layered on top of the displayed code.
- */
- -webkit-print-color-adjust: exact;
- color-adjust: exact;
- }
-}
-
- .line-highlight:before,
- .line-highlight[data-end]:after {
- content: attr(data-start);
- position: absolute;
- top: .4em;
- left: .6em;
- min-width: 1em;
- padding: 0 .5em;
- background-color: hsla(24, 20%, 50%,.4);
- color: hsl(24, 20%, 95%);
- font: bold 65%/1.5 sans-serif;
- text-align: center;
- vertical-align: .3em;
- border-radius: 999px;
- text-shadow: none;
- box-shadow: 0 1px white;
- }
-
- .line-highlight[data-end]:after {
- content: attr(data-end);
- top: auto;
- bottom: .4em;
- }
-
-.line-numbers .line-highlight:before,
-.line-numbers .line-highlight:after {
- content: none;
-}
-
-pre[id].linkable-line-numbers span.line-numbers-rows {
- pointer-events: all;
-}
-pre[id].linkable-line-numbers span.line-numbers-rows > span:before {
- cursor: pointer;
-}
-pre[id].linkable-line-numbers span.line-numbers-rows > span:hover:before {
- background-color: rgba(128, 128, 128, .2);
-}
diff --git a/resources/prism-line-highlight.min.css b/resources/prism-line-highlight.min.css
new file mode 100644
index 0000000..6cd8772
--- /dev/null
+++ b/resources/prism-line-highlight.min.css
@@ -0,0 +1 @@
+pre[data-line]{position:relative;padding:1em 0 1em 3em}.line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:hsla(24,20%,50%,.08);background:linear-gradient(to right,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));pointer-events:none;line-height:inherit;white-space:pre}@media print{.line-highlight{-webkit-print-color-adjust:exact;color-adjust:exact}}.line-highlight:before,.line-highlight[data-end]:after{content:attr(data-start);position:absolute;top:.4em;left:.6em;min-width:1em;padding:0 .5em;background-color:hsla(24,20%,50%,.4);color:#f4f1ef;font:bold 65%/1.5 sans-serif;text-align:center;vertical-align:.3em;border-radius:999px;text-shadow:none;box-shadow:0 1px #fff}.line-highlight[data-end]:after{content:attr(data-end);top:auto;bottom:.4em}.line-numbers .line-highlight:after,.line-numbers .line-highlight:before{content:none}pre[id].linkable-line-numbers span.line-numbers-rows{pointer-events:all}pre[id].linkable-line-numbers span.line-numbers-rows>span:before{cursor:pointer}pre[id].linkable-line-numbers span.line-numbers-rows>span:hover:before{background-color:rgba(128,128,128,.2)}
\ No newline at end of file
diff --git a/resources/prism-line-numbers.css b/resources/prism-line-numbers.css
deleted file mode 100644
index 5770530..0000000
--- a/resources/prism-line-numbers.css
+++ /dev/null
@@ -1,40 +0,0 @@
-pre[class*="language-"].line-numbers {
- position: relative;
- padding-left: 3.8em;
- counter-reset: linenumber;
-}
-
-pre[class*="language-"].line-numbers > code {
- position: relative;
- white-space: inherit;
-}
-
-.line-numbers .line-numbers-rows {
- position: absolute;
- pointer-events: none;
- top: 0;
- font-size: 100%;
- left: -3.8em;
- width: 3em; /* works for line-numbers below 1000 lines */
- letter-spacing: -1px;
- border-right: 1px solid #999;
-
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-
-}
-
- .line-numbers-rows > span {
- display: block;
- counter-increment: linenumber;
- }
-
- .line-numbers-rows > span:before {
- content: counter(linenumber);
- color: #999;
- display: block;
- padding-right: 0.8em;
- text-align: right;
- }
diff --git a/resources/prism-line-numbers.min.css b/resources/prism-line-numbers.min.css
new file mode 100644
index 0000000..8170f64
--- /dev/null
+++ b/resources/prism-line-numbers.min.css
@@ -0,0 +1 @@
+pre[class*=language-].line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}pre[class*=language-].line-numbers>code{position:relative;white-space:inherit}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.line-numbers-rows>span{display:block;counter-increment:linenumber}.line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}
\ No newline at end of file
diff --git a/resources/prism-okaidia.min.css b/resources/prism-okaidia.min.css
new file mode 100644
index 0000000..dc0b418
--- /dev/null
+++ b/resources/prism-okaidia.min.css
@@ -0,0 +1 @@
+code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
\ No newline at end of file
diff --git a/resources/prism-solarizedlight.min.css b/resources/prism-solarizedlight.min.css
new file mode 100644
index 0000000..8deecf9
--- /dev/null
+++ b/resources/prism-solarizedlight.min.css
@@ -0,0 +1 @@
+code[class*=language-],pre[class*=language-]{color:#657b83;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{background:#073642}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{background:#073642}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background-color:#fdf6e3}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#93a1a1}.token.punctuation{color:#586e75}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#268bd2}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string,.token.url{color:#2aa198}.token.entity{color:#657b83;background:#eee8d5}.token.atrule,.token.attr-value,.token.keyword{color:#859900}.token.class-name,.token.function{color:#b58900}.token.important,.token.regex,.token.variable{color:#cb4b16}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
\ No newline at end of file
diff --git a/resources/prism-tomorrow.min.css b/resources/prism-tomorrow.min.css
new file mode 100644
index 0000000..8fce550
--- /dev/null
+++ b/resources/prism-tomorrow.min.css
@@ -0,0 +1 @@
+code[class*=language-],pre[class*=language-]{color:#ccc;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}
\ No newline at end of file
diff --git a/resources/prism-toolbar.min.css b/resources/prism-toolbar.min.css
new file mode 100644
index 0000000..d4298ec
--- /dev/null
+++ b/resources/prism-toolbar.min.css
@@ -0,0 +1 @@
+div.code-toolbar{position:relative}div.code-toolbar>.toolbar{position:absolute;z-index:10;top:.3em;right:.2em;transition:opacity .3s ease-in-out;opacity:0}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{color:#bbb;font-size:.8em;padding:0 .5em;background:#f5f2f0;background:rgba(224,224,224,.2);box-shadow:0 2px 0 0 rgba(0,0,0,.2);border-radius:.5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;text-decoration:none}
\ No newline at end of file
diff --git a/resources/prism-toolbar.min.js b/resources/prism-toolbar.min.js
new file mode 100644
index 0000000..54eb118
--- /dev/null
+++ b/resources/prism-toolbar.min.js
@@ -0,0 +1 @@
+!function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document){var e=[],t={},n=function(){};Prism.plugins.toolbar={};var a=Prism.plugins.toolbar.registerButton=function(n,a){var r;r="function"==typeof a?a:function(e){var t;return"function"==typeof a.onClick?((t=document.createElement("button")).type="button",t.addEventListener("click",(function(){a.onClick.call(this,e)}))):"string"==typeof a.url?(t=document.createElement("a")).href=a.url:t=document.createElement("span"),a.className&&t.classList.add(a.className),t.textContent=a.text,t},n in t?console.warn('There is a button with the key "'+n+'" registered already.'):e.push(t[n]=r)},r=Prism.plugins.toolbar.hook=function(a){var r=a.element.parentNode;if(r&&/pre/i.test(r.nodeName)&&!r.parentNode.classList.contains("code-toolbar")){var o=document.createElement("div");o.classList.add("code-toolbar"),r.parentNode.insertBefore(o,r),o.appendChild(r);var i=document.createElement("div");i.classList.add("toolbar");var l=e,d=function(e){for(;e;){var t=e.getAttribute("data-toolbar-order");if(null!=t)return(t=t.trim()).length?t.split(/\s*,\s*/g):[];e=e.parentElement}}(a.element);d&&(l=d.map((function(e){return t[e]||n}))),l.forEach((function(e){var t=e(a);if(t){var n=document.createElement("div");n.classList.add("toolbar-item"),n.appendChild(t),i.appendChild(n)}})),o.appendChild(i)}};a("label",(function(e){var t=e.element.parentNode;if(t&&/pre/i.test(t.nodeName)&&t.hasAttribute("data-label")){var n,a,r=t.getAttribute("data-label");try{a=document.querySelector("template#"+r)}catch(e){}return a?n=a.content:(t.hasAttribute("data-url")?(n=document.createElement("a")).href=t.getAttribute("data-url"):n=document.createElement("span"),n.textContent=r),n}})),Prism.hooks.add("complete",r)}}();
\ No newline at end of file
diff --git a/resources/prism.css b/resources/prism.css
deleted file mode 100644
index 5b8ed2d..0000000
--- a/resources/prism.css
+++ /dev/null
@@ -1,140 +0,0 @@
-/**
- * prism.js default theme for JavaScript, CSS and HTML
- * Based on dabblet (http://dabblet.com)
- * @author Lea Verou
- */
-
-code[class*="language-"],
-pre[class*="language-"] {
- color: black;
- background: none;
- text-shadow: 0 1px white;
- font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
- font-size: 1em;
- text-align: left;
- white-space: pre;
- word-spacing: normal;
- word-break: normal;
- word-wrap: normal;
- line-height: 1.5;
-
- -moz-tab-size: 4;
- -o-tab-size: 4;
- tab-size: 4;
-
- -webkit-hyphens: none;
- -moz-hyphens: none;
- -ms-hyphens: none;
- hyphens: none;
-}
-
-pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
-code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
- text-shadow: none;
- background: #b3d4fc;
-}
-
-pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
-code[class*="language-"]::selection, code[class*="language-"] ::selection {
- text-shadow: none;
- background: #b3d4fc;
-}
-
-@media print {
- code[class*="language-"],
- pre[class*="language-"] {
- text-shadow: none;
- }
-}
-
-/* Code blocks */
-pre[class*="language-"] {
- padding: 1em;
- margin: .5em 0;
- overflow: auto;
-}
-
-:not(pre) > code[class*="language-"],
-pre[class*="language-"] {
- background: #f5f2f0;
-}
-
-/* Inline code */
-:not(pre) > code[class*="language-"] {
- padding: .1em;
- border-radius: .3em;
- white-space: normal;
-}
-
-.token.comment,
-.token.prolog,
-.token.doctype,
-.token.cdata {
- color: slategray;
-}
-
-.token.punctuation {
- color: #999;
-}
-
-.token.namespace {
- opacity: .7;
-}
-
-.token.property,
-.token.tag,
-.token.boolean,
-.token.number,
-.token.constant,
-.token.symbol,
-.token.deleted {
- color: #905;
-}
-
-.token.selector,
-.token.attr-name,
-.token.string,
-.token.char,
-.token.builtin,
-.token.inserted {
- color: #690;
-}
-
-.token.operator,
-.token.entity,
-.token.url,
-.language-css .token.string,
-.style .token.string {
- color: #9a6e3a;
- /* This background color was intended by the author of this theme. */
- background: hsla(0, 0%, 100%, .5);
-}
-
-.token.atrule,
-.token.attr-value,
-.token.keyword {
- color: #07a;
-}
-
-.token.function,
-.token.class-name {
- color: #DD4A68;
-}
-
-.token.regex,
-.token.important,
-.token.variable {
- color: #e90;
-}
-
-.token.important,
-.token.bold {
- font-weight: bold;
-}
-.token.italic {
- font-style: italic;
-}
-
-.token.entity {
- cursor: help;
-}
diff --git a/resources/prism.min.css b/resources/prism.min.css
new file mode 100644
index 0000000..8c4cc05
--- /dev/null
+++ b/resources/prism.min.css
@@ -0,0 +1 @@
+code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}
\ No newline at end of file
diff --git a/resources/syntaxhighlight-core.css b/resources/syntaxhighlight-core.css
index f315827..f5237b4 100644
--- a/resources/syntaxhighlight-core.css
+++ b/resources/syntaxhighlight-core.css
@@ -1,5 +1,9 @@
pre.mw-syntaxhighlight > code.mw-syntaxhighlight-code {
- border-radius: unset;
- border: unset;
- padding: unset;
+ border-radius: unset;
+ border: unset;
+}
+
+:where(pre.mw-syntaxhighlight:not(.clipboard) + .toolbar)
+ .copy-to-clipboard-button {
+ display: none;
}
diff --git a/resources/syntaxhighlight-core.js b/resources/syntaxhighlight-core.js
index 0635d51..72598d2 100644
--- a/resources/syntaxhighlight-core.js
+++ b/resources/syntaxhighlight-core.js
@@ -2,28 +2,39 @@ const domLoaded = () => {
window.Prism = window.Prism || {};
window.Prism.manual = true;
const languages = Array.from(
- new Set(
- Array.from(
- document.querySelectorAll("[data-mw-syntaxhighlight-resourceloader-module]"),
- elem => elem.dataset.mwSyntaxhighlightResourceloaderModule
+ new Set(
+ Array.from(
+ document.querySelectorAll(
+ "[data-mw-syntaxhighlight-resourceloader-module]"
+ ),
+ (elem) => elem.dataset.mwSyntaxhighlightResourceloaderModule
+ )
)
- )
);
const plugins = [];
- if (document.querySelectorAll("pre.mw-syntaxhighlight.line-numbers")) {
- plugins.push("ext.SyntaxHighlight.lineNumbers");
+ if (document.querySelector("pre.mw-syntaxhighlight.line-numbers")) {
+ plugins.push("ext.SyntaxHighlight.lineNumbers");
}
- if (document.querySelectorAll("pre.mw-syntaxhighlight[data-line]")) {
- plugins.push("ext.SyntaxHighlight.lineHighlight");
+ if (document.querySelector("pre.mw-syntaxhighlight.clipboard")) {
+ plugins.push("ext.SyntaxHighlight.copyToClipboard");
}
- mw.loader.using(languages.map(lang => `ext.SyntaxHighlight.${lang}`).concat(plugins)).then(() => {
- console.log("Highlighted in:", languages);
- Prism.highlightAll();
- });
+ if (document.querySelector("pre.mw-syntaxhighlight[data-line]")) {
+ plugins.push("ext.SyntaxHighlight.lineHighlight");
+ }
+ mw.loader
+ .using(
+ languages
+ .map((lang) => `ext.SyntaxHighlight.${lang}`)
+ .concat(plugins)
+ )
+ .then(() => {
+ console.log("Highlighted in:", languages);
+ Prism.highlightAll();
+ });
};
if (document.readyState === "loading") {
- window.addEventListener("DOMContentLoaded", domLoaded, {once: true});
+ window.addEventListener("DOMContentLoaded", domLoaded, { once: true });
} else {
- domLoaded();
-}
\ No newline at end of file
+ domLoaded();
+}
diff --git a/resources/syntaxhighlight-wikieditor.js b/resources/syntaxhighlight-wikieditor.js
index f85922e..1f2ae67 100644
--- a/resources/syntaxhighlight-wikieditor.js
+++ b/resources/syntaxhighlight-wikieditor.js
@@ -1,21 +1,21 @@
-mw.hook('wikiEditor.toolbarReady').add(function ($textarea) {
- $textarea.wikiEditor('addToToolbar', {
- section: 'advanced',
- group: 'insert',
+mw.hook("wikiEditor.toolbarReady").add(function ($textarea) {
+ $textarea.wikiEditor("addToToolbar", {
+ section: "advanced",
+ group: "insert",
tools: {
smile: {
- labelMsg: 'syntaxhighlight-wikieditor-button',
- type: 'button',
- oouiIcon: 'code',
+ labelMsg: "syntaxhighlight-wikieditor-button",
+ type: "button",
+ oouiIcon: "code",
action: {
- type: 'encapsulate',
+ type: "encapsulate",
options: {
- pre: "\n",
+ pre: '\n',
post: "\n",
- ownline: true
- }
- }
- }
- }
+ ownline: true,
+ },
+ },
+ },
+ },
});
-});
\ No newline at end of file
+});