C++-Programm zum Abgleich des Verzeichnisses aller Vorlagen, deren Name mit „Vorlage:User “ beginnt, mit den Vorlagen, die auf den Projektseiten Wikipedia:Babel, Wikipedia:Babel/Dialekt und Wikipedia:Babel/Schriften verlinkt sind. Das Programm gibt dabei eine Liste der Vorlagen aus, die auf keiner der Projektseiten verlinkt sind. Näheres zur Handhabung steht im Quelltextkommentar über dem eigentlichen Programmcode.



// C++

// 22.8.2011, Stefan Knauf

/*

Programm, das die Menge der Babelvorlagen aus dem Verzeichnis aller Vorlagen
(http://de.wikipedia.org/w/index.php?title=Spezial:Alle_Seiten&namespace=10&from=User)
mit den auf den Projektseiten Wikipedia:Babel, Wikipedia:Babel/Dialekt und
Wikipedia:Babel/Schriften verlinkten Vorlagen abgleicht. Das Programm benötigt
als Parameter zwei Textdateien, in der ersten den HTML-Quelltext des
Verzeichnisses und in der zweiten den HTML-Quelltext der Projektseiten. Ein
korrekter Programmaufruf sieht also beispielsweise so aus:

BabellistenprogrammII Verzeichnis.htm Projektseiten.htm

Die Dateinamen dürfen dabei natürlich keine Leerzeichen enthalten.

Das Programm wertet nur die Links auf Vorlagen aus, Umlaute liest es dabei
natürlich in der UTF-8-%-URL-Kodierung aus (denn so stehen sie ja im
HTML-Quelltext). Genauer durchsucht es den HTML-Quelltext nach dem Muster
"wiki/Vorlage:User_" und interpretiert alles dahinter bis zum nächsten
Gänsefüßchen (") als Namen, mit dem es die Vorlage identifiziert. Aufgrund des
Suchmusters kann es keine "roten Links" sehen.
Das Verzeichnis wird einem in der Wikipedia auf mehrere Seiten verteilt
angezeigt; das Programm benötigt natürlich eine Datei, in der der HTML-Quelltext
aller dieser Seiten steht, die Vorlagen enthalten, deren Name mit
"Vorlage:User " beginnt.

Das Programm gibt eine Liste am Bildschirm aus, die genau alle Babelvorlagen
enthält, deren Name mit "Vorlage:User " beginnt und die nicht auf einer der
Projektseiten verlinkt sind.

Dem Programm ist es fast egal, wie die Dateien mit dem HTML-Quelltext kodiert
sind, weil es nur die Links im HTML-Quelltext ausliest, wo nur ASCII-Zeichen
vorkommen können. Mit jeder halbwegs vernünftigen Kodierung (z.B. UTF-8 oder
ANSI) kommt es daher klar.



*/
using namespace std;

#include<vector> //enthält die praktische Vektor-Klasse vector<irgendein Typ>
#include<iostream> //enthält die Befehle zum Schreiben auf den Bildschirm
#include<fstream> //enthält die Befehle zum Schreiben in und zum Lesen aus Dateien
#include<string> //enthält den Kram zu Strings, also zu Zeichenketten



struct Babellisteneintrag //Typdefinition für ein Tripel aus Sprachcode (string) und zwei Booleschen Variablen dafür,
//ob die Vorlage im Verzeichnis oder den Projektseiten aufgelistet ist
 {string Name;
  bool Verzeichnis;
  bool Projektseite;
 };
 



vector<Babellisteneintrag> FuelleVerzeichnisein (vector<Babellisteneintrag> Babelliste, string Dateiname)
//bekommt eine Babelliste und einen Dateinamen als Eingabe; durchsucht die
//Datei nach dem Muster "wiki/Vorlage:User_" und interpretiert alles dahinter
//bis zum nächsten Gänsefüßchen (") als Namen; räumt die neu gefundenen Einträge
//in die Babelliste ein bzw. vermerkt bei schon vorhandenen Einträgen, dass sie
//auch im Verzeichnis auftauchten.
 {ifstream Datei;
  char x;
  Datei.open(Dateiname.c_str());
  while (Datei.good())
   {Datei.get(x);
    if (x=='w' && Datei.good())
     {Datei.get(x);
      if (x=='i' && Datei.good())
       {Datei.get(x);
        if (x=='k' && Datei.good())
         {Datei.get(x);
          if (x=='i' && Datei.good())
           {Datei.get(x);
            if (x=='/' && Datei.good())
             {Datei.get(x);
              if (x=='V' && Datei.good())
               {Datei.get(x);
                if (x=='o' && Datei.good())
                 {Datei.get(x);
                  if (x=='r' && Datei.good())
                   {Datei.get(x);
                    if (x=='l' && Datei.good())
                     {Datei.get(x);
                      if (x=='a' && Datei.good())
                       {Datei.get(x);
                        if (x=='g' && Datei.good())
                         {Datei.get(x);
                          if (x=='e' && Datei.good())
                           {Datei.get(x);
                            if (x==':' && Datei.good())
                             {Datei.get(x);
                              if (x=='U' && Datei.good())
                               {Datei.get(x);
                                if (x=='s' && Datei.good())
                                 {Datei.get(x);
                                  if (x=='e' && Datei.good())
                                   {Datei.get(x);
                                    if (x=='r' && Datei.good())
                                     {Datei.get(x);
                                      if (x=='_' && Datei.good())
                                       {string Name="";
                                        Datei.get(x);
                                        while (x!='"' && Datei.good()) //liest den Namen ein
                                         {Name.push_back(x);
                                          Datei.get(x);
                                         }
                                        int i=0;
                                        bool fertig=false;
                                        while (i<Babelliste.size() && !fertig) //wenn der Name bereits in der Babelliste stand, wird hier vermerkt, dass er auch im Verzeichnis war
                                         {if (Name==Babelliste[i].Name)
     	                                   {Babelliste[i].Verzeichnis=true;
                                            fertig=true;
                                           }
                                          else
                                           {i++;
                                           }
                                         }
                                        if (!fertig) //wenn der Name nicht in der Babelliste stand, wird er hier eingeräumt
                                         {Babellisteneintrag Eintrag;
    	                                  Eintrag.Name=Name;
                                          Eintrag.Verzeichnis=true;
                                          Eintrag.Projektseite=false;
                                          Babelliste.push_back(Eintrag);
                                         }
                                       }
                                     }
                                   }
                                 }
                               }
                             }
                           }
                         }
                       }
                     }
                   }
                 }
               }
             }
           }
         }
       }
     }
   }
  Datei.close();
  return Babelliste;
 }
 
 
vector<Babellisteneintrag> FuelleProjektseitenein (vector<Babellisteneintrag> Babelliste, string Dateiname)
//macht das gleiche wie FuelleVerzeichnisein, nur dass es alle in der Datei
//aufgespürten Treffer als Einträge der Projektseiten interpretiert und
//entsprechend vermerkt
 {ifstream Datei;
  char x;
  Datei.open(Dateiname.c_str());
  while (Datei.good())
   {Datei.get(x);
    if (x=='w' && Datei.good())
     {Datei.get(x);
      if (x=='i' && Datei.good())
       {Datei.get(x);
        if (x=='k' && Datei.good())
         {Datei.get(x);
          if (x=='i' && Datei.good())
           {Datei.get(x);
            if (x=='/' && Datei.good())
             {Datei.get(x);
              if (x=='V' && Datei.good())
               {Datei.get(x);
                if (x=='o' && Datei.good())
                 {Datei.get(x);
                  if (x=='r' && Datei.good())
                   {Datei.get(x);
                    if (x=='l' && Datei.good())
                     {Datei.get(x);
                      if (x=='a' && Datei.good())
                       {Datei.get(x);
                        if (x=='g' && Datei.good())
                         {Datei.get(x);
                          if (x=='e' && Datei.good())
                           {Datei.get(x);
                            if (x==':' && Datei.good())
                             {Datei.get(x);
                              if (x=='U' && Datei.good())
                               {Datei.get(x);
                                if (x=='s' && Datei.good())
                                 {Datei.get(x);
                                  if (x=='e' && Datei.good())
                                   {Datei.get(x);
                                    if (x=='r' && Datei.good())
                                     {Datei.get(x);
                                      if (x=='_' && Datei.good())
                                       {string Name="";
                                        Datei.get(x);
                                        while (x!='"' && Datei.good()) //liest den Namen ein
                                         {Name.push_back(x);
                                          Datei.get(x);
                                         }
                                        int i=0;
                                        bool fertig=false;
                                        while (i<Babelliste.size() && !fertig) //wenn der Name bereits in der Babelliste stand, wird hier vermerkt, dass er auch auf einer der Projektseiten war
                                         {if (Name==Babelliste[i].Name)
     	                                   {Babelliste[i].Projektseite=true;
                                            fertig=true;
                                           }
                                          else
                                           {i++;
                                           }
                                         }
                                        if (!fertig) //wenn der Name nicht in der Babelliste stand, wird er hier eingeräumt
                                         {Babellisteneintrag Eintrag;
    	                                  Eintrag.Name=Name;
                                          Eintrag.Verzeichnis=false;
                                          Eintrag.Projektseite=true;
                                          Babelliste.push_back(Eintrag);
                                         }
                                       }
                                     }
                                   }
                                 }
                               }
                             }
                           }
                         }
                       }
                     }
                   }
                 }
               }
             }
           }
         }
       }
     }
   }
  Datei.close();
  return Babelliste;
 }


void nurVer (vector<Babellisteneintrag> Babelliste) //gibt alle Einträge aus, die nur im Verzeichnis auftauchten
 {for (int i=0; i<Babelliste.size(); i++)
   {if (Babelliste[i].Projektseite==false)
     {cout << Babelliste[i].Name << endl;
     }
   }
 }


int main(int argc, char ** argv)
 {if (argc<3) //Die Bedingung ist erfüllt, wenn dem Programm zu wenig Parameter übergeben wurden.
   {cout << "Dieses Programm benötigt als Parameter zwei Textdateien, in der ersten den HTML-Quelltext des Verzeichnisses aller Vorlagen beginnend ab \"Vorlage:User \" und in der zweiten den HTML-Quelltext der Babel-Projektseiten. Näheres steht in der Quelltextdatei ganz oben." << endl;
   }
  else
   {string Verzeichnis=argv[1];
    string Projektseiten=argv[2];
    vector<Babellisteneintrag> Babelliste(0);
    Babelliste = FuelleVerzeichnisein(FuelleProjektseitenein(Babelliste, Projektseiten), Verzeichnis);
    cout << "Folgende Babel-Vorlagen tauchten nur im Verzeichnis auf: " << endl;
    nurVer(Babelliste);
    cout << "Insgesamt wurden " << Babelliste.size() << " verschiedene Vorlagen im Verzeichnis und auf den Projektseiten gefunden." << endl;
   }
  return 0;
 }