IServ-Wiki:Konvertierungsscript: Unterschied zwischen den Versionen

Aus dem IServ-Wiki
Zur Navigation springen Zur Suche springen
K
K (IServ-Wiki:Konvertierung wurde nach IServ-Wiki:Konvertierungsscript verschoben)
 
(2 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
 
Ich arbeite zur Zeit mit Jörgs Hilfe an einem Perl-Script, das die Konvertierung von DokuWiki-Artikeln in das MediaWiki-Format erleichern soll. Viele der kleinen Seiten können problemlos per Hand übersetzt werden, bei der Seiten wie der Kommandozeilenreferenz ist das allerdings nicht so gut machbar...
 
Ich arbeite zur Zeit mit Jörgs Hilfe an einem Perl-Script, das die Konvertierung von DokuWiki-Artikeln in das MediaWiki-Format erleichern soll. Viele der kleinen Seiten können problemlos per Hand übersetzt werden, bei der Seiten wie der Kommandozeilenreferenz ist das allerdings nicht so gut machbar...
  
Das Konvertierungsscript besteht in Wirklichkeit aus zwei Scripts. Das Erste (<tt>convert.pl</tt>) arbeitet die Eingabedatei zeilenweise ab, das Zweite (<tt>convert2.pl</tt>) lädt die gesamte Datei auf einmal in den Puffer, da die Erkennung von DokuWiki-Tabellenenden mehrere Zeilen durchsucht werden müssen.
+
'''Update:''' Das Script scheint nun praktisch fertig zu sein. Es funktioniert genau genommen besser, als ich das je erwartet hätte :)
  
 
== Aufruf ==
 
== Aufruf ==
  cat artikel.txt | ./convert.pl | ./convert2.pl
+
<ol>
 +
<li>Eine Datei konvertieren (mit Pipes). Das Ergebnis wird auf stdout ausgegeben.
 +
<pre>cat datei.txt | ./convert.pl</pre>
 +
</li>
 +
<li>Eine Datei konvertieren (ohne Pipes). Das Ergebnis wird als _datei.txt abgespeichert.
 +
<pre>./convert.pl datei.txt</pre>
 +
</li>
 +
<li>Mehrere Dateien konvertieren. Die Dateien werden als _<Dateiname>.txt abgespeichert.
 +
<pre>./convert.pl *.txt</pre>
 +
</li>
 +
</ol>
  
 
== convert.pl ==
 
== convert.pl ==
 
<pre>
 
<pre>
#!/usr/bin/perl -p -w
+
#!/usr/bin/perl -w
  
# Ueberschriften
+
use File::Basename;
if (/^=/m)      { s/======/=/g or s/=====/==/g or s/====/===/g or s/===/====/g or s/==/=====/g; }
 
# Schreibmaschinenschrift-Tags
 
s/''(.+?)''/<tt>$1<\/tt>/g;
 
# Kursiv-Tags
 
s~//~''~g;
 
# Fettgedruckt-Tags
 
s~**~'''~g;
 
# Platzhalter für leere Tabellenzellen sind jetzt überflüssig
 
s/%% %%//g;
 
  
##############################
+
$outfile = "";
### Tabellen #################
+
$outfile2 = "";
##############################
 
  
# Im MediaWiki werden Tabellen durch {| eingeleitet, im DokuWiki werden
+
while (<>) {
# Tabellen gar nicht eingeleitet. Wir suchen daher einfach alle DokuWiki-
+
if($ARGV ne "-") {
# Tabellenheader heraus, und stellen ihnen die MediaWiki-Einleitung voran.
+
if($ARGV ne $outfile) {
 +
# bisher geöffnete Datei schließen
 +
if($outfile) { close(OUT); }
  
# Das DokuWiki beendet eine TH-Zeile mit einem ^, eine TD-Zeile mit einem |.
+
# neuen Dateinamen bestimmen
# Das MediaWiki beendet Zeilen nur mit dem Zeilenumbruch, daher muessen wir
+
$outfile = $ARGV;
# die ueberstehenden Zeichen ^ und | entfernen.
+
$outfile2 = dirname($ARGV) . "/_" . basename($ARGV);
if(/^\^/m)     { s/(.*)\^/$1/; }
+
print STDERR "Verarbeite Datei $outfile2...\n";
if(/^\|/m)     { s/(.*)\|/$1/; }
+
open(OUT, ">$outfile2");
 +
}
 +
} else {
 +
if(!$open) {
 +
open(OUT, ">&STDOUT");
 +
$open = 1;
 +
}
 +
}
  
# Das erste ^ ersetzen wir nun durch ein "! ", das erste | wird nur um ein
+
# Artikel-Überschriften entfernen, die sind im MW automatisch
# Leerzeichen ergaenzt.
+
s/====== [^=]* ======//g;
if(/^\^/m)     { s/^\^/! /; }
+
# Ueberschriften
if(/^\|/m)      { s/^\|/\| /; }
+
if (/^=/m) { s/======/=/g or s/=====/==/g or s/====/===/g or s/===/====/g or s/==/=====/g; }
 +
# Schreibmaschinenschrift-Tags
 +
s/''(.+?)''/<tt>$1<\/tt>/g;
 +
# Kursiv-Tags
 +
s~//(.+?)//~''$1''~g;
 +
# Fettgedruckt-Tags
 +
s~\*\*(.+?)\*\*~'''$1'''~g;
 +
# Platzhalter für leere Tabellenzellen sind jetzt überflüssig
 +
s/%% %%/\&nbsp\;/g;
 +
# nowiki-Tags
 +
s/%%(.+?)%%/<nowiki>$1<\/nowiki>/g;
 +
# Zeilenumbrüche
 +
s/([ \n])\\\\([ \n])/$1\<br\/\>$2/g;
 +
# Fußnoten
 +
s/\(\((.*)\)\)/\<ref\>$1\<\/ref\>/g;
 +
# HTTP-Links etc.
 +
s~\[(\[.+//.*\])\]~$1~g;
 +
s~(\[.+)\|(.+\])~$1 $2~g;
 +
# Listen
 +
s/^  -/#/g;
 +
s/^ \*/\*/g;
  
# Alle weiteren ^ ersetzen wir durch " !! ".
+
### Tabellen #################
if(/^!/m)      { s/\^/ !! /g; }
 
# Alle weiteren | ersetzen wir durch " || ".
 
# Zu dem Zweck muessen wir das erste | temporaer entfernen, es wird nachher
 
# wiederhergestellt. Sonst wuerde das erste auch ersetzt werden :-/
 
if(/^\|/m)      { s/^\|//m; }          # das erste | löschen
 
if(/\|/m)      { s/%%\|%%/{pipe}/g }  # escapte | maskieren
 
if(/\|/m)      { s/\|/ \|\| /g; }      # | durch || ersetzen
 
if(/\|/m)      { s/.*/\|$&/; }        # das erste | wiederherstellen
 
                                        # demaskieren und übersetzen
 
if(/{pipe}/m)  { s/{pipe}/<nowiki>\|<\/nowiki>/g; }
 
  
# Tabellenanfangs-Tag
+
# Das DokuWiki beendet eine TH-Zeile mit einem ^, eine TD-Zeile mit einem |.
# muss zuletzt ausgeführt werden, da diese Anweisung die Zeilenumbrüche
+
# Das MediaWiki beendet Zeilen nur mit dem Zeilenumbruch, daher müssen wir
# verfummelt.
+
# die überstehenden Zeichen ^ und | entfernen.
s/^!/{| class="wikitable"\n$&/g;
+
if(/^\^/) { s/(.*)\^/$1/; }
</pre>
+
if(/^\|/) { s/(.*)\|/$1/; }
  
== convert2.pl ==
+
# Das erste ^ ersetzen wir nun durch ein "! ", das erste | wird nur um ein
<pre>
+
# Leerzeichen ergaenzt.
#!/usr/bin/perl -w
+
if(/^\^/) { s/^\^/! /; }
 +
if(/^\|/) { s/^\|/\| /; }
  
undef $/;
+
# Alle weiteren ^ ersetzen wir durch " !! ".
 +
if(/^!/) { s/\^/ !! /g; }
 +
# Alle weiteren | ersetzen wir durch " || ".
 +
if(/^\|/) { s/^\|/\{pipe\}/; } # das erste | maskieren
 +
s/(\[\[.+)\|(.+\]\])/$1\{pipe\}$2/g; # | in Links maskieren
 +
if(/\|/) { s/\|/ \|\| /g; } # | durch || ersetzen
 +
s/\{pipe\}/\|/g; # maskierte | wiederherstellen
  
while (<>)
+
# TR-Tags: |-
{
+
if(/^!/) { s/$/\n\|-/; }
        s/(.*!.*|.*)\n\n/$1\n|}\n/g;
+
if(/^\|/) { s/$/\n\|-/; }
        print;
 
  
}
+
# <nowiki> || </nowiki> reparieren (muss <nowiki>|</nowiki> heißen)
</pre>
+
s/\<nowiki\> *\|\| *\<\/nowiki\>/\<nowiki\>\|\<\/nowiki\>/g;
  
== Testdatei mit DokuWiki-Sytnax ==
+
# Tabellenanfangs-Tag
<pre>
+
s/^!/{| class="wikitable"\n$&/g;
== Header 1 ==
 
  
=== Header 2 ===
+
#-------------------------------------------------------------------------------
 +
# dieser Teil arbeitet nicht zeilenweise, sondern absatzweise!
 +
# das ist eigentlich nur nötig, um das Tabellenende-Tag |} einzufügen.
 +
$old = $/;
 +
$/ = "\n\n";
 +
s/(.*?{\|.*?)\n\n/$1\n\|}\n\n/gs;
 +
$/ = $old;
 +
#-------------------------------------------------------------------------------
 +
 +
print OUT;
 +
}
  
^Kopf^Kopf^Kopf^Kopf^
+
close(OUT)
|Spalte|Spalte|Spalte|Spalte|
 
|Spalte|Spalte|Spalte|Spalte|
 
|Spalte|Spalte|Spalte|Spalte|
 
 
</pre>
 
</pre>
  

Aktuelle Version vom 22. August 2006, 14:10 Uhr

Ich arbeite zur Zeit mit Jörgs Hilfe an einem Perl-Script, das die Konvertierung von DokuWiki-Artikeln in das MediaWiki-Format erleichern soll. Viele der kleinen Seiten können problemlos per Hand übersetzt werden, bei der Seiten wie der Kommandozeilenreferenz ist das allerdings nicht so gut machbar...

Update: Das Script scheint nun praktisch fertig zu sein. Es funktioniert genau genommen besser, als ich das je erwartet hätte :)

Aufruf

  1. Eine Datei konvertieren (mit Pipes). Das Ergebnis wird auf stdout ausgegeben.
    cat datei.txt | ./convert.pl
  2. Eine Datei konvertieren (ohne Pipes). Das Ergebnis wird als _datei.txt abgespeichert.
    ./convert.pl datei.txt
  3. Mehrere Dateien konvertieren. Die Dateien werden als _<Dateiname>.txt abgespeichert.
    ./convert.pl *.txt

convert.pl

#!/usr/bin/perl -w

use File::Basename;

$outfile = "";
$outfile2 = "";

while (<>) {
	if($ARGV ne "-") {
		if($ARGV ne $outfile) {
			# bisher geöffnete Datei schließen
			if($outfile) { close(OUT); }

			# neuen Dateinamen bestimmen
			$outfile = $ARGV;
			$outfile2 = dirname($ARGV) . "/_" . basename($ARGV);
			print STDERR "Verarbeite Datei $outfile2...\n";
			open(OUT, ">$outfile2");
		}
	} else {
		if(!$open) {
			open(OUT, ">&STDOUT");
			$open = 1;
		}
	}

	# Artikel-Überschriften entfernen, die sind im MW automatisch
	s/====== [^=]* ======//g;
	# Ueberschriften
	if (/^=/m)	{ s/======/=/g or s/=====/==/g or s/====/===/g or s/===/====/g or s/==/=====/g; }
	# Schreibmaschinenschrift-Tags
	s/''(.+?)''/<tt>$1<\/tt>/g;
	# Kursiv-Tags
	s~//(.+?)//~''$1''~g;
	# Fettgedruckt-Tags
	s~\*\*(.+?)\*\*~'''$1'''~g;
	# Platzhalter für leere Tabellenzellen sind jetzt überflüssig
	s/%% %%/\&nbsp\;/g;
	# nowiki-Tags
	s/%%(.+?)%%/$1<\/nowiki>/g;
	# Zeilenumbrüche
	s/([ \n])\\\\([ \n])/$1\<br\/\>$2/g;
	# Fußnoten
	s/\(\((.*)\)\)/\<ref\>$1\<\/ref\>/g;
	# HTTP-Links etc.
	s~\[(\[.+//.*\])\]~$1~g;
	s~(\[.+)\|(.+\])~$1 $2~g;
	# Listen
	s/^  -/#/g;
	s/^  \*/\*/g;

	### Tabellen #################

	# Das DokuWiki beendet eine TH-Zeile mit einem ^, eine TD-Zeile mit einem |.
	# Das MediaWiki beendet Zeilen nur mit dem Zeilenumbruch, daher müssen wir
	# die überstehenden Zeichen ^ und | entfernen.
	if(/^\^/)	{ s/(.*)\^/$1/; }
	if(/^\|/)	{ s/(.*)\|/$1/; }

	# Das erste ^ ersetzen wir nun durch ein "! ", das erste | wird nur um ein
	# Leerzeichen ergaenzt.
	if(/^\^/)	{ s/^\^/! /; }
	if(/^\|/)	{ s/^\|/\| /; }

	# Alle weiteren ^ ersetzen wir durch " !! ".
	if(/^!/)	{ s/\^/ !! /g; }
	# Alle weiteren | ersetzen wir durch " || ".
	if(/^\|/)	{ s/^\|/\{pipe\}/; }	# das erste | maskieren
	s/(\[\[.+)\|(.+\]\])/$1\{pipe\}$2/g;	# | in Links maskieren
	if(/\|/)	{ s/\|/ \|\| /g; } 	# | durch || ersetzen
	s/\{pipe\}/\|/g;			# maskierte | wiederherstellen

	# TR-Tags: |-
	if(/^!/)	{ s/$/\n\|-/; }
	if(/^\|/)	{ s/$/\n\|-/; }

	# <nowiki> ||  reparieren (muss | heißen)
	s/\<nowiki\> *\|\| *\<\/nowiki\>/\<nowiki\>\|\<\/nowiki\>/g;

	# Tabellenanfangs-Tag
	s/^!/{| class="wikitable"\n$&/g;

	#-------------------------------------------------------------------------------
	# dieser Teil arbeitet nicht zeilenweise, sondern absatzweise!
	# das ist eigentlich nur nötig, um das Tabellenende-Tag |} einzufügen.
	$old = $/;
	$/ = "\n\n";
	s/(.*?{\|.*?)\n\n/$1\n\|}\n\n/gs;
	$/ = $old;
	#-------------------------------------------------------------------------------
	
	print OUT;
}

close(OUT)

Probleme

Die bisherigen Probleme scheinen alle gelöst zu sein.