From 8b3f49bed5e289206dfd7357fd67136c06563a38 Mon Sep 17 00:00:00 2001 From: Erik Moeller Date: Mon, 30 Jun 2003 00:19:35 +0000 Subject: [PATCH] * "Edit this section" feature that allows loading just part of an article instead of the whole one * "Table of contents" feature that is displayed above the article if that preference is enabled and there are more than three headings * Rewrote auto-numbering code * Automatic insertion of anchors into every page * minor fixes to update.php --- includes/Article.php | 37 +++++++++-- includes/OutputPage.php | 140 +++++++++++++++++++++++++++++++--------- includes/Skin.php | 36 +++++++++++ languages/Language.php | 6 +- update.php | 4 +- 5 files changed, 183 insertions(+), 40 deletions(-) diff --git a/includes/Article.php b/includes/Article.php index 85617c3160..ea9e958222 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -50,7 +50,7 @@ class Article { function getContent( $noredir = false ) { - global $action,$wgTitle; # From query string + global $action,$section,$count,$wgTitle; # From query string wfProfileIn( "Article::getContent" ); if ( 0 == $this->getID() ) { @@ -75,7 +75,20 @@ class Article { ) { return $this->mContent . "\n" .wfMsg("anontalkpagetext"); } - else { + else { + if($action=="edit") { + if($section!="") { + + $secs=preg_split("/(^=+.*?=+)/m", + $this->mContent, -1, + PREG_SPLIT_DELIM_CAPTURE); + if($section==0) { + return trim($secs[0]); + } else { + return trim($secs[$section*2-1] . $secs[$section*2]); + } + } + } return $this->mContent; } } @@ -367,10 +380,12 @@ class Article { global $wgOut, $wgUser, $wgTitle; global $wpTextbox1, $wpSummary, $wpWatchthis; global $wpSave, $wpPreview; - global $wpMinoredit, $wpEdittime, $wpTextbox2; - global $oldid, $redirect; + global $wpMinoredit, $wpEdittime, $wpTextbox2, $wpSection; + global $oldid, $redirect, $section; global $wgLang; + if($wpSection) { $section=$wpSection; } + $sk = $wgUser->getSkin(); $isConflict = false; $wpTextbox1 = rtrim ( $wpTextbox1 ) ; # To avoid text getting longer on each preview @@ -424,7 +439,7 @@ class Article { } if ( ! $isConflict ) { # All's well: update the article here - $this->updateArticle( $wpTextbox1, $wpSummary, $wpMinoredit, $wpWatchthis ); + $this->updateArticle( $wpTextbox1, $wpSummary, $wpMinoredit, $wpWatchthis, $wpSection ); return; } } @@ -553,6 +568,7 @@ name=\"wpSummary\" maxlength=200 size=60>
{$cancel} | {$edithelp}

{$copywarn} + \n" ); if ( $isConflict ) { @@ -628,12 +644,21 @@ name=\"wpSummary\" maxlength=200 size=60>
$this->showArticle( $text, wfMsg( "newarticle" ) ); } - function updateArticle( $text, $summary, $minor, $watchthis ) + function updateArticle( $text, $summary, $minor, $watchthis, $section ) { global $wgOut, $wgUser, $wgTitle, $wgLinkCache; global $wgDBtransactions; $fname = "Article::updateArticle"; + // insert updated section into old text if we have only edited part + // of the article + if ($section != "") { + $oldtext=$this->getContent(); + $secs=preg_split("/(^=+.*?=+)/m",$oldtext,-1,PREG_SPLIT_DELIM_CAPTURE); + $secs[$section*2]=$text."\n\n"; // replace with edited + if($section) { $secs[$section*2-1]=""; } // erase old headline + $text=join("",$secs); + } if ( $this->mMinorEdit ) { $me1 = 1; } else { $me1 = 0; } if ( $minor ) { $me2 = 1; } else { $me2 = 0; } if ( preg_match( "/^(#redirect[^\\n]+)/i", $text, $m ) ) { diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 21019c3ad7..8aaf592368 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -664,7 +664,7 @@ class OutputPage { $text = $this->magicISBN( $text ); $text = $this->magicRFC( $text ); - $text = $this->autoNumberHeadings( $text ); + $text = $this->formatHeadings( $text ); $sk = $wgUser->getSkin(); $text = $sk->transformContent( $text ); @@ -1190,41 +1190,119 @@ class OutputPage { return $text; } - /* private */ function autoNumberHeadings( $text ) + +/* + * + * This function accomplishes several tasks: + * 1) Auto-number headings if that option is enabled + * 2) Add an [edit] link to sections for logged in users who have enabled the option + * 3) Add a Table of contents on the top for users who have enabled the option + * 4) Auto-anchor headings + * + * It loops through all headlines, collects the necessary data, then splits up the + * string and re-inserts the newly formatted headlines. + * + * */ + /* private */ function formatHeadings( $text ) { - global $wgUser; - if ( 1 != $wgUser->getOption( "numberheadings" ) ) { - return $text; - } - $j = 0; - $n = -1; - for ( $i = 0; $i < 9; ++$i ) { - if ( stristr( $text, "" ) != false ) { - ++$j; - if ( $n == -1 ) $n = $i; + global $wgUser,$wgArticle,$wgTitle,$wpPreview; + $nh=$wgUser->getOption( "numberheadings" ); + $st=$wgUser->getOption( "showtoc" ); + $es=$wgUser->getID() && $wgUser->getOption( "editsection" ); + + $sk=$wgUser->getSkin(); + preg_match_all("/)(.*?)<\/H[1-6]>/i",$text,$matches); + + $c=0; + + foreach($matches[3] as $headline) { + if($level) { $prevlevel=$level;} + $level=$matches[1][$c]; + if(($nh||$st) && $level>$prevlevel) { + + $h[$level]=0; // reset when we enter a new level + if($toclevel) { + $toc.=$sk->tocIndent($level-$prevlevel); + } + $toclevel++; + + } + if(($nh||$st) && $level<$prevlevel) { + $h[$level+1]=0; // reset when we step back a level + if($toclevel) { + $toc.=$sk->tocUnindent($prevlevel-$level); + } + $toclevel--; + + } + $h[$level]++; // count number of headlines for each level + + if($nh||$st) { + for($i=1;$i<=$level;$i++) { + if($h[$i]) { + if($dot) {$numbering.=".";} + $numbering.=$h[$i]; + $dot=1; + } + } } + + + $canonized_headline=preg_replace("/<.*?>/","",$headline); // strip out HTML + $tocline=$canonized_headline; + $canonized_headline=str_replace(" ","_",trim($canonized_headline)); + $refer[$c]=$canonized_headline; + $refers[$canonized_headline]++; // count how many in assoc. array so we can track dupes in anchors + $refcount[$c]=$refers[$canonized_headline]; + if($nh||$st) { + $tocline=$numbering ." ". $tocline; + if($nh) { + $headline=$numbering . " " . $headline; // the two are different if the line contains a link + } + } + $anchor=$canonized_headline; + if($refcount[$c]>1) {$anchor.="_".$refcount[$c];} + if($st) { + $toc.=$sk->tocLine($anchor,$tocline); + } + $head[$c].="" + .$headline + ."" + .""; + $numbering=""; + $c++; + $dot=0; + } + + if($st) { + $toclines=$c; + while($toclevel>0) { + $toc.=""; + $toclevel--; + } + + $toc=$sk->tocTable($toc); } - if ( $j < 2 ) return $text; - $i = $n; - $v = array( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); - $t = ""; - while ( count( spliti( ""; - ++$v[$j]; - $b = array(); - for ( $k = $i; $k <= $j; $k++ ) array_push( $b, $v[$k] ); - for ( $k = $j+1; $k < 9; $k++ ) $v[$k] = 0; - $t .= implode( ".", $b ) . " "; - $text = substr( $a[1] , 2 ) ; - } else { #
tag, not a heading! - $t .= $a[0] . "
"; - $text = substr( $a[1], 2 ); + + + // split up and insert constructed headlines + + $blocks=preg_split("/.*?<\/H[1-6]>/i",$text); + $i=0; + foreach($blocks as $block) { + $full.=$block; + if($es && $c>0 && !isset($wpPreview)) { + $full.=$sk->editSectionLink($i); } + + $full.=$head[$i]; + $i++; + } + if($st && $toclines>3) { + $full=$toc."".$full; } - return $t . $text; + return $full; } /* private */ function magicISBN( $text ) diff --git a/includes/Skin.php b/includes/Skin.php index d00a1920c9..2525476674 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -1655,6 +1655,42 @@ class Skin { $s .= "\n"; return $s; } + + function tocIndent($level) { + + while($level--) $rv.="
    "; + return $rv; + + } + + function tocUnindent($level) { + while($level--) $rv.="
"; + return $rv; + } + + function tocLine($anchor,$tocline) { + + return "
  • ".$tocline."
  • "; + + } + + function tocTable($toc) { + + return + "
    " . + "
    ". + "".wfMsg("toc")."

    ". + $toc."

    "; + } + + function editSectionLink($section) { + + global $wgTitle; + $editurl="§ion={$section}"; + $url=$this->makeKnownLink($wgTitle->getPrefixedText(),wfMsg("editsection"),"action=edit".$editurl); + return "

    [".$url."]

    "; + + } } include_once( "SkinStandard.php" ); diff --git a/languages/Language.php b/languages/Language.php index 42579d6bd5..b857533988 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -25,7 +25,7 @@ "contextlines" => 5, "contextchars" => 50, "skin" => 0, "math" => 1, "rcdays" => 7, "rclimit" => 50, "highlightbroken" => 1, "stubthreshold" => 0, - "previewontop" => 1 + "previewontop" => 1, "editsection"=>1, "showtoc"=>1 ); /* private */ $wgQuickbarSettingsEn = array( @@ -53,6 +53,8 @@ this (alternative: like this?).", "hideminor" => "Hide minor edits in recent changes", "usenewrc" => "Enhanced recent changes (not for all browsers)", "numberheadings" => "Auto-number headings", + "editsection"=>"Show links for editing individual sections", + "showtoc"=>"Show table of contents for articles with more than 3 headings", "rememberpassword" => "Remember password across sessions", "editwidth" => "Edit box has full width", "editondblclick" => "Edit pages on double click (JavaScript)", @@ -351,6 +353,8 @@ See $1.", "retrievedfrom" => "Retrieved from \"$1\"", "newmessages" => "You have $1.", "newmessageslink" => "new messages", +"editsection"=>"edit", +"toc" => "Table of contents", # Main script and global functions # diff --git a/update.php b/update.php index e93fb1e771..66ae6f0600 100644 --- a/update.php +++ b/update.php @@ -10,7 +10,7 @@ if ( ! ( is_readable( "./LocalSettings.php" ) exit(); } -$DP = "./includes"; +$IP = "./includes"; include_once( "./LocalSettings.php" ); include_once( "./AdminSettings.php" ); @@ -23,7 +23,7 @@ if ( $wgUseTeX && ( ! is_executable( "./math/texvc" ) ) ) { umask( 000 ); set_time_limit( 0 ); -include_once( "{$IP}/Version.php" ); +include_once( "Version.php" ); include_once( "{$IP}/Setup.php" ); $wgTitle = Title::newFromText( "Update script" ); $wgCommandLineMode = true; -- 2.20.1