Padre::Plugin::SpellCheck::Engine - Spell check engine for the plugin


Padre-Plugin-SpellCheck documentation Contained in the Padre-Plugin-SpellCheck distribution.

Index


Code Index:

NAME

Top

Padre::Plugin::SpellCheck::Engine - Spell check engine for the plugin

VERSION

Top

version 1.21

PUBLIC METHODS

Top

Constructor

my $engine = PPS::Engine->new;

Create a new engine to be used later on.

Instance methods

* my ($word, $pos) = $engine->check( $text );

Spell check $text (according to current speller), and return the first error encountered (undef if no spelling mistake). An error is reported as the faulty $word, as well as the $pos of the word in the text (position of the start of the faulty word).

* $engine->ignore( $word );

Tell engine to ignore $word for rest of the spell check.

* my @dictionaries = $engine->dictionaries;

Return a (reduced) list of dictionaries installed with aspell. The names returned are the dictionary locale names (eg en_US). Note that only plain locales are reported, the variations coming with aspell are stripped.

* my @suggestions = $engine->suggestions( $word );

Return suggestions for $word.

SEE ALSO

Top

For all related information (bug reporting, source code repository, etc.), refer to Padre::Plugin::SpellCheck.

AUTHORS

Top

COPYRIGHT AND LICENSE

Top


Padre-Plugin-SpellCheck documentation Contained in the Padre-Plugin-SpellCheck distribution.

package Padre::Plugin::SpellCheck::Engine;
BEGIN {
  $Padre::Plugin::SpellCheck::Engine::VERSION = '1.21';
}

# ABSTRACT: Spell check engine for the plugin

use warnings;
use strict;

use Class::XSAccessor accessors => {
	_ignore    => '_ignore',    # list of words to ignore
	_plugin    => '_plugin',    # ref to spellecheck plugin
	_speller   => '_speller',   # real text::aspell object
	_utf_chars => '_utf_chars', # FIXME: as soon as wxWidgets/wxPerl supports
	                            # newer version of STC:
	                            # number of UTF8 characters
	                            # used in calculating current possition
};
use Text::Aspell;

my %MIMETYPE_MODE = (
	'application/x-latex' => 'tex',
	'text/html'           => 'html',
	'text/xml'            => 'sgml',
);

# -- constructor

sub new {
	my ( $class, $plugin, $mimetype ) = @_;

	my $self = bless {
		_ignore    => {},
		_plugin    => $plugin,
		_utf_chars => 0,
	}, $class;

	# create speller object
	my $speller = Text::Aspell->new;
	my $config  = $plugin->config;

	# TODO: configurable later
	$speller->set_option( 'sug-mode', 'normal' );
	$speller->set_option( 'lang',     $config->{dictionary} );

	$speller->print_config;

	if (exists $MIMETYPE_MODE{$mimetype}) {
		if (not defined $speller->set_option( 'mode', $MIMETYPE_MODE{$mimetype})) {
			my $err = $speller->errstr;
			warn "Could not set aspell mode '$MIMETYPE_MODE{$mimetype}': $err\n";
		}
	}

	$speller->print_config;

	$self->_speller($speller);

	return $self;
}


# -- public methods

sub check {
	my ( $self, $text ) = @_;
	my $speller = $self->_speller;
	my $ignore  = $self->_ignore;

	# iterate over word boundaries
	while ( $text =~ /(.+?)(\b|\z)/g ) {
		my $word = $1;

		# skip...
		next unless defined $word;             # empty strings
		next unless $word =~ /^\p{Letter}+$/i; # non-spellable words

		# FIXME: when STC issues will be resolved:
		# count number of UTF8 characters in ignored/correct words
		# it's going to be used to calculate relative position
		# of next problematic word
		if ( exists $ignore->{$word} ) {
			$self->_count_utf_chars($word);
			next;
		}
		if ( $speller->check($word) ) {
			$self->_count_utf_chars($word);
			next;
		}

		# uncomment when fixed above
		#        next if exists $ignore->{$word};        # ignored words
		#
		#        # check spelling
		#        next if $speller->check( $word );

		# oops! spell mistake!
		my $pos = pos($text) - length($word);

		return $word, $pos;
	}

	# $text does not contain any error
	return;
}


sub dictionaries {
	my ($self) = @_;
	return grep { $_ =~ /^\w+$/ }
		map { $_->{name} } $self->_speller->dictionary_info;
}

sub ignore {
	my ( $self, $word ) = @_;
	$self->_ignore->{$word} = 1;
}

sub suggestions {
	my ( $self, $word ) = @_;
	return $self->_speller->suggest($word);
}

# -- private methods

#
# FIXME: as soon as STC issues is resolved
#
sub _count_utf_chars {
	my ( $self, $word ) = @_;

	foreach ( split //, $word ) {
		$self->{_utf_chars}++ if ord($_) >= 128;
	}

	return;
}

1;




__END__