diff --git a/make-index b/make-index deleted file mode 100755 index 9bf405f7..00000000 --- a/make-index +++ /dev/null @@ -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 = ; -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"; -} diff --git a/makefile b/makefile index 2836fa2d..4acf8f1f 100644 --- a/makefile +++ b/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" diff --git a/songbook-makeindex.py b/songbook-makeindex.py new file mode 100755 index 00000000..ab001b1b --- /dev/null +++ b/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()