/**
	 * This method will be called before an article is displayed or previewed.
	 * For display and preview we strip out the semantic properties and append them
	 * at the end of the article.
	 *
	 * @param Parser $parser
	 * @param string $text
	 */
	static public function onInternalParseBeforeLinks( &$parser, &$text ) {
		global $smwgStoreAnnotations, $smwgLinksInValues;

		SMWParseData::stripMagicWords( $text, $parser );

		// Store the results if enabled (we have to parse them in any case,
		// in order to clean the wiki source for further processing).
		$smwgStoreAnnotations = smwfIsSemanticsProcessed( $parser->getTitle()->getNamespace() );
		SMWParserExtensions::$mTempStoreAnnotations = true; // used for [[SMW::on]] and [[SMW:off]]

		// Process redirects, if any (it seems that there is indeed no more direct way of getting this info from MW)
		if ( $smwgStoreAnnotations ) {
			$rt = Title::newFromRedirect( $text );
			
			if ( !is_null( $rt ) ) {
				$p = new SMWDIProperty( '_REDI' );
				$di = SMWDIWikiPage::newFromTitle( $rt, '__red' );
				SMWParseData::getSMWData( $parser )->addPropertyObjectValue( $p, $di );
			}
		}

		// only used in subsequent callbacks, forgotten afterwards
		SMWParserExtensions::$mTempParser = $parser;

		// In the regexp matches below, leading ':' escapes the markup, as known for Categories.
		// Parse links to extract semantic properties.
		if ( $smwgLinksInValues ) { // More complex regexp -- lib PCRE may cause segfaults if text is long :-(
			$semanticLinkPattern = '/\[\[                 # Beginning of the link
			                        (?:([^:][^]]*):[=:])+ # Property name (or a list of those)
			                        (                     # After that:
			                          (?:[^|\[\]]         #   either normal text (without |, [ or ])
			                          |\[\[[^]]*\]\]      #   or a [[link]]
			                          |\[[^]]*\]          #   or an [external link]
			                        )*)                   # all this zero or more times
			                        (?:\|([^]]*))?        # Display text (like "text" in [[link|text]]), optional
			                        \]\]                  # End of link
			                        /xu';
			$text = preg_replace_callback( $semanticLinkPattern, array( 'SMWParserExtensions', 'parsePropertiesCallback' ), $text );
		} else { // Simpler regexps -- no segfaults found for those, but no links in values.
			$semanticLinkPattern = '/\[\[                 # Beginning of the link
			                        (?:([^:][^]]*):[=:])+ # Property name (or a list of those)
			                        ([^\[\]]*)            # content: anything but [, |, ]
			                        \]\]                  # End of link
			                        /xu';
			$text = preg_replace_callback( $semanticLinkPattern, array( 'SMWParserExtensions', 'simpleParsePropertiesCallback' ), $text );
		}

		// Add link to RDF to HTML header.
		// TODO: do escaping via Html or Xml class.
		SMWOutputs::requireHeadItem(
			'smw_rdf', '<link rel="alternate" type="application/rdf+xml" title="' .
			htmlspecialchars( $parser->getTitle()->getPrefixedText() ) . '" href="' .
			htmlspecialchars(
				SpecialPage::getTitleFor( 'ExportRDF', $parser->getTitle()->getPrefixedText() )->getLocalUrl( 'xmlmime=rdf' )
			) . "\" />"
		);

		SMWOutputs::commitToParser( $parser );
		return true; // always return true, in order not to stop MW's hook processing!
	}