FlightGear wiki:Instant-Refs: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
m (move selection handling into CONFIG hash to prepare post-processing, e.g. content parsing/transformation via transform() callback)
m (allow selected text to be transformed via transform() callback (prepends "YIKES !!!" to the selection ATM), need to port CR/LF handling next by moving it into the transform callback)
Line 47: Line 47:
         content: {
         content: {
           selection: GetSelectedText,
           selection: GetSelectedText,
          transform: make_prepend("YIKES !!!")
         },  
         },  
         author: {
         author: {
Line 67: Line 68:
         content: {
         content: {
           selection: GetSelectedText,
           selection: GetSelectedText,
          transform: make_prepend("YIKES !!!")
         },
         },
         author: {
         author: {
Line 187: Line 189:
     // check if we got text
     // check if we got text
     if ( text != "" ) {
     if ( text != "" ) {
        var profile = CONFIG[window.location.hostname];
        var transform = profile.content.transform;
        if(transform)
          text = transform( text );
         var cquote = CreateCquote(text, parent);
         var cquote = CreateCquote(text, parent);
         if (window.prompt ("Copy to clipboard: Ctrl+C, Enter", cquote) != null)
         if (window.prompt ("Copy to clipboard: Ctrl+C, Enter", cquote) != null)
Line 203: Line 210:
   
   
window.addEventListener('load', register );
window.addEventListener('load', register );
</syntaxhighlight>
</syntaxhighlight>


[[Category:Wiki maintenance]]
[[Category:Wiki maintenance]]

Revision as of 11:10, 3 June 2014

Note  FlightGear development is not centrally coordinated in any way - at the very best, FlightGear development is "self-coordinated" - i.e. contributors discuss ideas and make proposals to contribute in a certain fashion and then team up to implement certain features and building blocks temporarily.

Obviously, ideas and feature requests made by end-users are also appreciated. But at the end of the day, people who do the actual work have obviously more say about future development than those who merely make suggestions. And contributors tend to prioritize work on items that are prioritized/suggested by other contributors, especially those offering to get involved and help.

But given the lack of development manpower, many good ideas tend to have a fairly long shelf life unfortunately. So that good ideas may be forgotten over time.

This is also why it is important for other developers/contributors to know who came up with a certain idea and who supported/supports it, possibly months (or even years) after a discussion took place - which is why good ideas should not just be preserved, but accompanied with corresponding quotes, linking back to the original discussion, so that potential contributors can make up their own minds to determine if they want to get involved in some effort or not. The script that you can find below is intended to help with this - it allows people to easily copy&paste important discussions over to the wiki, without having to rewrite any text, and without having to put together proper cquotes manually. In fact, it's a matter of just a few seconds.


or to any forum message
  • copy/mark some relevant portion of text
  • and directly get a full cquote paragraph that you can add to the wiki here
// ==UserScript==
// @name       instant-cquotes
// @description automatically create proper wikimedia cquotes for sourceforge ml and forum text selections
// @namespace  http://wiki.flightgear.org/
// @version    0.7
// @icon http://wiki.flightgear.org/skins/common/images/icons-fg-135.png
// @match      http://sourceforge.net/p/flightgear/mailman/* 
// @match      http://forum.flightgear.org/*
// @copyright  2013+, FlightGear.org (bigstones, Philosopher & Hooray)
// ==/UserScript==
 
var debug = 0; 
 
function make_prepend(prefix) {
 return function(data) {
  return prefix+data;
 };
}

/* for each domain, fields: author, title, date, url.
 * for each field:
        xpath - relative to the text body element
        regex - will extract the first capture group (i.e. '(xxx)')
        prepend - a string to be prepended (useful for urls)
*/
var CONFIG = {
    "sourceforge.net": {
        content: {
           selection: GetSelectedText,
           transform: make_prepend("YIKES !!!")
        }, 
        author: {
            xpath: "../../../tr/td/div/small/text()",
            regex: "/^From: (.*) <.*@.*>/"
        },
        title: {
            xpath: "../../../tr/td/div/div/b/a/text()"
        },
        date: {
            xpath: "../../../tr/td/div/small/text()",
            regex: "/ - (.*-.*-.*) /"
        },
        url: {
            xpath: "../../../tr/td/div/div/b/a/@href",
            transform: make_prepend("http://sourceforge.net"),
        }
    },
    "forum.flightgear.org": {
        content: {
           selection: GetSelectedText,
           transform: make_prepend("YIKES !!!")
        },
        author: {
            xpath: "../p/strong/a/text()"
        },
        title: {
            xpath: "../h3/a/text()"
        },
        date: {
            xpath: "../p/text()[2]",
            regex: "/ » (.*),/"
        },
        url: {
            xpath: "../p/a/@href",
            regex: "/\.(.*)/",
            transform: make_prepend("http://forum.flightgear.org"),
        }
    }
 
};
 
function getPathTo(element) {
    if (element.id!=='')
        return 'id("'+element.id+'")';
    if (element===document.body)
        return element.tagName;
 
    var ix= 0;
    var siblings= element.parentNode.childNodes;
    for (var i= 0; i<siblings.length; i++) {
        var sibling= siblings[i];
        if (sibling===element)
            return getPathTo(element.parentNode)+'/'+element.tagName+'['+(ix+1)+']';
        if (sibling.nodeType===1 && sibling.tagName===element.tagName)
            ix++;
    }
}
 
function nowiki(text) {
    return "<nowiki>" + text + "</nowiki>";
}
 
// TODO: we may want to parse URLs in the quoted text and not use nowiki-escaping ?
function extractInfo(parentPath, profile) {
    var info = {};
    for (field in profile) {
        var fieldInfo = "";
        if (profile[field].xpath) {
            var fullPath =  parentPath + "/" + profile[field].xpath;
            fieldInfo = document.evaluate(fullPath, document, null, XPathResult.STRING_TYPE, null ).stringValue;
        }
 
        if (profile[field].regex) {
            var regex = eval(profile[field].regex);
            fieldInfo = fieldInfo.match(regex)[1];
        }
 
        
         var transform = profile[field].transform;
         if(transform)
           fieldInfo = transform(fieldInfo);
         
 
        if (debug) alert(field+" = "+fieldInfo);
        info[field] = fieldInfo;
    }
 
    return info;
}
 

function CreateCquote(text, parent) {
    var info = {};
 
    if(parent) {
        var profile = CONFIG[window.location.hostname];
        var parentPath = getPathTo(parent);
 
        info = extractInfo(parentPath, profile);
    } else {
        // fallback. XXX: not tested
        info.url = document.URL;
        info.title = "from " + window.location.hostname;
        info.author = "";
        info.date = "";
    }
 
    text = newline2br(text);
    
    //TODO: add template string to profile
    var template = "{{cquote" + "\n" +
        "  |" + nowiki(text) + "\n" +
        "  |{{cite web |url=" + info.url + "\n" +
        "     |title=" + nowiki(info.title) + "\n" +
        "     |author=" + nowiki(info.author) + "\n" +
        "     |date=" + nowiki(info.date) + "\n" +
        "   }}" + "\n" +
        "}}";
    return template;
}

function newline2br(text) {
    return text.replace(/\n/g,"</nowiki><br/><nowiki>\n");
}
 
function GetSelectedText () {    
    var text = "";
    var parent = null;
 
    if (document.getSelection) {
        var sel = document.getSelection(); 
        parent = sel.anchorNode.parentNode;// anchorNode is the textnode,
        text += sel.toString();             // parentNode is the actual parent, i.e. html element
    } else if (document.selection) { // for IE <= v8
        var textRange = document.selection.createRange();
        parent = textRange.parentElement(); // XXX: not tested!
        text = textRange.text;
    }
 
    // check if we got text
    if ( text != "" ) {
        var profile = CONFIG[window.location.hostname];
        var transform = profile.content.transform;
        if(transform)
          text = transform( text );

        var cquote = CreateCquote(text, parent);
        if (window.prompt ("Copy to clipboard: Ctrl+C, Enter", cquote) != null)
            window.getSelection().removeAllRanges(); // deselect all text
    }
}
 
function register() {
    // check if we have a matching domain in the CONFIG hash
    if (CONFIG.hasOwnProperty(window.location.hostname) ) {        
        // if yes, register a callback to handle mouse events
        var profile = CONFIG[window.location.hostname];
        document.onmouseup = profile.content.selection;
    }        
}
 
window.addEventListener('load', register );