From: Tara L Andrews Date: Thu, 3 May 2012 18:38:45 +0000 (+0200) Subject: reading IDs must be XML names; now used in SVG node IDs X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=10e4b1acc8fc6607456481c568da930983efac33;p=scpubgit%2Fstemmatology.git reading IDs must be XML names; now used in SVG node IDs --- diff --git a/lib/Text/Tradition/Collation.pm b/lib/Text/Tradition/Collation.pm index a77f74f..63daec7 100644 --- a/lib/Text/Tradition/Collation.pm +++ b/lib/Text/Tradition/Collation.pm @@ -642,10 +642,10 @@ sub as_dot { # Output substitute start/end readings if necessary if( $startrank ) { - $dot .= "\t\"#SUBSTART#\" [ label=\"...\" ];\n"; + $dot .= "\t\"#SUBSTART#\" [ label=\"...\",id=\"__SUBSTART__\" ];\n"; } if( $endrank ) { - $dot .= "\t\"#SUBEND#\" [ label=\"...\" ];\n"; + $dot .= "\t\"#SUBEND#\" [ label=\"...\",id=\"__SUBEND__\" ];\n"; } if( $STRAIGHTENHACK ) { ## HACK part 1 @@ -672,6 +672,7 @@ sub as_dot { $label = "-$label" if $reading->join_prior; $label =~ s/\"/\\\"/g; $rattrs->{'label'} = $label; + $rattrs->{'id'} = $reading->id; $rattrs->{'fillcolor'} = '#b3f36d' if $reading->is_common && $color_common; $dot .= sprintf( "\t\"%s\" %s;\n", $reading->id, _dot_attr_string( $rattrs ) ); } @@ -929,6 +930,7 @@ sub as_graphml { 'Str' => 'string', 'Int' => 'int', 'Bool' => 'boolean', + 'ReadingID' => 'string', 'RelationshipType' => 'string', 'RelationshipScope' => 'string', ); @@ -1727,12 +1729,12 @@ my $c = $t->collation; is( $c->common_predecessor( 'n24', 'n23' )->id, 'n20', "Found correct common predecessor" ); is( $c->common_successor( 'n24', 'n23' )->id, - '#END#', "Found correct common successor" ); + '__END__', "Found correct common successor" ); is( $c->common_predecessor( 'n19', 'n17' )->id, 'n16', "Found correct common predecessor for readings on same path" ); is( $c->common_successor( 'n21', 'n10' )->id, - '#END#', "Found correct common successor for readings on same path" ); + '__END__', "Found correct common successor for readings on same path" ); =end testing diff --git a/lib/Text/Tradition/Collation/Reading.pm b/lib/Text/Tradition/Collation/Reading.pm index 5a60823..9d96421 100644 --- a/lib/Text/Tradition/Collation/Reading.pm +++ b/lib/Text/Tradition/Collation/Reading.pm @@ -1,12 +1,21 @@ package Text::Tradition::Collation::Reading; use Moose; +use Moose::Util::TypeConstraints; use JSON qw/ from_json /; use Module::Load; use Text::Tradition::Error; +use XML::Easy::Syntax qw( $xml10_name_rx $xml10_namestartchar_rx ); use YAML::XS; use overload '""' => \&_stringify, 'fallback' => 1; +subtype 'ReadingID', + as 'Str', + where { $_ =~ /\A$xml10_name_rx\z/ }, + message { 'Reading ID must be a valid XML attribute string' }; + +no Moose::Util::TypeConstraints; + =head1 NAME Text::Tradition::Collation::Reading - represents a reading (usually a word) @@ -79,7 +88,7 @@ has 'collation' => ( has 'id' => ( is => 'ro', - isa => 'Str', + isa => 'ReadingID', required => 1, ); @@ -184,16 +193,25 @@ around BUILDARGS => sub { if( exists $args->{'is_lacuna'} && !exists $args->{'text'} ) { $args->{'text'} = '#LACUNA#'; } elsif( exists $args->{'is_start'} ) { - $args->{'id'} = '#START#'; # Change the ID to ensure we have only one + $args->{'id'} = '__START__'; # Change the ID to ensure we have only one $args->{'text'} = '#START#'; $args->{'rank'} = 0; } elsif( exists $args->{'is_end'} ) { - $args->{'id'} = '#END#'; # Change the ID to ensure we have only one + $args->{'id'} = '__END__'; # Change the ID to ensure we have only one $args->{'text'} = '#END#'; } elsif( exists $args->{'is_ph'} ) { $args->{'text'} = $args->{'id'}; } + # Backwards compatibility for non-XMLname IDs + my $rid = $args->{'id'}; + $rid =~ s/\#/__/g; + $rid =~ s/[\/,]/./g; + if( $rid !~ /^$xml10_namestartchar_rx/ ) { + $rid = 'r'.$rid; + } + $args->{'id'} = $rid; + $class->$orig( $args ); }; diff --git a/lib/Text/Tradition/Collation/RelationshipStore.pm b/lib/Text/Tradition/Collation/RelationshipStore.pm index 8517ac1..bbfc50d 100644 --- a/lib/Text/Tradition/Collation/RelationshipStore.pm +++ b/lib/Text/Tradition/Collation/RelationshipStore.pm @@ -267,14 +267,14 @@ my $t1 = Text::Tradition->new( 'input' => 'Self', 'file' => 't/data/legendfrag.x # Test 1.1: try to equate nodes that are prevented with an intermediate collation ok( $t1, "Parsed test fragment file" ); my $c1 = $t1->collation; -my $trel = $c1->get_relationship( '9,2', '9,3' ); +my $trel = $c1->get_relationship( 'r9.2', 'r9.3' ); is( ref( $trel ), 'Text::Tradition::Collation::Relationship', "Troublesome relationship exists" ); is( $trel->type, 'collated', "Troublesome relationship is a collation" ); # Try to make the link we want try { - $c1->add_relationship( '8,6', '10,3', { 'type' => 'orthographic' } ); + $c1->add_relationship( 'r8.6', 'r10.3', { 'type' => 'orthographic' } ); ok( 1, "Added cross-collation relationship as expected" ); } catch( Text::Tradition::Error $e ) { ok( 0, "Existing collation blocked equivalence relationship: " . $e->message ); @@ -289,7 +289,7 @@ try { # Test 1.2: attempt merge of an identical reading try { - $c1->merge_readings( '9,3', '11,5' ); + $c1->merge_readings( 'r9.3', 'r11.5' ); ok( 1, "Successfully merged reading 'pontifex'" ); } catch ( Text::Tradition::Error $e ) { ok( 0, "Merge of mergeable readings failed: $e->message" ); @@ -298,7 +298,7 @@ try { # Test 1.3: attempt relationship with a meta reading (should fail) try { - $c1->add_relationship( '8,1', '9,2', { 'type' => 'collated' } ); + $c1->add_relationship( 'r8.1', 'r9.2', { 'type' => 'collated' } ); ok( 0, "Allowed a meta-reading to be used in a relationship" ); } catch ( Text::Tradition::Error $e ) { is( $e->message, 'Cannot set relationship on a meta reading', @@ -309,14 +309,14 @@ try { # equivalence my $t2 = Text::Tradition->new( 'input' => 'Self', 'file' => 't/data/legendfrag.xml' ); my $c2 = $t2->collation; -$c2->add_relationship( '9,2', '9,3', { 'type' => 'lexical' } ); -my $trel2 = $c2->get_relationship( '9,2', '9,3' ); +$c2->add_relationship( 'r9.2', 'r9.3', { 'type' => 'lexical' } ); +my $trel2 = $c2->get_relationship( 'r9.2', 'r9.3' ); is( ref( $trel2 ), 'Text::Tradition::Collation::Relationship', "Created blocking relationship" ); is( $trel2->type, 'lexical', "Blocking relationship is not a collation" ); # This time the link ought to fail try { - $c2->add_relationship( '8,6', '10,3', { 'type' => 'orthographic' } ); + $c2->add_relationship( 'r8.6', 'r10.3', { 'type' => 'orthographic' } ); ok( 0, "Added cross-equivalent bad relationship" ); } catch ( Text::Tradition::Error $e ) { like( $e->message, qr/witness loop/, @@ -335,13 +335,13 @@ my $t3 = Text::Tradition->new( 'input' => 'Self', 'file' => 't/data/lf2.xml' ); # Test 1: try to equate nodes that are prevented with an intermediate collation my $c3 = $t3->collation; try { - $c3->add_relationship( '36,4', '38,3', { 'type' => 'transposition' } ); + $c3->add_relationship( 'r36.4', 'r38.3', { 'type' => 'transposition' } ); ok( 1, "Added straightforward transposition" ); } catch ( Text::Tradition::Error $e ) { ok( 0, "Failed to add normal transposition: " . $e->message ); } try { - $c3->add_relationship( '36,3', '38,2', { 'type' => 'transposition' } ); + $c3->add_relationship( 'r36.3', 'r38.2', { 'type' => 'transposition' } ); ok( 1, "Added straightforward transposition complement" ); } catch ( Text::Tradition::Error $e ) { ok( 0, "Failed to add normal transposition complement: " . $e->message ); @@ -349,7 +349,7 @@ try { # Test 3.2: try to make a transposition that could be a parallel. try { - $c3->add_relationship( '28,2', '29,2', { 'type' => 'transposition' } ); + $c3->add_relationship( 'r28.2', 'r29.2', { 'type' => 'transposition' } ); ok( 0, "Added bad colocated transposition" ); } catch ( Text::Tradition::Error $e ) { like( $e->message, qr/Readings appear to be colocated/, @@ -358,13 +358,13 @@ try { # Test 3.3: make the parallel, and then make the transposition again. try { - $c3->add_relationship( '28,3', '29,3', { 'type' => 'orthographic' } ); + $c3->add_relationship( 'r28.3', 'r29.3', { 'type' => 'orthographic' } ); ok( 1, "Equated identical readings for transposition" ); } catch ( Text::Tradition::Error $e ) { ok( 0, "Failed to equate identical readings: " . $e->message ); } try { - $c3->add_relationship( '28,2', '29,2', { 'type' => 'transposition' } ); + $c3->add_relationship( 'r28.2', 'r29.2', { 'type' => 'transposition' } ); ok( 1, "Added straightforward transposition complement" ); } catch ( Text::Tradition::Error $e ) { ok( 0, "Failed to add normal transposition complement: " . $e->message ); @@ -760,14 +760,12 @@ sub _remove_equivalence_node { my $group = $self->equivalence( $node ); my $nodelist = $self->eqreadings( $group ); if( @$nodelist == 1 && $nodelist->[0] eq $node ) { - print STDERR "Removing equivalence $group for $node\n" if $node eq '451,2'; $self->remove_eqreadings( $group ); } elsif( @$nodelist == 1 ) { warn "DATA INCONSISTENCY in equivalence graph: " . $nodelist->[0] . " in group that should have only $node"; } else { - print STDERR "Removing $node from equivalence $group\n" if $node eq '451,2'; - my @newlist = grep { $_ ne $node } @$nodelist; + my @newlist = grep { $_ ne $node } @$nodelist; $self->set_eqreadings( $group, \@newlist ); $self->remove_equivalence( $node ); } @@ -798,8 +796,6 @@ sub delete_equivalence_edge { my( $self, $source, $target ) = @_; my $seq = $self->equivalence( $source ); my $teq = $self->equivalence( $target ); - print STDERR "Deleting equivalence edge $seq -> $teq for $source -> $target\n" - if grep { $_ eq '451,2' } @_; $self->equivalence_graph->delete_edge( $seq, $teq ); } @@ -817,12 +813,8 @@ sub _make_equivalence { my $teq = $self->equivalence( $target ); # Nothing to do if they are already equivalent... return if $seq eq $teq; - print STDERR "Making equivalence for $source -> $target\n" - if grep { $_ eq '451,2' } @_; my $sourcepool = $self->eqreadings( $seq ); # and add them to the target readings. - print STDERR "Moving readings '@$sourcepool' from group $seq to $teq\n" - if grep { $_ eq '451,2' } @_; push( @{$self->eqreadings( $teq )}, @$sourcepool ); map { $self->set_equivalence( $_, $teq ) } @$sourcepool; # Then merge the nodes in the equivalence graph. @@ -910,14 +902,8 @@ sub _break_equivalence { map { $tng{$_} = 1 } $self->_find_equiv_without( $target, $source ); # If these groups intersect, they are still connected; do nothing. foreach my $el ( keys %tng ) { - if( exists $sng{$el} ) { - print STDERR "Equivalence break $source / $target is a noop\n" - if grep { $_ eq '451,2' } @_; - return; - } + return if( exists $sng{$el} ); } - print STDERR "Breaking equivalence $source / $target\n" - if grep { $_ eq '451,2' } @_; # If they don't intersect, then we split the nodes in the graph and in # the hashes. First figure out which group has which name my $oldgroup = $self->equivalence( $source ); # same as $target diff --git a/lib/Text/Tradition/Parser/CTE.pm b/lib/Text/Tradition/Parser/CTE.pm index 49bcfe2..cf8a2e7 100644 --- a/lib/Text/Tradition/Parser/CTE.pm +++ b/lib/Text/Tradition/Parser/CTE.pm @@ -78,10 +78,10 @@ sub parse { $r = $c->add_reading( { id => 'n'.$counter++, text => $item->{'content'} } ); } elsif ( $item->{'type'} eq 'anchor' ) { - $r = $c->add_reading( { id => '#ANCHOR_' . $item->{'content'} . '#', + $r = $c->add_reading( { id => '__ANCHOR_' . $item->{'content'} . '__', is_ph => 1 } ); } elsif ( $item->{'type'} eq 'app' ) { - my $tag = '#APP_' . $counter++ . '#'; + my $tag = '__APP_' . $counter++ . '__'; $r = $c->add_reading( { id => $tag, is_ph => 1 } ); $apps{$tag} = $item->{'content'}; } @@ -207,14 +207,14 @@ sub _add_readings { # Get the lemma, which is all the readings between app and anchor, # excluding other apps or anchors. my @lemma = _return_lemma( $c, $app_id, $anchor ); - my $lemma_str = join( ' ', grep { $_ !~ /^\#/ } map { $_->text } @lemma ); + my $lemma_str = join( ' ', grep { $_ !~ /^__/ } map { $_->text } @lemma ); # For each reading, send its text to 'interpret' along with the lemma, # and then save the list of witnesses that these tokens belong to. my %wit_rdgs; # Maps from witnesses to the variant text my $ctr = 0; my $tag = $app_id; - $tag =~ s/^\#APP_(.*)\#$/$1/; + $tag =~ s/^\__APP_(.*)\__$/$1/; foreach my $rdg ( $xn->getChildrenByTagName( 'rdg' ) ) { my @text; @@ -230,11 +230,11 @@ sub _add_readings { my @rdg_nodes; if( $interpreted eq '#LACUNA#' ) { - push( @rdg_nodes, $c->add_reading( { id => $tag . "/" . $ctr++, + push( @rdg_nodes, $c->add_reading( { id => 'r'.$tag.".".$ctr++, is_lacuna => 1 } ) ); } else { foreach my $w ( split( /\s+/, $interpreted ) ) { - my $r = $c->add_reading( { id => $tag . "/" . $ctr++, + my $r = $c->add_reading( { id => 'r'.$tag.".".$ctr++, text => $w } ); push( @rdg_nodes, $r ); } @@ -272,12 +272,12 @@ sub _add_readings { sub _anchor_name { my $xmlid = shift; $xmlid =~ s/^\#//; - return sprintf( "#ANCHOR_%s#", $xmlid ); + return sprintf( "__ANCHOR_%s__", $xmlid ); } sub _return_lemma { my( $c, $app, $anchor ) = @_; - my @nodes = grep { $_->id !~ /^\#A(PP|NCHOR)/ } + my @nodes = grep { $_->id !~ /^__A(PP|NCHOR)/ } $c->reading_sequence( $c->reading( $app ), $c->reading( $anchor ), $c->baselabel ); return @nodes; diff --git a/lib/Text/Tradition/Parser/JSON.pm b/lib/Text/Tradition/Parser/JSON.pm index 1d618dc..0734856 100644 --- a/lib/Text/Tradition/Parser/JSON.pm +++ b/lib/Text/Tradition/Parser/JSON.pm @@ -207,7 +207,7 @@ sub make_nodes { if( exists( $unique{$word} ) ) { $rdg = $unique{$word}; } else { - my %args = ( 'id' => join( ',', $idx, $j+1 ), + my %args = ( 'id' => 'r' . join( '.', $idx, $j+1 ), 'rank' => $idx, 'text' => $word, 'collation' => $c ); diff --git a/lib/Text/Tradition/Parser/Self.pm b/lib/Text/Tradition/Parser/Self.pm index 432d8a3..5e92b9a 100644 --- a/lib/Text/Tradition/Parser/Self.pm +++ b/lib/Text/Tradition/Parser/Self.pm @@ -167,7 +167,10 @@ sub parse { } } - # Add the nodes to the graph. + # Add the nodes to the graph. + # Note any reading IDs that were changed in order to comply with XML + # name restrictions; we have to hardcode start & end. + my %namechange = ( '#START#' => '__START__', '#END#' => '__END__' ); # print STDERR "Adding collation readings\n"; foreach my $n ( @{$graph_data->{'nodes'}} ) { @@ -179,13 +182,20 @@ sub parse { next; } my $gnode = $collation->add_reading( $n ); + if( $gnode->id ne $n->{'id'} ) { + $namechange{$n->{'id'}} = $gnode->id; + } } # Now add the edges. # print STDERR "Adding collation path edges\n"; foreach my $e ( @{$graph_data->{'edges'}} ) { - my $from = $collation->reading( $e->{'source'}->{'id'} ); - my $to = $collation->reading( $e->{'target'}->{'id'} ); + my $sourceid = exists $namechange{$e->{'source'}->{'id'}} + ? $namechange{$e->{'source'}->{'id'}} : $e->{'source'}->{'id'}; + my $targetid = exists $namechange{$e->{'target'}->{'id'}} + ? $namechange{$e->{'target'}->{'id'}} : $e->{'target'}->{'id'}; + my $from = $collation->reading( $sourceid ); + my $to = $collation->reading( $targetid ); warn "No witness label on path edge!" unless $e->{'witness'}; my $label = $e->{'witness'} . ( $e->{'extra'} ? $collation->ac_label : '' ); @@ -206,8 +216,12 @@ sub parse { # TODO check that scoping does trt $rel_data->{'edges'} ||= []; # so that the next line doesn't break on no rels foreach my $e ( sort { _layersort_rel( $a, $b ) } @{$rel_data->{'edges'}} ) { - my $from = $collation->reading( $e->{'source'}->{'id'} ); - my $to = $collation->reading( $e->{'target'}->{'id'} ); + my $sourceid = exists $namechange{$e->{'source'}->{'id'}} + ? $namechange{$e->{'source'}->{'id'}} : $e->{'source'}->{'id'}; + my $targetid = exists $namechange{$e->{'target'}->{'id'}} + ? $namechange{$e->{'target'}->{'id'}} : $e->{'target'}->{'id'}; + my $from = $collation->reading( $sourceid ); + my $to = $collation->reading( $targetid ); delete $e->{'source'}; delete $e->{'target'}; # The remaining keys are relationship attributes. diff --git a/lib/Text/Tradition/Parser/Tabular.pm b/lib/Text/Tradition/Parser/Tabular.pm index b8e3439..0048f87 100644 --- a/lib/Text/Tradition/Parser/Tabular.pm +++ b/lib/Text/Tradition/Parser/Tabular.pm @@ -266,7 +266,7 @@ sub _make_nodes { my $ctr = 1; foreach my $w ( keys %unique ) { my $rargs = { - 'id' => "$index,$ctr", + 'id' => "r$index.$ctr", 'rank' => $index, 'text' => $w, }; diff --git a/t/text_tradition_collation.t b/t/text_tradition_collation.t index 8c29c02..bd2ebf3 100644 --- a/t/text_tradition_collation.t +++ b/t/text_tradition_collation.t @@ -149,12 +149,12 @@ my $c = $t->collation; is( $c->common_predecessor( 'n24', 'n23' )->id, 'n20', "Found correct common predecessor" ); is( $c->common_successor( 'n24', 'n23' )->id, - '#END#', "Found correct common successor" ); + '__END__', "Found correct common successor" ); is( $c->common_predecessor( 'n19', 'n17' )->id, 'n16', "Found correct common predecessor for readings on same path" ); is( $c->common_successor( 'n21', 'n10' )->id, - '#END#', "Found correct common successor for readings on same path" ); + '__END__', "Found correct common successor for readings on same path" ); } diff --git a/t/text_tradition_collation_relationshipstore.t b/t/text_tradition_collation_relationshipstore.t index 573b30e..16724a6 100644 --- a/t/text_tradition_collation_relationshipstore.t +++ b/t/text_tradition_collation_relationshipstore.t @@ -49,14 +49,14 @@ my $t1 = Text::Tradition->new( 'input' => 'Self', 'file' => 't/data/legendfrag.x # Test 1.1: try to equate nodes that are prevented with an intermediate collation ok( $t1, "Parsed test fragment file" ); my $c1 = $t1->collation; -my $trel = $c1->get_relationship( '9,2', '9,3' ); +my $trel = $c1->get_relationship( 'r9.2', 'r9.3' ); is( ref( $trel ), 'Text::Tradition::Collation::Relationship', "Troublesome relationship exists" ); is( $trel->type, 'collated', "Troublesome relationship is a collation" ); # Try to make the link we want try { - $c1->add_relationship( '8,6', '10,3', { 'type' => 'orthographic' } ); + $c1->add_relationship( 'r8.6', 'r10.3', { 'type' => 'orthographic' } ); ok( 1, "Added cross-collation relationship as expected" ); } catch( Text::Tradition::Error $e ) { ok( 0, "Existing collation blocked equivalence relationship: " . $e->message ); @@ -71,7 +71,7 @@ try { # Test 1.2: attempt merge of an identical reading try { - $c1->merge_readings( '9,3', '11,5' ); + $c1->merge_readings( 'r9.3', 'r11.5' ); ok( 1, "Successfully merged reading 'pontifex'" ); } catch ( Text::Tradition::Error $e ) { ok( 0, "Merge of mergeable readings failed: $e->message" ); @@ -80,7 +80,7 @@ try { # Test 1.3: attempt relationship with a meta reading (should fail) try { - $c1->add_relationship( '8,1', '9,2', { 'type' => 'collated' } ); + $c1->add_relationship( 'r8.1', 'r9.2', { 'type' => 'collated' } ); ok( 0, "Allowed a meta-reading to be used in a relationship" ); } catch ( Text::Tradition::Error $e ) { is( $e->message, 'Cannot set relationship on a meta reading', @@ -91,14 +91,14 @@ try { # equivalence my $t2 = Text::Tradition->new( 'input' => 'Self', 'file' => 't/data/legendfrag.xml' ); my $c2 = $t2->collation; -$c2->add_relationship( '9,2', '9,3', { 'type' => 'lexical' } ); -my $trel2 = $c2->get_relationship( '9,2', '9,3' ); +$c2->add_relationship( 'r9.2', 'r9.3', { 'type' => 'lexical' } ); +my $trel2 = $c2->get_relationship( 'r9.2', 'r9.3' ); is( ref( $trel2 ), 'Text::Tradition::Collation::Relationship', "Created blocking relationship" ); is( $trel2->type, 'lexical', "Blocking relationship is not a collation" ); # This time the link ought to fail try { - $c2->add_relationship( '8,6', '10,3', { 'type' => 'orthographic' } ); + $c2->add_relationship( 'r8.6', 'r10.3', { 'type' => 'orthographic' } ); ok( 0, "Added cross-equivalent bad relationship" ); } catch ( Text::Tradition::Error $e ) { like( $e->message, qr/witness loop/, @@ -117,13 +117,13 @@ my $t3 = Text::Tradition->new( 'input' => 'Self', 'file' => 't/data/lf2.xml' ); # Test 1: try to equate nodes that are prevented with an intermediate collation my $c3 = $t3->collation; try { - $c3->add_relationship( '36,4', '38,3', { 'type' => 'transposition' } ); + $c3->add_relationship( 'r36.4', 'r38.3', { 'type' => 'transposition' } ); ok( 1, "Added straightforward transposition" ); } catch ( Text::Tradition::Error $e ) { ok( 0, "Failed to add normal transposition: " . $e->message ); } try { - $c3->add_relationship( '36,3', '38,2', { 'type' => 'transposition' } ); + $c3->add_relationship( 'r36.3', 'r38.2', { 'type' => 'transposition' } ); ok( 1, "Added straightforward transposition complement" ); } catch ( Text::Tradition::Error $e ) { ok( 0, "Failed to add normal transposition complement: " . $e->message ); @@ -131,7 +131,7 @@ try { # Test 3.2: try to make a transposition that could be a parallel. try { - $c3->add_relationship( '28,2', '29,2', { 'type' => 'transposition' } ); + $c3->add_relationship( 'r28.2', 'r29.2', { 'type' => 'transposition' } ); ok( 0, "Added bad colocated transposition" ); } catch ( Text::Tradition::Error $e ) { like( $e->message, qr/Readings appear to be colocated/, @@ -140,13 +140,13 @@ try { # Test 3.3: make the parallel, and then make the transposition again. try { - $c3->add_relationship( '28,3', '29,3', { 'type' => 'orthographic' } ); + $c3->add_relationship( 'r28.3', 'r29.3', { 'type' => 'orthographic' } ); ok( 1, "Equated identical readings for transposition" ); } catch ( Text::Tradition::Error $e ) { ok( 0, "Failed to equate identical readings: " . $e->message ); } try { - $c3->add_relationship( '28,2', '29,2', { 'type' => 'transposition' } ); + $c3->add_relationship( 'r28.2', 'r29.2', { 'type' => 'transposition' } ); ok( 1, "Added straightforward transposition complement" ); } catch ( Text::Tradition::Error $e ) { ok( 0, "Failed to add normal transposition complement: " . $e->message );