2012-12-30 5 views
5

Im Moment versuche ich ein Skript zu erstellen, das automatisch Links zu anderen Seiten in einem Wiki-Dokument erstellt.Automatisches Hinzufügen von Wikilinks in einer MediaWiki-Seite mit einer Liste von Seitentiteln

function createLinks(startingSymbol, endingSymbol, text, links){ 
    //this needs to be implemented somehow - replace every match of the list of links with a link 
} 
createLinks("[[", "]]", "This is the text to wikify", ["wikify", "text"]); 
//this function would return "This is the [[text]] to [[wikify]]" as its output. 

Die naheliegendste Lösung wäre, einfach jedes Spiel des text mit [[text]], string zu ersetzen, aber dann würde ich in einige Probleme laufen - zum Beispiel, wenn ich die Zeichenfolge "some problems" und "problems" innerhalb der Zeichenfolge zu wikify versucht "Einige Probleme", würde ich mit der Zeichenfolge "[[some [[problems]]]]" enden. Gibt es eine Möglichkeit, dieses Problem zu umgehen?

+0

Ich frage im Wesentlichen, ob es möglich ist, eine Zeichenfolge innerhalb einer anderen Zeichenfolge zu ersetzen, wenn und nur wenn es nicht zwischen zwei anderen Zeichenfolgen ist. (Ersetze beispielsweise die Zeichenkette "str1" innerhalb der Zeichenkette "str2", genau dann, wenn "str2" nicht zwischen den Zeichenketten "str3" und "str4" liegt). –

+0

sollte das lesen '// Diese Funktion würde zurückkehren" Dies ist der [[Text]] zu [[wikify]] "als Ausgabe? – kieran

+0

Es könnte möglich sein, dies mithilfe der Lookahead- und Lookbehind-Operatoren in einem regulären JavaScript-Ausdruck zu tun, aber ich bin mit der Syntax für reguläre Ausdrücke nicht vertraut. –

Antwort

1

Hier ist ein weiterer Ansatz, basierend auf dynamisch ein regexp Aufbau:

function wikifyText (startString, endString, text, list) { 
    list = list.map(function (str) { 
     return str.replace(/([^a-z0-9_])/g, '\\$1'); 
    }); 
    list.sort(); 
    list.reverse(); 
    var re = new RegExp('\\b(' + list.join('|') + ')\\b', 'g'); 
    return text.replace(re, startString + '$1' + endString); 
} 

(JSFiddle)

Die \b Anker an beiden Enden des regexp diese Version verhindern versuchen, alle Teile Worte wikify, aber Sie könnten diese Einschränkung lockern, wenn Sie wollten. Zum Beispiel ersetzen regexp Konstruktion mit:

var re = new RegExp('\\b(' + list.join('|') + ')(?=(e?s)?\\b)', 'g'); 

würde ein s oder es Suffix am Ende des letzten Wortes wikified (JSFiddle) ermöglichen. Beachten Sie, dass MediaWiki automatisch solche Suffixe als Teil des Linktextes einfügt, wenn die Seite angezeigt wird.


Edit: Hier ist eine Version, die die ersten Buchstaben jeden Satzes ermöglicht auch Groß- und Kleinschreibung zu sein, wie MediaWiki Seitentitel sind. Es ersetzt auch die \b Anker mit einer etwas Unicode freundliche Lösung:

function wikifyText (startString, endString, text, list) { 
    list = list.map(function (str) { 
     var first = str.charAt(0); 
     str = first.toUpperCase() + first.toLowerCase() + str.substr(1); 
     str = str.replace(/(\W)/ig, '\\$1'); 
     return str.replace(/^(\\?.\\?.)/, '[$1]'); 
    }); 
    list.sort(); 
    list.reverse(); 
    var re = new RegExp('(^|\\W)(' + list.join('|') + ')(?=(e?s)?\\W)', 'g'); 
    return text.replace(re, '$1' + startString + '$2' + endString); 
} 

(JSFiddle)

Dieses viel weniger chaotisch wäre, wenn JavaScript solche Standard PCRE Funktionen wie Groß- und Kleinschreibung Abschnitte unterstützt regexps, Look-Behind- oder Unicode-Zeichenklassen.

Insbesondere aufgrund der letzten dieser fehlenden Features, auch diese Lösung noch nicht vollständig ist Unicode-aware: es insbesondere Verbindungen nach oder beginnen kann, bevor ein Zeichen enden, die \W übereinstimmt, die Interpunktion enthält aber auch alle Nicht-ASCII-Zeichen, sogar Buchstaben. (Nicht-ASCII-Buchstaben innerhalb Links werden jedoch korrekt behandelt.) In der Praxis glaube ich nicht, dass dies ein großes Problem sein sollte.

+0

Ich habe einen Klon von Tomboy Notes mit meiner Version des Skripts erstellt. Er erzeugt während der Eingabe Links zu Wikipedia und druckt auch das generierte HTML. http://jsfiddle.net/gjqWy/77/ –

+1

@AndersonGreen: Cool! Ich wünschte, ich könnte dir dafür eine zweite +1 geben. –

+0

Ich habe auch einen Wiki-Link-Generator geschrieben, der viel vom selben Code verwendet. Es erzeugt Wiki-Markup-Links anstelle von HTML-Links. Momentan ist es nur in der Lage, reinen Text richtig zu wikifizieren. http://jsfiddle.net/jarble/gjqWy/78/ –

1

Ich habe eine funktionierende Demo eines Skripts erstellt, das fast genau das tut, was ich tun muss.

http://jsfiddle.net/8JcZC/2/

alert(wikifyText("[[", "]]", "There are cars, be careful, carefully, and with great care!!", ["text", "hoogahjush", "wikify", "car", "careful", "carefully", "great care"])); 

function wikifyText(startString, endString, text, list){ 
    //sort list into ascending order 
    list.sort(function(a, b){ 
     return a.length - b.length; // ASC -> a - b; DESC -> b - a 
    }); 
    //replace every element in the array with the wikified text 
    for(var i = 0; i < list.length; i++){ 
     text = text.replace(list[i], startString + list[i] + endString); 
    } 
    return text; 
} 

Ein Wort der Vorsicht: In einigen Fällen kann dieses Skript Wörter wikify, die Teil von anderen Wörtern sind. Wenn beispielsweise das Wort "careful" nicht in der Liste enthalten ist und das Wort car in der Liste enthalten ist, wird das Wort "car" innerhalb des Worts "careful" wie folgt abgefragt: "[[car]]eful". Ich hoffe, dass ich diese Einschränkung umgehen kann.

Verwandte Themen