[ Skip to the content ]

Institute of Formal and Applied Linguistics Wiki


[ Back to the navigation ]

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

media2doku.pl [2008/07/09 11:08] (current)
zeman vytvořeno
Line 1: Line 1:
 +====== media2doku.pl ======
  
 +<code perl>#!/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 <zeman@ufal.mff.cuni.cz>
 +# 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/&/&amp;/sg;
 +$wiki =~ s/</&lt;/sg;
 +$wiki =~ s/>/&gt;/sg;
 +$wiki =~ s/\[\[(.*?)\|(.*?)\]\]/<a href='$1'>$2<\/a>/sg;
 +$wiki =~ s/\[(http.*?) (.*?)\]/<a href='$1'>$2<\/a>/sg;
 +$wiki =~ s/^====\s*(.*?)\s*====$/<h4>$1<\/h4>/mg;
 +$wiki =~ s/^===\s*(.*?)\s*===$/<h3>$1<\/h3>/mg;
 +$wiki =~ s/^==\s*(.*?)\s*==$/<h2>$1<\/h2>/mg;
 +$wiki =~ s/^=\s*(.*?)\s*=$/<h1>$1<\/h1>/mg;
 +$wiki =~ s/'''(.*?)'''/<b>$1<\/b>/sg;
 +$wiki =~ s/''(.*?)''/<i>$1<\/i>/sg;
 +$wiki =~ s/&lt;tt&gt;(.*?)&lt;\/tt&gt;/<tt>$1<\/tt>/sg;
 +$wiki =~ s/&lt;sub&gt;(.*?)&lt;\/sub&gt;/<sub>$1<\/sub>/sg;
 +$wiki =~ s/&lt;sup&gt;(.*?)&lt;\/sup&gt;/<sup>$1<\/sup>/sg;
 +$wiki =~ s/&lt;pre&gt;(.*?)&lt;\/pre&gt;/<pre>$1<\/pre>/sg;
 +$wiki =~ s/&lt;span (.*?)&gt;(.*?)&lt;\/span&gt;/<span $1>$2<\/span>/sg;
 +$wiki =~ s/^\*\*\*\*\s*/<uli4>/mg;
 +$wiki =~ s/^\*\*\*\s*/<uli3>/mg;
 +$wiki =~ s/^\*\*\s*/<uli2>/mg;
 +$wiki =~ s/^\*\s*/<uli1>/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_>/<table$#tabulky>/s;
 +}
 +# Převést pseudo-HTML na konstrukce Doku Wiki.
 +$wiki =~ s/<a href='(.*?)'>(.*?)<\/a>/[[$1|$2]]/sg;
 +$wiki =~ s/<h1>(.*?)<\/h1>/======$1======/mg;
 +$wiki =~ s/<h2>(.*?)<\/h2>/=====$1=====/mg;
 +$wiki =~ s/<h3>(.*?)<\/h3>/====$1====/mg;
 +$wiki =~ s/<h4>(.*?)<\/h4>/===$1===/mg;
 +$wiki =~ s/<b>(.*?)<\/b>/**$1**/sg;
 +$wiki =~ s/<i>(.*?)<\/i>/\/\/$1\/\//sg;
 +$wiki =~ s/<tt>(.*?)<\/tt>/''$1''/sg;
 +$wiki =~ s/<pre>(.*?)<\/pre>/<code>$1<\/code>/sg;
 +$wiki =~ s/(<span .*?>.*?<\/span>)/<html>$1<\/html>/sg;
 +$wiki =~ s/<uli1>/  * /mg;
 +$wiki =~ s/<uli2>/    * /mg;
 +$wiki =~ s/<uli3>/      * /mg;
 +$wiki =~ s/<uli4>/        * /mg;
 +# Tabulky mají složitější syntax, takže si nevystačíme pouze s regulárními výrazy.
 +while($wiki =~ s/<table(\d+)>/<_table_being_written_>/s)
 +{
 +    my $index = $1;
 +    my $tabulka = zakodovat_tabulku($tabulky[$index]);
 +    $wiki =~ s/<_table_being_written_>/$tabulka/s;
 +}
 +$wiki =~ s/&gt;/>/sg;
 +$wiki =~ s/&lt;/</sg;
 +$wiki =~ s/&amp;/&/sg;
 +# Dokuwiki neumí většinu entit HTML, proto dekódovat i ty &lt; a &gt;, které už byly v kódu MediaWiki.
 +$wiki =~ s/&gt;/>/sg;
 +$wiki =~ s/&lt;/</sg;
 +# Vypsat převedený zdroják na standardní výstup.
 +print($wiki);
 +
 +
 +
 +#------------------------------------------------------------------------------
 +# Rozebere tabulku v syntaxi Media Wiki a uloží ji jako pole buněk.
 +#------------------------------------------------------------------------------
 +sub dekodovat_tabulku
 +{
 +    my $tabulka = shift;
 +    # Rozsekat kód tabulky na řádky.
 +    my @radky_kodu = split(/\r?\n/, $tabulka);
 +    # Projít řádky kódu, přečíst parametry celé tabulky a rozdělit kód podle řádků tabulky (což není totéž jako řádky kódu).
 +    my $atributy_tabulky;
 +    my @radky_tabulky;
 +    foreach my $radek (@radky_kodu)
 +    {
 +        if($radek =~ m/^\{\|(.*)/)
 +        {
 +            $atributy_tabulky = $1;
 +        }
 +        elsif($radek =~ m/^\|([^-\|\}].*)/)
 +        {
 +            # Umazat úvodní svislítko.
 +            $radek = $1;
 +            $radek =~ s/^\s+//;
 +            $radek =~ s/\s+$//;
 +            my @bunky = split(/\s*\|\|\s*/, $radek);
 +            # Projít buňky a oddělit atributy od obsahu.
 +            foreach my $bunka (@bunky)
 +            {
 +                my %bunka;
 +                if($bunka =~ m/^(.*?)\|(.*)$/)
 +                {
 +                    my $atributy = $1;
 +                    $bunka{obsah} = $2;
 +                    my @atributy = split(/\s+/, $atributy);
 +                    foreach my $atribut (@atributy)
 +                    {
 +                        # $atribut nemůže obsahovat mezery, protože na mezerách jsme odsekávali atributy od sebe.
 +                        # Nemusíme se proto starat o mezery v následujícím regulárním výrazu.
 +                        if($atribut =~ m/^(.+?)=(.*)$/)
 +                        {
 +                            $bunka{$1} = $2;
 +                        }
 +                        else
 +                        {
 +                            $bunka{$atribut}++;
 +                        }
 +                    }
 +                }
 +                else
 +                {
 +                    $bunka{obsah} = $bunka;
 +                }
 +                # V původním poli buněk nahradit řetězec odkazem na hash.
 +                $bunka = \%bunka;
 +            }
 +            push(@radky_tabulky, \@bunky);
 +        }
 +    }
 +    # Vytvořit hash z atributů a matice buněk a vrátit odkaz na něj.
 +    my %tabulka =
 +    (
 +        'atributy' => $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;
 +}
 +</code>

[ Back to the navigation ] [ Back to the content ]