summaryrefslogtreecommitdiff
path: root/Master/tlpkg/dev/keyword-search/parse-texcatalogue-keywords
blob: 25cb5617a458a7109470828ba3bc43f40bb8392f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#!/usr/bin/env perl
# $Id$
# parse a TeXCatalogue v2 .xml dump containing keywords and
# characterizations 
# 
# Copyright 2010 Norbert Preining
# This file is licensed under the GNU General Public License version 2
# or any later version.

$^W = 1;
use strict;


use XML::Parser;
use XML::XPath;
use XML::XPath::XMLParser;
use Text::Unidecode;
use Data::Dumper;

my $tcfile;
if (@ARGV) {
  $tcfile = shift @ARGV;
} else {
  $tcfile = "texcatalogue.xml";
}

my %taxonomy;

parse_texcatalogue($tcfile);

$Data::Dumper::Indent = 1;
print Data::Dumper->Dump([\%taxonomy], ["taxonomy"]), $/;


# how to read in!!!
#my $taxonomy;
#my $foo = `cat tc-dump`;
# the no strict "vars" is *ABSOLUT* necessary otherwise the file is not
# evaluated, no idea why!
#no strict "vars";
#eval "$foo";
#use strict "vars";
#
#print_keywords($taxonomy->{'by-taxonomy'}{'keywords'});
#print "\n===================\nprimary characterizations\n";
#walk_cz_tree($taxonomy->{'by-taxonomy'}{'primary'}, "PRIM");
#print "\n===================\nsecondary characterizations\n";
#walk_cz_tree($taxonomy->{'by-taxonomy'}{'secondary'}, "SEC");
#print "\n===================\nfunctionality characterizations\n";
#walk_cz_tree($cz_pkg->{'by-taxonomy'}{'functionality'}, "BFUNC");

##### only subs from here ##########

sub parse_texcatalogue {
  my $tcfile = shift;
  my $_parser = XML::Parser->new(
    ErrorContext => 2,
    ParseParamEnt => 1,
    NoLWP => 1
  );
  my $io;
  open($io, "<", $tcfile) or die "Cannot open texcatalogue.xml: $!";
  my $parser = new XML::XPath->new(ioref => $io, parser => $_parser) ||
    die "Failed to parse texcatalogue.xml: $!";

  # format of the data
  # $taxonomy{'by-package'}{'keyword'}{$package} = [ $kwi, $kwii,...];
  # $taxonomy{'by-package'}{'primary'}{$package} = $primchar;
  # $taxonomy{'by-package'}{'secondary'}{$package'} = $secchar;
  # $taxonomy{'by-package'}{'functionality'}{$package} = [ $bfi, $bfii, ...];
  #
  # post processing gives
  # $taxonomy{'by-taxonomy'}{'keyword'}{$keyword} = [ $pkg1, $pkg2, ...];
  # $taxonomy{'by-taxonomy'}{'primary'}{$level1}{$level2}...{'_packages_'} = [ $pkg1, $pkg2, ...];
  # $taxonomy{'by-taxonomy'}{'secondary'}{$level1}{$level2}...{'_packages_'} = [ $pkg1, $pkg2, ...];
  # $taxonomy{'by-taxonomy'}{'functionality'}{$level1}{$level2}...{'_packages_'} = [ $pkg1, $pkg2, ...];


  foreach my $e ($parser->find('/fullcat/catalogue/entry')->get_nodelist) {
    my $pkg = $parser->findvalue('./name',$e)->value();
    #print "FOUND: $pkg\n";
    my $n = $parser->find('./keyword',$e);
    for my $kw ($n->get_nodelist) {
      my $kwval = $parser->find('./@keyword',$kw)->string_value();
      push @{$taxonomy{'by-package'}{'keyword'}{$pkg}}, $kwval;
      #print "keyword = $kwval\n";
    }
    $n = $parser->find('./characterization',$e);
    for my $cz ($n->get_nodelist) {
      my $czdimnl = $parser->find('./@dimension',$cz);
      my $czdim = $czdimnl->string_value();
      my $czvalnl = $parser->findvalue('.',$cz);
      my $czval = $czvalnl->value();
      if (($czdim eq "primary") || ($czdim eq "secondary")) {
        # assume only one primary and one secondary function
        $taxonomy{'by-package'}{$czdim}{$pkg} = $czval;
      } else {
        # assume that it is always "functionality"
        push @{$taxonomy{'by-package'}{'functionality'}{$pkg}}, $czval;
      }
      #print "char dim = $czdim val=$czval\n";
    }
  }


  #
  # do the keyword reshuffling
  for my $pkg (keys %{$taxonomy{'by-package'}{'keyword'}}) {
    for my $kw (@{$taxonomy{'by-package'}{'keyword'}{$pkg}}) {
      push @{$taxonomy{'by-taxonomy'}{'keyword'}{$kw}}, $pkg;
    }
  }

  parse_characterizations('primary');
  parse_characterizations('secondary');
  parse_characterizations('functionality');
}

sub parse_characterizations {
  my $what = shift;
  $taxonomy{'by-taxonomy'}{$what} = {};
  for my $pkg (keys %{$taxonomy{'by-package'}{$what}}) {
    my $value = $taxonomy{'by-package'}{$what}{$pkg};
    my @charlist;
    if (!ref($value)) {
      @charlist = ($value);
    } else {
      @charlist = @$value;
    }
    for my $prim (@charlist) {
      # split the primary into levels sep by >
      my @levels = split(' > ', $prim);
      my $currentpointer;
      $currentpointer = $taxonomy{'by-taxonomy'}{$what};
      for my $l (@levels) {
        if (!defined($currentpointer->{$l})) {
          $currentpointer->{$l} = {};
        }
        $currentpointer = $currentpointer->{$l}
      }
      push @{$currentpointer->{'_packages_'}}, $pkg;
    }
  }
}


sub print_keywords {
  my $kw_pkg = shift;
  for my $k (keys %$kw_pkg) {
    my @pkgl = @{$kw_pkg->{$k}};
    if (defined(@pkgl)) {
      print "keyword = $k\n  package = @pkgl\n";
    } else {
      print "keyword = $k\n  package = NO PACKAGE FOUND!\n";
    }
  }
}


sub walk_cz_tree {
  my $cp = shift;
  my $prestring = shift;
  if (defined($cp->{'_packages_'})) {
    my @pkgs = sort @{$cp->{'_packages_'}};
    print "$prestring\n";
    print "--> @pkgs\n";
  }
  for my $cz (keys %$cp) {
    if ($cz ne '_packages_') {
      my $nextstring = "$prestring > $cz";
      my $np = $cp->{$cz};
      &walk_cz_tree($np,$nextstring);
    }
  }
}