User:Dschwen/Works in progress/Timelineoptimizer
Jump to navigation
Jump to search
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 :-)
#!/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(<STDIN>)
{
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++;
}