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)
 
(3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
Ich arbeite zur Zeit an einem sed-Script, dass die Konvertierung von DokuWiki-Artikeln in das MediaWiki-Format erleichern soll. Viele der kleinen Seiten können problemlos per Hand übersetzt werden, bei 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...
:Ich bin gerade dabei, das Script mit Jörgs Hilfe nach Perl zu portieren. Das ermöglicht es dem Script, einige Sachen besser zu machen. --[[Benutzer:Martin von Wittich|Martin von Wittich]] 23:53, 3. Aug 2006 (CEST)
 
  
== Konvertierungs-Script ==
+
'''Update:''' Das Script scheint nun praktisch fertig zu sein. Es funktioniert genau genommen besser, als ich das je erwartet hätte :)
 +
 
 +
== Aufruf ==
 +
<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 ==
 
<pre>
 
<pre>
#!/bin/sed -f
+
#!/usr/bin/perl -w
  
# Ueberschriften
+
use File::Basename;
s/======/=/g;t headersdone
 
s/=====/==/g;t headersdone
 
s/====/===/g;t headersdone
 
s/===/====/g;t headersdone
 
s/==/=====/g;t headersdone
 
:headersdone
 
  
##############################
+
$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) {
/^\^/ i\
+
# bisher geöffnete Datei schließen
{| class="wikitable"
+
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 entfernen.
+
$outfile2 = dirname($ARGV) . "/_" . basename($ARGV);
/^\^/ s/\(.*\)\^/\1/
+
print STDERR "Verarbeite Datei $outfile2...\n";
/^|/ 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;
/^\^/ s/^\^/! /
+
# Ueberschriften
/^|/ 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 #################
/^!/ s/\^/ !! /g
+
 
# Alle weiteren | ersetzen wir durch " || ".
+
# Das DokuWiki beendet eine TH-Zeile mit einem ^, eine TD-Zeile mit einem |.
# Zu dem Zweck muessen wir das erste | temporaer entfernen, es wird nachher
+
# Das MediaWiki beendet Zeilen nur mit dem Zeilenumbruch, daher müssen wir
# wiederhergestellt. Sonst wuerde das erste auch ersetzt werden :-/
+
# die überstehenden Zeichen ^ und | entfernen.
/^|/ s/|//
+
if(/^\^/) { s/(.*)\^/$1/; }
/|/ s/|/ || /g
+
if(/^\|/) { s/(.*)\|/$1/; }
/|/ s/.*/|&/
+
 
</pre>
+
# 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> || </nowiki> reparieren (muss <nowiki>|</nowiki> heißen)
 +
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>
  
 
== Probleme ==
 
== Probleme ==
 +
Die bisherigen Probleme scheinen alle gelöst zu sein.
  
<ol>
+
__NOTOC__
<li>Das Tabellenende wird im MediaWiki mit <tt><nowiki>|}</nowiki></tt> markiert, das Script ist jedoch nicht in der Lage, dies an die Tabellen anzuhängen. Mir ist es nicht gelungen, mit <tt>sed</tt> das Ende einer DokuWiki-Tabelle zu erkennen, unter anderem deshalb, weil <tt>sed</tt> den Zeilenumbruch vor Scriptausführung ausfiltert.
 
:Jörg hat einen Lösungsvorschlag, ich bin allerdings noch nicht dazu gekommen, ihn zu testen. --[[Benutzer:Martin von Wittich|Martin von Wittich]] 23:53, 3. Aug 2006 (CEST)</li>
 
<li><del>Die Schreibmaschinenschrift wird im Dokuwiki mit <nowiki>''</nowiki> ein- und ausgeschaltet. Die entsprechenden Tags dazu im MediaWiki sind <tt><nowiki><tt></nowiki></tt> und <tt><nowiki></tt></nowiki></tt>. Das sed-Script ersetzt einfachheitshalber alle <nowiki>''</nowiki> durch <tt><nowiki><tt></nowiki></tt>.</del> gelöst --[[Benutzer:Martin von Wittich|Martin von Wittich]] 23:53, 3. Aug 2006 (CEST)</li>
 
</ol>
 

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.