+ foreach my $xref ( $xml->findnodes('//xref') ) {
+ my $linkend = $xref->getAttribute('linkend');
+ if ( exists $index{$linkend} ) {
+ $xref->setAttribute( 'chapter_id', $index{$linkend}{'chapter_id'} );
+ $xref->setAttribute( 'chapter_title', $index{$linkend}{'chapter_title'} );
+ $xref->setAttribute( 'section_id', $index{$linkend}{'section_id'} ) if ( $index{$linkend}{'section_id'} );
+ $xref->setAttribute( 'section_title', $index{$linkend}{'section_title'} ) if ( $index{$linkend}{'section_title'} );
+ $xref->setAttribute( 'url',
+ sprintf( '%sch%02d.html', $prepend_chapter, $index{$linkend}{'chapter_id'} )
+ . ( $index{$linkend}{'section_id'} ? '#' . $linkend : '' ) );
+ }
+ }
+}
+
+## Build indexes
+sub build_indexes {
+ my ( $xml, $prepend_chapter, $xref ) = @_;
+
+ my $index_hash = {};
+ my $current_id;
+ foreach my $node ( $xml->findnodes('//section | //chapter | //indexterm') ) {
+ if ( $node->nodeName eq 'indexterm' ) {
+ my $role = $node->getAttribute('role') || 'concept';
+ my $primary = $node->findvalue('child::primary');
+ my $first = ( $primary =~ /^[A-Za-z]/ ) ? uc( substr( $primary, 0, 1 ) ) : ''; # first letter or marker
+ my $secondary = $node->findvalue('child::secondary') || '';
+ next unless ( $primary || $secondary ); # skip blank entries for now...
+ $index_hash->{$role}{$first}{$primary}{$secondary} ||= [];
+ push @{ $index_hash->{$role}{$first}{$primary}{$secondary} }, $current_id;
+ }
+ else {
+ $current_id = $node->getAttribute('id');
+ }
+ }
+
+ # now we build a set of new chapters with the index data in
+ my $book = ( $xml->findnodes('/book') )[0];
+ foreach my $role ( sort { $a cmp $b } keys %{$index_hash} ) {
+ my $chapter = XML::LibXML::Element->new('chapter');
+ $book->appendChild($chapter);
+ $chapter->setAttribute( 'id', join( '_', 'index', $role ) );
+ $chapter->setAttribute( 'class', 'index' );
+ $chapter->appendTextChild( 'title', ( ucfirst($role) . ' Index' ) );
+ foreach my $first ( sort { $a cmp $b } keys %{ $index_hash->{$role} } ) {
+ my $section = XML::LibXML::Element->new('section');
+ my $list = XML::LibXML::Element->new('variablelist');
+ $chapter->appendChild($section);
+ $section->setAttribute( 'id', join( '_', 'index', $role, $first ) );
+ $section->setAttribute( 'class', 'index' );
+ $section->appendTextChild( 'title', $first ? $first : 'Symbols' );
+ $section->appendChild($list);
+ foreach my $primary ( sort { $a cmp $b } keys %{ $index_hash->{$role}{$first} } ) {
+ my $entry = XML::LibXML::Element->new('varlistentry');
+ my $item = XML::LibXML::Element->new('listitem');
+ $list->appendChild($entry)->appendTextChild( 'term', $primary );
+ $entry->appendChild($item);
+ my $slist;
+ foreach my $secondary ( sort { $a cmp $b } keys %{ $index_hash->{$role}{$first}{$primary} } ) {
+ my $para = XML::LibXML::Element->new('para');
+ if ( $secondary eq '' ) {
+ $item->appendChild($para); # skip having extra layer of heirarchy
+ }
+ else {
+ unless ($slist) {
+ $slist = XML::LibXML::Element->new('variablelist');
+ $item->appendChild($slist);
+ }
+ my $sentry = XML::LibXML::Element->new('varlistentry');
+ my $sitem = XML::LibXML::Element->new('listitem');
+ $slist->appendChild($sentry)->appendTextChild( 'term', $secondary );
+ $sentry->appendChild($sitem)->appendChild($para);
+ }
+ my $count = 0;
+ foreach my $ref ( @{ $index_hash->{$role}{$first}{$primary}{$secondary} } ) {
+ $para->appendText(', ')
+ if ( $count++ );
+ my $xrefel = XML::LibXML::Element->new('xref');
+ $xrefel->setAttribute( linkend => $ref );
+ $xrefel->setAttribute( longref => 1 );
+ $para->appendChild($xrefel);
+ }
+ }
+ }
+ }
+ }
+}