{"id":16589009,"url":"https://github.com/lyubomirt/lesp","last_synced_at":"2025-10-29T09:31:36.184Z","repository":{"id":209313225,"uuid":"723472704","full_name":"LyubomirT/lesp","owner":"LyubomirT","description":"📚 LESP is a lightweight, efficient spelling proofreader written in Python. It's designed to be easy to use and lightweight, while still providing a decent result when checking for spelling errors. Resource consumption is kept to a minimum, and the program is designed to be as fast as possible.","archived":false,"fork":false,"pushed_at":"2023-12-07T15:31:22.000Z","size":1200,"stargazers_count":9,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-14T06:18:46.749Z","etag":null,"topics":["collaborate","cross-platform","easy-to-use","github","lightweight","plug-and-play","spellcheck","student-vscode"],"latest_commit_sha":null,"homepage":"https://lesp.gitbook.io/lesp","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LyubomirT.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-11-25T19:23:48.000Z","updated_at":"2024-09-25T06:08:40.000Z","dependencies_parsed_at":"2023-12-01T20:32:32.569Z","dependency_job_id":"8ba07314-a262-4f49-92a5-e3b045a2b0d5","html_url":"https://github.com/LyubomirT/lesp","commit_stats":null,"previous_names":["lyubomirt/lesp"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LyubomirT%2Flesp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LyubomirT%2Flesp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LyubomirT%2Flesp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LyubomirT%2Flesp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LyubomirT","download_url":"https://codeload.github.com/LyubomirT/lesp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238791981,"owners_count":19531031,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["collaborate","cross-platform","easy-to-use","github","lightweight","plug-and-play","spellcheck","student-vscode"],"created_at":"2024-10-11T23:07:28.733Z","updated_at":"2025-10-29T09:31:35.478Z","avatar_url":"https://github.com/LyubomirT.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003ch1\u003eLESP - Lightweight Efficient Spelling Proofreader\u003c/h1\u003e\n\u003cimg src=\"branding/BANNER.png\"\u003e\n\u003c/div\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/Version-1.1.1-gold.svg\" alt=\"version\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/License-BSD%203--Clause-blue.svg\" alt=\"license\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/Python-3.6+-green.svg\" alt=\"python\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/Platform-Linux%20%7C%20Windows%20%7C%20macOS-lightgrey.svg\" alt=\"platform\"\u003e\n\u003c!-- No dependencies --\u003e\n\u003cimg src=\"https://img.shields.io/badge/Dependencies-none-red.svg\" alt=\"dependencies\"\u003e\n\u003c/div\u003e\n\n## Welcome to the LESP repository! 👋\n\nLESP is a lightweight, efficient spelling proofreader written in Python. It's designed to be easy to use and lightweight, while still providing a decent result when checking for spelling errors. Resource consumption is kept to a minimum, and the program is designed to be as fast as possible.\n\n## Features ✨\n\n- Lightweight and efficient\n- Easy to use\n- Fast\n- Cross-platform\n- No dependencies\n- (Kind of) Customizable\n\n## Installation 📥\n\nSimply clone the repository and run the `demo.py` file to check it out. You don't need to install any additional libraries, so this is like plug-and-play. Just note that anything below Python 3.6 won't run this since old versions don't support `concurrent.futures`, which is used to speed up the process.\n\n## ...or install it with `pip` 📥\n\n```bash\npip install lesp\n```\n\n### Detailed installation instructions for Git\n\n1. Clone the repository\n\n```bash\ngit clone https://github.com/LyubomirT/lesp.git\n```\n\n2. Open the folder\n\n```bash\ncd lesp\n```\n\n3. Run the demo\n\n```bash\npython demo.py\n```\n\n## Usage 📖\n\nLESP is pretty easy to setup, and basic demo configuration is already pre-built. You can find it in `demo_config` (this is a file, not a folder!) and you can edit it to your liking. Note that the file is **required** for the demo to run, so don't delete, move, or rename it. Not required for installing it with `pip` though.\n\nIf you want to take a closer look at how to use LESP, you can check out our [documentation](https://lesp.gitbook.io/lesp). There we have a detailed explanation of how to use LESP, along with some examples. If you're still not sure how to use LESP, you can check out the `examples` folder. It contains some examples of how you can use LESP in your projects. These examples are pretty simple, but they should give you an idea of how you can use LESP in your projects.\n\n### Basic usage\n\nTo use LESP, you need to import the `Proofreader` class from the `lesp` module. The class has a decent amount of functions, but the most important ones are `is_correct` and `get_similar`. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\nclearlynotcorrect = proofreader.is_correct(\"apgle\") # False\n\nif not clearlynotcorrect:\n    print(\"Did you mean: \" + proofreader.get_similar(\"apgle\")) # Did you mean: apple\n```\n\nSimple as that!\n\n### Advanced usage\n\nBy default, `Proofreader` will use the `lesp-wordlist.txt` file as the wordlist.\n\nYou can use a different wordlist by specifying the path to it in the `wordlist` argument, when initializing the `Proofreader` class.\n\nA wordlist must be structured with each word on a new line, like this:\n\n```\napple\nbanana\norange\n```\n\nWhen finished with writing your wordlist, save it as a `.txt` file. Then, you can use it like this:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n```\n\nYou can customize the process of getting similar words as well. Configuration will be provided as arguments to the `get_similar` function. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n\nsimilar_words = proofreader.get_similar(\"apgle\", similarity_rate=0.5, chunks=4, upto=3)\n\nprint(similar_words)\n```\n\nIn the code above, we're getting similar words to `apgle` with a similarity rate of 0.5, splitting the wordlist into 4 chunks, and returning up to 3 similar words. \n\nA similarity rate of `0.5` means that the words returned will be at least 50% similar to the word we're checking. The higher the similarity rate, the more precise the results will be, but generally there will be less words. Myself I would recommend to keep the similarity rate at `0.5`, but you can experiment with it and see what works best for you.\n\nThe `chunks` argument specifies how many chunks the wordlist will be split into. This is useful if you have a large wordlist and you want to speed up the process. The higher the number, the faster the process will be, but the more memory/CPU it will consume. For example, when trying to scan `wordlist.txt` with 1500 chunks, the process takes about 0.5 seconds on my machine, but it consumes about 1.5 GB of RAM and 44% of one of the CPU cores. If you have a large wordlist.\n\nThe `upto` argument specifies how many similar words will be returned. If you set it to `3`, then the function will return up to 3 similar words. If you set it to `1`, then it will return up to 1 similar word. But, whatever amount you select, the output will still be a list. If you set it to `0`, then the function will raise a `ValueError`.\n\n### Get similarity score\n\nEven if this function isn't really supposed to be a feature, you can still use it if you want to. It's pretty simple to use, just use the `get_similarity_score` function of the `Proofreader` class and pass the two words you want to compare as arguments. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n\nscore = proofreader.get_similarity_score(\"apple\", \"apgle\") # 0.8\n\nprint(score)\n```\n\nThe function will return a float between 0 and 1, where 0 means that the words are completely different, and 1 means that the words are exactly the same.\n\n### Backup\n\nIf you're concerned about losing your wordlist, you can use the `backup` function to backup your wordlist. It will create a file in the path you specify, and it will write the wordlist in it. Note that the file will be overwritten if it already exists. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n\nproofreader.backup(\"my_wordlist_backup.txt\") # Leave empty to use default path\n```\n\n### Restore\n\nIf you've backed up your wordlist, you can restore it using the `restore` function. It will read the file you specify and it will overwrite the current wordlist with the one in the file. Note that the file must exist, otherwise the function will raise a `FileNotFoundError`. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n\nproofreader.restore(True, \"my_wordlist_backup.txt\") # Leave empty to use default path\n```\n\nTrue here stands for `overridecurrent`, which lets you choose whether you want the wordlist file to be overwritten or not. If you set it to `False`, then the function will leave your current wordlist file untouched, and will just modify the wordlist variable in the current session. If you set it to `True`, then the function will overwrite the wordlist file with the one in the backup file along with the wordlist variable in the current session.\n\n### Extend wordlist\n\nThis is useful if the user usually writes about a specific, non-general topic. For example, if the user is a programmer, you can extend the wordlist with programming-related words if one is not found in the wordlist already. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n\nif not proofreader.is_correct(\"reactjs\") and proofreader.get_similar(\"reactjs\") is None:\n    confirm = input(\"reactjs is not in the wordlist. Would you like to add it? (y/n) \")\n    if confirm.lower() == \"y\":\n        proofreader.backup()\n        proofreader.extend_wordlist(\"reactjs\")\n        print(\"reactjs added to wordlist.\")\n    else:\n        pass\n```\n\nYou can also extend the wordlist with multiple words at once by passing a list or a tuple to the function. Like this:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n\nwords = [\"reactjs\", \"vuejs\", \"angularjs\"]\n\nproofreader.extend_wordlist(words)\n```\n\n### Remove from wordlist\n\nAn opposite of the `extend_wordlist` function, this function removes a word from the wordlist. Note that this function will raise a `ValueError` if the word is not in the wordlist. Also note that this function will not remove the word from the wordlist permanently, it will only remove it for the current session. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n\nword = \"reactjs\"\nproofreader.remove_from_wordlist(word)\n```\n\nIf you want to remove multiple words at once, you can pass a list or a tuple to the function. Like this:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n\nwords = [\"reactjs\", \"vuejs\", \"angularjs\"]\n\nproofreader.remove_from_wordlist(words)\n```\n\n### Stacking\n\nThis function lets you stack two wordlist files together, so you can have a bigger wordlist out of two combined. The function will take two arguments, the source file and the destination file. The source file is the file that will be stacked on top of the destination file. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader.stack(\"wordlist.txt\", \"my_wordlist.txt\")\n```\n\n### Merge delete\n\nThis function lets you delete all words from the destination file that are in the source file. For example, if you have a wordlist with the following words:\n\n```\napple\nbanana\norange\n```\n\nAnd you have another wordlist with the following words:\n\n```\napple\nbanana\nraspberry\n```\n\nThen, if you use the `merge_delete` function, the destination file will be modified to look like this:\n\n```\norange\nraspberry\n```\n\nHere's an example of how you can use it:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n\nproofreader.merge_delete(\"wordlist.txt\", \"my_wordlist.txt\")\n\nwith open(\"my_wordlist.txt\", \"r\") as f:\n    print(f.read())\n```\n\n### Caching\n\nTo improve the perfomance of LESP, `get_similar` uses a cache file to store similar words. This way, if you check the same word multiple times, it will be much faster. The default cache file is `lesp_cache/lesp.cache`, but you can change it by specifying the `cache_file` argument when initializing the `Proofreader` class. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\", cache_file=\"my_cache.cache\")\n```\n\nCache works only for mistakes that have been made at least once. For example, if you check the word `apgle` and it returns `apple`, then the next time you check `apgle`, it will be much faster. This can save a lot of time and resources, especially if the user makes a lot of mistakes.\n\nIf you want to clear the cache, you can use the `clear_cache` function. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\", cache_file=\"my_cache.cache\")\n\nproofreader.clear_cache()\n```\n\nThis will delete the cache file and clear the cache variable in the current session. Note that the file will be deleted permanently, so make sure you have a backup if you want to keep it.\n\nTo use the cache, you need to specify the `use_cache` (or `set_cache` if you want it to be modified) argument when calling the `get_similar` function. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\", cache_file=\"my_cache.cache\")\n\nsimilar_words = proofreader.get_similar(\"apgle\", similarity_rate=0.5, chunks=4, upto=3, use_cache=True, set_cache=True) # Takes about 0.18 seconds on my machine\nsimilar_words2 = proofreader.get_similar(\"apgle\", similarity_rate=0.5, chunks=4, upto=3, use_cache=True, set_cache=True) # Works almost instantly thanks to cache\n```\n\nHere, `use_cache` is responsible for using the loaded cache file (if it exists) and `set_cache` helps you to add a new mistake to cache. If you set `set_cache` to `True`, then the function will add the mistake to cache, so the next time you check the same word, it will be much faster with `use_cache` enabled.\n\n### Removing Special Characters\n\nSometimes, a string may contain special characters, such as `!`, `?`, `@`, etc. These characters can be removed using the `remove_special` method. It covers most of the special characters out there, but not all of them. So if you find a special character that is not covered, please open an issue and I'll add it. Here's an example:\n\n```python\nfrom lesp.autocorrect import Proofreader\n\nproofreader = Proofreader(wordlist_path=\"my_wordlist.txt\")\n\nword = \"apgle!\"\nword = proofreader.remove_special(word) # apgle\n\nif not proofreader.is_correct(word): # Not correct, of course\n    print(\"Did you mean: \" + proofreader.get_similar(word)) # Did you mean: apple\n```\n\n## Examples 📝\n\nIf you're still not sure where to use LESP, you can check out the `examples` folder. It contains some examples of how you can use LESP in your projects. These examples are pretty simple, but they should give you an idea of how you can use LESP in your projects.\n\n### How to run an example?\n\nSimply open the folder of the example you want to run, then copy the `main.py` file to the root of the directory (same as `demo.py`, for instance). After that, run the `main.py` file and voila! The application is running!\n\n## Contributing 🤝\n\nContributions, issues and feature requests are welcome! Feel free to check out the [issues page](https://github.com/LyubomirT/lesp/issues).\n\n### How to contribute?\n\nThank you for your interest in contributing to LESP! Here's a quick guide on how to contribute:\n\n1. Fork the repository\n\n```bash\ngit clone https://github.com/LyubomirT/lesp.git\n```\n\n2. Make your changes\n\n3. Test your changes to make sure everything works as expected\n\n4. Commit your changes\n\n```bash\ngit commit -m \"Your changes\"\n```\n\n5. Push your changes\n\n```bash\ngit push\n```\n\n6. Open a pull request\n\n7. Wait for your pull request to be reviewed\n\nOnce again, thank you for your support!\n\n## Reach out to the developer 👨‍💻\n\nYou can contact me on Discord either in my [Discord Server](https://discord.gg/XkjPDcSfNz) or in my DMs (@lyubomirt). Creating a discussion might also work, but I'm a bit faster to respond on Discord.\n\n## License 📜\n\nThis project is licensed under the BSD 3-Clause License. For more information, please refer to the `LICENSE` file.\n\n## Acknowledgements 🙏\n\nMany thanks to the following Open-Source projects:\n\n- [Google 10000 English](https://github.com/first20hours/google-10000-english) - `small_wordlist.txt`\n- [English Word List](https://github.com/dwyl/english-words) - `wordlist.txt`\n\n## Our Amazing Contributors ✨\n\nThanks to these awesome people for contributing! I appreciate your support a lot! ❤️\n\n[![Contributors](https://contrib.rocks/image?repo=lyubomirt/lesp)](https://github.com/lyubomirt/lesp/graphs/contributors)\n\n(Note that due to a glitch, some contributors may not appear in the grid)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flyubomirt%2Flesp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flyubomirt%2Flesp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flyubomirt%2Flesp/lists"}