=item * merge_types - Specify a list of relationship types, where related readings
should be treated as identical for the purposes of analysis.
+=item * exclude_type1 - Exclude those ranks whose groupings have only type-1 variants.
+
=back
=begin testing
my %lacunae;
foreach my $rank ( @ranks ) {
my $missing = [ @lacunose ];
- push( @groups, group_variants( $tradition, $rank, $missing, \@collapse ) );
+ my $rankgroup = group_variants( $tradition, $rank, $missing, \@collapse );
+ if( $opts{'exclude_type1'} ) {
+ # Check to see whether this is a "useful" group.
+ my( $rdgs, $grps ) = _useful_variant( $rankgroup );
+ next unless @$rdgs;
+ }
+ push( @groups, $rankgroup );
$lacunae{$rank} = $missing;
}
$DB::single = 1;
be a reference to an array, to which the sigla of lacunose witnesses at this
rank will be appended.
-Returns two ordered lists $readings, $groups, where $readings->[$n] is attested
-by the witnesses listed in $groups->[$n].
+Returns a hash $group_readings where $rdg is attested by the witnesses listed
+in $group_readings->{$rdg}.
=cut
ok( $c->reading( 'n21p0' ), "New reading exists" );
is( scalar $c->readings, $rno, "Reading add offset by flatten_ranks" );
-# Combine n3 and n4
+# Combine n3 and n4 ( with his )
$c->merge_readings( 'n3', 'n4', 1 );
ok( !$c->reading('n4'), "Reading n4 is gone" );
is( $c->reading('n3')->text, 'with his', "Reading n3 has both words" );
-# Collapse n25 and n26
-$c->merge_readings( 'n25', 'n26' );
-ok( !$c->reading('n26'), "Reading n26 is gone" );
-is( $c->reading('n25')->text, 'rood', "Reading n25 has an unchanged word" );
+# Collapse n9 and n10 ( rood / root )
+$c->merge_readings( 'n9', 'n10' );
+ok( !$c->reading('n10'), "Reading n10 is gone" );
+is( $c->reading('n9')->text, 'rood', "Reading n9 has an unchanged word" );
# Combine n21 and n21p0
my $remaining = $c->reading('n21');
is( $c->alignment_table, $table, "Cached table returned upon second call" );
$c->calculate_ranks;
is( $c->alignment_table, $table, "Cached table retained with no rank change" );
-$c->add_relationship( 'n9', 'n23', { 'type' => 'spelling' } );
+$c->add_relationship( 'n24', 'n23', { 'type' => 'spelling' } );
isnt( $c->alignment_table, $table, "Alignment table changed after relationship add" );
=end testing
is( scalar @common, 8, "Found correct number of common readings" );
my @marked = sort $c->common_readings();
is( scalar @common, 8, "All common readings got marked as such" );
-my @expected = qw/ n1 n12 n16 n19 n20 n5 n6 n7 /;
+my @expected = qw/ n1 n11 n16 n19 n20 n5 n6 n7 /;
is_deeply( \@marked, \@expected, "Found correct list of common readings" );
=end testing
);
my $c = $t->collation;
-is( $c->common_predecessor( 'n9', 'n23' )->id,
+is( $c->common_predecessor( 'n24', 'n23' )->id,
'n20', "Found correct common predecessor" );
-is( $c->common_successor( 'n9', 'n23' )->id,
+is( $c->common_successor( 'n24', 'n23' )->id,
'#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', 'n26' )->id,
+is( $c->common_successor( 'n21', 'n10' )->id,
'#END#', "Found correct common successor for readings on same path" );
=end testing
is( scalar @v1, 1, "Added a single relationship" );
is( $v1[0]->[0], 'n21', "Got correct node 1" );
is( $v1[0]->[1], 'n22', "Got correct node 2" );
-my @v2 = $c->add_relationship( 'n9', 'n23',
+my @v2 = $c->add_relationship( 'n24', 'n23',
{ 'type' => 'spelling', 'scope' => 'global' } );
is( scalar @v2, 2, "Added a global relationship with two instances" );
@v1 = $c->del_relationship( 'n22', 'n21' );
is( scalar @v1, 1, "Deleted first relationship" );
-@v2 = $c->del_relationship( 'n8', 'n13' );
+@v2 = $c->del_relationship( 'n12', 'n13' );
is( scalar @v2, 2, "Deleted second global relationship" );
my @v3 = $c->del_relationship( 'n1', 'n2' );
is( scalar @v3, 0, "Nothing deleted on non-existent relationship" );
'file' => $cxfile,
);
-is( ref( $t ), 'Text::Tradition', "Parsed our own GraphML" );
+is( ref( $t ), 'Text::Tradition', "Parsed a CollateX input" );
if( $t ) {
is( scalar $t->collation->readings, 26, "Collation has all readings" );
is( scalar $t->collation->paths, 32, "Collation has all paths" );
my $transposed = $t->collation->reading( 'n15' );
my @related = $transposed->related_readings;
is( scalar @related, 1, "Reading links to transposed version" );
- is( $related[0]->id, 'n17', "Correct transposition link" );
+ is( $related[0]->id, 'n18', "Correct transposition link" );
}
=end testing
=cut
my $IDKEY = 'number';
-my $CONTENTKEY = 'token';
-my $TRANSKEY = 'identical';
+my $CONTENTKEY = 'tokens';
+my $EDGETYPEKEY = 'type';
+my $WITKEY = 'witnesses';
sub parse {
my( $tradition, $opts ) = @_;
my $collation = $tradition->collation;
# First add the readings to the graph.
- my $extra_data = {}; # Keep track of info to be processed after all
- # nodes have been created
+ ## Assume the start node has no text and id 0, and the end node has
+ ## no text and ID [number of nodes] - 1.
+ my $endnode = scalar @{$graph_data->{'nodes'}} - 1;
foreach my $n ( @{$graph_data->{'nodes'}} ) {
unless( defined $n->{$IDKEY} && defined $n->{$CONTENTKEY} ) {
- warn "Did not find an ID or token for graph node, can't add it";
+ if( defined $n->{$IDKEY} && $n->{$IDKEY} == 0 ) {
+ # It's the start node.
+ $n->{$IDKEY} = $collation->start->id;
+ } elsif ( defined $n->{$IDKEY} && $n->{$IDKEY} == $endnode ) {
+ # It's the end node.
+ $n->{$IDKEY} = $collation->end->id;
+ } else {
+ # Something is probably wrong.
+ warn "Did not find an ID or token for graph node, can't add it";
+ }
next;
}
- my %node_data = %$n;
+ # Node ID should be an XML name, so prepend an 'n' if necessary.
+ if( $n->{$IDKEY} =~ /^\d/ ) {
+ $n->{$IDKEY} = 'n' . $n->{$IDKEY};
+ }
+ # Create the reading.
my $gnode_args = {
- 'id' => delete $node_data{$IDKEY},
- 'text' => delete $node_data{$CONTENTKEY},
+ 'id' => $n->{$IDKEY},
+ 'text' => $n->{$CONTENTKEY},
};
my $gnode = $collation->add_reading( $gnode_args );
-
- # Whatever is left is extra info to be processed later,
- # e.g. a transposition link.
- if( keys %node_data ) {
- $extra_data->{$gnode->id} = \%node_data;
- }
}
# Now add the path edges.
foreach my $e ( @{$graph_data->{'edges'}} ) {
- my %edge_data = %$e;
- my $from = delete $edge_data{'source'};
- my $to = delete $edge_data{'target'};
-
- # In CollateX, we have a distinct witness data ID per witness,
- # so that we can have multiple witnesses per edge. We want to
- # translate this to one witness per edge in our own
- # representation.
- foreach my $ekey ( keys %edge_data ) {
- my $wit = $edge_data{$ekey};
- # Create the witness object if it does not yet exist.
- unless( $tradition->witness( $wit ) ) {
- $tradition->add_witness( 'sigil' => $wit );
- }
- $collation->add_path( $from->{$IDKEY}, $to->{$IDKEY}, $wit );
+ my $from = $e->{'source'};
+ my $to = $e->{'target'};
+
+ ## Edge data keys are ID (which we don't need), witnesses, and type.
+ ## Type can be 'path' or 'relationship';
+ ## witnesses is a comma-separated list.
+ if( $e->{$EDGETYPEKEY} eq 'path' ) {
+ ## Add the path for each witness listesd.
+ # Create the witness objects if they does not yet exist.
+ foreach my $wit ( split( /, /, $e->{$WITKEY} ) ) {
+ unless( $tradition->witness( $wit ) ) {
+ $tradition->add_witness( 'sigil' => $wit );
+ }
+ $collation->add_path( $from->{$IDKEY}, $to->{$IDKEY}, $wit );
+ }
+ } else { # type 'relationship'
+ $collation->add_relationship( $from->{$IDKEY}, $to->{$IDKEY},
+ { 'type' => 'transposition' } );
}
}
- # Process the extra node data if it exists.
- foreach my $nodeid ( keys %$extra_data ) {
- my $ed = $extra_data->{$nodeid};
- if( exists $ed->{$TRANSKEY} ) {
- my $tn_reading = $collation->reading( $nodeid );
- my $main_reading = $collation->reading( $ed->{$TRANSKEY} );
- if( $collation->linear ) {
- $collation->add_relationship( $tn_reading, $main_reading,
- { type => 'transposition' } );
- } else {
- $collation->merge_readings( $main_reading, $tn_reading );
- }
- } # else we don't have any other tags to process yet.
- }
-
- # Find the beginning and end nodes of the graph. The beginning node
- # has no incoming edges; the end node has no outgoing edges.
- my( $begin_node, $end_node );
- my @starts = $collation->sequence->source_vertices();
- my @ends = $collation->sequence->sink_vertices();
- if( @starts != 1 ) {
- warn "Found more or less than one start vertex: @starts";
- } else {
- $collation->merge_readings( $collation->start, @starts );
- }
- if( @ends != 1 ) {
- warn "Found more or less than one end vertex: @ends";
- } else {
- $collation->merge_readings( $collation->end, @ends );
- }
-
# Rank the readings.
$collation->calculate_common_readings(); # will implicitly rank
$c->stash->{text_title} = $tradition->name;
$c->stash->{template} = 'stexaminer.tt';
# TODO Run the analysis as AJAX from the loaded page.
- my $t = run_analysis( $tradition );
+ my $t = run_analysis( $tradition, 'exclude_type1' => 1 );
# Stringify the reading groups
foreach my $loc ( @{$t->{'variants'}} ) {
my $mst = wit_stringify( $loc->{'missing'} );
padding-top: 5px;
padding-bottom: 5px;
}
+#loading_overlay {
+ display: none;
+ position: absolute;
+ height: 500px;
+ width: 89%;
+ z-index: 2;
+ opacity: 0.7;
+ background-color: #c5c5c5;
+}
#dialog_overlay {
display: none;
position: absolute;
}
function svgEnlargementLoaded() {
+ //Give some visual evidence that we are working
+ $('#loading_overlay').show();
//Set viewbox widht and height to widht and height of $('#svgenlargement svg').
//This is essential to make sure zooming and panning works properly.
$('#svgenlargement ellipse').attr( {stroke:'green', fill:'#b3f36d'} );
//used to calculate min and max zoom level:
start_element_height = $("#svgenlargement .node title:contains('#START#')").siblings('ellipse')[0].getBBox().height;
add_relations();
+ // $('#loading_overlay').hide();
}
function add_relations() {
</div>
<div id="enlargement_container">
+ <div id="loading_overlay"></div>
<div id="enlargement">
<div id="svgenlargement" style="height: 500px;"></div>
</div>
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
- <key attr.name="number" attr.type="int" for="node" id="d1"/>
- <key attr.name="token" attr.type="string" for="node" id="d0"/>
- <key attr.name="identical" attr.type="string" for="node" id="d2"/>
- <key attr.name="A" attr.type="string" for="edge" id="w0"/>
- <key attr.name="B" attr.type="string" for="edge" id="w1"/>
- <key attr.name="C" attr.type="string" for="edge" id="w2"/>
- <graph edgedefault="directed" id="g0" parse.edgeids="canonical" parse.edges="32" parse.nodeids="canonical" parse.nodes="26" parse.order="nodesfirst">
+<?xml version="1.0" ?>
+<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
+ xmlns:xsi="http://www.C.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
+ <key id="d0" for="node" attr.name="number" attr.type="int"/>
+ <key id="d1" for="node" attr.name="tokens" attr.type="string"/>
+ <key id="d2" for="edge" attr.name="number" attr.type="int"/>
+ <key id="d3" for="edge" attr.name="type" attr.type="string"/>
+ <key id="d4" for="edge" attr.name="witnesses" attr.type="string"/>
+ <graph id="g0" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical"
+ parse.order="nodesfirst">
<node id="n0">
- <data key="d0">#</data>
- <data key="d1">n0</data>
+ <data key="d0">0</data>
+ <data key="d1"/>
</node>
<node id="n1">
- <data key="d0">when</data>
- <data key="d1">n1</data>
+ <data key="d0">1</data>
+ <data key="d1">when</data>
</node>
<node id="n2">
- <data key="d0">april</data>
- <data key="d1">n2</data>
+ <data key="d0">2</data>
+ <data key="d1">april</data>
</node>
<node id="n3">
- <data key="d0">with</data>
- <data key="d1">n3</data>
+ <data key="d0">3</data>
+ <data key="d1">with</data>
</node>
<node id="n4">
- <data key="d0">his</data>
- <data key="d1">n4</data>
+ <data key="d0">4</data>
+ <data key="d1">his</data>
</node>
<node id="n5">
- <data key="d0">showers</data>
- <data key="d1">n5</data>
+ <data key="d0">5</data>
+ <data key="d1">showers</data>
</node>
<node id="n6">
- <data key="d0">sweet</data>
- <data key="d1">n6</data>
+ <data key="d0">6</data>
+ <data key="d1">sweet</data>
</node>
<node id="n7">
- <data key="d0">with</data>
- <data key="d1">n7</data>
- </node>
- <node id="n8">
- <data key="d0">teh</data>
- <data key="d1">n8</data>
- </node>
- <node id="n9">
- <data key="d0">teh</data>
- <data key="d1">n9</data>
- </node>
+ <data key="d0">7</data>
+ <data key="d1">with</data>
+ </node>
+ <node id="n8">
+ <data key="d0">8</data>
+ <data key="d1">april</data>
+ </node>
+ <node id="n9">
+ <data key="d0">11</data>
+ <data key="d1">fruit</data>
+ </node>
+ <node id="n10">
+ <data key="d0">12</data>
+ <data key="d1">the</data>
+ </node>
<node id="n11">
- <data key="d0">april</data>
- <data key="d1">n11</data>
- <data key="d2">n2</data>
+ <data key="d0">13</data>
+ <data key="d1">teh</data>
</node>
<node id="n12">
- <data key="d0">fruit</data>
- <data key="d1">n12</data>
+ <data key="d0">14</data>
+ <data key="d1">march</data>
</node>
<node id="n13">
- <data key="d0">the</data>
- <data key="d1">n13</data>
+ <data key="d0">15</data>
+ <data key="d1">drought</data>
</node>
<node id="n14">
- <data key="d0">drought</data>
- <data key="d1">n14</data>
+ <data key="d0">16</data>
+ <data key="d1">of</data>
</node>
<node id="n15">
- <data key="d0">march</data>
- <data key="d1">n15</data>
- <data key="d2">n17</data>
+ <data key="d0">17</data>
+ <data key="d1">march</data>
</node>
<node id="n16">
- <data key="d0">of</data>
- <data key="d1">n16</data>
+ <data key="d0">18</data>
+ <data key="d1">drought</data>
</node>
<node id="n17">
- <data key="d0">march</data>
- <data key="d1">n17</data>
+ <data key="d0">19</data>
+ <data key="d1">has</data>
</node>
<node id="n18">
- <data key="d0">drought</data>
- <data key="d1">n18</data>
- <data key="d2">n14</data>
+ <data key="d0">20</data>
+ <data key="d1">pierced</data>
</node>
<node id="n19">
- <data key="d0">has</data>
- <data key="d1">n19</data>
+ <data key="d0">21</data>
+ <data key="d1">unto</data>
</node>
<node id="n20">
- <data key="d0">pierced</data>
- <data key="d1">n20</data>
+ <data key="d0">22</data>
+ <data key="d1">to</data>
</node>
<node id="n21">
- <data key="d0">unto</data>
- <data key="d1">n21</data>
+ <data key="d0">23</data>
+ <data key="d1">teh</data>
</node>
<node id="n22">
- <data key="d0">to</data>
- <data key="d1">n22</data>
+ <data key="d0">24</data>
+ <data key="d1">the</data>
</node>
<node id="n23">
- <data key="d0">the</data>
- <data key="d1">n23</data>
+ <data key="d0">9</data>
+ <data key="d1">rood</data>
</node>
- <node id="n25">
- <data key="d0">rood</data>
- <data key="d1">n25</data>
- </node>
- <node id="n26">
- <data key="d0">root</data>
- <data key="d1">n26</data>
+ <node id="n24">
+ <data key="d0">10</data>
+ <data key="d1">root</data>
</node>
- <node id="n27">
- <data key="d0">#</data>
- <data key="d1">n27</data>
+ <node id="n25">
+ <data key="d0">25</data>
+ <data key="d1"/>
</node>
<edge id="e0" source="n0" target="n1">
- <data key="w0">A</data>
- <data key="w2">C</data>
- <data key="w1">B</data>
+ <data key="d2">0</data>
+ <data key="d3">path</data>
+ <data key="d4">A, B, C</data>
</edge>
<edge id="e1" source="n1" target="n2">
- <data key="w0">A</data>
+ <data key="d2">1</data>
+ <data key="d3">path</data>
+ <data key="d4">A</data>
</edge>
- <edge id="e2" source="n2" target="n3">
- <data key="w0">A</data>
+ <edge id="e2" source="n1" target="n5">
+ <data key="d2">2</data>
+ <data key="d3">path</data>
+ <data key="d4">B, C</data>
</edge>
- <edge id="e3" source="n3" target="n4">
- <data key="w0">A</data>
+ <edge id="e3" source="n2" target="n3">
+ <data key="d2">3</data>
+ <data key="d3">path</data>
+ <data key="d4">A</data>
</edge>
- <edge id="e4" source="n4" target="n5">
- <data key="w0">A</data>
+ <edge id="e4" source="n8" target="n9">
+ <data key="d2">4</data>
+ <data key="d3">path</data>
+ <data key="d4">B, C</data>
</edge>
<edge id="e5" source="n5" target="n6">
- <data key="w0">A</data>
- <data key="w1">B</data>
- <data key="w2">C</data>
+ <data key="d2">5</data>
+ <data key="d3">path</data>
+ <data key="d4">A, B, C</data>
+ </edge>
+ <edge id="e6" source="n3" target="n4">
+ <data key="d2">6</data>
+ <data key="d3">path</data>
+ <data key="d4">A</data>
+ </edge>
+ <edge id="e7" source="n9" target="n10">
+ <data key="d2">7</data>
+ <data key="d3">path</data>
+ <data key="d4">A, B</data>
+ </edge>
+ <edge id="e8" source="n9" target="n11">
+ <data key="d2">8</data>
+ <data key="d3">path</data>
+ <data key="d4">C</data>
+ </edge>
+ <edge id="e9" source="n6" target="n7">
+ <data key="d2">9</data>
+ <data key="d3">path</data>
+ <data key="d4">A, B, C</data>
+ </edge>
+ <edge id="e10" source="n7" target="n8">
+ <data key="d2">10</data>
+ <data key="d3">path</data>
+ <data key="d4">B, C</data>
+ </edge>
+ <edge id="e11" source="n10" target="n13">
+ <data key="d2">11</data>
+ <data key="d3">path</data>
+ <data key="d4">A</data>
</edge>
- <edge id="e6" source="n6" target="n7">
- <data key="w0">A</data>
- <data key="w1">B</data>
- <data key="w2">C</data>
+ <edge id="e12" source="n10" target="n12">
+ <data key="d2">12</data>
+ <data key="d3">path</data>
+ <data key="d4">B</data>
</edge>
- <edge id="e7" source="n1" target="n5">
- <data key="w2">C</data>
- <data key="w1">B</data>
+ <edge id="e13" source="n11" target="n13">
+ <data key="d2">13</data>
+ <data key="d3">path</data>
+ <data key="d4">C</data>
</edge>
- <edge id="e8" source="n12" target="n8">
- <data key="w2">C</data>
- </edge>
- <edge id="e9" source="n8" target="n14">
- <data key="w2">C</data>
- </edge>
- <edge id="e10" source="n7" target="n11">
- <data key="w2">C</data>
- <data key="w1">B</data>
+ <edge id="e14" source="n7" target="n9">
+ <data key="d2">14</data>
+ <data key="d3">path</data>
+ <data key="d4">A</data>
</edge>
- <edge id="e11" source="n7" target="n12">
- <data key="w0">A</data>
+ <edge id="e15" source="n3" target="n4">
+ <data key="d2">15</data>
+ <data key="d3">path</data>
+ <data key="d4">A</data>
</edge>
- <edge id="e12" source="n11" target="n12">
- <data key="w2">C</data>
- <data key="w1">B</data>
+ <edge id="e16" source="n13" target="n14">
+ <data key="d2">16</data>
+ <data key="d3">path</data>
+ <data key="d4">A, C</data>
</edge>
- <edge id="e13" source="n12" target="n13">
- <data key="w0">A</data>
- <data key="w1">B</data>
+ <edge id="e17" source="n12" target="n14">
+ <data key="d2">17</data>
+ <data key="d3">path</data>
+ <data key="d4">B</data>
</edge>
- <edge id="e14" source="n13" target="n14">
- <data key="w0">A</data>
+ <edge id="e18" source="n4" target="n5">
+ <data key="d2">18</data>
+ <data key="d3">path</data>
+ <data key="d4">A</data>
</edge>
- <edge id="e15" source="n13" target="n15">
- <data key="w1">B</data>
+ <edge id="e19" source="n14" target="n15">
+ <data key="d2">19</data>
+ <data key="d3">path</data>
+ <data key="d4">A, C</data>
</edge>
- <edge id="e16" source="n14" target="n16">
- <data key="w0">A</data>
- <data key="w2">C</data>
+ <edge id="e20" source="n14" target="n16">
+ <data key="d2">20</data>
+ <data key="d3">path</data>
+ <data key="d4">B</data>
</edge>
- <edge id="e17" source="n15" target="n16">
- <data key="w1">B</data>
+ <edge id="e22" source="n15" target="n17">
+ <data key="d2">22</data>
+ <data key="d3">path</data>
+ <data key="d4">A, C</data>
</edge>
- <edge id="e18" source="n16" target="n17">
- <data key="w0">A</data>
- <data key="w2">C</data>
+ <edge id="e23" source="n16" target="n17">
+ <data key="d2">23</data>
+ <data key="d3">path</data>
+ <data key="d4">B</data>
</edge>
- <edge id="e19" source="n16" target="n18">
- <data key="w1">B</data>
+ <edge id="e24" source="n17" target="n18">
+ <data key="d2">24</data>
+ <data key="d3">path</data>
+ <data key="d4">A, B, C</data>
</edge>
- <edge id="e20" source="n17" target="n19">
- <data key="w0">A</data>
- <data key="w2">C</data>
+ <edge id="e25" source="n18" target="n19">
+ <data key="d2">25</data>
+ <data key="d3">path</data>
+ <data key="d4">A</data>
</edge>
- <edge id="e21" source="n18" target="n19">
- <data key="w1">B</data>
+ <edge id="e26" source="n18" target="n20">
+ <data key="d2">26</data>
+ <data key="d3">path</data>
+ <data key="d4">B</data>
</edge>
- <edge id="e22" source="n19" target="n20">
- <data key="w0">A</data>
- <data key="w2">C</data>
- <data key="w1">B</data>
+ <edge id="e27" source="n18" target="n21">
+ <data key="d2">27</data>
+ <data key="d3">path</data>
+ <data key="d4">C</data>
</edge>
- <edge id="e23" source="n20" target="n21">
- <data key="w0">A</data>
+ <edge id="e28" source="n19" target="n22">
+ <data key="d2">28</data>
+ <data key="d3">path</data>
+ <data key="d4">A</data>
</edge>
- <edge id="e24" source="n20" target="n22">
- <data key="w1">B</data>
+ <edge id="e29" source="n20" target="n22">
+ <data key="d2">29</data>
+ <data key="d3">path</data>
+ <data key="d4">B</data>
</edge>
- <edge id="e25" source="n21" target="n23">
- <data key="w0">A</data>
+ <edge id="e30" source="n21" target="n23">
+ <data key="d2">30</data>
+ <data key="d3">path</data>
+ <data key="d4">C</data>
</edge>
- <edge id="e26" source="n22" target="n23">
- <data key="w1">B</data>
+ <edge id="e31" source="n22" target="n24">
+ <data key="d2">31</data>
+ <data key="d3">path</data>
+ <data key="d4">A, B</data>
</edge>
- <edge id="e27" source="n20" target="n9">
- <data key="w2">C</data>
+ <edge id="e32" source="n23" target="n25">
+ <data key="d2">32</data>
+ <data key="d3">path</data>
+ <data key="d4">C</data>
</edge>
- <edge id="e28" source="n9" target="n25">
- <data key="w2">C</data>
+ <edge id="e33" source="n24" target="n25">
+ <data key="d2">33</data>
+ <data key="d3">path</data>
+ <data key="d4">A, B</data>
</edge>
- <edge id="e29" source="n23" target="n26">
- <data key="w0">A</data>
- <data key="w1">B</data>
+ <edge id="e36" source="n8" target="n2">
+ <data key="d2">36</data>
+ <data key="d3">transposition</data>
</edge>
- <edge id="e30" source="n26" target="n27">
- <data key="w0">A</data>
- <data key="w1">B</data>
+ <edge id="e37" source="n13" target="n16">
+ <data key="d2">37</data>
+ <data key="d3">transposition</data>
</edge>
- <edge id="e31" source="n25" target="n27">
- <data key="w2">C</data>
+ <edge id="e38" source="n15" target="n12">
+ <data key="d2">38</data>
+ <data key="d3">transposition</data>
</edge>
</graph>
</graphml>
-
);
# Set up some relationships
my $c = $tradition->collation;
-$c->add_relationship( 'n25', 'n26', { 'type' => 'spelling' } );
-$c->add_relationship( 'n9', 'n23', { 'type' => 'spelling' } );
-$c->add_relationship( 'n8', 'n13', { 'type' => 'spelling' } );
+$c->add_relationship( 'n23', 'n24', { 'type' => 'spelling' } );
+$c->add_relationship( 'n9', 'n10', { 'type' => 'spelling' } );
+$c->add_relationship( 'n12', 'n13', { 'type' => 'spelling' } );
$c->calculate_ranks();
my $stemma = $tradition->add_stemma( dotfile => 't/data/simple.dot' );
unless( exists $expected_genealogical{$row->{'id'}} ) {
$expected_genealogical{$row->{'id'}} = 1;
}
- my $gen_bool = $row->{'genealogical'} ? 1 : 0;
- is( $gen_bool, $expected_genealogical{$row->{'id'}},
+ is( $row->{'genealogical'}, $expected_genealogical{$row->{'id'}},
"Got correct genealogical flag for row " . $row->{'id'} );
}
is( $data->{'variant_count'}, 58, "Got right total variant number" );
ok( $c->reading( 'n21p0' ), "New reading exists" );
is( scalar $c->readings, $rno, "Reading add offset by flatten_ranks" );
-# Combine n3 and n4
+# Combine n3 and n4 ( with his )
$c->merge_readings( 'n3', 'n4', 1 );
ok( !$c->reading('n4'), "Reading n4 is gone" );
is( $c->reading('n3')->text, 'with his', "Reading n3 has both words" );
-# Collapse n25 and n26
-$c->merge_readings( 'n25', 'n26' );
-ok( !$c->reading('n26'), "Reading n26 is gone" );
-is( $c->reading('n25')->text, 'rood', "Reading n25 has an unchanged word" );
+# Collapse n9 and n10 ( rood / root )
+$c->merge_readings( 'n9', 'n10' );
+ok( !$c->reading('n10'), "Reading n10 is gone" );
+is( $c->reading('n9')->text, 'rood', "Reading n9 has an unchanged word" );
# Combine n21 and n21p0
my $remaining = $c->reading('n21');
is( $c->alignment_table, $table, "Cached table returned upon second call" );
$c->calculate_ranks;
is( $c->alignment_table, $table, "Cached table retained with no rank change" );
-$c->add_relationship( 'n9', 'n23', { 'type' => 'spelling' } );
+$c->add_relationship( 'n24', 'n23', { 'type' => 'spelling' } );
isnt( $c->alignment_table, $table, "Alignment table changed after relationship add" );
}
is( scalar @common, 8, "Found correct number of common readings" );
my @marked = sort $c->common_readings();
is( scalar @common, 8, "All common readings got marked as such" );
-my @expected = qw/ n1 n12 n16 n19 n20 n5 n6 n7 /;
+my @expected = qw/ n1 n11 n16 n19 n20 n5 n6 n7 /;
is_deeply( \@marked, \@expected, "Found correct list of common readings" );
}
);
my $c = $t->collation;
-is( $c->common_predecessor( 'n9', 'n23' )->id,
+is( $c->common_predecessor( 'n24', 'n23' )->id,
'n20', "Found correct common predecessor" );
-is( $c->common_successor( 'n9', 'n23' )->id,
+is( $c->common_successor( 'n24', 'n23' )->id,
'#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', 'n26' )->id,
+is( $c->common_successor( 'n21', 'n10' )->id,
'#END#', "Found correct common successor for readings on same path" );
}
is( scalar @v1, 1, "Added a single relationship" );
is( $v1[0]->[0], 'n21', "Got correct node 1" );
is( $v1[0]->[1], 'n22', "Got correct node 2" );
-my @v2 = $c->add_relationship( 'n9', 'n23',
+my @v2 = $c->add_relationship( 'n24', 'n23',
{ 'type' => 'spelling', 'scope' => 'global' } );
is( scalar @v2, 2, "Added a global relationship with two instances" );
@v1 = $c->del_relationship( 'n22', 'n21' );
is( scalar @v1, 1, "Deleted first relationship" );
-@v2 = $c->del_relationship( 'n8', 'n13' );
+@v2 = $c->del_relationship( 'n12', 'n13' );
is( scalar @v2, 2, "Deleted second global relationship" );
my @v3 = $c->del_relationship( 'n1', 'n2' );
is( scalar @v3, 0, "Nothing deleted on non-existent relationship" );
'file' => $cxfile,
);
-is( ref( $t ), 'Text::Tradition', "Parsed our own GraphML" );
+is( ref( $t ), 'Text::Tradition', "Parsed a CollateX input" );
if( $t ) {
is( scalar $t->collation->readings, 26, "Collation has all readings" );
is( scalar $t->collation->paths, 32, "Collation has all paths" );
my $transposed = $t->collation->reading( 'n15' );
my @related = $transposed->related_readings;
is( scalar @related, 1, "Reading links to transposed version" );
- is( $related[0]->id, 'n17', "Correct transposition link" );
+ is( $related[0]->id, 'n18', "Correct transposition link" );
}
}