Re: [dssslist] Re: Problems with ? for page numbers in index

Subject: Re: [dssslist] Re: Problems with ? for page numbers in index
From: Ian Zimmerman <nobrowser@xxxxxxxxx>
Date: Tue, 14 Mar 2006 19:41:03 -0800 (PST)
Jeremy> An index entry is only placed where there is an <indexterm> in
Jeremy> my SGML document, so if I want the same word indexed whenever it
Jeremy> occurs I still have to manually insert <indexterm>s at each
Jeremy> occurence.

Raghavendra> AFAIK that is true even with LaTeX indexing, cf., the
Raghavendra> `makeindex' documentation.

For highly structured documents such as software documentation, this
can be at least partly automated.  Here's a bit of Perl I use:

#! /usr/bin/perl -w

use SGMLS;

our $VERSION = '$Id: specindex.pl,v 1.6 2003/04/03 21:16:12 itz Exp $';
our $parse = SGMLS->new(STDIN);
our %index_elements =
(
 function   => 'function',
 classname  => 'class',
 structname => 'struct',
 type       => 'type',
 varname    => 'variable',
 constant   => 'constant',
 command    => 'program',
 );

our %section_elements =
    map {$_, 1} qw(preface chapter appendix glossary bibliography
                   sect1 sect2 sect3 sect4 section simplesect glossdiv
                   bibliodiv);
our $content = '';
our %indexmap = ( );

sub find_target {
    my $element = $_[0];

  PARENT:
    while(1) {
        my $parent = $element->parent;
        (ref $parent) eq 'SGMLS_Element' or return undef;
        my $name = $parent->name;
        $element = $parent, next PARENT
            unless $section_elements{lc $name} &&
            ref $parent->attribute('ID') eq 'SGMLS_Attribute';
        my $id = $parent->attribute('ID')->value;
        $element = $parent, next PARENT unless $id;
        return $id;
    }
}

 EVENT:
    while (1) {
        
        my $event = $parse->next_event;
        (ref $event) eq SGMLS_Event
                     or die "unexpected end of file, not conforming?\n";
        for ($event->type) {
            /^conforming/		and last EVENT;
            /^start_element/		and do {
                my $element = $event->data;    # class SGMLS_Element
                my $name = $element->name;
                $content = '' if $index_elements{lc $name};
                next EVENT;
            };
            /^end_element/			and do {
                my $element = $event->data;    # class SGMLS_Element
                my $name = $element->name;
                if ($index_elements{lc $name}) {
                    my $id = &find_target($element);
                    defined $id or next EVENT;
                    $indexmap{"$content ($index_elements{lc $name})"}
                              ->{lc $id} = 1;
                }
                next EVENT;
            };
            /^cdata/			and do {
                my $cdata = $event->data;      # A string
                my $element = $event->element;
                my $name = $element->name;
                $content .= $cdata if $index_elements{lc $name};
                next EVENT;
            };
        }
    }

our $idgen = 1;

foreach my $entry (sort(keys %indexmap)) {
    print '<indexterm id="IDX-ID', $idgen++,'" zone="', 
           join(' ',keys %{$indexmap{$entry}});
    print '"><primary>', $entry, '</primary></indexterm>', "\n";
}

-- 
A true pessimist won't be discouraged by a little success.

Current Thread