Data-Edit-Xml-Xref
view release on metacpan or search on metacpan
lib/Data/Edit/Xml/Xref.pm view on Meta::CPAN
</folder>
<folder name="Images">
$images
</folder>
<folder name="Resources">
$resources
</folder>
<folder name="Topics">
$topics
</folder>
</folder>
<folder name="CCX Content Repo (All)">
<folder path="../"/>
</folder>
</projectTree>
</project>
END
# $X->go_projectTree->last->by(sub # Cut out empty folders under the last folder otherwise we get lots of empty folders that contain no files because the files in them were not relevant to this bookmap
# {my ($f) = @_;
# $f->cutIfEmpty_folder;
# });
if ($@)
{cluck "Unable to parse generated oxygen project file:\n$@"
}
else
{my $text = Data::Edit::Xml::xmlHeader -p $X;
owf($out, $text);
}
} # createOxygenProjectFile
sub createOxygenProjectMapFiles($) #P Create Oxygen project files from Xref results
{my ($xref) = @_; # Cross referencer
my $xprName = sub # Method of choosing xpr file name
{my $x = $xref->oxygenProjects; # Method specified by caller
if (isSubInPackage(q(Data::Edit::Xml::Xref), q(xprName)))
{return sub {&Data::Edit::Xml::Xref::xprName(@_)} # Call supplied sub to generate xpr file name
}
return sub {my ($bm) = @_; setFileExtension($bm, q(xpr))} unless ref $x; # xpr file mirrors book map
}->();
processFilesInParallel
sub
{my ($bm) = @_;
createOxygenProjectFile($xref, $bm, $xprName);
},
sub {}, sort keys $xref->exteriorMaps->%*; # Only for exterior book maps - i.e. only book maps that not referenced by any other book map.
{} # Multiverse to universe
} # createOxygenProjectMapFiles
sub oneBadRef($$$) #P Check one reference and return the first error encountered or B<undef> if no errors encountered. Relies on L<topicIds> to test files present and test the B<topicId> is...
{my ($xref, $file, $href) = @_; # Cross referencer, file containing reference, reference
my $fileExists = sub # Check that the specified file exists by looking for the topic id which L<Dita> guarantees will exist
{my ($file) = @_; # File to check
return 1 if $xref->topicIds->{$file}; # File exists
my $decodedTarget = wwwDecode($file); # Decode file name by expanding % signs to see if we can get a match
return 2 if $xref->topicIds->{$decodedTarget}; # File exists after decoding % signs
return 3 if -e $file; # Images
undef # Cannot locate file
};
if ($href =~ m(#)) # Full Dita href
{my $sourceTopicId = $xref->topicIds->{$file}; # Source id for referencing file
my ($target, $topicId, $id) = parseDitaRef($href, $file, $sourceTopicId); # Parse full Dita href
my $targetFile = absFromAbsPlusRel($file, $target//$file); # Absolute target file which might be the current file
my $targetTopicId = $xref->topicIds->{$targetFile}; # Topic Id of target file
my $bad = sub # Report a bad reference
{my ($r) = @_; # Reason
[$r, $href, $target, $topicId, $id, $sourceTopicId,
$targetTopicId, $file, $targetFile];
};
return &$bad(q(No such file)) unless &$fileExists($targetFile); # Check target file exists
return &$bad(q(No topic id)) unless $targetTopicId; # Check the target has a topic id
return &$bad(q(Topic id does not match))
unless $targetTopicId eq $topicId or $topicId eq q(); # Check topic id of referenced topic against supplied topicId. It is safe to assume that the target does have topic id as Dita requires one
if ($id) # Checkid if supplied
{my $i = $xref->ids->{$target}{$id}; # Number of ids in the target topic with this value
return &$bad(q(No such id in target topic)) unless $i; # No such id
return &$bad(q(Duplicated id in target topic)) # Duplicate ids
unless $i == 1 or $i == 2 && $id eq $topicId; # Using dita topic references we can cope with one internal id that duplicates the topic id
}
}
else # No # in href
{my $targetFile = absFromAbsPlusRel($file, $href);
return [q(No such file), $href, $href, q(), q(), q(), q(),
$file, $targetFile] unless &$fileExists($targetFile); # Check target file exists
}
undef # No error to report
} # oneBadRef
#D0
# podDocumentation
=pod
=encoding utf-8
=head1 Name
Data::Edit::Xml::Xref - Cross reference Dita XML, match topics and ameliorate missing references.
=head1 Synopsis
L<Xref> scans an entire document corpus looking primarily for problems with
references between the files in the corpus; it reports any opportunities for
improvements it finds and makes changes to the corpus to implement these
improvements if so requested taking advantage of parallelism where ever
possible.
The following example checks the references in a corpus of Dita XML
documents held in folder L<inputFolder|/inputFolder>:
use Data::Edit::Xml::Xref;
( run in 1.562 second using v1.01-cache-2.11-cpan-995e09ba956 )