## -*- Mode: CPerl -*-
##
## File: DTA::CAB::Analyzer::Morph::Helsinki.pm
## Author: Bryan Jurish <moocow@cpan.org>
## Description: morphological analysis via Gfsm automata, for use with Helsinki-style transducers
## + transducers available in HFST format from https://sourceforge.net/projects/hfst/files/resources/morphological-transducers/

##==============================================================================
## Package: Analyzer::Morph
##==============================================================================
package DTA::CAB::Analyzer::Morph::Helsinki;
use DTA::CAB::Analyzer::Automaton::Gfsm;
use Carp;
use strict;
our @ISA = qw(DTA::CAB::Analyzer::Automaton::Gfsm);

## $obj = CLASS_OR_OBJ->new(%args)
##  + object structure: see DTA::CAB::Analyzer::Automaton::Gfsm
sub new {
  my $that = shift;
  my $aut = $that->SUPER::new(
			      ##-- defaults

			      ##-- analysis selection
			      label => 'morph',
			      wantAnalysisLo => 0,
			      wantAnalysisLemma => 0, ##-- default=0
			      tolower => 1,

			      ##-- verbosity
			      check_symbols => 0,

			      ##-- user args
			      @_
			     );
  return $aut;
}

##==============================================================================
## Methods: Analysis: v1.x
##==============================================================================

## $doc = $anl->analyzeTypes($doc,\%types,\%opts)
##  + perform type-wise analysis of all (text) types in %types (= %{$doc->{types}})
sub analyzeTypes {
  my ($aut,$doc,$types,$opts) = @_;
  return if (!$aut->SUPER::analyzeTypes($doc,$types,$opts));

  ##-- post-process: simulate TAGH-notation
  my $label = $aut->{label};
  my $null  = [];
  my ($w,$a,$hi,$tag,$lemma);
  foreach $w (values %$types) {
    foreach $a (@{$w->{$label}//$null}) {
      $hi = $a->{hi};
      if ($hi =~ /((?:\\?\[[^\<\>\[\]\/\\]+\\?\])+)$/) {
	$tag   = $1;
	$lemma = substr($hi, 0, length($hi)-length($tag));
	$tag   = join('.', ($tag =~ /\[\+?([^\<\>\[\]\/\\]+)\\?\]/g));
      }
      elsif ($hi =~ /((?:\\?\[\<?[^\<\>\[\]\/\\]+\>?\\?\]))$/) {
	$tag   = $1;
	$lemma = substr($hi, 0, length($hi)-length($tag));
	$tag   =~ s/[\\\<\>\[\]\+]//g;
      }
      $lemma =~ s/(?:\[[^\+\]]*\]|\\)//g;
      $lemma =~ s/\[([A-Z]+)\+\]/lc($1)."+"/eg;
      $lemma =~ s/\[\+([A-Z]+)\]/"~".lc($1)/eg;
      $a->{hi} = "$lemma\[_$tag]=$hi" if ($lemma || $tag);
    }
  }

  return $doc;
}

1; ##-- be happy

__END__
##========================================================================
## POD DOCUMENTATION, auto-generated by podextract.perl
=pod

=cut

##========================================================================
## NAME
=pod

=head1 NAME

DTA::CAB::Analyzer::Morph - morphological analysis via Gfsm automata

=cut

##========================================================================
## SYNOPSIS
=pod

=head1 SYNOPSIS

 use DTA::CAB::Analyzer::Morph::Helsinki;
 
 $morph = DTA::CAB::Analyzer::Morph::Helsinki->new(%args);
 $morph->analyze($tok);

=cut

##========================================================================
## DESCRIPTION
=pod

=head1 DESCRIPTION

DTA::CAB::Analyzer::Morph
a simplified wrapper for
L<DTA::CAB::Analyzer::Automaton::Gfsm|DTA::CAB::Analyzer::Automaton::Gfsm>
which sets the following default options:

 ##-- analysis selection
 label => 'morph',        ##-- analysis output property
 wantAnalysisLo => 0,     ##-- don't output lower label paths
 tolower => 1,            ##-- bash input to lower-case

It also adds TAGH-style tag-extraction post-processing in its analyzeTypes() method.

=cut

##========================================================================
## END POD DOCUMENTATION, auto-generated by podextract.perl

##======================================================================
## Footer
##======================================================================

=pod

=head1 AUTHOR

Bryan Jurish E<lt>moocow@cpan.orgE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2016-2019 by Bryan Jurish

This package is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.24.1 or,
at your option, any later version of Perl 5 you may have available.

=cut
