2012-03-01 12:47:05 +00:00
|
|
|
var title = require('./mediawiki.Title.js'),
|
|
|
|
Title = title.Title,
|
|
|
|
Namespace = title.Namespace;
|
|
|
|
|
2011-11-02 21:07:51 +00:00
|
|
|
var MWParserEnvironment = function(opts) {
|
|
|
|
var options = {
|
|
|
|
tagHooks: {},
|
|
|
|
parserFunctions: {},
|
|
|
|
pageCache: {}, // @fixme use something with managed space
|
2012-01-18 19:38:32 +00:00
|
|
|
debug: false,
|
2012-01-31 16:50:16 +00:00
|
|
|
trace: false,
|
2012-01-18 19:38:32 +00:00
|
|
|
wgScriptPath: "http://en.wikipedia.org/w",
|
|
|
|
wgScriptExtension: ".php",
|
2012-01-22 19:32:28 +00:00
|
|
|
fetchTemplates: false,
|
|
|
|
maxDepth: 40
|
2011-11-02 21:07:51 +00:00
|
|
|
};
|
2012-03-01 12:47:05 +00:00
|
|
|
// XXX: this should be namespaced
|
2011-11-02 21:07:51 +00:00
|
|
|
$.extend(options, opts);
|
2012-01-18 19:38:32 +00:00
|
|
|
$.extend(this, options);
|
2011-11-02 21:07:51 +00:00
|
|
|
};
|
|
|
|
|
2012-01-20 02:36:18 +00:00
|
|
|
// Outstanding page requests (for templates etc)
|
|
|
|
// Class-static
|
|
|
|
MWParserEnvironment.prototype.requestQueue = {};
|
|
|
|
|
2012-01-10 01:09:50 +00:00
|
|
|
MWParserEnvironment.prototype.lookupKV = function ( kvs, key ) {
|
2012-01-18 01:42:56 +00:00
|
|
|
if ( ! kvs ) {
|
|
|
|
return null;
|
|
|
|
}
|
2012-01-10 01:09:50 +00:00
|
|
|
var kv;
|
|
|
|
for ( var i = 0, l = kvs.length; i < l; i++ ) {
|
|
|
|
kv = kvs[i];
|
2012-02-01 16:30:43 +00:00
|
|
|
if ( kv.k === key ) {
|
2012-01-10 01:09:50 +00:00
|
|
|
// found, return it.
|
2012-01-18 01:42:56 +00:00
|
|
|
return kv;
|
2011-11-02 21:07:51 +00:00
|
|
|
}
|
|
|
|
}
|
2012-01-10 01:09:50 +00:00
|
|
|
// nothing found!
|
|
|
|
return null;
|
|
|
|
};
|
2011-11-02 21:07:51 +00:00
|
|
|
|
2012-02-22 14:57:50 +00:00
|
|
|
MWParserEnvironment.prototype.lookupValue = function ( kvs, key ) {
|
|
|
|
if ( ! kvs ) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
var kv;
|
|
|
|
for ( var i = 0, l = kvs.length; i < l; i++ ) {
|
|
|
|
kv = kvs[i];
|
|
|
|
if ( kv.v === key ) {
|
|
|
|
// found, return it.
|
|
|
|
return kv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// nothing found!
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
2012-01-17 22:29:26 +00:00
|
|
|
MWParserEnvironment.prototype.KVtoHash = function ( kvs ) {
|
2012-01-19 23:43:39 +00:00
|
|
|
if ( ! kvs ) {
|
2012-02-14 20:56:14 +00:00
|
|
|
console.warn( "Invalid kvs!: " + JSON.stringify( kvs, null, 2 ) );
|
2012-01-19 23:43:39 +00:00
|
|
|
return {};
|
|
|
|
}
|
2012-01-17 22:29:26 +00:00
|
|
|
var res = {};
|
|
|
|
for ( var i = 0, l = kvs.length; i < l; i++ ) {
|
|
|
|
var kv = kvs[i],
|
2012-02-01 16:30:43 +00:00
|
|
|
key = this.tokensToString( kv.k ).trim();
|
2012-01-17 22:29:26 +00:00
|
|
|
if( res[key] === undefined ) {
|
2012-02-01 16:30:43 +00:00
|
|
|
res[key] = kv.v;
|
2012-01-17 22:29:26 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-14 20:56:14 +00:00
|
|
|
//console.warn( 'KVtoHash: ' + JSON.stringify( res ));
|
2012-01-17 22:29:26 +00:00
|
|
|
return res;
|
2012-03-01 12:47:05 +00:00
|
|
|
};
|
2011-11-02 21:07:51 +00:00
|
|
|
|
2012-01-10 01:09:50 +00:00
|
|
|
// Does this need separate UI/content inputs?
|
|
|
|
MWParserEnvironment.prototype.formatNum = function( num ) {
|
|
|
|
return num + '';
|
|
|
|
};
|
2011-11-02 21:07:51 +00:00
|
|
|
|
2012-01-10 01:09:50 +00:00
|
|
|
MWParserEnvironment.prototype.getVariable = function( varname, options ) {
|
2011-11-02 21:07:51 +00:00
|
|
|
//
|
2012-01-10 01:09:50 +00:00
|
|
|
};
|
2011-11-02 21:07:51 +00:00
|
|
|
|
|
|
|
/**
|
2012-01-10 01:09:50 +00:00
|
|
|
* @return MWParserFunction
|
2011-11-02 21:07:51 +00:00
|
|
|
*/
|
2012-01-10 01:09:50 +00:00
|
|
|
MWParserEnvironment.prototype.getParserFunction = function( name ) {
|
|
|
|
if (name in this.parserFunctions) {
|
|
|
|
return new this.parserFunctions[name]( this );
|
|
|
|
} else {
|
|
|
|
return null;
|
2011-11-02 21:07:51 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2012-01-10 01:09:50 +00:00
|
|
|
* @return MWParserTagHook
|
2011-11-02 21:07:51 +00:00
|
|
|
*/
|
2012-01-10 01:09:50 +00:00
|
|
|
MWParserEnvironment.prototype.getTagHook = function( name ) {
|
|
|
|
if (name in this.tagHooks) {
|
|
|
|
return new this.tagHooks[name](this);
|
|
|
|
} else {
|
|
|
|
return null;
|
2011-11-02 21:07:51 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-03-01 12:47:05 +00:00
|
|
|
|
|
|
|
MWParserEnvironment.prototype.makeTitleFromPrefixedText = function ( text ) {
|
|
|
|
text = this.normalizeTitle( text );
|
|
|
|
var nsText = text.split( ':', 1 )[0];
|
|
|
|
if ( nsText && nsText !== text ) {
|
|
|
|
var _ns = new Namespace(0);
|
|
|
|
var ns = _ns._defaultNamespaceIDs[ nsText.toLowerCase() ];
|
2012-03-01 13:51:53 +00:00
|
|
|
//console.warn( JSON.stringify( [ nsText, ns ] ) );
|
2012-03-01 12:47:05 +00:00
|
|
|
if ( ns !== undefined ) {
|
|
|
|
return new Title( text.substr( nsText.length + 1 ), ns, nsText, this );
|
|
|
|
} else {
|
|
|
|
return new Title( text, 0, '', this );
|
|
|
|
}
|
|
|
|
} else {
|
2012-03-05 12:00:38 +00:00
|
|
|
return new Title( text, 0, '', this );
|
2012-03-01 12:47:05 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// XXX: move to Title!
|
2012-01-14 00:58:20 +00:00
|
|
|
MWParserEnvironment.prototype.normalizeTitle = function( name ) {
|
|
|
|
if (typeof name !== 'string') {
|
|
|
|
throw new Error('nooooooooo not a string');
|
|
|
|
}
|
2012-03-01 12:47:05 +00:00
|
|
|
var forceNS;
|
|
|
|
if ( name.substr( 0, 1 ) === ':' ) {
|
|
|
|
forceNS = ':';
|
|
|
|
name = name.substr(1);
|
|
|
|
} else {
|
|
|
|
forceNS = '';
|
|
|
|
}
|
|
|
|
|
2012-01-17 23:18:33 +00:00
|
|
|
name = name.trim().replace(/[\s_]+/g, '_');
|
2012-02-13 13:35:46 +00:00
|
|
|
|
|
|
|
// Implement int: as alias for MediaWiki:
|
|
|
|
if ( name.substr( 0, 4 ) === 'int:' ) {
|
|
|
|
name = 'MediaWiki:' + name.substr( 4 );
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: Generalize namespace case normalization
|
|
|
|
if ( name.substr( 0, 10 ).toLowerCase() === 'mediawiki:' ) {
|
|
|
|
name = 'MediaWiki:' + name.substr( 10 );
|
|
|
|
}
|
|
|
|
|
2012-01-14 00:58:20 +00:00
|
|
|
function upperFirst( s ) { return s.substr(0, 1).toUpperCase() + s.substr(1); }
|
2012-03-01 12:47:05 +00:00
|
|
|
// XXX: Do not uppercase all bits!
|
|
|
|
var ns = name.split(':', 1)[0];
|
|
|
|
if( ns !== '' && ns !== name ) {
|
|
|
|
name = upperFirst( ns ) + ':' + upperFirst( name.substr( ns.length + 1 ) );
|
|
|
|
} else {
|
|
|
|
name = upperFirst( name );
|
|
|
|
}
|
|
|
|
//name = name.split(':').map( upperFirst ).join(':');
|
2012-01-14 00:58:20 +00:00
|
|
|
//if (name === '') {
|
|
|
|
// throw new Error('Invalid/empty title');
|
|
|
|
//}
|
2012-03-01 12:47:05 +00:00
|
|
|
return forceNS + name;
|
2012-01-14 00:58:20 +00:00
|
|
|
};
|
|
|
|
|
2011-11-02 21:07:51 +00:00
|
|
|
/**
|
2012-01-10 01:09:50 +00:00
|
|
|
* @fixme do this for real eh
|
2011-11-02 21:07:51 +00:00
|
|
|
*/
|
2012-01-10 01:09:50 +00:00
|
|
|
MWParserEnvironment.prototype.resolveTitle = function( name, namespace ) {
|
|
|
|
// hack!
|
|
|
|
if (name.indexOf(':') == -1 && typeof namespace ) {
|
|
|
|
// hack hack hack
|
2012-01-14 00:58:20 +00:00
|
|
|
name = namespace + ':' + this.normalizeTitle( name );
|
2012-01-10 01:09:50 +00:00
|
|
|
}
|
|
|
|
return name;
|
2011-11-02 21:07:51 +00:00
|
|
|
};
|
|
|
|
|
2012-03-05 12:00:38 +00:00
|
|
|
MWParserEnvironment.prototype.tokensToString = function ( tokens, strict ) {
|
2012-01-11 19:48:49 +00:00
|
|
|
var out = [];
|
2012-02-14 20:56:14 +00:00
|
|
|
//console.warn( 'MWParserEnvironment.tokensToString, tokens: ' + JSON.stringify( tokens ) );
|
2012-01-11 19:48:49 +00:00
|
|
|
// XXX: quick hack, track down non-array sources later!
|
|
|
|
if ( ! $.isArray( tokens ) ) {
|
|
|
|
tokens = [ tokens ];
|
|
|
|
}
|
|
|
|
for ( var i = 0, l = tokens.length; i < l; i++ ) {
|
|
|
|
var token = tokens[i];
|
2012-02-06 19:15:44 +00:00
|
|
|
if ( token === undefined ) {
|
2012-01-19 23:43:39 +00:00
|
|
|
console.trace();
|
2012-02-06 19:15:44 +00:00
|
|
|
this.tp( 'MWParserEnvironment.tokensToString, invalid token: ' +
|
|
|
|
JSON.stringify( token ) +
|
|
|
|
' tokens:' + JSON.stringify( tokens, null, 2 ));
|
2012-01-19 23:43:39 +00:00
|
|
|
continue;
|
|
|
|
}
|
2012-02-01 16:30:43 +00:00
|
|
|
if ( token.constructor === String ) {
|
|
|
|
out.push( token );
|
2012-01-19 23:43:39 +00:00
|
|
|
} else if ( token.type === 'COMMENT' || token.type === 'NEWLINE' ) {
|
|
|
|
// strip comments and newlines
|
2012-01-11 19:48:49 +00:00
|
|
|
} else {
|
2012-03-05 12:00:38 +00:00
|
|
|
if ( strict ) {
|
2012-03-05 16:23:00 +00:00
|
|
|
return [out.join(''), tokens.slice( i )];
|
2012-03-05 12:00:38 +00:00
|
|
|
}
|
2012-01-11 19:48:49 +00:00
|
|
|
var tstring = JSON.stringify( token );
|
2012-01-21 20:38:13 +00:00
|
|
|
this.dp ( 'MWParserEnvironment.tokensToString, non-text token: ' +
|
2012-01-19 23:43:39 +00:00
|
|
|
tstring + JSON.stringify( tokens, null, 2 ) );
|
2012-01-31 16:50:16 +00:00
|
|
|
//out.push( tstring );
|
2012-01-11 19:48:49 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-14 20:56:14 +00:00
|
|
|
//console.warn( 'MWParserEnvironment.tokensToString result: ' + out.join('') );
|
2012-01-11 19:48:49 +00:00
|
|
|
return out.join('');
|
|
|
|
};
|
|
|
|
|
2012-03-06 13:49:37 +00:00
|
|
|
MWParserEnvironment.prototype.decodeURI = function ( s ) {
|
|
|
|
return s.replace( /%[0-9a-f][0-9a-f]/g, function( m ) {
|
|
|
|
try {
|
|
|
|
return decodeURI( m );
|
|
|
|
} catch ( e ) {
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
};
|
|
|
|
|
|
|
|
MWParserEnvironment.prototype.sanitizeURI = function ( s ) {
|
|
|
|
var host = s.match(/^[a-zA-Z]+:\/\/[^\/]+(?:\/|$)/),
|
|
|
|
path = s,
|
|
|
|
anchor = null;
|
2012-03-06 14:32:45 +00:00
|
|
|
//console.warn( 'host: ' + host );
|
2012-03-06 13:49:37 +00:00
|
|
|
if ( host ) {
|
|
|
|
path = s.substr( host[0].length );
|
|
|
|
host = host[0];
|
|
|
|
} else {
|
|
|
|
host = '';
|
|
|
|
}
|
|
|
|
var bits = path.split('#');
|
|
|
|
if ( bits.length > 1 ) {
|
|
|
|
anchor = bits[bits.length - 1];
|
|
|
|
path = path.substr(0, path.length - anchor.length - 1);
|
|
|
|
}
|
|
|
|
host = host.replace( /%(?![0-9a-fA-F][0-9a-fA-F])|[#|]/g, function ( m ) {
|
|
|
|
return encodeURIComponent( m );
|
|
|
|
} );
|
|
|
|
path = path.replace( /%(?![0-9a-fA-F][0-9a-fA-F])|[\[\]#|]/g, function ( m ) {
|
|
|
|
return encodeURIComponent( m );
|
|
|
|
} );
|
|
|
|
s = host + path;
|
|
|
|
if ( anchor !== null ) {
|
|
|
|
s += '#' + anchor;
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
};
|
2012-01-11 19:48:49 +00:00
|
|
|
|
2012-01-19 23:43:39 +00:00
|
|
|
/**
|
|
|
|
* Simple debug helper
|
|
|
|
*/
|
|
|
|
MWParserEnvironment.prototype.dp = function ( ) {
|
|
|
|
if ( this.debug ) {
|
2012-01-20 01:46:16 +00:00
|
|
|
if ( arguments.length > 1 ) {
|
2012-02-14 20:56:14 +00:00
|
|
|
console.warn( JSON.stringify( arguments, null, 2 ) );
|
2012-01-20 01:46:16 +00:00
|
|
|
} else {
|
2012-02-14 20:56:14 +00:00
|
|
|
console.warn( arguments[0] );
|
2012-01-20 01:46:16 +00:00
|
|
|
}
|
2012-01-19 23:43:39 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-01-31 16:50:16 +00:00
|
|
|
/**
|
|
|
|
* Simple debug helper, trace-only
|
|
|
|
*/
|
|
|
|
MWParserEnvironment.prototype.tp = function ( ) {
|
|
|
|
if ( this.debug || this.trace ) {
|
|
|
|
if ( arguments.length > 1 ) {
|
2012-02-14 20:56:14 +00:00
|
|
|
console.warn( JSON.stringify( arguments, null, 2 ) );
|
2012-01-31 16:50:16 +00:00
|
|
|
} else {
|
2012-02-14 20:56:14 +00:00
|
|
|
console.warn( arguments[0] );
|
2012-01-31 16:50:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2012-01-19 23:43:39 +00:00
|
|
|
|
2012-01-10 01:09:50 +00:00
|
|
|
|
2011-11-02 21:07:51 +00:00
|
|
|
if (typeof module == "object") {
|
|
|
|
module.exports.MWParserEnvironment = MWParserEnvironment;
|
|
|
|
}
|