Support non-word-tokens (fixes #5)
Change-Id: I6867745afd7c0fb865722bcd62a0724aaa9a6ccb
diff --git a/Changes b/Changes
index d6c7931..ce01343 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,6 @@
+0.36 2019-01-22
+ - Support for non-word tokens (fixes #5).
+
0.35 2018-09-24
- Lift minimum version of Perl to 5.16 as for
"fc"-feature.
diff --git a/Readme.pod b/Readme.pod
index 9b80513..3b3ef8d 100644
--- a/Readme.pod
+++ b/Readme.pod
@@ -178,6 +178,13 @@
This is I<deprecated>.
+=item B<--non-word-tokens|-nwt>
+
+Tokenize non-word tokens like word tokens (defined as matching
+C</[\d\w]/>). Useful to treat punctuations as tokens.
+
+ Defaults to unset.
+
=item B<--jobs|-j>
Define the number of concurrent jobs in seperated forks
@@ -343,6 +350,9 @@
Glemm
#Morpho
+ HNC
+ #Morpho
+
LWC
#Dependency
@@ -389,7 +399,7 @@
=head1 COPYRIGHT AND LICENSE
-Copyright (C) 2015-2018, L<IDS Mannheim|http://www.ids-mannheim.de/>
+Copyright (C) 2015-2019, L<IDS Mannheim|http://www.ids-mannheim.de/>
Author: L<Nils Diewald|http://nils-diewald.de/>
diff --git a/lib/KorAP/XML/Batch/File.pm b/lib/KorAP/XML/Batch/File.pm
index dbb6ded..583bc8f 100644
--- a/lib/KorAP/XML/Batch/File.pm
+++ b/lib/KorAP/XML/Batch/File.pm
@@ -12,16 +12,17 @@
my %param = @_;
bless {
- cache => $param{cache} // undef,
- meta_type => $param{meta_type} || 'I5',
- overwrite => $param{overwrite},
- foundry => $param{foundry} || 'Base',
- layer => $param{layer} || 'Tokens',
- anno => $param{anno} || [[]],
- log => $param{log} || Mojo::Log->new(level => 'fatal'),
- primary => $param{primary},
- pretty => $param{pretty},
- gzip => $param{gzip} // 0
+ cache => $param{cache} // undef,
+ meta_type => $param{meta_type} || 'I5',
+ overwrite => $param{overwrite},
+ foundry => $param{foundry} || 'Base',
+ layer => $param{layer} || 'Tokens',
+ anno => $param{anno} || [[]],
+ log => $param{log} || Mojo::Log->new(level => 'fatal'),
+ primary => $param{primary},
+ non_word_tokens => $param{non_word_tokens},
+ pretty => $param{pretty},
+ gzip => $param{gzip} // 0
}, $class;
};
@@ -54,7 +55,8 @@
doc => $doc,
foundry => $self->{foundry},
layer => $self->{layer},
- name => 'tokens'
+ name => 'tokens',
+ non_word_tokens => $self->{non_word_tokens}
);
# Unable to process base tokenization
diff --git a/lib/KorAP/XML/Krill.pm b/lib/KorAP/XML/Krill.pm
index 95e8204..221c5f4 100644
--- a/lib/KorAP/XML/Krill.pm
+++ b/lib/KorAP/XML/Krill.pm
@@ -16,7 +16,7 @@
use Data::Dumper;
use File::Spec::Functions qw/catdir catfile catpath splitdir splitpath rel2abs/;
-our $VERSION = '0.35';
+our $VERSION = '0.36';
has 'path';
has [qw/text_sigle doc_sigle corpus_sigle/];
diff --git a/lib/KorAP/XML/Tokenizer.pm b/lib/KorAP/XML/Tokenizer.pm
index fe8ee04..dec20cf 100644
--- a/lib/KorAP/XML/Tokenizer.pm
+++ b/lib/KorAP/XML/Tokenizer.pm
@@ -34,6 +34,7 @@
has [qw/path foundry doc stream should have name/];
has layer => 'Tokens';
+has non_word_tokens => 0;
has log => sub {
if (Log::Log4perl->initialized()) {
@@ -131,7 +132,7 @@
$should++;
# Ignore non-word and non-number tokens (sorry!)
- if ($token !~ /[\w\d]/) {
+ if (!$self->non_word_tokens && $token !~ /[\w\d]/) {
# TODO: Recognize punctuations!
# if ($mtt) {
diff --git a/script/korapxml2krill b/script/korapxml2krill
index 772e430..f1ba9d4 100644
--- a/script/korapxml2krill
+++ b/script/korapxml2krill
@@ -129,9 +129,12 @@
#
# 2018/07/19
# - Preliminary support for HNC.
+#
+# 2019/01/22
+# - Support for non-word tokens.
# ----------------------------------------------------------
-our $LAST_CHANGE = '2018/07/19';
+our $LAST_CHANGE = '2019/01/22';
our $LOCAL = $FindBin::Bin;
our $VERSION_MSG = <<"VERSION";
Version $KorAP::XML::Krill::VERSION - diewald\@ids-mannheim.de - $LAST_CHANGE
@@ -175,6 +178,7 @@
'pretty|y' => \(my $pretty),
'jobs|j=i' => \(my $jobs),
'to-tar' => \(my $to_tar),
+ 'non-word-tokens|nwt' => \(my $non_word_tokens),
'sequential-extraction|se' => \(my $sequential_extraction),
'cache-size|cs=s' => \(my $cache_size),
'cache-delete|cd!' => \(my $cache_delete),
@@ -233,6 +237,11 @@
$token_base = $config{token};
};
+ # temporary-extract
+ if (!defined($non_word_tokens) && defined $config{'non-word-tokens'}) {
+ $non_word_tokens = $config{'non-word-tokens'};
+ };
+
# Cache file
if (!defined($cache_file) && defined $config{cache}) {
$cache_file = $config{cache};
@@ -322,6 +331,7 @@
$base_sentences //= '';
$base_paragraphs //= '';
$base_pagebreaks //= '';
+$non_word_tokens //= 0;
$base_sentences = lc $base_sentences;
$base_paragraphs = lc $base_paragraphs;
@@ -548,7 +558,8 @@
log => $log,
primary => $primary,
pretty => $pretty,
- anno => \@filtered_anno
+ anno => \@filtered_anno,
+ non_word_tokens => $non_word_tokens
);
# Get file name based on path information
@@ -1221,6 +1232,13 @@
This is I<deprecated>.
+=item B<--non-word-tokens|-nwt>
+
+Tokenize non-word tokens like word tokens (defined as matching
+C</[\d\w]/>). Useful to treat punctuations as tokens.
+
+ Defaults to unset.
+
=item B<--jobs|-j>
Define the number of concurrent jobs in seperated forks
@@ -1435,7 +1453,7 @@
=head1 COPYRIGHT AND LICENSE
-Copyright (C) 2015-2018, L<IDS Mannheim|http://www.ids-mannheim.de/>
+Copyright (C) 2015-2019, L<IDS Mannheim|http://www.ids-mannheim.de/>
Author: L<Nils Diewald|http://nils-diewald.de/>
diff --git a/t/script/non_word_tokens.t b/t/script/non_word_tokens.t
new file mode 100644
index 0000000..0eb9e14
--- /dev/null
+++ b/t/script/non_word_tokens.t
@@ -0,0 +1,95 @@
+#/usr/bin/env perl
+use strict;
+use warnings;
+use File::Basename 'dirname';
+use File::Spec::Functions qw/catdir catfile/;
+use File::Temp qw/ :POSIX /;
+use Mojo::File;
+use Mojo::JSON qw/decode_json/;
+use IO::Uncompress::Gunzip;
+use Test::More;
+use Test::Output;
+use Data::Dumper;
+use utf8;
+
+my $f = dirname(__FILE__);
+my $script = catfile($f, '..', '..', 'script', 'korapxml2krill');
+
+my $input = catdir($f, '..', 'corpus', 'WPD', '00001');
+ok(-d $input, 'Input directory found');
+
+my $output = tmpnam();
+my $cache = tmpnam();
+
+ok(!-f $output, 'Output does not exist');
+
+my $call = join(
+ ' ',
+ 'perl', $script,
+ '--input' => $input,
+ '--output' => $output,
+ '--cache' => $cache,
+ '-t' => 'OpenNLP#tokens',
+ '-l' => 'INFO'
+);
+
+# Test without compression
+stderr_like(
+ sub {
+ system($call);
+ },
+ qr!The code took!,
+ $call
+);
+
+ok(-f $output, 'Output does exist');
+ok((my $file = Mojo::File->new($output)->slurp), 'Slurp data');
+ok((my $json = decode_json $file), 'decode json');
+is($json->{textSigle}, 'WPD/AAA/00001', 'text sigle');
+is($json->{title}, 'A', 'Title');
+is($json->{data}->{tokenSource}, 'opennlp#tokens', 'Title');
+is($json->{data}->{foundries}, 'base base/paragraphs base/sentences connexor connexor/morpho connexor/phrase connexor/sentences connexor/syntax corenlp corenlp/sentences dereko dereko/structure mate mate/dependency mate/morpho opennlp opennlp/morpho opennlp/sentences treetagger treetagger/morpho treetagger/sentences xip xip/constituency xip/morpho xip/sentences', 'Foundries');
+my $stream = $json->{data}->{stream};
+my $token = $stream->[12];
+is($token->[17], 's:Vokal', 'Token');
+$token = $stream->[13];
+is($token->[23], 's:Der', 'Token');
+
+
+$call = join(
+ ' ',
+ 'perl', $script,
+ '--input' => $input,
+ '--output' => $output,
+ '--cache' => $cache,
+ '-t' => 'OpenNLP#tokens',
+ '-l' => 'INFO',
+ '-w' => '',
+ '-nwt' => ''
+);
+
+# Test without compression
+stderr_like(
+ sub {
+ system($call);
+ },
+ qr!The code took!,
+ $call
+);
+
+ok(-f $output, 'Output does exist');
+ok(($file = Mojo::File->new($output)->slurp), 'Slurp data');
+ok(($json = decode_json $file), 'decode json');
+$stream = $json->{data}->{stream};
+$token = $stream->[12];
+is($token->[17], 's:Vokal', 'Token');
+$token = $stream->[13];
+is($token->[7], 's:.', 'Token');
+is($token->[11], 'xip/p:PUNCT', 'Token');
+$token = $stream->[14];
+is($token->[23], 's:Der', 'Token');
+
+
+done_testing;
+
+__END__
diff --git a/t/tokenization.t b/t/tokenization.t
new file mode 100644
index 0000000..4c4ddaa
--- /dev/null
+++ b/t/tokenization.t
@@ -0,0 +1,65 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use utf8;
+use Test::More;
+use JSON::XS;
+
+use File::Basename 'dirname';
+use File::Spec::Functions 'catdir';
+
+sub _t2h {
+ my $string = shift;
+ $string =~ s/^\[\(\d+?-\d+?\)(.+?)\]$/$1/;
+ my %hash = ();
+ foreach (split(qr!\|!, $string)) {
+ $hash{$_} = 1;
+ };
+ return \%hash;
+};
+
+use_ok('KorAP::XML::Krill');
+
+my $path = catdir(dirname(__FILE__), 'corpus/WPD/00001');
+ok(my $doc = KorAP::XML::Krill->new( path => $path ), 'Load Korap::Document');
+like($doc->path, qr!\Q$path\E/$!, 'Path');
+ok($doc->parse, 'Parse document');
+is($doc->text_sigle, 'WPD/AAA/00001', 'ID');
+
+
+# Get tokens
+use_ok('KorAP::XML::Tokenizer');
+
+# Get tokenization
+ok(my $tokens = KorAP::XML::Tokenizer->new(
+ path => $doc->path,
+ doc => $doc,
+ foundry => 'OpenNLP',
+ layer => 'Tokens',
+ name => 'tokens'
+), 'New Tokenizer');
+ok($tokens->parse, 'Parse');
+
+like($tokens->stream->pos(12)->to_string, qr/s:Vokal/);
+like($tokens->stream->pos(13)->to_string, qr/s:Der/);
+
+
+# Get tokenization with non word tokens
+ok($tokens = KorAP::XML::Tokenizer->new(
+ path => $doc->path,
+ doc => $doc,
+ foundry => 'OpenNLP',
+ layer => 'Tokens',
+ name => 'tokens',
+ non_word_tokens => 1
+), 'New Tokenizer');
+ok($tokens->parse, 'Parse');
+
+like($tokens->stream->pos(12)->to_string, qr/s:Vokal/);
+like($tokens->stream->pos(13)->to_string, qr/s:\./);
+like($tokens->stream->pos(14)->to_string, qr/s:Der/);
+
+
+done_testing;
+
+__END__