+ /**
+ * Merge a LinkHolderArray from another parser instance into this one. The
+ * keys will not be preserved. Any text which went with the old
+ * LinkHolderArray and needs to work with the new one should be passed in
+ * the $texts array. The strings in this array will have their link holders
+ * converted for use in the destination link holder. The resulting array of
+ * strings will be returned.
+ *
+ * @param $other LinkHolderArray
+ * @param $texts Array of strings
+ * @return Array
+ */
+ function mergeForeign( $other, $texts ) {
+ $this->tempIdOffset = $idOffset = $this->parent->nextLinkID();
+ $maxId = 0;
+
+ # Renumber internal links
+ foreach ( $other->internals as $ns => $nsLinks ) {
+ foreach ( $nsLinks as $key => $entry ) {
+ $newKey = $idOffset + $key;
+ $this->internals[$ns][$newKey] = $entry;
+ $maxId = $newKey > $maxId ? $newKey : $maxId;
+ }
+ }
+ $texts = preg_replace_callback( '/(<!--LINK \d+:)(\d+)(-->)/',
+ array( $this, 'mergeForeignCallback' ), $texts );
+
+ # Renumber interwiki links
+ foreach ( $other->interwikis as $key => $entry ) {
+ $newKey = $idOffset + $key;
+ $this->interwikis[$newKey] = $entry;
+ $maxId = $newKey > $maxId ? $newKey : $maxId;
+ }
+ $texts = preg_replace_callback( '/(<!--IWLINK )(\d+)(-->)/',
+ array( $this, 'mergeForeignCallback' ), $texts );
+
+ # Set the parent link ID to be beyond the highest used ID
+ $this->parent->setLinkID( $maxId + 1 );
+ $this->tempIdOffset = null;
+ return $texts;
+ }
+
+ protected function mergeForeignCallback( $m ) {
+ return $m[1] . ( $m[2] + $this->tempIdOffset ) . $m[3];
+ }
+
+ /**
+ * Get a subset of the current LinkHolderArray which is sufficient to
+ * interpret the given text.
+ */
+ function getSubArray( $text ) {
+ $sub = new LinkHolderArray( $this->parent );
+
+ # Internal links
+ $pos = 0;
+ while ( $pos < strlen( $text ) ) {
+ if ( !preg_match( '/<!--LINK (\d+):(\d+)-->/',
+ $text, $m, PREG_OFFSET_CAPTURE, $pos ) )
+ {
+ break;
+ }
+ $ns = $m[1][0];
+ $key = $m[2][0];
+ $sub->internals[$ns][$key] = $this->internals[$ns][$key];
+ $pos = $m[0][1] + strlen( $m[0][0] );
+ }
+
+ # Interwiki links
+ $pos = 0;
+ while ( $pos < strlen( $text ) ) {
+ if ( !preg_match( '/<!--IWLINK (\d+)-->/', $text, $m, PREG_OFFSET_CAPTURE, $pos ) ) {
+ break;
+ }
+ $key = $m[1][0];
+ $sub->interwikis[$key] = $this->interwikis[$key];
+ $pos = $m[0][1] + strlen( $m[0][0] );
+ }
+ return $sub;
+ }
+