User:Dschwen/Works in progress/Timelineoptimizer

A perl script to optimize bar positions in a Wikipedia timeline. The Script


 * reads all lines containing from,till pairs
 * estimates their text length and bar length
 * shifts text which passes the right margin back into the picture
 * shifts bar text for bars at the left edge of the picture as much left as possible, to make room on the right
 * recurses to find the combination of bars per line that uses the space best
 * is horrible perl :-)


 * 1) !/usr/bin/perl

$n=0;

$start=1900; $end=2005; $width=800; $spacing=10; $margin_right=50;

sub recurse_list {       my $i = shift ; my $m_end = shift ; my $len = shift ; my $growlist = shift ;

my $added=0; my $min_len=$width;

while($i<$n) {               if( (($x1[$sorted[$i]]-$m_end) > $spacing) && ($status[$i]==0) && (($x1[$sorted[$i]]-$m_end)<$min_len) ) {                       $min_len=$x1[$sorted[$i]]-$m_end; recurse_list($i,$x2[$sorted[$i]],$len+($x1[$sorted[$i]]-$m_end),$growlist.",$i"); $added++; }               $i++; }

if($added==0) {               if($len<$min_len) { $min_len=$len; } push(@liste,$growlist); push(@laengen,$len); } }

while() {       if(/^\s\s(from|at):/) {               s/\n//g; $line[$n]=$_;

if(/^ from:([0-9start]+)\s+till:([0-9end]+)\s+text:\"([^\"]+)\"/)                {                        $text_raw=$3;                        $from=$1; if($from eq "start") { $from=$start; }                        $till=$2; if($till eq "end")   { $till=$end; }                }                elsif(/^  at:([0-9startend]+)\s+text:\"([^\"]+)\"/) {                       $text_raw=$2; $from=$1; if($from eq "start") { $from=$start; } $till=$1; if($till eq "end")  { $till=$end; } }

$text_raw =~ s/\[\[([^\|]+)\|([^\]]+)\]\]/$2/g; $text_raw =~ s/\[\[//g; $text_raw =~ s/\]\]//g;

$text=""; foreach(split(/~/,$text_raw)) {                       s/~//; if(length($_)>length($text)) { $text=$_; } }

$len_text=length($text)*7; $len_box=(($till-$from)*$width)/($end-$start); if($len_box>$len_text) { $len=$len_box; $textover[$n]=0; } else { $len=$len_text; $textover[$n]=($len_text-$len_box); }

$x1[$n]=(($from-$start)*$width)/($end-$start); $x2[$n]=$x1[$n]+$len;

#randcheck $over=$x2[$n]-($width+$margin_right); if($over>0) {                       $x1[$n]-=$over; $x2[$n]-=$over; $shifted[$n]=(5-$over); }

$unsorted[$n]=$n;

$n++; } }

@sorted = sort {$x1[$a] <=> $x1[$b]} (@unsorted);

$i=0; while($i<$n) {       undef @liste; undef @laengen;

# Element noch nicht verarbeitet if($status[$i]==0) {               if($shifted[$sorted[$i]]==0) {                       if($textover[$sorted[$i]]>$x1[$sorted[$i]]) {                               $x2[$sorted[$i]]-=$x1[$sorted[$i]]; $shifted[$sorted[$i]]=-$x1[$sorted[$i]]; $x1[$sorted[$i]]=0; }                       else {                               $x1[$sorted[$i]]-=$textover[$sorted[$i]]; $x2[$sorted[$i]]-=$textover[$sorted[$i]]; $shifted[$sorted[$i]]=-$textover[$sorted[$i]]; }               }                $min_len=$width; recurse_list($i,$x2[$sorted[$i]],0,"$i");

# alle laengen durchsehen, kleinste nehmen und elemente aus liste in status markieren $j=0; $minj=0; for( $j=1 ;$j<=$#laengen; $j++) {                       if($laengen[$j]<$laengen[$minj]) { $minj=$j; } }

print "\n bar:wars$i\n\n";

foreach(split(/,/,$liste[$minj])) {                       $status[$_]=1; print $line[$sorted[$_]]; if($shifted[$sorted[$_]]) { print " shift:(".int($shifted[$sorted[$_]]).",1)"; } print "\n"; }

}

$i++; }