Benutzer Diskussion:Umherirrender/Archiv/2011-1

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

Hallo Umherirrender! Anlässlich des zehnten Geburtstags von Wikipedia möchten wir von Wikimedia Deutschland in Zusammenarbeit mit der Wikipedia-Gemeinschaft ein Buch veröffentlichen. Möglicherweise hast du Lust dich daran zu beteiligen?! Was wir suchen sind kurze Geschichten, Anekdoten und Erlebnisberichte, die den Sachinhalt des Buches ergänzen und ihm eine menschliche Dimension verleihen. --Boris Marinov (WMDE) 14:56, 5. Jan. 2011 (CET)

Hallo, ich glaube nicht, das ich einen guten Artikel für das Buch schreiben könnte. Ich schreibe ja jetzt schon keine Artikel für Wikipedia, weil ich kein guter Schreiber bin. Daher möchte ich nicht am Wikipedia-Buch teilnehmen. Trotzdem vielen Dank, das du gefragst hast. Ich denke, es finden sich andere Benutzer die beispielsweise rund um die Technik etwas schreiben könnten. Vielleicht ließt auch jemand mit, der gerne für mich einspringen kann. Der Umherirrende 16:47, 5. Jan. 2011 (CET)

kurze Frage

Hallo Umherirrender. Bei dieser Änderung verstehe ich ja die Änderung der Reihenfolge von Personendaten und Kategorien. Aber was genau hast du in der Filmografie geändert. Erkenne da nicht einmal im DiffLink einen Unterschied. Soll nur zur Info sein, damit ich es beim nächsten Mal richtig mache. Grüße, --BlueCücü 21:34, 14. Jan. 2011 (CET)

Ich habe Leerzeichen am Ende der Zeile entfernt. Sie sind nutzlos, daher entferne ich sie. Macht die Versionsunterschiede nicht besser, da reine Leerzeichenänderungen nicht extra markiert werden. Das finde ich auch nicht schön, aber es gibt noch schlimmere Versionsunterschiede aufgrund der Entfernung von Leerzeichen am Satzende. Der Umherirrende 21:46, 14. Jan. 2011 (CET)
Und wie erkennst du beim "umherirren", dass sich Leerzeichen am Ende einer Zeile befinden? Testest du jede Zeile einzeln durch? Oder gibts da ein Helferlein? --BlueCücü 21:56, 14. Jan. 2011 (CET)
Ich habe mir da etwas (nur für den eigenen Gebrauch) geschrieben. Der Umherirrende 21:59, 14. Jan. 2011 (CET)
Bin da nicht so firm. Welche Programmiersprachen müsste man einigermaßen beherrschen, um das zu verstehen? HTML? C++? Delfi? Ich kann nur Excel-Zellen programmieren ;) --BlueCücü 23:33, 14. Jan. 2011 (CET)
Das ist JavaScript, welches dann der Browser ausführt. Es gibt auch auch Benutzer, die ihre Implementierung zum einbinden anbieten: Benutzer Diskussion:TMg/autoFormatter.js, Benutzer:BLueFiSH.as/JS/markup.js oder Benutzer:Codeispoetry/Benutzerscripte#regengine.js. Excel-Formeln sind auch häufig hilfreich, aber hier wird es doch schon schwierig. Der Umherirrende 11:31, 15. Jan. 2011 (CET)

Du hattest als Letzter die Vorlage:Babel field 2 verbessert, und mein Mentee Benutzer:JackCandem hat ein Problem beim Einbinden der Vorlage. Ich habe das leider auch nicht reparieren können, und wollte Dich fragen, ob Du da mal drüber schauen kannst. Danke und Gruß --Pitlane02 disk 16:24, 23. Jan. 2011 (CET)

Das wäre auch vor meiner Bearbeitung nicht gegangen. Es ist nicht gedacht, das man die Felder innerhalb der Vorlage:Babel anlegt, sondern immer auf einer extra Seite, oder man gibt der Vorlage:Babel keinerlei Parameter mit, sondern schreibt sie so darunter. Ich habe mir erlaubt, die Benutzerseite anzupassen. Ich hoffe, das war so in Ordnung. Der Umherirrende 19:29, 23. Jan. 2011 (CET)
Im Namen meines Mentee Danke! --Pitlane02 disk 20:09, 23. Jan. 2011 (CET)
Danke, vielen Danke -- Horkrux 20:10, 23. Jan. 2011 (CET)

Anzahl roter Links

Bezug: deine Antwort auf Fragen zur Wikipedia. Das Verhältnis beträgt also 1,78 Artikelwünsche pro Artikel (2094625/1174500). Das ist interessanterweise fast die gleiche Zahl wie in der englischsprachigen Wikipedia: zwischen Januar 2003 und Januar 2006 schwankte das Verhältnis zwischen 1,6 und 1,9 (vgl. Diomidis Spinellis und Panagiotis Louridas: Why Wikipedia's remarkable growth is sustainable. In: Communications of the ACM. Band 51, Nr. 8, August 2008, S. 68–73, doi:10.1145/1378704.1378720, wenn du auf den Artikel keinen Zugriff hast, kann ich ihr dir gerne mailen, brauchst mir nur per Wikimail deine E-Mail-Adresse zu schicken.) Inzwischen hatte sich aber die Artikelanzahl von 100526 auf 922000 mehr als verneunfacht! (Quelle) Trotzdem blieb das Verhältnis ungefähr konstant. Leider habe ich für die englischsprachige Wikipedia keine aktuelleren Daten. So jetzt kommt meine Bitte: Kannst du die Anzahl der Wunschartikel auch aus dem Dump der englischsprachigen Wikipedia bestimmen? Es wäre sehr spannend zu erfahren, ob auch heute noch diese Konstante in der englischsprachigen Wikipedia existiert. --Ephraim33 15:15, 28. Jan. 2011 (CET)

Ja, das könnte ich mal versuchen. Die Downloadmenge ist aber schonmal 7 mal höher, mal schauen, wie lange das braucht. Soll ich dir die Anzahl der Nicht-Weiterleitung im Artikelnamensraum auch noch mit ausgeben? Die Zahl 922000 kann ich mir gerade nicht erklären, da es ja 3,5 Millionen Artikel auf en.wp gibt. Der Umherirrende 16:07, 28. Jan. 2011 (CET)
922000 ist der Stand 31.12.2005, weil ich das Verhältnis auch nur bis zum Januar 2006 habe, hatte ich blöd aufgeschrieben, sorry. Aktuell müssten es, wie du sagtest, 3,5 Millionen Artikel sein. Zum Downloadmenge: Reicht nicht: "Recombine articles, templates, image descriptions, and primary meta-pages." (6.5 GB) Als Laie würde ich erwarten, dass Diskussions- und Benutzerseiten nicht notwendig sind, oder? --Ephraim33 16:31, 28. Jan. 2011 (CET)
Die Benutzer- und Diskussionsseiten sind nicht nötig, da ich aber den Inhalt der Hilfstabellen (page.sql.gz, pagelinks.sql.gz) nehme, kann ich das nicht unterscheiden. Durch die Hilfstabellen sind es dann nur ca. 4,2 GB und nicht 6,5 GB und das Ergebnis ist genauer, da auch Links durch Vorlagen gezählt werden. Der Download wird wohl einige Stunden dauern, bei 282 KB/s. Der Umherirrende 16:37, 28. Jan. 2011 (CET)
Erstmal die fehlenden Zahlen für de.wp: Weiterleitungen im ANR: 824.262, Artikel im ANR: 1.190.176.
Für die englischsprachigen habe ich die page.sql schon heruntergeladen. En.wp hat 3.558.029 Artikel bei 4.721.190 Weiterleitungen. Der Umherirrende 18:36, 28. Jan. 2011 (CET)
Hat dein Programm schon du Anzahl der Artikelwünsche in der englischsprachigen Wikipedia offenbart? [Ich hoffe die Laufzeit skaliert nur linear mit der Downloadmenge, nicht quadratisch.] --Ephraim33 19:17, 31. Jan. 2011 (CET)
En.wp hat 532.264.073 Links in allen Namensräumen, davon sind 233.969.655 Links innerhalb des ANR. Aufgrund der großen Anzahl, musste ich die Verarbeitung innerhalb meines Programms umschreiben. Daher habe ich leider noch keine Zahl für dich. Bin aber auf guten Wege, das morgen oder übermorgen fertig zu kriegen. Die Laufzeit ist nicht zwar nicht linear, aber zum Glück auch nicht quadratisch, irgendwo dazwischen. Der Umherirrende 22:38, 31. Jan. 2011 (CET)
Ich komme erstmal auf 16.545.469 rote Links, die auf 5.421.543 verschiedene Seiten verlinken. Also ergibt sich 1,52. In den nächsten Tagen oder am Wochenende könnte ich das ganze nochmal prüfen, aber im Moment gehe ich davon aus, das alles seine Richtigkeit hat. Ein guter Beweis dafür, finde ich, ist die generierte Liste der 2000 gewünschten Seiten auf en.wp. Ich hoffe, du kannst mit den Zahlen etwas anfangen. Der Umherirrende 23:24, 1. Feb. 2011 (CET)
Danke, dass du das programmiert hast und auch die zeitaufwändige Abfrage für die englischsprachige Wikipedia gemacht hast. Es ist etwas weniger als ich gedacht hätte, aber so ungefähr in dem Bereich. Man kann ja die Wirklichkeit nicht ändern – außer man verlinkt 271.000 rote Artikel neu ;-) Wie willst du denn eigentlich zitiert werden? Ist dir "Datenbankabfrage vom Benutzer „Umherirrender“, 31. Januar 2011" recht? --Ephraim33 14:44, 2. Feb. 2011 (CET)
Kein Problem. Wenn du mich erwähnen möchtest, schreibe lieber Datenbankauswertung, das trifft es besser, glaub ich. Der Umherirrende 18:09, 2. Feb. 2011 (CET)
Nur zur Doku: Zum Überprüfen habe ich das Programm auch nochmal mit den dewiki-SQL-Dumps laufen lassen und es kommen die Zahlen heraus, die ich auch schon genannt habe. Daher kann ich annehmen, das die Zahlen stimmen. Der Umherirrende 21:07, 3. Feb. 2011 (CET)

Scan

Hi, kannst du mal schauen, ob du auf irgendwelche Benutzerseiten oder Benutzerdisks noch die Codeteile font-color: transparent oder left: - enthalten, wie es z.B. in <div style="left: -50px; position: absolute; top: -50px; font-color: transparent"> enthalten ist? Es geht um versteckten Weblinkspam, wie du vermutlich mitbekommen hast. Ich bin die recentchanges-Einträge durchgegangen, aber ältere Sachen konnte ich so natürlich nicht finden. Merlissimo 16:50, 4. Feb. 2011 (CET)

Reicht dir das auf Basis des letzten Dumps (11.01.2011)? Dann müsste ich zwar noch den meta-current-Dump herunterladen, das sollte aber gehen. Alle Benutzerhauptseiten zu extrahieren und dann jetzt zu exportieren, könnte die Server etwas überlasten, da es wohl 500.000 Seiten (NS2+3) wären. Der Umherirrende 19:33, 4. Feb. 2011 (CET)
Der letzte Dump sollte wohl reichen, da er vom 01.02.11 ist. So schnell waren die ja noch nie … Der Umherirrende 19:42, 4. Feb. 2011 (CET)
Wie gesagt, die recentchanges (=letzten 30 Tage) habe ich gecheckt. Insofern wären beide Dumps absolut ok. Du brauchst eigentlich nur Benutzer(disk)seiten von Benutzer mit < 10 Beiträgen zu checken. Das würde imo reichen. Merlissimo 14:42, 5. Feb. 2011 (CET)
Das du die letzten 30 Tage bereits betrachtet hattest, hatte ich garnicht so mitbekommen. Da ich den Dump von 11.01 ohne die Benutzerseiten hatte, musste ich eh etwas herunterladen, da war egal, welcher. Ich habe mal nach font-color\s*:\s*transparent gesucht. Die Variante mit negativen left muss ich mir noch mal anschauen. Falls du noch ein anderen Regex (Java6-Notation) vorschlagen möchtest, nur zu. Der Umherirrende 17:51, 5. Feb. 2011 (CET)
left\s*:\s*- trifft auch viele, die Dateien "anders" platziert haben. Die Liste ist sehr unübersichtlich (388 Seiten aus 3.360.879 Seiten gesamt über alle Namensräume), daher wollte ich die jetzt nicht veröffentlichen. Der Umherirrende 18:26, 5. Feb. 2011 (CET)
Die Liste war super und ich habe sie auch abgearbeitet. Ich hatte mich noch nicht bedankt, weil ich die Sperren in meinem Log nicht direkt mit der Query in Verbindung bringen wollte. Die Trefferquote war 100% auch wenn einer dabei war, der das wohl nicht kommerziell machte (und somit von der Sperre verschont blieb).
Kannst du die zweite Liste mit den 388 Ergebnissen noch mit der users-Tabelle filtern um nur Benutzerseiten von Benutzer mit maximal zwei Beiträgen zu bekommen? Merlissimo 22:25, 6. Feb. 2011 (CET)
Oh entschuldige, dann war meine Anmerkung unpassend. Ob man den Zusammenhang verbergen muss, kann ich nicht beurteilen, nur habe ich an soetwas nicht gedacht, da ich nie mit soetwas zu tuen hatte. Ich habe das ganze mal auf Benutzerbeiträge <= 2 geprüft. Ich habe nur 44 Benutzer gefunden. Zwei haben nur eigenes css angelegt, ein SUL-Account aus en.wp, und der Rest war bereits von dir und einem anderen Admin gesperrt worden, sowie die Benutzer- und -diskussionsseite gelöscht worden. Somit gibt es mit den Suchkritieren nichts mehr zu tuen. Der Umherirrende 21:05, 7. Feb. 2011 (CET)
Super. Danke. Merlissimo 22:20, 7. Feb. 2011 (CET)

Warum haben Sie meine (217.226.84.66) Änderung verworfen? Seine beiden Bücher sind identisch! Sie stehen bei mir im Bücherschrank. Edgar und ich waren befreundet.

Mit freundlichen Grüßen

Peter Mäurer

--E-Mail-Adresse entfernt--

(täglich wechselnde IP von T-Online)

Hallo, Ihre Änderung wurde von Benutzer:Erika39 zurückgesetzt . Mein Benutzernamen taucht in dem Bearbeitungskommentar nur auf, weil auf meine Version zurückgesetzt wurde (Es war die Version vor Ihrer Bearbeitung), nicht weil ich die Version zurückgesetzt habe. Sie müssten daher beim besagtem Benutzer anfragen. Ich hoffe, ich konnte helfen. Der Umherirrende 19:27, 17. Jan. 2011 (CET)

Danke

Peter Mäurer (nicht signierter Beitrag von 91.12.82.61 (Diskussion) 14:58, 21. Jan. 2011 (CET))

Kannst Du den Quatsch bitte lassen? Das, was Du da schreibst, ist einfach falsch. Die Vorlage dient dazu, Den Baustein automatisch einfügen zu können. Sie wird nicht verlinkt. Schau Dir die Wirkung einfach an beispielsweise dort. Vorlage:Baustelle/preload liefert nicht den Text für die Beschreibung, sondern das, was eingefügt wird. Anka Wau! 21:42, 16. Feb. 2011 (CET)

Du meinst also der Text in Vorlage:Dokumentation/Preloadseite ist schlecht gewählt? Nun, mir viel bei der Anlage nichts bessers ein. Überlicherweise werden solche preloads in der Vorlage verwendet, von der sie ein Unterseite sind, daher hatte ich es so gewählt. Siehe beispielsweise Vorlage:Dokumentation#Unterseiten anlegen. Ich werde mir noch einen anderen Text überlegen. Oder geht es dir darum, das der Baustein jetzt auf der Seite ist? Das würde ich ungerne ändern, den durch den Baustein wird die Vorlage nicht mehr auf Wartungsseiten wie Spezial:Nicht kategorisierte Vorlagen auftauchen. Der Umherirrende 21:49, 16. Feb. 2011 (CET)
Ich weiß nicht, ob er irgendwo passt. Da, wo ich es geprüft habe, jedenfalls nicht. Interessiert mich auch herzlich wenig, sollen die Leute entscheiden, in deren Vorlagen Du den Kram reinschreibst. Hier bitte nicht, denn es ist falsch und bleibt daher bitte draußen. Anka Wau! 21:55, 16. Feb. 2011 (CET)
Ich weiß zwar nicht, warum ein unpassender Text so akut entfernt werden muss, aber ok. Vielleicht gefällt dir mein neuer ja besser. Du kannst ihn übrigens auch ändern. Jetzt müsstes du sie nur noch aus Spezial:Unbenutzte Vorlagen rausbekommen (Was der Baustein mit einem kleinen "Hack" bereits macht), und MerlBot wird morgen auch anschlagen (siehe Vorlage:Vorlagenverwendung notwendig, die in der Kategorie steht), soetwas wie das war bis jetzt noch nicht bedacht und vorgesehen. Der Umherirrende 22:03, 16. Feb. 2011 (CET)

Median der Artikelgröße

Wie groß ist denn derzeit der Median der Artikellänge? Ich würde gern Guldbrandssons Prognose (10.000 Byte) mit der Realität vergleichen. Die Wikipedia-Statistik bietet nur die Durchschnittswerte Bytes pro Artikel (leider nicht den Median), und die auch nur bis November 2009. Kannst du die durchschnittliche Artikellänge und den Median der Artikellänge aus dem Dump herausbekommen? [Ich vermute, dass die durchschnittliche Artikellänge bei etwa 3785 Byte liegt und der Median darunter liegt (vielleicht zwischen 2500 und 3000 Byte).] --Ephraim33 11:13, 15. Feb. 2011 (CET)

Mit allen Seiten im Namensraum 0 (Dump vom 31.01.2011) komme ich auf folgende Zahlen:
Gesamt:
Pages: 2029677
Average: 2822.8951015358602
Median: 1093.0

Nicht-Weiterleitungen:
Pages: 1199312
Average: 4751.402151400136
Median: 2892.0

Weiterleitungen:
Pages: 830365
Average: 37.51560337923684
Median: 32.0
Der Umherirrende 19:43, 16. Feb. 2011 (CET)

Danke! Seltsam: Die Durchschnittslänge ist zwischen November 2009 und Januar 2011 viel stärker gestiegen als früher, von 3634 auf 4751 (um 1117 Byte). Davon brauchte Wikipedia über vier Jahre (von August 2005 bis November 2009) um pro Artikel 1117 Byte zu wachsen. Naja, wenigstens der Median liegt dort, wo ich ihn vermutet habe ;-) --Ephraim33 19:59, 16. Feb. 2011 (CET)

Die durchschnittliche Artikelgröße hatte ich vor einiger Zeit auch auf meta:Small and large wikis/Statistics eingeführt. Merlissimo 20:34, 16. Feb. 2011 (CET)
Dann liege ich mit meinem Ergebnis ja richtig ;-) Interessante Seite, die ich noch nicht kannte. Built-In-Median für MySql scheint es aber nicht zu geben, sonst hätte man das noch ergänzen können. Der Umherirrende 20:41, 16. Feb. 2011 (CET)

Kannst du neben den Weiterleitungen auch die mal testweise die Begriffsklärungen und Falschschreibungen ausblenden? Die inzwischen 341905 BKLs und 3114 Falschschreibungen senken den Durchschnitt und den Median wahrscheinlich signifikant. --Ephraim33 14:03, 17. Feb. 2011 (CET)

Die Zahlen mit PAGESINCAT stimmen nicht ganz, da ich nur 134.214 Seiten so ausschließen konnte (Habe die Kategorieeinträge genommen)
Exclude: 134214
Count: 1065098
Average: 5284.048452818426
Median: 3235.0
Der Umherirrende 21:09, 17. Feb. 2011 (CET)
Danke! Das sind wir also schon auf gutem Wege zu den 10.000 Byte, zwar noch nicht bis 2013, aber vielleicht in zehn Jahren. Die Differenz zwischen PAGESINCAT und den 134.214 Seiten, die du ausschließen konntest, dürfte sich aus dem Datum des Dumps (31.01.2011) und dem heutigen Tag ergeben. --Ephraim33 21:25, 17. Feb. 2011 (CET)

Zur Info

Das ist nicht besonders klug, da das, was in noinclude steht, in den Preload leider mit übernommen wird :-( -- Metalhead 12:10, 18. Feb. 2011 (CET)

Da gibt es offenbar schon einen Bugfix. Sorry, war ein Schnellschuss. Ist also erledigt. -- Metalhead 12:35, 18. Feb. 2011 (CET)
Ja, sonst hätte ich das aber auch nicht gemacht. Trotzdem gut, das jemand aufpasst. Der Umherirrende 18:01, 18. Feb. 2011 (CET)

Nachfrage zu css

Hallo. Deine Idee mit dem css bezüglich der Hervorhebung von Änderungen auf der BEO-Liste gefällt mir sehr, und es klappte auch mit deinem beispiel (FzW). Mit den Seiten, die ich so einfärben möchte, klappt es nicht. Kann es daran liegen, dass dein code nicht bei Unterseiten funktioniert? Siehe Benutzer:-jkb-/vector.css unten. Gruß -jkb- 17:15, 28. Feb. 2011 (CET)

Schau jetzt mal, nu müsste es gehen. Bei den CSS-IDs wird aus '/' anscheinend'_'. --Guandalug 17:20, 28. Feb. 2011 (CET)
Und das "Benutzer:" muss weg. Die beiden "--" sind in Ordnung. Die genauen Regeln für class in CSS kenne ich nicht, aber / scheint nicht dazuzugehören. Ich würde daher immer im HTML-Quelltext nachschauen, aber das ist auch nicht gerade einfach, da der so viel ist. Der Umherirrende 17:24, 28. Feb. 2011 (CET)
Guter Tip: Da hilft für Firefox-Nutzer der 'Firebug' ungemein. Stimmt, Benutzer: muss weg (das hatte ich übersehen bei der Korrektur), das steht ja schon als ns-2 bzw. ns-3 kodiert. --Guandalug 17:27, 28. Feb. 2011 (CET)
//BK// Jetzt aber. Der benutzer musste noch wech. Vielen Dank an beide, Gruß -jkb- 17:28, 28. Feb. 2011 (CET)
P.S. Endlich. Die Seite ...-jkb-_Mentees_D_grossekathöfer wollte nicht, egal was ich machte, bis ich die Idee bekam, den Punkt ebenfalls durch _ zu ersetzen - dann geht es; im Quelltext war es jedoch ein Punkt, was mich irritierte. Also, schönen Rest des Tages, -jkb- 18:14, 28. Feb. 2011 (CET)

Hallo Umherirrender

Wir hatten doch schon mal darüber diskutiert, daß gelegentlich nicht angezeigte BKs zur Löschung eigener Beiträge führen und zwar dann, wenn es sich um den letzten Abschnitt einer Seite handelt. Ein neues Beispiel habe ich soeben erlebt. Ich weiß nicht, ob es da schon einen Bugreport gibt (und wüßte auch kaum, wie man das beschreiben sollte). Was denkst du? --Matthiasb (CallMeCenter) 21:22, 4. Mär. 2011 (CET)

Hallo Matthiasb, hier haben nicht beide mit "section=new" gearbeitet (Erkennbar an der Zusammenfassung, und die Zeile nach der Überschrift fehlt), dann wäre das vermutlich nicht passiert. Hier scheint es aber an WP:Huggle zu liegen, weil es nicht mit section=new zu arbeiten scheint. Bearbeitungskonflikte wird es vermutlich generell auch nicht erkennen oder auflösen können. Der Umherirrende 21:49, 4. Mär. 2011 (CET)
Ich hatte auf neuer Benutzervandalismus (oder wie das heißt, mag nicht nachschauen) geklickt, also über die Preloadvorlage die Meldung abgefaßt. Wenn mein "Kontrahent" mit Huggle arbeitet, und das der Hauptgrund wäre, dann wäre das ein unschöner Bug in Huggle. --Matthiasb (CallMeCenter) 22:48, 4. Mär. 2011 (CET)

Warnsystem: AdT nicht aktuell → Eintrag auf WP:ADT, welcher der am weitesten vorbereitete ist

Hallo Umherirrender, ich fand deinen Edit in der Versionsgeschichte der Bearbeitungshinweise. Gibt es vllt. einen Kniff, mit dem der Text hinter Vorbereitete Wochentage: bis einschließlich auf WP:ADT immer das Datum + Wochentag anzeigen kann, das der „von jetzt an spätesten“ Wochentags-Vorlage entspricht, bei der nach Einbindung editiert wurde? Ggf. reicht auch allein die Anzeige des Wochentags auf WP:ADT, falls das Umrechenen dann-Wochentag → Datum nicht geht oder alles zu kompliziert machen würde.

Natürlich kann das System auch irren i.S.v. stumm bleiben, wenn ein Edit, der nicht aktualisiert, nach HS-Einbindung erfolgt. Aber i.d.R. passiert das nicht, auch werden die Wochentag fortlaufend akt., also nicht erst Sa und dann am nächsten Tag die Fr-Vorlage. Die „manuelle“ Prüfung bleibt natürlich immer und wird vmtl. auch nie über werden, aber hiermit könnte eben ein bisschen mehr Energie dafür frei werden :-)

Es eilt btw nicht, kannst es als langfristige Anfrage sehen. Gruß, ggis 01:57, 2. Mär. 2011 (CET)

Der Edit hatte mir schon einiges an Nerven gekostetet ;-), aber ich finde ihn immer noch sehr hilfreich. Zumindestens hat man einen ersten Indiz. Wenn allerdings jemand zwischendurch eine Bearbeitung tätigt, dann funktioniert das auch nicht, aber das kann man nicht überprüfen, das passiert ja auch sehr selten.
Nun zu deiner Frage: Leider ist es nicht möglich, den Zeitpunkt der letzten Bearbeitung einer anderen Seite mit der Vorlagenprogrammierung in Erfahrung zu bringen (Bug 6092). Es ist nur von der eigenen Seite möglich. Leider, denn wenn das gehen würde, bräuchte es Kategorie:Wikipedia:Hauptseite/Artikel des Tages/alt/Kategorie:Wikipedia:Hauptseite/Schon gewusst/alt auch nicht. Ansonsten könne man auch die Kästen auf WP:ADT mit rotem Rand versehen, wenn sie noch nicht aktualisiert wurden (fände ich ganz nett), aber leider gehts es nicht. Für jede Seite eine Kategorie und dann mit PAGESINCATEGORY ist auch keine schöne Methode. Tut mir Leid, zum jetztigen Zeitpunkt nicht umsetzbar. Der Umherirrende 20:13, 2. Mär. 2011 (CET)
Schade schade, lt. Bug-Disk gibt es sogar erheblichen Bedarf. Danke für die Auskünfte. Schönen Rosenmontag (wie nach Geschmack :-) ggis 02:52, 7. Mär. 2011 (CET)

Frage

Könntest du bei Wikipedia:Bots/Anfragen#Kategorie:DEFA mithelfen? --77.9.177.191 20:06, 12. Mär. 2011 (CET)

Wenn es um Kategorie-Leerung geht, dann könnte das auch auf WP:KWS eingetragen werden. Ist vermutlich schneller und sauberer (bekannter Prozess). Ich kann da leider nicht helfen. Der Umherirrende 20:11, 12. Mär. 2011 (CET)

Hallo Umherirrender!

Kannst du vielleicht hier helfen? --knopfkind 21:49, 12. Mär. 2011 (CET)

Hallo knopfkind, ich hoffe, so gefällt es. Der richtige Ort wäre WP:Vorlagenwerkstatt gewesen. Der Umherirrende 22:51, 12. Mär. 2011 (CET)
vielen dank für deine hilfe :) und werde ich mir fürs nächstes mal merken. ich war durch zwiebelleders kommentar ("dich an die Autoren zu wenden") und weil du grad on warst auf dich gekommen ;) viele grüße --knopfkind 23:05, 12. Mär. 2011 (CET)
Aso, und dabei waren meine Änderungen nur kleine Wartungen ;-) --Der Umherirrende 23:09, 12. Mär. 2011 (CET)

Identische Datei

Hallo Umherirrender, wie hast Du das herrausgefunden? Grüße --Brackenheim 12:28, 12. Mär. 2011 (CET)

Hallo Brackenheim, die Diskussion zum Thema findest du unter Wikipedia Diskussion:WikiProjekt Commons-Transfer#Duplikate von bzw. in engl. WP. Ich habe die Datenbanken der deutschsprachigen Wikipedia mit der englischsprachigen Wikipedia verglichen (weitere Wikis werden folgen, denke ich). In der entsprechenden Datenbanktabelle für die Dateien gibt es ein Feld, welches einen Hashwert der Datei beinhaltet. Wenn der Hashwert und die Bildgröße, sowie der MIME-Type identisch sind, dann kann man mit sehr hoher Sicherheit sagen, das es sich um das identische Bild handelt. In der genannten Diskussion wurde dann angeregt ein entsprechenden Baustein zu bauen. Ich bin gerade dabei ihn in die Dateien einzubinden. Der Umherirrende 12:52, 12. Mär. 2011 (CET)
Danke! Die Diskussion hatte ich übersehen... Warum hast Du Deine Benutzerunterseite wieder geleert? Könntest Du nicht so etwas in der Art wie das hier erstellen? Oder habe ich wieder etwas übersehen? Grüße --Brackenheim 16:41, 12. Mär. 2011 (CET)
Schau mal in Kategorie:Datei:Identisch. Dort werden sie alle gelistet. Hat auch den Vorteil das man einen sichtbaren Hinweis anbringen kann, damit auch die unregelmäßigen Commons-Verschieber das sehen. Meine Unterseite ist immer nur zum online stellen von Ergebnissen und wird von mir daher regelmäßig mit anderem Inhalt gefüllt. Die Weiterbearbeitung der Listen kann sich dann jeder selber organisieren. Die von dir verlinkte Bot-Liste wird regelmäßig aktualisiert, das werde ich nicht leisten können. Ich kann nur in unregelmäßigen Abständen gucken können, ob auf den verschiedenen Projekten Dateien hochgeladen wurden, die auch hier existieren. Der Umherirrende 16:47, 12. Mär. 2011 (CET)
Die Zeitabstände der Aktualisierung sind ja nicht so wichtig - besser unregelmäßig, als auf den Service verzichten zu müssen ;-) Mit der Liste wolle ich eigentlich nur nach einem „Weg“ fragen, wie ich die neue Wartungskategorie füllen kann... Wie hast Du die Datenbanken verglichen? --Brackenheim 16:59, 12. Mär. 2011 (CET)
Die Wartungskategorie fülle ich gerade. Ich habe mir die SQL-Dumps von dewiki und enwiki heruntergeladen. Speziell handelt es sich um die Datenbanktabelle image. Dann habe ich erst alle dewiki-Dateien in den Arbeitsspeicher geladen und dann mit den enwiki-Dateien verglichen, wobei das ganze einmal für die Dateien mit einem Zeitstempel früher enwiki und später enwiki. Abschließend habe ich die beiden Liste auf Vorlage:NoCommons, Vorlage:NowCommons und Vorlage:DÜP geprüft, weil die so gekennzeichnete Dateien hier bleiben oder bereits auf Commons sind. Ich hoffe, das ist verständlich erklärt. Für Toolserver-Leute dürfte das vermutlich noch einfacher sein und Sie könnten mit Live-Daten arbeiten. Der Umherirrende 17:07, 12. Mär. 2011 (CET)
Ganz schön großer Aufwand - Danke! (auch für die Erklärung...) --Brackenheim 17:35, 12. Mär. 2011 (CET)
Ja, ist schon etwas Aufwand, aber es macht mir auch Spaß, daher ist es nicht so schlimm. Ist ja außerdem für eine gute Sache. Der Umherirrende 18:35, 12. Mär. 2011 (CET)

Bei Datei:Zebrafinken.jpg und wohl weiteren Dateien mit nachfolgenden Uploads ist die Quelle gerade die andere. Aber das lässt sich wohl nicht einfach ändern… --Leyo 11:03, 16. Mär. 2011 (CET)

Ja, das ist etwas schwieriger zu erkennen, da ich nur mit der aktuellen Dateiversion zu tuen habe. Ich denke aber, das ich das in Zukunft mit berücksichtigen kann und bei diesen Dateien etwas genauer hinschauen werde. 101 der aktuell mit Vorlage:Datei identisch markierten Dateien, haben mehr als eine Dateiversion. Ich glaube aber, das die meisten Dateiversionen sehr zeitnah hintereinander hochgeladen wurden und so ein Fall wie dein Beispiel nicht so häufig ist. Aber trotzdem danke für den Hinweis. Der Umherirrende 21:20, 16. Mär. 2011 (CET)
Dass es etwas schwieriger ist, kann ich mir gut vorstellen. Naja, ist auch nicht so schlimm. Übrigens: Ich habe es schon etliche Male gesehen, dass offensichtlich mehrmals hintereinander dieselbe Datei hochgeladen wurde. Ein Filter, der erkennt neue Version = alte Version, wäre doch auch was. :-) --Leyo 17:47, 17. Mär. 2011 (CET)
Ja, das war mir auch aufgefallen, aber ich hatte das immer nur bei sehr alten Dateien gesehen und noch nicht bei neuen Dateien. Ich werde das am Wochenende mal ausprobieren. Sinn macht es ja nicht. Bei Versionen bekommt MediaWiki das ja auch hin. Der Umherirrende 19:57, 17. Mär. 2011 (CET)

Offlineparser

Lieber Umherirrender, nun bin ich schon über eine Menge Seiten gekommen auf der Suche nach einer, wo ich meine Frage loswerden kann, aber so richtig hat es nirgends gepaßt, auch nicht auf MediaWiki: Gibt es einen Standalone-Offline-Parser, für den es nicht nötig ist die ganze Suite mit Datenbankanbindung p.p. zu installieren; einfach ein PHP-Skript, das WikiText in validen HTLM-Code übersetzt? Nur um beispielsweise zu sehen, wie eine Tabelle aussieht und ähnliches, ohne sich immer auf der WP:Spielwiese rumtreiben zu müssen.

Gruß, Friz -- 77.186.165.29 12:12, 18. Mär. 2011 (CET)

Wenn ich hier mal einfach antworten darf: Der Parser, den MediaWiki (derzeit) verwendet, ist ziemlich komplex. Den eigenständig ans Laufen zu bekommen erfordert vermutlich einen ganzen Haufen Arbeit, weshalb das (meines Wissens) noch keiner wirklich in Angriff genommen hat. Es gibt Gerüchte, dass man an einem neuen Parser arbeitet (mal wieder) - ob DER dann aber offline-tauglich wird, steht auf einem anderen Blatt. --Guandalug 12:15, 18. Mär. 2011 (CET)
Danke für die schnelle Antwort, Guandalug. :( Gruß, Friz -- 77.186.165.29 12:21, 18. Mär. 2011 (CET)
Das Problem beim offline ist, das dann keine Vorlagen ausgewertet werden können. Ich empfehle für solche Sachen Spezial:Vorlagen expandieren oder einfach die Vorschau jeder beliebiger Seite, vielleicht auch in einem lokalen Wiki auf dem eigenen Rechner. Den Parser nachzuprogrammieren stell ich mir auch schwierig vor, da man den dann erstmal verstanden haben muss, da er sehr komplex ist. Ich glaube, das noch nicht viele Leute den (kompletten) Parser bis jetzt verstanden haben. Der Umherirrende 16:18, 18. Mär. 2011 (CET)
Das Problem mit "einem lokalen Wiki auf dem eigenen Rechner" ist ja doch wohl eine Vollinstallation mit 'Xamp' oder dergl. und das nur um zu sehen, ob Tabellen und Zeilenumbrüche richtig dargestellt werden. Small is beautiful, isn´t it? Wär halt schön gewesen, wenn es sowas gäbe, aber hatte ich schon befürchtet, daß es sowas nicht gibt; würde aber die Server entlasten. ;-) Gruß, Friz -- 77.186.165.29 22:05, 18. Mär. 2011 (CET)

<math>-Renderung

Lieder Herumirrender, verstehst Du warum der Code:

Es seien <math>a=1,\ b=2,\ c=3,\ d=4</math> und <math>e=5</math>.

dies hier:

Es seien und .

ergibt, bei Zwangsrenderung aber:

Es seien und .

der Ausdruck zu tief steht? Gruß, Friz -- 77.186.142.252 08:06, 21. Mär. 2011 (CET)

Mit Tex habe ich noch nicht viel gemacht. Eine kurze Suche hat mir auch keinen Anhaltspunkt gegeben. Du könntest es auf Hilfe Diskussion:TeX versuchen, da dürften einige Benutzer mitlesen, die sich damit auskennen. Tut mir Leid. Der Umherirrende 17:28, 21. Mär. 2011 (CET)
Der Grund ist die fehlende "Unterlänge", die durch die Kommata eingeführt werden. Eine Altenative:
.
Eine andere:
Es seien und .
Dann muss man halt den Rest des Satzes umformulieren ... :D --Guandalug 17:34, 21. Mär. 2011 (CET)
Lieber Guandalug, bei mir funktioniert Altenative A gut, B dagegen nicht: ist klein & sehe dabei das Komma. Danke, Friz -- 77.186.142.252 20:05, 21. Mär. 2011 (CET)
Ich würde folgende Darstellung ohne erzwungenes Rendering wählen:
Es seien , , , und .
Dabei sind die Kommas auch semantisch korrekt nicht als Teil der Formel, sondern als Teil der Aufzählung im Satz ausgezeichnet. --Fomafix 20:28, 21. Mär. 2011 (CET)
Lieber Fomafix, Deine Variante wird bei mir nicht gerendert. :·o Friz 77.188.7.211 08:21, 22. Mär. 2011 (CET)
Das ist auch sinnvoll, denn erzwungenes Rendering ist unerwünscht. --Fomafix 09:00, 22. Mär. 2011 (CET)
Lieber Umherirrender, habe Deinen Rat befolgt und die Frage auf Hilfe Diskussion:TeX nochmals (Fauxpas?) gepostet. Dort hat Fomafix eine Möglichkeit mit style="vertical-align:top" dargestellt. Wenn man von den nicht korrekten Kommata absieht, ist das das, was ich mir vorgestellt habe:
Es seien und .   Danke, Friz 77.188.5.15 08:57, 25. Mär. 2011 (CET)

Ist diese Kategorie nicht überflüssig, wenn es doch für die großen Wikipedien extra Kategorien gibt? SteMicha 23:42, 27. Mär. 2011 (CEST)

Nein, die Kategorie:Datei:Identisch mit Kopie in anderem Projekt umfasst die Dateien, die in andere Projekte kopiert wurden (Also ist der Hochladezeitpunkt hier früher als auf dem anderem Projekt). Die Kategorien für die Sprache umfassen die Dateien, die von einem anderem Projekt nach hier kopiert wurden (Hochladezeitpunkt hier ist später als im anderem Projekt). Der Hochladezeitpunkt bezieht sich immer auf die letzte Dateiversion, das führt aber nur bei sehr wenigen Dateien zur falschen Einsortierung. Der Umherirrende 16:38, 28. Mär. 2011 (CEST)

Hallo Umherirrender,

du hattest mir dort geantwortet, vielen Dank dafür. Als Technik-Null habe ich dort noch eine Nachfrage gestellt. Könntest du hier oder dort nochwas zu meiner Erhellung beitragen?

Ganz liebe Grüße, --Drahreg01 16:45, 30. Mär. 2011 (CEST)

Antwort dort. Der Umherirrende 20:15, 31. Mär. 2011 (CEST)

API-Analyse Benutzersperren

Hallo Umherirrender, du hattest Anfang 2009 mal dankenswerterweise eine API-Analyse von infiniten Benutzersperren gegen stimmberechtigte Accounts durchgeführt. Diese Daten sind in die Sperrtabelle eingegangen, die seitdem aber nicht mehr systematisch ergänzt wurde. Aktuell wird ein Meinungsbild zum Thema vorbereitet, für dessen sachliche Diskussion eine aktuelle Datenbasis wertvoll wäre. Könntest du daher den Staub von deinen Skripten pusten, und die API-Abfrage mit unveränderten Parametern noch einmal fahren? Abfragezeitraum sollte der Einfachheit halber 01. Januar 2009 bis heute sein. Die seit deiner letzten Analyse eingeführte Verschärfung der Stimmberechtigung (50 Edits in einem beweglichen Zeitfenster von einem Jahr Dauer) könntest du zugunsten der Vergleichbarkeit mit den Ergebnissen davor ignorieren. Was denkst du? --Minderbinder 09:36, 28. Mär. 2011 (CEST)

Kann ich mir am Wochenende anschauen. Ich denke, das ich das alte Skript noch irgendwo habe und wieder verwenden kann. Der Umherirrende 16:39, 28. Mär. 2011 (CEST)
Super, vielen Dank. Wenn du Ergebnisse hast, kannst du die direkt unter meiner Ankündigung einstellen, amn besten wohl als Unterseite. Ich gehe davon aus, dass die Daten noch kräftig von Hand nachbearbeitet werden müssen, aber das übernehmen wir dann. --Minderbinder 18:58, 28. Mär. 2011 (CEST)
Ich erinnere mich gerade, das ich bei der Aktualisierung der allgemeinen Tabelle Anfang dieses Jahres die Benutzerliste bereits verlinkt hatte. Die Liste für 2009 hatte ich Anfang 2010 erstellt. Ich weiß aber nicht, ob die dort bereits vollständig eingearbeitet wurde. Falls 2009 eingearbeitet ist, und die Liste für 2010 zur Verfügung steht, fehlt dann noch was? Falls ja, einfach Bescheid geben, schaue ich mir dann am Wochenende an. Der Umherirrende 19:08, 28. Mär. 2011 (CEST)
Blunt sagt dort, dass 2009 eingearbeitet ist. Also würde wohl 2010 und das erste Quartal von 2011 reichen. Vielen Dank vorab! --Minderbinder 13:27, 29. Mär. 2011 (CEST)
2010 ist oben verlinkt, für das erste Quartal 2011 kann ich das ganze aber noch nachliefern. Wenn ich das am Wochenende mache, nehme ich den 31. März als Stichtag, ist ja dann auch Quartalsende. Der Umherirrende 19:22, 29. Mär. 2011 (CEST)
Im ersten Quartal 2011 gibt es 39 unbegrenzt gesperrte Konten, die mehr als 200 Artikelbearbeitungen haben und dessen erste Bearbeitung mehr als 2 Monate zurück liegt. Der Umherirrende 14:52, 2. Apr. 2011 (CEST)

Hinweis zu Adminvorschlägen

Moin! Es hat dich offensichtlich niemand darauf hingewiesen, dass hier eine kleine Abstimmung läuft, die deinen Hinweis auf deiner Benutzerseite ignoriert. Hier noch eine Diskussion dazu. Viele Grüße, NNW 20:34, 4. Apr. 2011 (CEST)

Hallo. Danke für deinen Hinweis. Da Leyo meine erste Adminkandidatur initiiert hat, vertraue ich ihm bei diesem Eintrag. Ich sehe meine Chancen zwar aktuell nicht viel besser als damals, da sich mein Arbeitsgebiet nicht sehr verändert hat, aber ich bin mit einem solchen Eintrag einverstanden. Der Umherirrende 20:37, 5. Apr. 2011 (CEST)
Ich sehe gerade, dass der Eintrag gestern mit Hinweis auf deine BS schon entfernt wurde. Soll ich ihn wieder einfügen? Tut mir leid mir dem Hin und Her. NNW 20:41, 5. Apr. 2011 (CEST)
Kein Problem. Geht ja nichts verloren. Setze am besten ein Permalink. Der Umherirrende 20:56, 5. Apr. 2011 (CEST)
Ich habe die Stimmen wieder eingesetzt, da hier die Zustimmung zu Vorschlägen abgegeben werden soll. Dafür ist eine Liste geeigneter als ein Permalink. NNW 09:50, 6. Apr. 2011 (CEST)
Ich wollte den Eintrag dort nutzen, um die Chancen besser ausloten zu können. Meiner Meinung nach hättest du bestimmt guten Chancen, wenn man das Laudatio besser formulieren würde als ich es das letzte Mal getan hatte. Falls du grundsätzlich zu einer erneuten AK bereit bist, kann ich mich gelegentlich nochmals daran versuchen. :-( --Leyo 21:17, 5. Apr. 2011 (CEST)
Das Problem sehe ich eher darin, das die Community aktuell nur Admins haben möchte, die ein (sehr) weites Spektrum der Admintätigkeit abdecken können. Ich habe Verständnis dafür, das ein Benutzer nicht umbedingt Artikel löschen sollte, wenn er nicht selber welche geschrieben hat. Und da diese Arbeit ein Großteil ausmacht, hat das bei vielen ein gewisses Gewicht in der Abstimmung. Alles nachvollziehbar.
Danke für dein Angebot, aber aktuell habe ich noch kein Interesse. Ich werde mich aber bei Zeiten dran erinnern. Der Umherirrende 21:31, 5. Apr. 2011 (CEST)
In der ersten AK vor drei Jahren hast du die Wahl mit 58 % Pro zu 42 % Contra nur knapp verpasst. Es müsste in der Laudatio natürlich klar werden, wofür du die Adminrechte benutzen würdest (Bearbeiten von vollgeschützten Vorlagen, MediaWiki-Seiten, Einsicht in gelöschte Versionen, ggf. Löschen von Dateien nach Commons-Transfer, ggf. Direkthilfe bei Skins, …) und vor allem wofür nicht (Entscheiden von Artikel-LAs, Sperren von Benutzern). Dann stünden deine Chancen IMHO gut. --Leyo 09:55, 6. Apr. 2011 (CEST)

Zählen ist schwer …

… und dass ich es manchmal nicht kann, hast du ja schon herausgefunden. Immerhin komme ich jetzt auf Zahlen in der gleichen Größenordnung wie du, was mich schon einmal beruhigt. Was mich sehr irritiert, und weswegen ich dich frage, ob du plausiblere Zahlen hast, ist die Anzahl der Bilder mit px. Gezählt habe ich sie als /\|[\s\dx]+px\s*[\|\]]/ innerhalb der gefundenen Bilder. Oder haben wir inzwischen so viele Artikel mit irgendwelchen kleinen Symbolen, die nicht durch eine Vorlage eingefügt werden? --Schnark 09:51, 18. Apr. 2011 (CEST)

Ich wollte keinen bloßstellen ;-). Ich bin mir bei meinen Zahlen auch nicht immer sicher, da die Datenbasis einfach zu groß ist, und man es daher nicht so einfach nachvollziehen kann. Mit meinem ausgedachten Regex komme ich auf 572.561 Dateieinbindungen mit px, die sich aber nur auf 145.678 verschiedenen Seiten befinden, ich kann mir vorstellen, das vor allem Listenartikel dabei sind, die mit Flaggenbilder ausgestattet sind, oder so (man weiß nie, was die Autoren so machen). Dabei habe ich (genauso wie vorher) nur den Artikelnamensraum betrachtet. Ich hoffe, das hilft dir. Alles ohne Gewähr. Der Umherirrende 21:02, 18. Apr. 2011 (CEST)
Wenn wir jetzt auf so ähnliche Zahlen kommen, werden sie wohl stimmen. Da ich stur alle Seiten analysiert habe, sind bei meinen Zahlen insbesondere die Portale dabei, wo pixelgenaue Formatierungen durchaus häufiger zu erwarten sind. Falls mir mal ganz langweilig werden sollte, werde ich weitere Nachforschungen anstellen. --Schnark 10:30, 19. Apr. 2011 (CEST)
Im gesamtem Dump dewiki-20110322-pages-articles.xml komme ich auf 671.866, wenn du den alle-Seiten-Dump hast, könnte deine höhere Zahl stimmen, da gebe ich dir recht. Der Umherirrende 19:53, 19. Apr. 2011 (CEST)

Versionslöschung

Nachfrage: Der Uploader hatte seinen Klarnamen beim Upload des Bildes angegeben und der Uploader Account trug ebenfalls seinen Klarnamen. Wie hätte man dies anders lösen können als über eine Versionslöschung? Groetjes --Neozoon 16:15, 30. Apr. 2011 (CEST)

Es gibt ja zwei Möglichkeiten der Versionslöschung: Einmal alles löschen und die besagte Version nicht wiederherstellen oder per RevisionDelete (So heißt es technisch) nur Teile der Dateiversion verstecken. Das wird dann durchgestrichen dargestellt, wie auch die erste Version in der Versionsgeschichte der Dateien. Da das durchstrichen aber nicht für die aktuelle Dateiversion funktioniert, ist das vorgehen in diesem Fall egal gewesen. Dein Reupload war eh notwendig, ob man jetzt sieht, das nur eine Dateiversion oder doch zwei Dateiversionen mal da waren, ist egal. Hier hat sich der Admin für das andere entschieden, was auch vollig in Ordnung ist. Der Umherirrende 17:26, 30. Apr. 2011 (CEST)

Danke für deine Erläuterung Groetjes --Neozoon 19:41, 30. Apr. 2011 (CEST)

API

Hallo Umherirrender,

du hast mir mal sehr mit der Api geholfen [1]. Wärst du bereit mir – als so eine Art "Mentor" – gelegentlich Nachhilfe in API-Abfragen zu geben?

Unter Benutzer:Drahreg01/API habe ich zwei Abfragen hinbekommen (da bin ich schon ganz stolz). Zeigst du mir in der Dokumentation die Stelle, die mir erklärt, wie ich diese Abfrage kombiniere? Also: „Zeige Artikel (ns=0), die auf beiden Listen stehen.“

Liebe Grüße, --Drahreg01 10:44, 14. Mai 2011 (CEST)

Ja, du kannst mich gerne fragen bezüglich API-Abfragen.
Ich befürchte aber, dass in diesem Fall ein Tabellenkalkulationsprogramm deiner Wahl die Arbeit am besten übernimmt, da mir keine Möglichkeit bekannt ist, die zwei Ergebnisse zu filtern/kombinieren. Eine andere Abfrage kenne ich auch nicht, da man sich nicht zu jedem Link von einer Seite die darauf verlinkten Seiten anzeigen lassen kann. Tut mir Leid. Der Umherirrende 15:38, 14. Mai 2011 (CEST)
Das ist schade. Trotzdem vielen Dank für dein Hilfeangebot. Ich hatte noch Ideen zu komplexeren Abfragen. Vermutlich müsste man sich dazu Skripte schreiben, was mich endgültig überfordert. Falls ich noch mal deine Hilfe brauche, wende ich mich an dich. Viele Grüße, --Drahreg01 17:30, 14. Mai 2011 (CEST)

meine Vorlage

Hey! Kannst du dich vielleicht um mein Anliegen in der Vorlagenwerkstatt kümmern. Ich wäre dir sehr dankbar. -- Dr. Knauff 11:41, 28. Mai 2011 (CEST)

Hallo, du bist mit dem Entwurf der Infobox schon sehr weit, nur fehlt dir die tatsächliche Umsetzung, sodass man sie auch verwenden kann. Ich selber kümmere mich aber eher um das Beheben von bestehenden Problemen mit Vorlagen, als das ich eine neue Vorlage erstelle. Falls du es selber versuchen möchtest, gibt es Wikipedia:WikiProjekt Vorlagen/Anleitung: Erstellen einer Infobox. Ich denke aber das sich in der nächsten Woche sicher jemand finden wird, der die Anfrage bearbeitet, ansonsten schaue ich mir das am nächsten Wochenende an. Der Umherirrende 13:38, 28. Mai 2011 (CEST)
Danke dir. Ich habe ja mein Anliegen in der Werkstatt hinterlegt. Ich warte lieber, dass sich ein Erfahrender damit beschäftigt. Ich glaube, in Wiki-Anleitungen lesen und verstehen, bin ich nicht gut. -- Dr. Knauff 13:54, 28. Mai 2011 (CEST)

Diff #1: Visualize space-only differences

Objective: The current standard diff function doesn’t show space-only differences. Readers find identical black text and may guess that the reason is a superfluous space character somewhere, or perhaps a period changed into a comma?

Example for visualized space difference:

old: The old  lady looks  confused.
new: The young girl looks confused.
The old lady looks▯▯confused. The young girl looksconfused.
  • Make space-only differences visible, including heading/trailing space.
  • Enable reader to count number of spacing characters.
  • Don’t confuse reader with space-▯ if there are visible changes: If one of the adjacent words is already red, space difference is negliable.
  • Show not only different number of spacing characters, but also varying types (currently only: ASCII Space U+0020 and HorTab U+0009, but there are many more spaces like U+2004-200A).

The following code enables wikidiff2 to make this visible. Performance is not remarkable influenced, since the diff algorithm is not touched. Only if any difference was already found, displaying the result is improved.


Word.h

Insert:

   bool equals_suffix(const Word &w) const {
      // True iff this and other word w suffixes are literally equal
      return (suffixEnd - bodyEnd == w.suffixEnd - w.bodyEnd)
             & std::equal(bodyEnd, suffixEnd, w.bodyEnd);
   }   // equals_suffix()
   size_t get_suffixlength() const {
      return (suffixEnd - bodyEnd);
   }   // get_suffixlength()

(BTW: should be Word.cpp.h indicates to simple minded fellows like me a declarative header file, no implementation expected. #include accepts any file name and won't care about a file extension – but I do.)

wikidiff2.cpp

Insert:

   #define SPAN_INLINE "<span class=\"diffchange diffchange-inline\">"
   #define SPACE_DIFF "&#x25AF;"
   void Wikidiff2::printWordDiffSideBlack(
                   const DiffOp<Word>::PointerVector current,
                   const DiffOp<Word>::PointerVector others,
                   const bool lastBlack,
                         String & word) {
      // Print a block of words in black, but possibly with space diffs.
      // The last black word before a red one is indicated by lastBlack.
      size_t k;
      const size_t n = current.size();
      const size_t meet = (lastBlack ? n-1 : n+1);
      Word & item;
      for (size_t j = 0;  j < n;  j++) {
         item = current[j];
         if (j == meet) {
            item->get_whole(word);
            printText(word);
         } else {
            if (item->equals_suffix(others[j])) {
               item->get_whole(word);
               printText(word);
            } else {   // space diff
               k = item->get_suffixlength();
               // may be limited to a certain number of spaces
               if (k == 0) {   // last word in line
                  item->get_whole(word);
                  printText(word);
               } else {
                  printText(item->String());
                  result += SPAN_INLINE;
                  for (size_t i = 0;  i < k;  i++) {
                     result += SPACE_DIFF;
                  }   // for i
                  result += "</span>";
               }
            }
         }
      }   // for j
   }   // printWordDiffSideBlack()

printWordDiffSideBlack() needs to be declared in wikidiff2.h also.

Replace at begin of printWordDiffSide():

   DiffOp<Word> & op;
   DiffOp<Word>::PointerVector current;
   DiffOp<Word>::PointerVector others;
   String word;
   const size_t nw = worddiff.size();
   const size_t nwb = nw - 1;
   const size_t nwb2 = nw - 2;
   size_t n, j;
   bool lastBlack;
   for (size_t i = 0; i < nw; ++i) {
      op = worddiff[i];
      if (op.op == DiffOp<Word>::copy) {
         lastBlack = (i < nwb);
         if (added) {
            current = op.to;
            others = op.from;
         } else {
            current = op.from;
            others = op.to;
         }
         if (lastBlack) {
            switch (worddiff[i+1].op) {
               case DiffOp<Word>::copy :
                  lastBlack = false;
                  break;
               case DiffOp<Word>::del :
                  if (added) {
                     if (i < nwb2) {
                        lastBlack = (worddiff[i+2].op == DiffOp<Word>::copy);
                     } else {
                        lastBlack = false;
                     }
                  }
                  break;
               case DiffOp<Word>::add :
                  if (! added) {
                     if (i < nwb2) {
                        lastBlack = (worddiff[i+2].op == DiffOp<Word>::copy);
                     } else {
                        lastBlack = false;
                     }
                  }
                  break;
               case DiffOp<Word>::change :   // skip
            }   // switch
         }
         printWordDiffSideBlack(current, others, last, word);
      } else if (!added && (op.op == DiffOp<Word>::del ||


This code has been written from scratch, never compiled (might be completed somewhere by * or &). Even worse: not tested. But I checked it carefully; should work.

Open Issue: Leading whitespace is currently not present in worddiff[]. If the improvement above is basically adopted, there are two solutions to integrate this feature:

  1. Modify explodeWords() and don't skip heading break. This requires a Word with bodyStart=bodyEnd=0. That might confuse the operators and String(), Diff algorithm could be disturbed.
  2. Provide printWordDiffSide() with both text1 and text2. If worddiff[0].op==DiffOp::copy visualize heading spaces, if any and different, and continue with loop.

My SONY credit card ID is PerfektesChaos@de.wikipedia – enjoy. --PerfektesChaos 23:52, 29. Apr. 2011 (CEST)

Sleeping over my last edit I made a slight improvement. --PerfektesChaos 20:42, 1. Mai 2011 (CEST)
still pondering --PerfektesChaos 22:04, 16. Mai 2011 (CEST)
Dieser Abschnitt kann archiviert werden. PerfektesChaos 18:07, 19. Jun. 2011 (CEST)

Diff #2: Visualize non-ASCII spaces

If visualization of space-only differences (#1) is adopted, the methodology might be extended to other types of space.

Objective: Other spaces shall be treated like ASCII space. This goes for both word-splitting and displaying of modification.

Affected unicodes:

2002;EN SPACE
2003;EM SPACE
2004;THREE-PER-EM SPACE
2005;FOUR-PER-EM SPACE
2006;SIX-PER-EM SPACE
2007;FIGURE SPACE
2008;PUNCTUATION SPACE
2009;THIN SPACE
200A;HAIR SPACE

Looking into the existing code, I found no point to place this feature into the procedure. Moreover, I was quite confused and got the impression that there has been a longer history of amendments. The resulting state seemed to be not very efficient. Therefore I decided to rewrite the entire explodeWords() business heading for a more clear and accelerated execution.

Programming changes:

wikidiff2.cpp

Replace functions:

// Split a string into words
void Wikidiff2::explodeWords(const String & text, WordVector &words)
{
   const String::const_iterator pE = text.end();
   String::const_iterator p = text.begin();
   // Don't try to do a word-level diff on very long lines
   if (text.size() > MAX_DIFF_LINE) {
      words.push_back(Word(p, pE, pE));
      return;
   }
   String::const_iterator chStart;
   String::const_iterator suffixStart;
   String::const_iterator wordStart;
   wchar_t ch;
   unsigned char b;
   bool livingSuffix = false;
   bool livingWord = false;
   bool locateSuffix;
   while (p < pE) {
      chStart = p;
      locateSuffix = false;
      b = (unsigned char)*p;
      if (b < 0xC0) {   // ASCII or undefined
         if (b < 0x21) {
            locateSuffix = (b == 0x20 || 0x09);   // some more ...
         }
      } else {   // UTF range
         ch = nextUtf8Char(p, b, pE);
         if (ch > 0x0E00) {   // could be interesting
            if (ch < 0x0EFC) {   // Thai
               explodeWordSuffix(livingWord, wordStart, livingSuffix, suffixStart, chStart, words);
               wordStart = chStart;
               explodeWordsThai(ch, p, pE, words, wordStart);
            } else if (ch >= 0x2002 && ch <= 0x200A) {   // spaces
               locateSuffix = true;
            } else if (ch >= 0x1100 && ch <= 0x11FF ||
                       ch >= 0x2E80 && ch <= 0x9FFF ||
                       ch >= 0xAC00 && ch <= 0xD7AF ||
                       ch >= 0x20000 && ch <= 0x2FA1F) {   // CJK
               explodeWordSuffix(livingWord, wordStart, livingSuffix, suffixStart, chStart, words);
               wordStart = chStart;
               words.push_back(Word(chStart, p, p));
            }
         }
      }
      if (locateSuffix) {
         if (! livingSuffix) {
            suffixStart = chStart;
            livingSuffix = true;
         }
      } else if (livingSuffix) {
         explodeWordSuffix(livingWord, wordStart, livingSuffix, suffixStart, p, words);
      } else (! livingWord) {
         wordStart = chStart;
         livingWord = true;
      }
      ++p;
   }   // while (p < pE)
   explodeWordSuffix(livingWord, wordStart, livingSuffix, suffixStart, pE, words);
}   // explodeWords()

void Wikidiff2::explodeWordSuffix(bool & livingWord,
                                  const String::const_iterator wordStart,
                                  bool & livingSuffix,
                                  const String::const_iterator suffixStart,
                                  const String::const_iterator wordNext,
                                  WordVector & words)
{
   // Add word body and suffix interval to words, if any; reset living
   if (livingWord) {   // regular word pending
      if (wordStart < wordNext) {
         words->push_back(Word(wordStart, (livingSuffix?suffixStart:wordNext), wordNext));
      }
   } else if (livingSuffix) {   // append to previous CJK or Thai word
      if (! words->empty()) {   // not the beginning of the line
         words->pop_back();
         words->push_back(Word(wordStart, suffixStart, wordNext);
      }
   }
   livingWord = false;
   livingSuffix = false;
}   // explodeWordSuffix()

void Wikidiff2::explodeWordsThai(wchar_t ch,
                                 String::const_iterator & p,
                                 const String::const_iterator pE,
                                 WordVector & words,
                                 String::const_iterator & wordStart)
{
   // Pointing on thai character sequence and add particular thai words
   IntVector thaiBreakPositions;
   std::vector<int, WD2_ALLOCATOR<const_iterator> > charPtrs;
   String tisText;
   String::const_iterator pT = p;
   int nBreaks;
   size_t max = (pE - p) / 2 + 3;
   thchar_t thaiChar = (char)th_uni2tis(ch);
   unsigned char b;
   charPtrs.reserve(max);
   tisText.reserve(max);
   charPtr.push_back(wordStart);
   tisText = thaiChar;
   while (pT < pE) {
      b = (unsigned char)*pT;
      if (b == 0xC0) {
         ch = nextUtf8Char(p, b, pE);
         thaiChar = (char)th_uni2tis(ch);
         if (thaiChar >= 0x80 && thaiChar != THCHAR_ERR) {
            p = pT;
            tisText += thaiChar;
            charPtrs.push_back(p);
            pT++;
         } else {
            break;   // while
         }
      } else {
         break;   // while
      }
   }   // while (pT < pE)
   tisText += '\0';
   nBreaks = tisText.size();
   thaiBreakPositions.resize(nBreaks);
   nBreaks = th_brk((const thchar_t*)(tisText.data()), &thaiBreakPositions[0], nBreaks);
   for (int i = 0; i < nBreaks; i++) {
      pT = charPtrs[ thaiBreakPositions[i] ];
      words.push_back(Word(wordStart, pT, pT));
      wordStart = pT;
   }   // for i
}   // explodeWordThai()

wchar_t Wikidiff2::nextUtf8Char(String::const_iterator & p,
                                unsigned char b,
                                const String::const_iterator pE)
{
   // Weak UTF-8 decoder
   // Will return garbage on invalid input (overshort sequences, overlong sequences, etc.)
   // but Mediawiki never provides bad UTF-8 texts ...
   short seqLength = 0;
   wchar_t c = 0;
   while (p < pE) {
      if (b < 0x80) {
         c = b;
         seqLength = 0;
      } else if (b >= 0xC0) {
         // Start of UTF-8 character
         // If this is unexpected, due to an overshort sequence,
         // we ignore the invalid sequence and resynchronise here
         if (b < 0xE0) {
            seqLength = 1;
            c = b & 0x1F;
         } else if (b < 0xF0) {
            seqLength = 2;
            c = b & 0x0F;
         } else {
            seqLength = 3;
            c = b & 7;
         }
      } else if (seqLength) {
         c <<= 6;
         c |= b & 0x3F;
         --seqLength;
      } else {
         // Unexpected continuation, ignore
      }
      ++p;
      if (! seqLength) {
         break;   // while
      }
   }   // while (p < pE)
   return c;
}   // nextUtf8Char()

The code is faster now, since:

  • The loop over all characters is run just once.
  • Thai sequence is investigated only if there are really Thai characters in text; more than 99 % of edits won't contain them.
  • Even if there is a Thai string only that particular sequence is broken into words.
  • UTF-8 analysis is started if UTF-8 encoding really starts, not for every plain English ASCII letter.
  • "inline" functions of just one line integrated, nowhere else used.

I think the procedure is much more clearly arranged now, enabling further changes and reducing future efforts in extending (after fixing minor problems with this not yet tested suggestion, I'm afraid).

  • CJK recognition is extended.
  • Non-ASCII spaces are used for word separation.

Implementations should be moved into Wikidiff2.cpp,

  • const Wikidiff2::String & Wikidiff2::getResult() const
  • not needed by any #include of Wikidiff2.h would be then:
    • bool Wikidiff2::isChineseJapanese(int ch)
    • bool Wikidiff2::isSpace(int ch)

Unfortunately I don't have a site to do full testing in thai environmment. --PerfektesChaos 20:42, 1. Mai 2011 (CEST)

spelling checked --PerfektesChaos 17:05, 4. Mai 2011 (CEST)
still pondering --PerfektesChaos 22:04, 16. Mai 2011 (CEST)
Dieser Abschnitt kann archiviert werden. PerfektesChaos 18:07, 19. Jun. 2011 (CEST)

Diff #3: Visualize zero-width differences

Objective: There are modified words where the modification keeps invisible, since a zero-width character has been added or removed. The user encounters two red words without any visible difference.

Affected unicodes:

  • 00AD;SOFT HYPHEN   &shy;
  • 200B;ZERO WIDTH SPACE
  • 200C;ZERO WIDTH NON-JOINER   &zwnj;
  • 200D;ZERO WIDTH JOINER   &zwj;
  • 200E;LEFT-TO-RIGHT MARK   &lrm;
  • 200F;RIGHT-TO-LEFT MARK   &rlm;
  • 202A;LEFT-TO-RIGHT EMBEDDING
  • 202B;RIGHT-TO-LEFT EMBEDDING
  • 202C;POP DIRECTIONAL FORMATTING
  • 202D;LEFT-TO-RIGHT OVERRIDE
  • 202E;RIGHT-TO-LEFT OVERRIDE

Example (invisible characters shown as HTML entities):

old: Meaning&shy;less to &rlm;change&lrm; direction.
new: Meaningless to change direction.
Meaningless to change direction. Meaningless to change direction.

The users have no clue why these words are red, give’em one:

Meaning▯less to ▯change▯ direction. Meaningless to change direction.

Any red word is affected. Also deleted and added lines are considered – that doesn’t help much, but some users might learn the first time that they are carrying spooky characters.

Programming changes:

wikidiff2.cpp

Replace function calls for printText() but keep the current implementation within the new suggestion printWordDiffSideBlack() – best solution would be renaming current printText() into printTextBlack():

void Wikidiff2::printTextRed(const String & text)
{
   // HTML source code in UTF-8, general colour red, zero-width chars
   const String::const_iterator pE = text.end();
   String::const_iterator p = text.begin();
   size_t i = 0;
   size_t j = 0;
   size_t k = 0;
   wchar_t ch;
   unsigned char b;
   while (p < pE) {
      b = (unsigned char)*p;
      j++;
      if (b < 0xC0) {   // ASCII or undefined
         if (b == 0x26 || b == 0x3D) {   // & <
            k = j;
            j--;
         }
      } else {   // UTF range
         ch = nextUtf8Char(p, b, pE);
         if (ch == 0xAD ||
             ch >= 0x200B && ch <= 0x200F ||
             ch >= 0x202A && ch <= 0x202E) {
            k = j + (ch < 0x0800 ? 1 : 2);
            j--;
         }
      }
      if (k) {
         if (j > i) {
            result.append(text, i, j - i);
         }
         if (b == 0x26) {
            result.append("&amp;");
         } else if (b == 0x3D) {
            result.append("&lt;");
         } else {   // UTF
            result.append(SPACE_DIFF);
         }
         i = k;
         j = k;
         k = 0;
      }
   }   // while (p < pE)
   if (j > i) {
      result.append(text, i, j - i);
   }
}   // printTextRed()

The same story goes for invalid Unicodes U+007F-009F. They result mainly from Windows codepage (like CP-1250/1252) and won’t be displayed at all by many browsers, best case by a replacement character. Can be captured easily above, since everything > U+007E is bad UTF and UTF starts at U+00C0.
--PerfektesChaos 17:05, 4. Mai 2011 (CEST)

still pondering --PerfektesChaos 22:04, 16. Mai 2011 (CEST)
Dieser Abschnitt kann archiviert werden. PerfektesChaos 18:07, 19. Jun. 2011 (CEST)

Diff #4: Improve modified consecutive lines

Objective: The line based algorithm makes minor corrections in consecutive lines appear as a dramatic change.

Example:

previous line small modification …whaffle… …blah…   …Blah… …Whaffle… change little following line
previous line minor modification …whaffle… …blah… added line …Blah… …Whaffle… change slighty following line

results currently in:

previous line previous line
small modification

…whaffle…

…blah…
 
…Blah…

…Whaffle…

change little
 
  minor modification

…whaffle…

…blah…
  added line
  …Blah…

…Whaffle…

change slighty
following line following line

This shall be made more readable by an improved algorithm:

previous line previous line
small modification

…whaffle…

…blah…
minor modification

…whaffle…

…blah…
  added line
…Blah…

…Whaffle…

change little
…Blah…

…Whaffle…

change slighty
following line following line

Background: Line comparison algorithms have been developed in the 1970s. Due to the size of a punched card no program line was longer than 80 characters. This gives meaningful results when detecting modified and unchanged sections of lines.
However, wikitext lines (I would like to call them ‘paragraphs’ here) may consist of 1000 characters and more, containing several sentences in human language. Any slight change, even a single space, makes the entire paragraph to be ‘changed’. The line comparison algorithm needs to skip over this and looks for the next recovering point with absolute identity.

Suggestion:

  1. Split long lines by insertion of 'virtual' breaks.
  2. Run the diff engine as is (cheat by virtual lines).
  3. Analyze the result and merge adjacent virtual lines.
  4. Display the differences based on the original paragraphs.

The following rules illustrate how splitting is to be performed. Figures like 100 and 250 are just clarifying the envisioned size, they are set by #define and may be chosen as desired.

  • If a line is longer than 250 bytes
    • search a possible position for breaking
      • start at byte 100
      • look for ". " (period+space, \x2E\x20)
      • if remaining length is longer than 100 bytes
        • insert virtual break
    • if remaining length is longer than 250 bytes
      • start at byte 100 of the remainder as above

The choice of period+space for a break point is conducted by the following assumption: A long paragraph is quite likely written in human language. If the author reformulates something, the entire sentence might have been subject to modification. The following sentence is kept unchanged, hopefully. A common separator in human languages is the period and a space; period might have another meaning (e.g. abbreviation) but doesn’t matter. There are many other ways to terminate a sentence in various human languages, but we won’t look for them for the sake of simplicity and speed of the program.

If the method was successfully implemented, this might be extended to U+3002 in CJK as well as detection of exclamation or question marks.

Splitting yields to

previous line small modification …whaffle… …blah… …Blah… …Whaffle… change little following line
previous line minor modification …whaffle… …blah… added line …Blah… …Whaffle… change slighty following line

The result of the diff engine is an amalgamated sequence of parts, containing the original from and to as well as a code op as follows:

  • copy
    Entire part absolutely unchanged.
No change. No change.
  • change
    Number of parts between two neighbouring copy chunks unchanged and content differs.
Something modified. Something changed.
  • del
    Count of parts between neighbouring copy chunks differs and another content; from has the greater number and this is attached to from while to is null.
Deleted paragraph.  
  • add
    Count of parts between neighbouring copy chunks differs and another content; to has the greater number and this is attached to to while from is null.
  Added paragraph.

The example above results in the traditional diff engine output:

from previous line¶ small modification …whaffle… …blah…¶ …Blah… …Whaffle… change little null null null following line¶
to previous line¶ null null minor modification …whaffle… …blah…¶ added line …Blah… …Whaffle… change slighty following line¶
op copy del del add add add copy

Following the suggested insertion of virtual line breaks the recovering points were found:

from previous line¶ small modification♣ …whaffle…♣ …blah…¶ null …Blah…♣ …Whaffle…♣ change little following line¶
to previous line¶ minor modification♣ …whaffle…♣ …blah…¶ added line …Blah…♣ …Whaffle…♣ change slighty following line¶
op copy change copy copy add copy copy change copy


This leads to the following rules for merging of virtual line breaks, showing any possible combination of op codes:

Engine result Reconstruction
op[i] from[i] to[i] op[i+1] op[i] op[i+1] Remark join
copy
change
hard hard any keep Skip
Regular procedure
0
del null
add null hard
copy virtual virtual copy keep Remove Merge entire [i] with successor [i+1]
from[i]=from[i]+from[i+1]
to[i]=to[i]+to[i+1]
Then Remove [i+1]
1
else change
change any
del null del keep
else change
add null virtual add keep
else change
copy
change
hard virtual copy
change
del
del change to[i+1]=to[i]+to[i+1]
to[i]=null
2
add add
virtual hard copy
change
add
add change from[i+1]=from[i]+from[i+1]
from[i]=null
del del

Example for merging hard and virtual line break:

Before reconstruction
# op from to
i copy Virtually terminated sentence. Virtually terminated sentence.
i+1 del Deleted line of any termination … null
i+2 any And now … … something completely different.
After reconstruction
# op from to
i change Virtually terminated sentence. Deleted line of any termination … Virtually terminated sentence.
i+1 any And now … … something completely different.

Note that from and to lines with the same op code are finally merged into line arrays by diff engine.


Programming changes:
(For definite implementation see code suggestions in context of trailing whitespace.)

Line.cpp
Similar to Word.cpp (formerly known as Word.h) as new file. Replace String-based line diff by Line objects.

printAdd(), printDelete(), printTextWithDiv() or their calls need to be transferred from String to Line and/or Line.getString(). These print methods might be renamed into printLineAdd, printLineDelete, printLineWithDiv analogous to already existing printWord*. This applies also to the unique call of printWordDiff().

wikidiff2.h

Discard:

typedef std::vector<String, WD2_ALLOCATOR<String> > StringVector;
typedef Diff<String> StringDiff;

Add:

#include Line.cpp
typedef std::vector<Line, WD2_ALLOCATOR<Line> > LineVector;
typedef Diff<Line> LineDiff;

Implementation merged into whitespace trailing --PerfektesChaos 22:04, 16. Mai 2011 (CEST)

Dieser Abschnitt kann archiviert werden. PerfektesChaos 18:07, 19. Jun. 2011 (CEST)

Diff #5: Avoid confusion by empty lines

Objective: If an “empty line” (maybe with some invisible content) has been inserted or removed by the author and the adjacent paragraphs are modified in some way, the presentation of the result is currently disturbed.

Currently:

previous line previous line
small modification  
change little  
  minor modification
   
  change slighty
following line following line

This could be remedied as:

previous line previous line
small modification minor modification
   
change little change slighty
following line following line

Solution: The method is already in effect for Word objects:
Administrate

  • a suffix: spaces between last visible character and line termination (if virtual break identified by period+space there is a suffix of at least one space)
  • trailing lines: after hard break any further paragraph without any visible content (ASCII spaces and \t for the moment, might be extended later to invisible Unicode)

As currently performed for Word strings compare the visible body of Line only in the DiffEngine.

Postprocess the Line objects for reconstruction of the original paragraphs, if there are any changes.


Programming changes:
(based on the virtual line concept)

Line.cpp
This new class (similar to existing Word) administrates virtual lines, trailing whitespace (and empty lines) and records the original paragraph numbers.

#ifndef LINE_CPP
#define LINE_CPP

#include <string>
#include <algorithm>
// algorithm -- why?
#include "wikidiff2.h"

// a small class to accomodate lines with hard and virtual termination
// basically, the pointers and a marker indicating the termination type
//
// This class stores iterators pointing to the text string, this is to avoid
// excessive allocation calls. To avoid invalidation, the source string should
// not be changed or destroyed.
class Line {
public:
   typedef std::basic_string<char, std::char_traits<char>, WD2_ALLOCATOR<char> > String;
   typedef String::const_iterator Iterator;

   Iterator bodyStart;
   Iterator bodyEnd;
   Iterator suffixEnd;
   Iterator trailingEnd;
   bool hard;
   size_t number;

   /**
     * The body is the character sequence [bs, be)
     * The space suffix is the character sequence [be, se), none if se=be
     * A \n break is indicated by hard;  false for virtual break
     * Trailing empty lines after hard break is [se, te), none if te=se
     * The suffix is at least a "\n" for hard breaks
     *     and one space if virtual break detected by ". "
     *     suffix is empty at end of text.
     * The number is the line number in original \n counting
     */
   Line(Iterator bs, Iterator be, Iterator se, Iterator te, size_t n)
      : bodyStart(bs), bodyEnd(be), suffixEnd(se), trailingEnd(te), number(n)
   {
      // \n break or end of text
      hard = true;
   }
   Line(Iterator bs, Iterator be, Iterator se, size_t n)
      : bodyStart(bs), bodyEnd(be), suffixEnd(se), number(n)
   {
      // virtual line
      hard = false;
      trailingEnd = be;
   }

   bool operator== (const Line &o) const {
      return (bodyEnd - bodyStart == o.bodyEnd - o.bodyStart)
         && std::equal(bodyStart, bodyEnd, o.bodyStart);
   }
   bool operator!=(const Line &o) const {
      return !operator==(o);
   }
   bool operator<(const Line &o) const {
      return std::lexicographical_compare(bodyStart, bodyEnd, o.bodyStart, o.bodyEnd);
   }
   operator String() const {
      return String(bodyStart, suffixEnd);
   }

   bool is_HardBreak() const {
      // true: \n      false: virtual
      return hard;
   }   // is_HardBreak()

   bool equals_aftermath(const Line &o) const {
      // True iff this and other line o suffixes and trailer are equal
      if (trailingEnd == bodyEnd) {
         return (o.trailingEnd == o.bodyEnd);
      }
      return (trailingEnd - bodyEnd == o.trailingEnd - o.bodyEnd)
              & std::equal(bodyEnd, trailingEnd, o.bodyEnd);
   }   // equals_aftermath()
   bool equals_suffix(const Line &o) const {
      // True iff this and other line o suffixes are literally equal
      if (suffixEnd == bodyEnd) {
         return (o.suffixEnd == o.bodyEnd);
      }
      return (suffixEnd - bodyEnd == o.suffixEnd - o.bodyEnd)
              & std::equal(bodyEnd, suffixEnd, o.bodyEnd);
   }   // equals_suffix()

   size_t get_lineNumber() const {
      return number;
   }   // get_lineNumber()
   String get_paragraph() const {
      // Retrieve body+suffix; this may be empty
      if (bodyStart) {
         return String(bodyStart, suffixEnd);
      }
      return String();
   }   // get_paragraph()
   size_t get_trailingCount() const {
      // Retrieve number of empty trailing lines; this may be empty
      size_t n = 0;
      if (bodyStart) {
         if (trailingEnd > suffixEnd) {
            Iterator p = suffixEnd;   // '\n' before suffixEnd
            Iterator pE = trailingEnd - 1;   // before '\n' or text end
            unsigned char b;
            while (p < trailingEnd) {
               if (b == 0x0A) {
                  n++;
               }
               p++;
            }   // while
         }   // trailing exists
      }   // bodyStart
      return n;
   }   // get_trailingCount()

   void merge_withPredecessor(const Line o) {
      bodyStart = o.bodyStart;
   }
   void merge_withSuccessor(const Line o) {
      bodyEnd = o.bodyEnd;
      suffixEnd = o.suffixEnd;
      hard = o.hard;
      trailingEnd = o.trailingEnd;
   }

};   // class Line


#endif


wikidiff2.h

Reserve space for line number headers once only.

class Wikidiff2 {
#ifndef NOLINENUMBERS
   private:
      char scratch256[256];
#endif


wikidiff2.cpp

The following algorithm might replace explodeLines(). It identifies virtual lines, trailing whitespace (and empty lines) and records original paragraph numbers.

void Wikidiff2::explodeLines(const String & text,
                             LinesVector & lines)
{
   const String::const_iterator pE = text.end();
   String::const_iterator p;
   String::const_iterator pB = text.begin();
   String::const_iterator pH;
   String::const_iterator pV;
   String::const_iterator pS;
   String::const_iterator pT;
   size_t k = 1;
   size_t keep = 1;
   unsigned char b;
   while (pB != pE) {
      pH = std::find(pB, pE, '\n');
      if (pH == string::npos) {   // end of text
         pH = pE;
      }
      while (pH - pB > LINELENGTHVIRTUAL) {
         pV = std::find(pB + LINELENGTHMIN, pH, ". ");
         if (pV == string::npos) {
            break;   // while
         } else {
            pS = ++pV;
            while (pS != pE) {
               b = (unsigned char)*pS;
               if (b == 0x20) {   // or other invisibles
                  pS++;
               } else {
                  break;   // while
               }
            }   // while
            if (pH - pS > LINELENGTHMIN) {
               lines.push_back(Line(pB, pV, pS, keep));
               pB = pS;
            } else {
               break;   // while
            }
         } else {   // not found
            break;   // while
         }
      }   // while  pH - pB > LINELENGTHVIRTUAL
      pS = pH;
      p = pH;
      while (p > pB) {
         p--;
         b = (unsigned char)*p;
         if (b == 0x20) {   // or other invisibles
            pS = p;
         } else {
            break;   // while
         }
      }   // while suffix
      pT = pH;
      if (pH != pE) {
         p = ++pH;
         while (true) {
            p++;
            if (p == pE) {
               pT = pE;
               break;   // while
            } else {
               b = (unsigned char)*p;
               if (b > 0x20) {   // may be other invisibles (Unicode)
                  break;   // while
               } else if (b == 0x0A) {
                  pT = p + 1;
                  k++;
               }
            }
         }   // while trailing
      }   // within text
      lines.push_back(Line(pB, pS, pH, pT, keep));
      k++;
      keep = k;
      pB = pT;
      if (pB != pE) {
         ++pB;
      }
   }   // while  pB != pE
}   // explodeLines()


Recovering the hidden invisible lines and invisible trailing whitespace changes needs quite a lot of simple decisions but won’t impair performance. Hiding lines on the other hand makes comparison faster and requires less objects for invisible and empty lines. Outcome will pay off.

void Wikidiff2::showContext(const LineDiff & block,
                            const int numContextLines,
                            const bool leadCell,
                            const bool lastCell)
{
   // Print block of copy lines with same visible content
   // but possible trailing whitespace and empty lines.
   size_t i;
   size_t j;
   size_t join = 0;
   size_t nBlock = block.from.size();
   IntVector display = IntVector.resize(nBlock);
   for (j = 0; j < nBlock; j++) {   // whitespace changes
      if (block.from[j].equals_aftermath(block.to[j])) {
         display[j] = 0;
      } else if (! block.from[j].equals_suffix()) {
         display[j] = 4;
         for (i = j - 1; i; i--) {
            if (block.from[i].is_HardBreak()) {
               break;   // for i
            }
            display[i] = 4;
         }   // for i
         for ( ; j < nBlock; j++) {
            if (block.from[j].is_HardBreak()) {
               break;   // for i
            }
            display[i] = 4;
         }   // for j
      } else {   // difference in trailing empty lines
         display[j] = 2;
      }
   }   // for j
   if (! leadCell) {   // trailing
      for (j = 0; j < numContextLines; j++) {
         if (j == nBlock) {
            break;   // for j
         } else if (display[j]) {
            break;   // for j
         } else {
            display[j] = 1;
            join = j;
         }
      }
   }
   // blocks with whitespace change are marked now
   for (j = join; j < nBlock; j++) {   // context for whitespace change
      if (display[j]) {
         join = j;
         i = (display[j] == 2 ? 1 : 0);
         for ( ; i < numContextLines; i++) {
            j--;
            if (! j) {
               break;   // for i
            } else if (display[j]) {
               break;   // for i
            }
            display[j] = 1;
         }   // for i
         for ( ; join < nBlock; join++) {
            if (! display[join]) {
               break;   // for join
            }
         }   // for join
         j = join;
         for (i = 0; i < numContextLines; i++) {
            if (j == nBlock) {
               break;   // for i
            } else if (display[j]) {
               break;   // for i
            }
            display[j] = 1;
            j++;
         }   // for i
      }
   }   // for j
   if (! lastCell) {   // heading
      j = nBlock;
      for (i = 0; i < numContextLines; i++) {
         if (j) {
            j--;
            if (display[j]) {
               break;   // for i
            }
            display[j] = 1;
         } else {
            break;   // for i
         }
      }   // for i
   }
   // display contains now markers for all context or changed whitespace
   for (j = 0; j < nBlock; j++) {
      if (display[j]) {
         for ( ; j < nBlock; j++) {
            if (! display[j]) {
               break;   // for j
            }
         }   // for j
         i = 0;
         if (j) {
            if (block.from[j-1].is_HardBreak()) {
               i = 1;
            }
         }
         for (join = j; join < nBlock; join++) {
            if (block.from[join].is_HardBreak()) {
               i++;
               if (i > 1) {
                  break;   // for join
               }
            }
            if (display[join]) {
               break;   // for join
            }
         }   // for join
         if (i < 2) {   // fill small gap between partial context
            for ( ; j < join; j++) {
               display[j] = 1;
            }   // for j
         } else {   // large gap
            j = join;
         }
      }
   }   // for j
   // display contains now markers for all parts to be visualized
   for (j = 0; j < nBlock; j++) {
      switch (display[j]) {
         case 0:   // invisible
            break;
         case 1:   // context (white)
#ifndef NOLINENUMBERS
            sprintLineNumber(block.from[j].get_lineNumber(),
                             block.to[j].get_lineNumber());
#endif
            // fall thru
         case 2:   // change (trailing empty lines)
            i = display[j];
            join = j;
            for (++j; j < nBlock; j++) {
               if (! display[j] || display[j] > 2) {
                  break;
               }
            }   // for j
            while (join < j) {
               printContextCell(block.from, nBlock, j, &join);
            }   // while join < j
            j--;
            if (i) {   // change (trailing empty lines)
               printTrailers(block.from, block.to, nBlock, j, &join);
            }   // just context
            break;
         case 4:   // change (whitespace suffix)
            printCellDiff(block.from, block.to, nBlock, j, &join);
            break;
      }   // switch display[j]
   }   // for j
}   // showContext()


#ifndef NOLINENUMBERS
void Wikidiff2::sprintLineNumber(const size_t from, const size_t & to)
{
   snprintf(scratch256, 256,
            "<tr>\n"
            "  <td colspan=\"2\" class=\"diff-lineno\"><!--LINE %u--></td>\n"
            "  <td colspan=\"2\" class=\"diff-lineno\"><!--LINE %u--></td>\n"
            "</tr>\n",
            from, to);
}   // sprintLineNumber()
#endif


void Wikidiff2::printContextCell(const Line * context,
                                 const size_t n,
                                 const size_t jMax,
                                 size_t * join)
{
   // Print paragraph for context from <td ...</td>, return next line ID
   size_t j;
   size_t k;
   result += "<tr>\n"
             "  <td class=\"diff-marker\"> </td>\n"
             "  <td class=\"diff-context\"><div>";
   for (j = *join; j < jMax; j++) {
      result += (String)context[j];
      if (context[j].is_HardBreak()) {
         k = j;
         break;   // for j
      }
   }   // for j
   result += "</div></td>\n"
             "  <td class=\"diff-marker\"> </td>\n"
             "  <td class=\"diff-context\"><div>";
   for (j = *join; j < k; j++) {
      result += (String)context[j];
   }   // for j
   result += "</div></td>\n</tr>\n";
   *join = k;
}   // printContextCell()

(some more code for presenting the results still in pipeline, will be added soon)

Inserting temporary break here--PerfektesChaos 22:04, 16. Mai 2011 (CEST)

Dieser Abschnitt kann archiviert werden. PerfektesChaos 18:07, 19. Jun. 2011 (CEST)

Diff #6: Improve visualization of context lines

Objectives: Currently any kind of line is displayed when two lines preceding or following shall give an impression of the unchanged context where a changed block is located.

  1. If one or both of these lines are empty they are put into HTML source but invisible and not informative.
  2. If these lines are very long (sometimes each 1000 bytes and more), both paragraphs are displayed anyway, making the output lengthy and hard to survey.

The suggested code has a slightly different behaviour:

  1. The most adjacent non-empty (visible) lines will be shown.
  2. Not two paragraphs but the next two virtual lines (each expected of at least 100 bytes if not full paragraph) will be displayed.

Coding is already integrated in suggestions above.

  • Another idea: context \n could be represented as <br />
  • Are line numbers still meaningful? They are common when comparing lines of source code, but the wiki author hasn’t a clue where line 57 may be located, and some lines have 3000 characters, others just 15 (scrollbar position doesn’t help).

--PerfektesChaos 22:04, 16. Mai 2011 (CEST)

Dieser Abschnitt kann archiviert werden. PerfektesChaos 18:07, 19. Jun. 2011 (CEST)

Datei identisch

Dein Skript oder was du auch immer verwendest um zu überprüfen, ob zwei Dateien in zwei Projekten identisch sind, ist fehlerhaft: Datei:Satellit Chisinau 01.jpg wurde hier bereits 2004 hochgeladen, in ru:wp erst 2010, und dort wurde auch explizit de:wp als Quelle angegeben. Trotzdem hast du die Datei in die Kategorie "Quelle ru:wp" eingetragen, was ja offensichtlich falsch ist. 88.130.215.151 19:30, 18. Jun. 2011 (CEST)

Mein Skript hat immer den Zeitstempel der aktuellen Dateiversion genommen, da auch diese Version für die Prüfung der Gleichheit genutzt wurde. In diesem Fall hat der Benutzer erst in der ru.wp und dann hier die neue Datei hochgeladen, daher kommt es zu einer falschen Zuordnung. Dies war auch schonmal bei einer anderen Datei aufgefallen, ich bin aber davon ausgegangen, das es nicht viele Dateien betrifft und habe daher das ganze nicht geändert. Falls du (oder ein Mitlesender) meint, das sollte ich nochmal tuen, dann würde ich mir das natürlich anschauen und die markierten Dateien überprüfen. Sagt Bescheid. Der Umherirrende 17:40, 19. Jun. 2011 (CEST)
Ich habe das mal heute abend bearbeitet und 10 Dateien gefunden und diese angepasst. Bei über 1.800 Einbindungen ist das aber nur der erwartete Bruchstück. Eine Fehlerrate von unter 1 % halte ich für akzeptabel. Der Umherirrende 00:30, 26. Jun. 2011 (CEST)

Diff: Improve in 2011

Die nachstehend skizzierte Entwicklung wurde im April 2011 angestoßen vom Umherirrenden.
Sie ist mit Ende Mai 2011 umgezogen nach Mediawiki und wird dort weitergeführt.
Ich hatte gehofft, dass das seltsame Geschehen auf dieser Disku, die vielleicht von Techies mitgelesen und gelegentlich aufgesucht wird, Mitstreiter anlocken würde.
Weiterhin sind Anregungen, Kommentare und Mitarbeit willkommen.
--PerfektesChaos 09:24, 30. Mai 2011 (CEST)
Danke für deine Bemühungen. Ich hatte nicht gedacht, das sie solche Ausmaße annimmt, da ich nur eine einfache Frage gestellt habe. Ich habe deinen Text gelesen und finde auch, das es Schritte in die richtige Richtung sind, aber leider kann ich dir bei der Umsetzung nicht viel helfen, da die Algorithmen mir fremd sind. Toole Arbeit, was sicher einige Stunden gekostet hat. Bleib dran, ich würde mich sehr freuen, wenn es dir gelingt, die neue Version auf den WMF-Wikis freigeschaltet zu bekommen. Der Umherirrende 20:23, 30. Mai 2011 (CEST)
Ich bin letztens auf Bug 5072 und Bug 29385 gestoßen. Gehört irgendwie in das Thema hier, finde ich, daher poste ich die mal, vielleicht ist das ja was für dich. Der Umherirrende 17:35, 19. Jun. 2011 (CEST)
Danke für die Info.
Du kannst mir mit deinem Account einen großen Gefallen tun: Poste doch mal im aktuell laufenden Bug 29385 die Mediawiki→WikidiffLX und wir schauen mal, was da so passiert.
Liebe Grüße --PerfektesChaos 18:07, 19. Jun. 2011 (CEST)
Ich habe mal Kommentar 3 hinterlassen. Es ist einfach dort ein Account zu eröffnen, du brauchst nur eine E-Mail-Adresse die du halb-öffentlich nennen möchtest (halb-öffentlich, da angemeldete Benutzer diese sehen können). Ich würde die Diskussionsseite auf MediaWiki noch anlegen, mit einem kurzen Hinweis, das du dich über Kommentare freust, eine vorhande Seite lädt mehr zum hinterlassen von Abschnitten ein, als wenn sie nicht da ist. Der Umherirrende 19:03, 19. Jun. 2011 (CEST)
Ja , danke schön, für’s Posten und sonst.
Weder mag ich meine E-Mail irgendwo sichtbar machen, noch irgendwo Gaga-Accounts mit forwarder anlegen (ich bin auch nicht bei facebook).
Die Disku lege ich gleich an, danke für die Erinnerung. Es war heute abend etwas plötzlich gekommen; wenn ich Zeit und Nerven habe, teste ich das neue Programm lokal auf dem PC aus und war noch nicht auf aktive Weltöffentlichkeit eingestellt.
Schönen Abend --PerfektesChaos 19:25, 19. Jun. 2011 (CEST)
Das ist auch jedem selber überlassen, nur ist mir aufgefallen, das im Entwicklungsbereich von MediaWiki viel mit E-Mail passiert (neben den Bugs auch andere Mailinglisten, Notifier and so on). Eine "Gaga"-Adresse habe ich auch, aber kein forwarder, so wichtig können die Mails nicht sein.
Zum überraschend: Ich wollte das nur hier notieren, sonst habe ich es vergessen, du hättest dir mit dem Antworten Zeit lassen können ;-) Der Umherirrende 20:13, 19. Jun. 2011 (CEST)
Kommentar 5 ließt sich nach schlechten Neuigkeiten für dein Anliegen (rewrite), aber nur nicht aufgeben. Der Umherirrende 20:06, 20. Jun. 2011 (CEST)
Ich hatte das schmunzelnd zur Kenntnis genommen: Zum einen halte ich die ASCII-Art beim Bugzilla für ungeeignet für eine komplexe Aktion wie diese, des Weiteren kommt mir der ganze Bugzilla wie ein Hühnerhaufen oder Chat-Room vor, um den sich richtige Entwickler ohnehin nicht scheren, und schließlich beabsichtige ich mit Empfehlung von Raymond an die höheren Chargen heranzutreten. Aus den binnen Minuten erfolgenden Kommentaren schloss ich, dass die beiden Chatter nichts gelesen, geschweige denn begriffen hatten; insbesondere nicht merkten, dass der Code längst geschrieben wurde und bei mir schon lokal läuft. Krinkle wird sich freuen, dass man ihm seinen vor knapp einer Woche eröffneten Erinnerungszettel (reminder) einfach so wieder zugemacht hat; der Schließende versucht sich unter den Top10 der Report-Resolved an die Spitze zu arbeiten. Krinkle ist einer der nächsten, an denen ich mich bei Gelegenheit direkt wenden werde. Einen Versuch war es wert („wir schauen mal, was da so passiert“); Danke für deine Unterstützung und schönen Abend --PerfektesChaos 21:22, 20. Jun. 2011 (CEST)


The current standard diff suffers from some limitations. The implementation can be improved a bit without major decrease in performance. A million of users world wide should not be flabbergasted by an entirely new appearance. The basic algorithm (line based diff engine) is quite fast and should be kept. However, preparing the input and displaying the results might be enhanced.

Six improvements are suggested.

It is expected that performance is not impaired. Suggested code is longer, but saves a lot of work from existing and untouched diff engine, e.g. by hiding empty lines. Showing the differences in a better way should pay off even some slight additional resources.

Avoid confusion by empty lines

Objective: If an “empty line” (maybe with some invisible content) has been inserted or removed by the author and the adjacent paragraphs are modified in some way, the presentation of the result is currently disturbed.

Example:

previous line previous line
small modification  
change little  
  minor modification
   
  change slighty
following line following line

Could be presented as:

previous line previous line
small modification minor modification
   
change little change slighty
following line following line

more…

Improve modified consecutive lines

Objective: The line based algorithm makes minor corrections in consecutive lines appear as a dramatic change.

Example:

previous line small modification …whaffle… …blah…   …Blah… …Whaffle… change little following line
previous line minor modification …whaffle… …blah… added line …Blah… …Whaffle… change slighty following line

results currently in:

previous line previous line
small modification

…whaffle…

…blah…
 
…Blah…

…Whaffle…

change little
 
  minor modification

…whaffle…

…blah…
  added line
  …Blah…

…Whaffle…

change slighty
following line following line

This shall be made more readable:

previous line previous line
small modification

…whaffle…

…blah…
minor modification

…whaffle…

…blah…
  added line
…Blah…

…Whaffle…

change little
…Blah…

…Whaffle…

change slighty
following line following line

more…

Improve visualization of context lines

Objectives: Currently any kind of line is displayed when two lines preceding or following shall give an impression of the unchanged context where a changed block is located.

  1. If one or both of these lines are empty they are put into HTML source but invisible and not informative.
  2. If these lines are very long (sometimes each 1000 bytes and more), both paragraphs are displayed anyway, making the output lengthy and hard to survey.

The suggested code has a slightly different behaviour:

  1. The most adjacent non-empty (visible) lines will be shown.
  2. Not two paragraphs but the next unchanged two virtual lines (each expected of at least 100 bytes if not full paragraph) will be displayed.

Visualize space-only differences

Objective: The current function doesn’t show space-only differences. Readers find identical black text and may guess that the reason is a superfluous space character somewhere, or perhaps a period changed into a comma?

Example:

old: The old  lady looks  confused.
new: The young girl looks confused.
The old lady looks▯▯confused. The young girl looksconfused.
  • Make space-only differences visible, including heading/trailing space.
  • Enable reader to count number of spacing characters.
  • Don’t confuse reader with space-▯ if there are visible changes: If one of the adjacent words is already red, space difference is negliable.
  • Show not only different number of spacing characters, but also varying types (currently only: ASCII Space U+0020 and HorTab U+0009, but there are many more spaces like U+2004-200A).

more…

Visualize non-ASCII spaces

Objective: Other spaces shall be treated like ASCII space. This goes for both word-splitting and displaying of modification.

Affected unicodes:

2002;EN SPACE
2003;EM SPACE
2004;THREE-PER-EM SPACE
2005;FOUR-PER-EM SPACE
2006;SIX-PER-EM SPACE
2007;FIGURE SPACE
2008;PUNCTUATION SPACE
2009;THIN SPACE
200A;HAIR SPACE

more…

Visualize zero-width differences

Objective: There are modified words where the modification keeps invisible, since a zero-width character has been added or removed. The user encounters two red words without any visible difference.

Affected unicodes:
  • 00AD;SOFT HYPHEN   &shy;
  • 200B;ZERO WIDTH SPACE
  • 200C;ZERO WIDTH NON-JOINER   &zwnj;
  • 200D;ZERO WIDTH JOINER   &zwj;
  • 200E;LEFT-TO-RIGHT MARK   &lrm;
  • 200F;RIGHT-TO-LEFT MARK   &rlm;
  • 202A;LEFT-TO-RIGHT EMBEDDING
  • 202B;RIGHT-TO-LEFT EMBEDDING
  • 202C;POP DIRECTIONAL FORMATTING
  • 202D;LEFT-TO-RIGHT OVERRIDE
  • 202E;RIGHT-TO-LEFT OVERRIDE

Example (invisible characters shown as HTML entities):

old: Meaning&shy;less to &rlm;change&lrm; direction.
new: Meaningless to change direction.
Meaningless to change direction. Meaningless to change direction.

The users have no clue why these words are red, give’em one:

Meaning▯less to ▯change▯ direction. Meaningless to change direction.

Any red word is affected. Also deleted and added lines are considered – that doesn’t help much, but some users might learn the first time that they are carrying spooky characters.
more…

Project dissemination

In order to turn this into reality, some steps are to be made:

  • A project page (best on MW:) needs to be established, and this content shall be copied. (The current talk page has been fine for prenatal issues.)
  • A decision is to be prepared whether the proposal is welcome and there should be developed something like windiff3.
  • As soon the course of action is clear I do volunteer to create a suite of C++ source codes, merging all the kinda ‘patches’ into a syntactically correct set of subpages.
  • Somebody else might establish a test environment, look for bugs, and test in local environment.
  • If sufficient, a windiff3 could be set on SVG and performance test are required in testwiki.
  • If everybody is happy, the call on the server may be switched from 2 into 3, falling back if major complaints arrive.

Enjoy. --PerfektesChaos 23:04, 11. Mai 2011 (CEST)

Amendment --PerfektesChaos 10:18, 13. Mai 2011 (CEST)
Another amendment --PerfektesChaos 22:04, 16. Mai 2011 (CEST)