Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
76 changes: 71 additions & 5 deletions extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,29 @@
},
"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"
]
},
"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"
Expand All @@ -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",
Expand All @@ -64,14 +111,33 @@
]
},
"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",
"dependencies": [
"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"
Expand Down
18 changes: 10 additions & 8 deletions extension_base.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"name": "SyntaxHighlight_PrismJS",
"author": [
"apple502j"
],
"author": ["apple502j"],
"descriptionmsg": "syntaxhighlight-desc",
"license-name": "GPL-3.0-or-later",
"type": "parserhook",
Expand All @@ -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
}
9 changes: 8 additions & 1 deletion i18n/en.json
Original file line number Diff line number Diff line change
@@ -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:"
}
9 changes: 8 additions & 1 deletion i18n/ja.json
Original file line number Diff line number Diff line change
@@ -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": "構文強調テーマ:"
}
9 changes: 8 additions & 1 deletion i18n/qqq.json
Original file line number Diff line number Diff line change
@@ -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"
}
70 changes: 67 additions & 3 deletions includes/SyntaxHighlight.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/*
Copyright (C) 2020-2022 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
Expand All @@ -13,10 +13,18 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

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',
Expand Down Expand Up @@ -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'));
Expand All @@ -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');
}
Expand All @@ -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']);
Expand All @@ -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) {
Expand All @@ -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;
}
}
Loading