trivial docbook helper script - useful?
I wrote this to automatically index various programming language
constructs, similar to the way makeinfo does (with @deftypefunc and
similar commands). It snarfs the content of elements like
<function>foo</function> and prints a list of <indexterm>'s.
#! /usr/bin/perl -w
# specindex.pl - a simple index autogenerator
use SGMLS;
our $VERSION = '$Id: specindex.pl,v 1.3 2003/04/01 01:06:36 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{$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 last EVENT;
for ($event->type) {
/^conforming/ and last EVENT;
/^start_element/ and do {
my $element = $event->data; # An object of class SGMLS_Element
my $name = $element->name;
$content = '' if $index_elements{$name};
next EVENT;
};
/^end_element/ and do {
my $element = $event->data; # An object of class SGMLS_Element
my $name = $element->name;
if ($index_elements{$name}) {
my $id = &find_target($element);
defined $id or next EVENT;
$indexmap{"$content ($index_elements{$name})"}->{$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{$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";
}
___END___
Use like this:
$(NSGMLS) $(NSGMLSFLAGS) xml.dcl foo.xml | specindex.pl > idxterms.xml
then declare an external entity for idxterms.xml, call it out at a
strategic point in the document (i.e. anywhere the DTD allows it), and
let the stylesheet do its indexing magic.
If anyone thinks this has potential for wider use, let me know.
--
Ian Zimmerman, Oakland, California, U.S.A.
if (sizeof(signed) > sizeof(unsigned) + 4) { delete this; }
GPG: 433BA087 9C0F 194F 203A 63F7 B1B8 6E5A 8CA3 27DB 433B A087
Reply to: