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

Reply via email to