[ 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 ]