sphinxcontrib_spelling-8.0.2/.git_archival.txt0000644000000000000000000000024613615410400016505 0ustar00# https://github.com/pypa/setuptools_scm node: $Format:%H$ node-date: $Format:%cI$ describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$ ref-names: $Format:%D$ sphinxcontrib_spelling-8.0.2/.gitattributes0000644000000000000000000000004013615410400016115 0ustar00.git_archival.txt export-subst sphinxcontrib_spelling-8.0.2/.readthedocs.yml0000644000000000000000000000027713615410400016324 0ustar00# https://docs.readthedocs.io/en/stable/config-file/v2.html # Required version: 2 sphinx: configuration: docs/source/conf.py python: install: - requirements: docs/requirements.txt sphinxcontrib_spelling-8.0.2/.testr.conf0000644000000000000000000000022713615410400015317 0ustar00[DEFAULT] test_command=${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION test_id_option=--load-list $IDFILE test_list_option=--list sphinxcontrib_spelling-8.0.2/MANIFEST.in0000644000000000000000000000003713615410400014766 0ustar00include README include LICENSE sphinxcontrib_spelling-8.0.2/Makefile0000644000000000000000000000170513615410400014673 0ustar00# Default target is to show help help: @echo "sdist - Source distribution" @echo "html - HTML documentation" @echo "spelling - Check spelling of documentation" @echo "upload - upload a new release to PyPI" @echo "installwebsite - deploy web version of docs" @echo "develop - install development version" @echo "test - run the test suite" .PHONY: sdist sdist: html python setup.py sdist .PHONY: upload upload: html python setup.py sdist upload # Documentation .PHONY: html html: (cd docs && $(MAKE) html) .PHONY: spelling spelling: (cd docs && $(MAKE) spelling) installwebsite: html (cd docs/build/html && rsync --rsh=ssh --archive --delete --verbose . www.doughellmann.com:/var/www/doughellmann/DocumentRoot/docs/sphinxcontrib.spelling/) # Register the new version on pypi .PHONY: register register: python setup.py register # Testing .PHONY: test test: tox develop: python setup.py develop sphinxcontrib_spelling-8.0.2/requirements-dev.txt0000644000000000000000000000000513615410400017263 0ustar00ruff sphinxcontrib_spelling-8.0.2/show-changelog.sh0000755000000000000000000000057513615410400016503 0ustar00#!/bin/bash git_project=$(git remote get-url origin | cut -f2 -d: | sed 's/.git//') pr_url_base="https://github.com/${git_project}/pull/" git log --merges --pretty="format:- %s %b" $(git describe --abbrev=0).. \ | sed -E \ -e 's#Merge pull request ##g' \ -e 's# from [^[:space:]]+##' \ -e 's|#([[:digit:]]+)|`#\1 <'${pr_url_base}'\1>`__|g' echo sphinxcontrib_spelling-8.0.2/.virtualenvwrapper/postactivate0000755000000000000000000000036613615410400021547 0ustar00# -*- shell-script -*- #export PYENCHANT_LIBRARY_PATH=/opt/homebrew/Cellar/enchant/2.6.4/lib/libenchant-2.2.dylib if [ $(uname) = Darwin ]; then export PYENCHANT_LIBRARY_PATH=$(brew list enchant | grep 'libenchant-.*\.dylib' | head -n 1) fi sphinxcontrib_spelling-8.0.2/.virtualenvwrapper/predeactivate0000644000000000000000000000006513615410400021652 0ustar00# -*- shell-script -*- unset PYENCHANT_LIBRARY_PATH sphinxcontrib_spelling-8.0.2/docs/Makefile0000644000000000000000000001117313615410400015623 0ustar00# 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 .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest help: @echo "Please use \`make ' where 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 " 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/sphinxcontribspelling.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/sphinxcontribspelling.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/sphinxcontribspelling" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/sphinxcontribspelling" @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." 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." spelling: $(SPHINXBUILD) -b spelling $(ALLSPHINXOPTS) $(BUILDDIR)/spelling doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." sphinxcontrib_spelling-8.0.2/docs/requirements.txt0000644000000000000000000000006713615410400017447 0ustar00# This file is only needed for readthedocs.org .[docs] sphinxcontrib_spelling-8.0.2/docs/source/code.rst0000644000000000000000000000111513615410400017122 0ustar00==== Code ==== spelling.builder ================ .. automodule:: sphinxcontrib.spelling.builder :members: spelling.checker ================ .. automodule:: sphinxcontrib.spelling.checker :members: spelling.directive ================== .. automodule:: sphinxcontrib.spelling.directive :members: spelling.domain ================ .. automodule:: sphinxcontrib.spelling.domain :members: spelling.filters ================ .. automodule:: sphinxcontrib.spelling.filters :members: spelling.role ================ .. automodule:: sphinxcontrib.spelling.role :members: sphinxcontrib_spelling-8.0.2/docs/source/conf.py0000644000000000000000000001647513615410400016774 0ustar00# sphinxcontrib.spelling documentation build configuration file, created by # sphinx-quickstart on Sun Apr 17 15:33:23 2011. # # 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 os import pathlib import sys # 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('.')) sys.path.insert(0, str(pathlib.Path("..", "src").resolve())) # -- 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 = [ "sphinxcontrib.spelling", "sphinx.ext.autodoc", ] spelling_word_list_filename = [ "spelling_wordlist.txt", ] spelling_show_suggestions = True spelling_ignore_pypi_package_names = True spelling_ignore_contributor_names = True # 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 = "index" # General information about the project. project = "sphinxcontrib.spelling" copyright = "2011, Doug Hellmann" # 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 = "1.4" # The full version, including alpha/beta/rc tags. release = version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. language = "en" # 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 # " v 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 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 = "sphinxcontribspellingdoc" # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). # latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). # latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ( "index", "sphinxcontribspelling.tex", "sphinxcontrib.spelling Documentation", "Doug Hellmann", "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 # Additional stuff for the LaTeX preamble. # latex_preamble = '' # 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 = [ ( "index", "sphinxcontribspelling", "sphinxcontrib.spelling Documentation", ["Doug Hellmann"], 1, ) ] sphinxcontrib_spelling-8.0.2/docs/source/customize.rst0000644000000000000000000001657313615410400020250 0ustar00======================= Configuration Options ======================= These options can be set in ``conf.py`` along with the other Sphinx configuration settings. Input Options ============= ``spelling_lang='en_US'`` String specifying the language, as understood by PyEnchant and enchant. Defaults to ``en_US`` for US English. ``tokenizer_lang='en_US'`` String specifying the tokenizer language as understood by PyEnchant and enchant. Defaults to ``en_US`` for US English. ``spelling_word_list_filename='spelling_wordlist.txt'`` String specifying a file containing a list of words known to be spelled correctly but that do not appear in the language dictionary selected by ``spelling_lang``. The file should contain one word per line. Refer to the `PyEnchant tutorial`_ for details. To add multiple files use a list, or a comma separated string. This is useful when calling sphinx with ``-D spelling_word_list_filename=...`` which will not accept a list and will only accept a string parameter. ``spelling_word_list_filename=['spelling_wordlist.txt','another_list.txt']`` Same as above, but with several files of correctly spelled words. ``spelling_word_list_filename='spelling_wordlist.txt,another_list.txt'`` Same as above, but with several files of correctly spelled words, and passing the setting as a single string. ``spelling_exclude_patterns=['ignored_*']`` A list of glob-style patterns that should be ignored when checking spelling. They are matched against the source file names relative to the source directory, using slashes as directory separators on all platforms. See Sphinx's `exclude_patterns`_ option for more details on glob-style patterns. .. _PyEnchant tutorial: https://github.com/rfk/pyenchant/blob/master/website/content/tutorial.rst .. _exclude_patterns : https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-exclude_patterns .. _output-options: Output Options ============== ``spelling_show_suggestions=False`` Boolean controlling whether suggestions for misspelled words are printed. Defaults to ``False``. ``spelling_suggestion_limit=0`` Integer number of suggestions to emit when ``spelling_show_suggestions`` is ``True``. Defaults to ``0``, meaning no limit. Any positive value truncates the suggestion limit. ``spelling_show_whole_line=True`` Boolean controlling whether the contents of the line containing each misspelled word is printed, for more context about the location of each word. Defaults to True. ``spelling_warning=False`` Boolean controlling whether a misspelling is emitted as a sphinx warning or as an info message. Defaults to False. ``spelling_verbose=True`` Choose whether or not the misspelled words should be displayed in the terminal. Defaults to True. Word Filters ============ Enable or disable the built-in filters to control which words are returned by the tokenizer to be checked. ``spelling_ignore_pypi_package_names=False`` Boolean controlling whether words that look like package names from PyPI are treated as spelled properly. When ``True``, the current list of package names is downloaded at the start of the build and used to extend the list of known words in the dictionary. Defaults to ``False``. ``spelling_ignore_wiki_words=True`` Boolean controlling whether words that follow the CamelCase conventions used for page names in :spelling:word:`wikis` should be treated as spelled properly. Defaults to ``True``. ``spelling_ignore_acronyms=True`` Boolean controlling treatment of words that appear in all capital letters, or all capital letters followed by a lower case ``s``. When ``True``, acronyms are assumed to be spelled properly. Defaults to ``True``. ``spelling_ignore_python_builtins=True`` Boolean controlling whether names built in to Python should be treated as spelled properly. Defaults to ``True``. ``spelling_ignore_importable_modules=True`` Boolean controlling whether words that are names of modules found on ``sys.path`` are treated as spelled properly. Defaults to ``True``. ``spelling_ignore_contributor_names=True`` Boolean controlling whether contributor names taken from the git history for the repository are considered as spelled correctly. ``spelling_filters=[]`` List of importable filter classes to be added to the tokenizer that produces words to be checked. For example, ``["enchant.tokenize.MentionFilter"]``. The classes should be derived from ``enchant.tokenize.Filter``. Refer to the `PyEnchant tutorial`_ for examples. Managing Lists of Correctly Spelled Words and Ignoring Words ============================================================ There are three ways to provide a list of known good words. The ``spelling_word_list_filename`` option (described above) specifies the name of a plain text file containing one word per line. All of the words in the file are assumed to be spelled correctly and may appear in any part of the document being processed. You can use multiple text files with words to be added to the dictionary, to do this all you need to do is use a list and include the name of your text files. For example:: spelling_word_list_filename = ['spelling_wordlist.txt', 'my_wordlist.txt'] The ``spelling:word-list`` directive can be used to create a list of words known to be spelled correctly within a single file. For example, if a document refers to a person or project by name, the name can be added to the list of known words for just that document. :: .. spelling:word-list:: Docutils Goodger The ``spelling:word`` role can be used to annotate individual words as being spelled correctly throughout a single document. :: This text refers to :spelling:word:`Goodger`. The ``spelling:ignore`` role can be used to ignore a single instance of a word. :: This text refers to :spelling:ignore:`docutils`. .. _PyEnchant: https://github.com/rfk/pyenchant Custom Word Filters =================== The PyEnchant tokenizer supports a "filtering" API for processing words from the input. Filters can alter the stream of words by adding, replacing, or dropping values. New filters should be derived from ``enchant.tokenize.Filter`` and implement either the ``_split()`` method (to add or replace words) or ``_skip()`` (to treat words as being spelled correctly). For example, this :class:`AcronymFilter` skips words that are all uppercase letters or all uppercase with a trailing lowercase "s". :: class AcronymFilter(Filter): """If a word looks like an acronym (all upper case letters), ignore it. """ def _skip(self, word): return (word.isupper() # all caps or # pluralized acronym ("URLs") (word[-1].lower() == 's' and word[:-1].isupper() ) ) To be used in a document, the custom filter needs to be installed somewhere that Sphinx can import it while processing the input files. The Sphinx project's ``conf.py`` then needs two changes. 1. Import the filter class. 2. Add the import string for the filter class to the ``spelling_filters`` configuration variable. :: spelling_filters = ['mymodule.MyFilter'] .. seealso:: * `Creating a Spelling Checker for reStructuredText Documents `_ * `PyEnchant tutorial`_ sphinxcontrib_spelling-8.0.2/docs/source/developers.rst0000644000000000000000000000374713615410400020375 0ustar00.. spelling:word-list:: sphinxcontrib reStructuredText ============ Developers ============ If you would like to contribute to sphinxcontrib.spelling directly, these instructions should help you get started. Patches, bug reports, and feature requests are all welcome through the `GitHub site `__. Contributions in the form of patches or pull requests are easier to integrate and will receive priority attention. Running tests ============= To run the tests, you need ``tox`` installed, then just run ``tox``. This should run the unit tests, the source code linter, and try to build the current documentation. Enchant C Library ----------------- You also need the C library from Enchant installed. On macOS, use `brew` to install the `enchant` package, then set `PYENCHANT_LIBRARY_PATH` to point to the `dylib` file included in the output of `brew list enchant`. .. code-block:: console $ brew list enchant | grep dylib /opt/homebrew/Cellar/enchant/2.6.4/lib/libenchant-2.dylib /opt/homebrew/Cellar/enchant/2.6.4/lib/libenchant-2.2.dylib $ export PYENCHANT_LIBRARY_PATH=/opt/homebrew/Cellar/enchant/2.6.4/lib/libenchant-2.2.dylib Coding style ============ Python imports are formatted and sorted using `isort `__. To format all files, run: .. code-block:: console $ tox -e style Building Documentation ====================== The documentation for sphinxcontrib.spelling is written in reStructuredText and converted to HTML using Sphinx. The build is driven by ``tox``. To build only the documentation, run ``tox -e docs``. Contributing ============ Please submit changes as pull requests using the `GitHub repository `__. In the pull request description, link to any issues closed by the changes using ``Fixes #NUM``, replacing ``NUM`` with the issue number. Release Notes ============= Please add a release note for each pull request to ``docs/history.rst``. sphinxcontrib_spelling-8.0.2/docs/source/history.rst0000644000000000000000000003440313615410400017717 0ustar00================= Release History ================= .. spelling:word-list:: arg commandline config docstring Dutta emacs env Gulden Homebrew libenchant macOS namespace Nico repo scm setuptools testrepository unicode unmaintained Next ==== - Modernize packaging using hatch and hatchling. - List Python 3.13 as supported. - Add automatically generated documentation for key modules. - `#234 `__ Fix bug where nodes with no source information would cause a TypeError. Reported by Trevor Gross, Ronnie Dutta, and Nico Gulden. Bug Fixes --------- - `#229 `__ Gracefully handle if git is not installed - `#227 `__ Use pypi.org's JSON API instead of XML-RPC. 7.7.0 ===== New Features ------------ - `#199 `__ Add ``spelling:ignore`` role for marking inline text to not be checked. See :doc:`/customize` for more details. 7.6.2 ===== Bug Fixes --------- - `#193 `__ Remove excessive debug printing in `:spelling:word:` and `spelling` builder implementations. 7.6.1 ===== Bug Fixes --------- - `#188 `__ Fix `:spelling:word:` directives from being printed verbatim in output files. 7.6.0 ===== Features -------- - Convert to use Sphinx domains. Add ``spelling:word-list`` directive. Have ``spelling`` directive report that it is deprecated. - Add ``spelling:word`` role for marking inline text as spelled correctly. 7.5.1 ===== Bug Fixes --------- - `#180 `__ Suppress `SystemExit` errors in `ImportableModuleFilter` caused by importing modules that run code on import and exit when that code sees an error. Bug report and reproducer provided by Trevor Gross. 7.5.0 ===== Features -------- - `#151 `__ Added configuration option to limit the number of suggestions output. See :doc:`/customize` for more details. Idea contributed by Trevor Gross. - `#169 `__ Adds the ability to pass in multiple wordlists via the sphinx command line as ``-D spelling_word_list_filename=file1,file2``. Bug Fixes --------- - `#36 `__ Include captions of figures in the set of nodes for which the text is checked. 7.4.1 ===== - `#160 `__ Fixed issue with the builder crashing when reporting a misspelled word in a python docstring. 7.4.0 ===== - Fix a problem that occurred when the extra word list is empty and an IndexError is thrown. Prevent the error by checking the contents of the file before using the list. - `#153 `__ Ensure the correct relative filename is reported as the location of a misspelled word when the word is in an included file. Log the location ourselves instead of letting the logging system compute it for consistency until `the fix `__ is merged into Sphinx. - Change default env list for local tox runs to only include the current python version, as defined by the installation of tox. - Tell tox to pass `PYENCHANT_LIBRARY_PATH` through to commands. On macOS it can be a little tricky to set up libenchant if your default python does not match the one used by Homebrew for the library. Setting the variable to point to the library fixes that, but we don't want to set it in this file for everyone so use `passenv` to tell tox to pass the setting through when running the commands for each env. - `#159 `__ Report using the line number of the misspelled word instead of using the first line of the node, in both the log and `.spelling` output file. 7.3.3 ===== Bug Fixes --------- - `#149 `__ Fixes to support testing when building RPMs. Switch to PEP 420 native namespace and skip contributors test when not in a git repo. - `#150 `__ Minor code cleanup primarily around string interpolation. 7.3.2 ===== Bug Fixes --------- - `#143 `__ Treat ``__main__`` as a special module name that cannot be imported. If the test suite is invoked by running ``python -m pytest`` instead of ``pytest`` then there will be no ``__main__`` and find_spec() will fail, so this change makes the tests work in both modes. - `#144 `__ Fix python filename handling in ``ImportableModuleFilter``. If the word looks like a python module filename, strip the extension to avoid the side-effect of actually importing the module. This prevents, for example, ``'setup.py'`` triggering an import of the ``setup`` module during a doc build, which makes it look like Sphinx is complaining about a commandline argument. 7.3.1 ===== Bug Fixes --------- - `#137 `__ replace the use of deprecated ``imp`` in ``ImportableModuleFilter`` with ``importlib`` 7.3.0 ===== New Features ------------ - `#131 `__ included a documentation update to fix a broken link. - `#130 `__ tested support for Python 3.10, and added the trove classifier. - `#129 `__ improved the speed of the ``ImportableModuleFilter``. - `#128 `__ fixed some issues with the packaging configuration. 7.2.0 ===== New Features ------------ - `#123 `__ adds the ``spelling_verbose`` configuration option for controlling whether misspelled words are printed to the console as well as the output log files. See :ref:`output-options` for details. 7.1.0 ===== New Features ------------ - `#116 `__ adds a config option `spelling_warning` that makes individual messages about misspellings warnings. The same change also updates the formatting of the message to make it easier for IDEs to parse, allowing the editor to navigate to the location of the misspelled word. See :ref:`output-options` for details. Contributed by Robert Cohn. 7.0.1 ===== Bug Fixes --------- - `#105 `__ reverts a change that switched from `imp` to `importlib`. Using `importlib.find_spec()` is not safe at runtime as it can import modules which will cause side effects within environments. 7.0.0 ===== This major release drops support for Python 3.5. This version is not maintained anymore. Bug Fixes --------- - Fixes an issue with ellipsis incorrectly being interpreted as relative imports and triggering a `ValueError` in the `ImportableModuleFilter`. See `#96 `__ for details. 6.0.0 ===== With this release, sphinxcontrib-spelling moves from beta to stable. It also updates the use of Python 3, including packaging metadata, code style, and test configuration. New Features ------------ - Add packaging metadata declaring the project stable. - Add packaging metadata declaring support for Python 3 only. - Add packaging metadata indicating that this is a sphinx extension. Bug Fixes --------- - Replace use of deprecated `imp` module with `importlib`. - Update use of `pyenchant.get_tokenizer()` to pass filters argument as a keyword and avoid a runtime warning message. - Remove unused test dependency on `fixtures`. - Use `pyupgrade` to modernize the source code. 5.4.0 ===== New Features ------------ - Added a new filter (``sphinxcontrib.spelling.filters.ContributorFilter``) that treats contributor names extracted from the git history as spelled correctly, making it easier to refer to the names in acknowledgments . Includes a new configuration option, ``spelling_ignore_contributor_names`` to enable it. 5.3.0 ===== New Features ------------ - Add a configuration option ``spelling_exclude_patterns`` to manage skipping spell checking for some input files. The option uses a list of glob-style patterns that are matched against the source file names relative to the source directory. See :doc:`/customize` for more details. Contributed by sdelliot. 5.2.2 ===== Bug Fixes --------- - Updated to only create ``.spelling`` output files for inputs that generate spelling warnings. Fixes #63. 5.2.0 ===== New Features ------------ - The builder is now registered using an entry point, so that if the ``spelling`` directive is not used in a project ``sphinxcontrib.spelling`` does not need to be included explicitly in the ``extensions`` list in ``conf.py`` in order to use it with the project on the command line. - PyEnchant is an optional dependency. If it is not installed, the spell checker will not work, but the extension can still be initialized. This allows projects that use spell checking to publish their documentation to ``readthedocs.org``, where it is not possible to install PyEnchant. - Restore support for parallel builds. Words that do not appear in any configured dictionary are written to a file named based on the input file, with the ``.rst`` extension replaced with ``.spelling``. 5.1.2 ===== - Mark as unsafe for parallel builds (contributed by Jared Dillard) - Add -W arg to sphinx-build in docs so warnings cause error (contributed by Elsa Gonsiorowski, PhD) 5.1.0 ===== - Add an option to show the line containing a misspelling for context (contributed by Huon Wilson) 5.0.0 ===== - Drop Python 2.7 support. (contributed by Johannes Raggam) - `allow customizing with classes using import strings `__ - pyenchant is now maintained (contributed by Adam Johnson 4.3.0 ===== - Logging: use warning() instead of its deprecated alias (contributed by Sergey Kolosov) - Support additional contractions (contributed by David Baumgold) - require Sphinx >= 2.0.0 - declare support for Python 3.6 4.2.1 ===== - fix remaining logging issue (contributed by Timotheus Kampik) - Remove usage of deprecated logging API (contributed by Tim Graham) 4.2.0 ===== - Fix a bug with empty word lists (contributed by FabioRosado) - Update dependency management to use setuptools extras - Document how to create multiple wordfiles (contributed by FabioRosado) - Note that PyEnchant is unmaintained and fix links (contributed by Marti Raudsepp) - Don’t use mutable default argument (contributed by Daniele Tricoli) 4.1.0 ===== - Make it possible to provide several wordlists (contributed by Tobias Olausson) - Update developer documentation (contributed by Tobias Olausson) - Update home page link (contributed by Devin Sevilla) 4.0.1 ===== - use the right method to emit warnings - disable smart quotes so that we can recognize contractions/possessives correctly (contributed by Alex Gaynor) 4.0.0 ===== - Don’t fail by default (contributed by Stephen Finucane) - Mark the extension as safe for parallel reading (contributed by Alex Gaynor) - be more verbose about configuration options - switch to testrepository for running tests - update Python 3.3 to 3.5 2.3.0 ===== - make it possible to specify tokenizer #7 (contributed by Timotheus Kampik) 2.2.0 ===== - Use ``https`` with ``pypi.python.org`` package name checker (contributed by John-Scott Atlakson) - Removed unnecessary shebang lines from non-script files (contributed by Avram Lubkin) - Re-enable the PyEnchant dependency (contributed by Julian Berman) 2.1.2 ===== - Fixed issue with six under Python 3.4 2.1.1 ===== - Use ``str.isupper()`` instead of ad-hoc method - fix syntax for tags directive - Removed no more used CHANGES file 2.1 === - Fix unicode error in ``PythonBuiltinsFilter``. - Make error output useful in emacs compiler mode - Only show the words being added to a local dictionary if debugging is enabled. 2.0 === - Add Python 3.3 support. - Add PyPy support. - Use pbr for packaging. - Update tox config to work with forked version of PyEnchant until changes are accepted upstream. 1.4 === - Fixed detection of builtins under PyPy, contributed by Hong Minhee (https://bitbucket.org/dahlia). 1.3 === - Handle text nodes without parents. (#19) - Include the input document name in the console output. - Use the Sphinx wrapper for registering a directive. 1.2 === - Add the document name to the messages showing the contents of a local dictionary created by the ``spelling`` directive. - Add title nodes to the list of node types checked for spelling. Resolves issue #17. - Add test/test_wordlist.txt to the manifest so it is included in the source distribution and the tests will pass. Resolves issue #17. - Documentation patch from Hank Gay. 1.1.1 ===== - Fix initialization so the per-document filters work even if no ``spelling`` directive is used. 1.1 === - Add an option treat the names of packages on PyPI as spelled properly. - Add an option to treat CamelCase names as spelled properly. - Add an option to treat acronyms as spelled properly. - Add an option to treat Python built-ins as spelled properly. - Add an option to treat names that can be found as modules as spelled properly. - Add an option to let the user provide a list of other filter classes for the tokenizer. - Add ``spelling`` directive for passing local configuration settings to the spelling checker. This version allows setting a list of words known to be spelled correctly. 1.0 === - Re-implement using just a Builder, without a separate visitor class. - Show the file and line number of any words not appearing in the dictionary, instead of the section title. - Log the file, line, and unknown words as the documents are processed. 0.2 === - Warn but otherwise ignore unknown node types. 0.1 === - First public release. sphinxcontrib_spelling-8.0.2/docs/source/index.rst0000644000000000000000000000175113615410400017325 0ustar00.. spelling:word-list:: sphinxcontrib .. sphinxcontrib.spelling documentation master file, created by sphinx-quickstart on Sun Apr 17 15:33:23 2011. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. ======================== sphinxcontrib.spelling ======================== ``sphinxcontrib.spelling`` is a spelling checker for Sphinx_. It uses PyEnchant_ to produce a report showing misspelled words. Features ======== 1. Supports multiple source languages using the standard enchant dictionaries. 2. Supports project-specific dictionaries for localized jargon and other terminology that may not appear in the global dictionaries. 3. Suggests alternatives to words not found in the dictionary, when possible. Details ======= .. toctree:: :maxdepth: 2 install customize run developers code history .. _PyEnchant: https://github.com/rfk/pyenchant .. _Sphinx: https://www.sphinx-doc.org/ sphinxcontrib_spelling-8.0.2/docs/source/install.rst0000644000000000000000000000074613615410400017667 0ustar00.. spelling:word-list:: sphinxcontrib ============== Installation ============== 1. Install the extension with pip: ``pip install sphinxcontrib-spelling`` 2. Add ``'sphinxcontrib.spelling'`` to the ``extensions`` list in ``conf.py``. .. code-block:: python extensions = [ 'sphinxcontrib.spelling' ] 3. Then pass ``"spelling"`` as the builder argument to ``sphinx-build``. .. code-block:: shell-session $ sphinx-build -b spelling docs/source docs/build sphinxcontrib_spelling-8.0.2/docs/source/run.rst0000644000000000000000000000772513615410400017031 0ustar00========= Running ========= To process a document with the spell checker, use ``sphinx-build`` and specify ``spelling`` as the builder name using the ``-b`` option. The output includes the headings from the document and any misspelled words. If suggestions are enabled, they are shown on the same line as the misspelling. A log of the words in each input file not found in the dictionary is saved to the file ``.spelling`` under the build directory. .. code-block:: console $ tox -e spelling -r spelling create: .../sphinxcontrib-spelling/.tox/spelling spelling installdeps: .[docs] spelling develop-inst: .../sphinxcontrib-spelling spelling installed: -f /Users/dhellmann/.pip/wheelhouse,alabaster==0.7.12,Babel==2.8.0,certifi==2020.6.20,chardet==3.0.4,docutils==0.16,dulwich==0.20.5,idna==2.10,imagesize==1.2.0,importlib-metadata==1.7.0,Jinja2==2.11.2,MarkupSafe==1.1.1,packaging==20.4,pbr==5.4.5,pyenchant==3.1.1,Pygments==2.6.1,pyparsing==2.4.7,pytz==2020.1,PyYAML==5.3.1,reno==3.1.0,requests==2.24.0,six==1.15.0,snowballstemmer==2.0.0,Sphinx==3.2.0,sphinxcontrib-applehelp==1.0.2,sphinxcontrib-devhelp==1.0.2,sphinxcontrib-htmlhelp==1.0.3,sphinxcontrib-jsmath==1.0.1,sphinxcontrib-qthelp==1.0.3,sphinxcontrib-serializinghtml==1.1.4,-e git+git@github.com:sphinx-contrib/spelling.git@b0b3e2a8c935701cfcbbc76ea1aa501a03ae4e22#egg=sphinxcontrib_spelling,urllib3==1.25.10,zipp==3.1.0 spelling run-test-pre: PYTHONHASHSEED='1632297322' spelling run-test: commands[0] | sphinx-build -W -j auto -b spelling -d docs/build/doctrees docs/source docs/build/spelling Running Sphinx v3.2.0 Initializing Spelling Checker 5.2.1.dev2 Ignoring wiki words Ignoring acronyms Adding package names from PyPI to local dictionary… Ignoring Python builtins Ignoring importable module names Adding contents of .../sphinxcontrib-spelling/docs/source/spelling_wordlist.txt to custom word list Adding contents of .../sphinxcontrib-spelling/docs/source/spelling_people.txt to custom word list Looking for custom word list in /var/folders/5q/8gk0wq888xlggz008k8dr7180000hg/T/tmphsetrn0s/spelling_wordlist.txt building [mo]: targets for 0 po files that are out of date building [spelling]: all documents updating environment: [new config] 6 added, 0 changed, 0 removed reading sources... [ 16%] customize reading sources... [ 33%] developers reading sources... [ 50%] history reading sources... [ 66%] index reading sources... [ 83%] install reading sources... [100%] run waiting for workers... scanning .../sphinxcontrib-spelling/releasenotes/notes for current branch release notes got versions ['5.2.0'] looking for now-outdated files... none found pickling environment... done checking consistency... done preparing documents... done writing output... [ 16%] customize Extending local dictionary for customize writing output... [ 33%] developers Extending local dictionary for developers writing output... [ 50%] history Extending local dictionary for history writing output... [ 66%] index Extending local dictionary for index index.rst:17:speel:["Peel", "peel", "spell", "spiel", "Speer", "speed", "steel", "sepal", "spill", "spoil", "spool", "speller", "Pele", "supple", "Perl", "spew", "spree", "suppl", "repel", "spells", "spiels", "spleen", "peal", "seal", "seep", "sell", "Aspell", "Ispell", "sleep", "spell's", "spiel's"]:I can't speel. Writing .../sphinxcontrib-spelling/docs/build/spelling/index.spelling writing output... [ 83%] install Extending local dictionary for install writing output... [100%] run Warning, treated as error: Found 1 misspelled words ERROR: InvocationError for command .../sphinxcontrib-spelling/.tox/spelling/bin/sphinx-build -W -j auto -b spelling -d docs/build/doctrees docs/source docs/build/spelling (exited with code 2) __________________________________________________ summary ___________________________________________________ ERROR: spelling: commands failed sphinxcontrib_spelling-8.0.2/docs/source/spelling_wordlist.txt0000644000000000000000000000020213615410400021757 0ustar00builtins hoc linter linters macOS pypi reStructuredText sphinxcontrib tokenizer txt wikis wordfiles wordlist wordlists domaindata sphinxcontrib_spelling-8.0.2/integration_tests/build_django.py0000755000000000000000000000422713615410400022000 0ustar00#!/usr/bin/env python3 # """Try to build the Django documentation.""" import argparse import os import subprocess import sys import tempfile def doit(*cmd, description="", cwd=None): print(f"\n[{description}]\nrunning: {' '.join(cmd)}") completed = subprocess.run(cmd, cwd=cwd) try: completed.check_returncode() except subprocess.CalledProcessError as err: raise RuntimeError(f"command failed {description}") from err def try_build(workdir, srcdir, django_repo): print(f"working in {workdir}") doit( "git", "clone", "--depth", "1", django_repo, "django", description="clone django", cwd=workdir, ) djangodir = workdir + "/django" doit( "tox", "-e", "docs", "--notest", description="build django docs virtualenv", cwd=djangodir, ) doit( ".tox/docs/bin/pip", "uninstall", "-y", "sphinxcontrib-spelling", description="uninstall packaged sphinxcontrib-spelling", cwd=djangodir, ) doit( ".tox/docs/bin/pip", "install", srcdir, description="install sphinxcontrib-spelling from source", cwd=djangodir, ) doit( "tox", "-e", "docs", description="build django docs", cwd=djangodir, ) def main(args=sys.argv[1:]): parser = argparse.ArgumentParser() parser.add_argument( "--debug", action="store_true", default=False, help="show full tracebacks" ) parser.add_argument("--src", help="source directory") parser.add_argument("--django-repo", default="https://github.com/django/django.git") parsed = parser.parse_args(args) srcdir = parsed.src if not srcdir: srcdir = os.path.realpath(os.path.dirname(os.path.dirname(sys.argv[0]))) try: with tempfile.TemporaryDirectory() as dirname: try_build(dirname, srcdir, parsed.django_repo) except Exception as err: if parsed.debug: raise print(f"ERROR: {err}") return 1 return 0 if __name__ == "__main__": sys.exit(main()) sphinxcontrib_spelling-8.0.2/sphinxcontrib/spelling/__init__.py0000644000000000000000000000570313615410400022055 0ustar00try: # For Python 3.8 and later import importlib.metadata as importlib_metadata except ImportError: # For everyone else import importlib_metadata from sphinx.util import logging from . import asset, builder, directive, domain logger = logging.getLogger(__name__) def setup(app): version = importlib_metadata.version("sphinxcontrib-spelling") logger.info("Initializing Spelling Checker %s", version) app.add_builder(builder.SpellingBuilder) # Register the 'spelling' directive for setting parameters within # a document app.add_directive("spelling", directive.LegacySpellingDirective) app.add_domain(domain.SpellingDomain) # Register an environment collector to merge data gathered by the # directive in parallel builds app.add_env_collector(asset.SpellingCollector) # Report guesses about correct spelling app.add_config_value("spelling_show_suggestions", False, "env") # Limit the number of suggestions output app.add_config_value("spelling_suggestion_limit", 0, "env") # Report the whole line that has the error app.add_config_value("spelling_show_whole_line", True, "env") # Emit misspelling as a sphinx warning instead of info message app.add_config_value("spelling_warning", False, "env") # Set the language for the text app.add_config_value("spelling_lang", "en_US", "env") # Set the language for the tokenizer app.add_config_value("tokenizer_lang", "en_US", "env") # Set a user-provided list of words known to be spelled properly app.add_config_value("spelling_word_list_filename", None, "env") # Assume anything that looks like a PyPI package name is spelled properly app.add_config_value("spelling_ignore_pypi_package_names", False, "env") # Assume words that look like wiki page names are spelled properly app.add_config_value("spelling_ignore_wiki_words", True, "env") # Assume words that are all caps, or all caps with trailing s, are # spelled properly app.add_config_value("spelling_ignore_acronyms", True, "env") # Assume words that are part of __builtins__ are spelled properly app.add_config_value("spelling_ignore_python_builtins", True, "env") # Assume words that look like the names of importable modules are # spelled properly app.add_config_value("spelling_ignore_importable_modules", True, "env") # Treat contributor names from git history as spelled correctly app.add_config_value("spelling_ignore_contributor_names", True, "env") # Add any user-defined filter classes app.add_config_value("spelling_filters", [], "env") # Set a user-provided list of files to ignore app.add_config_value("spelling_exclude_patterns", [], "env") # Choose whether or not the misspelled output should be displayed # in the terminal app.add_config_value("spelling_verbose", True, "env") return { "parallel_read_safe": True, "parallel_write_safe": True, "version": version, } sphinxcontrib_spelling-8.0.2/sphinxcontrib/spelling/asset.py0000644000000000000000000000163513615410400021435 0ustar00# # Copyright (c) 2020 Doug Hellmann. All rights reserved. # """Asset collector for additional spelling terms.""" import collections import contextlib from sphinx.environment.collectors import EnvironmentCollector from sphinx.util import logging logger = logging.getLogger(__name__) class SpellingCollector(EnvironmentCollector): def clear_doc(self, app, env, docname) -> None: with contextlib.suppress(AttributeError, KeyError): del env.spelling_document_words[docname] def merge_other(self, app, env, docnames, other): try: other_words = other.spelling_document_words except AttributeError: other_words = {} if not hasattr(env, "spelling_document_words"): env.spelling_document_words = collections.defaultdict(list) env.spelling_document_words.update(other_words) def process_doc(self, app, doctree): pass sphinxcontrib_spelling-8.0.2/sphinxcontrib/spelling/builder.py0000644000000000000000000002424013615410400021741 0ustar00# # Copyright (c) 2010 Doug Hellmann. All rights reserved. # """Spelling checker extension for Sphinx.""" import collections import importlib import os import tempfile import docutils.nodes import docutils.utils from sphinx.builders import Builder from sphinx.util import logging, osutil from sphinx.util.console import red from sphinx.util.matching import Matcher from sphinx.util.osutil import ensuredir try: from enchant.tokenize import EmailFilter, WikiWordFilter except ImportError as imp_exc: enchant_import_error = imp_exc else: enchant_import_error = None from . import checker, filters logger = logging.getLogger(__name__) # TODO - Words with multiple uppercase letters treated as classes and ignored class SpellingBuilder(Builder): """ Spell checks a document """ name = "spelling" def init(self): if enchant_import_error is not None: raise RuntimeError( "Cannot initialize spelling builder without PyEnchant installed" ) from enchant_import_error self.misspelling_count = 0 self.env.settings["smart_quotes"] = False # Initialize the per-document filters if not hasattr(self.env, "spelling_document_words"): self.env.spelling_document_words = collections.defaultdict(list) # Initialize the global filters f = [ filters.ContractionFilter, EmailFilter, ] if self.config.spelling_ignore_wiki_words: logger.info("Ignoring wiki words") f.append(WikiWordFilter) if self.config.spelling_ignore_acronyms: logger.info("Ignoring acronyms") f.append(filters.AcronymFilter) if self.config.spelling_ignore_pypi_package_names: logger.info("Adding package names from PyPI to local dictionary…") f.append(filters.PyPIFilterFactory()) if self.config.spelling_ignore_python_builtins: logger.info("Ignoring Python builtins") f.append(filters.PythonBuiltinsFilter) if self.config.spelling_ignore_importable_modules: logger.info("Ignoring importable module names") f.append(filters.ImportableModuleFilter) if self.config.spelling_ignore_contributor_names: logger.info("Ignoring contributor names") f.append(filters.ContributorFilter) f.extend(self._load_filter_classes(self.config.spelling_filters)) if not os.path.isdir(self.outdir): os.mkdir(self.outdir) word_list = self.get_wordlist_filename() logger.info("Looking for custom word list in %s", word_list) self.checker = checker.SpellingChecker( lang=self.config.spelling_lang, tokenizer_lang=self.config.tokenizer_lang, suggest=self.config.spelling_show_suggestions, word_list_filename=word_list, filters=f, context_line=self.config.spelling_show_whole_line, ) def _load_filter_classes(self, filters): # Filters may be expressed in the configuration file using # names, so look through them and import the referenced class # and use that in the checker. for filter_ in filters: if not isinstance(filter_, str): yield filter_ continue module_name, _, class_name = filter_.rpartition(".") mod = importlib.import_module(module_name) yield getattr(mod, class_name) def get_configured_wordlist_filenames(self): "Returns the configured wordlist filenames." word_list = self.config.spelling_word_list_filename if word_list is None: word_list = ["spelling_wordlist.txt"] if isinstance(word_list, str): # Wordlist is a string. Split on comma in case it came # from the command line, via -D, and has multiple values. word_list = word_list.split(",") return [os.path.join(self.srcdir, p) for p in word_list] def get_wordlist_filename(self): "Returns the filename of the wordlist to use when checking content." filenames = self.get_configured_wordlist_filenames() if len(filenames) == 1: return filenames[0] # In case the user has multiple word lists, we combine them # into one large list that we pass on to the checker. return self._build_combined_wordlist() def _build_combined_wordlist(self): # If we have a list, the combined list is the first list plus all words # from the other lists. Otherwise, word_list is assumed to just be a # string. temp_dir = tempfile.mkdtemp() combined_word_list = os.path.join(temp_dir, "spelling_wordlist.txt") with open(combined_word_list, "w", encoding="UTF-8") as outfile: for word_file in self.get_configured_wordlist_filenames(): # Paths are relative long_word_file = os.path.join(self.srcdir, word_file) logger.info("Adding contents of %s to custom word list", long_word_file) with open(long_word_file, encoding="UTF-8") as infile: infile_contents = infile.readlines() outfile.writelines(infile_contents) # Check for newline, and add one if not present if infile_contents and not infile_contents[-1].endswith("\n"): outfile.write("\n") return combined_word_list def get_outdated_docs(self): return "all documents" def prepare_writing(self, docnames): return def get_target_uri(self, docname, typ=None): return "" def get_suggestions_to_show(self, suggestions): if not self.config.spelling_show_suggestions or not suggestions: return [] to_show = suggestions try: n_to_show = int(self.config.spelling_suggestion_limit) except ValueError: n_to_show = 0 if n_to_show > 0: to_show = suggestions[:n_to_show] return to_show def format_suggestions(self, suggestions): to_show = self.get_suggestions_to_show(suggestions) if not to_show: return "" return "[" + ", ".join('"%s"' % s for s in to_show) + "]" TEXT_NODES = { "block_quote", "caption", "paragraph", "list_item", "term", "definition_list_item", "title", } def write_doc(self, docname, doctree): """write the document""" lines = list(self._find_misspellings(docname, doctree)) self.misspelling_count += len(lines) if lines: output_filename = os.path.join(self.outdir, f"{docname}.spelling") logger.info("Writing %s", output_filename) ensuredir(os.path.dirname(output_filename)) with open(output_filename, "w", encoding="UTF-8") as output: output.writelines(lines) def _find_misspellings(self, docname, doctree): excluded = Matcher(self.config.spelling_exclude_patterns) if excluded(self.env.doc2path(docname, None)): return # Build the document-specific word filter based on any good # words listed in spelling directives. If we have no such # words, we want to push an empty list of filters so that we # can always safely pop the filter stack when we are done with # this document. doc_filters = [] good_words = self.env.spelling_document_words.get(docname) if good_words: logger.debug("Extending local dictionary for %s", docname) doc_filters.append(filters.IgnoreWordsFilterFactory(good_words)) self.checker.push_filters(doc_filters) # Set up a filter for the types of nodes to ignore during # traversal. def filter(n): if n.tagname != "#text": return False if n.parent and n.parent.tagname not in self.TEXT_NODES: return False # Nodes marked by the spelling:ignore role if hasattr(n, "spellingIgnore"): return False return True for node in doctree.findall(filter): # Get the location of the text being checked so we can # report it in the output file. Nodes from text that # comes in via an 'include' directive does not include # the full path, so convert all to relative path # for consistency. source, node_lineno = docutils.utils.get_source_line(node) if source is not None: source = osutil.relpath(source) else: # Some nodes (e.g., programmatically generated) may not have # source information. Use a placeholder. source = "" # Check the text of the node. misspellings = self.checker.check(node.astext()) for word, suggestions, context_line, line_offset in misspellings: # Avoid TypeError on nodes lacking a line number # This happens for some node originating from docstrings lineno = node_lineno if lineno is not None: lineno += line_offset msg_parts = [ f"{source}:{lineno}: ", "Spell check", red(word), ] if self.format_suggestions(suggestions) != "": msg_parts.append(self.format_suggestions(suggestions)) msg_parts.append(context_line) msg = ": ".join(msg_parts) + "." if self.config.spelling_warning: logger.warning(msg) elif self.config.spelling_verbose: logger.info(msg) yield "%s:%s: (%s) %s %s\n" % ( source, lineno, word, self.format_suggestions(suggestions), context_line, ) self.checker.pop_filters() return def finish(self): if self.misspelling_count: logger.warning("Found %d misspelled words", self.misspelling_count) sphinxcontrib_spelling-8.0.2/sphinxcontrib/spelling/checker.py0000644000000000000000000000440713615410400021722 0ustar00# # Copyright (c) 2010 Doug Hellmann. All rights reserved. # """Spelling checker extension for Sphinx.""" try: import enchant from enchant.tokenize import get_tokenizer except ImportError as imp_exc: enchant_import_error = imp_exc else: enchant_import_error = None class SpellingChecker: """Checks the spelling of blocks of text. Uses options defined in the sphinx configuration file to control the checking and filtering behavior. """ def __init__( self, lang, suggest, word_list_filename, tokenizer_lang="en_US", filters=None, context_line=False, ): if enchant_import_error is not None: raise RuntimeError( "Cannot instantiate SpellingChecker without PyEnchant installed", ) from enchant_import_error if filters is None: filters = [] self.dictionary = enchant.DictWithPWL(lang, word_list_filename) self.tokenizer = get_tokenizer(tokenizer_lang, filters=filters) self.original_tokenizer = self.tokenizer self.suggest = suggest self.context_line = context_line def push_filters(self, new_filters): """Add a filter to the tokenizer chain.""" t = self.tokenizer for f in new_filters: t = f(t) self.tokenizer = t def pop_filters(self): """Remove the filters pushed during the last call to push_filters().""" self.tokenizer = self.original_tokenizer def check(self, text): """Yields bad words and suggested alternate spellings.""" for word, pos in self.tokenizer(text): correct = self.dictionary.check(word) if correct: continue suggestions = self.dictionary.suggest(word) if self.suggest else [] line = line_of_index(text, pos) if self.context_line else "" line_offset = text.count("\n", 0, pos) yield word, suggestions, line, line_offset def line_of_index(text, index): try: line_start = text.rindex("\n", 0, index) + 1 except ValueError: line_start = 0 try: line_end = text.index("\n", index) except ValueError: line_end = len(text) return text[line_start:line_end] sphinxcontrib_spelling-8.0.2/sphinxcontrib/spelling/directive.py0000644000000000000000000000260013615410400022265 0ustar00# # Copyright (c) 2010 Doug Hellmann. All rights reserved. # """Spelling checker extension for Sphinx.""" import collections from docutils.parsers import rst from sphinx.util import logging logger = logging.getLogger(__name__) def add_good_words_to_document(env, docname, good_words): # Initialize the per-document good words list if not hasattr(env, "spelling_document_words"): env.spelling_document_words = collections.defaultdict(list) logger.debug("Extending local dictionary for %s with %s", env.docname, good_words) env.spelling_document_words[env.docname].extend(good_words) class SpellingDirective(rst.Directive): """Custom directive for passing instructions to the spelling checker. .. spelling:: word1 word2 """ has_content = True def run(self): env = self.state.document.settings.env good_words = [] for entry in self.content: if not entry: continue good_words.extend(entry.split()) if good_words: add_good_words_to_document(env, env.docname, good_words) return [] class LegacySpellingDirective(SpellingDirective): def run(self): logger.info( "direct use of the spelling directive is deprecated, " 'replace ".. spelling::" with ".. spelling:word-list::"' ) return super().run() sphinxcontrib_spelling-8.0.2/sphinxcontrib/spelling/domain.py0000644000000000000000000000122013615410400021553 0ustar00from sphinx.domains import Domain from . import directive, role class SpellingDomain(Domain): name = "spelling" label = "Spelling Checker" directives = { "word-list": directive.SpellingDirective, } roles = {"word": role.spelling_word, "ignore": role.spelling_ignore} def get_objects(self): return [] def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode): """resolve cross reference""" return None def resolve_any_xref(self, env, fromdocname, builder, target, node, contnode): return [] def merge_domaindata(self, docnames, otherdata): pass sphinxcontrib_spelling-8.0.2/sphinxcontrib/spelling/filters.py0000644000000000000000000002037313615410400021766 0ustar00# # Copyright (c) 2010 Doug Hellmann. All rights reserved. # """Spelling checker extension for Sphinx.""" # TODO - Words with multiple uppercase letters treated as classes and ignored import builtins import importlib import subprocess import sys import requests from enchant.tokenize import Filter, get_tokenizer, tokenize, unit_tokenize from sphinx.util import logging logger = logging.getLogger(__name__) class AcronymFilter(Filter): """If a word looks like an acronym (all upper case letters), ignore it. """ def _skip(self, word): return ( word.isupper() # all caps or # pluralized acronym ("URLs") (word[-1].lower() == "s" and word[:-1].isupper()) ) class list_tokenize(tokenize): def __init__(self, words): super().__init__("") self._words = words def next(self): if not self._words: raise StopIteration() word = self._words.pop(0) return (word, 0) class ContractionFilter(Filter): """Strip common contractions from words.""" splits = { "aren't": ["are", "not"], "can't": ["can", "not"], "could've": ["could", "have"], "couldn't": ["could", "not"], "didn't": ["did", "not"], "doesn't": ["does", "not"], "don't": ["do", "not"], "hadn't": ["had", "not"], "hasn't": ["has", "not"], "haven't": ["have", "not"], "he'd": ["he", "would"], "he'll": ["he", "will"], "he's": ["he", "is"], "how'd": ["how", "would"], "how'll": ["how", "will"], "how's": ["how", "is"], "i'd": ["I", "would"], "i'll": ["I", "will"], "i'm": ["I", "am"], "i've": ["I", "have"], "isn't": ["is", "not"], "it'd": ["it", "would"], "it'll": ["it", "will"], "it's": ["it", "is"], "ma'am": ["madam"], "might've": ["might", "have"], "mightn't": ["might", "not"], "must've": ["must", "have"], "mustn't": ["must", "not"], "o'": ["of"], "o'clock": ["of", "the", "clock"], "she'd": ["she", "would"], "she'll": ["she", "will"], "she's": ["she", "is"], "should've": ["should", "have"], "shouldn't": ["should", "not"], "that'd": ["that", "would"], "that'll": ["that", "will"], "that's": ["that", "is"], "they'd": ["they", "would"], "they'll": ["they", "will"], "they're": ["they", "are"], "they've": ["they", "have"], "wasn't": ["was", "not"], "we'd": ["we", "would"], "we'll": ["we", "will"], "we're": ["we", "are"], "we've": ["we", "have"], "weren't": ["were", "not"], "what'd": ["what", "would"], "what'll": ["what", "will"], "what're": ["what", "are"], "what's": ["what", "is"], "when'd": ["when", "would"], "when'll": ["when", "will"], "when's": ["when", "is"], "where'd": ["where", "would"], "where'll": ["where", "will"], "where's": ["where", "is"], "who'd": ["who", "would"], "who'll": ["who", "will"], "who's": ["who", "is"], "why'd": ["why", "would"], "why'll": ["why", "will"], "why's": ["why", "is"], "won't": ["will", "not"], "would've": ["would", "have"], "wouldn't": ["would", "not"], "you'd": ["you", "would"], "you'll": ["you", "will"], "you're": ["you", "are"], "you've": ["you", "have"], } def _split(self, word): # Fixed responses if word.lower() in self.splits: return list_tokenize(self.splits[word.lower()]) # Possessive if word.lower().endswith("'s"): return unit_tokenize(word[:-2]) # * not if word.lower().endswith("n't"): return unit_tokenize(word[:-3]) return unit_tokenize(word) class IgnoreWordsFilter(Filter): """Given a set of words, ignore them all.""" def __init__(self, tokenizer, word_set): self.word_set = set(word_set) super().__init__(tokenizer) def _skip(self, word): return word in self.word_set class IgnoreWordsFilterFactory: def __init__(self, words): self.words = words def __call__(self, tokenizer): return IgnoreWordsFilter(tokenizer, self.words) class PyPIFilterFactory(IgnoreWordsFilterFactory): """Build an IgnoreWordsFilter for all of the names of packages on PyPI.""" def __init__(self): r = requests.get( "https://pypi.org/simple/", headers={ "user-agent": "sphinxcontrib.spelling", "accept": "application/vnd.pypi.simple.v1+json", }, ) names = [i["name"] for i in r.json()["projects"]] logger.debug("retrieved %d project names from pypi.org", len(names)) super().__init__(names) class PythonBuiltinsFilter(Filter): """Ignore names of built-in Python symbols.""" def _skip(self, word): return hasattr(builtins, word) class ImportableModuleFilter(Filter): """Ignore names of modules that we could import.""" def __init__(self, tokenizer): super().__init__(tokenizer) self.found_modules = set(sys.builtin_module_names) self.sought_modules = self.found_modules.copy() # By adding __main__ to the list of sought modules but not # found modules we ensure that it is never recognized as a # valid module, which is consistent with the behavior before # version 7.3.1. See # https://github.com/sphinx-contrib/spelling/issues/141 self.sought_modules.add("__main__") def _skip(self, word): # If the word looks like a python module filename, strip the # extension to avoid the side-effect of actually importing the # module. This prevents, for example, 'setup.py' triggering an # import of the setup module during a doc build, which makes # it look like Sphinx is complaining about a commandline # argument. See # https://github.com/sphinx-contrib/spelling/issues/142 if word.endswith(".py"): logger.debug( "removing .py extension from %r before searching for module", word ) word = word[:-3] valid_module_name = all(n.isidentifier() for n in word.split(".")) if not valid_module_name: return False if word not in self.sought_modules: self.sought_modules.add(word) try: mod = importlib.util.find_spec(word) except BaseException as err: # This could be an ImportError, SystemExit, some more detailed # error out of distutils, or something else triggered # by failing to be able to import a parent package to # use the metadata to search for a subpackage. logger.debug("find_spec(%r) failed, invalid module name: %s", word, err) else: if mod is not None: self.found_modules.add(word) return word in self.found_modules class ContributorFilter(IgnoreWordsFilter): """Accept information about contributors as spelled correctly. Look in the git history for authors and committers and accept tokens that are in the set. """ _pretty_format = "%(trailers:key=Co-Authored-By,separator=%x0A)%x0A%an%x0A%cn" def __init__(self, tokenizer): contributors = self._get_contributors() super().__init__(tokenizer, contributors) def _get_contributors(self): logger.info("Scanning contributors") cmd = [ "git", "log", "--quiet", "--no-color", f"--pretty=format:{self._pretty_format}", ] try: p = subprocess.run(cmd, check=True, stdout=subprocess.PIPE) except (subprocess.CalledProcessError, FileNotFoundError) as err: logger.warning("Called: %s", " ".join(cmd)) logger.warning("Failed to scan contributors: %s", err) return set() output = p.stdout.decode("utf-8") tokenizer = get_tokenizer("en_US", filters=[]) return {word for word, pos in tokenizer(output)} sphinxcontrib_spelling-8.0.2/sphinxcontrib/spelling/role.py0000644000000000000000000000124013615410400021247 0ustar00from docutils import nodes from . import directive def spelling_word(role, rawtext, text, lineno, inliner, options={}, content=[]): """Let the user indicate that inline text is spelled correctly.""" env = inliner.document.settings.env docname = env.docname good_words = text.split() directive.add_good_words_to_document(env, docname, good_words) node = nodes.Text(text) return [node], [] def spelling_ignore(role, rawtext, text, lineno, inliner, options={}, content=[]): """Let the user indicate that inline text is to not be spellchecked.""" node = nodes.Text(text) setattr(node, "spellingIgnore", True) return [node], [] sphinxcontrib_spelling-8.0.2/sphinxcontrib/spelling/version.py0000644000000000000000000000130013615410400021770 0ustar00# file generated by setuptools-scm # don't change, don't track in version control __all__ = [ "__version__", "__version_tuple__", "version", "version_tuple", "__commit_id__", "commit_id", ] TYPE_CHECKING = False if TYPE_CHECKING: from typing import Tuple from typing import Union VERSION_TUPLE = Tuple[Union[int, str], ...] COMMIT_ID = Union[str, None] else: VERSION_TUPLE = object COMMIT_ID = object version: str __version__: str __version_tuple__: VERSION_TUPLE version_tuple: VERSION_TUPLE commit_id: COMMIT_ID __commit_id__: COMMIT_ID __version__ = version = '8.0.2' __version_tuple__ = version_tuple = (8, 0, 2) __commit_id__ = commit_id = None sphinxcontrib_spelling-8.0.2/tests/helpers.py0000644000000000000000000000032613615410400016407 0ustar00#!/usr/bin/env python3 import os import pathlib import pytest def require_git_repo(f): return pytest.mark.skipif( not (pathlib.Path(os.getcwd()) / ".git").is_dir(), reason="Not a git repo" )(f) sphinxcontrib_spelling-8.0.2/tests/test_builder.py0000644000000000000000000004061513615410400017437 0ustar00# # Copyright (c) 2010 Doug Hellmann. All rights reserved. # """Tests for SpellingBuilder""" import contextlib import io import os import sys import textwrap import pytest from sphinx.application import Sphinx from tests import helpers # isort:skip def _make_sphinx_project(tmpdir): srcdir = tmpdir.mkdir("src") outdir = tmpdir.mkdir("out") add_file( srcdir, "conf.py", """ extensions = [ 'sphinxcontrib.spelling' ] """, ) return (srcdir, outdir) @pytest.fixture def sphinx_project(tmpdir): yield _make_sphinx_project(tmpdir) @contextlib.contextmanager def working_dir(targetdir): "Temporarily change the working directory of the process." before = os.getcwd() os.chdir(targetdir) try: yield os.getcwd() finally: os.chdir(before) @contextlib.contextmanager def import_path(new_path): "Temporarily change sys.path for imports." before = sys.path try: sys.path = new_path yield finally: sys.path = before def add_file(thedir, filename, content): with open(thedir.join(filename), "w") as f: f.write(textwrap.dedent(content)) def get_sphinx_app(srcdir, outdir, docname, builder="spelling"): stdout = io.StringIO() stderr = io.StringIO() app = Sphinx( srcdir, srcdir, outdir, outdir, builder, status=stdout, warning=stderr, freshenv=True, ) return (stdout, stderr, app) def get_sphinx_output(srcdir, outdir, docname, builder="spelling"): stdout, stderr, app = get_sphinx_app(srcdir, outdir, docname, builder) app.build() path = os.path.join(outdir, f"{docname}.spelling") try: with open(path, "r") as f: output_text = f.read() except FileNotFoundError: output_text = None return (stdout, stderr, output_text) def test_setup(sphinx_project): srcdir, outdir = sphinx_project stdout = io.StringIO() stderr = io.StringIO() # If the spelling builder is not properly initialized, # trying to use it with the Sphinx app class will # generate an exception. Sphinx( str(srcdir), str(srcdir), str(outdir), str(outdir), "spelling", status=stdout, warning=stderr, freshenv=True, ) def test_title(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ Welcome to Speeling Checker documentation! ========================================== """, ) stdout, stderr, output_text = get_sphinx_output(srcdir, outdir, "contents") assert "(Speeling)" in output_text def test_body(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ Welcome to Spelling Checker documentation! ========================================== There are several mispelled words in this txt. """, ) stdout, stderr, output_text = get_sphinx_output(srcdir, outdir, "contents") assert "(mispelled)" in output_text assert "(txt)" in output_text def test_ignore_literals(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ Welcome to Spelling Checker documentation! ========================================== There are several misspelled words in this text. :: Literal blocks are ignoreed. Inline ``litterals`` are ignored, too. """, ) stdout, stderr, output_text = get_sphinx_output(srcdir, outdir, "contents") # The 'contents.spelling' output file should not have been # created, because the errors are ignored. assert output_text is None def test_several_word_lists(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "conf.py", """ extensions = ['sphinxcontrib.spelling'] spelling_word_list_filename=['test_wordlist.txt','test_wordlist2.txt'] """, ) add_file( srcdir, "contents.rst", """ Welcome to Spelling Checker documentation! ========================================== There are several mispelled words in tihs txt. """, ) add_file( srcdir, "test_wordlist.txt", """ txt """, ) add_file( srcdir, "test_wordlist2.txt", """ mispelled """, ) stdout, stderr, output_text = get_sphinx_output(srcdir, outdir, "contents") # Both of these should be fine now assert "(mispelled)" not in output_text assert "(txt)" not in output_text # But not this one assert "(tihs)" in output_text def _wordlist_sphinx_project(tmpdir, conf_contents): srcdir, outdir = _make_sphinx_project(tmpdir) add_file(srcdir, "conf.py", conf_contents) add_file( srcdir, "test_wordlist.txt", """ txt """, ) add_file( srcdir, "test_wordlist2.txt", """ mispelled """, ) stdout, stderr, app = get_sphinx_app(srcdir, outdir, "contents") return (srcdir, outdir, stdout, stderr, app) def test_word_list_default(tmpdir): srcdir, outdir, stdout, stderr, app = _wordlist_sphinx_project( tmpdir, """ extensions = ['sphinxcontrib.spelling'] """, ) results = app.builder.get_configured_wordlist_filenames() assert len(results) == 1 assert os.path.basename(results[0]) == "spelling_wordlist.txt" def test_one_word_list_str(tmpdir): srcdir, outdir, stdout, stderr, app = _wordlist_sphinx_project( tmpdir, """ extensions = ['sphinxcontrib.spelling'] spelling_word_list_filename='test_wordlist.txt' """, ) results = app.builder.get_configured_wordlist_filenames() assert len(results) == 1 assert os.path.basename(results[0]) == "test_wordlist.txt" def test_multiple_word_list_str(tmpdir): # We don't expect anyone to set up their conf.py this way but it # simulates passing the configuration option from the command line # using -D. srcdir, outdir, stdout, stderr, app = _wordlist_sphinx_project( tmpdir, """ extensions = ['sphinxcontrib.spelling'] spelling_word_list_filename='test_wordlist.txt,test_wordlist2.txt' """, ) results = app.builder.get_configured_wordlist_filenames() assert len(results) == 2 assert os.path.basename(results[0]) == "test_wordlist.txt" assert os.path.basename(results[1]) == "test_wordlist2.txt" def test_multiple_word_list_list(tmpdir): srcdir, outdir, stdout, stderr, app = _wordlist_sphinx_project( tmpdir, """ extensions = ['sphinxcontrib.spelling'] spelling_word_list_filename=['test_wordlist.txt', 'test_wordlist2.txt'] """, ) results = app.builder.get_configured_wordlist_filenames() assert len(results) == 2 assert os.path.basename(results[0]) == "test_wordlist.txt" assert os.path.basename(results[1]) == "test_wordlist2.txt" def test_ignore_file(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "conf.py", """ extensions = ['sphinxcontrib.spelling'] spelling_exclude_patterns=['con*'] """, ) add_file( srcdir, "contents.rst", """ Welcome to Speeling Checker documentation! ========================================== """, ) stdout, stderr, output_text = get_sphinx_output(srcdir, outdir, "contents") # The 'contents.spelling' output file should not have been # created, because the file is ignored. assert output_text is None @helpers.require_git_repo def test_docstrings(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "conf.py", """ extensions = ['sphinxcontrib.spelling', 'sphinx.ext.autodoc'] """, ) add_file( srcdir / "..", "the_source.py", ''' #!/usr/bin/env python3 def public_function(arg_name): """Does something useful. :param arg_name: Pass a vaule """ return 1 ''', ) add_file( srcdir, "contents.rst", """ The Module ========== .. automodule:: the_source :members: """, ) with working_dir(srcdir / ".."): with import_path(["."] + sys.path): stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", ) expected = "src/contents.rst:3: (vaule) Pass a vaule\n" assert expected in output_text def test_get_suggestions_to_show_all(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "conf.py", """ extensions = ['sphinxcontrib.spelling'] spelling_show_suggestions = True spelling_suggestion_limit = 0 """, ) stdout, stderr, app = get_sphinx_app(srcdir, outdir, "contents") results = app.builder.get_suggestions_to_show(["a", "b", "c"]) assert len(results) == 3 def test_get_suggestions_to_show_limit(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "conf.py", """ extensions = ['sphinxcontrib.spelling'] spelling_show_suggestions = True spelling_suggestion_limit = 1 """, ) stdout, stderr, app = get_sphinx_app(srcdir, outdir, "contents") results = app.builder.get_suggestions_to_show(["a", "b", "c"]) assert len(results) == 1 def test_get_suggestions_to_show_disabled(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "conf.py", """ extensions = ['sphinxcontrib.spelling'] spelling_show_suggestions = False spelling_suggestion_limit = 0 """, ) stdout, stderr, app = get_sphinx_app(srcdir, outdir, "contents") results = app.builder.get_suggestions_to_show(["a", "b", "c"]) assert len(results) == 0 def test_captions(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ The Module ========== .. figure:: blah.gif Teh caption """, ) stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", ) assert "(Teh)" in output_text def test_legacy_directive(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ The Module ========== .. spelling:: teh teh is OK """, ) stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", ) assert output_text is None def test_domain_directive(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ The Module ========== .. spelling:word-list:: teh teh is OK """, ) stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", ) assert output_text is None def test_domain_role(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ The Module ========== :spelling:word:`teh` is OK """, ) stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", ) assert output_text is None def test_domain_role_multiple_words(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ The Module ========== :spelling:word:`teh is KO` """, ) stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", ) assert output_text is None def test_domain_role_output(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ The Module ========== :spelling:word:`teh` is OK """, ) stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", "text", ) path = os.path.join(outdir, "contents.txt") try: with open(path, "r") as f: output_text = f.read() except FileNotFoundError: output_text = None assert output_text == "The Module\n**********\n\nteh is OK\n" def test_domain_ignore(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ The Module ========== :spelling:ignore:`baddddd` is OK """, ) stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", ) assert output_text is None def test_domain_ignore_multiple_words(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ The Module ========== :spelling:ignore:`baddddd` is OK here. But, baddddd is not OK here. Nor, here baddddd. """, ) stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", ) assert "(baddddd)" in output_text assert output_text.count("\n") == 2 # Only expect 2 errors, not 3. def test_domain_ignore_output(sphinx_project): srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ The Module ========== :spelling:ignore:`teh` is OK """, ) stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", "text", ) path = os.path.join(outdir, "contents.txt") try: with open(path, "r") as f: output_text = f.read() except FileNotFoundError: output_text = None assert output_text == "The Module\n**********\n\nteh is OK\n" def test_only_directive(sphinx_project): # How to skip checking nested blocks of content # https://github.com/sphinx-contrib/spelling/issues/204 srcdir, outdir = sphinx_project add_file( srcdir, "contents.rst", """ The Module ========== .. only:: html teh is ok whaat is not ok """, ) stdout, stderr, output_text = get_sphinx_output( srcdir, outdir, "contents", ) assert "(whaat)" in output_text assert "(teh)" not in output_text def test_nodes_with_none_source(sphinx_project): # Reproduces https://github.com/sphinx-contrib/spelling/issues/234 # Tests handling of nodes where get_source_line returns None for source srcdir, outdir = sphinx_project # Create an extension that patches docutils.utils.get_source_line to return None # This directly simulates the bug condition add_file( srcdir, "mock_none_source.py", """ import docutils.utils # Store the original function _original_get_source_line = docutils.utils.get_source_line def patched_get_source_line(node): '''Return None for source to simulate issue #234''' # Call original to get line number source, lineno = _original_get_source_line(node) # But return None for source to trigger the bug return (None, lineno) def setup(app): # Patch the function when building def on_build_finished(app, exception): # Restore original after build docutils.utils.get_source_line = _original_get_source_line # Patch before doctree-read def on_doctree_read(app, doctree): docutils.utils.get_source_line = patched_get_source_line app.connect('doctree-read', on_doctree_read, priority=1) app.connect('build-finished', on_build_finished) return {'version': '0.1'} """, ) add_file( srcdir, "conf.py", f""" import sys sys.path.insert(0, r'{srcdir}') extensions = ['sphinxcontrib.spelling', 'mock_none_source'] """, ) add_file( srcdir, "contents.rst", """ Test Document ============= This text has a mispeling that should be caught. """, ) # Without the fix, this will crash with: # TypeError: expected str, bytes or os.PathLike object, not NoneType # With the fix, it should handle None gracefully and produce output stdout, stderr, output_text = get_sphinx_output(srcdir, outdir, "contents") # The spelling check should still work and find the misspelling assert output_text is not None assert "(mispeling)" in output_text sphinxcontrib_spelling-8.0.2/tests/test_checker.py0000644000000000000000000000452313615410400017413 0ustar00# # Copyright (c) 2010 Doug Hellmann. All rights reserved. # """Tests for SpellingChecker.""" import os from sphinxcontrib.spelling.checker import SpellingChecker, line_of_index def test_errors_only(): checker = SpellingChecker( lang="en_US", suggest=False, word_list_filename=None, ) for word, suggestions, line, offset in checker.check("This txt is wrong"): assert not suggestions, "Suggesting" assert word == "txt" assert line == "" assert offset == 0 def test_with_suggestions(): checker = SpellingChecker( lang="en_US", suggest=True, word_list_filename=None, ) for word, suggestions, line, offset in checker.check("This txt is wrong"): assert suggestions, "Not suggesting" assert word == "txt" assert line == "" assert offset == 0 def test_with_wordlist(): checker = SpellingChecker( lang="en_US", suggest=False, word_list_filename=os.path.join(os.path.dirname(__file__), "test_wordlist.txt"), ) words = [ word for word, suggestions, line, offset in checker.check("This txt is wrong") ] assert not words, "Did not use personal word list file" def test_with_context_line(): checker = SpellingChecker( lang="en_US", suggest=False, word_list_filename=None, context_line=True, ) text = "Line one\nThis txt is wrong\nLine two" for word, suggestions, line, offset in checker.check(text): assert not suggestions, "Suggesting" assert word == "txt" assert line == "This txt is wrong" assert offset == 1 def test_line_of_index_one_line(): text = "foo bar baz" assert line_of_index(text, 0) == text assert line_of_index(text, 5) == text assert line_of_index(text, len(text)) == text def test_line_of_index_multi_line(): text = "\nfoo\n\nbar baz\n" assert line_of_index(text, 0) == "" assert line_of_index(text, 1) == "foo" assert line_of_index(text, 2) == "foo" assert line_of_index(text, 3) == "foo" assert line_of_index(text, 4) == "foo" assert line_of_index(text, 5) == "" assert line_of_index(text, 6) == "bar baz" assert line_of_index(text, 12) == "bar baz" assert line_of_index(text, 13) == "bar baz" assert line_of_index(text, 14) == "" sphinxcontrib_spelling-8.0.2/tests/test_filter.py0000644000000000000000000000733713615410400017302 0ustar00# # Copyright (c) 2010 Doug Hellmann. All rights reserved. # """Tests for filters.""" import contextlib import logging import os import sys import pytest from enchant.tokenize import get_tokenizer from sphinxcontrib.spelling import filters # isort:skip from tests import helpers # isort:skip # Replace the sphinx logger with a normal one so pytest can collect # the output. filters.logger = logging.getLogger("test.filters") def test_builtin_unicode(): f = filters.PythonBuiltinsFilter(None) assert not f._skip("passé") def test_builtin_regular(): f = filters.PythonBuiltinsFilter(None) assert f._skip("print") def test_acronym(): text = "a front-end for DBM-style databases" t = get_tokenizer("en_US", []) f = filters.AcronymFilter(t) words = [w[0] for w in f(text)] assert "DBM" not in words, "Failed to filter out acronym" def test_acronym_unicode(): text = "a front-end for DBM-style databases" t = get_tokenizer("en_US", []) f = filters.AcronymFilter(t) words = [w[0] for w in f(text)] assert "DBM" not in words, "Failed to filter out acronym" @helpers.require_git_repo @pytest.mark.parametrize( "name", [ "Alex", "Atlakson", "Avram", "Baumgold", "Berman", "Daniele", "Doug", "Finucane", "Gaynor", "Gonsiorowski", "Hong", "Hong", "Huon", "Kampik", "Kolosov", "Lubkin", "Marti", "Minhee", "Olausson", "Raggam", "Raudsepp", "sdelliot", "Sergey", "Sevilla", "Timotheus", "Tobias", "Tricoli", ], ) def test_contributors(name): f = filters.ContributorFilter(None) assert f._skip(name) @pytest.mark.parametrize( "word,expected", [ ("os", True), ("os.name", False), ("__main__", False), ("don't", False), ], ) def test_importable_module_skip(word, expected): f = filters.ImportableModuleFilter(None) assert f._skip(word) is expected @contextlib.contextmanager def import_path(new_path): "Temporarily change sys.path for imports." before = sys.path try: sys.path = new_path yield finally: sys.path = before def test_importable_module_with_side_effets(tmpdir): logging.debug("tmpdir %r", tmpdir) logging.debug("cwd %r", os.getcwd()) parentdir = tmpdir.join("parent") parentdir.mkdir() parentdir.join("__init__.py").write('raise SystemExit("exit as side-effect")\n') parentdir.join("child.py").write("") with import_path([str(tmpdir)] + sys.path): f = filters.ImportableModuleFilter(None) skip_parent = f._skip("parent") skip_both = f._skip("parent.child") # The parent module name is valid because it is not imported, only # discovered. assert skip_parent is True assert "parent" in f.found_modules # The child module name is not valid because the parent is # imported to find the child and that triggers the side-effect. assert skip_both is False assert "parent.child" not in f.found_modules def test_importable_module_with_system_exit(tmpdir): path = tmpdir.join("mytestmodule.py") path.write('raise SystemExit("exit as side-effect")\n') with import_path([str(tmpdir)] + sys.path): f = filters.ImportableModuleFilter(None) skip = f._skip("mytestmodule") # The filter does not actually import the module in this case, so # it shows up as a valid word. assert skip is True assert "mytestmodule" in f.found_modules def test_pypi_filter_factory(): f = filters.PyPIFilterFactory() assert "sphinxcontrib-spelling" in f.words assert "setuptools" in f.words sphinxcontrib_spelling-8.0.2/tests/test_wordlist.txt0000644000000000000000000000000413615410400020033 0ustar00txt sphinxcontrib_spelling-8.0.2/tools/history-update.sh0000755000000000000000000000071513615410400017713 0ustar00#!/usr/bin/env bash set -x git remote -v git branch -a # We only look at the files that have changed in the current PR, to # avoid problems when the template is changed in a way that is # incompatible with existing documents. if git log --name-only --pretty= "origin/main.." -- \ | grep -q '^docs/source/history.rst$'; then echo "Found a change to history file." exit 0 fi echo "PRs must include a change in docs/source/history.rst" exit 1 sphinxcontrib_spelling-8.0.2/.gitignore0000644000000000000000000000042413615410400015220 0ustar00*.pyc *.egg *.so build/ dist/ env/ *.egg-info/ TAGS *~ .DS_Store .idea .vscode spelling/spelling_wordlist.txt .tox/ .coverage/ *.swp # Created by pbr AUTHORS ChangeLog /.coverage /.testrepository/ /cover/ .eggs/ # Generated by setuptools_scm sphinxcontrib/spelling/version.pysphinxcontrib_spelling-8.0.2/LICENSE0000644000000000000000000000242213615410400014235 0ustar00Copyright (c) 2010 by Doug Hellmann. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sphinxcontrib_spelling-8.0.2/README.rst0000644000000000000000000000262013615410400014717 0ustar00.. -*- mode: rst -*- ========================= sphinxcontrib-spelling ========================= This package contains sphinxcontrib.spelling, a spelling checker for Sphinx-based documentation. It uses PyEnchant_ to produce a report showing misspelled words. Refer to the `main documentation page `__ for installation and setup details. License ======= Copyright Doug Hellmann, All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Doug Hellmann not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DOUG HELLMANN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .. _PyEnchant: https://github.com/pyenchant/pyenchant sphinxcontrib_spelling-8.0.2/pyproject.toml0000644000000000000000000000566613615410400016161 0ustar00[build-system] requires = ["hatchling", "hatch-vcs"] build-backend = "hatchling.build" [project] name = "sphinxcontrib-spelling" readme = "README.rst" authors = [{ name = "Doug Hellmann", email = "doug@doughellmann.com" }] description = "Sphinx spelling extension" dynamic = ["version"] classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Environment :: Web Environment", "Framework :: Sphinx :: Extension", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Documentation", "Topic :: Utilities", ] requires-python = ">=3.10" dependencies = ["PyEnchant>=3.1.1", "Sphinx>=3.0.0", "requests>=2.32.3"] [project.optional-dependencies] test = ["pytest", "pytest-cov", "coverage!=4.4,>=4.0"] [project.entry-points."sphinx.builders"] spelling = "sphinxcontrib.spelling" [project.urls] homepage = "https://sphinxcontrib-spelling.readthedocs.io/en/latest/" repository = "https://github.com/sphinx-contrib/spelling" [tool.hatch.version] source = "vcs" [tool.hatch.build.hooks.vcs] version-file = "sphinxcontrib/spelling/version.py" [tool.hatch.build.targets.sdist] exclude = [".github", "cover", ".mergify.yml", ".gitignore"] [tool.hatch.build.targets.wheel] only-include = ["sphinxcontrib"] [tool.hatch.envs.docs] dependencies = ["sphinx"] [tool.hatch.envs.docs.env] ENABLE_SPELLING = "1" [tool.hatch.envs.docs.scripts] build = [ "sphinx-build -W -j auto -b html -d docs/build/doctrees docs/source docs/build/html", "sphinx-build -W -j auto -b spelling -d docs/build/doctrees docs/source docs/build/spelling", ] check = "sphinx-build -W -j auto -b spelling -d docs/build/doctrees docs/source docs/build/spelling" [tool.hatch.envs.test] dependencies = [ "pytest", "pytest-cov", "coverage!=4.4,>=4.0", "ruff", "twine", "check-python-versions", ] [tool.hatch.envs.test.scripts] test = "python -m pytest --cov=sphinxcontrib.spelling --cov-report term-missing --log-level DEBUG tests" lint = [ "ruff check sphinxcontrib integration_tests tests", "ruff format --check sphinxcontrib integration_tests tests", ] lint-fix = ["ruff format sphinxcontrib integration_tests tests"] pkglint = [ "hatch build", "twine check dist/*.tar.gz dist/*.whl", "check-python-versions --only pyproject.toml,.github/workflows/test.yml", ] [tool.hatch.envs.integration] dependencies = ["tox"] [tool.hatch.envs.integration.scripts] django = "./integration_tests/build_django.py" [tool.ruff] exclude = ["sphinxcontrib/spelling/version.py"] sphinxcontrib_spelling-8.0.2/PKG-INFO0000644000000000000000000000546313615410400014335 0ustar00Metadata-Version: 2.4 Name: sphinxcontrib-spelling Version: 8.0.2 Summary: Sphinx spelling extension Project-URL: homepage, https://sphinxcontrib-spelling.readthedocs.io/en/latest/ Project-URL: repository, https://github.com/sphinx-contrib/spelling Author-email: Doug Hellmann License-File: LICENSE Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: Environment :: Web Environment Classifier: Framework :: Sphinx :: Extension Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3 :: Only Classifier: Programming Language :: Python :: 3.10 Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: 3.13 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Topic :: Documentation Classifier: Topic :: Utilities Requires-Python: >=3.10 Requires-Dist: pyenchant>=3.1.1 Requires-Dist: requests>=2.32.3 Requires-Dist: sphinx>=3.0.0 Provides-Extra: test Requires-Dist: coverage!=4.4,>=4.0; extra == 'test' Requires-Dist: pytest; extra == 'test' Requires-Dist: pytest-cov; extra == 'test' Description-Content-Type: text/x-rst .. -*- mode: rst -*- ========================= sphinxcontrib-spelling ========================= This package contains sphinxcontrib.spelling, a spelling checker for Sphinx-based documentation. It uses PyEnchant_ to produce a report showing misspelled words. Refer to the `main documentation page `__ for installation and setup details. License ======= Copyright Doug Hellmann, All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Doug Hellmann not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DOUG HELLMANN BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .. _PyEnchant: https://github.com/pyenchant/pyenchant