xwords/xwords4/dawg/xloc.pm
Eric House 03f175dd8f handle new format for tile face 'A|a', meaning "A" or "a", as far as
being able to compile a wordlist and take it apart using dawg2dict.
None of the compiled clients can handle this format yet.
2013-04-06 10:28:22 -07:00

189 lines
4.7 KiB
Perl

#!/usr/bin/perl
# Copyright 2002 by Eric House (xwords@eehouse.org). All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# The idea here is that all that matters about a language is stored in
# one file (possibly excepting rules for prepping a dictionary).
# There's a list of tile faces, counts and values, and also some
# name-value pairs as needed. The pairs come first, and then a list
# of tiles.
package xloc;
use strict;
use warnings;
BEGIN {
use Exporter ();
our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = qw(&ParseTileInfo &GetNTiles &TileFace &TileValue
&TileCount &GetValue &WriteMapFile &WriteValuesFile);
%EXPORT_TAGS = ( );
}
# Returns what's meant to be an opaque object that can be passed back
# for queries. It's a hash with name-value pairs and an _INFO entry
# containing a list of tile info lists.
sub ParseTileInfo($$) {
my ( $filePath, $enc ) = @_;
my %result;
if ( $enc ) {
open( INPUT, "<:encoding($enc)", "$filePath" )
or die "couldn't open $filePath";
} else {
open( INPUT, "<$filePath" )
or die "couldn't open $filePath";
}
my $inTiles = 0;
my @tiles;
while ( <INPUT> ) {
chomp;
s/\#.*$//;
s/^\s*$//; # nuke all-white-space lines
next if !length;
if ( $inTiles ) {
if ( /<END_TILES>/ ) {
last;
} else {
my ( $count, $val, $face ) = m/^\s*(\w+)\s+(\w+)\s+(.*)\s*$/;
push @tiles, [ $count, $val, $face ];
}
} elsif ( /\w:/ ) {
my ( $nam, $val ) = split ':', $_, 2;
$result{$nam} .= $val;
} elsif ( /<BEGIN_TILES>/ ) {
$inTiles = 1;
}
}
close INPUT;
$result{"_TILES"} = [ @tiles ];
return \%result;
}
sub GetNTiles($) {
my ( $hashR ) = @_;
my $listR = ${$hashR}{"_TILES"};
return 0 + @{$listR};
}
sub GetValue($$) {
my ( $hashR, $name ) = @_;
return ${$hashR}{$name};
}
sub printLetters($$) {
my ( $str, $fhr ) = @_;
my @letters = split( /\|/, $str );
$str = join( " ", @letters );
for ( my $key = 0; $key < length($str); ++$key ) {
my $chr = substr( $str, $key, 1 );
print $fhr pack( "U", ord($chr) );
}
}
sub WriteMapFile($$$) {
my ( $hashR, $unicode, $fhr ) = @_;
my $count = GetNTiles($hashR);
my $specialCount = 0;
for ( my $i = 0; $i < $count; ++$i ) {
my $tileR = GetNthTile( $hashR, $i );
my $str = ${$tileR}[2];
if ( $str =~ /\'(.(\|.)*)\'/ ) {
printLetters( $1, $fhr );
} elsif ( $str =~ /\"(.+)\"/ ) {
print $fhr pack( "c", $specialCount++ );
} elsif ( $str =~ /(\d+)/ ) {
print $fhr pack( "n", $1 );
} else {
die "WriteMapFile: unrecognized face format $str, elem $i";
}
}
} # WriteMapFile
sub WriteValuesFile($$) {
my ( $hashR, $fhr ) = @_;
my $header = GetValue( $hashR,"XLOC_HEADER" );
die "no XLOC_HEADER found" if ! $header;
print STDERR "header is $header\n";
print $fhr pack( "n", hex($header) );
my $count = GetNTiles($hashR);
for ( my $i = 0; $i < $count; ++$i ) {
my $tileR = GetNthTile( $hashR, $i );
print $fhr pack( "c", TileValue($tileR) );
print $fhr pack( "c", TileCount($tileR) );
}
} # WriteValuesFile
sub GetNthTile($$) {
my ( $hashR, $n ) = @_;
my $listR = ${$hashR}{"_TILES"};
return ${$listR}[$n];
}
sub TileFace($) {
my ( $tileR ) = @_;
my $str = ${$tileR}[2];
if ( $str =~ /\'(.)\'/ ) {
return $1;
} elsif ( $str =~ /\"(.+)\"/ ) {
return $1;
} elsif ( $str =~ /(\d+)/ ) {
return chr($1);
} else {
die "TileFace: unrecognized face format: $str";
}
}
sub TileValue($) {
my ( $tileR ) = @_;
return ${$tileR}[0];
}
sub TileCount($) {
my ( $tileR ) = @_;
return ${$tileR}[1];
}
1;