#! /usr/bin/perl
# Reads a plain text file of tube lines and their stations,
# writes a Map::Tube-compatible XML file.
# Input format:
# The input is, in general, ordered by tube lines.
# The very first line is the name of the tube network.
# A new tube line is started by a text line starting with the # sign,
# followed by the tube line's name.
# Then, the stations on this tube line follow, in the appropriate
# order, one per text line.
#
# Note: Branching lines are a bit tricky to handle in the input.
# The best way is probably to pretend to start a new line, but with the
# same line name, and to specify the last station before the branch as
# the first station of this "new" line.
#
# Gisbert W. Selke, TapirSoft Selke & Selke GbR, Jan 2015
my( %stations, %names, $id, $prev );
my $line = '??';
my $lastid = 's000';
my $mapname;
while (<>) {
chomp;
s/^\s+//;
s/\s+$//;
s/\s+/ /g;
next if /^\s*$/;
if ( $. == 1 ) {
$mapname = $_;
next;
}
if (/^#(.+)/) {
$line = uc($1);
undef($prev);
next;
}
if ( !exists $names{$_} ) {
$names{$_} = ++$lastid;
$stations{$lastid}{name} = $_;
}
$id = $names{$_};
$stations{$id}{lines}{$line}++;
$stations{$id}{links}{$prev}++ if $prev;
$stations{$prev}{links}{$id}++ if $prev;
$prev = $id;
}
my $writer = XML::Writer->new(DATA_MODE => 1, DATA_INDENT => 2, ENCODING => 'utf-8',);
$writer->xmlDecl();
if ($mapname) {
$writer->startTag( 'tube', 'name' => $mapname );
} else {
$writer->startTag( 'tube' );
}
$writer->startTag( 'stations' );
for my $id( sort { uc($stations{$a}{name}) cmp uc($stations{$b}{name}) } keys %stations ) {
$writer->emptyTag( 'station', 'id' => $id,
'name' => $stations{$id}{name},
'line' => join( ',', sort keys %{ $stations{$id}{lines} } ),
'link' => join( ',', sort keys %{ $stations{$id}{links} } ),
);
}
$writer->endTag();
$writer->endTag();
$writer->end();