Parser improvements: global variable destruction

This commit is contained in:
Tim Starling 2004-02-29 08:43:29 +00:00
parent 7f0854126d
commit db41d9ae7c
6 changed files with 284 additions and 190 deletions

View file

@ -304,7 +304,7 @@ class Article {
function view()
{
global $wgUser, $wgOut, $wgLang;
global $oldid, $diff; # From query
global $oldid, $diff, $printable; # From query
global $wgLinkCache, $IP, $wgEnableParserCache;
$fname = "Article::view";
@ -356,6 +356,10 @@ class Article {
$wgLinkCache->preFill( $this->mTitle );
if ( $printable == "yes" ) {
$wgOut->mParserOptions->setPrintable( true );
}
if( $wgEnableParserCache && intval($wgUser->getOption( "stubthreshold" )) == 0 ){
$wgOut->addWikiText( $text, true, $this );
} else {

View file

@ -85,7 +85,7 @@ class EditPage {
global $wpSave, $wpPreview;
global $wpMinoredit, $wpEdittime, $wpTextbox2, $wpSection;
global $oldid, $redirect, $section;
global $wgLang;
global $wgLang, $wgParser, $wgTitle;
global $wgAllowAnonymousMinor;
if(isset($wpSection)) { $section=$wpSection; } else { $wpSection=$section; }
@ -288,9 +288,17 @@ class EditPage {
}
$previewtext = wfUnescapeHTML( $wpTextbox1 );
$parserOptions = ParserOptions::newFromUser( $wgUser );
$parserOptions->setUseCategoryMagic( false );
$parserOptions->setEditSection( false );
$parserOptions->setEditSectionOnRightClick( false );
$parserOutput = $wgParser->parse( $this->mArticle->preSaveTransform( $previewtext ) ."\n\n",
$wgTitle, $parserOptions );
$previewHTML = $parserOutput->mText;
if($wgUser->getOption("previewontop")) {
$wgOut->addHTML($previewhead);
$wgOut->addWikiText( $this->mArticle->preSaveTransform( $previewtext ) ."\n\n");
$wgOut->addHTML($previewHTML);
}
$wgOut->addHTML( "<br clear=\"all\" />\n" );
}
@ -342,7 +350,7 @@ $wgLang->recodeForEdit( $wpTextbox1 ) .
$wgOut->addHTML( "</form>\n" );
if($formtype =="preview" && !$wgUser->getOption("previewontop")) {
$wgOut->addHTML($previewhead);
$wgOut->addWikiText( $this->mArticle->preSaveTransform( $previewtext ) );
$wgOut->addHTML($previewHTML);
}
}

View file

@ -15,6 +15,7 @@ class OutputPage {
var $mDoNothing;
var $mContainsOldMagic, $mContainsNewMagic;
var $mIsArticleRelated;
var $mParserOptions;
function OutputPage()
{
@ -30,6 +31,7 @@ class OutputPage {
$this->mCategoryLinks = array() ;
$this->mDoNothing = false;
$this->mContainsOldMagic = $this->mContainsNewMagic = 0;
$this->mParserOptions = ParserOptions::newFromUser( $temp = NULL );
}
function addHeader( $name, $val ) { array_push( $this->mHeaders, "$name: $val" ) ; }
@ -136,6 +138,11 @@ class OutputPage {
function addHeadtext( $text ) { $this->mHeadtext .= $text; }
function debug( $text ) { $this->mDebugtext .= $text; }
function setParserOptions( $options )
{
return wfSetVar( $this->mParserOptions, $options );
}
# First pass--just handle <nowiki> sections, pass the rest off
# to doWikiPass2() which does all the real work.
#
@ -143,7 +150,7 @@ class OutputPage {
#
function addWikiText( $text, $linestart = true, $cacheArticle = NULL )
{
global $wgParser, $wgParserCache, $wgUser;
global $wgParser, $wgParserCache, $wgUser, $wgTitle;
$parserOutput = false;
if ( $cacheArticle ) {
@ -151,7 +158,7 @@ class OutputPage {
}
if ( $parserOutput === false ) {
$parserOutput = $wgParser->parse( $text, $linestart );
$parserOutput = $wgParser->parse( $text, $wgTitle, $this->mParserOptions, $linestart );
if ( $cacheArticle ) {
$wgParserCache->save( $parserOutput, $cacheArticle, $wgUser );
}

View file

@ -2,18 +2,26 @@
include_once('Tokenizer.php');
# PHP Parser
#
# Converts wikitext to HTML.
#
# Globals used:
# objects: $wgUser, $wgTitle, $wgLang, $wgDateFormatter, $wgLinkCache, $wgCurOut, $wgArticle
# objects: $wgLang, $wgDateFormatter, $wgLinkCache, $wgCurOut
#
# query: $wpPreview
# settings: $wgUseTex*, $wgUseCategoryMagic*, $wgUseDynamicDates*, $wgInterwikiMagic*,
# $wgNamespacesWithSubpages, $wgLanguageCode, $wgAllowExternalImages*
#
# settings: $wgUseTex, $wgUseCategoryMagic, $wgUseDynamicDates, $wgInterwikiMagic,
# $wgNamespacesWithSubpages, $wgLanguageCode, $wgUseLinkPrefixCombination
# * only within ParserOptions
class Parser
{
# Cleared with clearState():
var $mOutput, $mAutonumber, $mLastSection, $mDTopen;
# Temporary:
var $mOptions, $mTitle;
function Parser()
{
$this->clearState();
@ -32,9 +40,8 @@ class Parser
#
# Returns a ParserOutput
#
function parse( $text, $linestart = true, $clearState = true )
function parse( $text, &$title, $options, $linestart = true, $clearState = true )
{
global $wgUseTeX;
$fname = "Parser::parse";
wfProfileIn( $fname );
$unique = "3iyZiyA7iMwg5rhxP0Dcc9oTnj8qD1jm1Sfv4";
@ -54,6 +61,9 @@ class Parser
$this->clearState();
}
$this->mOptions = $options;
$this->mTitle =& $title;
# Replace any instances of the placeholders
$text = str_replace( $unique, wfHtmlEscapeFirst( $unique ), $text );
$text = str_replace( $unique2, wfHtmlEscapeFirst( $unique2 ), $text );
@ -72,7 +82,7 @@ class Parser
}
}
if( $wgUseTeX ) {
if( $this->mOptions->getUseTeX() ) {
while ( "" != $stripped ) {
$p = preg_split( "/<\\s*math\\s*>/i", $stripped, 2 );
$stripped2 .= $p[0];
@ -130,11 +140,11 @@ class Parser
function categoryMagic ()
{
global $wgTitle , $wgUseCategoryMagic, $wgLang ;
if ( !isset ( $wgUseCategoryMagic ) || !$wgUseCategoryMagic ) return ;
$id = $wgTitle->getArticleID() ;
global $wgLang ;
if ( !$this->mOptions->getUseCategoryMagic() ) return ;
$id = $this->mTitle->getArticleID() ;
$cat = ucfirst ( wfMsg ( "category" ) ) ;
$ti = $wgTitle->getText() ;
$ti = $this->mTitle->getText() ;
$ti = explode ( ":" , $ti , 2 ) ;
if ( $cat != $ti[0] ) return "" ;
$r = "<br break=all>\n" ;
@ -144,8 +154,7 @@ class Parser
$children = array() ;
global $wgUser ;
$sk = $wgUser->getSkin() ;
$sk =& $this->mGetSkin();
$doesexist = false ;
if ( $doesexist ) {
@ -198,8 +207,8 @@ class Parser
return $r ;
}
function getHTMLattrs ()
{
function getHTMLattrs ()
{
$htmlattrs = array( # Allowed attributes--no scripting, etc.
"title", "align", "lang", "dir", "width", "height",
"bgcolor", "clear", /* BR */ "noshade", /* HR */
@ -212,11 +221,11 @@ function getHTMLattrs ()
"headers", "scope", "rowspan", "colspan", /* Tables */
"id", "class", "name", "style" /* For CSS */
);
return $htmlattrs ;
}
return $htmlattrs ;
}
function fixTagAttributes ( $t )
{
function fixTagAttributes ( $t )
{
if ( trim ( $t ) == "" ) return "" ; # Saves runtime ;-)
$htmlattrs = $this->getHTMLattrs() ;
@ -236,10 +245,10 @@ function fixTagAttributes ( $t )
}
return trim ( $t ) ;
}
}
function doTableStuff ( $t )
{
function doTableStuff ( $t )
{
$t = explode ( "\n" , $t ) ;
$td = array () ; # Is currently a td tag open?
$ltd = array () ; # Was it TD or TH?
@ -336,7 +345,7 @@ function doTableStuff ( $t )
$t = implode ( "\n" , $t ) ;
# $t = $this->removeHTMLtags( $t );
return $t ;
}
}
# Well, OK, it's actually about 14 passes. But since all the
# hard lifting is done inside PHP's regex code, it probably
@ -344,7 +353,6 @@ function doTableStuff ( $t )
#
function doWikiPass2( $text, $linestart )
{
global $wgUser, $wgLang, $wgUseDynamicDates;
$fname = "OutputPage::doWikiPass2";
wfProfileIn( $fname );
@ -357,9 +365,9 @@ function doTableStuff ( $t )
$text = $this->doHeadings( $text );
$text = $this->doBlockLevels( $text, $linestart );
if($wgUseDynamicDates) {
if($this->mOptions->getUseDynamicDates()) {
global $wgDateFormatter;
$text = $wgDateFormatter->reformat( $wgUser->getOption("date"), $text );
$text = $wgDateFormatter->reformat( $this->mOptions->getDateFormat(), $text );
}
$text = $this->replaceExternalLinks( $text );
@ -370,7 +378,7 @@ function doTableStuff ( $t )
$text = $this->magicRFC( $text );
$text = $this->formatHeadings( $text );
$sk = $wgUser->getSkin();
$sk =& $this->mOptions->getSkin();
$text = $sk->transformContent( $text );
$text .= $this->categoryMagic () ;
@ -410,10 +418,6 @@ function doTableStuff ( $t )
/* private */ function subReplaceExternalLinks( $s, $protocol, $autonumber )
{
global $wgUser, $printable;
global $wgAllowExternalImages;
$unique = "4jzAfzB8hNvf4sqyO9Edd8pSmk9rE2in0Tgw3";
$uc = "A-Za-z0-9_\\/~%\\-+&*#?!=()@\\x80-\\xFF";
@ -433,9 +437,9 @@ function doTableStuff ( $t )
"((?i){$images})([^{$uc}]|$)/";
$e2 = "/(^|[^\\[])({$protocol}:)(([".$uc."]|[".$sep."][".$uc."])+)([^". $uc . $sep. "]|[".$sep."]|$)/";
$sk = $wgUser->getSkin();
$sk =& $this->mOptions->getSkin();
if ( $autonumber and $wgAllowExternalImages) { # Use img tags only for HTTP urls
if ( $autonumber and $this->mOptions->getAllowExternalImages() ) { # Use img tags only for HTTP urls
$s = preg_replace( $e1, "\\1" . $sk->makeImage( "{$unique}:\\3" .
"/\\4.\\5", "\\4.\\5" ) . "\\6", $s );
}
@ -466,7 +470,7 @@ function doTableStuff ( $t )
$s .= "[{$protocol}:" . $line;
continue;
}
if ( $printable == "yes") $paren = " (<i>" . htmlspecialchars ( $link ) . "</i>)";
if ( $this->mOptions->getPrintable() ) $paren = " (<i>" . htmlspecialchars ( $link ) . "</i>)";
else $paren = "";
$la = $sk->getExternalLinkAttributes( $link, $text );
$s .= "<a href='{$link}'{$la}>{$text}</a>{$paren}{$trail}";
@ -641,17 +645,15 @@ function doTableStuff ( $t )
/* private */ function handleInternalLink( $line )
{
global $wgTitle, $wgUser, $wgLang;
global $wgLinkCache, $wgInterwikiMagic, $wgUseCategoryMagic;
global $wgLang, $wgLinkCache;
global $wgNamespacesWithSubpages, $wgLanguageCode;
static $fname = "OutputPage::replaceInternalLinks" ;
wfProfileIn( $fname );
wfProfileIn( "$fname-setup" );
static $tc = FALSE;
static $sk = FALSE;
if ( !$tc ) { $tc = Title::legalChars() . "#"; }
if ( !$sk ) { $sk = $wgUser->getSkin(); }
$sk =& $this->mOptions->getSkin();
# Match a link having the form [[namespace:link|alternate]]trail
static $e1 = FALSE;
@ -668,13 +670,12 @@ function doTableStuff ( $t )
static $special = FALSE;
static $media = FALSE;
static $category = FALSE;
static $nottalk = "";
if ( !$image ) { $image = Namespace::getImage(); }
if ( !$special ) { $special = Namespace::getSpecial(); }
if ( !$media ) { $media = Namespace::getMedia(); }
if ( !$category ) { $category = wfMsg ( "category" ) ; }
if ( $nottalk=="" ) { $nottalk = !Namespace::isTalk( $wgTitle->getNamespace() ); }
$nottalk = !Namespace::isTalk( $this->mTitle->getNamespace() );
wfProfileOut( "$fname-setup" );
@ -708,8 +709,8 @@ function doTableStuff ( $t )
} else {
$noslash=substr($m[1],1);
}
if($wgNamespacesWithSubpages[$wgTitle->getNamespace()]) { # subpages allowed here
$link = $wgTitle->getPrefixedText(). "/" . trim($noslash);
if($wgNamespacesWithSubpages[$this->mTitle->getNamespace()]) { # subpages allowed here
$link = $this->mTitle->getPrefixedText(). "/" . trim($noslash);
if( "" == $text ) {
$text= $m[1];
} # this might be changed for ugliness reasons
@ -743,7 +744,7 @@ function doTableStuff ( $t )
return $s;
}
}
if( ( $nt->getPrefixedText() == $wgTitle->getPrefixedText() ) &&
if( ( $nt->getPrefixedText() == $this->mTitle->getPrefixedText() ) &&
( strpos( $link, "#" ) == FALSE ) ) {
$s .= $prefix . "<strong>" . $text . "</strong>" . $trail;
return $s;
@ -1110,15 +1111,14 @@ function doTableStuff ( $t )
* */
/* private */ function formatHeadings( $text )
{
global $wgUser,$wgArticle,$wgTitle,$wpPreview;
$nh=$wgUser->getOption( "numberheadings" );
$st=$wgUser->getOption( "showtoc" );
if(!$wgTitle->userCanEdit()) {
$nh=$this->mOptions->getNumberHeadings();
$st=$this->mOptions->getShowToc();
if(!$this->mTitle->userCanEdit()) {
$es=0;
$esr=0;
} else {
$es=$wgUser->getID() && $wgUser->getOption( "editsection" );
$esr=$wgUser->getID() && $wgUser->getOption( "editsectiononrightclick" );
$es=$this->mOptions->getEditSection();
$esr=$this->mOptions->getEditSectionOnRightClick();
}
# Inhibit editsection links if requested in the page
@ -1136,10 +1136,10 @@ function doTableStuff ( $t )
# never add the TOC to the Main Page. This is an entry page that should not
# be more than 1-2 screens large anyway
if($wgTitle->getPrefixedText()==wfMsg("mainpage")) {$st=0;}
if($this->mTitle->getPrefixedText()==wfMsg("mainpage")) {$st=0;}
# We need this to perform operations on the HTML
$sk=$wgUser->getSkin();
$sk =& $this->mOptions->getSkin();
# Get all headlines for numbering them and adding funky stuff like [edit]
# links
@ -1206,7 +1206,7 @@ function doTableStuff ( $t )
if($st) {
$toc.=$sk->tocLine($anchor,$tocline,$toclevel);
}
if($es && !isset($wpPreview)) {
if($es) {
$head[$c].=$sk->editSectionLink($c+1);
}
@ -1220,7 +1220,7 @@ function doTableStuff ( $t )
// Add the edit section link
if($esr && !isset($wpPreview)) {
if($esr) {
$head[$c]=$sk->editSectionScript($c+1,$head[$c]);
}
@ -1241,7 +1241,7 @@ function doTableStuff ( $t )
$i=0;
foreach($blocks as $block) {
if(($es) && !isset($wpPreview) && $c>0 && $i==0) {
if(($es) && $c>0 && $i==0) {
# This is the [edit] link that appears for the top block of text when
# section editing is enabled
$full.=$sk->editSectionLink(0);
@ -1323,6 +1323,80 @@ class ParserOutput
function setContainsOldMagic( $com ) { return wfSetVar( $this->mContainsOldMagic, $com ); }
}
class ParserOptions
{
# All variables are private
var $mUseTeX; # Use texvc to expand <math> tags
var $mUseCategoryMagic; # Treat [[Category:xxxx]] tags specially
var $mUseDynamicDates; # Use $wgDateFormatter to format dates
var $mInterwikiMagic; # Interlanguage links are removed and returned in an array
var $mAllowExternalImages; # Allow external images inline
var $mSkin; # Reference to the preferred skin
var $mDateFormat; # Date format index
var $mEditSection; # Create "edit section" links
var $mEditSectionOnRightClick; # Generate JavaScript to edit section on right click
var $mPrintable; # Generate printable output
var $mNumberHeadings; # Automatically number headings
var $mShowToc; # Show table of contents
function getUseTeX() { return $this->mUseTeX; }
function getUseCategoryMagic() { return $this->mUseCategoryMagic; }
function getUseDynamicDates() { return $this->mUseDynamicDates; }
function getInterwikiMagic() { return $this->mInterwikiMagic; }
function getAllowExternalImages() { return $this->mAllowExternalImages; }
function getSkin() { return $this->mSkin; }
function getDateFormat() { return $this->mDateFormat; }
function getEditSection() { return $this->mEditSection; }
function getEditSectionOnRightClick() { return $this->mEditSectionOnRightClick; }
function getPrintable() { return $this->mPrintable; }
function getNumberHeadings() { return $this->mNumberHeadings; }
function getShowToc() { return $this->mShowToc; }
function setUseTeX( $x ) { return wfSetVar( $this->mUseTeX, $x ); }
function setUseCategoryMagic( $x ) { return wfSetVar( $this->mUseCategoryMagic, $x ); }
function setUseDynamicDates( $x ) { return wfSetVar( $this->mUseDynamicDates, $x ); }
function setInterwikiMagic( $x ) { return wfSetVar( $this->mInterwikiMagic, $x ); }
function setAllowExternalImages( $x ) { return wfSetVar( $this->mAllowExternalImages, $x ); }
function setSkin( $x ) { return wfSetRef( $this->mSkin, $x ); }
function setDateFormat( $x ) { return wfSetVar( $this->mDateFormat, $x ); }
function setEditSection( $x ) { return wfSetVar( $this->mEditSection, $x ); }
function setEditSectionOnRightClick( $x ) { return wfSetVar( $this->mEditSectionOnRightClick, $x ); }
function setPrintable( $x ) { return wfSetVar( $this->mPrintable, $x ); }
function setNumberHeadings( $x ) { return wfSetVar( $this->mNumberHeadings, $x ); }
function setShowToc( $x ) { return wfSetVar( $this->mShowToc, $x ); }
/* static */ function newFromUser( &$user )
{
$popts = new ParserOptions;
$popts->initialiseFromUser( &$user );
return $popts;
}
function initialiseFromUser( &$userInput )
{
global $wgUseTeX, $wgUseCategoryMagic, $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages;
if ( !$userInput ) {
$user = new User;
} else {
$user =& $userInput;
}
$this->mUseTeX = $wgUseTeX;
$this->mUseCategoryMagic = $wgUseCategoryMagic;
$this->mUseDynamicDates = $wgUseDynamicDates;
$this->mInterwikiMagic = $wgInterwikiMagic;
$this->mAllowExternalImages = $wgAllowExternalImages;
$this->mSkin =& $user->getSkin();
$this->mDateFormat = $user->getOption( "date" );
$this->mEditSection = $user->getOption( "editsection" );
$this->mEditSectionOnRightClick = $user->getOption( "editsectiononrightclick" );
$this->mPrintable = false;
$this->mNumberHeadings = $user->getOption( "numberheadings" );
$this->mShowToc = $user->getOption( "showtoc" );
}
}
# Regex callbacks, used in OutputPage::replaceVariables
# Just get rid of the dangerous stuff

View file

@ -127,9 +127,6 @@ include_once( "Language.php" );
$wgMessageCache = new MessageCache;
$wgOut = new OutputPage();
wfDebug( "\n\n" );
$wgLangClass = "Language" . ucfirst( $wgLanguageCode );
if( ! class_exists( $wgLangClass ) ) {
include_once( "LanguageUtf8.php" );
@ -142,6 +139,9 @@ if ( !is_object($wgLang) ) {
}
$wgMessageCache->initialise( $wgUseMemCached, $wgUseDatabaseMessages, $wgMsgCacheExpiry, $wgDBname );
$wgOut = new OutputPage();
wfDebug( "\n\n" );
if ( $wgUseDynamicDates ) {
include_once( "DateFormatter.php" );
global $wgDateFormatter;
@ -160,6 +160,7 @@ $wgMagicWords = array();
$wgMwRedir =& MagicWord::get( MAG_REDIRECT );
$wgParserCache = new ParserCache();
$wgParser = new Parser();
$wgOut->setParserOptions( ParserOptions::newFromUser( $wgUser ) );
wfProfileOut( "$fname-misc" );
wfProfileOut( $fname );

View file

@ -1,7 +1,7 @@
<?php
class Tokenizer {
/* private */ var $mText, $mPos, $mTextLength;
/* private */ var $mCount, $mM, $mMPos;
/* private */ var $mCount, $mM, $mMPos; # What is M meant to stand for?
/* private */ function Tokenizer()
{