[sword-devel] SWIG Perl

Joachim Ansorg sword-devel@crosswire.org
Sun, 19 Jan 2003 11:25:03 +0100


--------------Boundary-00=_R9IY1X2QQ9EXTSOCA0JP
Content-Type: text/plain;
  charset="iso-8859-15"
Content-Transfer-Encoding: quoted-printable

Chad,
Have a look at the following messy Perl script. It was never intended for=
=20
a release, so the code isn't very good. At the end you'll see how I creat=
ed a=20
compressed commentary module using the Swig bindings.

If you need more help let me know.

Joachim

> Can someone tell me how to create a module in SWIG Perl?  I try and
> follow the example given but I get an error message like this:
>
> Usage: xText_createModule(self,path,blockBound);
>
> Can any one help?
>
> Thanks
> Chad
>
> _______________________________________________
> sword-devel mailing list
> sword-devel@crosswire.org
> http://www.crosswire.org/mailman/listinfo/sword-devel

--=20
Joachim Ansorg
www.bibletime.info
www.ansorgs.de


--------------Boundary-00=_R9IY1X2QQ9EXTSOCA0JP
Content-Type: text/x-perl;
  charset="iso-8859-15";
  name="create_mak.pl"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="create_mak.pl"

#!/usr/bin/perl

use Sword; #Use the Sword bindings for Perl
use Encode;
use File::Path;
use Cwd;
use strict;

# Parameters:
#	1. The modules
#	2. The key as english string
#	3. The data as string

sub writeData {
	my $mod = shift;
	my $key = shift;
	my $data = shift;

	# We have to parse the key to be able to write a range to the module
	# The first entry is written using the data, ther others are written as links
	my $vk = Sword::VerseKey->new();
	$vk->setLocale("de");

	my $list = $vk->ParseVerseList($key, "Genesis 1:1", 1); # "1" to parse ranges!
	for (my $i = 0; $i < $list->Count(); $i++) {
		my $sw_key= $list->GetElement($i);
		if (my $rangeKey = $sw_key->toVerseKey()) {
			# write the data to the first key and link the others to this first one
			my $k = $rangeKey->LowerBound();
			print "\tWriting to " . $k->getText() . "\n";
			$mod->SetKey($k);
			$mod->write($data);

			$k->next();
			# go up until we reach UpperBound and link each entry to the LowerBound
			while(($k->compare($rangeKey->UpperBound()) == -1)) { #as long as $k is before UpperBound
				$mod->SetKey($k);
				$mod->writeLink($rangeKey->LowerBound());
				print "\t\t" . $k->getText() . ": linking to ". $sw_key->getText() . "\n";
				$k->next();
			}
			#we reached the last entry
			#$mod->writeLink($rangeKey->LowerBound());
			print "\t\t" . $k->getText() . ": linking to ". $sw_key->getText() . "\n";
		}
		else {
			print "\tWriting single key to " . $sw_key->getText() . "\n";
			$mod->SetKey($sw_key);
			$mod->write($data);
		}
	}

	#print out the list
};

sub convert_key {
	my $key = shift;
	$key =~ s/,/:/g;
	$key =~ s/(\d)\./$1. /;
	if ($key =~ /[^0-9]$/) {
		die "Invalid key $key"
	};

	return $key;
};

sub format_content {
	my $key = shift;
	my $date = shift;
	my $data = shift;
	# Format the data in the following way:
	# Datum: $date
	# Stelle: <scripRef passage="$englishKey">$key</scripRef>
	# <BR>
	# $data

	#Fix existing scripRefs
	# 1. Remove newlines within scripRef tags
	$data =~ s/<scripRef[\n\s]?(.+?)\n(.+?)>/<scripRef $1 $2>/gi;
	# 2. Remove version=".+?" parts
	$data =~ s|<scripRef (.+?)version=".+?"(.+?)>|<scripRef $1 $2>|gis;
	# 3. Beautify scripRefs, e.g. remove trailing spaces
	$data =~ s|<scripRef (.+?)\s+>|<scripRef $1>|gis;


	my $ret = '<FONT color="#800000"><B>Datum:</B> ' . $date . '</FONT><BR>';

	my $vk = Sword::VerseKey->new();
	$vk->setLocale("de");
	$vk->setText($key);
	#$vk->setLocale("en");

	my $rangeText = undef;
	my $list = $vk->ParseVerseList($key, "Genesis 1:1", 1); # "1" to parse ranges!
	for (my $i = 0; $i < $list->Count(); $i++) {
		my $sw_key= $list->GetElement($i);
		if (my $rangeKey = $sw_key->toVerseKey()) {
			$rangeKey->setLocale("en");
			# write the data to the first key and link the others to this first one
			if( $rangeKey->LowerBound()->compare($rangeKey->UpperBound()) == -1 ) { #as long as $k is before UpperBound
				$rangeText .= $rangeKey->LowerBound()->getText() . "-" . $rangeKey->UpperBound()->getText() . ";";
			}
		}
		else {
			$vk->setLocale("de");
			$vk->setText($sw_key->getText());
			$vk->setLocale("en");
			$rangeText .= $vk->getText();
		}
	}


	$ret .= '<FONT color="#800000"><B>Stelle:</B> ' . '<scripRef passage="' . $rangeText .'">' . $key . '</scripRef></FONT>';
	$ret .= '<BR><P align="justify">' . $data . '</P>';

	#Finally change all possible characters into UTF-8 so it will work on any platform
	Encode::from_to($ret, "iso-8859-15", "utf-8");
	return $ret;
};

# This function created the module configuration file for the MAK module
sub create_config {
	my $path = shift;
	my $filename = shift;
	
	mkpath("$path");
	open(OUT, "> $path/$filename");

	print OUT <<'EOF';
[MAK]
DataPath=./modules/comments/rawcom/mak/
ModDrv=RawCom
SourceType=ThML
Encoding=UTF-8
Lang=de
MinimumVersion=1.5.2
Version=1.0
History_1.0=2002-11-24 -- Major update. Many new comments, updated format, changed encoding to UTF-8, fixed existing scripRefs
History_0.9=2000-07-29 -- First official version -- ThML-Tags for scripture ref
SwordVersionDate=2002-11-24
Description=Matthias Ansorgs Kommentar
About=Matthias Ansorgs Kommentar zur Bibel\par\
Der Kommentar wurde von Matthias Ansorg geschrieben.\par\
Kontakt: matthias@ansorgs.de
TextSource=Matthias Ansorg,matthias@ansorgs.de
LCSH=Bible--Commentaries, German.
DistributionLicense=Public Domain
EOF
	close(OUT);
};



sub write_module {
	Sword::LocaleMgr::getSystemLocaleMgr()->setDefaultLocaleName("de");

	my $file = shift;
	open(IN, $file) || die "Can't open file $file\n";

	my $key = undef;
	my $date = undef;
	my $comment = undef;

	#Create the directories where the module should be created
	mkpath("data/modules/comments/rawcom/mak");
	#LocaleMgr()->setDefaultLocaleName("de");


	#Sword::zCom::createModule("data/modules/comments/rawcom/mak",4) || die "Couldn't create the zCom module!";
	Sword::RawCom::createModule("data/modules/comments/rawcom/mak") || die "Couldn't create the zCom module!";
	#my $compressor = Sword::LZSSCompress->new();
	#my $mod = Sword::zCom->new("data/modules/comments/rawcom/mak", 0, 0, 4, $compressor ); #blocktype = 4, compressor type is LZSSCompression
	my $mod = Sword::RawCom->new("data/modules/comments/rawcom/mak");
	$mod->setSkipConsecutiveLinks(0);

	while (<IN>) {
		if (/^Text:\s?(.+?)\n/) { #The start if a new entry was found
			if ($key && $date && $comment) { #write the found comment to disk
				$key = convert_key($key);
				print "Found: " . $key. "\n";
				my $data = format_content($key, $date, $comment);
				writeData($mod, $key, $data);
			};

			$key = $1;
			$date = undef;
			$comment = undef;
		}
		elsif (/^Datum:\s?(.+?)\n/) {
			$date = $1;
		}
		else {
			$comment .= $_;
		};
	};
	#write the last entry into the module
	if ($key && $date && $comment) { #write the found comment to disk
		$key = convert_key($key);
		print "Found: " . $key. "\n";
		my $data = format_content($key, $date, $comment);
		writeData($mod, $key, $data);
	};

	close(IN);
};

sub zip_module {
	my $path = shift;
	my $filename = shift;

	my $start_dir = getcwd();
	unlink("$filename");
	chdir("$path");
	
	system("chmod -R a+r+X $start_dir/$path");

	# Call zip command to compress all files in the current directory
	my $ret = system( "zip -q -9 -r $start_dir/$filename *");
	chdir($start_dir);
	rmtree("$start_dir/data/");

	print "Zipped module data files are in the ZIP archive $filename\n";

	return $ret;
}

#main part
create_config("data/mods.d/", "mak.conf");
write_module("stilleZeit.Kommentare.txt");
zip_module("data", "mak.zip");
create_config(".", "mak.conf");

--------------Boundary-00=_R9IY1X2QQ9EXTSOCA0JP--