https://www.mediawiki.org/wiki/Special:Code/MediaWiki/112891
Revision: 112891
Author: gwicke
Date: 2012-03-02 13:36:37 +0000 (Fri, 02 Mar 2012)
Log Message:
-----------
Parse image options.
Modified Paths:
--------------
trunk/extensions/VisualEditor/modules/parser/ext.core.LinkHandler.js
trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js
trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt
Modified: trunk/extensions/VisualEditor/modules/parser/ext.core.LinkHandler.js
===================================================================
--- trunk/extensions/VisualEditor/modules/parser/ext.core.LinkHandler.js
2012-03-02 13:29:17 UTC (rev 112890)
+++ trunk/extensions/VisualEditor/modules/parser/ext.core.LinkHandler.js
2012-03-02 13:36:37 UTC (rev 112891)
@@ -53,6 +53,9 @@
var env = manager.env;
// distinguish media types
// if image: parse options
+
+ var content = env.lookupKV( token.attribs, 'content' ).v;
+
// XXX: get /wiki from config!
var a = new TagTk( 'a', [ new KV( 'href', '/wiki' + title.makeLink() )
] );
@@ -64,7 +67,11 @@
// XXX: parse options
- var options = this.parseImageOptions( env.lookupKV( token.attribs,
'content' ) );
+ var contentPos = token.dataAttribs.contentPos;
+ var optionSource = token.source.substr( contentPos[0], contentPos[1] -
contentPos[0] );
+ console.log( 'optionSource: ' + optionSource );
+ var options = this.imageParser.processImageOptions( optionSource );
+ //console.log( JSON.stringify( options, null, 2 ) );
// XXX: check if the file exists, generate thumbnail
// XXX: render according to mode (inline, thumb, framed etc)
var img = new SelfclosingTagTk( 'img',
@@ -80,8 +87,29 @@
};
WikiLinkHandler.prototype.parseImageOptions = function ( tokens ) {
- var text = this.manager.env.tokensToString( tokens );
+ var out = [],
+ s = '';
+ for ( var i = 0, l = tokens.length; i < l; i++ ) {
+ var token = tokens[i];
+ if ( token.constructor === String ) {
+ s += token;
+ } else if ( token.type === 'NEWLINE' ) {
+ s += '\n'; // XXX: preserve original newline
+ } else if ( token.type === 'COMMENT' ) {
+ // strip it
+ } else {
+ var res = this.imageParser.processImageOptions( s,
'img_options' ),
+ last = res.last();
+
+ if ( res.last().k !== 'caption' ) {
+ last.v.push = [last.v, token];
+ }
+ out.push( s );
+ s = '';
+ out.push(token);
+ }
+ }
};
if (typeof module == "object") {
Modified:
trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js
===================================================================
--- trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js
2012-03-02 13:29:17 UTC (rev 112890)
+++ trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js
2012-03-02 13:36:37 UTC (rev 112891)
@@ -67,6 +67,9 @@
//}
};
+PegTokenizer.prototype.processImageOptions = function( text ) {
+ return this.parser.parse(text, 'img_options', null, this );
+};
/*
* Inline breaks, flag-enabled production which detects end positions for
@@ -82,7 +85,8 @@
input.substr( pos + 1, 200)
.match(/[ \t]*[\r\n]/) !== null ) || null;
case '|':
- return syntaxFlags.template ||
+ return syntaxFlags.pipe ||
+ syntaxFlags.template ||
( syntaxFlags.table &&
( input[pos + 1].match(/[|}]/) !== null ||
syntaxFlags.tableCellArg
Modified: trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt
===================================================================
--- trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt
2012-03-02 13:29:17 UTC (rev 112890)
+++ trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt
2012-03-02 13:36:37 UTC (rev 112891)
@@ -292,6 +292,27 @@
// Start position of generic tag production
var tagStartPos = 0;
+ // Stack of source positions
+ var posStack = {
+ positions: {},
+ push: function( key, pos ) {
+ if ( this.positions[key] === undefined ) {
+ this.positions[key] = [pos];
+ } else {
+ this.positions[key].push( pos );
+ }
+ return true;
+ },
+ pop: function( key, pos ) {
+ var pk = this.positions[key];
+ if ( pk === undefined || ! pk.length ) {
+ throw "Tried to pop unknown position for " + key;
+ } else {
+ return [ pk.pop(), pos ];
+ }
+ }
+ };
+
// cache the input length
var inputLength = input.length;
@@ -736,23 +757,40 @@
// TODO: handle link prefixes as in al[[Razi]]
wikilink
- = "[["
+ = & { return posStack.push('wikilink' , pos); }
+ "[["
! url
//target:link_target
+ // XXX: disallow pipe!
target:wikilink_preprocessor_text
- lcontent:( "|" lt:link_text { return lt } )*
+ lcontent:(
+ & { return posStack.push('lcontent' , pos); }
+ lcs:( "|" lt:link_text { return lt; } )+ {
+ return { pos: posStack.pop('lcontent' , pos), content: lcs
};
+ }
+
+ / {
+ return { pos: posStack.pop('lcontent' , pos), content: null };
+ }
+ )
"]]"
// XXX In real MediaWiki, this is a language-dependent positive character
// class. Can we work out a static negative class instead?
// XXX: Exclude uppercase chars from non-latin languages too!
- trail:(! [A-Z \t(),.:-] tc:text_char { return tc })* {
+ trail:( ![A-Z \t(),.:-] tc:text_char { return tc } )* {
var obj = new SelfclosingTagTk( 'wikilink' ),
textTokens = [];
obj.attribs.push( new KV('href', target) );
+ obj.dataAttribs = {
+ sourcePos: posStack.pop( 'wikilink', pos ),
+ contentPos: lcontent.pos
+ };
+ // XXX: Point to object with path, revision and input information
+ obj.source = input;
// Deal with content. XXX: Properly support pipe-trick etc
- if (lcontent && lcontent.length) {
- textTokens = lcontent;
+ if (lcontent.content && lcontent.content.length) {
+ textTokens = lcontent.content;
if (trail) {
textTokens.push( trail.join('') );
}
@@ -769,6 +807,7 @@
//console.warn( "XXX:" + pp([obj].concat(textTokens, [new EndTagTk( 'a'
)])) );
return [obj];
}
+ / ! { return posStack.pop( 'wikilink', pos ); }
link_text
= & { return setFlag('linkdesc'); }
@@ -807,37 +846,43 @@
* Image option productions, only called from the LinkHandler token stream
* transformer, and only for images.
*/
-img_options = os:img_option* c:img_caption {
+img_options =
+ & { return setFlag( 'pipe' ); }
+ os:img_option* {
+ clearFlag( 'pipe' );
var options = {};
os = flatten( os );
- for ( var i = 0, l = options.length; i < l; i++ ) {
+ for ( var i = 0, l = os.length; i < l; i++ ) {
var o = os[i];
options[o.k] = o.v;
}
- options.options = os;
- options.caption = c;
+ options._options = os;
return options;
}
+/ & { return clearFlag( 'pipe' ); }
img_option
- = space*
- (
- img_format
+ = "|" space*
+ o:(
+ img_attribute
+ / img_format
/ img_dimensions
/ img_halign
/ img_valign
/ img_link
- / img_attribute
+ / lt:link_text { return new KV('caption', lt) }
)
- ("|" / eof)
+ space* {
+ return o
+ };
img_format
- = f:( 'border' / 'frameless' / 'frame' / 'thumb' / 'thumbnail' ) {
+ = f:( 'border' / 'frameless' / 'frame' / 'thumbnail' / 'thumb' ) {
return new KV( 'format', f );
}
img_dimensions
- = x:([0-9]+)? y:('x' [0-9]+)? 'px' {
+ = x:(n:[0-9]+ { return n.join('') })? y:('x' n:[0-9]+ { return n.join('')
})? 'px' {
if ( x === '' && y ) {
return new KV( 'height', y );
} else if ( y === '' && x ) {
@@ -863,17 +908,23 @@
// sure that those cleanly convert back to the original text, then we could
// re-parse them here.
img_link
- = 'link=' t:urltext {
- return new KV( 'link', t );
- }
+ = 'link=' space*
+ u:(
+ t:url {
+ clearFlag( 'pipe' );
+ return t;
+ }
+ / & { return clearFlag( 'pipe' ); }
+ )
+{
+ return new KV( 'link', u );
+}
img_attribute
- = k:( 'page' / 'alt' / 'thumb' ) '=' t:preprocessor_text {
+ = k:( 'page' / 'alt' / 'thumbnail' / 'thumb' ) '=' t:preprocessor_text? {
return new KV( k, t );
}
-// catch-all
-img_caption = .*
/***********************************************************
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs