diff options
Diffstat (limited to 'www/wiki/extensions/Scribunto/includes/common/ScribuntoContent.php')
-rw-r--r-- | www/wiki/extensions/Scribunto/includes/common/ScribuntoContent.php | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/www/wiki/extensions/Scribunto/includes/common/ScribuntoContent.php b/www/wiki/extensions/Scribunto/includes/common/ScribuntoContent.php new file mode 100644 index 00000000..ff2ec8e4 --- /dev/null +++ b/www/wiki/extensions/Scribunto/includes/common/ScribuntoContent.php @@ -0,0 +1,160 @@ +<?php +/** + * Scribunto Content Model + * + * @file + * @ingroup Extensions + * @ingroup Scribunto + * + * @author Brad Jorsch <bjorsch@wikimedia.org> + */ + +/** + * Represents the content of a Scribunto script page + */ +class ScribuntoContent extends TextContent { + + function __construct( $text ) { + parent::__construct( $text, CONTENT_MODEL_SCRIBUNTO ); + } + + /** + * Checks whether the script is valid + * + * @param Title $title + * @return Status + */ + public function validate( Title $title ) { + $engine = Scribunto::newDefaultEngine(); + $engine->setTitle( $title ); + return $engine->validate( $this->getNativeData(), $title->getPrefixedDBkey() ); + } + + public function prepareSave( WikiPage $page, $flags, $parentRevId, User $user ) { + return $this->validate( $page->getTitle() ); + } + + /** + * Parse the Content object and generate a ParserOutput from the result. + * + * @param Title $title The page title to use as a context for rendering + * @param null|int $revId The revision being rendered (optional) + * @param null|ParserOptions $options Any parser options + * @param bool $generateHtml Whether to generate HTML (default: true). + * @param ParserOutput &$output ParserOutput representing the HTML form of the text. + * @return ParserOutput + */ + protected function fillParserOutput( + Title $title, $revId, ParserOptions $options, $generateHtml, ParserOutput &$output + ) { + global $wgParser; + + $text = $this->getNativeData(); + + // Get documentation, if any + $output = new ParserOutput(); + $doc = Scribunto::getDocPage( $title ); + if ( $doc ) { + $msg = wfMessage( + $doc->exists() ? 'scribunto-doc-page-show' : 'scribunto-doc-page-does-not-exist', + $doc->getPrefixedText() + )->inContentLanguage(); + + if ( !$msg->isDisabled() ) { + // We need the ParserOutput for categories and such, so we + // can't use $msg->parse(). + $docViewLang = $doc->getPageViewLanguage(); + $dir = $docViewLang->getDir(); + + // Code is forced to be ltr, but the documentation can be rtl. + // Correct direction class is needed for correct formatting. + // The possible classes are + // mw-content-ltr or mw-content-rtl + $dirClass = "mw-content-$dir"; + + $docWikitext = Html::rawElement( + 'div', + [ + 'lang' => $docViewLang->getHtmlCode(), + 'dir' => $dir, + 'class' => $dirClass, + ], + // Line breaks are needed so that wikitext would be + // appropriately isolated for correct parsing. See Bug 60664. + "\n" . $msg->plain() . "\n" + ); + + if ( !$options ) { + // NOTE: use canonical options per default to produce cacheable output + $options = ContentHandler::getForTitle( $doc )->makeParserOptions( 'canonical' ); + } else { + if ( $options->getTargetLanguage() === null ) { + $options->setTargetLanguage( $doc->getPageLanguage() ); + } + } + + $output = $wgParser->parse( $docWikitext, $title, $options, true, true, $revId ); + } + + // Mark the doc page as a transclusion, so we get purged when it + // changes. + $output->addTemplate( $doc, $doc->getArticleID(), $doc->getLatestRevID() ); + } + + // Validate the script, and include an error message and tracking + // category if it's invalid + $status = $this->validate( $title ); + if ( !$status->isOK() ) { + $output->setText( $output->getRawText() . + Html::rawElement( 'div', [ 'class' => 'errorbox' ], + $status->getHTML( 'scribunto-error-short', 'scribunto-error-long' ) + ) + ); + $output->addTrackingCategory( 'scribunto-module-with-errors-category', $title ); + } + + if ( !$generateHtml ) { + // We don't need the actual HTML + $output->setText( '' ); + return $output; + } + + $engine = Scribunto::newDefaultEngine(); + $engine->setTitle( $title ); + if ( $this->highlight( $text, $output, $engine ) ) { + return $output; + } + + // No GeSHi, or GeSHi can't parse it, use plain <pre> + $output->setText( $output->getRawText() . + "<pre class='mw-code mw-script' dir='ltr'>\n" . + htmlspecialchars( $text ) . + "\n</pre>\n" + ); + + return $output; + } + + /** + * Adds syntax highlighting to the output (or do not touch it and return false). + * @param string $text + * @param ParserOutput $output + * @param ScribuntoEngineBase $engine + * @return bool Success status + */ + protected function highlight( $text, ParserOutput $output, ScribuntoEngineBase $engine ) { + global $wgScribuntoUseGeSHi; + $language = $engine->getGeSHiLanguage(); + if ( $wgScribuntoUseGeSHi && class_exists( SyntaxHighlight::class ) && $language ) { + $status = SyntaxHighlight::highlight( $text, $language ); + if ( $status->isGood() ) { + // @todo replace addModuleStyles line with the appropriate call on + // SyntaxHighlight once one is created + $output->addModuleStyles( 'ext.pygments' ); + $output->setText( $output->getRawText() . $status->getValue() ); + return true; + } + } + return false; + } +} |