mirror of
https://github.com/gnosygnu/xowa.git
synced 2024-10-27 20:34:16 +00:00
Xomw: Convert XomwLinkHolderArray
This commit is contained in:
parent
7fe4ed59ac
commit
dec8dbc713
@ -50,7 +50,7 @@ public class HashByInt {
|
||||
int len = hash.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
HashByIntItem item = (HashByIntItem)hash.Get_at(i);
|
||||
rv.Add(item.key, item);
|
||||
rv.Add(item.key, item.val);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -17,15 +17,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.mediawiki.includes.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
|
||||
import gplx.langs.htmls.*;
|
||||
import gplx.xowa.mediawiki.includes.htmls.*;
|
||||
import gplx.xowa.mediawiki.includes.linkers.*;
|
||||
/**
|
||||
* Holder of replacement pairs for wiki links
|
||||
*/
|
||||
public class XomwLinkHolderArray {
|
||||
private final Bry_bfr tmp = Bry_bfr_.New();
|
||||
private final Xomw_link_holder_list internals = new Xomw_link_holder_list();
|
||||
private final XomwLinkHolderList internals = new XomwLinkHolderList();
|
||||
// public $interwikis = [];
|
||||
// public $size = 0;
|
||||
//
|
||||
// private int size = 0;
|
||||
|
||||
private final Bry_bfr tmp = Bry_bfr_.New();
|
||||
private final Xomw_atr_mgr extraAtrs = new Xomw_atr_mgr();
|
||||
private final Xomw_qry_mgr query = new Xomw_qry_mgr();
|
||||
/**
|
||||
* @var Parser
|
||||
*/
|
||||
@ -39,25 +43,25 @@ public class XomwLinkHolderArray {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Reduce memory usage to reduce the impact of circular references
|
||||
// */
|
||||
/**
|
||||
* Reduce memory usage to reduce the impact of circular references
|
||||
*/
|
||||
// public function __destruct() {
|
||||
// foreach ( $this as $name => $value ) {
|
||||
// unset( $this->$name );
|
||||
// unset( this.$name );
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Don't serialize the parent Object, it is big, and not needed when it is
|
||||
// * a parameter to mergeForeign(), which is the only application of
|
||||
// * serializing at present.
|
||||
// *
|
||||
// * Compact the titles, only serialize the text form.
|
||||
// * @return array
|
||||
// */
|
||||
|
||||
/**
|
||||
* Don't serialize the parent Object, it is big, and not needed when it is
|
||||
* a parameter to mergeForeign(), which is the only application of
|
||||
* serializing at present.
|
||||
*
|
||||
* Compact the titles, only serialize the text form.
|
||||
* @return array
|
||||
*/
|
||||
// public function __sleep() {
|
||||
// foreach ( $this->internals as &$nsLinks ) {
|
||||
// foreach ( this.internals as &$nsLinks ) {
|
||||
// foreach ( $nsLinks as &$entry ) {
|
||||
// unset( $entry['title'] );
|
||||
// }
|
||||
@ -65,19 +69,19 @@ public class XomwLinkHolderArray {
|
||||
// unset( $nsLinks );
|
||||
// unset( $entry );
|
||||
//
|
||||
// foreach ( $this->interwikis as &$entry ) {
|
||||
// foreach ( this.interwikis as &$entry ) {
|
||||
// unset( $entry['title'] );
|
||||
// }
|
||||
// unset( $entry );
|
||||
//
|
||||
// return [ 'internals', 'interwikis', 'size' ];
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Recreate the Title objects
|
||||
// */
|
||||
|
||||
/**
|
||||
* Recreate the Title objects
|
||||
*/
|
||||
// public function __wakeup() {
|
||||
// foreach ( $this->internals as &$nsLinks ) {
|
||||
// foreach ( this.internals as &$nsLinks ) {
|
||||
// foreach ( $nsLinks as &$entry ) {
|
||||
// $entry['title'] = Title::newFromText( $entry['pdbk'] );
|
||||
// }
|
||||
@ -85,26 +89,26 @@ public class XomwLinkHolderArray {
|
||||
// unset( $nsLinks );
|
||||
// unset( $entry );
|
||||
//
|
||||
// foreach ( $this->interwikis as &$entry ) {
|
||||
// foreach ( this.interwikis as &$entry ) {
|
||||
// $entry['title'] = Title::newFromText( $entry['pdbk'] );
|
||||
// }
|
||||
// unset( $entry );
|
||||
// }
|
||||
//
|
||||
|
||||
// /**
|
||||
// * Merge another LinkHolderArray into this one
|
||||
// * @param LinkHolderArray $other
|
||||
// */
|
||||
// public function merge( $other ) {
|
||||
// foreach ( $other->internals as $ns => $entries ) {
|
||||
// $this->size += count( $entries );
|
||||
// if ( !isset( $this->internals[$ns] ) ) {
|
||||
// $this->internals[$ns] = $entries;
|
||||
// this.size += count( $entries );
|
||||
// if ( !isset( this.internals[$ns] ) ) {
|
||||
// this.internals[$ns] = $entries;
|
||||
// } else {
|
||||
// $this->internals[$ns] += $entries;
|
||||
// this.internals[$ns] += $entries;
|
||||
// }
|
||||
// }
|
||||
// $this->interwikis += $other->interwikis;
|
||||
// this.interwikis += $other->interwikis;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
@ -120,14 +124,14 @@ public class XomwLinkHolderArray {
|
||||
// * @return array
|
||||
// */
|
||||
// public function mergeForeign( $other, $texts ) {
|
||||
// $this->tempIdOffset = $idOffset = $this->parent->nextLinkID();
|
||||
// this.tempIdOffset = $idOffset = this.parent->nextLinkID();
|
||||
// $maxId = 0;
|
||||
//
|
||||
// # Renumber @gplx.Internal protected links
|
||||
// foreach ( $other->internals as $ns => $nsLinks ) {
|
||||
// foreach ( $nsLinks as $key => $entry ) {
|
||||
// $newKey = $idOffset + $key;
|
||||
// $this->internals[$ns][$newKey] = $entry;
|
||||
// this.internals[$ns][$newKey] = $entry;
|
||||
// $maxId = $newKey > $maxId ? $newKey : $maxId;
|
||||
// }
|
||||
// }
|
||||
@ -137,15 +141,15 @@ public class XomwLinkHolderArray {
|
||||
// # Renumber interwiki links
|
||||
// foreach ( $other->interwikis as $key => $entry ) {
|
||||
// $newKey = $idOffset + $key;
|
||||
// $this->interwikis[$newKey] = $entry;
|
||||
// this.interwikis[$newKey] = $entry;
|
||||
// $maxId = $newKey > $maxId ? $newKey : $maxId;
|
||||
// }
|
||||
// $texts = preg_replace_callback( '/(<!--IWLINK )(\d+)(-->)/',
|
||||
// [ $this, 'mergeForeignCallback' ], $texts );
|
||||
//
|
||||
// # Set the parent link ID to be beyond the highest used ID
|
||||
// $this->parent->setLinkID( $maxId + 1 );
|
||||
// $this->tempIdOffset = null;
|
||||
// this.parent->setLinkID( $maxId + 1 );
|
||||
// this.tempIdOffset = null;
|
||||
// return $texts;
|
||||
// }
|
||||
//
|
||||
@ -154,7 +158,7 @@ public class XomwLinkHolderArray {
|
||||
// * @return String
|
||||
// */
|
||||
// protected function mergeForeignCallback( $m ) {
|
||||
// return $m[1] . ( $m[2] + $this->tempIdOffset ) . $m[3];
|
||||
// return $m[1] . ( $m[2] + this.tempIdOffset ) . $m[3];
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
@ -164,7 +168,7 @@ public class XomwLinkHolderArray {
|
||||
// * @return LinkHolderArray
|
||||
// */
|
||||
// public function getSubArray( $text ) {
|
||||
// $sub = new LinkHolderArray( $this->parent );
|
||||
// $sub = new LinkHolderArray( this.parent );
|
||||
//
|
||||
// # Internal links
|
||||
// $pos = 0;
|
||||
@ -176,7 +180,7 @@ public class XomwLinkHolderArray {
|
||||
// }
|
||||
// $ns = $m[1][0];
|
||||
// $key = $m[2][0];
|
||||
// $sub->internals[$ns][$key] = $this->internals[$ns][$key];
|
||||
// $sub->internals[$ns][$key] = this.internals[$ns][$key];
|
||||
// $pos = $m[0][1] + strlen( $m[0][0] );
|
||||
// }
|
||||
//
|
||||
@ -187,7 +191,7 @@ public class XomwLinkHolderArray {
|
||||
// break;
|
||||
// }
|
||||
// $key = $m[1][0];
|
||||
// $sub->interwikis[$key] = $this->interwikis[$key];
|
||||
// $sub->interwikis[$key] = this.interwikis[$key];
|
||||
// $pos = $m[0][1] + strlen( $m[0][0] );
|
||||
// }
|
||||
// return $sub;
|
||||
@ -199,19 +203,19 @@ public class XomwLinkHolderArray {
|
||||
// */
|
||||
// public function isBig() {
|
||||
// global $wgLinkHolderBatchSize;
|
||||
// return $this->size > $wgLinkHolderBatchSize;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Clear all stored link holders.
|
||||
// * Make sure you don't have any text left using these link holders, before you call this
|
||||
// */
|
||||
// public function clear() {
|
||||
// $this->internals = [];
|
||||
// $this->interwikis = [];
|
||||
// $this->size = 0;
|
||||
// return this.size > $wgLinkHolderBatchSize;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Clear all stored link holders.
|
||||
* Make sure you don't have any text left using these link holders, before you call this
|
||||
*/
|
||||
public void clear() {
|
||||
this.internals.Clear();//
|
||||
// this.interwikis = [];
|
||||
// this.size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a link placeholder. The text returned can be later resolved to a real link with
|
||||
* replaceLinkHolders(). This is done for two reasons: firstly to avoid further
|
||||
@ -235,15 +239,15 @@ public class XomwLinkHolderArray {
|
||||
// list( $inside, $trail ) = Linker::splitTrail( $trail );
|
||||
byte[] inside = Bry_.Empty;
|
||||
|
||||
Xomw_link_holder_item entry = new Xomw_link_holder_item
|
||||
XomwLinkHolderItem entry = new XomwLinkHolderItem
|
||||
( nt
|
||||
, tmp.Add_bry_many(prefix, text, inside).To_bry_and_clear()
|
||||
, query);
|
||||
|
||||
if (nt.isExternal()) {
|
||||
// Use a globally unique ID to keep the objects mergable
|
||||
// $key = $this->parent->nextLinkID();
|
||||
// $this->interwikis[$key] = $entry;
|
||||
// $key = this.parent->nextLinkID();
|
||||
// this.interwikis[$key] = $entry;
|
||||
// $retVal = "<!--IWLINK $key-->{$trail}";
|
||||
}
|
||||
else {
|
||||
@ -253,37 +257,38 @@ public class XomwLinkHolderArray {
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * Replace <!--LINK--> link placeholders with actual links, in the buffer
|
||||
// *
|
||||
// * @param String $text
|
||||
// */
|
||||
// public function replace( &$text ) {
|
||||
// $this->replaceInternal( $text );
|
||||
|
||||
/**
|
||||
* Replace <!--LINK--> link placeholders with actual links, in the buffer
|
||||
*
|
||||
* @param String $text
|
||||
*/
|
||||
public void Replace(Xomw_parser_ctx pctx, Xomw_parser_bfr pbfr) {
|
||||
this.replaceInternal(pbfr);
|
||||
// $this->replaceInterwiki( $text );
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Replace @gplx.Internal protected links
|
||||
// * @param String $text
|
||||
// */
|
||||
// protected function replaceInternal( &$text ) {
|
||||
// if ( !$this->internals ) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace @gplx.Internal protected links
|
||||
* @param String $text
|
||||
*/
|
||||
private void replaceInternal(Xomw_parser_bfr pbfr) {
|
||||
if (internals.Len() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// SKIP:Replace_internals does db lookup to identify redlinks;
|
||||
// global $wgContLang;
|
||||
//
|
||||
// $colours = [];
|
||||
// $linkCache = LinkCache::singleton();
|
||||
// $output = $this->parent->getOutput();
|
||||
// $linkRenderer = $this->parent->getLinkRenderer();
|
||||
// $output = this.parent->getOutput();
|
||||
Xomw_link_renderer linkRenderer = this.parent.getLinkRenderer();
|
||||
//
|
||||
// $dbr = wfGetDB( DB_REPLICA );
|
||||
//
|
||||
// # Sort by namespace
|
||||
// ksort( $this->internals );
|
||||
// ksort( this.internals );
|
||||
//
|
||||
// $linkcolour_ids = [];
|
||||
//
|
||||
@ -291,6 +296,378 @@ public class XomwLinkHolderArray {
|
||||
// $lb = new LinkBatch();
|
||||
// $lb->setCaller( __METHOD__ );
|
||||
//
|
||||
// foreach ( this.internals as $ns => $entries ) {
|
||||
// foreach ( $entries as $entry ) {
|
||||
// /** @var Title $title */
|
||||
// $title = $entry['title'];
|
||||
// $pdbk = $entry['pdbk'];
|
||||
//
|
||||
// # Skip invalid entries.
|
||||
// # Result will be ugly, but prevents crash.
|
||||
// if ( is_null( $title ) ) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// # Check if it's a static known link, e.g. interwiki
|
||||
// if ( $title->isAlwaysKnown() ) {
|
||||
// $colours[$pdbk] = '';
|
||||
// } elseif ( $ns == NS_SPECIAL ) {
|
||||
// $colours[$pdbk] = 'new';
|
||||
// } else {
|
||||
// $id = $linkCache->getGoodLinkID( $pdbk );
|
||||
// if ( $id != 0 ) {
|
||||
// $colours[$pdbk] = $linkRenderer->getLinkClasses( $title );
|
||||
// $output->addLink( $title, $id );
|
||||
// $linkcolour_ids[$id] = $pdbk;
|
||||
// } elseif ( $linkCache->isBadLink( $pdbk ) ) {
|
||||
// $colours[$pdbk] = 'new';
|
||||
// } else {
|
||||
// # Not in the link cache, add it to the query
|
||||
// $lb->addObj( $title );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if ( !$lb->isEmpty() ) {
|
||||
// $fields = array_merge(
|
||||
// LinkCache::getSelectFields(),
|
||||
// [ 'page_namespace', 'page_title' ]
|
||||
// );
|
||||
//
|
||||
// $res = $dbr->select(
|
||||
// 'page',
|
||||
// $fields,
|
||||
// $lb->constructSet( 'page', $dbr ),
|
||||
// __METHOD__
|
||||
// );
|
||||
//
|
||||
// # Fetch data and form into an associative array
|
||||
// # non-existent = broken
|
||||
// foreach ( $res as $s ) {
|
||||
// $title = Title::makeTitle( $s->page_namespace, $s->page_title );
|
||||
// $pdbk = $title->getPrefixedDBkey();
|
||||
// $linkCache->addGoodLinkObjFromRow( $title, $s );
|
||||
// $output->addLink( $title, $s->page_id );
|
||||
// $colours[$pdbk] = $linkRenderer->getLinkClasses( $title );
|
||||
// // add id to the extension todolist
|
||||
// $linkcolour_ids[$s->page_id] = $pdbk;
|
||||
// }
|
||||
// unset( $res );
|
||||
// }
|
||||
// if ( count( $linkcolour_ids ) ) {
|
||||
// // pass an array of page_ids to an extension
|
||||
// Hooks::run( 'GetLinkColours', [ $linkcolour_ids, &$colours ] );
|
||||
// }
|
||||
//
|
||||
// # Do a second query for different language variants of links and categories
|
||||
// if ( $wgContLang->hasVariants() ) {
|
||||
// this.doVariants( $colours );
|
||||
// }
|
||||
|
||||
// Construct search and replace arrays
|
||||
Bry_bfr src_bfr = pbfr.Src();
|
||||
byte[] src = src_bfr.Bfr();
|
||||
int src_bgn = 0;
|
||||
int src_end = src_bfr.Len();
|
||||
Bry_bfr bfr = pbfr.Trg();
|
||||
pbfr.Switch();
|
||||
|
||||
int cur = src_bgn;
|
||||
int prv = 0;
|
||||
while (true) {
|
||||
int link_bgn = Bry_find_.Find_fwd(src, Bry__link__bgn, cur, src_end);
|
||||
if (link_bgn == Bry_find_.Not_found) {
|
||||
bfr.Add_mid(src, prv, src_end);
|
||||
break;
|
||||
}
|
||||
int key_bgn = link_bgn + Bry__link__bgn.length;
|
||||
int key_end = Bry_find_.Find_fwd_while_num(src, key_bgn, src_end);
|
||||
int link_key = Bry_.To_int_or(src, key_bgn, key_end, -1);
|
||||
XomwLinkHolderItem item = internals.Get_by(link_key);
|
||||
|
||||
// $pdbk = $entry['pdbk'];
|
||||
// $title = $entry['title'];
|
||||
// $query = isset( $entry['query'] ) ? $entry['query'] : [];
|
||||
// $key = "$ns:$index";
|
||||
// $searchkey = "<!--LINK $key-->";
|
||||
// $displayText = $entry['text'];
|
||||
// if ( isset( $entry['selflink'] ) ) {
|
||||
// $replacePairs[$searchkey] = Linker::makeSelfLinkObj( $title, $displayText, $query );
|
||||
// continue;
|
||||
// }
|
||||
// if ( $displayText === '' ) {
|
||||
// $displayText = null;
|
||||
// } else {
|
||||
// $displayText = new HtmlArmor( $displayText );
|
||||
// }
|
||||
// if ( !isset( $colours[$pdbk] ) ) {
|
||||
// $colours[$pdbk] = 'new';
|
||||
// }
|
||||
// $attribs = [];
|
||||
// if ( $colours[$pdbk] == 'new' ) {
|
||||
// $linkCache->addBadLinkObj( $title );
|
||||
// $output->addLink( $title, 0 );
|
||||
// $link = $linkRenderer->makeBrokenLink(
|
||||
// $title, $displayText, $attribs, $query
|
||||
// );
|
||||
// } else {
|
||||
// $link = $linkRenderer->makePreloadedLink(
|
||||
// $title, $displayText, $colours[$pdbk], $attribs, $query
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// $replacePairs[$searchkey] = $link;
|
||||
// }
|
||||
// }
|
||||
bfr.Add_mid(src, prv, link_bgn);
|
||||
linkRenderer.Make_preloaded_link(bfr, item.Title(), item.Text(), Bry_.Empty, extraAtrs, query.Clear());
|
||||
cur = key_end + Gfh_tag_.Comm_end_len;
|
||||
prv = cur;
|
||||
}
|
||||
// $replacer = new HashtableReplacer( $replacePairs, 1 );
|
||||
//
|
||||
// # Do the thing
|
||||
// $text = preg_replace_callback(
|
||||
// '/(<!--LINK .*?-->)/',
|
||||
// $replacer->cb(),
|
||||
// $text
|
||||
// );
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Replace interwiki links
|
||||
// * @param String $text
|
||||
// */
|
||||
// protected function replaceInterwiki( &$text ) {
|
||||
// if ( empty( this.interwikis ) ) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// # Make interwiki link HTML
|
||||
// $output = this.parent->getOutput();
|
||||
// $replacePairs = [];
|
||||
// $linkRenderer = this.parent->getLinkRenderer();
|
||||
// foreach ( this.interwikis as $key => $link ) {
|
||||
// $replacePairs[$key] = $linkRenderer->makeLink(
|
||||
// $link['title'],
|
||||
// new HtmlArmor( $link['text'] )
|
||||
// );
|
||||
// $output->addInterwikiLink( $link['title'] );
|
||||
// }
|
||||
// $replacer = new HashtableReplacer( $replacePairs, 1 );
|
||||
//
|
||||
// $text = preg_replace_callback(
|
||||
// '/<!--IWLINK (.*?)-->/',
|
||||
// $replacer->cb(),
|
||||
// $text );
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Modify this.internals and $colours according to language variant linking rules
|
||||
// * @param array $colours
|
||||
// */
|
||||
// protected function doVariants( &$colours ) {
|
||||
// global $wgContLang;
|
||||
// $linkBatch = new LinkBatch();
|
||||
// $variantMap = []; // maps $pdbkey_Variant => $keys (of link holders)
|
||||
// $output = this.parent->getOutput();
|
||||
// $linkCache = LinkCache::singleton();
|
||||
// $titlesToBeConverted = '';
|
||||
// $titlesAttrs = [];
|
||||
//
|
||||
// // Concatenate titles to a single String, thus we only need auto convert the
|
||||
// // single String to all variants. This would improve parser's performance
|
||||
// // significantly.
|
||||
// foreach ( this.internals as $ns => $entries ) {
|
||||
// if ( $ns == NS_SPECIAL ) {
|
||||
// continue;
|
||||
// }
|
||||
// foreach ( $entries as $index => $entry ) {
|
||||
// $pdbk = $entry['pdbk'];
|
||||
// // we only deal with new links (in its first query)
|
||||
// if ( !isset( $colours[$pdbk] ) || $colours[$pdbk] === 'new' ) {
|
||||
// $titlesAttrs[] = [ $index, $entry['title'] ];
|
||||
// // separate titles with \0 because it would never appears
|
||||
// // in a valid title
|
||||
// $titlesToBeConverted .= $entry['title']->getText() . "\0";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Now do the conversion and explode String to text of titles
|
||||
// $titlesAllVariants = $wgContLang->autoConvertToAllVariants( rtrim( $titlesToBeConverted, "\0" ) );
|
||||
// $allVariantsName = array_keys( $titlesAllVariants );
|
||||
// foreach ( $titlesAllVariants as &$titlesVariant ) {
|
||||
// $titlesVariant = explode( "\0", $titlesVariant );
|
||||
// }
|
||||
//
|
||||
// // Then add variants of links to link batch
|
||||
// $parentTitle = this.parent->getTitle();
|
||||
// foreach ( $titlesAttrs as $i => $attrs ) {
|
||||
// /** @var Title $title */
|
||||
// list( $index, $title ) = $attrs;
|
||||
// $ns = $title->getNamespace();
|
||||
// $text = $title->getText();
|
||||
//
|
||||
// foreach ( $allVariantsName as $variantName ) {
|
||||
// $textVariant = $titlesAllVariants[$variantName][$i];
|
||||
// if ( $textVariant === $text ) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// $variantTitle = Title::makeTitle( $ns, $textVariant );
|
||||
//
|
||||
// // Self-link checking for mixed/different variant titles. At this point, we
|
||||
// // already know the exact title does not exist, so the link cannot be to a
|
||||
// // variant of the current title that exists as a separate page.
|
||||
// if ( $variantTitle->equals( $parentTitle ) && !$title->hasFragment() ) {
|
||||
// this.internals[$ns][$index]['selflink'] = true;
|
||||
// continue 2;
|
||||
// }
|
||||
//
|
||||
// $linkBatch->addObj( $variantTitle );
|
||||
// $variantMap[$variantTitle->getPrefixedDBkey()][] = "$ns:$index";
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // process categories, check if a category exists in some variant
|
||||
// $categoryMap = []; // maps $category_variant => $category (dbkeys)
|
||||
// $varCategories = []; // category replacements oldDBkey => newDBkey
|
||||
// foreach ( $output->getCategoryLinks() as $category ) {
|
||||
// $categoryTitle = Title::makeTitleSafe( NS_CATEGORY, $category );
|
||||
// $linkBatch->addObj( $categoryTitle );
|
||||
// $variants = $wgContLang->autoConvertToAllVariants( $category );
|
||||
// foreach ( $variants as $variant ) {
|
||||
// if ( $variant !== $category ) {
|
||||
// $variantTitle = Title::makeTitleSafe( NS_CATEGORY, $variant );
|
||||
// if ( is_null( $variantTitle ) ) {
|
||||
// continue;
|
||||
// }
|
||||
// $linkBatch->addObj( $variantTitle );
|
||||
// $categoryMap[$variant] = [ $category, $categoryTitle ];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if ( !$linkBatch->isEmpty() ) {
|
||||
// // construct query
|
||||
// $dbr = wfGetDB( DB_REPLICA );
|
||||
// $fields = array_merge(
|
||||
// LinkCache::getSelectFields(),
|
||||
// [ 'page_namespace', 'page_title' ]
|
||||
// );
|
||||
//
|
||||
// $varRes = $dbr->select( 'page',
|
||||
// $fields,
|
||||
// $linkBatch->constructSet( 'page', $dbr ),
|
||||
// __METHOD__
|
||||
// );
|
||||
//
|
||||
// $linkcolour_ids = [];
|
||||
// $linkRenderer = this.parent->getLinkRenderer();
|
||||
//
|
||||
// // for each found variants, figure out link holders and replace
|
||||
// foreach ( $varRes as $s ) {
|
||||
// $variantTitle = Title::makeTitle( $s->page_namespace, $s->page_title );
|
||||
// $varPdbk = $variantTitle->getPrefixedDBkey();
|
||||
// $vardbk = $variantTitle->getDBkey();
|
||||
//
|
||||
// $holderKeys = [];
|
||||
// if ( isset( $variantMap[$varPdbk] ) ) {
|
||||
// $holderKeys = $variantMap[$varPdbk];
|
||||
// $linkCache->addGoodLinkObjFromRow( $variantTitle, $s );
|
||||
// $output->addLink( $variantTitle, $s->page_id );
|
||||
// }
|
||||
//
|
||||
// // loop over link holders
|
||||
// foreach ( $holderKeys as $key ) {
|
||||
// list( $ns, $index ) = explode( ':', $key, 2 );
|
||||
// $entry =& this.internals[$ns][$index];
|
||||
// $pdbk = $entry['pdbk'];
|
||||
//
|
||||
// if ( !isset( $colours[$pdbk] ) || $colours[$pdbk] === 'new' ) {
|
||||
// // found link in some of the variants, replace the link holder data
|
||||
// $entry['title'] = $variantTitle;
|
||||
// $entry['pdbk'] = $varPdbk;
|
||||
//
|
||||
// // set pdbk and colour
|
||||
// $colours[$varPdbk] = $linkRenderer->getLinkClasses( $variantTitle );
|
||||
// $linkcolour_ids[$s->page_id] = $pdbk;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // check if the Object is a variant of a category
|
||||
// if ( isset( $categoryMap[$vardbk] ) ) {
|
||||
// list( $oldkey, $oldtitle ) = $categoryMap[$vardbk];
|
||||
// if ( !isset( $varCategories[$oldkey] ) && !$oldtitle->exists() ) {
|
||||
// $varCategories[$oldkey] = $vardbk;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Hooks::run( 'GetLinkColours', [ $linkcolour_ids, &$colours ] );
|
||||
//
|
||||
// // rebuild the categories in original order (if there are replacements)
|
||||
// if ( count( $varCategories ) > 0 ) {
|
||||
// $newCats = [];
|
||||
// $originalCats = $output->getCategories();
|
||||
// foreach ( $originalCats as $cat => $sortkey ) {
|
||||
// // make the replacement
|
||||
// if ( array_key_exists( $cat, $varCategories ) ) {
|
||||
// $newCats[$varCategories[$cat]] = $sortkey;
|
||||
// } else {
|
||||
// $newCats[$cat] = $sortkey;
|
||||
// }
|
||||
// }
|
||||
// $output->setCategoryLinks( $newCats );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Replace <!--LINK--> link placeholders with plain text of links
|
||||
// * (not HTML-formatted).
|
||||
// *
|
||||
// * @param String $text
|
||||
// * @return String
|
||||
// */
|
||||
// public function replaceText( $text ) {
|
||||
// $text = preg_replace_callback(
|
||||
// '/<!--(LINK|IWLINK) (.*?)-->/',
|
||||
// [ &$this, 'replaceTextCallback' ],
|
||||
// $text );
|
||||
//
|
||||
// return $text;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Callback for replaceText()
|
||||
// *
|
||||
// * @param array $matches
|
||||
// * @return String
|
||||
// * @private
|
||||
// */
|
||||
// public function replaceTextCallback( $matches ) {
|
||||
// $type = $matches[1];
|
||||
// $key = $matches[2];
|
||||
// if ( $type == 'LINK' ) {
|
||||
// list( $ns, $index ) = explode( ':', $key, 2 );
|
||||
// if ( isset( this.internals[$ns][$index]['text'] ) ) {
|
||||
// return this.internals[$ns][$index]['text'];
|
||||
// }
|
||||
// } elseif ( $type == 'IWLINK' ) {
|
||||
// if ( isset( this.interwikis[$key]['text'] ) ) {
|
||||
// return this.interwikis[$key]['text'];
|
||||
// }
|
||||
// }
|
||||
// return $matches[0];
|
||||
// }
|
||||
|
||||
|
||||
// private void Replace_internal__db() {
|
||||
// // Generate query
|
||||
// $lb = new LinkBatch();
|
||||
// $lb->setCaller( __METHOD__ );
|
||||
//
|
||||
// foreach ( $this->internals as $ns => $entries ) {
|
||||
// foreach ( $entries as $entry ) {
|
||||
// /** @var Title $title */
|
||||
@ -358,281 +735,42 @@ public class XomwLinkHolderArray {
|
||||
// if ( $wgContLang->hasVariants() ) {
|
||||
// $this->doVariants( $colours );
|
||||
// }
|
||||
//
|
||||
// # Construct search and replace arrays
|
||||
// $replacePairs = [];
|
||||
// foreach ( $this->internals as $ns => $entries ) {
|
||||
// foreach ( $entries as $index => $entry ) {
|
||||
// $pdbk = $entry['pdbk'];
|
||||
// $title = $entry['title'];
|
||||
// $query = isset( $entry['query'] ) ? $entry['query'] : [];
|
||||
// $key = "$ns:$index";
|
||||
// $searchkey = "<!--LINK $key-->";
|
||||
// $displayText = $entry['text'];
|
||||
// if ( isset( $entry['selflink'] ) ) {
|
||||
// $replacePairs[$searchkey] = Linker::makeSelfLinkObj( $title, $displayText, $query );
|
||||
// continue;
|
||||
// }
|
||||
// if ( $displayText === '' ) {
|
||||
// $displayText = null;
|
||||
// } else {
|
||||
// $displayText = new HtmlArmor( $displayText );
|
||||
// }
|
||||
// if ( !isset( $colours[$pdbk] ) ) {
|
||||
// $colours[$pdbk] = 'new';
|
||||
// }
|
||||
// $attribs = [];
|
||||
// if ( $colours[$pdbk] == 'new' ) {
|
||||
// $linkCache->addBadLinkObj( $title );
|
||||
// $output->addLink( $title, 0 );
|
||||
// $link = $linkRenderer->makeBrokenLink(
|
||||
// $title, $displayText, $attribs, $query
|
||||
// );
|
||||
// } else {
|
||||
// $link = $linkRenderer->makePreloadedLink(
|
||||
// $title, $displayText, $colours[$pdbk], $attribs, $query
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// $replacePairs[$searchkey] = $link;
|
||||
// }
|
||||
// }
|
||||
// $replacer = new HashtableReplacer( $replacePairs, 1 );
|
||||
//
|
||||
// # Do the thing
|
||||
// $text = preg_replace_callback(
|
||||
// '/(<!--LINK .*?-->)/',
|
||||
// $replacer->cb(),
|
||||
// $text
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Replace interwiki links
|
||||
// * @param String $text
|
||||
// */
|
||||
// protected function replaceInterwiki( &$text ) {
|
||||
// if ( empty( $this->interwikis ) ) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// # Make interwiki link HTML
|
||||
// $output = $this->parent->getOutput();
|
||||
// $replacePairs = [];
|
||||
// $linkRenderer = $this->parent->getLinkRenderer();
|
||||
// foreach ( $this->interwikis as $key => $link ) {
|
||||
// $replacePairs[$key] = $linkRenderer->makeLink(
|
||||
// $link['title'],
|
||||
// new HtmlArmor( $link['text'] )
|
||||
// );
|
||||
// $output->addInterwikiLink( $link['title'] );
|
||||
// }
|
||||
// $replacer = new HashtableReplacer( $replacePairs, 1 );
|
||||
//
|
||||
// $text = preg_replace_callback(
|
||||
// '/<!--IWLINK (.*?)-->/',
|
||||
// $replacer->cb(),
|
||||
// $text );
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Modify $this->internals and $colours according to language variant linking rules
|
||||
// * @param array $colours
|
||||
// */
|
||||
// protected function doVariants( &$colours ) {
|
||||
// global $wgContLang;
|
||||
// $linkBatch = new LinkBatch();
|
||||
// $variantMap = []; // maps $pdbkey_Variant => $keys (of link holders)
|
||||
// $output = $this->parent->getOutput();
|
||||
// $linkCache = LinkCache::singleton();
|
||||
// $titlesToBeConverted = '';
|
||||
// $titlesAttrs = [];
|
||||
//
|
||||
// // Concatenate titles to a single String, thus we only need auto convert the
|
||||
// // single String to all variants. This would improve parser's performance
|
||||
// // significantly.
|
||||
// foreach ( $this->internals as $ns => $entries ) {
|
||||
// if ( $ns == NS_SPECIAL ) {
|
||||
// continue;
|
||||
// }
|
||||
// foreach ( $entries as $index => $entry ) {
|
||||
// $pdbk = $entry['pdbk'];
|
||||
// // we only deal with new links (in its first query)
|
||||
// if ( !isset( $colours[$pdbk] ) || $colours[$pdbk] === 'new' ) {
|
||||
// $titlesAttrs[] = [ $index, $entry['title'] ];
|
||||
// // separate titles with \0 because it would never appears
|
||||
// // in a valid title
|
||||
// $titlesToBeConverted .= $entry['title']->getText() . "\0";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Now do the conversion and explode String to text of titles
|
||||
// $titlesAllVariants = $wgContLang->autoConvertToAllVariants( rtrim( $titlesToBeConverted, "\0" ) );
|
||||
// $allVariantsName = array_keys( $titlesAllVariants );
|
||||
// foreach ( $titlesAllVariants as &$titlesVariant ) {
|
||||
// $titlesVariant = explode( "\0", $titlesVariant );
|
||||
// }
|
||||
//
|
||||
// // Then add variants of links to link batch
|
||||
// $parentTitle = $this->parent->getTitle();
|
||||
// foreach ( $titlesAttrs as $i => $attrs ) {
|
||||
// /** @var Title $title */
|
||||
// list( $index, $title ) = $attrs;
|
||||
// $ns = $title->getNamespace();
|
||||
// $text = $title->getText();
|
||||
//
|
||||
// foreach ( $allVariantsName as $variantName ) {
|
||||
// $textVariant = $titlesAllVariants[$variantName][$i];
|
||||
// if ( $textVariant === $text ) {
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// $variantTitle = Title::makeTitle( $ns, $textVariant );
|
||||
//
|
||||
// // Self-link checking for mixed/different variant titles. At this point, we
|
||||
// // already know the exact title does not exist, so the link cannot be to a
|
||||
// // variant of the current title that exists as a separate page.
|
||||
// if ( $variantTitle->equals( $parentTitle ) && !$title->hasFragment() ) {
|
||||
// $this->internals[$ns][$index]['selflink'] = true;
|
||||
// continue 2;
|
||||
// }
|
||||
//
|
||||
// $linkBatch->addObj( $variantTitle );
|
||||
// $variantMap[$variantTitle->getPrefixedDBkey()][] = "$ns:$index";
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // process categories, check if a category exists in some variant
|
||||
// $categoryMap = []; // maps $category_variant => $category (dbkeys)
|
||||
// $varCategories = []; // category replacements oldDBkey => newDBkey
|
||||
// foreach ( $output->getCategoryLinks() as $category ) {
|
||||
// $categoryTitle = Title::makeTitleSafe( NS_CATEGORY, $category );
|
||||
// $linkBatch->addObj( $categoryTitle );
|
||||
// $variants = $wgContLang->autoConvertToAllVariants( $category );
|
||||
// foreach ( $variants as $variant ) {
|
||||
// if ( $variant !== $category ) {
|
||||
// $variantTitle = Title::makeTitleSafe( NS_CATEGORY, $variant );
|
||||
// if ( is_null( $variantTitle ) ) {
|
||||
// continue;
|
||||
// }
|
||||
// $linkBatch->addObj( $variantTitle );
|
||||
// $categoryMap[$variant] = [ $category, $categoryTitle ];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if ( !$linkBatch->isEmpty() ) {
|
||||
// // construct query
|
||||
// $dbr = wfGetDB( DB_REPLICA );
|
||||
// $fields = array_merge(
|
||||
// LinkCache::getSelectFields(),
|
||||
// [ 'page_namespace', 'page_title' ]
|
||||
// );
|
||||
//
|
||||
// $varRes = $dbr->select( 'page',
|
||||
// $fields,
|
||||
// $linkBatch->constructSet( 'page', $dbr ),
|
||||
// __METHOD__
|
||||
// );
|
||||
//
|
||||
// $linkcolour_ids = [];
|
||||
// $linkRenderer = $this->parent->getLinkRenderer();
|
||||
//
|
||||
// // for each found variants, figure out link holders and replace
|
||||
// foreach ( $varRes as $s ) {
|
||||
// $variantTitle = Title::makeTitle( $s->page_namespace, $s->page_title );
|
||||
// $varPdbk = $variantTitle->getPrefixedDBkey();
|
||||
// $vardbk = $variantTitle->getDBkey();
|
||||
//
|
||||
// $holderKeys = [];
|
||||
// if ( isset( $variantMap[$varPdbk] ) ) {
|
||||
// $holderKeys = $variantMap[$varPdbk];
|
||||
// $linkCache->addGoodLinkObjFromRow( $variantTitle, $s );
|
||||
// $output->addLink( $variantTitle, $s->page_id );
|
||||
// }
|
||||
//
|
||||
// // loop over link holders
|
||||
// foreach ( $holderKeys as $key ) {
|
||||
// list( $ns, $index ) = explode( ':', $key, 2 );
|
||||
// $entry =& $this->internals[$ns][$index];
|
||||
// $pdbk = $entry['pdbk'];
|
||||
//
|
||||
// if ( !isset( $colours[$pdbk] ) || $colours[$pdbk] === 'new' ) {
|
||||
// // found link in some of the variants, replace the link holder data
|
||||
// $entry['title'] = $variantTitle;
|
||||
// $entry['pdbk'] = $varPdbk;
|
||||
//
|
||||
// // set pdbk and colour
|
||||
// $colours[$varPdbk] = $linkRenderer->getLinkClasses( $variantTitle );
|
||||
// $linkcolour_ids[$s->page_id] = $pdbk;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // check if the Object is a variant of a category
|
||||
// if ( isset( $categoryMap[$vardbk] ) ) {
|
||||
// list( $oldkey, $oldtitle ) = $categoryMap[$vardbk];
|
||||
// if ( !isset( $varCategories[$oldkey] ) && !$oldtitle->exists() ) {
|
||||
// $varCategories[$oldkey] = $vardbk;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// Hooks::run( 'GetLinkColours', [ $linkcolour_ids, &$colours ] );
|
||||
//
|
||||
// // rebuild the categories in original order (if there are replacements)
|
||||
// if ( count( $varCategories ) > 0 ) {
|
||||
// $newCats = [];
|
||||
// $originalCats = $output->getCategories();
|
||||
// foreach ( $originalCats as $cat => $sortkey ) {
|
||||
// // make the replacement
|
||||
// if ( array_key_exists( $cat, $varCategories ) ) {
|
||||
// $newCats[$varCategories[$cat]] = $sortkey;
|
||||
// } else {
|
||||
// $newCats[$cat] = $sortkey;
|
||||
// }
|
||||
// }
|
||||
// $output->setCategoryLinks( $newCats );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Replace <!--LINK--> link placeholders with plain text of links
|
||||
// * (not HTML-formatted).
|
||||
// *
|
||||
// * @param String $text
|
||||
// * @return String
|
||||
// */
|
||||
// public function replaceText( $text ) {
|
||||
// $text = preg_replace_callback(
|
||||
// '/<!--(LINK|IWLINK) (.*?)-->/',
|
||||
// [ &$this, 'replaceTextCallback' ],
|
||||
// $text );
|
||||
//
|
||||
// return $text;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Callback for replaceText()
|
||||
// *
|
||||
// * @param array $matches
|
||||
// * @return String
|
||||
// * @private
|
||||
// */
|
||||
// public function replaceTextCallback( $matches ) {
|
||||
// $type = $matches[1];
|
||||
// $key = $matches[2];
|
||||
// if ( $type == 'LINK' ) {
|
||||
// list( $ns, $index ) = explode( ':', $key, 2 );
|
||||
// if ( isset( $this->internals[$ns][$index]['text'] ) ) {
|
||||
// return $this->internals[$ns][$index]['text'];
|
||||
// }
|
||||
// } elseif ( $type == 'IWLINK' ) {
|
||||
// if ( isset( $this->interwikis[$key]['text'] ) ) {
|
||||
// return $this->interwikis[$key]['text'];
|
||||
// }
|
||||
// }
|
||||
// return $matches[0];
|
||||
// }
|
||||
public void Test__add(XomwTitle ttl, byte[] capt) {
|
||||
int key = parent.nextLinkID();
|
||||
XomwLinkHolderItem item = new XomwLinkHolderItem(ttl, capt, Bry_.Ary_empty);
|
||||
internals.Add(key, item);
|
||||
}
|
||||
private static final byte[] Bry__link__bgn = Bry_.new_a7("<!--LINK ");
|
||||
}
|
||||
class XomwLinkHolderList {
|
||||
private int ary_len = 0, ary_max = 128;
|
||||
private XomwLinkHolderItem[] ary = new XomwLinkHolderItem[128];
|
||||
public int Len() {return ary_len;}
|
||||
public void Clear() {
|
||||
ary_len = 0;
|
||||
if (ary_max > 128)
|
||||
ary = new XomwLinkHolderItem[128];
|
||||
}
|
||||
public void Add(int key, XomwLinkHolderItem item) {
|
||||
if (key >= ary_max) {
|
||||
int new_max = ary_max * 2;
|
||||
ary = (XomwLinkHolderItem[])Array_.Resize(ary, new_max);
|
||||
ary_max = new_max;
|
||||
}
|
||||
ary[key] = item;
|
||||
ary_len++;
|
||||
}
|
||||
public XomwLinkHolderItem Get_by(int key) {return ary[key];}
|
||||
}
|
||||
class XomwLinkHolderItem {
|
||||
public XomwLinkHolderItem(XomwTitle title, byte[] text, byte[][] query) {
|
||||
this.title = title;
|
||||
this.text = text;
|
||||
this.query = query;
|
||||
}
|
||||
public XomwTitle Title() {return title;} private final XomwTitle title;
|
||||
public byte[] Text() {return text;} private final byte[] text;
|
||||
public byte[] Pdbk() {return title.getPrefixedDBkey();}
|
||||
public byte[][] Query() {return query;} private final byte[][] query;
|
||||
}
|
||||
|
@ -15,237 +15,134 @@ GNU Affero General Public License for more details.
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package gplx.xowa.mediawiki.includes.parsers; import gplx.*; import gplx.xowa.*; import gplx.xowa.mediawiki.*; import gplx.xowa.mediawiki.includes.*;
|
||||
import gplx.langs.htmls.*;
|
||||
import gplx.xowa.mediawiki.includes.*;
|
||||
import gplx.xowa.mediawiki.includes.htmls.*;
|
||||
import gplx.xowa.mediawiki.includes.linkers.*;
|
||||
public class Xomw_link_holders {
|
||||
private final Xomw_link_renderer link_renderer;
|
||||
private final Bry_bfr tmp;
|
||||
private int link_id = 0; // MOVED:Parser.php
|
||||
private final Xomw_link_holder_list internals = new Xomw_link_holder_list();
|
||||
private final Xomw_atr_mgr extra_atrs = new Xomw_atr_mgr();
|
||||
private final Xomw_qry_mgr query = new Xomw_qry_mgr();
|
||||
public Xomw_link_holders(Xomw_link_renderer link_renderer, Bry_bfr tmp) {
|
||||
this.link_renderer = link_renderer;
|
||||
this.tmp = tmp;
|
||||
}
|
||||
public void Clear() {
|
||||
internals.Clear();
|
||||
|
||||
link_id = 0;
|
||||
}
|
||||
public void Make_holder(Bry_bfr bfr, XomwTitle nt, byte[] text, byte[][] query, byte[] trail, byte[] prefix) {
|
||||
if (nt == null) {
|
||||
// Fail gracefully
|
||||
bfr.Add_str_a7("<!-- ERROR -->").Add(prefix).Add(text).Add(trail);
|
||||
}
|
||||
else {
|
||||
// Separate the link trail from the rest of the link
|
||||
// list( $inside, $trail ) = Linker::splitTrail( $trail );
|
||||
byte[] inside = Bry_.Empty;
|
||||
|
||||
Xomw_link_holder_item entry = new Xomw_link_holder_item(nt, tmp.Add_bry_many(prefix, text, inside).To_bry_and_clear(), query);
|
||||
|
||||
boolean is_external = false; // $nt->isExternal()
|
||||
if (is_external) {
|
||||
// Use a globally unique ID to keep the objects mergable
|
||||
// $key = $this->parent->nextLinkID();
|
||||
// $this->interwikis[$key] = $entry;
|
||||
// $retVal = "<!--IWLINK $key-->{$trail}";
|
||||
}
|
||||
else {
|
||||
int key = link_id++;
|
||||
internals.Add(key, entry);
|
||||
bfr.Add(Bry__link__bgn).Add_int_variable(key).Add(Gfh_tag_.Comm_end).Add(trail); // "<!--LINK $ns:$key-->{$trail}";
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Test__add(XomwTitle ttl, byte[] capt) {
|
||||
int key = link_id++;
|
||||
Xomw_link_holder_item item = new Xomw_link_holder_item(ttl, capt, Bry_.Ary_empty);
|
||||
internals.Add(key, item);
|
||||
}
|
||||
public void Replace(Xomw_parser_ctx pctx, Xomw_parser_bfr pbfr) {
|
||||
this.Replace_internal(pbfr);
|
||||
// $this->replaceInterwiki( $text );
|
||||
}
|
||||
private void Replace_internal(Xomw_parser_bfr pbfr) {
|
||||
if (internals.Len() == 0)
|
||||
return;
|
||||
|
||||
// $colours = [];
|
||||
// $linkCache = LinkCache::singleton();
|
||||
// $output = $this->parent->getOutput();
|
||||
// $linkRenderer = $this->parent->getLinkRenderer();
|
||||
|
||||
// $linkcolour_ids = [];
|
||||
|
||||
// SKIP:Replace_internals does db lookup to identify redlinks;
|
||||
|
||||
// Construct search and replace arrays
|
||||
Bry_bfr src_bfr = pbfr.Src();
|
||||
byte[] src = src_bfr.Bfr();
|
||||
int src_bgn = 0;
|
||||
int src_end = src_bfr.Len();
|
||||
Bry_bfr bfr = pbfr.Trg();
|
||||
pbfr.Switch();
|
||||
|
||||
int cur = src_bgn;
|
||||
int prv = 0;
|
||||
while (true) {
|
||||
int link_bgn = Bry_find_.Find_fwd(src, Bry__link__bgn, cur, src_end);
|
||||
if (link_bgn == Bry_find_.Not_found) {
|
||||
bfr.Add_mid(src, prv, src_end);
|
||||
break;
|
||||
}
|
||||
int key_bgn = link_bgn + Bry__link__bgn.length;
|
||||
int key_end = Bry_find_.Find_fwd_while_num(src, key_bgn, src_end);
|
||||
int link_key = Bry_.To_int_or(src, key_bgn, key_end, -1);
|
||||
Xomw_link_holder_item item = internals.Get_by(link_key);
|
||||
|
||||
// $pdbk = $entry['pdbk'];
|
||||
// $title = $entry['title'];
|
||||
// $query = isset( $entry['query'] ) ? $entry['query'] : [];
|
||||
// $key = "$ns:$index";
|
||||
// $searchkey = "<!--LINK $key-->";
|
||||
// $displayText = $entry['text'];
|
||||
// if ( isset( $entry['selflink'] ) ) {
|
||||
// $replacePairs[$searchkey] = Linker::makeSelfLinkObj( $title, $displayText, $query );
|
||||
// continue;
|
||||
//namespace gplx.xowa.mediawiki.includes.parsers {
|
||||
// using gplx.langs.htmls;
|
||||
// using gplx.xowa.mediawiki.includes;
|
||||
// using gplx.xowa.mediawiki.includes.htmls;
|
||||
// using gplx.xowa.mediawiki.includes.linkers;
|
||||
// public class Xomw_link_holders {
|
||||
// private final Xomw_link_renderer link_renderer;
|
||||
// private final Bry_bfr tmp;
|
||||
// private int link_id = 0; // MOVED:Parser.php
|
||||
// private final XomwLinkHolderList internals = new XomwLinkHolderList();
|
||||
// private final Xomw_atr_mgr extra_atrs = new Xomw_atr_mgr();
|
||||
// private final Xomw_qry_mgr query = new Xomw_qry_mgr();
|
||||
// public Xomw_link_holders(Xomw_link_renderer link_renderer, Bry_bfr tmp) {
|
||||
// this.link_renderer = link_renderer;
|
||||
// this.tmp = tmp;
|
||||
// }
|
||||
// if ( $displayText === '' ) {
|
||||
// $displayText = null;
|
||||
// } else {
|
||||
// $displayText = new HtmlArmor( $displayText );
|
||||
// }
|
||||
// if ( !isset( $colours[$pdbk] ) ) {
|
||||
// $colours[$pdbk] = 'new';
|
||||
// }
|
||||
// $attribs = [];
|
||||
// if ( $colours[$pdbk] == 'new' ) {
|
||||
// $linkCache->addBadLinkObj( $title );
|
||||
// $output->addLink( $title, 0 );
|
||||
// $link = $linkRenderer->makeBrokenLink(
|
||||
// $title, $displayText, $attribs, $query
|
||||
// );
|
||||
// } else {
|
||||
// $link = $linkRenderer->makePreloadedLink(
|
||||
// $title, $displayText, $colours[$pdbk], $attribs, $query
|
||||
// );
|
||||
// }
|
||||
|
||||
bfr.Add_mid(src, prv, link_bgn);
|
||||
link_renderer.Make_preloaded_link(bfr, item.Title(), item.Text(), Bry_.Empty, extra_atrs, query.Clear());
|
||||
cur = key_end + Gfh_tag_.Comm_end_len;
|
||||
prv = cur;
|
||||
}
|
||||
}
|
||||
// private void Replace_internal__db() {
|
||||
// // Generate query
|
||||
// $lb = new LinkBatch();
|
||||
// $lb->setCaller( __METHOD__ );
|
||||
// public void Clear() {
|
||||
// internals.Clear();
|
||||
//
|
||||
// foreach ( $this->internals as $ns => $entries ) {
|
||||
// foreach ( $entries as $entry ) {
|
||||
// /** @var Title $title */
|
||||
// $title = $entry['title'];
|
||||
// $pdbk = $entry['pdbk'];
|
||||
// link_id = 0;
|
||||
// }
|
||||
// public void Make_holder(Bry_bfr bfr, XomwTitle nt, byte[] text, byte[][] query, byte[] trail, byte[] prefix) {
|
||||
// if (nt == null) {
|
||||
// // Fail gracefully
|
||||
// bfr.Add_str_a7("<!-- ERROR -->").Add(prefix).Add(text).Add(trail);
|
||||
// }
|
||||
// else {
|
||||
// // Separate the link trail from the rest of the link
|
||||
//// list( $inside, $trail ) = Linker::splitTrail( $trail );
|
||||
// byte[] inside = Bry_.Empty;
|
||||
//
|
||||
// # Skip invalid entries.
|
||||
// # Result will be ugly, but prevents crash.
|
||||
// if ( is_null( $title ) ) {
|
||||
// continue;
|
||||
// XomwLinkHolderItem entry = new XomwLinkHolderItem(nt, tmp.Add_bry_many(prefix, text, inside).To_bry_and_clear(), query);
|
||||
//
|
||||
// boolean is_external = false; // $nt->isExternal()
|
||||
// if (is_external) {
|
||||
// // Use a globally unique ID to keep the objects mergable
|
||||
//// $key = $this->parent->nextLinkID();
|
||||
//// $this->interwikis[$key] = $entry;
|
||||
//// $retVal = "<!--IWLINK $key-->{$trail}";
|
||||
// }
|
||||
// else {
|
||||
// int key = link_id++;
|
||||
// internals.Add(key, entry);
|
||||
// bfr.Add(Bry__link__bgn).Add_int_variable(key).Add(Gfh_tag_.Comm_end).Add(trail); // "<!--LINK $ns:$key-->{$trail}";
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// public void Test__add(XomwTitle ttl, byte[] capt) {
|
||||
// int key = link_id++;
|
||||
// XomwLinkHolderItem item = new XomwLinkHolderItem(ttl, capt, Bry_.Ary_empty);
|
||||
// internals.Add(key, item);
|
||||
// }
|
||||
// public void Replace(Xomw_parser_ctx pctx, Xomw_parser_bfr pbfr) {
|
||||
// this.Replace_internal(pbfr);
|
||||
//// $this->replaceInterwiki( $text );
|
||||
// }
|
||||
// private void Replace_internal(Xomw_parser_bfr pbfr) {
|
||||
// if (internals.Len() == 0)
|
||||
// return;
|
||||
//
|
||||
//// $colours = [];
|
||||
//// $linkCache = LinkCache::singleton();
|
||||
//// $output = $this->parent->getOutput();
|
||||
//// $linkRenderer = $this->parent->getLinkRenderer();
|
||||
//
|
||||
//// $linkcolour_ids = [];
|
||||
//
|
||||
// // SKIP:Replace_internals does db lookup to identify redlinks;
|
||||
//
|
||||
// // Construct search and replace arrays
|
||||
// Bry_bfr src_bfr = pbfr.Src();
|
||||
// byte[] src = src_bfr.Bfr();
|
||||
// int src_bgn = 0;
|
||||
// int src_end = src_bfr.Len();
|
||||
// Bry_bfr bfr = pbfr.Trg();
|
||||
// pbfr.Switch();
|
||||
//
|
||||
// int cur = src_bgn;
|
||||
// int prv = 0;
|
||||
// while (true) {
|
||||
// int link_bgn = Bry_find_.Find_fwd(src, Bry__link__bgn, cur, src_end);
|
||||
// if (link_bgn == Bry_find_.Not_found) {
|
||||
// bfr.Add_mid(src, prv, src_end);
|
||||
// break;
|
||||
// }
|
||||
// int key_bgn = link_bgn + Bry__link__bgn.length;
|
||||
// int key_end = Bry_find_.Find_fwd_while_num(src, key_bgn, src_end);
|
||||
// int link_key = Bry_.To_int_or(src, key_bgn, key_end, -1);
|
||||
// XomwLinkHolderItem item = internals.Get_by(link_key);
|
||||
//
|
||||
//// $pdbk = $entry['pdbk'];
|
||||
//// $title = $entry['title'];
|
||||
//// $query = isset( $entry['query'] ) ? $entry['query'] : [];
|
||||
//// $key = "$ns:$index";
|
||||
//// $searchkey = "<!--LINK $key-->";
|
||||
//// $displayText = $entry['text'];
|
||||
//// if ( isset( $entry['selflink'] ) ) {
|
||||
//// $replacePairs[$searchkey] = Linker::makeSelfLinkObj( $title, $displayText, $query );
|
||||
//// continue;
|
||||
//// }
|
||||
//// if ( $displayText === '' ) {
|
||||
//// $displayText = null;
|
||||
//// } else {
|
||||
//// $displayText = new HtmlArmor( $displayText );
|
||||
//// }
|
||||
//// if ( !isset( $colours[$pdbk] ) ) {
|
||||
//// $colours[$pdbk] = 'new';
|
||||
//// }
|
||||
//// $attribs = [];
|
||||
//// if ( $colours[$pdbk] == 'new' ) {
|
||||
//// $linkCache->addBadLinkObj( $title );
|
||||
//// $output->addLink( $title, 0 );
|
||||
//// $link = $linkRenderer->makeBrokenLink(
|
||||
//// $title, $displayText, $attribs, $query
|
||||
//// );
|
||||
//// } else {
|
||||
//// $link = $linkRenderer->makePreloadedLink(
|
||||
//// $title, $displayText, $colours[$pdbk], $attribs, $query
|
||||
//// );
|
||||
//// }
|
||||
//
|
||||
// bfr.Add_mid(src, prv, link_bgn);
|
||||
// link_renderer.Make_preloaded_link(bfr, item.Title(), item.Text(), Bry_.Empty, extra_atrs, query.Clear());
|
||||
// cur = key_end + Gfh_tag_.Comm_end_len;
|
||||
// prv = cur;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// # Check if it's a static known link, e.g. interwiki
|
||||
// if ( $title->isAlwaysKnown() ) {
|
||||
// $colours[$pdbk] = '';
|
||||
// } elseif ( $ns == NS_SPECIAL ) {
|
||||
// $colours[$pdbk] = 'new';
|
||||
// } else {
|
||||
// $id = $linkCache->getGoodLinkID( $pdbk );
|
||||
// if ( $id != 0 ) {
|
||||
// $colours[$pdbk] = $linkRenderer->getLinkClasses( $title );
|
||||
// $output->addLink( $title, $id );
|
||||
// $linkcolour_ids[$id] = $pdbk;
|
||||
// } elseif ( $linkCache->isBadLink( $pdbk ) ) {
|
||||
// $colours[$pdbk] = 'new';
|
||||
// } else {
|
||||
// # Not in the link cache, add it to the query
|
||||
// $lb->addObj( $title );
|
||||
// private static final byte[] Bry__link__bgn = Bry_.new_a7("<!--LINK ");
|
||||
// }
|
||||
//}
|
||||
// }
|
||||
// }
|
||||
// if ( !$lb->isEmpty() ) {
|
||||
// $fields = array_merge(
|
||||
// LinkCache::getSelectFields(),
|
||||
// [ 'page_namespace', 'page_title' ]
|
||||
// );
|
||||
//
|
||||
// $res = $dbr->select(
|
||||
// 'page',
|
||||
// $fields,
|
||||
// $lb->constructSet( 'page', $dbr ),
|
||||
// __METHOD__
|
||||
// );
|
||||
//
|
||||
// # Fetch data and form into an associative array
|
||||
// # non-existent = broken
|
||||
// foreach ( $res as $s ) {
|
||||
// $title = Title::makeTitle( $s->page_namespace, $s->page_title );
|
||||
// $pdbk = $title->getPrefixedDBkey();
|
||||
// $linkCache->addGoodLinkObjFromRow( $title, $s );
|
||||
// $output->addLink( $title, $s->page_id );
|
||||
// $colours[$pdbk] = $linkRenderer->getLinkClasses( $title );
|
||||
// // add id to the extension todolist
|
||||
// $linkcolour_ids[$s->page_id] = $pdbk;
|
||||
// }
|
||||
// unset( $res );
|
||||
// }
|
||||
// if ( count( $linkcolour_ids ) ) {
|
||||
// // pass an array of page_ids to an extension
|
||||
// Hooks::run( 'GetLinkColours', [ $linkcolour_ids, &$colours ] );
|
||||
// }
|
||||
//
|
||||
// # Do a second query for different language variants of links and categories
|
||||
// if ( $wgContLang->hasVariants() ) {
|
||||
// $this->doVariants( $colours );
|
||||
// }
|
||||
// }
|
||||
|
||||
private static final byte[] Bry__link__bgn = Bry_.new_a7("<!--LINK ");
|
||||
}
|
||||
class Xomw_link_holder_list {
|
||||
private int ary_len = 0, ary_max = 128;
|
||||
private Xomw_link_holder_item[] ary = new Xomw_link_holder_item[128];
|
||||
public int Len() {return ary_len;}
|
||||
public void Clear() {
|
||||
ary_len = 0;
|
||||
if (ary_max > 128)
|
||||
ary = new Xomw_link_holder_item[128];
|
||||
}
|
||||
public void Add(int key, Xomw_link_holder_item item) {
|
||||
if (key >= ary_max) {
|
||||
int new_max = ary_max * 2;
|
||||
ary = (Xomw_link_holder_item[])Array_.Resize(ary, new_max);
|
||||
ary_max = new_max;
|
||||
}
|
||||
ary[key] = item;
|
||||
ary_len++;
|
||||
}
|
||||
public Xomw_link_holder_item Get_by(int key) {return ary[key];}
|
||||
}
|
||||
class Xomw_link_holder_item {
|
||||
public Xomw_link_holder_item(XomwTitle title, byte[] text, byte[][] query) {
|
||||
this.title = title;
|
||||
this.text = text;
|
||||
this.query = query;
|
||||
}
|
||||
public XomwTitle Title() {return title;} private final XomwTitle title;
|
||||
public byte[] Text() {return text;} private final byte[] text;
|
||||
public byte[] Pdbk() {return title.getPrefixedDBkey();}
|
||||
public byte[][] Query() {return query;} private final byte[][] query;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class Xomw_link_holders__tst {
|
||||
}
|
||||
}
|
||||
class Xomw_link_holders__fxt {
|
||||
private final Xomw_link_holders holders = new Xomw_link_holders(new Xomw_link_renderer(new XomwSanitizer()), Bry_bfr_.New());
|
||||
private final XomwLinkHolderArray holders = new XomwLinkHolderArray(new Xomw_parser());
|
||||
private final Xomw_parser_bfr pbfr = new Xomw_parser_bfr();
|
||||
private boolean apos = true;
|
||||
public Xomw_link_holders__fxt() {
|
||||
|
@ -33,7 +33,7 @@ public class Xomw_parser {
|
||||
private final Xomw_magiclinks_wkr magiclinks_wkr;
|
||||
private final Xomw_doubleunder_wkr doubleunder_wkr = new Xomw_doubleunder_wkr();
|
||||
private final Xomw_link_renderer link_renderer;
|
||||
private final Xomw_link_holders holders;
|
||||
private final XomwLinkHolderArray holders;
|
||||
private final Xomw_heading_cbk__html heading_wkr_cbk;
|
||||
private final Btrie_slim_mgr protocols_trie;
|
||||
private final Xomw_doubleunder_data doubleunder_data = new Xomw_doubleunder_data();
|
||||
@ -63,6 +63,23 @@ public class Xomw_parser {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a LinkRenderer instance to make links with
|
||||
*
|
||||
* @since 1.28
|
||||
* @return LinkRenderer
|
||||
*/
|
||||
public Xomw_link_renderer getLinkRenderer() {
|
||||
// if ( !$this->mLinkRenderer ) {
|
||||
// $this->mLinkRenderer = MediaWikiServices::getInstance()
|
||||
// ->getLinkRendererFactory()->create();
|
||||
// $this->mLinkRenderer->setStubThreshold(
|
||||
// $this->getOptions()->getStubThreshold()
|
||||
// );
|
||||
// }
|
||||
return link_renderer;
|
||||
}
|
||||
|
||||
public Xomw_parser() {
|
||||
if (regex_space == null) {
|
||||
synchronized (Type_adp_.ClassOf_obj(this)) {
|
||||
@ -77,7 +94,7 @@ public class Xomw_parser {
|
||||
this.link_renderer = new Xomw_link_renderer(sanitizer);
|
||||
this.linker = new XomwLinker(link_renderer);
|
||||
this.protocols_trie = Xomw_parser.Protocols__dflt();
|
||||
this.holders = new Xomw_link_holders(link_renderer, tmp);
|
||||
this.holders = new XomwLinkHolderArray(this);
|
||||
this.table_wkr = new Xomw_table_wkr(this);
|
||||
this.quote_wkr = new Xomw_quote_wkr(this);
|
||||
this.lnke_wkr = new Xomw_lnke_wkr(this);
|
||||
|
@ -37,7 +37,7 @@ import gplx.xowa.parsers.uniqs.*;
|
||||
* P1: link_prefix; EX: b[[A]]; [not enabled on enwiki]
|
||||
*/
|
||||
public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
|
||||
private final Xomw_link_holders holders;
|
||||
private final XomwLinkHolderArray holders;
|
||||
private final XomwLinker linker;
|
||||
private final Xomw_link_renderer link_renderer;
|
||||
// private final Btrie_slim_mgr protocols_trie;
|
||||
@ -55,7 +55,7 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
|
||||
private final List_adp tmp_list = List_adp_.New();
|
||||
private final Hash_adp mImageParams = Hash_adp_bry.cs();
|
||||
private final Hash_adp mImageParamsMagicArray = Hash_adp_bry.cs();
|
||||
public Xomw_lnki_wkr(Xomw_parser parser, Xomw_link_holders holders, Xomw_link_renderer link_renderer, Btrie_slim_mgr protocols_trie) {
|
||||
public Xomw_lnki_wkr(Xomw_parser parser, XomwLinkHolderArray holders, Xomw_link_renderer link_renderer, Btrie_slim_mgr protocols_trie) {
|
||||
this.parser = parser;
|
||||
this.holders = holders;
|
||||
this.link_renderer = link_renderer;
|
||||
@ -77,7 +77,7 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
|
||||
}
|
||||
}
|
||||
public void Clear_state() {
|
||||
holders.Clear();
|
||||
holders.clear();
|
||||
}
|
||||
public void Replace_internal_links(Xomw_parser_ctx pctx, Xomw_parser_bfr pbfr) {
|
||||
// XO.PBFR
|
||||
@ -440,11 +440,11 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
|
||||
}
|
||||
else {
|
||||
// Links will be added to the output link list after checking
|
||||
holders.Make_holder(bfr, nt, text, Bry_.Ary_empty, trail, prefix);
|
||||
holders.makeHolder(bfr, nt, text, Bry_.Ary_empty, trail, prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void makeImage(Xomw_parser_ctx pctx, Bry_bfr bfr, XomwTitle title, byte[] options_at_link, Xomw_link_holders holders) {
|
||||
public void makeImage(Xomw_parser_ctx pctx, Bry_bfr bfr, XomwTitle title, byte[] options_at_link, XomwLinkHolderArray holders) {
|
||||
// Check if the options text is of the form "options|alt text"
|
||||
// Options are:
|
||||
// * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
|
||||
|
Loading…
Reference in New Issue
Block a user