mirror of https://github.com/patacrep/patacrep.git
Browse Source
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/split-songs
Alexandre Dupas
15 years ago
3 changed files with 125 additions and 128 deletions
@ -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"; |
|
||||
} |
|
@ -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…
Reference in new issue