====== media2doku.pl ====== #!/usr/bin/perl # Převede zdroják Media Wiki (např. wiki StatMT CLIP UMIACS) do Doku Wiki (např. wiki ÚFAL MFF UK). # (c) 2008 Dan Zeman # Licence: GNU GPL use utf8; use open ":utf8"; binmode(STDIN, ":utf8"); binmode(STDOUT, ":utf8"); binmode(STDERR, ":utf8"); # Načíst zdroják Media Wiki. while(<>) { $wiki .= $_; } # Převést konstrukce Media Wiki do pseudo-HTML. $wiki =~ s/&/&/sg; $wiki =~ s//>/sg; $wiki =~ s/\[\[(.*?)\|(.*?)\]\]/$2<\/a>/sg; $wiki =~ s/\[(http.*?) (.*?)\]/$2<\/a>/sg; $wiki =~ s/^====\s*(.*?)\s*====$/

$1<\/h4>/mg; $wiki =~ s/^===\s*(.*?)\s*===$/

$1<\/h3>/mg; $wiki =~ s/^==\s*(.*?)\s*==$/

$1<\/h2>/mg; $wiki =~ s/^=\s*(.*?)\s*=$/

$1<\/h1>/mg; $wiki =~ s/'''(.*?)'''/$1<\/b>/sg; $wiki =~ s/''(.*?)''/$1<\/i>/sg; $wiki =~ s/<tt>(.*?)<\/tt>/$1<\/tt>/sg; $wiki =~ s/<sub>(.*?)<\/sub>/$1<\/sub>/sg; $wiki =~ s/<sup>(.*?)<\/sup>/$1<\/sup>/sg; $wiki =~ s/<pre>(.*?)<\/pre>/
$1<\/pre>/sg;
$wiki =~ s/<span (.*?)>(.*?)<\/span>/$2<\/span>/sg;
$wiki =~ s/^\*\*\*\*\s*//mg;
$wiki =~ s/^\*\*\*\s*//mg;
$wiki =~ s/^\*\*\s*//mg;
$wiki =~ s/^\*\s*//mg;
# Tabulky mají složitější syntax, takže si nevystačíme pouze s regulárními výrazy.
while($wiki =~ s/(\{\|.*?\|\})/<_table_being_read_>/s)
{
    my $tabulka = $1;
    push(@tabulky, dekodovat_tabulku($tabulka));
    $wiki =~ s/<_table_being_read_>//s;
}
# Převést pseudo-HTML na konstrukce Doku Wiki.
$wiki =~ s/(.*?)<\/a>/[[$1|$2]]/sg;
$wiki =~ s/

(.*?)<\/h1>/======$1======/mg; $wiki =~ s/

(.*?)<\/h2>/=====$1=====/mg; $wiki =~ s/

(.*?)<\/h3>/====$1====/mg; $wiki =~ s/

(.*?)<\/h4>/===$1===/mg; $wiki =~ s/(.*?)<\/b>/**$1**/sg; $wiki =~ s/(.*?)<\/i>/\/\/$1\/\//sg; $wiki =~ s/(.*?)<\/tt>/''$1''/sg; $wiki =~ s/
(.*?)<\/pre>/$1<\/code>/sg;
$wiki =~ s/(.*?<\/span>)/$1<\/html>/sg;
$wiki =~ s//  * /mg;
$wiki =~ s//    * /mg;
$wiki =~ s//      * /mg;
$wiki =~ s//        * /mg;
# Tabulky mají složitější syntax, takže si nevystačíme pouze s regulárními výrazy.
while($wiki =~ s//<_table_being_written_>/s)
{
    my $index = $1;
    my $tabulka = zakodovat_tabulku($tabulky[$index]);
    $wiki =~ s/<_table_being_written_>/$tabulka/s;
}
$wiki =~ s/>/>/sg;
$wiki =~ s/<//sg;
$wiki =~ s/</ $atributy_tabulky,
        'radky' => \@radky_tabulky
    );
    return \%tabulka;
}



#------------------------------------------------------------------------------
# Vypíše tabulku v syntaxi Doku Wiki.
#------------------------------------------------------------------------------
sub zakodovat_tabulku
{
    my $tabulka = shift; # odkaz na hash s atributy a maticí buněk
    my $kod;
    # Dokuwiki neumí rowspany. Projít tabulku a vložit místo nich prázdné buňky.
    for(my $i = 0; $i<=$#{$tabulka->{radky}}; $i++)
    {
        for(my $j = 0; $j<=$#{$tabulka->{radky}[$i]}; $j++)
        {
            if(exists($tabulka->{radky}[$i][$j]{rowspan}))
            {
                # Na každý následující řádek v rowspanu přidat do příslušného místa prázdnou buňku.
                for(my $k = $i+1; $k<=$i+$tabulka->{radky}[$i][$j]{rowspan}-1; $k++)
                {
                    # Pokud má aktuální buňka také colspan, nezapomenout ho okopírovat i do vkládané prázdné buňky.
                    my %bunka = ('obsah' => '');
                    if(exists($tabulka->{radky}[$i][$j]{colspan}))
                    {
                        $bunka{colspan} = $tabulka->{radky}[$i][$j]{colspan};
                    }
                    splice(@{$tabulka->{radky}[$k]}, $j, 0, \%bunka);
                }
            }
        }
    }
    # Dokuwiki špatně snáší, když všechny řádky tabulky nemají stejný počet buněk.
    # Zjistit počet buněk v nejdelším řádku tabulky.
    my $max_delka_radku = 0;
    foreach my $radek (@{$tabulka->{radky}})
    {
        my $delka_radku = 0;
        foreach my $bunka (@{$radek})
        {
            if(exists($bunka->{colspan}))
            {
                $delka_radku += $bunka->{colspan};
            }
            else
            {
                $delka_radku++;
            }
        }
        $max_delka_radku = $delka_radku if($delka_radku>$max_delka_radku);
    }
    # Doplnit řádky prázdnými buňkami na maximální počet.
    foreach my $radek (@{$tabulka->{radky}})
    {
        my $delka_radku = 0;
        foreach my $bunka (@{$radek})
        {
            if(exists($bunka->{colspan}))
            {
                $delka_radku += $bunka->{colspan};
            }
            else
            {
                $delka_radku++;
            }
        }
        # Vlastní doplňování začíná tady.
        for(my $i = $delka_radku+1; $i<=$max_delka_radku; $i++)
        {
            push(@{$radek}, {'obsah' => ''});
        }
    }
    # Zakódovat tabulku v syntaxi Doku Wiki.
    foreach my $radek (@{$tabulka->{radky}})
    {
        $kod .= join('', map
        {
            my $vysledek = $_->{obsah};
            $vysledek =~ s/^\s+//s;
            $vysledek =~ s/\s+$//s;
            if($_->{align} eq "center")
            {
                $vysledek = "  $vysledek  ";
            }
            elsif($_->{align} eq "left")
            {
                $vysledek = " $vysledek  ";
            }
            elsif($_->{align} eq "right")
            {
                $vysledek = "  $vysledek ";
            }
            else
            {
                $vysledek = " $vysledek ";
            }
            $vysledek = '|'.$vysledek;
            for(my $i = 2; $i<=$_->{colspan}; $i++)
            {
                $vysledek .= '|';
            }
            $vysledek;
        }
        (@{$radek}))."|\n";
    }
    return $kod;
}