2007-06-29 04:33:14 +00:00
|
|
|
<?php
|
2014-06-01 17:50:34 +00:00
|
|
|
/**
|
|
|
|
* 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 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
|
|
*/
|
|
|
|
|
2019-07-03 13:58:03 +00:00
|
|
|
use MediaWiki\MediaWikiServices;
|
2017-10-04 21:50:04 +00:00
|
|
|
use MediaWiki\Shell\Shell;
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
2017-05-10 14:18:57 +00:00
|
|
|
class SyntaxHighlight {
|
2008-01-11 09:05:18 +00:00
|
|
|
|
2020-01-14 12:44:56 +00:00
|
|
|
/** @var int The maximum number of lines that may be selected for highlighting. */
|
2020-05-30 00:34:01 +00:00
|
|
|
private const HIGHLIGHT_MAX_LINES = 1000;
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
2020-01-14 12:44:56 +00:00
|
|
|
/** @var int Maximum input size for the highlighter (100 kB). */
|
2020-05-30 00:34:01 +00:00
|
|
|
private const HIGHLIGHT_MAX_BYTES = 102400;
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
2020-12-30 20:29:59 +00:00
|
|
|
/** @var string CSS class for syntax-highlighted code. Public as used by the updateCSS maintenance script. */
|
2020-05-30 00:34:01 +00:00
|
|
|
public const HIGHLIGHT_CSS_CLASS = 'mw-highlight';
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
2017-01-23 21:32:32 +00:00
|
|
|
/** @var int Cache version. Increment whenever the HTML changes. */
|
2020-05-30 00:34:01 +00:00
|
|
|
private const CACHE_VERSION = 2;
|
2015-06-23 15:54:19 +00:00
|
|
|
|
2020-01-14 12:44:56 +00:00
|
|
|
/** @var array Mapping of MIME-types to lexer names. */
|
2017-06-15 16:16:11 +00:00
|
|
|
private static $mimeLexers = [
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
'text/javascript' => 'javascript',
|
|
|
|
'application/json' => 'javascript',
|
|
|
|
'text/xml' => 'xml',
|
2017-06-15 16:16:11 +00:00
|
|
|
];
|
2007-06-29 04:33:14 +00:00
|
|
|
|
2015-05-20 21:36:13 +00:00
|
|
|
/**
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
* Get the Pygments lexer name for a particular language.
|
|
|
|
*
|
|
|
|
* @param string $lang Language name.
|
|
|
|
* @return string|null Lexer name, or null if no matching lexer.
|
2015-05-20 21:36:13 +00:00
|
|
|
*/
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
private static function getLexer( $lang ) {
|
|
|
|
static $lexers = null;
|
|
|
|
|
2015-06-26 21:39:15 +00:00
|
|
|
if ( $lang === null ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
if ( !$lexers ) {
|
2018-02-15 22:21:52 +00:00
|
|
|
$lexers = require __DIR__ . '/../SyntaxHighlight.lexers.php';
|
2015-05-20 21:36:13 +00:00
|
|
|
}
|
|
|
|
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
$lexer = strtolower( $lang );
|
|
|
|
|
2018-07-29 04:29:30 +00:00
|
|
|
if ( isset( $lexers[$lexer] ) ) {
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
return $lexer;
|
2015-05-20 21:36:13 +00:00
|
|
|
}
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
2017-05-10 13:32:52 +00:00
|
|
|
$geshi2pygments = SyntaxHighlightGeSHiCompat::getGeSHiToPygmentsMap();
|
|
|
|
|
2015-06-22 20:29:54 +00:00
|
|
|
// Check if this is a GeSHi lexer name for which there exists
|
|
|
|
// a compatible Pygments lexer with a different name.
|
2017-05-10 13:32:52 +00:00
|
|
|
if ( isset( $geshi2pygments[$lexer] ) ) {
|
|
|
|
$lexer = $geshi2pygments[$lexer];
|
2015-06-22 20:29:54 +00:00
|
|
|
if ( in_array( $lexer, $lexers ) ) {
|
|
|
|
return $lexer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
return null;
|
2015-05-20 21:36:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Register parser hook
|
|
|
|
*
|
2019-11-15 05:41:31 +00:00
|
|
|
* @param Parser $parser
|
2015-05-20 21:36:13 +00:00
|
|
|
*/
|
2019-11-15 05:41:31 +00:00
|
|
|
public static function onParserFirstCallInit( Parser $parser ) {
|
2020-01-06 06:22:26 +00:00
|
|
|
$parser->setHook( 'source', [ 'SyntaxHighlight', 'parserHookSource' ] );
|
|
|
|
$parser->setHook( 'syntaxhighlight', [ 'SyntaxHighlight', 'parserHook' ] );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parser hook for <source> to add deprecated tracking category
|
|
|
|
*
|
|
|
|
* @param string $text
|
|
|
|
* @param array $args
|
|
|
|
* @param Parser $parser
|
|
|
|
* @return string
|
|
|
|
* @throws MWException
|
|
|
|
*/
|
|
|
|
public static function parserHookSource( $text, $args, $parser ) {
|
|
|
|
$parser->addTrackingCategory( 'syntaxhighlight-source-category' );
|
|
|
|
return self::parserHook( $text, $args, $parser );
|
2015-05-20 21:36:13 +00:00
|
|
|
}
|
|
|
|
|
2007-06-29 04:33:14 +00:00
|
|
|
/**
|
2020-01-06 06:22:26 +00:00
|
|
|
* Parser hook for both <source> and <syntaxhighlight> logic
|
2007-06-29 04:33:14 +00:00
|
|
|
*
|
|
|
|
* @param string $text
|
|
|
|
* @param array $args
|
|
|
|
* @param Parser $parser
|
|
|
|
* @return string
|
2017-03-27 23:25:36 +00:00
|
|
|
* @throws MWException
|
2007-06-29 04:33:14 +00:00
|
|
|
*/
|
2017-12-24 03:00:14 +00:00
|
|
|
public static function parserHook( $text, $args, $parser ) {
|
2016-03-14 04:18:07 +00:00
|
|
|
// Replace strip markers (For e.g. {{#tag:syntaxhighlight|<nowiki>...}})
|
|
|
|
$out = $parser->mStripState->unstripNoWiki( $text );
|
|
|
|
|
2008-07-11 18:12:48 +00:00
|
|
|
// Don't trim leading spaces away, just the linefeeds
|
2016-03-14 04:18:07 +00:00
|
|
|
$out = preg_replace( '/^\n+/', '', rtrim( $out ) );
|
2011-09-16 17:52:28 +00:00
|
|
|
|
2015-07-03 13:42:46 +00:00
|
|
|
// Convert deprecated attributes
|
|
|
|
if ( isset( $args['enclose'] ) ) {
|
|
|
|
if ( $args['enclose'] === 'none' ) {
|
|
|
|
$args['inline'] = true;
|
|
|
|
}
|
|
|
|
unset( $args['enclose'] );
|
2020-01-06 06:22:26 +00:00
|
|
|
$parser->addTrackingCategory( 'syntaxhighlight-enclose-category' );
|
2015-07-03 13:42:46 +00:00
|
|
|
}
|
|
|
|
|
2019-03-11 03:39:36 +00:00
|
|
|
$lexer = $args['lang'] ?? '';
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
2021-01-01 17:53:48 +00:00
|
|
|
$result = self::highlight( $out, $lexer, $args, $parser );
|
2015-06-26 21:39:15 +00:00
|
|
|
if ( !$result->isGood() ) {
|
|
|
|
$parser->addTrackingCategory( 'syntaxhighlight-error-category' );
|
|
|
|
}
|
|
|
|
$out = $result->getValue();
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
|
|
|
// Register CSS
|
2015-10-12 19:30:01 +00:00
|
|
|
// TODO: Consider moving to a separate method so that public method
|
|
|
|
// highlight() can be used without needing to know the module name.
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
$parser->getOutput()->addModuleStyles( 'ext.pygments' );
|
|
|
|
|
2015-07-03 13:42:46 +00:00
|
|
|
return $out;
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
}
|
|
|
|
|
2020-12-30 20:29:59 +00:00
|
|
|
/**
|
|
|
|
* Unwrap the <div> wrapper of the Pygments output
|
|
|
|
*
|
|
|
|
* @param string $out Output
|
|
|
|
* @return string Unwrapped output
|
|
|
|
*/
|
|
|
|
private static function unwrap( string $out ) : string {
|
|
|
|
if ( $out !== '' ) {
|
|
|
|
$m = [];
|
|
|
|
if ( preg_match( '/^<div class="?mw-highlight"?>(.*)<\/div>$/s', trim( $out ), $m ) ) {
|
|
|
|
$out = trim( $m[1] );
|
|
|
|
} else {
|
|
|
|
throw new MWException( 'Unexpected output from Pygments encountered' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $out;
|
|
|
|
}
|
|
|
|
|
2017-01-23 21:34:06 +00:00
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function getPygmentizePath() {
|
|
|
|
global $wgPygmentizePath;
|
|
|
|
|
|
|
|
// If $wgPygmentizePath is unset, use the bundled copy.
|
|
|
|
if ( $wgPygmentizePath === false ) {
|
2018-02-15 22:21:52 +00:00
|
|
|
$wgPygmentizePath = __DIR__ . '/../pygments/pygmentize';
|
2017-01-23 21:34:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $wgPygmentizePath;
|
|
|
|
}
|
|
|
|
|
2018-02-22 23:16:51 +00:00
|
|
|
/**
|
|
|
|
* @param string $code
|
2021-01-01 17:53:48 +00:00
|
|
|
* @param bool $isInline
|
2020-02-29 21:17:22 +00:00
|
|
|
* @return string HTML
|
2018-02-22 23:16:51 +00:00
|
|
|
*/
|
2021-01-01 17:53:48 +00:00
|
|
|
private static function plainCodeWrap( $code, $isInline ) {
|
|
|
|
if ( $isInline ) {
|
2018-02-22 23:29:33 +00:00
|
|
|
return htmlspecialchars( $code, ENT_NOQUOTES );
|
2018-02-22 23:16:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return Html::rawElement(
|
|
|
|
'div',
|
|
|
|
[ 'class' => self::HIGHLIGHT_CSS_CLASS ],
|
|
|
|
Html::element( 'pre', [], $code )
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
/**
|
2021-01-01 17:53:48 +00:00
|
|
|
* @param string $code
|
|
|
|
* @param string|null $lang
|
|
|
|
* @param array $args
|
|
|
|
* @return Status
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
*/
|
2021-01-01 17:53:48 +00:00
|
|
|
private static function highlightInner( $code, $lang = null, $args = [] ) {
|
2015-06-26 21:39:15 +00:00
|
|
|
$status = new Status;
|
|
|
|
|
|
|
|
$lexer = self::getLexer( $lang );
|
|
|
|
if ( $lexer === null && $lang !== null ) {
|
|
|
|
$status->warning( 'syntaxhighlight-error-unknown-language', $lang );
|
|
|
|
}
|
|
|
|
|
2018-02-22 23:06:58 +00:00
|
|
|
// For empty tag, output nothing instead of empty <pre>.
|
|
|
|
if ( $code === '' ) {
|
2018-02-22 21:19:53 +00:00
|
|
|
$status->value = '';
|
|
|
|
return $status;
|
2009-06-24 05:25:32 +00:00
|
|
|
}
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
2018-02-22 23:06:58 +00:00
|
|
|
$length = strlen( $code );
|
|
|
|
if ( strlen( $code ) > self::HIGHLIGHT_MAX_BYTES ) {
|
|
|
|
// Disable syntax highlighting
|
|
|
|
$lexer = null;
|
|
|
|
$status->warning(
|
|
|
|
'syntaxhighlight-error-exceeds-size-limit',
|
|
|
|
$length,
|
|
|
|
self::HIGHLIGHT_MAX_BYTES
|
|
|
|
);
|
|
|
|
} elseif ( Shell::isDisabled() ) {
|
|
|
|
// Disable syntax highlighting
|
|
|
|
$lexer = null;
|
2015-06-26 21:39:15 +00:00
|
|
|
$status->warning( 'syntaxhighlight-error-pygments-invocation-failure' );
|
2015-06-22 23:19:25 +00:00
|
|
|
wfWarn(
|
|
|
|
'MediaWiki determined that it cannot invoke Pygments. ' .
|
|
|
|
'As a result, SyntaxHighlight_GeSHi will not perform any syntax highlighting. ' .
|
|
|
|
'See the debug log for details: ' .
|
|
|
|
'https://www.mediawiki.org/wiki/Manual:$wgDebugLogFile'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-01-01 17:53:48 +00:00
|
|
|
$isInline = isset( $args['inline'] );
|
|
|
|
$showLines = isset( $args['line'] );
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
2021-01-01 17:53:48 +00:00
|
|
|
if ( $isInline ) {
|
2018-02-22 23:29:33 +00:00
|
|
|
$code = trim( $code );
|
|
|
|
}
|
|
|
|
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
if ( $lexer === null ) {
|
2018-02-22 23:06:58 +00:00
|
|
|
// When syntax highlighting is disabled..
|
2021-01-01 17:53:48 +00:00
|
|
|
$status->value = self::plainCodeWrap( $code, $isInline );
|
2015-06-26 21:39:15 +00:00
|
|
|
return $status;
|
2009-06-24 05:25:32 +00:00
|
|
|
}
|
2008-09-28 15:30:45 +00:00
|
|
|
|
2017-06-15 16:16:11 +00:00
|
|
|
$options = [
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
'cssclass' => self::HIGHLIGHT_CSS_CLASS,
|
|
|
|
'encoding' => 'utf-8',
|
2017-06-15 16:16:11 +00:00
|
|
|
];
|
2008-09-28 15:30:45 +00:00
|
|
|
|
2008-07-11 18:12:48 +00:00
|
|
|
// Line numbers
|
2021-01-01 17:53:48 +00:00
|
|
|
if ( $showLines ) {
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
$options['linenos'] = 'inline';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $lexer === 'php' && strpos( $code, '<?php' ) === false ) {
|
|
|
|
$options['startinline'] = 1;
|
2007-06-29 04:33:14 +00:00
|
|
|
}
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
|
|
|
// Highlight specific lines
|
2015-05-20 21:36:13 +00:00
|
|
|
if ( isset( $args['highlight'] ) ) {
|
2008-07-10 20:55:02 +00:00
|
|
|
$lines = self::parseHighlightLines( $args['highlight'] );
|
2011-12-02 17:00:19 +00:00
|
|
|
if ( count( $lines ) ) {
|
2015-06-23 13:49:16 +00:00
|
|
|
$options['hl_lines'] = implode( ' ', $lines );
|
2010-08-09 06:56:38 +00:00
|
|
|
}
|
2008-07-10 12:45:20 +00:00
|
|
|
}
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
2007-06-29 04:33:14 +00:00
|
|
|
// Starting line number
|
2017-02-21 19:20:16 +00:00
|
|
|
if ( isset( $args['start'] ) && ctype_digit( $args['start'] ) ) {
|
|
|
|
$options['linenostart'] = (int)$args['start'];
|
2010-08-09 06:56:38 +00:00
|
|
|
}
|
2011-11-20 18:07:20 +00:00
|
|
|
|
2021-01-01 19:48:57 +00:00
|
|
|
if ( !empty( $args['linelinks'] ) && ctype_alpha( $args['linelinks'] ) ) {
|
|
|
|
$options['linespans'] = $args['linelinks'];
|
|
|
|
}
|
|
|
|
|
2021-01-01 17:53:48 +00:00
|
|
|
if ( $isInline ) {
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
$options['nowrap'] = 1;
|
|
|
|
}
|
2011-02-10 01:59:14 +00:00
|
|
|
|
2019-07-03 13:58:03 +00:00
|
|
|
$cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
|
2018-02-22 23:29:33 +00:00
|
|
|
$error = null;
|
|
|
|
$output = $cache->getWithSetCallback(
|
|
|
|
$cache->makeGlobalKey( 'highlight', self::makeCacheKeyHash( $code, $lexer, $options ) ),
|
|
|
|
$cache::TTL_MONTH,
|
|
|
|
function ( $oldValue, &$ttl ) use ( $code, $lexer, $options, &$error ) {
|
|
|
|
$optionPairs = [];
|
|
|
|
foreach ( $options as $k => $v ) {
|
|
|
|
$optionPairs[] = "{$k}={$v}";
|
|
|
|
}
|
|
|
|
$result = Shell::command(
|
|
|
|
self::getPygmentizePath(),
|
|
|
|
'-l', $lexer,
|
|
|
|
'-f', 'html',
|
|
|
|
'-O', implode( ',', $optionPairs )
|
|
|
|
)
|
|
|
|
->input( $code )
|
|
|
|
->restrict( Shell::RESTRICT_DEFAULT | Shell::NO_NETWORK )
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
if ( $result->getExitCode() != 0 ) {
|
|
|
|
$ttl = WANObjectCache::TTL_UNCACHEABLE;
|
|
|
|
$error = $result->getStderr();
|
|
|
|
return null;
|
|
|
|
}
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
|
2021-01-01 17:53:48 +00:00
|
|
|
return $result->getStdout();
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
}
|
2018-02-22 23:29:33 +00:00
|
|
|
);
|
2015-12-02 21:21:11 +00:00
|
|
|
|
2018-02-22 23:29:33 +00:00
|
|
|
if ( $error !== null || $output === null ) {
|
|
|
|
$status->warning( 'syntaxhighlight-error-pygments-invocation-failure' );
|
2019-12-22 06:40:07 +00:00
|
|
|
if ( $error !== null ) {
|
|
|
|
wfWarn( 'Failed to invoke Pygments: ' . $error );
|
|
|
|
} else {
|
|
|
|
wfWarn( 'Invoking Pygments returned blank output with no error response' );
|
|
|
|
}
|
|
|
|
|
2018-02-22 23:29:33 +00:00
|
|
|
// Fall back to preformatted code without syntax highlighting
|
2021-01-01 17:53:48 +00:00
|
|
|
$output = self::plainCodeWrap( $code, $isInline );
|
|
|
|
}
|
|
|
|
|
|
|
|
$status->value = $output;
|
|
|
|
|
|
|
|
return $status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Highlight a code-block using a particular lexer.
|
|
|
|
*
|
|
|
|
* This produces raw HTML (wrapped by Status), the caller is responsible
|
|
|
|
* for making sure the "ext.pygments" module is loaded in the output.
|
|
|
|
*
|
|
|
|
* @param string $code Code to highlight.
|
|
|
|
* @param string|null $lang Language name, or null to use plain markup.
|
|
|
|
* @param array $args Associative array of additional arguments.
|
|
|
|
* If it contains a 'line' key, the output will include line numbers.
|
|
|
|
* If it includes a 'highlight' key, the value will be parsed as a
|
2021-01-01 19:48:57 +00:00
|
|
|
* comma-separated list of lines and line-ranges to highlight.
|
2021-01-01 17:53:48 +00:00
|
|
|
* If it contains a 'start' key, the value will be used as the line at which to
|
2021-01-01 19:48:57 +00:00
|
|
|
* start highlighting.
|
2021-01-01 17:53:48 +00:00
|
|
|
* If it contains a 'inline' key, the output will not be wrapped in `<div><pre/></div>`.
|
2021-01-01 19:48:57 +00:00
|
|
|
* If it contains a 'linelinks' key, lines will have links and anchors with a prefix
|
|
|
|
* of the value. Similar to the lineanchors+linespans features in Pygments.
|
2021-01-01 17:53:48 +00:00
|
|
|
* @param Parser|null $parser Parser, if generating content to be parsed.
|
|
|
|
* @return Status Status object, with HTML representing the highlighted
|
|
|
|
* code as its value.
|
|
|
|
*/
|
|
|
|
public static function highlight( $code, $lang = null, $args = [], ?Parser $parser = null ) {
|
|
|
|
$status = self::highlightInner( $code, $lang, $args );
|
|
|
|
$output = $status->getValue();
|
|
|
|
|
|
|
|
$isInline = isset( $args['inline'] );
|
|
|
|
$showLines = isset( $args['line'] );
|
|
|
|
$lexer = self::getLexer( $lang );
|
|
|
|
|
|
|
|
// Post-Pygment HTML transformations.
|
|
|
|
|
2021-01-01 19:48:57 +00:00
|
|
|
if ( $showLines ) {
|
|
|
|
$lineReplace = Html::element( 'span', [ 'class' => 'linenos', 'data-line' => '$1' ] );
|
|
|
|
if ( !empty( $args['linelinks'] ) ) {
|
|
|
|
$lineReplace = Html::rawElement(
|
|
|
|
'a',
|
|
|
|
[ 'href' => '#' . $args['linelinks'] . '-$1' ],
|
|
|
|
$lineReplace
|
|
|
|
);
|
|
|
|
}
|
|
|
|
// Convert line numbers to data attributes so they
|
|
|
|
// can be displayed as CSS generated content and be
|
|
|
|
// unselectable in all browsers.
|
|
|
|
$output = preg_replace(
|
|
|
|
'`<span class="linenos">\s*([^<]*)\s*</span>`',
|
|
|
|
$lineReplace,
|
|
|
|
$output
|
|
|
|
);
|
|
|
|
}
|
2021-01-01 17:53:48 +00:00
|
|
|
|
|
|
|
// Allow certain HTML attributes
|
|
|
|
$htmlAttribs = Sanitizer::validateAttributes(
|
|
|
|
$args, array_flip( [ 'style', 'class', 'id' ] )
|
|
|
|
);
|
|
|
|
|
|
|
|
$dir = ( isset( $args['dir'] ) && $args['dir'] === 'rtl' ) ? 'rtl' : 'ltr';
|
|
|
|
|
|
|
|
// Build class list
|
|
|
|
$classList = [];
|
|
|
|
if ( isset( $htmlAttribs['class'] ) ) {
|
|
|
|
$classList[] = $htmlAttribs['class'];
|
|
|
|
}
|
|
|
|
$classList[] = self::HIGHLIGHT_CSS_CLASS;
|
|
|
|
if ( $lexer !== null ) {
|
|
|
|
$classList[] = self::HIGHLIGHT_CSS_CLASS . '-lang-' . $lexer;
|
|
|
|
}
|
2021-01-15 17:29:46 +00:00
|
|
|
$classList[] = 'mw-content-' . $dir;
|
2021-01-01 17:53:48 +00:00
|
|
|
if ( $showLines ) {
|
|
|
|
$classList[] = self::HIGHLIGHT_CSS_CLASS . '-lines';
|
|
|
|
}
|
|
|
|
$htmlAttribs['class'] = implode( ' ', $classList );
|
|
|
|
$htmlAttribs['dir'] = $dir;
|
|
|
|
'@phan-var array{class:string,dir:string} $htmlAttribs';
|
2011-02-10 01:59:14 +00:00
|
|
|
|
2021-01-01 17:53:48 +00:00
|
|
|
if ( $isInline ) {
|
2018-02-22 23:29:33 +00:00
|
|
|
// We've already trimmed the input $code before highlighting,
|
|
|
|
// but pygment's standard out adds a line break afterwards,
|
|
|
|
// which would then be preserved in the paragraph that wraps this,
|
|
|
|
// and become visible as a space. Avoid that.
|
2015-07-03 13:42:46 +00:00
|
|
|
$output = trim( $output );
|
2021-01-01 17:53:48 +00:00
|
|
|
|
|
|
|
// Enforce inlineness. Stray newlines may result in unexpected list and paragraph processing
|
|
|
|
// (also known as doBlockLevels()).
|
|
|
|
$output = str_replace( "\n", ' ', $output );
|
|
|
|
$output = Html::rawElement( 'code', $htmlAttribs, $output );
|
|
|
|
} else {
|
|
|
|
$output = self::unwrap( $output );
|
|
|
|
|
|
|
|
if ( $parser ) {
|
|
|
|
// Use 'nowiki' strip marker to prevent list processing (also known as doBlockLevels()).
|
|
|
|
// However, leave the wrapping <div/> outside to prevent <p/>-wrapping.
|
|
|
|
$marker = $parser::MARKER_PREFIX . '-syntaxhighlightinner-' .
|
|
|
|
sprintf( '%08X', $parser->mMarkerIndex++ ) . $parser::MARKER_SUFFIX;
|
|
|
|
$parser->mStripState->addNoWiki( $marker, $output );
|
|
|
|
$output = $marker;
|
|
|
|
}
|
|
|
|
|
|
|
|
$output = Html::openElement( 'div', $htmlAttribs ) .
|
|
|
|
$output .
|
|
|
|
Html::closeElement( 'div' );
|
2007-06-29 04:33:14 +00:00
|
|
|
}
|
2011-02-10 01:59:14 +00:00
|
|
|
|
2015-06-26 21:39:15 +00:00
|
|
|
$status->value = $output;
|
|
|
|
return $status;
|
2011-02-10 01:59:14 +00:00
|
|
|
}
|
|
|
|
|
2015-06-23 15:54:19 +00:00
|
|
|
/**
|
|
|
|
* Construct a cache key for the results of a Pygments invocation.
|
|
|
|
*
|
|
|
|
* @param string $code Code to be highlighted.
|
|
|
|
* @param string $lexer Lexer name.
|
|
|
|
* @param array $options Options array.
|
|
|
|
* @return string Cache key.
|
|
|
|
*/
|
2018-02-22 23:29:33 +00:00
|
|
|
private static function makeCacheKeyHash( $code, $lexer, $options ) {
|
2015-06-23 15:54:19 +00:00
|
|
|
$optionString = FormatJson::encode( $options, false, FormatJson::ALL_OK );
|
2018-02-22 23:29:33 +00:00
|
|
|
return md5( "{$code}|{$lexer}|{$optionString}|" . self::CACHE_VERSION );
|
2015-06-23 15:54:19 +00:00
|
|
|
}
|
|
|
|
|
2008-07-10 20:55:02 +00:00
|
|
|
/**
|
|
|
|
* Take an input specifying a list of lines to highlight, returning
|
|
|
|
* a raw list of matching line numbers.
|
|
|
|
*
|
|
|
|
* Input is comma-separated list of lines or line ranges.
|
|
|
|
*
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
* @param string $lineSpec
|
|
|
|
* @return int[] Line numbers.
|
2008-07-10 20:55:02 +00:00
|
|
|
*/
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
protected static function parseHighlightLines( $lineSpec ) {
|
2017-06-15 16:16:11 +00:00
|
|
|
$lines = [];
|
2015-06-23 13:49:16 +00:00
|
|
|
$values = array_map( 'trim', explode( ',', $lineSpec ) );
|
|
|
|
foreach ( $values as $value ) {
|
|
|
|
if ( ctype_digit( $value ) ) {
|
|
|
|
$lines[] = (int)$value;
|
|
|
|
} elseif ( strpos( $value, '-' ) !== false ) {
|
2019-12-22 06:40:07 +00:00
|
|
|
list( $start, $end ) = array_map( 'intval', explode( '-', $value ) );
|
2015-06-23 13:49:16 +00:00
|
|
|
if ( self::validHighlightRange( $start, $end ) ) {
|
2019-12-22 06:40:07 +00:00
|
|
|
for ( $i = $start; $i <= $end; $i++ ) {
|
2015-06-23 13:49:16 +00:00
|
|
|
$lines[] = $i;
|
|
|
|
}
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( count( $lines ) > self::HIGHLIGHT_MAX_LINES ) {
|
|
|
|
$lines = array_slice( $lines, 0, self::HIGHLIGHT_MAX_LINES );
|
|
|
|
break;
|
2008-09-28 15:30:45 +00:00
|
|
|
}
|
|
|
|
}
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
return $lines;
|
2008-09-28 15:30:45 +00:00
|
|
|
}
|
|
|
|
|
2015-06-23 13:49:16 +00:00
|
|
|
/**
|
|
|
|
* Validate a provided input range
|
2017-10-07 15:16:00 +00:00
|
|
|
* @param int $start
|
|
|
|
* @param int $end
|
2015-06-23 13:49:16 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
protected static function validHighlightRange( $start, $end ) {
|
|
|
|
// Since we're taking this tiny range and producing a an
|
|
|
|
// array of every integer between them, it would be trivial
|
|
|
|
// to DoS the system by asking for a huge range.
|
|
|
|
// Impose an arbitrary limit on the number of lines in a
|
|
|
|
// given range to reduce the impact.
|
2019-12-22 06:40:07 +00:00
|
|
|
return $start > 0 &&
|
2015-06-23 13:49:16 +00:00
|
|
|
$start < $end &&
|
|
|
|
$end - $start < self::HIGHLIGHT_MAX_LINES;
|
|
|
|
}
|
|
|
|
|
2012-10-16 10:33:26 +00:00
|
|
|
/**
|
|
|
|
* Hook into Content::getParserOutput to provide syntax highlighting for
|
|
|
|
* script content.
|
|
|
|
*
|
2017-10-07 15:16:00 +00:00
|
|
|
* @param Content $content
|
|
|
|
* @param Title $title
|
|
|
|
* @param int $revId
|
|
|
|
* @param ParserOptions $options
|
|
|
|
* @param bool $generateHtml
|
|
|
|
* @param ParserOutput &$output
|
2012-10-16 10:33:26 +00:00
|
|
|
* @return bool
|
|
|
|
* @since MW 1.21
|
|
|
|
*/
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
public static function onContentGetParserOutput( Content $content, Title $title,
|
2017-07-08 09:51:33 +00:00
|
|
|
$revId, ParserOptions $options, $generateHtml, ParserOutput &$output
|
|
|
|
) {
|
2019-10-28 20:13:31 +00:00
|
|
|
global $wgTextModelsToParse;
|
2012-10-16 10:33:26 +00:00
|
|
|
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
if ( !$generateHtml ) {
|
|
|
|
// Nothing special for us to do, let MediaWiki handle this.
|
|
|
|
return true;
|
|
|
|
}
|
2015-05-20 21:36:13 +00:00
|
|
|
|
2012-10-16 10:33:26 +00:00
|
|
|
// Determine the language
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
$extension = ExtensionRegistry::getInstance();
|
|
|
|
$models = $extension->getAttribute( 'SyntaxHighlightModels' );
|
2012-10-16 10:33:26 +00:00
|
|
|
$model = $content->getModel();
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
if ( !isset( $models[$model] ) ) {
|
2012-10-16 10:33:26 +00:00
|
|
|
// We don't care about this model, carry on.
|
|
|
|
return true;
|
|
|
|
}
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
$lexer = $models[$model];
|
2012-10-16 10:33:26 +00:00
|
|
|
|
|
|
|
// Hope that $wgSyntaxHighlightModels does not contain silly types.
|
2014-09-15 04:50:20 +00:00
|
|
|
$text = ContentHandler::getContentText( $content );
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
if ( !$text ) {
|
2014-07-30 19:09:05 +00:00
|
|
|
// Oops! Non-text content? Let MediaWiki handle this.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse using the standard parser to get links etc. into the database, HTML is replaced below.
|
|
|
|
// We could do this using $content->fillParserOutput(), but alas it is 'protected'.
|
|
|
|
if ( $content instanceof TextContent && in_array( $model, $wgTextModelsToParse ) ) {
|
2019-10-28 20:13:31 +00:00
|
|
|
$output = MediaWikiServices::getInstance()->getParser()
|
|
|
|
->parse( $text, $title, $options, true, true, $revId );
|
2012-10-16 10:33:26 +00:00
|
|
|
}
|
|
|
|
|
2021-01-01 19:48:57 +00:00
|
|
|
$status = self::highlight( $text, $lexer, [ 'line' => true, 'linelinks' => 'L' ] );
|
2015-06-26 21:39:15 +00:00
|
|
|
if ( !$status->isOK() ) {
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
return true;
|
2015-05-20 21:36:13 +00:00
|
|
|
}
|
2015-06-26 21:39:15 +00:00
|
|
|
$out = $status->getValue();
|
2015-05-20 21:36:13 +00:00
|
|
|
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
$output->addModuleStyles( 'ext.pygments' );
|
2021-01-01 19:48:57 +00:00
|
|
|
$output->addModules( 'ext.pygments.linenumbers' );
|
2021-01-01 17:53:48 +00:00
|
|
|
$output->setText( $out );
|
2012-10-16 10:33:26 +00:00
|
|
|
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
// Inform MediaWiki that we have parsed this page and it shouldn't mess with it.
|
|
|
|
return false;
|
2014-09-17 19:32:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hook to provide syntax highlighting for API pretty-printed output
|
|
|
|
*
|
|
|
|
* @param IContextSource $context
|
|
|
|
* @param string $text
|
|
|
|
* @param string $mime
|
|
|
|
* @param string $format
|
|
|
|
* @since MW 1.24
|
2017-03-27 23:25:36 +00:00
|
|
|
* @return bool
|
2014-09-17 19:32:35 +00:00
|
|
|
*/
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
public static function onApiFormatHighlight( IContextSource $context, $text, $mime, $format ) {
|
|
|
|
if ( !isset( self::$mimeLexers[$mime] ) ) {
|
|
|
|
return true;
|
2014-09-17 19:32:35 +00:00
|
|
|
}
|
|
|
|
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
$lexer = self::$mimeLexers[$mime];
|
2015-06-26 21:39:15 +00:00
|
|
|
$status = self::highlight( $text, $lexer );
|
|
|
|
if ( !$status->isOK() ) {
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
return true;
|
2012-10-16 10:33:26 +00:00
|
|
|
}
|
|
|
|
|
2015-06-26 21:39:15 +00:00
|
|
|
$out = $status->getValue();
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
if ( preg_match( '/^<pre([^>]*)>/i', $out, $m ) ) {
|
|
|
|
$attrs = Sanitizer::decodeTagAttributes( $m[1] );
|
|
|
|
$attrs['class'] .= ' api-pretty-content';
|
|
|
|
$encodedAttrs = Sanitizer::safeEncodeTagAttributes( $attrs );
|
2018-09-03 19:50:49 +00:00
|
|
|
$out = '<pre' . $encodedAttrs . '>' . substr( $out, strlen( $m[0] ) );
|
2010-08-09 06:56:38 +00:00
|
|
|
}
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
$output = $context->getOutput();
|
|
|
|
$output->addModuleStyles( 'ext.pygments' );
|
|
|
|
$output->addHTML( '<div dir="ltr">' . $out . '</div>' );
|
2013-02-13 20:15:37 +00:00
|
|
|
|
Highlight using Pygments rather than Geshi
GeSHi is unmaintained, lacks support for many popular modern languages, and
suffers from deep architectural flaws, chief among them the inconsistent
tokenization of different languages, each of which requires a custom
stylesheet.
Pygments is a well-maintained alternative. It is, by my count, the most popular
syntax highlighting library around. It is BSD-licensed, actively maintained,
and is widely used in PHP projects.
To keep this easy to review, this change does not include update for l10n
files, and it does not delete the geshi/ directory. I will do those in a
separate patch.
The chief change between this and the previous implementation is that errors
result in the code block not being highlighted, as opposed to not being printed
at all, having been replaced by an angry red error message. I think that is the
right user experience. If you go to StackOverflow or GitHub and try to mark up
your code block as being written in some language that their highlighter
doesn't know about, you don't get an error message -- the code simply doesn't
get highlighted.
Because we don't recursively load dependencies for extensions, to test this,
you will need to create a composer.local.json in $IP and add:
{
"extra": {
"merge-plugin": {
"include": [
"extensions/SyntaxHighlight_GeSHi/composer.json"
]
}
}
}
Then run `composer update`.
Bug: T85794
Change-Id: I07446ec9893fae3d1e394f435d3d95cf8be6bc33
2015-06-16 03:52:58 +00:00
|
|
|
// Inform MediaWiki that we have parsed this page and it shouldn't mess with it.
|
|
|
|
return false;
|
2014-04-16 20:23:12 +00:00
|
|
|
}
|
2011-08-14 06:59:35 +00:00
|
|
|
}
|