$text = Parser::extractTags("math", $text, $math_content, $uniq_prefix);
foreach( $math_content as $marker => $content ){
- if( $render && $this->mOptions->getUseTeX() ){
- $math_content[$marker] = renderMath( $content );
+ if( $render ) {
+ if( $this->mOptions->getUseTeX() ) {
+ $math_content[$marker] = renderMath( $content );
+ } else {
+ $math_content[$marker] = "<math>$content<math>";
+ }
} else {
$math_content[$marker] = "<math>$content</math>";
}
$data = array () ;
$id = $this->mTitle->getArticleID() ;
- # For existing categories
- if( $id ) {
- $sql = "SELECT DISTINCT cur_title,cur_namespace FROM cur,links WHERE l_to={$id} AND l_from=cur_id";
- $res = wfQuery ( $sql, DB_READ ) ;
- while ( $x = wfFetchObject ( $res ) ) $data[] = $x ;
- } else {
- # For non-existing categories
- $t = wfStrencode( $this->mTitle->getPrefixedDBKey() );
- $sql = "SELECT DISTINCT cur_title,cur_namespace FROM cur,brokenlinks WHERE bl_to='$t' AND bl_from=cur_id" ;
- $res = wfQuery ( $sql, DB_READ ) ;
- while ( $x = wfFetchObject ( $res ) ) $data[] = $x ;
- }
+ # FIXME: add limits
+ $t = wfStrencode( $this->mTitle->getDBKey() );
+ $sql = "SELECT DISTINCT cur_title,cur_namespace FROM cur,categorylinks WHERE cl_to='$t' AND cl_from=cur_id ORDER BY cl_sortkey" ;
+ $res = wfQuery ( $sql, DB_READ ) ;
+ while ( $x = wfFetchObject ( $res ) ) $data[] = $x ;
# For all pages that link to this category
foreach ( $data AS $x )
wfFreeResult ( $res ) ;
# Showing subcategories
- if ( count ( $children ) > 0 )
- {
- asort ( $children ) ;
+ if ( count ( $children ) > 0 ) {
$r .= "<h2>".wfMsg("subcategories")."</h2>\n" ;
$r .= implode ( ", " , $children ) ;
}
# Showing pages in this category
- if ( count ( $articles ) > 0 )
- {
+ if ( count ( $articles ) > 0 ) {
$ti = $this->mTitle->getText() ;
- asort ( $articles ) ;
$h = wfMsg( "category_header", $ti );
$r .= "<h2>{$h}</h2>\n" ;
$r .= implode ( ", " , $articles ) ;
return $t ;
}
- function internalParse( $text, $linestart, $args = array() )
+ function internalParse( $text, $linestart, $args = array(), $isMain=true )
{
$fname = "Parser::internalParse";
wfProfileIn( $fname );
$text = $this->replaceExternalLinks( $text );
$text = $this->doTokenizedParser ( $text );
$text = $this->doTableStuff ( $text ) ;
- $text = $this->formatHeadings( $text );
+ $text = $this->formatHeadings( $text, $isMain );
$sk =& $this->mOptions->getSkin();
$text = $sk->transformContent( $text );
if ( !isset ( $this->categoryMagicDone ) ) {
- $text .= $this->categoryMagic () ;
- $this->categoryMagicDone = true ;
- }
+ $text .= $this->categoryMagic () ;
+ $this->categoryMagicDone = true ;
+ }
wfProfileOut( $fname );
return $text;
return $s;
}
+ /* private */ function handle4Quotes( &$state, $token )
+ {
+ /* This one makes some assumptions.
+ * '''Caesar''''s army => <strong>Caesar</strong>'s army
+ * ''''Caesar'''' was a roman emperor => '<strong>Caesar</strong>' was a roman emperor
+ * These assumptions might be wrong, but any other assumption might be wrong, too.
+ * So here we go */
+ if ( $state["strong"] !== false ) {
+ return $this->handle3Quotes( $state, $token ) . "'";
+ } else {
+ return "'" . $this->handle3Quotes( $state, $token );
+ }
+ }
+
+
/* private */ function handle3Quotes( &$state, $token )
{
if ( $state["strong"] !== false ) {
$state["strong"] = FALSE;
} else {
$s = "<strong>";
- $state["strong"] = isset($token["pos"]) ? $token["pos"] : true;
+ $state["strong"] = $token["pos"];
}
return $s;
}
$state["em"] = FALSE;
} else {
$s = "<em>";
- $state["em"] = isset($token["pos"]) ? $token["pos"] : true;
+ $state["em"] = $token["pos"];
}
return $s;
$state["em"] = $token["pos"];
} else { # not $em and not $strong
$s .= "<strong><em>";
- $state["strong"] = $state["em"] = isset($token["pos"]) ? $token["pos"] : true;
+ $state["strong"] = $state["em"] = $token["pos"];
}
return $s;
}
$txt = "\n<hr />\n";
break;
case "'''":
- # This and the three next ones handle quotes
+ # This and the four next ones handle quotes
$txt = $this->handle3Quotes( $state, $token );
break;
case "''":
case "'''''":
$txt = $this->handle5Quotes( $state, $token );
break;
+ case "''''":
+ $txt = $this->handle4Quotes( $state, $token );
+ break;
case "":
# empty token
$txt="";
break;
+ case "h":
+ #heading- used to close all unbalanced bold or em tags in this section
+ $txt = '';
+ if( $state['em'] !== false and
+ ( $state['strong'] === false or $state['em'] > $state['strong'] ) )
+ {
+ $s .= '</em>';
+ $state['em'] = false;
+ }
+ if ( $state['strong'] !== false ) $txt .= '</strong>';
+ if ( $state['em'] !== false ) $txt .= '</em>';
+ $state['strong'] = $state['em'] = false;
+ break;
case "RFC ":
if ( $tagIsOpen ) {
$txt = "RFC ";
$s .= $txt;
}
} #end while
+
+ # make 100% sure all strong and em tags are closed
+ # doBlockLevels often messes the last bit up though, but invalid nesting is better than unclosed tags
+ # tidy solves this though
+ if( $state['em'] !== false and
+ ( $state['strong'] === false or $state['em'] > $state['strong'] ) )
+ {
+ $s .= '</em>';
+ $state['em'] = false;
+ }
+ if ( $state['strong'] !== false ) $s .= '</strong>';
+ if ( $state['em'] !== false ) $s .= '</em>';
+
if ( count( $tokenStack ) != 0 )
{
# still objects on stack. opened [[ tag without closing ]] tag.
} else {
$link = substr( $m[1], 1 );
}
- if( "" == $text )
+ $wasblank = ( "" == $text );
+ if( $wasblank )
$text = $link;
$nt = Title::newFromText( $link );
if ( $ns == $category ) {
$t = $nt->getText() ;
$nnt = Title::newFromText ( Namespace::getCanonicalName($category).":".$t ) ;
+
+ $wgLinkCache->suspend(); # Don't save in links/brokenlinks
$t = $sk->makeLinkObj( $nnt, $t, "", "" , $prefix );
+ $wgLinkCache->resume();
+
+ $sortkey = $wasblank ? $this->mTitle->getPrefixedText() : $text;
+ $wgLinkCache->addCategoryLinkObj( $nt, $sortkey );
$this->mOutput->mCategoryLinks[] = $t ;
$s .= $prefix . $trail ;
return $s ;
$inBlockElem = true;
}
} else if ( !$inBlockElem ) {
- if ( " " == $t{0} ) {
+ if ( " " == $t{0} and trim($t) != '' ) {
// pre
if ($this->mLastSection != 'pre') {
$paragraphStack = false;
# Run full parser on the included text
$text = $this->strip( $text, $this->mStripState );
- $text = $this->internalParse( $text, (bool)$newline, $assocArgs );
+ $text = $this->internalParse( $text, (bool)$newline, $assocArgs, false );
+ if(!empty($newline)) $text = "\n".$text;
# Add the result to the strip state for re-inclusion after
# the rest of the processing
# Cleans up HTML, removes dangerous tags and attributes
/* private */ function removeHTMLtags( $text )
{
- global $wgUseTidy;
+ global $wgUseTidy, $wgUserHtml;
$fname = "Parser::removeHTMLtags";
wfProfileIn( $fname );
- $htmlpairs = array( # Tags that must be closed
- "b", "del", "i", "ins", "u", "font", "big", "small", "sub", "sup", "h1",
- "h2", "h3", "h4", "h5", "h6", "cite", "code", "em", "s",
- "strike", "strong", "tt", "var", "div", "center",
- "blockquote", "ol", "ul", "dl", "table", "caption", "pre",
- "ruby", "rt" , "rb" , "rp", "p"
- );
- $htmlsingle = array(
- "br", "hr", "li", "dt", "dd"
- );
- $htmlnest = array( # Tags that can be nested--??
- "table", "tr", "td", "th", "div", "blockquote", "ol", "ul",
- "dl", "font", "big", "small", "sub", "sup"
- );
- $tabletags = array( # Can only appear inside table
- "td", "th", "tr"
- );
+
+ if( $wgUserHtml ) {
+ $htmlpairs = array( # Tags that must be closed
+ "b", "del", "i", "ins", "u", "font", "big", "small", "sub", "sup", "h1",
+ "h2", "h3", "h4", "h5", "h6", "cite", "code", "em", "s",
+ "strike", "strong", "tt", "var", "div", "center",
+ "blockquote", "ol", "ul", "dl", "table", "caption", "pre",
+ "ruby", "rt" , "rb" , "rp", "p"
+ );
+ $htmlsingle = array(
+ "br", "hr", "li", "dt", "dd"
+ );
+ $htmlnest = array( # Tags that can be nested--??
+ "table", "tr", "td", "th", "div", "blockquote", "ol", "ul",
+ "dl", "font", "big", "small", "sub", "sup"
+ );
+ $tabletags = array( # Can only appear inside table
+ "td", "th", "tr"
+ );
+ } else {
+ $htmlpairs = array();
+ $htmlsingle = array();
+ $htmlnest = array();
+ $tabletags = array();
+ }
$htmlsingle = array_merge( $tabletags, $htmlsingle );
$htmlelements = array_merge( $htmlsingle, $htmlpairs );
*
*/
- /* private */ function formatHeadings( $text )
+ /* private */ function formatHeadings( $text, $isMain=true )
{
+ global $wgInputEncoding;
+
$doNumberHeadings = $this->mOptions->getNumberHeadings();
$doShowToc = $this->mOptions->getShowToc();
if( !$this->mTitle->userCanEdit() ) {
# strip out HTML
$canonized_headline = preg_replace( "/<.*?" . ">/","",$canonized_headline );
$tocline = trim( $canonized_headline );
- $canonized_headline = preg_replace("/[ \\?&\\/<>\\(\\)\\[\\]=,+']+/", '_', html_entity_decode( $tocline));
+ $canonized_headline = preg_replace("/[ \\?&\\/<>\\(\\)\\[\\]=,+']+/", '_', urlencode( do_html_entity_decode( $tocline, ENT_COMPAT, $wgInputEncoding ) ) );
+ # strip out urlencoded (inserted for french spaces, e.g. first space in 'something : something')
+ $canonized_headline = str_replace('%C2%A0','_', $canonized_headline);
$refer[$headlineCount] = $canonized_headline;
# count how many in assoc. array so we can track dupes in anchors
# $full .= $sk->editSectionLink(0);
}
$full .= $block;
- if( $doShowToc && !$i) {
+ if( $doShowToc && !$i && $isMain) {
# Top anchor now in skin
$full = $full.$toc;
}