1 package Text::Tradition::Parser::Tabular;
9 Text::Tradition::Parser::Tabular
13 Parser module for Text::Tradition to read an alignment table format, such as CSV.
21 parse( $graph, $graphml_string );
23 Takes an initialized Text::Tradition::Graph object and a string
24 containing the GraphML; creates the appropriate nodes and edges on the
30 my( $tradition, $tab_str ) = @_;
31 # TODO Allow setting of sep_char
32 my $c = $tradition->collation; # shorthand
33 my $csv = Text::CSV_XS->new( { binary => 1, # binary for UTF-8
35 my @lines = split( "\n", $tab_str );
36 # Conveniently, we are basically receiving exactly the sort of alignment table
37 # we might want to produce later. May as well save it.
39 foreach my $l ( @lines ) {
40 my $status = $csv->parse( $l );
42 push( @$alignment_table, [ $csv->fields ] );
44 warn "Could not parse line $l: " . $csv->error_input;
48 # Set up the witnesses we find in the first line
50 foreach my $sigil ( @{$alignment_table->[0]} ) {
51 my $wit = $tradition->add_witness( 'sigil' => $sigil );
52 $wit->path( [ $c->start ] );
53 push( @witnesses, $wit );
56 # Now for the next rows, make nodes as necessary, assign their ranks, and
57 # add them to the witness paths.
59 foreach my $idx ( 1 .. $#{$alignment_table} ) {
60 my $row = $alignment_table->[$idx];
61 my $nodes = make_nodes( $c, $row, $idx );
62 foreach my $w ( 0 .. $#{$row} ) {
63 # push the appropriate node onto the appropriate witness path
64 my $word = $row->[$w];
66 my $reading = $nodes->{$word};
67 my $wit = $witnesses[$w];
68 push( @{$wit->path}, $reading );
69 } # else skip it for empty readings.
74 # Collapse our lacunae into a single node and
75 # push the end node onto all paths.
76 $c->end->rank( scalar @$alignment_table );
77 foreach my $wit ( @witnesses ) {
79 my $last_rdg = shift @$p;
80 my $new_p = [ $last_rdg ];
81 foreach my $rdg ( @$p ) {
82 if( $rdg->text eq '#LACUNA#' ) {
83 # If we are in a lacuna already, drop this node.
84 # Otherwise make a lacuna node and drop this node.
85 unless( $last_rdg->is_lacuna ) {
86 my $l = $c->add_lacuna( $rdg->name );
87 $l->rank( $rdg->rank );
91 $c->del_reading( $rdg );
93 # No lacuna, save the reading.
94 push( @$new_p, $rdg );
97 push( @$new_p, $c->end );
102 $c->make_witness_paths;
104 # Save the alignment table that was so handily provided to us.
105 # TODO if we support other delimiters, we will have to re-export this
106 # rather than saving the original string.
107 $c->_save_csv( $tab_str );
111 my( $collation, $row, $index ) = @_;
113 foreach my $w ( @$row ) {
114 $unique{$w} = 1 if $w;
117 foreach my $w ( keys %unique ) {
118 my $r = $collation->add_reading( "$index,$ctr" );