Browse Source

Add new version of the makeindex program.

This new version is written in Python. It does not currently handle
prefix directives but is set to ignore any special words defined into
the songbook latex document.
remotes/origin/translate_notes
Alexandre Dupas 15 years ago
parent
commit
63f98cf51b
  1. 127
      make-index
  2. 2
      makefile
  3. 124
      songbook-makeindex.py

127
make-index

@ -1,127 +0,0 @@
#!/usr/bin/perl -w
#
# Generate indexes files for the Crep's chorbook compilation. This is a much
# simplified version from the original C programm that parse the input.
#
# Usage: mk-idx.pl SRC
# SRC should be an .sxd file generated by the latex songs package
#
use warnings;
use strict;
use utf8;
sub uppercase($)
{
my $letter = shift;
$letter =~ tr/a-zàéèëê/A-ZAEEEE/;
return $letter;
}
sub usage ()
{
die "usage: make-index [options] source", "\n";
}
my %options;
sub getoptions ()
{
eval q{use Getopt::Long};
Getopt::Long::Configure('pass_through');
GetOptions(
# "verbose|v!" => \$options{verbose},
) || usage();
}
getoptions();
# Process command line
usage() unless @ARGV;
my $file = shift;
# Open file and store data before closing the file
open( FILE, $file ) or die("unable to open $file");
my @data = <FILE>;
close( FILE );
# Process data
my %table;
# Get the type of the index. Not used but we have it.
my $type = shift @data;
# Parse data and create the index table
my $item;
my $index;
my $link;
my $letter;
my $ref;
my @prefix = ();
while( @data && ( $data[0] =~ /^\s*%prefix (.*)$/ ) )
{
push @prefix, $1;
shift @data;
}
# Create the prefix rule
my $prefix = '(('. join ("|", @prefix) . ')[\s])';
# Create the filter function
sub filter($)
{
my $string = shift;
$string =~ /^$prefix?[^\w]*([\w])/;
my $letter = uppercase $3;
$string =~ s/^$prefix\W*\w(.*)/$letter$3, $1/;
$letter = "0-9" if ( $letter =~ /\d/ ); # group every numbers
return (uppercase $letter, $string);
}
# Process data
while( @data )
{
$item = shift @data;
# entry goes on three lines
chomp $item;
$index = shift @data;
chomp $index;
$link = shift @data;
chomp $link;
# Get the first letter or number of the current item
($letter, $item) = filter $item;
# Create empty data index if needed
$table{$letter} = {} unless exists $table{$letter};
$table{$letter}{$item} = [] unless exists $table{$letter}{$item};
# Create reference for the current item
$ref = { num => $index, link => $link };
# Add the reference to the index
push @{$table{$letter}{$item}}, $ref;
}
# Create the index formated file
my @refs;
foreach $letter ( sort keys %table )
{
print '\begin{idxblock}{'.$letter."}\n";
foreach $item ( sort keys %{$table{$letter}} )
{
print '\idxentry{';
print $item;
print '}{';
@refs = @{$table{$letter}{$item}};
print join ("\\\\", map { "\\hyperlink{$_->{link}}{$_->{num}}" } @refs);
print '}'."\n";
}
print '\end{idxblock}'."\n";
}

2
makefile

@ -27,7 +27,7 @@ PSF = $(CIBLE:%=%.ps.gz)
SONGS = songs.sbd
SONGS_SRC = $(shell ls songs/*/*.sg)
MAKE_INDEX=./make-index
MAKE_INDEX=./songbook-makeindex.py
MAKE_SONGDB=./songbook-volume.py
PRINT=printf "%s\n"
PRINTTAB=printf "\t%s\n"

124
songbook-makeindex.py

@ -0,0 +1,124 @@
#!/usr/bin/python
#
# Generate indexes files for the Crep's chordbook compilation. This is
# a replacement for the original makeindex program written in C that
# produces an index file (.sbx) from a file generated by the latex
# compilation of the songbook (.sxd).
#
# Usage : songbook-makeindex.py src
# src is the .sxd file generated by latex
#
import sys
import os.path
import glob
import re
from optparse import OptionParser
# Pattern set to ignore latex command in title prefix
keywordPattern = re.compile(r"^%(\w+)\s?(\w*)")
firstLetterPattern = re.compile(r"^(?:\{?\\\w+\}?)*[^\w]*(\w)")
class index:
data = dict()
keywords = dict()
def filter(self, key):
letter = firstLetterPattern.match(key).group(1)
if re.match('\d',letter):
letter = '0-9'
return (letter, key)
def keyword(self, key, word):
if not self.keywords.has_key(key):
self.keywords[key] = []
self.keywords[key].append(word)
def compileKeywords(self):
pass
def add(self, key, number, link):
(first, key) = self.filter(key)
if not self.data.has_key(first):
self.data[first] = dict()
if not self.data[first].has_key(key):
self.data[first][key] = []
self.data[first][key].append({'num':number, 'link':link})
def refToStr(self, ref):
if sys.version_info >= (2,6):
return '\\hyperlink{{{0[link]}}}{{{0[num]}}}'.format(ref)
else:
return '\\hyperlink{%(link)s}{%(num)s}' % ref
def entryToStr(self, key, entry):
if sys.version_info >= (2,6):
return '\\idxentry{{{0}}}{{{1}}}\n'.format(key, '\\\\'.join(map(self.refToStr, entry)))
else:
return '\\idxentry{%s}{%s}\n' % (key, '\\\\'.join(map(self.refToStr, entry)))
def idxBlockToStr(self, letter, entries):
str = '\\begin{idxblock}{'+letter+'}'+'\n'
for key in entries.keys():
str += self.entryToStr(key, entries[key])
str += '\\end{idxblock}'+'\n'
return str
def entriesToStr(self):
str = ""
for letter in self.data.keys():
str += self.idxBlockToStr(letter, self.data[letter])
return str
def processSXDEntry(tab):
return (tab[0], tab[1], tab[2])
def processSXD(filename):
file = open(filename)
data = []
for line in file:
data.append(line.strip())
file.close()
type = data[0]
i = 1
idx = index()
while data[i].startswith('%'):
keywords = keywordPattern.match(data[i]).groups()
idx.keyword(keywords[0],keywords[1])
i += 1
idx.compileKeywords()
for i in range(i,len(data),3):
entry = processSXDEntry(data[i:i+3])
idx.add(entry[0],entry[1],entry[2])
return idx
def usage(exitCode=None):
print "usage: songbook-makeindex.py [options] source"
sys.exit(exitCode)
def main():
usage = "usage: %prog [options] FILE"
parser = OptionParser(usage)
parser.add_option("-o", "--output", dest="filename",
help="write result into FILE", metavar="FILE")
(options, args) = parser.parse_args()
# Args processing
if len(args) != 1:
parser.error("incorrect number of arguments")
if not os.path.exists(args[0]):
parser.error("inexistant input file")
# Options processing
if options.filename:
output = open(options.filename,"w")
else:
output = sys.stdout
# Actual processing
idx = processSXD(args[0])
output.write(idx.entriesToStr())
if __name__ == '__main__':
main()
Loading…
Cancel
Save