New Upstream Release - pygtkspellcheck
Ready changes
Summary
Merged new upstream version: 5.0.1 (was: 4.0.5).
Diff
diff --git a/LICENSE.txt b/LICENSE
similarity index 100%
rename from LICENSE.txt
rename to LICENSE
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index c970dff..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,7 +0,0 @@
-include LICENSE.txt
-include MANIFEST.in
-include README.md
-graft examples
-graft doc
-graft locale
-prune doc/build
\ No newline at end of file
diff --git a/PKG-INFO b/PKG-INFO
index 5c8dcf4..6b5be59 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,21 +1,100 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
Name: pygtkspellcheck
-Version: 4.0.5
-Summary: a simple but quite powerful Python spell checking library for GtkTextViews based on Enchant
-Home-page: http://koehlma.github.com/projects/pygtkspellcheck.html
-Author: Maximilian Köhl & Carlos Jenkins
-Author-email: linuxmaxi@googlemail.com & carlos@jenkins.co.cr
-License: GPLv3+
-Download-URL: https://github.com/koehlma/pygtkspellcheck/tarball/master
-Description: A simple but quite powerful spellchecking library written in pure Python for Gtk based on Enchant. It supports PyGObject as well as PyGtk for Python 2 and 3 with automatic switching and binding detection. For automatic translation of the user interface it can use Gedit’s translation files.
-Platform: UNKNOWN
+Version: 5.0.1
+Summary: A simple but quite powerful spellchecking library for GTK written in pure Python.
+Home-page: https://github.com/koehlma/pygtkspellcheck
+License: GPL-3.0-or-later
+Author: Maximilian Köhl
+Author-email: mail@koehlma.de
+Requires-Python: >=3.7,<4.0
Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: X11 Applications :: GTK
Classifier: Environment :: X11 Applications :: Gnome
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
-Classifier: Operating System :: MacOS :: MacOS X
+Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
-Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
Classifier: Topic :: Software Development :: Localization
+Provides-Extra: docs
+Requires-Dist: PyGObject (>=3.42.1,<4.0.0)
+Requires-Dist: myst-parser (>=0.18.0,<0.19.0); extra == "docs"
+Requires-Dist: pyenchant (>=3.0,<4.0)
+Requires-Dist: sphinx (>=4.5.0,<5.0.0); extra == "docs"
+Project-URL: Repository, https://github.com/koehlma/pygtkspellcheck.git
+Description-Content-Type: text/markdown
+
+# Python GTK Spellcheck
+
+[![PyPi Project Page](https://img.shields.io/pypi/v/pygtkspellcheck.svg?&label=latest%20version)](https://pypi.python.org/pypi/pygtkspellcheck)
+[![Documentation](https://readthedocs.org/projects/pygtkspellcheck/badge/?version=latest)](https://pygtkspellcheck.readthedocs.org/en/latest/)
+
+Python GTK Spellcheck is a simple but quite powerful spellchecking library for GTK written in pure Python. It's spellchecking component is based on [Enchant](http://www.abisource.com/projects/enchant/) and it supports both GTK 3 and 4 via [PyGObject](https://live.gnome.org/PyGObject/).
+
+**⚡️ News:** Thanks to [@cheywood](https://github.com/cheywood), Python GTK Spellcheck now supports GTK 4! 🎉
+
+**🟢 Status:** This project is mature, actively maintained, and open to contributions and co-maintainership.
+
+
+## ✨ Features
+
+- **spellchecking** based on [Enchant](http://www.abisource.com/projects/enchant/) for `GtkTextView`
+- support for word, line, and multiline **ignore regular expressions**
+- support for both **GTK 3 and 4** via [PyGObject](https://live.gnome.org/PyGObject/) for Python 3
+- configurable extra word characters such as `'`
+- localized names of the available languages based on [ISO-Codes](http://pkg-isocodes.alioth.debian.org/)
+- support for custom ignore tags and hot swap of `GtkTextBuffer`
+- support for Hunspell (LibreOffice) and Aspell (GNU) dictionaries
+
+<p align="center">
+ <img src="https://raw.githubusercontent.com/koehlma/pygtkspellcheck/master/docs/screenshots/screenshot.png" alt="Screenshot" />
+</p>
+
+
+## 🚀 Getting Started
+
+Python GTK Spellcheck is available from the [Python Package Index](https://pypi.python.org/pypi/pygtkspellcheck):
+```sh
+pip install pygtkspellcheck
+```
+Depending on your distribution, you may also find Python GTK Spellcheck in your package manager.
+For instance, on Debian you may want to install the [`python3-gtkspellcheck`](https://packages.debian.org/bullseye/python3-gtkspellcheck) package.
+
+
+## 🥳 Showcase
+
+Over time, several projects have used Python GTK Spellcheck or are still using it. Among those are:
+
+- [Nested Editor](http://nestededitor.sourceforge.net/about.html): “Specialized editor for structured documents.”
+- [Cherry Tree](http://www.giuspen.com/cherrytree/): “A hierarchical note taking application, […].”
+- [Zim](http://zim-wiki.org/): “Zim is a graphical text editor used to maintain a collection of wiki pages.”
+- [REMARKABLE](http://remarkableapp.github.io/): “The best markdown editor for Linux and Windows.”
+- [RedNotebook](http://rednotebook.sourceforge.net/): “RedNotebook is a modern journal.”
+- [Reportbug](https://packages.debian.org/stretch/reportbug): “Reports bugs in the Debian distribution.”
+- [UberWriter](http://uberwriter.wolfvollprecht.de/): “UberWriter is a writing application for markdown.”
+- [Gourmet](https://github.com/thinkle/gourmet): “Gourmet Recipe Manager is a manager, editor, and organizer for recipes.“
+
+
+## 🔖 Versions
+
+Version numbers follow [Semantic Versioning](http://semver.org/). However, the update from 3 to 4 pertains only API incompatible changes in `oxt_extract` and not the spellchecking component. The update from 4 to 5 removed support for Python 2, GTK 2, `pylocales`, and the `oxt_extract` API. Otherwise, the API is still compatible with version 3.
+
+
+## 📚 Documentation
+
+The documentation is available at [Read the Docs](http://pygtkspellcheck.readthedocs.org/).
+
+
+## 🏗 Contributing
+
+We welcome all kinds of contributions! ❤️
+
+For minor changes and bug fixes feel free to simply open a pull request. For major changes impacting the overall design of Python GTK Spellcheck, please first [start a discussion](https://github.com/koehlma/pygtkspellcheck/discussions/new?category=ideas) outlining your idea.
+
+By submitting a PR, you agree to license your contributions under “GPLv3 or later”.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1c5a4c9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,68 @@
+# Python GTK Spellcheck
+
+[![PyPi Project Page](https://img.shields.io/pypi/v/pygtkspellcheck.svg?&label=latest%20version)](https://pypi.python.org/pypi/pygtkspellcheck)
+[![Documentation](https://readthedocs.org/projects/pygtkspellcheck/badge/?version=latest)](https://pygtkspellcheck.readthedocs.org/en/latest/)
+
+Python GTK Spellcheck is a simple but quite powerful spellchecking library for GTK written in pure Python. It's spellchecking component is based on [Enchant](http://www.abisource.com/projects/enchant/) and it supports both GTK 3 and 4 via [PyGObject](https://live.gnome.org/PyGObject/).
+
+**⚡️ News:** Thanks to [@cheywood](https://github.com/cheywood), Python GTK Spellcheck now supports GTK 4! 🎉
+
+**🟢 Status:** This project is mature, actively maintained, and open to contributions and co-maintainership.
+
+
+## ✨ Features
+
+- **spellchecking** based on [Enchant](http://www.abisource.com/projects/enchant/) for `GtkTextView`
+- support for word, line, and multiline **ignore regular expressions**
+- support for both **GTK 3 and 4** via [PyGObject](https://live.gnome.org/PyGObject/) for Python 3
+- configurable extra word characters such as `'`
+- localized names of the available languages based on [ISO-Codes](http://pkg-isocodes.alioth.debian.org/)
+- support for custom ignore tags and hot swap of `GtkTextBuffer`
+- support for Hunspell (LibreOffice) and Aspell (GNU) dictionaries
+
+<p align="center">
+ <img src="https://raw.githubusercontent.com/koehlma/pygtkspellcheck/master/docs/screenshots/screenshot.png" alt="Screenshot" />
+</p>
+
+
+## 🚀 Getting Started
+
+Python GTK Spellcheck is available from the [Python Package Index](https://pypi.python.org/pypi/pygtkspellcheck):
+```sh
+pip install pygtkspellcheck
+```
+Depending on your distribution, you may also find Python GTK Spellcheck in your package manager.
+For instance, on Debian you may want to install the [`python3-gtkspellcheck`](https://packages.debian.org/bullseye/python3-gtkspellcheck) package.
+
+
+## 🥳 Showcase
+
+Over time, several projects have used Python GTK Spellcheck or are still using it. Among those are:
+
+- [Nested Editor](http://nestededitor.sourceforge.net/about.html): “Specialized editor for structured documents.”
+- [Cherry Tree](http://www.giuspen.com/cherrytree/): “A hierarchical note taking application, […].”
+- [Zim](http://zim-wiki.org/): “Zim is a graphical text editor used to maintain a collection of wiki pages.”
+- [REMARKABLE](http://remarkableapp.github.io/): “The best markdown editor for Linux and Windows.”
+- [RedNotebook](http://rednotebook.sourceforge.net/): “RedNotebook is a modern journal.”
+- [Reportbug](https://packages.debian.org/stretch/reportbug): “Reports bugs in the Debian distribution.”
+- [UberWriter](http://uberwriter.wolfvollprecht.de/): “UberWriter is a writing application for markdown.”
+- [Gourmet](https://github.com/thinkle/gourmet): “Gourmet Recipe Manager is a manager, editor, and organizer for recipes.“
+
+
+## 🔖 Versions
+
+Version numbers follow [Semantic Versioning](http://semver.org/). However, the update from 3 to 4 pertains only API incompatible changes in `oxt_extract` and not the spellchecking component. The update from 4 to 5 removed support for Python 2, GTK 2, `pylocales`, and the `oxt_extract` API. Otherwise, the API is still compatible with version 3.
+
+
+## 📚 Documentation
+
+The documentation is available at [Read the Docs](http://pygtkspellcheck.readthedocs.org/).
+
+
+## 🏗 Contributing
+
+We welcome all kinds of contributions! ❤️
+
+For minor changes and bug fixes feel free to simply open a pull request. For major changes impacting the overall design of Python GTK Spellcheck, please first [start a discussion](https://github.com/koehlma/pygtkspellcheck/discussions/new?category=ideas) outlining your idea.
+
+By submitting a PR, you agree to license your contributions under “GPLv3 or later”.
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 13d6551..0000000
--- a/README.rst
+++ /dev/null
@@ -1,71 +0,0 @@
-Python GTK Spellcheck
-=====================
-
-|pypi| |docs|
-
-Python GTK Spellcheck is a simple but quite powerful spellchecking library for GTK written
-in pure Python. It's spellchecking component is based on Enchant_ and it supports both GTK
-bindings (PyGObject_, PyGTK_) as well as Python 3 and 2.
-
-
-Features
---------
-- **spellchecking** based on Enchant_ for `GtkTextViews`
-- support for word, line and multiple line **ignore regular expressions**
-- PyGObject_ and PyGtk_ (automatic detection) as well as Python 3 and 2 compatible
-- localized names of the available languages based on ISO-Codes_
-- support for custom ignore tags and hot swap of `GtkTextBuffers`
-- enable and disable of spellchecking with preferences memory
-- support for Hunspell (LibreOffice) and Aspell (GNU) dictionaries
-- supports extraction of dictionaries out of LibreOffice extension files
-- legacy API for Python GtkSpell
-
-.. image:: https://raw.githubusercontent.com/koehlma/pygtkspellcheck/master/doc/screenshots/screenshot.png
- :alt: Python GTK Spellcheck Screenshot
- :align: center
-
-.. _Enchant: http://www.abisource.com/projects/enchant/
-.. _PyGObject: https://live.gnome.org/PyGObject/
-.. _PyGTK: http://www.pygtk.org/
-.. _ISO-Codes: http://pkg-isocodes.alioth.debian.org/
-
-
-Showcase
---------
-- `Nested Editor`_: “Specialized editor for structured documents.”
-- `Cherry Tree`_: “A hierarchical note taking application, […].”
-- `Zim`_: “Zim is a graphical text editor used to maintain a collection of wiki pages.”
-- `REMARKABLE`_: “The best markdown editor for Linux and Windows.”
-- `RedNotebook`_: “RedNotebook is a modern journal.”
-- `Reportbug`_: “Reports bugs in the Debian distribution.”
-- `UberWriter`_: “UberWriter is a writing application for markdown.”
-
-.. _Nested Editor: http://nestededitor.sourceforge.net/about.html
-.. _Cherry Tree: http://www.giuspen.com/cherrytree/
-.. _Zim: http://zim-wiki.org/
-.. _REMARKABLE: http://remarkableapp.github.io/
-.. _RedNotebook: http://rednotebook.sourceforge.net/
-.. _Reportbug: https://packages.debian.org/stretch/reportbug
-.. _UberWriter: http://uberwriter.wolfvollprecht.de/
-
-
-Versions
---------
-Version numbers follow `Semantic Versioning`_. However version change from 3 to 4 pertains
-only API incompatible changes in `oxt_extract` and not the spellchecking component.
-
-.. _Semantic Versioning: http://semver.org/
-
-
-Documentation
--------------
-The documentation is available at `Read the Docs`_.
-
-.. _Read the Docs: http://pygtkspellcheck.readthedocs.org/
-
-
-.. |pypi| image:: https://img.shields.io/pypi/v/pygtkspellcheck.svg?style=flat-square&label=latest%20version
- :target: https://pypi.python.org/pypi/pygtkspellcheck
-
-.. |docs| image:: https://readthedocs.org/projects/pygtkspellcheck/badge/?version=latest&style=flat-square
- :target: https://pygtkspellcheck.readthedocs.org/en/latest/
diff --git a/debian/changelog b/debian/changelog
index b67e701..56994e2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+pygtkspellcheck (5.0.1-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk> Mon, 20 Mar 2023 18:54:42 -0000
+
pygtkspellcheck (4.0.5-3) unstable; urgency=medium
[ Ondřej Nový ]
diff --git a/doc/Makefile b/doc/Makefile
deleted file mode 100644
index 491ff46..0000000
--- a/doc/Makefile
+++ /dev/null
@@ -1,153 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-BUILDDIR = build
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " texinfo to make Texinfo files"
- @echo " info to make Texinfo files and run them through makeinfo"
- @echo " gettext to make PO message catalogs"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
-
-clean:
- -rm -rf $(BUILDDIR)/*
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PythonGTKSpellchecker.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PythonGTKSpellchecker.qhc"
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/PythonGTKSpellchecker"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PythonGTKSpellchecker"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo
- @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
- @echo "Run \`make' in that directory to run these through makeinfo" \
- "(use \`make info' here to do that automatically)."
-
-info:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo "Running Texinfo files through makeinfo..."
- make -C $(BUILDDIR)/texinfo info
- @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
- @echo
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/doc/insert_metadata.py b/doc/insert_metadata.py
deleted file mode 100755
index 9cce46e..0000000
--- a/doc/insert_metadata.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python
-# -*- coding:utf-8 -*-
-#
-# Copyright (C) 2012, Maximilian Köhl <linuxmaxi@googlemail.com>
-# Copyright (C) 2012, Carlos Jenkins <carlos@jenkins.co.cr>
-#
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-ENCODING = 'UTF-8'
-
-import sys
-import argparse
-
-# Python 2/3 unicode
-import sys
-if sys.version_info.major == 3:
- io_in = lambda x: x
- io_out = io_in
-else:
- io_in = lambda x: x.decode(ENCODING)
- io_out = lambda x: x.encode(ENCODING)
-
-# Pipes Python enconding nightmare
-if sys.stdout.encoding is None:
- import codecs
- sys.stdout = codecs.getwriter(ENCODING)(sys.stdout)
-
-# Find metadata dict
-from os.path import join, dirname
-sys.path.append(join(dirname(__file__), '../src/'))
-from gtkspellcheck import __metadata__
-
-# Parse command line
-parser = argparse.ArgumentParser(description='Insert metadata into plain text files.')
-parser.add_argument('infile', type=argparse.FileType('r'),
- help='path to the template file or stdin pipe.')
-parser.add_argument('-w', '--writeback', action='store_true',
- help='write the output back to the input file.')
-args = parser.parse_args()
-
-# Read content
-out_content = io_in(args.infile.read())
-args.infile.close()
-
-# Replace variables
-# FIXME: Stop wasting memory like crazy!
-for key, value in __metadata__.items():
- out_content = out_content.replace(key, value)
-
-# Print/Write new content
-if args.writeback:
- try:
- with open(args.infile.name, 'w') as out_handler:
- out_handler.write(io_out(out_content))
- except Exception as e:
- sys.stderr.write(str(e) + '\n')
- sys.exit(-1)
-else:
- print(out_content)
-
-sys.exit(0)
diff --git a/doc/make.bat b/doc/make.bat
deleted file mode 100644
index 5c010b1..0000000
--- a/doc/make.bat
+++ /dev/null
@@ -1,190 +0,0 @@
-@ECHO OFF
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build2
-)
-set BUILDDIR=build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
-set I18NSPHINXOPTS=%SPHINXOPTS% source
-if NOT "%PAPER%" == "" (
- set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
- set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
-)
-
-if "%1" == "" goto help
-
-if "%1" == "help" (
- :help
- echo.Please use `make ^<target^>` where ^<target^> is one of
- echo. html to make standalone HTML files
- echo. dirhtml to make HTML files named index.html in directories
- echo. singlehtml to make a single large HTML file
- echo. pickle to make pickle files
- echo. json to make JSON files
- echo. htmlhelp to make HTML files and a HTML help project
- echo. qthelp to make HTML files and a qthelp project
- echo. devhelp to make HTML files and a Devhelp project
- echo. epub to make an epub
- echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
- echo. text to make text files
- echo. man to make manual pages
- echo. texinfo to make Texinfo files
- echo. gettext to make PO message catalogs
- echo. changes to make an overview over all changed/added/deprecated items
- echo. linkcheck to check all external links for integrity
- echo. doctest to run all doctests embedded in the documentation if enabled
- goto end
-)
-
-if "%1" == "clean" (
- for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
- del /q /s %BUILDDIR%\*
- goto end
-)
-
-if "%1" == "html" (
- %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/html.
- goto end
-)
-
-if "%1" == "dirhtml" (
- %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
- goto end
-)
-
-if "%1" == "singlehtml" (
- %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
- goto end
-)
-
-if "%1" == "pickle" (
- %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the pickle files.
- goto end
-)
-
-if "%1" == "json" (
- %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the JSON files.
- goto end
-)
-
-if "%1" == "htmlhelp" (
- %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run HTML Help Workshop with the ^
-.hhp project file in %BUILDDIR%/htmlhelp.
- goto end
-)
-
-if "%1" == "qthelp" (
- %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run "qcollectiongenerator" with the ^
-.qhcp project file in %BUILDDIR%/qthelp, like this:
- echo.^> qcollectiongenerator %BUILDDIR%\qthelp\PythonGTKSpellchecker.qhcp
- echo.To view the help file:
- echo.^> assistant -collectionFile %BUILDDIR%\qthelp\PythonGTKSpellchecker.ghc
- goto end
-)
-
-if "%1" == "devhelp" (
- %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished.
- goto end
-)
-
-if "%1" == "epub" (
- %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The epub file is in %BUILDDIR%/epub.
- goto end
-)
-
-if "%1" == "latex" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "text" (
- %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The text files are in %BUILDDIR%/text.
- goto end
-)
-
-if "%1" == "man" (
- %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The manual pages are in %BUILDDIR%/man.
- goto end
-)
-
-if "%1" == "texinfo" (
- %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
- goto end
-)
-
-if "%1" == "gettext" (
- %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
- goto end
-)
-
-if "%1" == "changes" (
- %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
- if errorlevel 1 exit /b 1
- echo.
- echo.The overview file is in %BUILDDIR%/changes.
- goto end
-)
-
-if "%1" == "linkcheck" (
- %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
- if errorlevel 1 exit /b 1
- echo.
- echo.Link check complete; look for any errors in the above output ^
-or in %BUILDDIR%/linkcheck/output.txt.
- goto end
-)
-
-if "%1" == "doctest" (
- %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
- if errorlevel 1 exit /b 1
- echo.
- echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
- goto end
-)
-
-:end
diff --git a/doc/metadata/documentation.rst b/doc/metadata/documentation.rst
deleted file mode 100644
index aa1ab72..0000000
--- a/doc/metadata/documentation.rst
+++ /dev/null
@@ -1,62 +0,0 @@
-{% names['full'] %}
-{% '=' * len(names['full']) %}
-{% linkify(description['long'], 'rst') %}
-
-Features
---------
-{% '- ' + '\n- '.join(features) %}
-
-API Reference
--------------
-.. autoclass:: gtkspellcheck.spellcheck.SpellChecker
- :members:
-
-.. autoclass:: gtkspellcheck.spellcheck.NoDictionariesFound
-
-.. autoclass:: gtkspellcheck.spellcheck.NoGtkBindingFound
-
-.. autofunction:: pylocales.code_to_name
-
-.. autofunction:: gtkspellcheck.oxt_extract.extract
-
-.. autofunction:: gtkspellcheck.oxt_extract.batch_extract
-
-.. autoclass:: gtkspellcheck.oxt_extract.BadXml
-
-.. autoclass:: gtkspellcheck.oxt_extract.BadExtensionFile
-
-.. autoclass:: gtkspellcheck.oxt_extract.ExtractPathIsNoDirectory
-
-Development
------------
-Development happens at `GitHub`_.
-
-.. _GitHub: {% development %}
-
- ``git clone git://github.com/koehlma/pygtkspellcheck.git``
-
-Download last sources in a `ZIP`_ or `Tarball`_ file.
-
-.. _ZIP: https://github.com/koehlma/pygtkspellcheck/zipball/master
-.. _Tarball: https://github.com/koehlma/pygtkspellcheck/tarball/master
-
-Website
--------
-Checkout the `official project website`_ for additional information.
-
-.. _official project website: {% homepage %}
-
-Examples
---------
-- `PyGObject Simple Example`_
-- `PyGtk Simple Example`_
-
-.. _PyGObject Simple Example: https://github.com/koehlma/pygtkspellcheck/blob/master/examples/simple_pygobject.py
-.. _PyGtk Simple Example: https://github.com/koehlma/pygtkspellcheck/blob/master/examples/simple_pygtk.py
-
-
-License
--------
-{% names['short'] %} is released under `GPLv3`_ or at your opinion any later version.
-
-.. _GPLv3: https://www.gnu.org/licenses/gpl-3.0.html
\ No newline at end of file
diff --git a/doc/metadata/metadata.py b/doc/metadata/metadata.py
deleted file mode 100644
index 61bbff1..0000000
--- a/doc/metadata/metadata.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# -*- coding:utf-8 -*-
-#
-# Copyright (C) 2012, Maximilian Köhl <linuxmaxi@googlemail.com>
-#
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-import os.path
-import re
-
-__path__ = os.path.dirname(__file__)
-
-names = {'full': 'Python GTK Spellchecker',
- 'short': 'PyGtkSpellcheck',
- 'url': 'pygtkspellcheck'}
-
-features = ['localized names of the available languages',
- 'supports word, line and multiple line ignore regular expressions',
- 'supports ignore custom tags on GtkTextBuffer',
- 'enable and disable of spellchecking with preferences memory',
- 'supports hotswap of GtkTextBuffers',
- 'PyGObject and PyGtk compatible with automatic detection',
- 'Python 2 and 3 support'
- 'as Enchant, support for Hunspell (LibreOffice) and Aspell (GNU) dictionaries',
- 'extract dictionaries out of LibreOffice extension files',
- 'legacy API for Python GtkSpell']
-
-description = {'short': 'a simple but quite powerful Python spell checking library for GtkTextViews based on Enchant',
- 'long': ('A simple but quite powerful spellchecking library written '
- 'in pure Python for Gtk based on Enchant. It supports PyGObject '
- 'as well as PyGtk for Python 2 and 3 with automatic switching '
- 'and binding detection. For automatic translation of the user '
- 'interface it can use Gedit’s translation files.')}
-
-screenshot = os.path.join(__path__, 'screenshot.png')
-
-development = 'https://github.com/koehlma/pygtkspellcheck'
-
-documentation = 'http://pygtkspellcheck.readthedocs.org/'
-
-homepage = 'http://koehlma.github.com/projects/pygtkspellcheck.html'
-
-links = {'Enchant': 'http://www.abisource.com/projects/enchant/',
- 'PyGObject': 'https://live.gnome.org/PyGObject/',
- 'PyGtk': 'http://www.pygtk.org/'}
-
-with open(os.path.join(__path__, 'readme.md'), 'rb') as _readme:
- readme = _readme.read().decode('utf-8')
-
-with open(os.path.join(__path__, 'pypi.rst'), 'rb') as _pypi:
- pypi = _pypi.read().decode('utf-8')
-
-with open(os.path.join(__path__, 'documentation.rst'), 'rb') as _documentation:
- docs = _documentation.read().decode('utf-8')
-
-with open(os.path.join(__path__, 'website.md'), 'rb') as _website:
- website = _website.read().decode('utf-8')
-
-replace = re.compile('\{%\s*(.+?)\s*%\}')
-
-def linkify(text, format):
- if format == 'markdown':
- for name, url in links.items():
- text = text.replace(name, '[{}]({})'.format(name, url))
- elif format == 'rst':
- for name in links:
- text = text.replace(name, '`{}`_'.format(name))
- text += '\n'
- for name, url in links.items():
- if text.find(name) > -1:
- text += '\n.. _{}: {}'.format(name, url)
- return text
-
-def template(match):
- code = match.group(1)
- return str(eval(code))
-
-if __name__ == '__main__':
- print('creating readme')
- with open(os.path.join(__path__, '..', '..', 'README.md'), 'wb') as _readme:
- _readme.write(replace.sub(template, readme).encode('utf-8'))
- print('creating pypi')
- with open(os.path.join(__path__, '..', 'pypi', 'page.rst'), 'wb') as _pypi:
- _pypi.write(replace.sub(template, pypi).encode('utf-8'))
- print('creating documentation')
- with open(os.path.join(__path__, '..', 'source', 'index.rst'), 'wb') as _documentation:
- _documentation.write(replace.sub(template, docs).encode('utf-8'))
- koehlma_github = os.path.join(__path__, '..', '..', '..', 'koehlma.github.com')
- if os.path.exists(koehlma_github):
- print('creating website')
- with open(os.path.join(koehlma_github, 'projects', 'pygtkspellcheck.md'), 'wb') as _website:
- _website.write(replace.sub(template, website).encode('utf-8'))
\ No newline at end of file
diff --git a/doc/metadata/pypi.rst b/doc/metadata/pypi.rst
deleted file mode 100644
index aebb83c..0000000
--- a/doc/metadata/pypi.rst
+++ /dev/null
@@ -1,85 +0,0 @@
-{% names['full'] %}
-{% '=' * len(names['full']) %}
-{% linkify(description['long'], 'rst') %}
-
-Features
-========
-{% '- ' + '\n- '.join(features) %}
-
-Documentation
-=============
-The documentation is available at `Read the Docs`_.
-
-.. _Read the Docs: {% documentation %}
-
-Distribution
-============
-Cheeseshop
-^^^^^^^^^^
-`PyPI package`_ is available:
-
-.. _PyPI package: http://pypi.python.org/pypi/pygtkspellcheck/
-
-::
-
- pip install pygtkspellcheck
-
-Archlinux - AUR
-^^^^^^^^^^^^^^^
-Python 3
---------
-
-::
- pacman -S python-gtkspellcheck
-
-Python 2
---------
-
-::
- pacman -S python2-gtkspellcheck
-
-Ubuntu / Debian
-^^^^^^^^^^^^^^^
-Ubuntu - Repository
--------------------
-
-::
-
- sudo add-apt-repository ppa:koehlma/packages
- sudo apt-get update
-
-Debian - Repository
--------------------
-
-::
-
- sudo su
- echo "deb http://ppa.launchpad.net/koehlma/packages/ubuntu precise main" >> /etc/apt/sources.list
- apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 775B7DF6
- apt-get update
-
-Python 2
---------
-
-::
-
- sudo apt-get install python-gtkspellcheck
-
-Python 3
---------
-
-::
-
- sudo apt-get install python3-gtkspellcheck
-
-Development
-^^^^^^^^^^^
-Development happens at `GitHub`_.
-
-.. _GitHub: {% development %}
-
-License
-^^^^^^^
-{% names['short'] %} is released under `GPLv3`_ or at your opinion any later version.
-
-.. _GPLv3: https://www.gnu.org/licenses/gpl-3.0.html
diff --git a/doc/metadata/readme.md b/doc/metadata/readme.md
deleted file mode 100644
index 4c61641..0000000
--- a/doc/metadata/readme.md
+++ /dev/null
@@ -1,25 +0,0 @@
-## About
-{% linkify(description['long'], 'markdown') %}
-
-## Features
-{% '* ' + '\n* '.join(features) %}
-
-## Documentation
-The documentation is available at [Read the Docs]({% documentation %}).
-
-## Website
-Checkout the [official project website]({% homepage %}).
-
-## License
-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 3 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, see <http://www.gnu.org/licenses/>.
diff --git a/doc/metadata/screenshot.png b/doc/metadata/screenshot.png
deleted file mode 100644
index 1075b12..0000000
Binary files a/doc/metadata/screenshot.png and /dev/null differ
diff --git a/doc/metadata/website.md b/doc/metadata/website.md
deleted file mode 100644
index f5a02bb..0000000
--- a/doc/metadata/website.md
+++ /dev/null
@@ -1,71 +0,0 @@
----
-layout: default
-title: Python GTK Spellchecker
-repository: pygtkspellcheck
-downloads:
-- class: archlinux
- url: https://github.com/downloads/koehlma/pygtkspellcheck/python-gtkspellcheck-3.0-1-any.pkg.tar.xz
- text: Python 3
-- class: archlinux
- url: https://github.com/downloads/koehlma/pygtkspellcheck/python2-gtkspellcheck-3.0-1-any.pkg.tar.xz
- text: Python 2
-- class: debian
- url: https://github.com/downloads/koehlma/pygtkspellcheck/python3-gtkspellcheck_3.0-1_all.deb
- text: Python 3
-- class: debian
- url: https://github.com/downloads/koehlma/pygtkspellcheck/python-gtkspellcheck_3.0-1_all.deb
- text: Python 2
----
-
-{% linkify(description['long'], 'markdown') %}
-
-# Features
-{% '* ' + '\n* '.join(features) %}
-
-# Screenshots
-![Screenshot](/projects/pygtkspellcheck/screenshot.png)
-
-## Documentation
-The documentation is available at [Read the Docs]({% documentation %}).
-
-# Examples
-* [PyGObject Simple Example](https://github.com/koehlma/pygtkspellcheck/blob/master/examples/simple_pygobject.py)
-* [PyGtk Simple Example](https://github.com/koehlma/pygtkspellcheck/blob/master/examples/simple_pygtk.py)
-
-# Distribution
-## Cheeseshop
-[PyPI package](http://pypi.python.org/pypi/pygtkspellcheck/) is available:
-
- pip install pygtkspellcheck
-
-## Archlinux - AUR
-### Python 3
-[AUR Package](https://aur.archlinux.org/packages.php?ID=61200)
-
- yaourt -S python-gtkspellcheck
-
-### Python 2
-[AUR Package](https://aur.archlinux.org/packages.php?ID=61199)
-
- yaourt -S python2-gtkspellcheck
-
-## Ubuntu / Debian
-### Ubuntu - Repository
-
- sudo add-apt-repository ppa:koehlma/packages
- sudo apt-get update
-
-### Debian - Repository
-
- sudo su
- echo "deb http://ppa.launchpad.net/koehlma/packages/ubuntu precise main" >> /etc/apt/sources.list
- apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 775B7DF6
- apt-get update
-
-### Python 2
-
- sudo apt-get install python-gtkspellcheck
-
-### Python 3
-
- sudo apt-get install python3-gtkspellcheck
diff --git a/doc/pypi/index.html b/doc/pypi/index.html
deleted file mode 100644
index c2514c2..0000000
--- a/doc/pypi/index.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8">
- <meta http-equiv="refresh" content="2; URL=http://pygtkspellcheck.readthedocs.org/">
-
- <title>PyGtkSpellcheck - Documentation</title>
-
- <meta name="author" content="Maximilian Köhl">
- </head>
- <body>
- The documentation has moved to <a href="http://pygtkspellcheck.readthedocs.org">Read the Docs</a>.
- </body>
-</html>
diff --git a/doc/pypi/page.rst b/doc/pypi/page.rst
deleted file mode 100644
index 995c241..0000000
--- a/doc/pypi/page.rst
+++ /dev/null
@@ -1,81 +0,0 @@
-Python GTK Spellchecker
-=======================
-A simple but quite powerful spellchecking library written in pure Python for Gtk based on `Enchant`_. It supports `PyGObject`_ as well as `PyGtk`_ for Python 2 and 3 with automatic switching and binding detection. For automatic translation of the user interface it can use Gedit’s translation files.
-
-.. _PyGObject: https://live.gnome.org/PyGObject/
-.. _Enchant: http://www.abisource.com/projects/enchant/
-.. _PyGtk: http://www.pygtk.org/
-
-Features
-========
-- localized names of the available languages
-- supports word, line and multiple line ignore regular expressions
-- supports ignore custom tags on GtkTextBuffer
-- enable and disable of spellchecking with preferences memory
-- supports hotswap of GtkTextBuffers
-- PyGObject and PyGtk compatible with automatic detection
-- Python 2 and 3 supportas Enchant, support for Hunspell (LibreOffice) and Aspell (GNU) dictionaries
-- extract dictionaries out of LibreOffice extension files
-- legacy API for Python GtkSpell
-
-Documentation
-=============
-The documentation is available at `Read the Docs`_.
-
-.. _Read the Docs: http://pygtkspellcheck.readthedocs.org/
-
-Distribution
-============
-Cheeseshop
-^^^^^^^^^^
-`PyPI package`_ is available:
-
-.. _PyPI package: http://pypi.python.org/pypi/pygtkspellcheck/
-
-::
-
- pip install pygtkspellcheck
-
-Archlinux - AUR
-^^^^^^^^^^^^^^^
-Python 3
---------
-
-::
-
- pacman -S python-gtkspellcheck
-
-Python 2
---------
-
-::
-
- pacman -S python2-gtkspellcheck
-
-Ubuntu / Debian
-^^^^^^^^^^^^^^^
-Python 2
---------
-
-::
-
- sudo apt-get install python-gtkspellcheck
-
-Python 3
---------
-
-::
-
- sudo apt-get install python3-gtkspellcheck
-
-Development
-^^^^^^^^^^^
-Development happens at `GitHub`_.
-
-.. _GitHub: https://github.com/koehlma/pygtkspellcheck
-
-License
-^^^^^^^
-PyGtkSpellcheck is released under `GPLv3`_ or at your opinion any later version.
-
-.. _GPLv3: https://www.gnu.org/licenses/gpl-3.0.html
diff --git a/doc/screenshots/screenshot.png b/doc/screenshots/screenshot.png
deleted file mode 100644
index 1075b12..0000000
Binary files a/doc/screenshots/screenshot.png and /dev/null differ
diff --git a/doc/source/conf.py b/doc/source/conf.py
deleted file mode 100644
index 5810273..0000000
--- a/doc/source/conf.py
+++ /dev/null
@@ -1,277 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Python GTK Spellchecker documentation build configuration file, created by
-# sphinx-quickstart2 on Tue Apr 10 18:57:32 2012.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys, os
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
-
-doc_directory = os.path.dirname(os.path.abspath(__file__))
-sys.path.append(os.path.join(doc_directory, '..', '..', 'src'))
-
-import sys
-
-# Support for readthedocs.org
-class Mock(object):
- def __init__(self, *args, **kwargs):
- pass
-
- def __call__(self, *args, **kwargs):
- return Mock()
-
- @classmethod
- def __getattr__(self, name):
- if name in ('__file__', '__path__'):
- return '/dev/null'
- elif name[0] == name[0].upper():
- return type(name, (), {})
- else:
- return Mock()
-
-MOCK_MODULES = ['enchant']
-for mod_name in MOCK_MODULES:
- try:
- __import__(mod_name)
- except:
- sys.modules[mod_name] = Mock()
-
-sys.modules['gtk'] = None
-import gtkspellcheck as m
-import pylocales
-
-start_file = 'index'
-
-# -- General configuration -----------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc']
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = start_file
-
-# General information about the project.
-project = m.__project__
-copyright = m.__authors__
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = m.__version__
-# The full version, including alpha/beta/rc tags.
-release = m.__version__
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = []
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-html_theme = 'default'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-#html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = m.__short_name__ + 'doc'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
- (start_file, m.__short_name__ + '.tex', m.__project__ + ' Documentation',
- m.__authors__.replace('&', r'\&'), 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- (start_file, m.__short_name__, m.__project__ + ' Documentation',
- m.__authors__.split(' & '), 1)
-]
-
-# If true, show URL addresses after external links.
-#man_show_urls = False
-
-
-# -- Options for Texinfo output ------------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- (start_file, m.__short_name__, m.__project__ + ' Documentation',
- m.__authors__, m.__short_name__, m.__desc_short__,
- 'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
-
-# If false, no module index is generated.
-#texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
diff --git a/doc/source/index.rst b/doc/source/index.rst
deleted file mode 100644
index 8cbd958..0000000
--- a/doc/source/index.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-Python GTK Spellchecker
-=======================
-A simple but quite powerful spellchecking library written in pure Python for Gtk based on `Enchant`_. It supports `PyGObject`_ as well as `PyGtk`_ for Python 2 and 3 with automatic switching and binding detection. For automatic translation of the user interface it can use Gedit’s translation files.
-
-.. _PyGObject: https://live.gnome.org/PyGObject/
-.. _Enchant: http://www.abisource.com/projects/enchant/
-.. _PyGtk: http://www.pygtk.org/
-
-Features
---------
-- localized names of the available languages
-- supports word, line and multiple line ignore regular expressions
-- supports ignore custom tags on GtkTextBuffer
-- enable and disable of spellchecking with preferences memory
-- supports hotswap of GtkTextBuffers
-- PyGObject and PyGtk compatible with automatic detection
-- Python 2 and 3 supportas Enchant, support for Hunspell (LibreOffice) and Aspell (GNU) dictionaries
-- extract dictionaries out of LibreOffice extension files
-- legacy API for Python GtkSpell
-
-API Reference
--------------
-.. autoclass:: gtkspellcheck.spellcheck.SpellChecker
- :members:
-
-.. autoclass:: gtkspellcheck.spellcheck.NoDictionariesFound
-
-.. autoclass:: gtkspellcheck.spellcheck.NoGtkBindingFound
-
-
-Deprecated API Reference
-------------------------
-.. warning::
-
- The following functions are deprecated since version 4.0.5, they will be removed
- from "pygtkspellcheck" in 5.0.
-
-
-.. autofunction:: pylocales.code_to_name
-
-.. autofunction:: gtkspellcheck.oxt_extract.extract
-
-.. autofunction:: gtkspellcheck.oxt_extract.batch_extract
-
-.. autoclass:: gtkspellcheck.oxt_extract.BadXml
-
-.. autoclass:: gtkspellcheck.oxt_extract.BadExtensionFile
-
-.. autoclass:: gtkspellcheck.oxt_extract.ExtractPathIsNoDirectory
-
-Development
------------
-Development happens at `GitHub`_.
-
-.. _GitHub: https://github.com/koehlma/pygtkspellcheck
-
- ``git clone git://github.com/koehlma/pygtkspellcheck.git``
-
-Download last sources in a `ZIP`_ or `Tarball`_ file.
-
-.. _ZIP: https://github.com/koehlma/pygtkspellcheck/zipball/master
-.. _Tarball: https://github.com/koehlma/pygtkspellcheck/tarball/master
-
-Website
--------
-Checkout the `official project website`_ for additional information.
-
-.. _official project website: http://koehlma.github.com/projects/pygtkspellcheck.html
-
-Examples
---------
-- `PyGObject Simple Example`_
-- `PyGtk Simple Example`_
-
-.. _PyGObject Simple Example: https://github.com/koehlma/pygtkspellcheck/blob/master/examples/simple_pygobject.py
-.. _PyGtk Simple Example: https://github.com/koehlma/pygtkspellcheck/blob/master/examples/simple_pygtk.py
-
-
-License
--------
-PyGtkSpellcheck is released under `GPLv3`_ or at your opinion any later version.
-
-.. _GPLv3: https://www.gnu.org/licenses/gpl-3.0.html
\ No newline at end of file
diff --git a/examples/large_pygobject.py b/examples/large_pygobject.py
deleted file mode 100644
index 4607b5e..0000000
--- a/examples/large_pygobject.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# -*- coding:utf-8 -*-
-#
-# Copyright (C) 2012, Maximilian Köhl <linuxmaxi@googlemail.com>
-# Copyright (C) 2012, Carlos Jenkins <carlos@jenkins.co.cr>
-#
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-# Load example if running from source, ignore this
-import sys
-from os.path import join, dirname
-sys.path.append(join(dirname(__file__), '../src/'))
-
-import locale
-
-from gi.repository import Gtk as gtk
-
-from gtkspellcheck import SpellChecker
-
-if __name__ == '__main__':
- def quit(*args):
- gtk.main_quit()
-
- window = gtk.Window.new(gtk.WindowType.TOPLEVEL)
- window.set_title('PyGtkSpellCheck Example')
- view = gtk.TextView.new()
-
- spellchecker = SpellChecker(view, locale.getdefaultlocale()[0], collapse=False)
-
- for code, name in spellchecker.languages:
- print('code: %5s, language: %s' % (code, name))
-
- window.set_default_size(600, 400)
- window.add(view)
- window.show_all()
- window.connect('delete-event', quit)
- gtk.main()
\ No newline at end of file
diff --git a/examples/large_pygtk.py b/examples/large_pygtk.py
deleted file mode 100644
index 35a1479..0000000
--- a/examples/large_pygtk.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# -*- coding:utf-8 -*-
-#
-# Copyright (C) 2012, Maximilian Köhl <linuxmaxi@googlemail.com>
-# Copyright (C) 2012, Carlos Jenkins <carlos@jenkins.co.cr>
-#
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-# Load example if running from source, ignore this
-import sys
-from os.path import join, dirname
-sys.path.append(join(dirname(__file__), '../src/'))
-
-import locale
-
-import gtk
-
-from gtkspellcheck import SpellChecker
-
-if __name__ == '__main__':
- def quit(*args):
- gtk.main_quit()
-
- window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- window.set_title('PyGtkSpellCheck Example')
- view = gtk.TextView()
-
- spellchecker = SpellChecker(view, locale.getdefaultlocale()[0], collapse=False)
-
- for code, name in spellchecker.languages:
- print('code: %5s, language: %s' % (code, name))
-
- window.set_default_size(600, 400)
- window.add(view)
- window.show_all()
- window.connect('delete-event', quit)
- gtk.main()
\ No newline at end of file
diff --git a/examples/simple_pygobject.py b/examples/simple_pygobject.py
deleted file mode 100644
index 8bf7bab..0000000
--- a/examples/simple_pygobject.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# -*- coding:utf-8 -*-
-#
-# Copyright (C) 2012, Maximilian Köhl <linuxmaxi@googlemail.com>
-# Copyright (C) 2012, Carlos Jenkins <carlos@jenkins.co.cr>
-#
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-# Load example if running from source, ignore this
-import sys
-from os.path import join, dirname
-sys.path.append(join(dirname(__file__), '../src/'))
-
-import locale
-
-from gi.repository import Gtk as gtk
-
-from gtkspellcheck import SpellChecker
-
-if __name__ == '__main__':
- def quit(*args):
- gtk.main_quit()
-
- window = gtk.Window.new(gtk.WindowType.TOPLEVEL)
- window.set_title('PyGtkSpellCheck Example')
- view = gtk.TextView.new()
-
- spellchecker = SpellChecker(view, locale.getdefaultlocale()[0])
-
- for code, name in spellchecker.languages:
- print('code: %5s, language: %s' % (code, name))
-
- window.set_default_size(600, 400)
- window.add(view)
- window.show_all()
- window.connect('delete-event', quit)
- gtk.main()
\ No newline at end of file
diff --git a/examples/simple_pygtk.py b/examples/simple_pygtk.py
deleted file mode 100644
index 9e26982..0000000
--- a/examples/simple_pygtk.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# -*- coding:utf-8 -*-
-#
-# Copyright (C) 2012, Maximilian Köhl <linuxmaxi@googlemail.com>
-# Copyright (C) 2012, Carlos Jenkins <carlos@jenkins.co.cr>
-#
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-# Load example if running from source, ignore this
-import sys
-from os.path import join, dirname
-sys.path.append(join(dirname(__file__), '../src/'))
-
-import locale
-
-import gtk
-
-from gtkspellcheck import SpellChecker
-
-if __name__ == '__main__':
- def quit(*args):
- gtk.main_quit()
-
- window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- window.set_title('PyGtkSpellCheck Example')
- view = gtk.TextView()
-
- spellchecker = SpellChecker(view, locale.getdefaultlocale()[0])
-
- for code, name in spellchecker.languages:
- print('code: %5s, language: %s' % (code, name))
-
- window.set_default_size(600, 400)
- window.add(view)
- window.show_all()
- window.connect('delete-event', quit)
- gtk.main()
diff --git a/locale/de/pygtkspellcheck.mo b/locale/de/pygtkspellcheck.mo
deleted file mode 100644
index f660023..0000000
Binary files a/locale/de/pygtkspellcheck.mo and /dev/null differ
diff --git a/locale/de/pygtkspellcheck.po b/locale/de/pygtkspellcheck.po
deleted file mode 100644
index 4537de0..0000000
--- a/locale/de/pygtkspellcheck.po
+++ /dev/null
@@ -1,58 +0,0 @@
-msgid ""
-msgstr ""
-"Project-Id-Version: gtkspellchecker\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-01-07 23:30+0100\n"
-"PO-Revision-Date: 2013-01-07 23:30+0100\n"
-"Last-Translator: Maximilian Köhl <linuxmaxi@googlemail.com>\n"
-"Language-Team: \n"
-"Language: de\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-KeywordsList: _;gettext;gettext_noop\n"
-"X-Poedit-Basepath: /home/maximilian/Entwicklung/pygtkspellcheck/src\n"
-"X-Poedit-SourceCharset: UTF-8\n"
-"X-Poedit-SearchPath-0: ./gtkspellcheck\n"
-
-#: gtkspellcheck/spellcheck.py:98
-msgid "Unknown"
-msgstr "Unbekannt"
-
-#: gtkspellcheck/spellcheck.py:480
-msgid "(no suggestions)"
-msgstr "(keine Vorschläge)"
-
-#: gtkspellcheck/spellcheck.py:502 gtkspellcheck/spellcheck.py:505
-msgid "Add \"{}\" to Dictionary"
-msgstr "\"{}\" zum Wörterbuch hinzufügen"
-
-#: gtkspellcheck/spellcheck.py:509 gtkspellcheck/spellcheck.py:511
-msgid "Ignore All"
-msgstr "Alles ignorieren"
-
-#: gtkspellcheck/spellcheck.py:526 gtkspellcheck/spellcheck.py:528
-msgid "Languages"
-msgstr "Sprachen"
-
-#: gtkspellcheck/spellcheck.py:544 gtkspellcheck/spellcheck.py:547
-msgid "Suggestions"
-msgstr "Vorschläge"
-
-#: gtkspellcheck/oxt_extract.py:244
-msgid "extension \"{}\" is not a valid ZIP file"
-msgstr "Extension \"{}\" ist keine ZIP Datei"
-
-#: gtkspellcheck/oxt_extract.py:250
-msgid "extension \"{}\" has no valid XML dictionary registry"
-msgstr "Extension hat keine valide XML Registry"
-
-#: gtkspellcheck/oxt_extract.py:270
-msgid "unable to move extension, file with same name exists within move_path"
-msgstr ""
-"Extension kann nicht verschoben werden, es existiert bereits eine Datei mit "
-"gleichem Name in move_path"
-
-#: gtkspellcheck/oxt_extract.py:278
-msgid "unable to move extension, move_path is not a directory"
-msgstr "Extension kann nicht verschoben werden, move_path ist kein Verzeichnis"
diff --git a/locale/en/pygtkspellcheck.mo b/locale/en/pygtkspellcheck.mo
deleted file mode 100644
index 87dde81..0000000
Binary files a/locale/en/pygtkspellcheck.mo and /dev/null differ
diff --git a/locale/en/pygtkspellcheck.po b/locale/en/pygtkspellcheck.po
deleted file mode 100644
index 070a130..0000000
--- a/locale/en/pygtkspellcheck.po
+++ /dev/null
@@ -1,60 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: gtkspellcheck\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-01-07 23:31+0100\n"
-"PO-Revision-Date: 2013-01-07 23:31+0100\n"
-"Last-Translator: Maximilian Köhl <linuxmaxi@googlemail.com>\n"
-"Language-Team: \n"
-"Language: en\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-Basepath: /home/maximilian/Entwicklung/pygtkspellcheck/src\n"
-"X-Poedit-SourceCharset: UTF-8\n"
-"X-Poedit-SearchPath-0: ./gtkspellcheck\n"
-
-#: gtkspellcheck/spellcheck.py:98
-msgid "Unknown"
-msgstr ""
-
-#: gtkspellcheck/spellcheck.py:480
-msgid "(no suggestions)"
-msgstr ""
-
-#: gtkspellcheck/spellcheck.py:502 gtkspellcheck/spellcheck.py:505
-msgid "Add \"{}\" to Dictionary"
-msgstr ""
-
-#: gtkspellcheck/spellcheck.py:509 gtkspellcheck/spellcheck.py:511
-msgid "Ignore All"
-msgstr ""
-
-#: gtkspellcheck/spellcheck.py:526 gtkspellcheck/spellcheck.py:528
-msgid "Languages"
-msgstr ""
-
-#: gtkspellcheck/spellcheck.py:544 gtkspellcheck/spellcheck.py:547
-msgid "Suggestions"
-msgstr ""
-
-#: gtkspellcheck/oxt_extract.py:244
-msgid "extension \"{}\" is not a valid ZIP file"
-msgstr ""
-
-#: gtkspellcheck/oxt_extract.py:250
-msgid "extension \"{}\" has no valid XML dictionary registry"
-msgstr ""
-
-#: gtkspellcheck/oxt_extract.py:270
-msgid "unable to move extension, file with same name exists within move_path"
-msgstr ""
-
-#: gtkspellcheck/oxt_extract.py:278
-msgid "unable to move extension, move_path is not a directory"
-msgstr ""
diff --git a/locale/es/pygtkspellcheck.mo b/locale/es/pygtkspellcheck.mo
deleted file mode 100644
index f2dd84a..0000000
Binary files a/locale/es/pygtkspellcheck.mo and /dev/null differ
diff --git a/locale/es/pygtkspellcheck.po b/locale/es/pygtkspellcheck.po
deleted file mode 100644
index e0e58bf..0000000
--- a/locale/es/pygtkspellcheck.po
+++ /dev/null
@@ -1,56 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: gtkspellcheck\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-09-15 10:16+0100\n"
-"PO-Revision-Date: 2012-09-15 10:16+0100\n"
-"Last-Translator: Maximilian Köhl <linuxmaxi@googlemail.com>\n"
-"Language-Team: Carlos Jenkins <carlos@jenkins.co.cr>\n"
-"Language: es\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"X-Poedit-SourceCharset: UTF-8\n"
-"X-Poedit-Basepath: /home/maximilian/development/pygtkspellcheck/src\n"
-"X-Poedit-SearchPath-0: ./gtkspellcheck\n"
-
-#: gtkspellcheck/oxt_extract.py:242
-msgid "extension \"{}\" is not a valid ZIP file"
-msgstr ""
-
-#: gtkspellcheck/oxt_extract.py:248
-msgid "extension \"{}\" has no valid XML dictionary registry"
-msgstr ""
-
-#: gtkspellcheck/oxt_extract.py:268
-msgid "unable to move extension, file with same name exists within move_path"
-msgstr ""
-
-#: gtkspellcheck/oxt_extract.py:276
-msgid "unable to move extension, move_path is not a directory"
-msgstr ""
-
-#: gtkspellcheck/spellcheck.py:467
-msgid "(no suggestions)"
-msgstr "(sin sugerencias)"
-
-#: gtkspellcheck/spellcheck.py:489 gtkspellcheck/spellcheck.py:492
-msgid "Add \"{}\" to Dictionary"
-msgstr "Agregar \"{}\" al Diccionario"
-
-#: gtkspellcheck/spellcheck.py:496 gtkspellcheck/spellcheck.py:498
-msgid "Ignore All"
-msgstr "Ignorar Todos"
-
-#: gtkspellcheck/spellcheck.py:513 gtkspellcheck/spellcheck.py:515
-msgid "Languages"
-msgstr "Idiomas"
-
-#: gtkspellcheck/spellcheck.py:527 gtkspellcheck/spellcheck.py:530
-msgid "Suggestions"
-msgstr "Sugerencias"
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..c3e87f4
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,46 @@
+[tool.poetry]
+name = "pygtkspellcheck"
+version = "5.0.1"
+description = "A simple but quite powerful spellchecking library for GTK written in pure Python."
+authors = ["Maximilian Köhl <mail@koehlma.de>"]
+license = "GPL-3.0-or-later"
+readme = "README.md"
+repository = "https://github.com/koehlma/pygtkspellcheck.git"
+homepage = "https://github.com/koehlma/pygtkspellcheck"
+classifiers = [
+ "Development Status :: 5 - Production/Stable",
+ "Environment :: X11 Applications :: Gnome",
+ "Environment :: X11 Applications :: GTK",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
+ "Operating System :: MacOS",
+ "Operating System :: Microsoft :: Windows",
+ "Operating System :: POSIX",
+ "Programming Language :: Python :: 3",
+ "Topic :: Software Development :: Localization"
+]
+packages = [
+ { include = "gtkspellcheck", from = "src" }
+]
+
+[tool.poetry.dependencies]
+python = "^3.7"
+pyenchant = "^3.0"
+PyGObject = "^3.42.1"
+sphinx = { version = "^4.5.0", optional = true }
+myst-parser = { version = "^0.18.0", optional = true }
+
+[tool.poetry.dev-dependencies]
+black = "^22.3.0"
+flake8 = "*"
+flake8-bugbear = "*"
+pep8-naming = "*"
+mypy = "*"
+sphinx-rtd-theme = "^1.0.0"
+
+[tool.poetry.extras]
+docs = ["sphinx", "myst-parser"]
+
+[build-system]
+requires = ["poetry_core>=1.0.0"]
+build-backend = "poetry.core.masonry.api"
\ No newline at end of file
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 861a9f5..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[egg_info]
-tag_build =
-tag_date = 0
-tag_svn_revision = 0
-
diff --git a/setup.py b/setup.py
index d7eecc6..6840681 100644
--- a/setup.py
+++ b/setup.py
@@ -1,110 +1,38 @@
-# -*- coding:utf-8 -*-
-#
-# Copyright (C) 2012, Maximilian Köhl <linuxmaxi@googlemail.com>
-# Copyright (C) 2012, Carlos Jenkins <carlos@jenkins.co.cr>
-#
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-from __future__ import print_function
-
-import distutils.cmd
-import distutils.command.install
-import distutils.command.install_data
-import os
-import sys
-
-try:
- from setuptools import setup
-except ImportError:
- from distutils.core import setup
-
-commands = {}
-try:
- from sphinx.setup_command import BuildDoc
- commands['build_sphinx'] = BuildDoc
-except ImportError:
- print('build_sphinx command is unavailable, please install Sphinx to solve this')
-
-__path__ = os.path.dirname(__file__)
-
-sys.path.insert(0, os.path.join(__path__, 'src'))
-
-sys.modules['gtk'] = None
-import gtkspellcheck
-
-if len(sys.argv) > 1 and sys.argv[1] == 'register':
- with open(os.path.join(__path__, 'doc', 'pypi', 'page.rst'), 'rb') as _pypi:
- gtkspellcheck.__desc_long__ = _pypi.read().decode('utf-8')
- print('pypi registration: override `long_description`')
-
-class InstallLocale(distutils.command.install_data.install_data):
- def run(self):
- locale_name = 'py{}gtkspellcheck.mo'.format(sys.version_info.major)
- base = os.path.join(self.install_dir, 'share', 'locale')
- self.mkpath(base)
- for lang in os.listdir(os.path.join(__path__, 'locale')):
- path = os.path.join(base, lang, 'LC_MESSAGES')
- self.mkpath(path)
- self.copy_file(os.path.join(__path__, 'locale', lang,
- 'pygtkspellcheck.mo'),
- os.path.join(path, locale_name))
-
-commands['install_locale'] = InstallLocale
-distutils.command.install.install.sub_commands.append(('install_locale',
- lambda self: True))
-
-data_files = []
-if len(sys.argv) > 1 and sys.argv[1] == 'bdist_wininst':
- windows_locale = os.path.join('dist', 'windows', 'locale')
- for lang in os.listdir(windows_locale):
- data_files.append((os.path.join('share', 'locale', lang, 'LC_MESSAGES'),
- [os.path.join(windows_locale, lang, 'LC_MESSAGES', message_file)
- for message_file in os.listdir(os.path.join(windows_locale, lang, 'LC_MESSAGES'))
- if message_file.endswith('.mo')]))
- print('windows bdist_wininst include iso message files')
-
-py_modules = []
-gtkspell = os.getenv('GTKSPELL')
-if sys.version_info.major == 2 and gtkspell is not None and gtkspell.lower() == 'true':
- py_modules.append('gtkspell')
-
-setup(name=gtkspellcheck.__short_name__,
- version=gtkspellcheck.__version__,
- description=gtkspellcheck.__desc_short__,
- long_description=gtkspellcheck.__desc_long__,
- author=gtkspellcheck.__authors__,
- author_email=gtkspellcheck.__emails__,
- url=gtkspellcheck.__website__,
- download_url=gtkspellcheck.__download_url__,
- license='GPLv3+',
- py_modules=py_modules,
- packages=['gtkspellcheck', 'pylocales'],
- package_dir={'': 'src'},
- package_data={'pylocales' : ['locales.db']},
- data_files=data_files,
- install_requires=['pyenchant'],
- extras_require={
- 'building the documentation': ['sphinx']
- },
- classifiers=['Development Status :: 5 - Production/Stable',
- 'Environment :: X11 Applications :: Gnome',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
- 'Operating System :: MacOS :: MacOS X',
- 'Operating System :: Microsoft :: Windows',
- 'Operating System :: POSIX',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 3',
- 'Topic :: Software Development :: Localization'],
- cmdclass=commands)
+# -*- coding: utf-8 -*-
+from setuptools import setup
+
+package_dir = \
+{'': 'src'}
+
+packages = \
+['gtkspellcheck', 'gtkspellcheck._pylocales']
+
+package_data = \
+{'': ['*']}
+
+install_requires = \
+['PyGObject>=3.42.1,<4.0.0', 'pyenchant>=3.0,<4.0']
+
+extras_require = \
+{'docs': ['sphinx>=4.5.0,<5.0.0', 'myst-parser>=0.18.0,<0.19.0']}
+
+setup_kwargs = {
+ 'name': 'pygtkspellcheck',
+ 'version': '5.0.1',
+ 'description': 'A simple but quite powerful spellchecking library for GTK written in pure Python.',
+ 'long_description': '# Python GTK Spellcheck\n\n[![PyPi Project Page](https://img.shields.io/pypi/v/pygtkspellcheck.svg?&label=latest%20version)](https://pypi.python.org/pypi/pygtkspellcheck)\n[![Documentation](https://readthedocs.org/projects/pygtkspellcheck/badge/?version=latest)](https://pygtkspellcheck.readthedocs.org/en/latest/)\n\nPython GTK Spellcheck is a simple but quite powerful spellchecking library for GTK written in pure Python. It\'s spellchecking component is based on [Enchant](http://www.abisource.com/projects/enchant/) and it supports both GTK 3 and 4 via [PyGObject](https://live.gnome.org/PyGObject/).\n\n**⚡️ News:** Thanks to [@cheywood](https://github.com/cheywood), Python GTK Spellcheck now supports GTK 4! 🎉\n\n**🟢 Status:** This project is mature, actively maintained, and open to contributions and co-maintainership.\n\n\n## ✨ Features\n\n- **spellchecking** based on [Enchant](http://www.abisource.com/projects/enchant/) for `GtkTextView`\n- support for word, line, and multiline **ignore regular expressions**\n- support for both **GTK 3 and 4** via [PyGObject](https://live.gnome.org/PyGObject/) for Python 3\n- configurable extra word characters such as `\'`\n- localized names of the available languages based on [ISO-Codes](http://pkg-isocodes.alioth.debian.org/)\n- support for custom ignore tags and hot swap of `GtkTextBuffer`\n- support for Hunspell (LibreOffice) and Aspell (GNU) dictionaries\n\n<p align="center">\n <img src="https://raw.githubusercontent.com/koehlma/pygtkspellcheck/master/docs/screenshots/screenshot.png" alt="Screenshot" />\n</p>\n\n\n## 🚀 Getting Started\n\nPython GTK Spellcheck is available from the [Python Package Index](https://pypi.python.org/pypi/pygtkspellcheck):\n```sh\npip install pygtkspellcheck\n```\nDepending on your distribution, you may also find Python GTK Spellcheck in your package manager.\nFor instance, on Debian you may want to install the [`python3-gtkspellcheck`](https://packages.debian.org/bullseye/python3-gtkspellcheck) package.\n\n\n## 🥳 Showcase\n\nOver time, several projects have used Python GTK Spellcheck or are still using it. Among those are:\n\n- [Nested Editor](http://nestededitor.sourceforge.net/about.html): “Specialized editor for structured documents.”\n- [Cherry Tree](http://www.giuspen.com/cherrytree/): “A hierarchical note taking application, […].”\n- [Zim](http://zim-wiki.org/): “Zim is a graphical text editor used to maintain a collection of wiki pages.”\n- [REMARKABLE](http://remarkableapp.github.io/): “The best markdown editor for Linux and Windows.”\n- [RedNotebook](http://rednotebook.sourceforge.net/): “RedNotebook is a modern journal.”\n- [Reportbug](https://packages.debian.org/stretch/reportbug): “Reports bugs in the Debian distribution.”\n- [UberWriter](http://uberwriter.wolfvollprecht.de/): “UberWriter is a writing application for markdown.”\n- [Gourmet](https://github.com/thinkle/gourmet): “Gourmet Recipe Manager is a manager, editor, and organizer for recipes.“\n\n\n## 🔖 Versions\n\nVersion numbers follow [Semantic Versioning](http://semver.org/). However, the update from 3 to 4 pertains only API incompatible changes in `oxt_extract` and not the spellchecking component. The update from 4 to 5 removed support for Python 2, GTK 2, `pylocales`, and the `oxt_extract` API. Otherwise, the API is still compatible with version 3.\n\n\n## 📚 Documentation\n\nThe documentation is available at [Read the Docs](http://pygtkspellcheck.readthedocs.org/).\n\n\n## 🏗 Contributing\n\nWe welcome all kinds of contributions! ❤️\n\nFor minor changes and bug fixes feel free to simply open a pull request. For major changes impacting the overall design of Python GTK Spellcheck, please first [start a discussion](https://github.com/koehlma/pygtkspellcheck/discussions/new?category=ideas) outlining your idea.\n\nBy submitting a PR, you agree to license your contributions under “GPLv3 or later”.\n',
+ 'author': 'Maximilian Köhl',
+ 'author_email': 'mail@koehlma.de',
+ 'maintainer': None,
+ 'maintainer_email': None,
+ 'url': 'https://github.com/koehlma/pygtkspellcheck',
+ 'package_dir': package_dir,
+ 'packages': packages,
+ 'package_data': package_data,
+ 'install_requires': install_requires,
+ 'extras_require': extras_require,
+ 'python_requires': '>=3.7,<4.0',
+}
+
+
+setup(**setup_kwargs)
diff --git a/src/gtkspellcheck/__init__.py b/src/gtkspellcheck/__init__.py
index 3b77d17..9624946 100644
--- a/src/gtkspellcheck/__init__.py
+++ b/src/gtkspellcheck/__init__.py
@@ -18,36 +18,43 @@
from __future__ import unicode_literals
-__version__ = '4.0.5'
-__project__ = 'Python GTK Spellcheck'
-__short_name__ = 'pygtkspellcheck'
-__authors__ = 'Maximilian Köhl & Carlos Jenkins'
-__emails__ = 'linuxmaxi@googlemail.com & carlos@jenkins.co.cr'
-__website__ = 'http://koehlma.github.com/projects/pygtkspellcheck.html'
-__download_url__ = 'https://github.com/koehlma/pygtkspellcheck/tarball/master'
-__source__ = 'https://github.com/koehlma/pygtkspellcheck/'
-__vcs__ = 'git://github.com/koehlma/pygtkspellcheck.git'
-__copyright__ = '2012, Maximilian Köhl & Carlos Jenkins'
-__desc_short__ = ('a simple but quite powerful Python spell checking library '
- 'for GtkTextViews based on Enchant')
-__desc_long__ = ('A simple but quite powerful spellchecking library written in '
- 'pure Python for Gtk based on Enchant. It supports PyGObject '
- 'as well as PyGtk for Python 2 and 3 with automatic switching '
- 'and binding detection. For automatic translation of the user '
- 'interface it can use Gedit’s translation files.')
+__version__ = "4.0.5"
+__project__ = "Python GTK Spellcheck"
+__short_name__ = "pygtkspellcheck"
+__authors__ = "The Python GTK Spellcheck Authors"
+__emails__ = "linuxmaxi@googlemail.com & carlos@jenkins.co.cr"
+__website__ = "http://koehlma.github.com/projects/pygtkspellcheck.html"
+__download_url__ = "https://github.com/koehlma/pygtkspellcheck/tarball/master"
+__source__ = "https://github.com/koehlma/pygtkspellcheck/"
+__vcs__ = "git://github.com/koehlma/pygtkspellcheck.git"
+__copyright__ = "2012-2022, The Python GTK Spellcheck Authors"
+__desc_short__ = """
+A Python spell-checking library for GtkTextViews based on Enchant
+"""
+__desc_long__ = """
+A simple but quite powerful spellchecking library written in pure Python for
+Gtk based on Enchant. It supports PyGObject as well as PyGtk for Python 2 and
+3 with automatic switching and binding detection. For automatic translation of
+the user interface it can use Gedit’s translation files.
+"""
+__metadata__ = {
+ "__version__": __version__,
+ "__project__": __project__,
+ "__short_name__": __short_name__,
+ "__authors__": __authors__,
+ "__emails__": __emails__,
+ "__website__": __website__,
+ "__download_url__": __download_url__,
+ "__source__": __source__,
+ "__vcs__": __vcs__,
+ "__copyright__": __copyright__,
+ "__desc_short__": __desc_short__,
+ "__desc_long__": __desc_long__,
+}
-__metadata__ = {'__version__' : __version__,
- '__project__' : __project__,
- '__short_name__' : __short_name__,
- '__authors__' : __authors__,
- '__emails__' : __emails__,
- '__website__' : __website__,
- '__download_url__' : __download_url__,
- '__source__' : __source__,
- '__vcs__' : __vcs__,
- '__copyright__' : __copyright__,
- '__desc_short__' : __desc_short__,
- '__desc_long__' : __desc_long__}
+from gtkspellcheck.spellcheck import (
+ SpellChecker,
+ NoDictionariesFound,
+)
-from gtkspellcheck.spellcheck import (SpellChecker, NoDictionariesFound,
- NoGtkBindingFound)
+__all__ = ["SpellChecker", "NoDictionariesFound"]
diff --git a/src/gtkspellcheck/oxt_extract.py b/src/gtkspellcheck/_oxt_extract.py
similarity index 59%
rename from src/gtkspellcheck/oxt_extract.py
rename to src/gtkspellcheck/_oxt_extract.py
index ce1c45a..9661918 100644
--- a/src/gtkspellcheck/oxt_extract.py
+++ b/src/gtkspellcheck/_oxt_extract.py
@@ -17,7 +17,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
-This module extracts the .dic and .aff (Hunspell) dictionaries from any given
+This module extracts the .dic and .aff (Hunspell) dictionaries from any given
.oxt extension.
Extensions could be found at:
@@ -37,30 +37,40 @@ import xml.parsers.expat
import zipfile
# enable deprecation warnings
-warnings.simplefilter('always', DeprecationWarning)
+warnings.simplefilter("always", DeprecationWarning)
# public objects
-__all__ = ['extract_oxt', 'batch_extract', 'BadXml', 'BadExtensionFile',
- 'ExtractPathIsNoDirectory', 'BATCH_SUCCESS', 'BATCH_ERROR',
- 'BATCH_WARNING']
+__all__ = [
+ "extract",
+ "batch_extract",
+ "BadXml",
+ "BadExtensionFile",
+ "ExtractPathIsNoDirectory",
+ "BATCH_SUCCESS",
+ "BATCH_ERROR",
+ "BATCH_WARNING",
+]
# logger
logger = logging.getLogger(__name__)
# translation
-locale_name = 'py{}gtkspellcheck'.format(sys.version_info.major)
+locale_name = "py{}gtkspellcheck".format(sys.version_info.major)
_ = gettext.translation(locale_name, fallback=True).gettext
+
class BadXml(Exception):
"""
The XML dictionary registry is not valid XML.
"""
-
+
+
class BadExtensionFile(Exception):
"""
The extension has a wrong file format, should be a ZIP file.
"""
+
class ExtractPathIsNoDirectory(Exception):
"""
The given `extract_path` is no directory.
@@ -69,44 +79,47 @@ class ExtractPathIsNoDirectory(Exception):
def find_dictionaries(registry):
def oor_name(name, element):
- return element.attributes['oor:name'].value.lower() == name
-
+ return element.attributes["oor:name"].value.lower() == name
+
def get_property(name, properties):
- property = list(filter(functools.partial(oor_name, name),
- properties))
+ property = list(filter(functools.partial(oor_name, name), properties))
if property:
- return property[0].getElementsByTagName('value')[0]
-
+ return property[0].getElementsByTagName("value")[0]
+
result = []
-
+
# find all "node" elements which have "dictionaries" as "oor:name" attribute
- for dictionaries in filter(functools.partial(oor_name, 'dictionaries'),
- registry.getElementsByTagName('node')):
+ for dictionaries in filter(
+ functools.partial(oor_name, "dictionaries"),
+ registry.getElementsByTagName("node"),
+ ):
# for all "node" elements in this dictionary nodes
- for dictionary in dictionaries.getElementsByTagName('node'):
+ for dictionary in dictionaries.getElementsByTagName("node"):
# get all "prop" elements
- properties = dictionary.getElementsByTagName('prop')
+ properties = dictionary.getElementsByTagName("prop")
# get the format property as text
- format = get_property('format', properties).firstChild.data.strip()
- if format and format == 'DICT_SPELL':
+ format = get_property("format", properties).firstChild.data.strip()
+ if format and format == "DICT_SPELL":
# find the locations property
- locations = get_property('locations', properties)
+ locations = get_property("locations", properties)
# if the location property is text:
# %origin%/dictionary.aff %origin%/dictionary.dic
if locations.firstChild.nodeType == xml.dom.Node.TEXT_NODE:
locations = locations.firstChild.data
- locations = locations.replace('%origin%/', '').strip()
+ locations = locations.replace("%origin%/", "").strip()
result.append(locations.split())
# otherwise:
# <i>%origin%/dictionary.aff</i> <i>%origin%/dictionary.dic</i>
else:
- locations = [item.firshChild.data.replace('%origin%/', '') \
- .strip() for item in
- locations.getElementsByTagName('it')]
+ locations = [
+ item.firshChild.data.replace("%origin%/", "").strip()
+ for item in locations.getElementsByTagName("it")
+ ]
result.append(locations)
-
+
return result
+
def extract(filename, target, override=False):
"""
Extract Hunspell dictionaries out of LibreOffice ``.oxt`` extensions.
@@ -124,56 +137,67 @@ def extract(filename, target, override=False):
http://extensions.services.openoffice.org/dictionary
"""
# TODO 5.0: remove this function
- warnings.warn(('call to deprecated function "{}", '
- 'moved to separate package "oxt_extract", '
- 'will be removed in pygtkspellcheck 5.0').format(extract.__name__),
- category=DeprecationWarning)
+ warnings.warn(
+ (
+ 'call to deprecated function "{}", '
+ 'moved to separate package "oxt_extract", '
+ "will be removed in pygtkspellcheck 5.0"
+ ).format(extract.__name__),
+ category=DeprecationWarning,
+ )
try:
- with zipfile.ZipFile(filename, 'r') as extension:
+ with zipfile.ZipFile(filename, "r") as extension:
files = extension.namelist()
-
- registry = 'dictionaries.xcu'
- if not registry in files:
+
+ registry = "dictionaries.xcu"
+ if registry not in files:
for filename in files:
if filename.lower().endswith(registry):
registry = filename
-
+
if registry in files:
registry = xml.dom.minidom.parse(extension.open(registry))
dictionaries = find_dictionaries(registry)
extracted = []
for dictionary in dictionaries:
for filename in dictionary:
- dict_file = os.path.join(target,
- os.path.basename(filename))
- if (not os.path.exists(dict_file)
- or (override and os.path.isfile(dict_file))):
+ dict_file = os.path.join(target, os.path.basename(filename))
+ if not os.path.exists(dict_file) or (
+ override and os.path.isfile(dict_file)
+ ):
if filename in files:
- with open(dict_file, 'wb') as _target:
- with extension.open(filename, 'r') as _source:
+ with open(dict_file, "wb") as _target:
+ with extension.open(filename, "r") as _source:
extracted.append(os.path.basename(filename))
_target.write(_source.read())
else:
- logger.warning('dictionary exists in registry '
- 'but not in the extension zip')
+ logger.warning(
+ "dictionary exists in registry "
+ "but not in the extension zip"
+ )
else:
- logging.warning(('dictionary file "{}" already exists '
- 'and not overriding it'
- ).format(dict_file))
+ logging.warning(
+ (
+ 'dictionary file "{}" already exists '
+ "and not overriding it"
+ ).format(dict_file)
+ )
return extracted
except zipfile.BadZipfile:
- raise BadExtensionFile('extension is not a valid ZIP file')
+ raise BadExtensionFile("extension is not a valid ZIP file")
except xml.parsers.expat.ExpatError:
- raise BadXml('dictionary registry is not valid XML')
+ raise BadXml("dictionary registry is not valid XML")
+
+
+BATCH_SUCCESS = "success"
+BATCH_ERROR = "error"
+BATCH_WARNING = "warning"
-BATCH_SUCCESS = 'success'
-BATCH_ERROR = 'error'
-BATCH_WARNING = 'warning'
def batch_extract(oxt_path, extract_path, override=False, move_path=None):
"""
Uncompress, read and install LibreOffice ``.oxt`` dictionaries extensions.
-
+
:param oxt_path: path to a directory containing the ``.oxt`` extensions
:param extract_path: path to extract Hunspell dictionaries files to
:param override: override already existing files
@@ -183,30 +207,30 @@ def batch_extract(oxt_path, extract_path, override=False, move_path=None):
would be :const:`BATCH_SUCCESS` for success, :const:`BATCH_ERROR` if
some error happened or :const:`BATCH_WARNING` which contain some warning
messages instead of errors
-
+
This function extracts the Hunspell dictionaries (``.dic`` and ``.aff``
files) from all the ``.oxt`` extensions found on ``oxt_path`` directory to
the ``extract_path`` directory.
-
+
Extensions could be found at:
-
+
http://extensions.services.openoffice.org/dictionary
-
+
In detail, this functions does the following:
-
+
1. find all the ``.oxt`` extension files within ``oxt_path``
2. open (unzip) each extension
3. find the dictionary definition file within (*dictionaries.xcu*)
4. parse the dictionary definition file and locate the dictionaries files
5. uncompress those files to ``extract_path``
-
-
+
+
By default file overriding is disabled, set ``override`` parameter to True
if you want to enable it. As additional option, each processed extension can
be moved to ``move_path``.
-
+
Example::
-
+
for result, name, error, dictionaries, message in oxt_extract.batch_extract(...):
if result == oxt_extract.BATCH_SUCCESS:
print('successfully extracted extension "{}"'.format(name))
@@ -218,53 +242,74 @@ def batch_extract(oxt_path, extract_path, override=False, move_path=None):
print('warning during processing extension "{}"'.format(name))
print(message)
print(error)
-
+
"""
# TODO 5.0: remove this function
- warnings.warn(('call to deprecated function "{}", '
- 'moved to separate package "oxt_extract", '
- 'will be removed in pygtkspellcheck 5.0').format(extract.__name__),
- category=DeprecationWarning)
+ warnings.warn(
+ (
+ 'call to deprecated function "{}", '
+ 'moved to separate package "oxt_extract", '
+ "will be removed in pygtkspellcheck 5.0"
+ ).format(extract.__name__),
+ category=DeprecationWarning,
+ )
# get the real, absolute and normalized path
oxt_path = os.path.normpath(os.path.abspath(os.path.realpath(oxt_path)))
-
+
# check that the input directory exists
if not os.path.isdir(oxt_path):
return
-
+
# create extract directory if not exists
if not os.path.exists(extract_path):
os.makedirs(extract_path)
# check that the extract path is a directory
if not os.path.isdir(extract_path):
- raise ExtractPathIsNoDirectory('extract path is not a valid directory')
-
+ raise ExtractPathIsNoDirectory("extract path is not a valid directory")
+
# get all .oxt extension at given path
- oxt_files = [extension for extension in os.listdir(oxt_path)
- if extension.lower().endswith('.oxt')]
-
+ oxt_files = [
+ extension
+ for extension in os.listdir(oxt_path)
+ if extension.lower().endswith(".oxt")
+ ]
+
for extension_name in oxt_files:
extension_path = os.path.join(oxt_path, extension_name)
-
+
try:
dictionaries = extract(extension_path, extract_path, override)
- yield BATCH_SUCCESS, extension_name, None, dictionaries, ''
+ yield BATCH_SUCCESS, extension_name, None, dictionaries, ""
except BadExtensionFile as error:
- logger.error(('extension "{}" is not a valid ZIP file'
- ).format(extension_name))
- yield (BATCH_ERROR, extension_name, error, [],
- _('extension "{}" is not a valid ZIP file'
- ).format(extension_name))
+ logger.error(
+ ('extension "{}" is not a valid ZIP file').format(extension_name)
+ )
+ yield (
+ BATCH_ERROR,
+ extension_name,
+ error,
+ [],
+ _('extension "{}" is not a valid ZIP file').format(extension_name),
+ )
except BadXml as error:
- logger.error(('extension "{}" has no valid XML dictionary registry'
- ).format(extension_name))
- yield (BATCH_ERROR, extension_name, error, [],
- _('extension "{}" has no valid XML dictionary registry'
- ).format(extension_name))
-
+ logger.error(
+ ('extension "{}" has no valid XML dictionary registry').format(
+ extension_name
+ )
+ )
+ yield (
+ BATCH_ERROR,
+ extension_name,
+ error,
+ [],
+ _('extension "{}" has no valid XML dictionary registry').format(
+ extension_name
+ ),
+ )
+
# move the extension after processing if user requires it
if move_path is not None:
# create move path if it doesn't exists
@@ -273,22 +318,39 @@ def batch_extract(oxt_path, extract_path, override=False, move_path=None):
# move to the given path only if it is a directory and target
# doesn't exists
if os.path.isdir(move_path):
- if (not os.path.exists(os.path.join(move_path, extension_name))
- or override):
+ if (
+ not os.path.exists(os.path.join(move_path, extension_name))
+ or override
+ ):
shutil.move(extension_path, move_path)
else:
- logger.warning(('unable to move extension, file with same '
- 'name exists within move_path'))
- yield (BATCH_WARNING, extension_name,
- ('unable to move extension, file with same name '
- 'exists within move_path'), [],
- _('unable to move extension, file with same name '
- 'exists within move_path'))
+ logger.warning(
+ (
+ "unable to move extension, file with same "
+ "name exists within move_path"
+ )
+ )
+ yield (
+ BATCH_WARNING,
+ extension_name,
+ (
+ "unable to move extension, file with same name "
+ "exists within move_path"
+ ),
+ [],
+ _(
+ "unable to move extension, file with same name "
+ "exists within move_path"
+ ),
+ )
else:
- logger.warning(('unable to move extension, move_path is not a '
- 'directory'))
- yield (BATCH_WARNING, extension_name,
- ('unable to move extension, move_path is not a '
- 'directory'), [],
- _('unable to move extension, move_path is not a '
- 'directory'))
\ No newline at end of file
+ logger.warning(
+ ("unable to move extension, move_path is not a " "directory")
+ )
+ yield (
+ BATCH_WARNING,
+ extension_name,
+ ("unable to move extension, move_path is not a " "directory"),
+ [],
+ _("unable to move extension, move_path is not a " "directory"),
+ )
diff --git a/src/gtkspellcheck/_pylocales/__init__.py b/src/gtkspellcheck/_pylocales/__init__.py
new file mode 100644
index 0000000..16fcb44
--- /dev/null
+++ b/src/gtkspellcheck/_pylocales/__init__.py
@@ -0,0 +1,60 @@
+# -*- coding:utf-8 -*-
+#
+# Copyright (C) 2012, Maximilian Köhl <linuxmaxi@googlemail.com>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+from __future__ import unicode_literals
+
+__version__ = "1.2"
+__project__ = "Python Locales"
+__short_name__ = "pylocales"
+__authors__ = "Maximilian Köhl"
+__emails__ = "linuxmaxi@googlemail.com"
+__website__ = "http://koehlma.github.com/projects/pygtkspellcheck.html"
+__source__ = "https://github.com/koehlma/pygtkspellcheck/"
+__vcs__ = "git://github.com/koehlma/pygtkspellcheck.git"
+__copyright__ = "2012, Maximilian Köhl"
+__desc_short__ = "query the ISO 639/3166 database about a country or a language."
+__desc_long__ = (
+ "Query the ISO 639/3166 database about a country or a"
+ "language. The locales database contains ISO 639 language"
+ "definitions and ISO 3166 country definitions. This package"
+ "provides translation for country and language names if"
+ "the iso-code messages are installed on your system."
+)
+
+__metadata__ = {
+ "__version__": __version__,
+ "__project__": __project__,
+ "__short_name__": __short_name__,
+ "__authors__": __authors__,
+ "__emails__": __emails__,
+ "__website__": __website__,
+ "__source__": __source__,
+ "__vcs__": __vcs__,
+ "__copyright__": __copyright__,
+ "__desc_short__": __desc_short__,
+ "__desc_long__": __desc_long__,
+}
+
+from .locales import (
+ Country,
+ Language,
+ LanguageNotFound,
+ CountryNotFound,
+ code_to_name,
+)
+
+__all__ = ["Country", "Language", "LanguageNotFound", "CountryNotFound", "code_to_name"]
diff --git a/src/pylocales/locales.db b/src/gtkspellcheck/_pylocales/locales.db
similarity index 100%
rename from src/pylocales/locales.db
rename to src/gtkspellcheck/_pylocales/locales.db
diff --git a/src/pylocales/locales.py b/src/gtkspellcheck/_pylocales/locales.py
similarity index 67%
rename from src/pylocales/locales.py
rename to src/gtkspellcheck/_pylocales/locales.py
index 9d4f10f..07749fc 100644
--- a/src/pylocales/locales.py
+++ b/src/gtkspellcheck/_pylocales/locales.py
@@ -30,119 +30,124 @@ import sqlite3
import sys
# public objects
-__all__ = ['Country', 'Language', 'LanguageNotFound',
- 'CountryNotFound', 'code_to_name']
+__all__ = ["Country", "Language", "LanguageNotFound", "CountryNotFound", "code_to_name"]
# translation
-_translator_language = gettext.translation('iso_639', fallback=True).gettext
-_translator_country = gettext.translation('iso_3166', fallback=True).gettext
+_translator_language = gettext.translation("iso_639", fallback=True).gettext
+_translator_country = gettext.translation("iso_3166", fallback=True).gettext
# Decides where the database is located. If an application provides an
# os.path.get_module_path monkey patch to determine the path where the module
# is located it uses this. If not it searches in the directory of this source
# code file.
__path__ = None
-if hasattr(os.path, 'get_module_path'):
+if hasattr(os.path, "get_module_path"):
__path__ = os.path.get_module_path(__file__)
- if not os.path.isfile(os.path.join(__path__, 'locales.db')):
+ if not os.path.isfile(os.path.join(__path__, "locales.db")):
__path__ = None
if __path__ is None:
- frozen = getattr(sys, 'frozen', None)
- if frozen in ('dll', 'console_exe', 'windows_exe'):
+ frozen = getattr(sys, "frozen", None)
+ if frozen in ("dll", "console_exe", "windows_exe"):
__path__ = os.path.abspath(os.path.dirname(sys.executable))
- elif frozen == 'macosx_app':
- __path__ = os.path.abspath(os.environ['RESOURCEPATH'])
+ elif frozen == "macosx_app":
+ __path__ = os.path.abspath(os.environ["RESOURCEPATH"])
elif frozen is True:
# Handle executables produced by PyInstaller.
__path__ = sys._MEIPASS
else:
__path__ = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
-
+
# loading the database
-_database = sqlite3.connect(os.path.join(__path__, 'locales.db'))
+_database = sqlite3.connect(os.path.join(__path__, "locales.db"))
logger = logging.getLogger(__name__)
+
class LanguageNotFound(Exception):
"""
The specified language wasn't found in the database.
"""
-
+
+
class CountryNotFound(Exception):
"""
The specified country wasn't found in the database.
"""
+
class Country(object):
def __init__(self, rowid):
- country = _database.execute('SELECT * FROM countries WHERE rowid == ?',
- (rowid,)).fetchone()
+ country = _database.execute(
+ "SELECT * FROM countries WHERE rowid == ?", (rowid,)
+ ).fetchone()
self.name = country[0]
self.official_name = country[1]
self.alpha_2 = country[2]
self.alpha_3 = country[3]
self.numeric = country[4]
self.translation = _translator_country(self.name)
-
+
@classmethod
def get_country(cls, code, codec):
country = _database.execute(
- 'SELECT rowid FROM countries WHERE %s == ?' % (codec),
- (code,)).fetchone()
+ "SELECT rowid FROM countries WHERE %s == ?" % (codec), (code,)
+ ).fetchone()
if country:
return cls(country[0])
- raise CountryNotFound('code: %s, codec: %s' % (code, codec))
-
+ raise CountryNotFound("code: %s, codec: %s" % (code, codec))
+
@classmethod
def by_alpha_2(cls, code):
- return Country.get_country(code, 'alpha_2')
-
+ return Country.get_country(code, "alpha_2")
+
@classmethod
def by_alpha_3(cls, code):
- return Country.get_country(code, 'alpha_3')
-
+ return Country.get_country(code, "alpha_3")
+
@classmethod
def by_numeric(cls, code):
- return Country.get_country(code, 'numeric')
-
+ return Country.get_country(code, "numeric")
+
+
class Language(object):
def __init__(self, rowid):
- language = _database.execute('SELECT * FROM languages WHERE rowid == ?',
- (rowid,)).fetchone()
+ language = _database.execute(
+ "SELECT * FROM languages WHERE rowid == ?", (rowid,)
+ ).fetchone()
self.name = language[0]
self.iso_639_2B = language[1]
self.iso_639_2T = language[2]
self.iso_639_1 = language[3]
self.translation = _translator_language(self.name)
-
+
@classmethod
def get_language(cls, code, codec):
language = _database.execute(
- 'SELECT rowid FROM languages WHERE %s == ?' % (codec),
- (code,)).fetchone()
+ "SELECT rowid FROM languages WHERE %s == ?" % (codec), (code,)
+ ).fetchone()
if language:
return cls(language[0])
- raise LanguageNotFound('code: %s, codec: %s' % (code, codec))
-
+ raise LanguageNotFound("code: %s, codec: %s" % (code, codec))
+
@classmethod
- def by_iso_639_2B(cls, code):
- return Language.get_language(code, 'iso_639_2B')
-
+ def by_iso_639_2b(cls, code):
+ return Language.get_language(code, "iso_639_2B")
+
@classmethod
- def by_iso_639_2T(cls, code):
- return Language.get_language(code, 'iso_639_2T')
-
+ def by_iso_639_2t(cls, code):
+ return Language.get_language(code, "iso_639_2T")
+
@classmethod
def by_iso_639_1(cls, code):
- return Language.get_language(code, 'iso_639_1')
+ return Language.get_language(code, "iso_639_1")
-def code_to_name(code, separator='_'):
- """
+def code_to_name(code, separator="_"):
+ """
Get the human readable and translated name of a language based on it's code.
-
- :param code: the code of the language (e.g. de_DE, en_US)
+
+ :param code: the code of the language (e.g. de_DE, en_US)
:param target: separator used to separate language from country
:rtype: human readable and translated language name
"""
@@ -151,6 +156,6 @@ def code_to_name(code, separator='_'):
if len(code) > 1:
lang = Language.by_iso_639_1(code[0]).translation
country = Country.by_alpha_2(code[1]).translation
- return '{} ({})'.format(lang, country)
+ return "{} ({})".format(lang, country)
else:
return Language.by_iso_639_1(code[0]).translation
diff --git a/src/gtkspellcheck/spellcheck.py b/src/gtkspellcheck/spellcheck.py
index ca1e4f8..1bf9a28 100644
--- a/src/gtkspellcheck/spellcheck.py
+++ b/src/gtkspellcheck/spellcheck.py
@@ -18,9 +18,8 @@
"""
A simple but quite powerful spellchecking library written in pure Python for Gtk
-based on Enchant. It supports PyGObject as well as PyGtk for Python 2 and 3 with
-automatic switching and binding detection. For automatic translation of the user
-interface it can use Gedit’s translation files.
+based on Enchant. It supports both GTK 3 and 4 via PyGObject with Python 3. For
+automatic translation of the user interface it can use Gedit’s translation files.
"""
import enchant
@@ -28,83 +27,71 @@ import gettext
import logging
import re
import sys
+from collections import UserList
-from pylocales import code_to_name as _code_to_name
-from pylocales import LanguageNotFound, CountryNotFound
+from ._pylocales import code_to_name as _code_to_name
+from ._pylocales import LanguageNotFound, CountryNotFound
+
+from gi.repository import Gio, GLib, GObject
+
+# find any loaded gtk binding
+if "gi.repository.Gtk" in sys.modules:
+ Gtk = sys.modules["gi.repository.Gtk"]
+else:
+ import gi
+
+ gi.require_version("Gtk", "3.0")
+ from gi.repository import Gtk # noqa: N813
+
+_IS_GTK3 = Gtk.MAJOR_VERSION < 4
# public objects
-__all__ = ['SpellChecker', 'NoDictionariesFound', 'NoGtkBindingFound']
+__all__ = ["SpellChecker", "NoDictionariesFound"]
# logger
logger = logging.getLogger(__name__)
+
class NoDictionariesFound(Exception):
"""
There aren't any dictionaries installed on the current system so
spellchecking could not work in any way.
"""
-class NoGtkBindingFound(Exception):
- """
- Could not find any loaded Gtk binding.
- """
-
-if sys.version_info.major == 3:
- _py3k = True
-else:
- _py3k = False
-
-if _py3k:
- # there is only the gi binding for Python 3
- from gi.repository import Gtk as gtk
- _pygobject = True
-else:
- # find any loaded gtk binding
- if 'gi.repository.Gtk' in sys.modules:
- gtk = sys.modules['gi.repository.Gtk']
- _pygobject = True
- elif 'gtk' in sys.modules:
- gtk = sys.modules['gtk']
- _pygobject = False
- else:
- raise NoGtkBindingFound('could not find any loaded Gtk binding')
-
-# select base list class
-try:
- from collections import UserList
- _list = UserList
-except ImportError:
- _list = list
-
-
-
-# select base string
-if _py3k:
- basestring = str
# map between Gedit's translation and PyGtkSpellcheck's
-_GEDIT_MAP = {'Languages' : 'Languages',
- 'Ignore All' : 'Ignore _All',
- 'Suggestions' : 'Suggestions',
- '(no suggestions)' : '(no suggested words)',
- 'Add "{}" to Dictionary' : 'Add w_ord',
- 'Unknown' : 'Unknown'}
+_GEDIT_MAP = {
+ "Languages": "Languages",
+ "Ignore All": "Ignore _All",
+ "Suggestions": "Suggestions",
+ "(no suggestions)": "(no suggested words)",
+ 'Add "{}" to Dictionary': "Add w_ord",
+ "Unknown": "Unknown",
+}
+
+_BATCHING_THRESHOLD_CHARS = 1500
+_BATCH_SIZE_CHARS = 1000
# translation
-if gettext.find('gedit'):
- _gedit = gettext.translation('gedit', fallback=True).gettext
- _ = lambda message: _gedit(_GEDIT_MAP[message]).replace('_', '')
+if gettext.find("gedit"):
+ _gedit = gettext.translation("gedit", fallback=True).gettext
+
+ def _(message):
+ return _gedit(_GEDIT_MAP[message]).replace("_", "")
+
else:
- locale_name = 'py{}gtkspellcheck'.format(sys.version_info.major)
+ locale_name = "py{}gtkspellcheck".format(sys.version_info.major)
_ = gettext.translation(locale_name, fallback=True).gettext
-def code_to_name(code, separator='_'):
+
+def code_to_name(code, separator="_"):
try:
return _code_to_name(code, separator)
except (LanguageNotFound, CountryNotFound):
- return '{} ({})'.format(_('Unknown'), code)
+ return "{} ({})".format(_("Unknown"), code)
+
-class SpellChecker(object):
+class SpellChecker(GObject.Object):
"""
Main spellchecking class, everything important happens here.
@@ -127,38 +114,48 @@ class SpellChecker(object):
:param language: language to check
"""
- FILTER_WORD = 'word'
- FILTER_LINE = 'line'
- FILTER_TEXT = 'text'
- DEFAULT_FILTERS = {FILTER_WORD : [r'[0-9.,]+'],
- FILTER_LINE : [(r'(https?|ftp|file):((//)|(\\\\))+[\w\d:'
- r'#@%/;$()~_?+-=\\.&]+'),
- r'[\w\d]+@[\w\d.]+'],
- FILTER_TEXT : []}
+ FILTER_WORD = "word"
+ FILTER_LINE = "line"
+ FILTER_TEXT = "text"
- class _LanguageList(_list):
+ DEFAULT_FILTERS = {
+ FILTER_WORD: [r"[0-9.,]+"],
+ FILTER_LINE: [
+ (r"(https?|ftp|file):((//)|(\\\\))+[\w\d:" r"#@%/;$()~_?+-=\\.&]+"),
+ r"[\w\d]+@[\w\d.]+",
+ ],
+ FILTER_TEXT: [],
+ }
+
+ DEFAULT_EXTRA_CHARS = "'"
+
+ class _LanguageList(UserList):
def __init__(self, *args, **kwargs):
- if sys.version_info.major == 3:
- super().__init__(*args, **kwargs)
- else:
- _list.__init__(self, *args, **kwargs)
+ super().__init__(*args, **kwargs)
self.mapping = dict(self)
@classmethod
def from_broker(cls, broker):
- return cls(sorted([(language, code_to_name(language))
- for language in broker.list_languages()],
- key=lambda language: language[1]))
+ return cls(
+ sorted(
+ [
+ (language, code_to_name(language))
+ for language in broker.list_languages()
+ ],
+ key=lambda language: language[1],
+ )
+ )
def exists(self, language):
return language in self.mapping
- class _Mark():
- def __init__(self, buffer, name, start):
+ class _Mark:
+ def __init__(self, buffer, name, start, iter_worker):
self._buffer = buffer
self._name = name
self._mark = self._buffer.create_mark(self._name, start, True)
+ self._iter_worker = iter_worker
@property
def iter(self):
@@ -166,63 +163,191 @@ class SpellChecker(object):
@property
def inside_word(self):
- return self.iter.inside_word()
+ return self._iter_worker.inside_word(self.iter)
@property
def word(self):
start = self.iter
- if not start.starts_word():
- start.backward_word_start()
+ if not self._iter_worker.starts_word(start):
+ self._iter_worker.backward_word_start(start)
end = self.iter
- if end.inside_word():
- end.forward_word_end()
+ if self._iter_worker.inside_word(end):
+ self._iter_worker.forward_word_end(end)
return start, end
def move(self, location):
self._buffer.move_mark(self._mark, location)
- def __init__(self, view, language='en', prefix='gtkspellchecker',
- collapse=True, params={}):
+ class _IterWorker:
+ def __init__(self, extra_word_chars):
+ self._extra_word_chars = extra_word_chars
+
+ def is_extra_word_char(self, loc):
+ # Language extra chararacters should also be processed once Enchant's
+ # enchant_dict_get_extra_word_characters is exposed in PyEnchant
+
+ char = loc.get_char()
+ return char != "" and char in self._extra_word_chars
+
+ def inside_word(self, loc):
+ if loc.inside_word():
+ return True
+ elif self.starts_word(loc):
+ return True
+ elif loc.ends_word() and not self.ends_word(loc):
+ return True
+ else:
+ return False
+
+ def starts_word(self, loc):
+ if loc.starts_word():
+ if loc.is_start():
+ return True
+ else:
+ tmp = loc.copy()
+ tmp.backward_char()
+ return not self.is_extra_word_char(tmp)
+ else:
+ return False
+
+ def ends_word(self, loc):
+ if loc.ends_word():
+ if loc.is_end():
+ return True
+ else:
+ tmp = loc.copy()
+ tmp.forward_char()
+ return not self.is_extra_word_char(tmp)
+ else:
+ return False
+
+ def forward_word_end(self, loc):
+ def move_through_extra_chars():
+ moved = False
+ while self.is_extra_word_char(loc):
+ if not loc.forward_char():
+ break
+ moved = True
+ return moved
+
+ tmp = loc.copy()
+ tmp.backward_char()
+ loc.forward_word_end()
+ while move_through_extra_chars():
+ if loc.is_end() or not loc.inside_word() or not loc.forward_word_end():
+ break
+
+ def backward_word_start(self, loc):
+ def move_through_extra_chars():
+ tmp = loc.copy()
+ tmp.backward_char()
+ moved = False
+ while self.is_extra_word_char(tmp):
+ moved = True
+ loc.assign(tmp)
+ if not tmp.backward_char():
+ break
+ return moved
+
+ loc.backward_word_start()
+ while move_through_extra_chars():
+ tmp = loc.copy()
+ tmp.backward_char()
+ if (
+ loc.is_start()
+ or not tmp.inside_word()
+ or not loc.backward_word_start()
+ ):
+ break
+
+ def sync_extra_chars(self, obj, value):
+ self._extra_word_chars = obj.extra_chars
+
+ def __init__(
+ self, view, language="en", prefix="gtkspellchecker", collapse=True, params=None
+ ):
+ super().__init__()
self._view = view
self.collapse = collapse
- self._view.connect('populate-popup',
- lambda entry, menu:self._extend_menu(menu))
- self._view.connect('popup-menu', self._click_move_popup)
- self._view.connect('button-press-event', self._click_move_button)
+ # GTK 3-only signals. GTK 4 uses actions, below.
+ if _IS_GTK3:
+ self._view.connect(
+ "populate-popup", lambda entry, menu: self._extend_menu(menu)
+ )
+ self._view.connect("popup-menu", self._click_move_popup)
+ self._view.connect("button-press-event", self._click_move_button)
self._prefix = prefix
self._broker = enchant.Broker()
- for param, value in params.items(): self._broker.set_param(param, value)
+ if params is not None:
+ for param, value in params.items():
+ self._broker.set_param(param, value)
self.languages = SpellChecker._LanguageList.from_broker(self._broker)
if self.languages.exists(language):
self._language = language
- elif self.languages.exists('en'):
- logger.warning(('no installed dictionary for language "{}", '
- 'fallback to english'.format(language)))
- self._language = 'en'
+ elif self.languages.exists("en"):
+ logger.warning(
+ (
+ 'no installed dictionary for language "{}", '
+ "fallback to english".format(language)
+ )
+ )
+ self._language = "en"
else:
if self.languages:
self._language = self.languages[0][0]
- logger.warning(('no installed dictionary for language "{}" '
- 'and english, fallback to first language in'
- 'language list ("{}")').format(language,
- self._language))
+ logger.warning(
+ (
+ 'no installed dictionary for language "{}" '
+ "and english, fallback to first language in"
+ 'language list ("{}")'
+ ).format(language, self._language)
+ )
else:
- logger.critical('no dictionaries found')
+ logger.critical("no dictionaries found")
raise NoDictionariesFound()
self._dictionary = self._broker.request_dict(self._language)
self._deferred_check = False
self._filters = dict(SpellChecker.DEFAULT_FILTERS)
- self._regexes = {SpellChecker.FILTER_WORD : re.compile('|'.join(
- self._filters[SpellChecker.FILTER_WORD])),
- SpellChecker.FILTER_LINE : re.compile('|'.join(
- self._filters[SpellChecker.FILTER_LINE])),
- SpellChecker.FILTER_TEXT : re.compile('|'.join(
- self._filters[SpellChecker.FILTER_TEXT]),
- re.MULTILINE)}
+ self._regexes = {
+ SpellChecker.FILTER_WORD: re.compile(
+ "|".join(self._filters[SpellChecker.FILTER_WORD])
+ ),
+ SpellChecker.FILTER_LINE: re.compile(
+ "|".join(self._filters[SpellChecker.FILTER_LINE])
+ ),
+ SpellChecker.FILTER_TEXT: re.compile(
+ "|".join(self._filters[SpellChecker.FILTER_TEXT]), re.MULTILINE
+ ),
+ }
+
+ self._extra_chars = SpellChecker.DEFAULT_EXTRA_CHARS
+ self._iter_worker = SpellChecker._IterWorker(self._extra_chars)
+ self.connect("notify::extra-chars", self._iter_worker.sync_extra_chars)
+
+ self._batched_rechecking = False
+
+ self._languages_menu = None
+ # GTK 4-only extra menu population, gesture creation and action setup. GTK 3
+ # uses signals, above.
+ if not _IS_GTK3:
+ extra_menu = self._view.get_extra_menu()
+ if extra_menu is None:
+ extra_menu = Gio.Menu()
+ self._view.set_extra_menu(extra_menu)
+ self._spelling_menu = Gio.Menu()
+ extra_menu.append_section(None, self._spelling_menu)
+
+ controller = Gtk.GestureClick()
+ controller.set_button(0)
+ controller.connect("pressed", self._gtk4_on_textview_click)
+ self._view.add_controller(controller)
+
+ self._gtk4_setup_actions()
+
self._enabled = True
self.buffer_initialize()
- @property
+ @GObject.Property(type=str, default="")
def language(self):
"""
The language used for spellchecking.
@@ -236,7 +361,7 @@ class SpellChecker(object):
self._dictionary = self._broker.request_dict(language)
self.recheck()
- @property
+ @GObject.Property(type=bool, default=False)
def enabled(self):
"""
Enable or disable spellchecking.
@@ -250,48 +375,82 @@ class SpellChecker(object):
elif not enabled and self._enabled:
self.disable()
+ @GObject.Property(type=bool, default=False)
+ def batched_rechecking(self):
+ """
+ Whether to enable batched rechecking of large buffers.
+ """
+ return self._batched_rechecking
+
+ @batched_rechecking.setter
+ def batched_rechecking(self, val):
+ self._batched_rechecking = val
+
+ @GObject.Property(type=str, default=",")
+ def extra_chars(self):
+ """
+ Fetch the list of extra characters beyond which words are extended.
+ """
+ return self._extra_chars
+
+ @extra_chars.setter
+ def extra_chars(self, chars):
+ """
+ Set the list of extra characters beyond which words are extended.
+
+ :param val: String containing list of characters
+ """
+ self._extra_chars = chars
+
def buffer_initialize(self):
"""
Initialize the GtkTextBuffer associated with the GtkTextView. If you
have associated a new GtkTextBuffer with the GtkTextView call this
method.
"""
- if _pygobject:
- self._misspelled = gtk.TextTag.new('{}-misspelled'\
- .format(self._prefix))
- else:
- self._misspelled = gtk.TextTag('{}-misspelled'.format(self._prefix))
- self._misspelled.set_property('underline', 4)
+ self._misspelled = Gtk.TextTag.new("{}-misspelled".format(self._prefix))
+ self._misspelled.set_property("underline", 4)
self._buffer = self._view.get_buffer()
- self._buffer.connect('insert-text', self._before_text_insert)
- self._buffer.connect_after('insert-text', self._after_text_insert)
- self._buffer.connect_after('delete-range', self._range_delete)
- self._buffer.connect_after('mark-set', self._mark_set)
+ self._buffer.connect("insert-text", self._before_text_insert)
+ self._buffer.connect_after("insert-text", self._after_text_insert)
+ self._buffer.connect_after("delete-range", self._range_delete)
+ self._buffer.connect_after("mark-set", self._mark_set)
start = self._buffer.get_bounds()[0]
- self._marks = {'insert-start' : SpellChecker._Mark(self._buffer,
- '{}-insert-start'.format(self._prefix), start),
- 'insert-end' : SpellChecker._Mark(self._buffer,
- '{}-insert-end'.format(self._prefix), start),
- 'click' : SpellChecker._Mark(self._buffer,
- '{}-click'.format(self._prefix), start)}
+ self._marks = {
+ "insert-start": SpellChecker._Mark(
+ self._buffer,
+ "{}-insert-start".format(self._prefix),
+ start,
+ self._iter_worker,
+ ),
+ "insert-end": SpellChecker._Mark(
+ self._buffer,
+ "{}-insert-end".format(self._prefix),
+ start,
+ self._iter_worker,
+ ),
+ "click": SpellChecker._Mark(
+ self._buffer, "{}-click".format(self._prefix), start, self._iter_worker
+ ),
+ }
self._table = self._buffer.get_tag_table()
self._table.add(self._misspelled)
self.ignored_tags = []
+
def tag_added(tag, *args):
- if hasattr(tag, 'spell_check') and not getattr(tag, 'spell_check'):
+ if hasattr(tag, "spell_check") and not tag.spell_check:
self.ignored_tags.append(tag)
+
def tag_removed(tag, *args):
if tag in self.ignored_tags:
self.ignored_tags.remove(tag)
- self._table.connect('tag-added', tag_added)
- self._table.connect('tag-removed', tag_removed)
+
+ self._table.connect("tag-added", tag_added)
+ self._table.connect("tag-removed", tag_removed)
self._table.foreach(tag_added, None)
- self.no_spell_check = self._table.lookup('no-spell-check')
+ self.no_spell_check = self._table.lookup("no-spell-check")
if not self.no_spell_check:
- if _pygobject:
- self.no_spell_check = gtk.TextTag.new('no-spell-check')
- else:
- self.no_spell_check = gtk.TextTag('no-spell-check')
+ self.no_spell_check = Gtk.TextTag.new("no-spell-check")
self._table.add(self.no_spell_check)
self.recheck()
@@ -300,7 +459,12 @@ class SpellChecker(object):
Rechecks the spelling of the whole text.
"""
start, end = self._buffer.get_bounds()
- self.check_range(start, end, True)
+
+ if self._batched_rechecking and end.get_offset() > _BATCHING_THRESHOLD_CHARS:
+ start_mark = self._buffer.create_mark(None, start)
+ self._continue_batched_recheck(start_mark)
+ else:
+ self.check_range(start, end, True)
def disable(self):
"""
@@ -343,11 +507,13 @@ class SpellChecker(object):
"""
self._filters[filter_type].append(regex)
if filter_type == SpellChecker.FILTER_TEXT:
- self._regexes[filter_type] = re.compile('|'.join(
- self._filters[filter_type]), re.MULTILINE)
+ self._regexes[filter_type] = re.compile(
+ "|".join(self._filters[filter_type]), re.MULTILINE
+ )
else:
- self._regexes[filter_type] = re.compile('|'.join(
- self._filters[filter_type]))
+ self._regexes[filter_type] = re.compile(
+ "|".join(self._filters[filter_type])
+ )
def remove_filter(self, regex, filter_type):
"""
@@ -358,11 +524,13 @@ class SpellChecker(object):
"""
self._filters[filter_type].remove(regex)
if filter_type == SpellChecker.FILTER_TEXT:
- self._regexes[filter_type] = re.compile('|'.join(
- self._filters[filter_type]), re.MULTILINE)
+ self._regexes[filter_type] = re.compile(
+ "|".join(self._filters[filter_type]), re.MULTILINE
+ )
else:
- self._regexes[filter_type] = re.compile('|'.join(
- self._filters[filter_type]))
+ self._regexes[filter_type] = re.compile(
+ "|".join(self._filters[filter_type])
+ )
def append_ignore_tag(self, tag):
"""
@@ -371,7 +539,7 @@ class SpellChecker(object):
:param tag: Tag object or tag name.
"""
- if isinstance(tag, basestring):
+ if isinstance(tag, str):
tag = self._table.lookup(tag)
self.ignored_tags.append(tag)
@@ -382,7 +550,7 @@ class SpellChecker(object):
:param tag: Tag object or tag name.
"""
- if isinstance(tag, basestring):
+ if isinstance(tag, str):
tag = self._table.lookup(tag)
self.ignored_tags.remove(tag)
@@ -411,27 +579,39 @@ class SpellChecker(object):
:param start: Start iter - checking starts here.
:param end: End iter - checking ends here.
"""
+ logger.debug(
+ "Check range called with range %d:%d to %d:%d and force all set to %s.",
+ start.get_line(),
+ start.get_line_offset(),
+ end.get_line(),
+ end.get_line_offset(),
+ force_all,
+ )
if not self._enabled:
return
- if end.inside_word(): end.forward_word_end()
- if not start.starts_word() and (start.inside_word() or
- start.ends_word()):
- start.backward_word_start()
+ start = start.copy()
+ end = end.copy()
+ if self._iter_worker.inside_word(end):
+ self._iter_worker.forward_word_end(end)
+ if self._iter_worker.inside_word(start) or self._iter_worker.ends_word(start):
+ self._iter_worker.backward_word_start(start)
+ if not self._iter_worker.starts_word(start):
+ self._iter_worker.forward_word_end(start)
+ self._iter_worker.backward_word_start(start)
self._buffer.remove_tag(self._misspelled, start, end)
cursor = self._buffer.get_iter_at_mark(self._buffer.get_insert())
precursor = cursor.copy()
precursor.backward_char()
- highlight = (cursor.has_tag(self._misspelled) or
- precursor.has_tag(self._misspelled))
- if not start.get_offset():
- start.forward_word_end()
- start.backward_word_start()
+ highlight = cursor.has_tag(self._misspelled) or precursor.has_tag(
+ self._misspelled
+ )
word_start = start.copy()
while word_start.compare(end) < 0:
word_end = word_start.copy()
- word_end.forward_word_end()
- in_word = ((word_start.compare(cursor) < 0) and
- (cursor.compare(word_end) <= 0))
+ self._iter_worker.forward_word_end(word_end)
+ in_word = (word_start.compare(cursor) < 0) and (
+ cursor.compare(word_end) <= 0
+ )
if in_word and not force_all:
if highlight:
self._check_word(word_start, word_end)
@@ -440,153 +620,225 @@ class SpellChecker(object):
else:
self._check_word(word_start, word_end)
self._deferred_check = False
- word_end.forward_word_end()
- word_end.backward_word_start()
+ self._iter_worker.forward_word_end(word_end)
+ self._iter_worker.backward_word_start(word_end)
if word_start.equal(word_end):
break
word_start = word_end.copy()
- def _languages_menu(self):
- def _set_language(item, code):
- self.language = code
- if _pygobject:
- menu = gtk.Menu.new()
+ def _gtk4_setup_actions(self) -> None:
+ action_group = Gio.SimpleActionGroup.new()
+
+ action = Gio.SimpleAction.new("ignore-all", GLib.VariantType("s"))
+ action.connect(
+ "activate", lambda _action, word: self.ignore_all(word.get_string())
+ )
+ action_group.add_action(action)
+
+ action = Gio.SimpleAction.new("add-to-dictionary", GLib.VariantType("s"))
+ action.connect(
+ "activate", lambda _action, word: self.add_to_dictionary(word.get_string())
+ )
+ action_group.add_action(action)
+
+ action = Gio.SimpleAction.new("replace-word", GLib.VariantType("s"))
+ action.connect(
+ "activate",
+ lambda _action, suggestion: self._replace_word(suggestion.get_string()),
+ )
+ action_group.add_action(action)
+
+ language = Gio.PropertyAction.new("language", self, "language")
+ action_group.add_action(language)
+
+ self._view.insert_action_group("spelling", action_group)
+
+ def _get_languages_menu(self):
+ if _IS_GTK3:
+ return self._build_languages_menu()
+ else:
+ if self._languages_menu is None:
+ self._languages_menu = self._build_languages_menu()
+ return self._languages_menu
+
+ def _build_languages_menu(self):
+ if _IS_GTK3:
+
+ def _set_language(item, code):
+ self.language = code
+
+ menu = Gtk.Menu.new()
group = []
+ connect = []
else:
- menu = gtk.Menu()
- group = gtk.RadioMenuItem()
- connect = []
+ menu = Gio.Menu.new()
+
for code, name in self.languages:
- if _pygobject:
- item = gtk.RadioMenuItem.new_with_label(group, name)
+ if _IS_GTK3:
+ item = Gtk.RadioMenuItem.new_with_label(group, name)
group.append(item)
+ if code == self.language:
+ item.set_active(True)
+ connect.append((item, code))
+ menu.append(item)
else:
- item = gtk.RadioMenuItem(group, name)
- if code == self.language:
- item.set_active(True)
- connect.append((item, code))
- menu.append(item)
- for item, code in connect:
- item.connect('activate', _set_language, code)
- return menu
+ item = Gio.MenuItem.new(name, None)
+ item.set_action_and_target_value(
+ "spelling.language", GLib.Variant.new_string(code)
+ )
+ menu.append_item(item)
+ if _IS_GTK3:
+ for item, code in connect:
+ item.connect("activate", _set_language, code)
+ return menu
+ else:
+ return Gio.MenuItem.new_submenu(_("Languages"), menu)
def _suggestion_menu(self, word):
menu = []
suggestions = self._dictionary.suggest(word)
if not suggestions:
- if _pygobject:
- item = gtk.MenuItem.new()
- label = gtk.Label.new('')
- else:
- item = gtk.MenuItem()
- label = gtk.Label()
- try:
- label.set_halign(gtk.Align.LEFT)
- except AttributeError:
- label.set_alignment(0.0, 0.5)
- label.set_markup('<i>{text}</i>'.format(text=_('(no suggestions)')))
- item.add(label)
- menu.append(item)
- else:
- for suggestion in suggestions:
- if _pygobject:
- item = gtk.MenuItem.new()
- label = gtk.Label.new('')
- else:
- item = gtk.MenuItem()
- label = gtk.Label()
- label.set_markup('<b>{text}</b>'.format(text=suggestion))
+ # Show GTK 3 no suggestions item (removed for GTK 4)
+ if _IS_GTK3:
+ item = Gtk.MenuItem.new()
+ label = Gtk.Label.new("")
try:
- label.set_halign(gtk.Align.LEFT)
+ label.set_halign(Gtk.Align.LEFT)
except AttributeError:
label.set_alignment(0.0, 0.5)
+ label.set_markup("<i>{text}</i>".format(text=_("(no suggestions)")))
item.add(label)
- item.connect('activate', self._replace_word, word, suggestion)
menu.append(item)
- if _pygobject:
- menu.append(gtk.SeparatorMenuItem.new())
- item = gtk.MenuItem.new_with_label(
- _('Add "{}" to Dictionary').format(word))
else:
- menu.append(gtk.SeparatorMenuItem())
- item = gtk.MenuItem(_('Add "{}" to Dictionary').format(word))
- item.connect('activate', lambda *args: self.add_to_dictionary(word))
+ for suggestion in suggestions:
+ if _IS_GTK3:
+ item = Gtk.MenuItem.new()
+ label = Gtk.Label.new("")
+ label.set_markup("<b>{text}</b>".format(text=suggestion))
+ try:
+ label.set_halign(Gtk.Align.LEFT)
+ except AttributeError:
+ label.set_alignment(0.0, 0.5)
+ item.add(label)
+
+ def _make_on_activate(word):
+ return lambda *args: self._replace_word(word)
+
+ item.connect("activate", _make_on_activate(word))
+ else:
+ escaped = suggestion.replace("'", "\\'")
+ item = Gio.MenuItem.new(
+ suggestion, f"spelling.replace-word('{escaped}')"
+ )
+ menu.append(item)
+ add_to_dict_menu_label = _("Add to Dictionary")
+ word_escaped = word.replace("'", "\\'")
+ if _IS_GTK3:
+ menu.append(Gtk.SeparatorMenuItem.new())
+ item = Gtk.MenuItem.new_with_label(add_to_dict_menu_label)
+ item.connect("activate", lambda *args: self.add_to_dictionary(word))
+ else:
+ item = Gio.MenuItem.new(
+ add_to_dict_menu_label, f"spelling.add-to-dictionary('{word_escaped}')"
+ )
menu.append(item)
- if _pygobject:
- item = gtk.MenuItem.new_with_label(_('Ignore All'))
+ ignore_menu_label = _("Ignore All")
+ if _IS_GTK3:
+ item = Gtk.MenuItem.new_with_label(ignore_menu_label)
+ item.connect("activate", lambda *args: self.ignore_all(word))
else:
- item = gtk.MenuItem(_('Ignore All'))
- item.connect('activate', lambda *args: self.ignore_all(word))
+ item = Gio.MenuItem.new(
+ ignore_menu_label, f"spelling.ignore-all('{word_escaped}')"
+ )
menu.append(item)
return menu
def _extend_menu(self, menu):
+ # In GTK 4 our existing menu needs to be cleared, providing for disabling
+ if not _IS_GTK3:
+ menu.remove_all()
+
if not self._enabled:
return
- if _pygobject:
- separator = gtk.SeparatorMenuItem.new()
- else:
- separator = gtk.SeparatorMenuItem()
- separator.show()
- menu.prepend(separator)
- if _pygobject:
- languages = gtk.MenuItem.new_with_label(_('Languages'))
+
+ if _IS_GTK3:
+ separator = Gtk.SeparatorMenuItem.new()
+ separator.show()
+ menu.prepend(separator)
+ languages = Gtk.MenuItem.new_with_label(_("Languages"))
+ languages.set_submenu(self._get_languages_menu())
+ languages.show_all()
+ menu.prepend(languages)
else:
- languages = gtk.MenuItem(_('Languages'))
- languages.set_submenu(self._languages_menu())
- languages.show_all()
- menu.prepend(languages)
- if self._marks['click'].inside_word:
- start, end = self._marks['click'].word
+ menu.append_item(self._get_languages_menu())
+
+ if self._marks["click"].inside_word:
+ start, end = self._marks["click"].word
if start.has_tag(self._misspelled):
- if _py3k:
- word = self._buffer.get_text(start, end, False)
- else:
- word = self._buffer.get_text(start, end,
- False).decode('utf-8')
+ word = self._buffer.get_text(start, end, False)
items = self._suggestion_menu(word)
if self.collapse:
- if _pygobject:
- suggestions = gtk.MenuItem.new_with_label(
- _('Suggestions'))
- submenu = gtk.Menu.new()
+ menu_label = _("Suggestions")
+ if _IS_GTK3:
+ suggestions = Gtk.MenuItem.new_with_label(menu_label)
+ submenu = Gtk.Menu.new()
else:
- suggestions = gtk.MenuItem(_('Suggestions'))
- submenu = gtk.Menu()
+ suggestions = Gio.MenuItem.new(menu_label, None)
+ submenu = Gio.Menu.new()
for item in items:
- submenu.append(item)
+ if _IS_GTK3:
+ submenu.append(item)
+ else:
+ submenu.append_item(item)
suggestions.set_submenu(submenu)
- suggestions.show_all()
- menu.prepend(suggestions)
+ if _IS_GTK3:
+ suggestions.show_all()
+ menu.prepend(suggestions)
+ else:
+ menu.prepend_item(suggestions)
else:
items.reverse()
for item in items:
- menu.prepend(item)
- menu.show_all()
+ if _IS_GTK3:
+ menu.prepend(item)
+ menu.show_all()
+ else:
+ menu.prepend_item(item)
def _click_move_popup(self, *args):
- self._marks['click'].move(self._buffer.get_iter_at_mark(
- self._buffer.get_insert()))
+ self._marks["click"].move(
+ self._buffer.get_iter_at_mark(self._buffer.get_insert())
+ )
return False
def _click_move_button(self, widget, event):
if event.button == 3:
- if self._deferred_check: self._check_deferred_range(True)
- x, y = self._view.window_to_buffer_coords(2, int(event.x),
- int(event.y))
- iter = self._view.get_iter_at_location(x, y)
- if isinstance(iter, tuple):
- iter = iter[1]
- self._marks['click'].move(iter)
+ self._move_mark_for_input(event.x, event.y)
return False
+ def _move_mark_for_input(self, input_x, input_y):
+ if self._deferred_check:
+ self._check_deferred_range(True)
+ x, y = self._view.window_to_buffer_coords(2, int(input_x), int(input_y))
+ iter = self._view.get_iter_at_location(x, y)
+ if isinstance(iter, tuple):
+ iter = iter[1]
+ self._marks["click"].move(iter)
+
+ def _gtk4_on_textview_click(self, click, n_press, x, y) -> None:
+ if n_press != 1 or click.get_current_button() != 3:
+ return
+
+ self._move_mark_for_input(x, y)
+ self._extend_menu(self._spelling_menu)
+
def _before_text_insert(self, textbuffer, location, text, length):
- self._marks['insert-start'].move(location)
+ self._marks["insert-start"].move(location)
def _after_text_insert(self, textbuffer, location, text, length):
- start = self._marks['insert-start'].iter
+ start = self._marks["insert-start"].iter
self.check_range(start, location)
- self._marks['insert-end'].move(location)
+ self._marks["insert-end"].move(location)
def _range_delete(self, textbuffer, start, end):
self.check_range(start, end)
@@ -595,8 +847,9 @@ class SpellChecker(object):
if mark == self._buffer.get_insert() and self._deferred_check:
self._check_deferred_range(False)
- def _replace_word(self, item, old_word, new_word):
- start, end = self._marks['click'].word
+ def _replace_word(self, new_word):
+ start, end = self._marks["click"].word
+ old_word = start.get_text(end)
offset = start.get_offset()
self._buffer.begin_user_action()
self._buffer.delete(start, end)
@@ -605,8 +858,8 @@ class SpellChecker(object):
self._dictionary.store_replacement(old_word, new_word)
def _check_deferred_range(self, force_all):
- start = self._marks['insert-start'].iter
- end = self._marks['insert-end'].iter
+ start = self._marks["insert-start"].iter
+ end = self._marks["insert-end"].iter
self.check_range(start, end, force_all)
def _check_word(self, start, end):
@@ -615,39 +868,51 @@ class SpellChecker(object):
for tag in self.ignored_tags:
if start.has_tag(tag):
return
- if _py3k:
- word = self._buffer.get_text(start, end, False).strip()
- else:
- word = self._buffer.get_text(start, end, False).decode('utf-8').strip()
+ word = self._buffer.get_text(start, end, False).strip()
+ logger.debug(
+ "Checking word %s in range %d:%d to %d:%d.",
+ word,
+ start.get_line(),
+ start.get_line_offset(),
+ end.get_line(),
+ end.get_line_offset(),
+ )
if not word:
return
if len(self._filters[SpellChecker.FILTER_WORD]):
if self._regexes[SpellChecker.FILTER_WORD].match(word):
return
if len(self._filters[SpellChecker.FILTER_LINE]):
- line_start = self._buffer.get_iter_at_line(start.get_line())
+ if _IS_GTK3:
+ line_start = self._buffer.get_iter_at_line(start.get_line())
+ else:
+ _success, line_start = self._buffer.get_iter_at_line(start.get_line())
line_end = end.copy()
line_end.forward_to_line_end()
- if _py3k:
- line = self._buffer.get_text(line_start, line_end, False)
- else:
- line = self._buffer.get_text(line_start, line_end,
- False).decode('utf-8')
+ line = self._buffer.get_text(line_start, line_end, False)
for match in self._regexes[SpellChecker.FILTER_LINE].finditer(line):
if match.start() <= start.get_line_offset() <= match.end():
- start = self._buffer.get_iter_at_line_offset(
- start.get_line(), match.start())
- end = self._buffer.get_iter_at_line_offset(start.get_line(),
- match.end())
+ if _IS_GTK3:
+ start = self._buffer.get_iter_at_line_offset(
+ start.get_line(), match.start()
+ )
+ end = self._buffer.get_iter_at_line_offset(
+ start.get_line(), match.end()
+ )
+ else:
+ # Success is not verified here as the locations come directly
+ # from the buffer
+ _success, start = self._buffer.get_iter_at_line_offset(
+ start.get_line(), match.start()
+ )
+ _success, end = self._buffer.get_iter_at_line_offset(
+ start.get_line(), match.end()
+ )
self._buffer.remove_tag(self._misspelled, start, end)
return
if len(self._filters[SpellChecker.FILTER_TEXT]):
text_start, text_end = self._buffer.get_bounds()
- if _py3k:
- text = self._buffer.get_text(text_start, text_end, False)
- else:
- text = self._buffer.get_text(text_start, text_end,
- False).decode('utf-8')
+ text = self._buffer.get_text(text_start, text_end, False)
for match in self._regexes[SpellChecker.FILTER_TEXT].finditer(text):
if match.start() <= start.get_offset() <= match.end():
start = self._buffer.get_iter_at_offset(match.start())
@@ -656,3 +921,23 @@ class SpellChecker(object):
return
if not self._dictionary.check(word):
self._buffer.apply_tag(self._misspelled, start, end)
+
+ def _continue_batched_recheck(self, start_mark):
+ if start_mark.get_buffer() != self._buffer:
+ return
+ start = self._buffer.get_iter_at_mark(start_mark)
+ self._buffer.delete_mark(start_mark)
+
+ if not self._enabled:
+ return
+
+ end = start.copy()
+ end.forward_chars(_BATCH_SIZE_CHARS)
+ self._iter_worker.forward_word_end(end)
+
+ self.check_range(start, end, True)
+
+ if not end.is_end():
+ end.forward_char()
+ start_mark = self._buffer.create_mark(None, end)
+ GLib.idle_add(self._continue_batched_recheck, start_mark)
diff --git a/src/pygtkspellcheck.egg-info/PKG-INFO b/src/pygtkspellcheck.egg-info/PKG-INFO
deleted file mode 100644
index 5c8dcf4..0000000
--- a/src/pygtkspellcheck.egg-info/PKG-INFO
+++ /dev/null
@@ -1,21 +0,0 @@
-Metadata-Version: 1.1
-Name: pygtkspellcheck
-Version: 4.0.5
-Summary: a simple but quite powerful Python spell checking library for GtkTextViews based on Enchant
-Home-page: http://koehlma.github.com/projects/pygtkspellcheck.html
-Author: Maximilian Köhl & Carlos Jenkins
-Author-email: linuxmaxi@googlemail.com & carlos@jenkins.co.cr
-License: GPLv3+
-Download-URL: https://github.com/koehlma/pygtkspellcheck/tarball/master
-Description: A simple but quite powerful spellchecking library written in pure Python for Gtk based on Enchant. It supports PyGObject as well as PyGtk for Python 2 and 3 with automatic switching and binding detection. For automatic translation of the user interface it can use Gedit’s translation files.
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: X11 Applications :: Gnome
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
-Classifier: Operating System :: MacOS :: MacOS X
-Classifier: Operating System :: Microsoft :: Windows
-Classifier: Operating System :: POSIX
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 3
-Classifier: Topic :: Software Development :: Localization
diff --git a/src/pygtkspellcheck.egg-info/SOURCES.txt b/src/pygtkspellcheck.egg-info/SOURCES.txt
deleted file mode 100644
index e7dd6ca..0000000
--- a/src/pygtkspellcheck.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-LICENSE.txt
-MANIFEST.in
-README.rst
-setup.py
-doc/Makefile
-doc/insert_metadata.py
-doc/make.bat
-doc/metadata/documentation.rst
-doc/metadata/metadata.py
-doc/metadata/pypi.rst
-doc/metadata/readme.md
-doc/metadata/screenshot.png
-doc/metadata/website.md
-doc/pypi/index.html
-doc/pypi/page.rst
-doc/screenshots/screenshot.png
-doc/source/conf.py
-doc/source/index.rst
-examples/large_pygobject.py
-examples/large_pygtk.py
-examples/simple_pygobject.py
-examples/simple_pygtk.py
-locale/de/pygtkspellcheck.mo
-locale/de/pygtkspellcheck.po
-locale/en/pygtkspellcheck.mo
-locale/en/pygtkspellcheck.po
-locale/es/pygtkspellcheck.mo
-locale/es/pygtkspellcheck.po
-src/gtkspellcheck/__init__.py
-src/gtkspellcheck/oxt_extract.py
-src/gtkspellcheck/spellcheck.py
-src/pygtkspellcheck.egg-info/PKG-INFO
-src/pygtkspellcheck.egg-info/SOURCES.txt
-src/pygtkspellcheck.egg-info/dependency_links.txt
-src/pygtkspellcheck.egg-info/requires.txt
-src/pygtkspellcheck.egg-info/top_level.txt
-src/pylocales/__init__.py
-src/pylocales/locales.db
-src/pylocales/locales.py
\ No newline at end of file
diff --git a/src/pygtkspellcheck.egg-info/dependency_links.txt b/src/pygtkspellcheck.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/src/pygtkspellcheck.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/pygtkspellcheck.egg-info/requires.txt b/src/pygtkspellcheck.egg-info/requires.txt
deleted file mode 100644
index b8f9eb4..0000000
--- a/src/pygtkspellcheck.egg-info/requires.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-pyenchant
-
-[building the documentation]
-sphinx
diff --git a/src/pygtkspellcheck.egg-info/top_level.txt b/src/pygtkspellcheck.egg-info/top_level.txt
deleted file mode 100644
index 54ac8a6..0000000
--- a/src/pygtkspellcheck.egg-info/top_level.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-gtkspellcheck
-pylocales
diff --git a/src/pylocales/__init__.py b/src/pylocales/__init__.py
deleted file mode 100644
index ee32ec0..0000000
--- a/src/pylocales/__init__.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# -*- coding:utf-8 -*-
-#
-# Copyright (C) 2012, Maximilian Köhl <linuxmaxi@googlemail.com>
-#
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-from __future__ import unicode_literals
-
-__version__ = '1.2'
-__project__ = 'Python Locales'
-__short_name__ = 'pylocales'
-__authors__ = 'Maximilian Köhl'
-__emails__ = 'linuxmaxi@googlemail.com'
-__website__ = 'http://koehlma.github.com/projects/pygtkspellcheck.html'
-__source__ = 'https://github.com/koehlma/pygtkspellcheck/'
-__vcs__ = 'git://github.com/koehlma/pygtkspellcheck.git'
-__copyright__ = '2012, Maximilian Köhl'
-__desc_short__ = 'query the ISO 639/3166 database about a country or a language.'
-__desc_long__ = ('Query the ISO 639/3166 database about a country or a'
- 'language. The locales database contains ISO 639 language'
- 'definitions and ISO 3166 country definitions. This package'
- 'provides translation for country and language names if'
- 'the iso-code messages are installed on your system.')
-
-__metadata__ = {'__version__' : __version__,
- '__project__' : __project__,
- '__short_name__' : __short_name__,
- '__authors__' : __authors__,
- '__emails__' : __emails__,
- '__website__' : __website__,
- '__source__' : __source__,
- '__vcs__' : __vcs__,
- '__copyright__' : __copyright__,
- '__desc_short__' : __desc_short__,
- '__desc_long__' : __desc_long__}
-
-from pylocales.locales import (Country, Language, LanguageNotFound,
- CountryNotFound, code_to_name)