FlightGear wiki:Instant-Refs: Difference between revisions

Jump to navigation Jump to search
Version 0.19 of script. Most transformation functions re-factored
(Tiny fixes, etc.)
(Version 0.19 of script. Most transformation functions re-factored)
Line 55: Line 55:
   
   
== Issues/limitations ==
== Issues/limitations ==
* The JavaScript {{Func link|prompt()|ext=https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt}} boxes used are typically restricted to a max size of about 10 KB; other options should be looked at. {{Not done}}
* The JavaScript {{Func link|window.prompt()|ext=https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt}} boxes used are typically restricted to a max size of about 10 KB; other options should be looked at. {{Not done}}


== Feature requests & ideas ==
== Feature requests & ideas ==
* Add support for [http://sourceforge.net/p/flightgear/codetickets/ tickets], merge requests comments and [http://www.fguk.eu/index.php/forum/index FGUK forum].
* GET-encoded SID arguments should be stripped from forum URLs. {{Not done}}
* GET-encoded SID arguments should be stripped from forum URLs. {{Not done}}
* Links to repositories should be converted to use wiki templates. {{Not done}}
* Links to repositories should be converted to use wiki templates. {{Not done}}
Line 74: Line 75:
// ==UserScript==
// ==UserScript==
// @name        Instant-Cquotes
// @name        Instant-Cquotes
// @version    0.18
// @version    0.19
// @description Automatically converts mailing list and forum quotes into Mediawiki markup.
// @description Automatically converts mailing list and forum quotes into Mediawiki markup.
// @author      Hooray, bigstones, Philosopher & Red Leader
// @author      Hooray, bigstones, Philosopher & Red Leader
Line 90: Line 91:
// ==/UserScript==
// ==/UserScript==


// Check if Greasemonkey/Tampermonkey is available
try {
try {
     GM_addStyle(GM_getResourceText("jQUI_CSS"));
     GM_addStyle(GM_getResourceText("jQUI_CSS"));
Line 98: Line 100:


// Define constants
// Define constants
var DEBUG = false;
var DEBUG = true;


var CONFIG = {
var CONFIG = {
     "sourceforge.net": {
     "Mailing list": {
         name: "mailing list",
         url_reg: /http:\/\/sourceforge\.net\/p\/flightgear\/mailman\/.*/,
         content: {
         content: {
             selection: getSelectedText,
             selection: getSelectedText,
             idStyle: /msg[0-9]{8}/,
             idStyle: /msg[0-9]{8}/,
             parentTag: ["tagName", "PRE"],
             parentTag: ["tagName", "PRE"]
            transform: [newline2br]
         },  
         },  
         author: {
         author: {
Line 126: Line 127:
     },
     },


     "forum.flightgear.org": {
     "FlightGear forum": {
         name: "forum",
         url_reg: /http:\/\/forum\.flightgear\.org\/.*/,
         content: {
         content: {
             selection: getSelectedHtml,
             selection: getSelectedHtml,
             idStyle: /p[0-9]{6}/,
             idStyle: /p[0-9]{6}/,
             parentTag: ["className", "content", "postbody"],
             parentTag: ["className", "content", "postbody"],
             transform: [removeComments, escapePipes, a2wikilink, phpBB_smilies2text,
             transform: [removeComments, forum_quote2cquote, forum_smilies2text,
                        img2link, phpBB_fontstyle2wikistyle, phpBB_code2syntaxhighlight,
                forum_fontstyle2wikistyle, forum_code2syntaxhighlight, img2link,
                        phpBB_quote2cquote, vid2wiki, escapeEquals, addNewlines]
                a2wikilink, vid2wiki, list2wiki, forum_br2newline]
 
         },
         },
         author: {
         author: {
Line 159: Line 161:
     },
     },


    // Show a jQuery dialog
     jQueryDiag: function(msg) {
     jQueryDiag: function(msg) {
         var diagDiv = $('<div id="MyDialog"><textarea id="quotedtext" rows="10"cols="80" style="width: 290px; height: 290px">' + msg + '</textarea></div>');
         var diagDiv = $('<div id="MyDialog"><textarea id="quotedtext" rows="10"cols="80" style="width: 290px; height: 290px">' + msg + '</textarea></div>');
Line 176: Line 179:
};
};


var OUTPUT = METHODS.msgbox;
var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];


var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
// Conversion for forum emoticons
var EMOTICONS = [
    [/:shock:/g,  "O_O"],
    [/:lol:/g,     "(lol)"],
    [/:oops:/g,   ":$"],
    [/:cry:/g,     ";("],
    [/:evil:/g,    ">:)"],
    [/:twisted:/g, "3:)"],
    [/:roll:/g,    "(eye roll)"],
    [/:wink:/g,    ";)"],
    [/:!:/g,      "(!)"],
    [/:\?:/g,     "(?)"],
    [/:idea:/g,   "(idea)"],
    [/:arrow:/g,  "(->)"],
    [/:mrgreen:/g, "xD"]
];


// ##################
// ##################
Line 186: Line 204:
window.addEventListener('load', init);
window.addEventListener('load', init);


// Initialize
function init() {
function init() {
     document.onmouseup = instantCquote;
     document.onmouseup = instantCquote;
Line 191: Line 210:
}
}


// The main function
function instantCquote() {
function instantCquote() {
     var profile = CONFIG[window.location.hostname],
     var profile = getProfile(),
         selection = document.getSelection(),
         selection = document.getSelection(),
         output = {},
         output = {},
Line 229: Line 249:


     }
     }
   
    output.content = stripWhitespace(output.content);


     output = createCquote(output);
     output = createCquote(output);


     OUTPUT(output);
     outputText(output);
}
 
// Gets to correct profile
function getProfile(){
    for (var profile in CONFIG){
        if(window.location.href.match(CONFIG[profile].url_reg) !== null){
            return CONFIG[profile];
        }
    }
}
}


// Get the HTML code that is selected
function getSelectedHtml() {
function getSelectedHtml() {
     // From http://stackoverflow.com/a/6668159
     // From http://stackoverflow.com/a/6668159
Line 253: Line 285:
}
}


// IE8 compat. function
// Gets the selected text
function getSelectedText() {
function getSelectedText() {
     return document.getSelection().toString();
     return document.getSelection().toString();
}
}


// Get the ID of the post
function getPostId(selection, profile, focus) {
function getPostId(selection, profile, focus) {
     if (focus !== undefined) {
     if (focus !== undefined) {
Line 272: Line 305:
}
}


// Checks that the selection is valid
function checkValid(selection, profile) {
function checkValid(selection, profile) {
     var ret = true,
     var ret = true,
Line 311: Line 345:
}
}


// Extracts the raw text from a certain place, using an XPath
function extractFieldInfo(profile, id, field) {
function extractFieldInfo(profile, id, field) {
     if (field === "content") {
     if (field === "content") {
Line 320: Line 355:
}
}


// Change the text using spcified transformations
function applyTransformations(fieldInfo, trans) {
function applyTransformations(fieldInfo, trans) {
     if (typeof trans === "function") {
     if (typeof trans === "function") {
        dbLog(fieldInfo);
         return trans(fieldInfo);
         return trans(fieldInfo);
     } else if (Array.isArray(trans)) {
     } else if (Array.isArray(trans)) {
Line 333: Line 368:
}
}


// Formats the quote
function createCquote(data) {
function createCquote(data) {
     var wikiText = "{{FGCquote\n" +
     var wikiText = "{{FGCquote\n" +
         "|" + data.content + "\n" +
         ((data.content.match(/^\s*?{{cquote/) === null) ? "|1= " : "| ") + data.content + "\n" +
         "| {{cite web\n" +
         "|2= {{cite web\n" +
         "  | url    = " + data.url + "\n" +
         "  | url    = " + data.url + "\n" +
         "  | title  = " + nowiki(data.title) + "\n" +
         "  | title  = " + nowiki(data.title) + "\n" +
Line 345: Line 381:


     return wikiText;
     return wikiText;
}
// Output the text.
// Tries the jQuery dialog, and falls back to window.prompt()
function outputText(msg){
    try {
        METHODS.jQueryDiag(msg);
    }
    catch(err){
        METHODS.msgbox(msg);
    }
}
}


Line 367: Line 414:
}
}


function escapePipes(text) {
// Not currently used (as of June 2015), but kept just in case
     text = text.replace(/\|\|/g,"{{!!}}");
function escapePipes(html) {
     text = text.replace(/\|\-/g,"{{!-}}");
     html = html.replace(/\|\|/g,"{{!!}}");
     return text.replace(/\|/g,"{{!}}");
     html = html.replace(/\|\-/g,"{{!-}}");
     return html.replace(/\|/g,"{{!}}");
}
}


// Converts HTML <a href="...">...</a> tags to wiki links, internal if possible.
// Converts HTML <a href="...">...</a> tags to wiki links, internal if possible.
function a2wikilink(html){
function a2wikilink(html){
     // Links to wiki images, because
     // Links to wiki images, because
     // they need special treatment, or else they get displayed.
     // they need special treatment, or else they get displayed.
Line 407: Line 456:
}
}


// Converts images, including images in <a> links
function img2link(html) {
function img2link(html) {
    html = html.replace(/<a[^<]*?href="([^<]*?)"[^<]*?><img.*?src="http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)".*?><\/a>/g, "[[File:$2|250px|link=$1]]");
     html = html.replace(/<img.*?src="http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)".*?>/g, "[[File:$1|250px]]");
     html = html.replace(/<img.*?src="http:\/\/wiki\.flightgear\.org\/images\/.*?\/.*?\/(.*?)".*?>/g, "[[File:$1|250px]]");
    html = html.replace(/<a[^<]*?href="([^<]*?)"[^<]*?><img.*?src="(.*?)".*?><\/a>/g, "(see [$2 image], links to [$1 here])");
     return html.replace(/<img.*?src="(.*?)".*?>/g, "(see the [$1 linked image])");
     return html.replace(/<img.*?src="(.*?)".*?>/g, "(see the [$1 linked image])");
}
}


function phpBB_smilies2text(html) {
// Converts smilies
     return html.replace(/<img src="\.\/images\/smilies\/icon_.*?\.gif" alt="(.*?)".*?>/g, "$1");
function forum_smilies2text(html) {
     html = html.replace(/<img src="\.\/images\/smilies\/icon_.*?\.gif" alt="(.*?)".*?>/g, "$1");
    for (var i = 0; i < EMOTICONS.length; i++){
        html = html.replace(EMOTICONS[i][0], EMOTICONS[i][1]);
    }
    return html;
}
}


function phpBB_fontstyle2wikistyle(html) {
// Converts font formatting
function forum_fontstyle2wikistyle(html) {
     html = html.replace(/<span style="font-weight: bold">(.*?)<\/span>/g, "'''$1'''");
     html = html.replace(/<span style="font-weight: bold">(.*?)<\/span>/g, "'''$1'''");
     html = html.replace(/<span style="text-decoration: underline">(.*?)<\/span>/g, "<u>$1</u>");
     html = html.replace(/<span style="text-decoration: underline">(.*?)<\/span>/g, "<u>$1</u>");
Line 423: Line 481:
}
}


function phpBB_code2syntaxhighlight(html) {
// Converts code blocks
     return html.replace(/<dl.*?><dt>.*?<\/dt><dd><code>(.*?)<\/code><\/dd><\/dl>/g, '<pre style="white-space:pre-wrap">\n$1\n</pre>');
function forum_code2syntaxhighlight(html) {
     var list = html.match(/<dl class="codebox">.*?<code>(.*?)<\/code>.*?<\/dl>/g),
        data = [];
 
    if (list === null) return html;
 
    for(var n = 0; n < list.length; n++){
        data = html.match(/<dl class="codebox">.*?<code>(.*?)<\/code>.*?<\/dl>/);
 
        html = html.replace(data[0], processCode(data));
    }
 
    return html;
}
 
// Strips any whitespace from the beginning and end of a string
function stripWhitespace(html){
    html = html.replace(/^\s*?(\S)/, "$1")
    return html.replace(/(\S)\s*?\z/, "$1");
}
 
// Process code, including basic detection of language
function processCode(data){
    var lang = "",
        code = data[1];
   
    code = code.replace(/&nbsp;/g, " ");
 
    if (code.match(/=?.*?\(?.*?\)?;/) !== null) lang = "nasal";
    if (code.match(/&lt;.*?&gt;.*?&lt;\/.*?&gt;/) !== null || code.match(/&lt;!--.*?--&gt;/) !== null) lang = "xml";
 
    code = code.replace(/<br\/?>/g, "\n");
 
    return '<syntaxhighlight lang="' + lang + '" enclose="div">\n' + code + '\n</syntaxhighlight>';
}
}


function phpBB_quote2cquote(html) {
// Converts quote blocks to Cquotes
     return html.replace(/<blockquote.*?><div>(?:<cite>.*?<\/cite>)?(.*?)<\/div><\/blockquote>/g, "{{cquote|$1}}");
function forum_quote2cquote(html) {
     html = html.replace(/<blockquote class="uncited"><div>(.*?)<\/div><\/blockquote>/g, "{{cquote|$1}}");
 
    if (html.match(/<blockquote>/g) === null) return html;
 
    var numQuotes = html.match(/<blockquote>/g).length;
    for(var n = 0; n < numQuotes; n++){
        html = html.replace(/<blockquote><div><cite>(.*?) wrote.*?:<\/cite>(.*?)<\/div><\/blockquote>/, "{{cquote|$2|$1}}");
    }
    return html;
}
}


// Converts videos to wiki style
function vid2wiki(html){
function vid2wiki(html){
     // YouTube
     // YouTube
     html = html.replace(/<div.*?><iframe width="(.*?)" height="(.*?)" src="http:\/\/www\.youtube\.com\/embed\/(.*?)".*?><\/iframe><\/div>/g, "{{#ev:youtube|$3|$1x$2}}");
     html = html.replace(/<div class="video-wrapper">\s.*?<div class="video-container">\s*?<iframe class="youtube-player".*?width="(.*?)" height="(.*?)" src="http:\/\/www\.youtube\.com\/embed\/(.*?)".*?><\/iframe>\s*?<\/div>\s*?<\/div>/g, "{{#ev:youtube|$3|$1x$2}}");
    html = html.replace(/\[.*? Watch on Youtube\]/g, "");


     // Vimeo: Doesn't currently work (cannot select video viewer on post)
     // Vimeo
     html = html.replace(/<iframe src="http:\/\/player\.vimeo\.com\/video\/(.*?)\?.*?" width="(.*?)" height="(.*?)".*?>.*?<\/iframe>/g, "{{#ev:vimeo|$3|$1x$2}}");
     html = html.replace(/<iframe src="http:\/\/player\.vimeo\.com\/video\/(.*?)\?.*?" width="(.*?)" height="(.*?)".*?>.*?<\/iframe>/g, "{{#ev:vimeo|$1|$2x$3}}");
     return html.replace(/\[.*? Watch on Vimeo\]/g, "");
     return html.replace(/\[.*? Watch on Vimeo\]/g, "");
}
}


// Not currently used (as of June 2015), but kept just in case
function escapeEquals(html) {
function escapeEquals(html) {
     return html.replace(/=/g,"{{=}}");
     return html.replace(/=/g,"{{=}}");
}
}


function addNewlines(html) {
// <br> to newline.
     html = html.replace(/<br\/?>/g, "<br/>\n");
function forum_br2newline(html) {
     html = html.replace(/(<\/?[uo]l>)/g, "$1\n");
     html = html.replace(/<br\/?><br\/?>/g, "\n");
     return html.replace(/<\/li>/g, "</li>\n");
    return html.replace(/<br\/?>/g, "\n\n");
}
 
// Forum list to wiki style
function list2wiki(html) {
     var list = html.match(/<ul>(.*?)<\/ul>/g);
    if (list !== null){
        for(var i = 0; i < list.length; i++){
            html = html.replace(/<li>(.*?)<\/li>/g, "* $1\n");
        }
    }
 
     list = html.match(/<ol.*?>(.*?)<\/ol>/g);
    if (list !== null){
        for(var i = 0; i < list.length; i++){
            html = html.replace(/<li>(.*?)<\/li>/g, "# $1\n");
        }
    }
   
    html = html.replace(/<\/?[uo]l>/g, "");
 
    return html;
}
}


Line 456: Line 578:


// Returns the correct ordinal adjective
// Returns the correct ordinal adjective
function ordAdj(date){
function ordAdj(date) {
     date = date.toString();
     date = date.toString();
     if(date == "11" || date == "12" || date == "13"){
     if(date == "11" || date == "12" || date == "13"){
Line 479: Line 601:
function underscore2Space(str){
function underscore2Space(str){
     return str.replace(/_/g, " ");
     return str.replace(/_/g, " ");
}
function newline2br(text) {
    return text.replace(/\n/g, "<br/>\n");
}
}


Navigation menu