# $Id$ # TeXLive::TeXCatalogue - module for accessing the TeX Catalogue # # Copyright 2007 Norbert Preining # This file is licensed under the GNU General Public License version 2 # or any later version. # # Loads of code taken from the catalogue checking script of Robin Fairbairns. use XML::DOM; package TeXLive::TeXCatalogue::Entry; sub new { my $class = shift; my %params = @_; my $self = { xmlfile => $params{'xmlfile'}, entry => defined($params{'entry'}) ? $params{'entry'} : {}, docs => defined($params{'docs'}) ? $params{'docs'} : {}, name => $params{'name'}, caption => $params{'caption'}, ctan => $params{'ctan'}, texlive => $params{'texlive'}, version => $params{'version'}, url => $params{'url'}, }; bless $self, $class; if (defined($self->{'xmlfile'})) { $self->initialize(); } return $self; } sub initialize { my $self = shift; my $parser = new XML::DOM::Parser; # parse all the files my $cat = $parser->parsefile ($self->{'xmlfile'}) || die "Failed to parse ", $self->{'xmlfile'}; # there's almost always only one, but... my $entryset = $cat -> getElementsByTagName ("entry"); my $entry = $entryset->item(0); # entry attributes my $entryid = $entry->getAttributeNode("id"); $self->{'entry'}{'id'} = $entryid->getValue; my $entrydate = $entry->getAttributeNode("datestamp"); if ($entrydate) { $self->{'entry'}{'date'} = $entrydate->getValue; } my $entrymodder = $entry->getAttributeNode("modifier"); if ($entrymodder) { $self->{'entry'}{'modder'} = $entrymodder->getValue; } # parse the rest of the entries # only the first name and caption is allowed # description CANNOT be parsed like this since it contains more childs!! # ( etc elements foreach my $k qw/name caption/ { $self->{$k} = $cat->getElementsByTagName($k)->item(0)->getFirstChild->toString; } $self->{'license'} = $cat->getElementsByTagName("license")->item(0)->getAttributeNode("type")->getValue; my $versnode = $cat->getElementsByTagName("version")->item(0); if ($versnode) { my $numnode = $versnode->getAttributeNode("number"); if ($numnode) { $self->{'version'} = $numnode->getValue; } } my $urlnode = $cat->getElementsByTagName("home")->item(0); if ($urlnode) { $self->{'url'} = $urlnode->getAttributeNode("href")->getValue; } $ctannode = $cat->getElementsByTagName("ctan")->item(0); if ($ctannode) { $self->{'ctan'} = $ctannode->getAttributeNode("path")->getValue; } my $tlnode = $cat->getElementsByTagName("texlive")->item(0); if ($tlnode) { $self->{'texlive'} = $tlnode->getAttributeNode("location")->getValue; } # parse the documentation entries my $doc = $cat->getElementsByTagName ("documentation"); for (my $i=0; $i < $doc->getLength; $i++ ) { my $node = $doc->item($i); my $docfile = $node->getAttributeNode("href")->getValue; my $detailsnode = $node->getAttributeNode("details"); if ($detailsnode) { $details = $detailsnode->getValue; } my $languagenode = $node->getAttributeNode("language"); if ($languagenode) { $language = $languagenode->getValue; } $self->{'docs'}{$docfile}{'available'} = 1; if ($details) { $self->{'docs'}{$docfile}{'details'} = $details; } if ($language) { $self->{'docs'}{$docfile}{'language'} = $language; } } $cat->dispose; } sub xmlfile { my $self = shift; if (@_) { $self->{'xmlfile'} = shift } return $self->{'xmlfile'}; } sub name { my $self = shift; if (@_) { $self->{'name'} = shift } return $self->{'name'}; } sub license { my $self = shift; if (@_) { $self->{'license'} = shift } return $self->{'license'}; } sub version { my $self = shift; if (@_) { $self->{'version'} = shift } return $self->{'version'}; } sub caption { my $self = shift; if (@_) { $self->{'caption'} = shift } return $self->{'caption'}; } sub url { my $self = shift; if (@_) { $self->{'url'} = shift } return $self->{'url'}; } sub ctan { my $self = shift; if (@_) { $self->{'ctan'} = shift } return $self->{'ctan'}; } sub texlive { my $self = shift; if (@_) { $self->{'texlive'} = shift } return $self->{'texlive'}; } sub docs { my $self = shift; my %newdocs = @_; if (@_) { $self->{'docs'} = \%newdocs } return $self->{'docs'}; } sub entry { my $self = shift; my %newentry = @_; if (@_) { $self->{'entry'} = \%newentry } return $self->{'entry'}; } ################################################################ # # TeXLive::TeXCatalogue # ################################################################ package TeXLive::TeXCatalogue; sub new { my $class = shift; my %params = @_; my $self = { location => $params{'location'}, entries => defined($params{'entries'}) ? $params{'entries'} : {}, }; bless $self, $class; if (defined($self->{'location'})) { $self->initialize(); } return $self; } sub initialize { my $self = shift; my $parser = new XML::DOM::Parser; # parse all the files foreach (glob($self->{'location'} . "/entries/?/*.xml")) { my $tce = TeXLive::TeXCatalogue::Entry->new( 'xmlfile' => "$_" ); $self->{'entries'}{$tce->name} = $tce; } } sub location { my $self = shift; if (@_) { $self->{'location'} = shift } return $self->{'location'}; } sub entries { my $self = shift; my %newentries = @_; if (@_) { $self->{'entries'} = \%newentries } return $self->{'entries'}; } 1; __END__ =head1 NAME TeXLive::TeXCatalogue - Accessing the TeX Catalogue =head1 SYNOPSIS missing =head1 DESCRIPTION The L module provides access to the data stored in the TeX Catalogue. DOCUMENTATION MISSING, SORRY!!! =head1 AUTHORS AND COPYRIGHT This script and its documentation were written for the TeX Live distribution (L) and both are licensed under the GNU General Public License Version 2 or later. =cut ### Local Variables: ### perl-indent-level: 2 ### tab-width: 2 ### indent-tabs-mode: nil ### End: # vim:set tabstop=2 expandtab: #