52 | ```
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | # This workflow will install Python dependencies, run tests and lint with a single version of Python
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3 |
4 | name: Test
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 | strategy:
16 | matrix:
17 | python-version: ["3.12", "3.11", "3.10", 3.9, 3.8]
18 | steps:
19 | - uses: actions/checkout@v2
20 | - name: Set up Python ${{ matrix.python-version }}
21 | uses: actions/setup-python@v2
22 | with:
23 | python-version: ${{ matrix.python-version }}
24 | - name: Install dependencies
25 | run: |
26 | python -m pip install --upgrade pip
27 | pip install flake8 pytest pytest-codeblocks
28 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
29 | - name: Set PYTHONPATH
30 | run: |
31 | echo "PYTHONPATH=$PWD" >> $GITHUB_ENV
32 | - name: Lint with flake8
33 | run: |
34 | # stop the build if there are Python syntax errors or undefined names
35 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
36 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
37 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
38 | - name: Test with pytest
39 | run: |
40 | pytest --codeblocks
41 | - name: Build docs
42 | run: |
43 | pip install mkdocs-material
44 | pip install mdx-include
45 | pip install mkdocstrings[python]
46 | mkdocs build
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '45 16 * * 2'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'python' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
37 | # Learn more:
38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
39 |
40 | steps:
41 | - name: Checkout repository
42 | uses: actions/checkout@v2
43 |
44 | # Initializes the CodeQL tools for scanning.
45 | - name: Initialize CodeQL
46 | uses: github/codeql-action/init@v1
47 | with:
48 | languages: ${{ matrix.language }}
49 | # If you wish to specify custom queries, you can do so here or in a config file.
50 | # By default, queries listed here will override any specified in a config file.
51 | # Prefix the list here with "+" to use these queries and those in the config file.
52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
53 |
54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
55 | # If this step fails, then you should remove it and run the build manually (see below)
56 | - name: Autobuild
57 | uses: github/codeql-action/autobuild@v1
58 |
59 | # ℹ️ Command-line programs to run using the OS shell.
60 | # 📚 https://git.io/JvXDl
61 |
62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
63 | # and modify them (or add more) to build your code if your project
64 | # uses a compiled language
65 |
66 | #- run: |
67 | # make bootstrap
68 | # make release
69 |
70 | - name: Perform CodeQL Analysis
71 | uses: github/codeql-action/analyze@v1
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | share/python-wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 | MANIFEST
28 |
29 | # PyInstaller
30 | # Usually these files are written by a python script from a template
31 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
32 | *.manifest
33 | *.spec
34 |
35 | # Installer logs
36 | pip-log.txt
37 | pip-delete-this-directory.txt
38 |
39 | # Unit test / coverage reports
40 | htmlcov/
41 | .tox/
42 | .nox/
43 | .coverage
44 | .coverage.*
45 | .cache
46 | nosetests.xml
47 | coverage.xml
48 | *.cover
49 | *.py,cover
50 | .hypothesis/
51 | .pytest_cache/
52 | cover/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | .pybuilder/
76 | target/
77 |
78 | # Jupyter Notebook
79 | .ipynb_checkpoints
80 |
81 | # IPython
82 | profile_default/
83 | ipython_config.py
84 |
85 | # pyenv
86 | # For a library or package, you might want to ignore these files since the code is
87 | # intended to run in multiple environments; otherwise, check them in:
88 | # .python-version
89 |
90 | # pipenv
91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
94 | # install all needed dependencies.
95 | #Pipfile.lock
96 |
97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
98 | __pypackages__/
99 |
100 | # Celery stuff
101 | celerybeat-schedule
102 | celerybeat.pid
103 |
104 | # SageMath parsed files
105 | *.sage.py
106 |
107 | # Environments
108 | .env
109 | .venv
110 | env/
111 | venv/
112 | ENV/
113 | env.bak/
114 | venv.bak/
115 |
116 | # Spyder project settings
117 | .spyderproject
118 | .spyproject
119 |
120 | # Rope project settings
121 | .ropeproject
122 |
123 | # mkdocs documentation
124 | /site
125 |
126 | # mypy
127 | .mypy_cache/
128 | .dmypy.json
129 | dmypy.json
130 |
131 | # Pyre type checker
132 | .pyre/
133 |
134 | # pytype static type analyzer
135 | .pytype/
136 |
137 | # Cython debug symbols
138 | cython_debug/
139 |
140 | #PyCharm
141 | .idea
--------------------------------------------------------------------------------
/hebrew/numerical_conversion/convert.py:
--------------------------------------------------------------------------------
1 | from typing import Optional, Callable, Tuple
2 |
3 | from hebrew.numerical_conversion.substitute import Substitutions
4 | from hebrew.numerical_conversion.mappings import (
5 | HEBREW_LETTER_TO_VALUE_MAPPINGS,
6 | STANDARD_HEBREW_LETTERS_VALUES_REVERSED,
7 | )
8 |
9 |
10 | def number_to_hebrew_string(
11 | number: int,
12 | punctuate: bool = True,
13 | geresh: bool = True,
14 | substitution_functions: Optional[
15 | Tuple[Callable[[str], str], ...]
16 | ] = Substitutions.DEFAULT,
17 | ) -> str:
18 | """
19 | Convert a number into its Hebrew letter form.
20 |
21 | :param number: The number to convert to Hebrew letters. Must be greater than 0.
22 | :param punctuate: Whether to add punctuation in the appropriate places.
23 | :param geresh: If punctuate is true, whether to use the unicode geresh or an apostrophe.
24 | :param substitution_functions: A tuple of functions that replaces some hebrew values in the result with an
25 | appropriate equivalent. By default, "יה" and "יו" are replaced with "טו" and "טז" respectively. To replace all
26 | values such as שמד ,רע, and others, use `Substitutions.ALL`.
27 | :return:
28 | """
29 | # Handle 0
30 | if number < 1:
31 | raise ValueError("Number must be greater than 0")
32 |
33 | reversed_result = ""
34 |
35 | # Prepare the numbers
36 | ones_value = _ones_column_value(number)
37 | if ones_value > 0:
38 | reversed_result += HEBREW_LETTER_TO_VALUE_MAPPINGS[ones_value]
39 | tens_value = _tens_column_value(number)
40 | if tens_value > 0:
41 | reversed_result += HEBREW_LETTER_TO_VALUE_MAPPINGS[tens_value]
42 | hundreds_value = _hundreds_and_above_column_value(number)
43 | if hundreds_value > 0:
44 | reversed_result += _hundreds_to_letters(hundreds_value)
45 |
46 | # Reverse the string
47 | result = reversed_result[::-1]
48 |
49 | # Substitute flags
50 | if substitution_functions:
51 | for func in substitution_functions:
52 | result = func(result)
53 |
54 | # Add Punctuation
55 | if punctuate:
56 | if len(result) > 1:
57 | punctuation = "״" if geresh else '"'
58 | result = result[:-1] + punctuation + result[-1]
59 | else:
60 | punctuation = "׳" if geresh else "'"
61 | result += punctuation
62 |
63 | return result
64 |
65 |
66 | def _ones_column_value(number: int):
67 | """
68 | Return the value of the ones column of a number.
69 | """
70 | return number % 10
71 |
72 |
73 | def _tens_column_value(number: int):
74 | """
75 | Return the value of the tens column of a number.
76 | """
77 | if number < 10:
78 | return 0
79 | return ((number % 100) // 10) * 10
80 |
81 |
82 | def _hundreds_and_above_column_value(number: int):
83 | """
84 | Returns the value of all columns of a number above the ten's column.
85 | """
86 | return (number // 100) * 100
87 |
88 |
89 | def _hundreds_to_letters(number: int) -> str:
90 | """
91 | Given a single digit number over 0 and a power of ten, return the Hebrew letters that represent that number.
92 |
93 | :param number: The digit to convert to Hebrew letters.
94 | :return: The Hebrew letters that represent the number.
95 | """
96 |
97 | # Check if the number maps directly to a letter
98 | if number in HEBREW_LETTER_TO_VALUE_MAPPINGS:
99 | return HEBREW_LETTER_TO_VALUE_MAPPINGS[number]
100 | else:
101 | # Get the largest letter and value that is less or equal to the number
102 | max_letter_value = next(
103 | i for i in STANDARD_HEBREW_LETTERS_VALUES_REVERSED if i <= number
104 | )
105 | max_letter = HEBREW_LETTER_TO_VALUE_MAPPINGS[max_letter_value]
106 |
107 | # Calculate the number of times the letter goes into the number
108 | letter_count, remainder = divmod(number, max_letter_value)
109 |
110 | # If the remainder is 0, we can just return the letter times the letter count
111 | if remainder == 0:
112 | return max_letter * letter_count
113 | else:
114 | # Otherwise we need to further break down the remainder
115 | remainder_letters = _hundreds_to_letters(remainder)
116 | return remainder_letters + max_letter * letter_count
117 |
--------------------------------------------------------------------------------
/tests/test_grapheme_string.py:
--------------------------------------------------------------------------------
1 | from collections.abc import Hashable
2 |
3 | import pytest
4 |
5 | from hebrew import GraphemeString
6 |
7 |
8 | @pytest.fixture
9 | def hebrew_grapheme_string():
10 | return GraphemeString(
11 | "וְהָאָ֗רֶץ הָיְתָ֥ה תֹ֙הוּ֙ וָבֹ֔הוּ וְחֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַמָּֽיִם"
12 | )
13 |
14 |
15 | @pytest.fixture
16 | def hebrew_no_nikkud():
17 | return "והארץ היתה תהו ובהו וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים"
18 |
19 |
20 | def test_graphemes(hebrew_grapheme_string):
21 | graphemes = hebrew_grapheme_string.graphemes
22 | assert hasattr(graphemes, "__iter__")
23 | assert list(hebrew_grapheme_string.graphemes) == [
24 | "וְ",
25 | "הָ",
26 | "אָ֗",
27 | "רֶ",
28 | "ץ",
29 | " ",
30 | "הָ",
31 | "יְ",
32 | "תָ֥",
33 | "ה",
34 | " ",
35 | "תֹ֙",
36 | "ה",
37 | "וּ֙",
38 | " ",
39 | "וָ",
40 | "בֹ֔",
41 | "ה",
42 | "וּ",
43 | " ",
44 | "וְ",
45 | "חֹ֖",
46 | "שֶׁ",
47 | "ךְ",
48 | " ",
49 | "עַ",
50 | "ל",
51 | "־",
52 | "פְּ",
53 | "נֵ֣",
54 | "י",
55 | " ",
56 | "תְ",
57 | "ה֑",
58 | "וֹ",
59 | "ם",
60 | " ",
61 | "וְ",
62 | "ר֣",
63 | "וּ",
64 | "חַ",
65 | " ",
66 | "אֱ",
67 | "לֹ",
68 | "הִ֔",
69 | "י",
70 | "ם",
71 | " ",
72 | "מְ",
73 | "רַ",
74 | "חֶ֖",
75 | "פֶ",
76 | "ת",
77 | " ",
78 | "עַ",
79 | "ל",
80 | "־",
81 | "פְּ",
82 | "נֵ֥",
83 | "י",
84 | " ",
85 | "הַ",
86 | "מָּֽ",
87 | "יִ",
88 | "ם",
89 | ]
90 |
91 |
92 | def test_length(hebrew_grapheme_string, hebrew_no_nikkud):
93 | assert hebrew_grapheme_string.length == len(hebrew_no_nikkud)
94 |
95 |
96 | def test_get_length(hebrew_grapheme_string):
97 | assert hebrew_grapheme_string.get_length(5) == 5
98 |
99 |
100 | def test_grapheme_lengths(hebrew_grapheme_string):
101 | graphemes_length = hebrew_grapheme_string.grapheme_lengths
102 | assert hasattr(graphemes_length, "__iter__")
103 | assert list(graphemes_length) == [
104 | 2,
105 | 2,
106 | 3,
107 | 2,
108 | 1,
109 | 1,
110 | 2,
111 | 2,
112 | 3,
113 | 1,
114 | 1,
115 | 3,
116 | 1,
117 | 3,
118 | 1,
119 | 2,
120 | 3,
121 | 1,
122 | 2,
123 | 1,
124 | 2,
125 | 3,
126 | 3,
127 | 2,
128 | 1,
129 | 2,
130 | 1,
131 | 1,
132 | 3,
133 | 3,
134 | 1,
135 | 1,
136 | 2,
137 | 2,
138 | 2,
139 | 1,
140 | 1,
141 | 2,
142 | 2,
143 | 2,
144 | 2,
145 | 1,
146 | 2,
147 | 2,
148 | 3,
149 | 1,
150 | 1,
151 | 1,
152 | 2,
153 | 2,
154 | 3,
155 | 2,
156 | 1,
157 | 1,
158 | 2,
159 | 1,
160 | 1,
161 | 3,
162 | 3,
163 | 1,
164 | 1,
165 | 2,
166 | 4,
167 | 2,
168 | 1,
169 | ]
170 |
171 |
172 | def test_slice(hebrew_grapheme_string):
173 | assert hebrew_grapheme_string.slice(start=0, end=5) == "וְהָאָ֗רֶץ"
174 | assert hebrew_grapheme_string.slice(start=6, end=10) == "הָיְתָ֥ה"
175 |
176 |
177 | def test_contains(hebrew_grapheme_string):
178 | assert "ו" in str(hebrew_grapheme_string) # Assert that test case is valid
179 | assert not hebrew_grapheme_string.contains("ו")
180 |
181 |
182 | def test_safe_split_index(hebrew_grapheme_string):
183 | assert hebrew_grapheme_string.safe_split_index(12) == 11
184 |
185 |
186 | def test_startswith(hebrew_grapheme_string):
187 | assert hebrew_grapheme_string.string.startswith(
188 | "ו"
189 | ) # Assert that test case is valid
190 | assert not hebrew_grapheme_string.startswith("ו")
191 |
192 |
193 | def test_endswith():
194 | assert GraphemeString("וְ").string.endswith("ְ") # Assert that test case is valid
195 | assert not GraphemeString("וְ").endswith("ְ")
196 |
197 |
198 | def test_string_repr(hebrew_grapheme_string):
199 | assert isinstance(hebrew_grapheme_string.string, str)
200 | assert hebrew_grapheme_string.__str__() == hebrew_grapheme_string.string
201 | assert hebrew_grapheme_string.__repr__() == hebrew_grapheme_string.string
202 |
203 |
204 | def test_add():
205 | full = GraphemeString(
206 | "והארץ היתה תהו ובהו וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים"
207 | )
208 | start = GraphemeString("והארץ היתה תהו ובהו")
209 | end = GraphemeString("וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים")
210 | new = start + " " + end
211 | assert new.string == full.string
212 |
213 |
214 | def test_equality():
215 | one = GraphemeString(
216 | "והארץ היתה תהו ובהו וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים"
217 | )
218 | two = GraphemeString(
219 | "והארץ היתה תהו ובהו וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים"
220 | )
221 | assert one == two
222 |
223 |
224 | def test_equality_unequal_type():
225 | one = GraphemeString(
226 | "והארץ היתה תהו ובהו וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים"
227 | )
228 | two = GraphemeString(
229 | "והארץ היתה תהו ובהו וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים"
230 | )
231 | assert one != str(two)
232 |
233 |
234 | def test_not_equality():
235 | one = GraphemeString(
236 | "והארץ היתה תהו ובהו וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים"
237 | )
238 | two = GraphemeString("והארץ")
239 | assert one != two
240 |
241 |
242 | def test_hashable():
243 | one = GraphemeString(
244 | "והארץ היתה תהו ובהו וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים"
245 | )
246 | two = GraphemeString(
247 | "והארץ היתה תהו ובהו וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים"
248 | )
249 | assert isinstance(one, Hashable)
250 | assert one.__hash__() == two.__hash__()
251 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
6 | to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [0.8.1] - 2023-12-11
9 |
10 | ### Fixed
11 |
12 | - Corrected an issue with subclasses of `BaseHebrewChar` where use of `__eq__` would break when the type for the
13 | comparison was not the same as itself.
14 |
15 | ## [0.8.0] - 2023-12-10
16 |
17 | ### Added
18 |
19 | - Added `Hebrew.normalize`, a function for normalizing the hebrew characters in a string. This is typically needed with
20 | text includes special hebrew characters.
21 |
22 | Hidden among hebrew text can be special characters that are visually identical humans, but are made up of different
23 | unicode characters. However, this can cause issues with presentation when there is no support for these characters.
24 |
25 | 
26 |
27 | In this case, the first letter is made up of 2 unicode characters, [sin with a dot](https://en.wiktionary.org/wiki/%D7%A9%D7%82)
28 | and [qamatz](https://en.wiktionary.org/wiki/%D6%B8). The issue here is the sin. By normalizing the sin with a dot to 2 unicode
29 | characters, [ש](https://en.wiktionary.org/wiki/%D7%A9) and the [dot](https://en.wiktionary.org/wiki/%D7%82), the display
30 | will look right!
31 |
32 | 
33 |
34 | To normalize content, use the `Hebrew.normalize` function:
35 | ```python
36 | from hebrew import Hebrew
37 |
38 | hs = Hebrew('שָׂחַקְתִּי כְּמוֹ')
39 |
40 | assert len(hs.string) == 14
41 | assert len(hs.normalize().string) == 18
42 | ```
43 |
44 | ### Normalizing Yiddish
45 |
46 | By default, special yiddish characters such as [ײ](https://en.wiktionary.org/wiki/%D7%B2) (double Yod) are _not_ normalized.
47 | However, [ײַ](https://en.wiktionary.org/wiki/%EF%AC%9F) (double Yod with a Patah) will be converted to [ײַ](https://en.wiktionary.org/wiki/%D7%B2%D6%B7).
48 |
49 | To fully "normalize" yiddish characters, pass `True` to `normalize`.
50 |
51 |
52 | ## [0.7.0] - 2023-12-10
53 |
54 | ### Added
55 |
56 | - New function `Hebrew.from_number` converts an int into its hebrew form
57 |
58 | ### Example:
59 |
60 | ``` python
61 | from hebrew import Hebrew
62 |
63 | hs1 = Hebrew.from_number(2)
64 | print(hs1) # ב׳
65 |
66 | # Do not add punctuation
67 | hs2 = Hebrew.from_number(2, geresh=False)
68 | print(hs2) # ב
69 | ```
70 |
71 | ## [0.6.2] - 2023-12-08
72 |
73 | ### Changed
74 |
75 | - Added 3.12 as a supported version
76 | - Updated project dependencies.
77 |
78 | ### Removed
79 | - Removed 3.11 as a supported version
80 |
81 | ## [0.6.1] - 2022-10-28
82 |
83 | ### Changed
84 |
85 | - Added 3.11 as a supported version
86 |
87 | ## [0.6.0] - 2022-04-19
88 |
89 | ### Added
90 |
91 | - Added the remaining missing Gematria methods. The complete list of supported methods is:
92 | - `ACHAS_BETA`
93 | - `ALBAM`
94 | - `ATBASH`
95 | - `AVGAD`
96 | - `AYAK_BACHAR`
97 | - `MISPAR_BONEEH`
98 | - `MISPAR_GADOL`
99 | - `MISPAR_HAACHOR`
100 | - `MISPAR_HAMERUBAH_HAKLALI`
101 | - `MISPAR_HECHRACHI`
102 | - `MISPAR_KATAN`
103 | - `MISPAR_KATAN_MISPARI`
104 | - `MISPAR_KIDMI`
105 | - `MISPAR_KOLEL`
106 | - `MISPAR_MESHULASH`
107 | - `MISPAR_MISPARI`
108 | - `MISPAR_MUSAFI`
109 | - `MISPAR_NEELAM`
110 | - `MISPAR_PERATI`
111 | - `MISPAR_SHEMI_MILUI`
112 | - `MISPAR_SIDURI`
113 | - `OFANIM`
114 | - `REVERSE_AVGAD`
115 |
116 | ### Example:
117 | ```python
118 | from hebrew import Hebrew
119 | from hebrew import GematriaTypes
120 |
121 | hs = Hebrew('בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ׃')
122 |
123 | print(hs.gematria()) # 2701
124 | print(hs.gematria(GematriaTypes.MISPAR_GADOL)) # 4631
125 | ```
126 |
127 | ## [0.5.8] - 2022-04-18
128 |
129 | ### Added
130 |
131 | - Added Gematria methods `MISPAR_MUSAFI`. This is the first of the complex Gematria types that goes deeper than just
132 | adding up values assigned to each letter, necessitating internal changes to the `Hebrew` class.
133 |
134 | ## [0.5.7] - 2022-04-18
135 |
136 | ### Added
137 |
138 | - Added Gematria methods `MISPAR_KATAN`, `MISPAR_PERATI`, `ATBASH`, `ALBAM`, `MISPAR_MESHULASH`.
139 |
140 | ## [0.5.6] - 2022-04-18
141 |
142 | ### Added
143 |
144 | - Added a new gematria method, `MISPAR_SIDURI`.
145 |
146 | ## [0.5.5] - 2021-11-22
147 |
148 | ### Added
149 |
150 | - Added a new gematria method, `MISPAR_GADOL`. A contribution by [Taber Andrew Bain](https://github.com/taber)
151 |
152 | ## [0.5.4] - 2021-11-21
153 |
154 | ### Fixed
155 |
156 | - Fixed an issue where `Hebrew.gematria` would through an error if the input string had no hebrew characters.
157 | In this case, we now return a value of 0.
158 |
159 | ## [0.5.3] - 2021-11-15
160 |
161 | ### Changed
162 |
163 | - Split the `PunctuationChar` type chars into `TaamimChar` and `OtherChar` types in `hebrew.char`.
164 | - Renamed the `no_punctuation` method of `Hebrew` to `no_taamim`.
165 |
166 | ## [0.5.0] - 2021-11-14
167 |
168 | ### Added
169 |
170 | - Added the method `Hebrew.gematria` method for calculating the gematria of a string.
171 | - Added `mispar_hechrachi` as a supported gematria type.
172 |
173 | ``` python
174 | >>> from hebrew import Hebrew
175 | >>> from hebrew.gematria import GematriaTypes
176 |
177 | >>> Hebrew("בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָרֶץ׃").gematria(GematriaTypes.MISPAR_HECHRACHI)
178 | 2701
179 | ```
180 |
181 | ## [0.4.0] - 2021-11-14
182 |
183 | ### Added
184 |
185 | - Added `hebrew.chars` with constants for Hebrew characters and classes to represent each letter.
186 | - Moved constants out of `Hebrew` and into `hebrew.chars`.
187 | - Constant values, previously strings, are now instances of a class with metadata for each letter.
188 |
189 | ### Removed
190 |
191 | - Support for Python 3.6 was removed because we are now using `@dataclasse`. It is possible to make this work with
192 | 3.6 but I am choosing not to at this time. If this is a problem for you, feel free to open an issue.
193 |
194 | ## [0.3.0] - 2021-11-08
195 |
196 | ### Changed
197 |
198 | - Renamed the python package from `hebrewstring` to `hebrew`.
199 |
200 | ## [0.2.0] - 2021-11-07
201 |
202 | ### Added
203 |
204 | - Added the `__eq__` method to the `GraphemeString` object.
205 |
206 | This is to support the `==` operator when comparing two `GraphemeString` objects.
207 |
208 | - Added the `__add__` method to the `GraphemeString` object.
209 |
210 | This is to support the `+` operator when adding two `GraphemeString` objects together.
211 |
212 | - Added the `__hash__` method to the `GraphemeString` object.
213 |
214 | This is to support the `hash()` function for a `GraphemeString` instance and allows it (as an example) to be used as
215 | a `dict` key.
216 |
217 | ## [0.1.2] - 2021-11-07
218 |
219 | ### Added
220 |
221 | - Added base code, tests, and examples for the first release.
--------------------------------------------------------------------------------
/tests/test_gematria.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from hebrew import Hebrew
4 | from hebrew.gematria import GematriaTypes
5 |
6 | # Test inputs and their expected values for each method type.
7 | # Add new test cases here!
8 | test_values = {
9 | "אבגדהוזחטיכךלמםנןסעפףצץקרשת": {
10 | GematriaTypes.ALBAM: 1913,
11 | GematriaTypes.ATBASH: 1555,
12 | GematriaTypes.MISPAR_GADOL: 4995,
13 | GematriaTypes.MISPAR_HECHRACHI: 1775,
14 | GematriaTypes.MISPAR_KATAN: 128,
15 | GematriaTypes.MISPAR_MESHULASH: 103_465_025,
16 | GematriaTypes.MISPAR_MUSAFI: 1802,
17 | GematriaTypes.MISPAR_PERATI: 347_785,
18 | GematriaTypes.MISPAR_SIDURI: 378,
19 | GematriaTypes.MISPAR_BONEEH: 9915,
20 | GematriaTypes.MISPAR_HAMERUBAH_HAKLALI: 3_150_625,
21 | GematriaTypes.MISPAR_HAACHOR: 39_785,
22 | GematriaTypes.MISPAR_KATAN_MISPARI: 2,
23 | GematriaTypes.MISPAR_KOLEL: 1776,
24 | GematriaTypes.MISPAR_KIDMI: 7515,
25 | GematriaTypes.MISPAR_NEELAM: 2925,
26 | GematriaTypes.MISPAR_MISPARI: 14_095,
27 | GematriaTypes.AYAK_BACHAR: 4995,
28 | GematriaTypes.AYAK_BAKAR: 4995,
29 | GematriaTypes.OFANIM: 2643,
30 | GematriaTypes.ACHAS_BETA: 2092,
31 | GematriaTypes.AVGAD: 1825,
32 | GematriaTypes.REVERSE_AVGAD: 1725,
33 | GematriaTypes.MISPAR_SHEMI_MILUI: 4700,
34 | },
35 | "בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ׃": {
36 | GematriaTypes.ALBAM: 1571,
37 | GematriaTypes.ATBASH: 3541,
38 | GematriaTypes.MISPAR_GADOL: 4631,
39 | GematriaTypes.MISPAR_HECHRACHI: 2701,
40 | GematriaTypes.MISPAR_KATAN: 82,
41 | GematriaTypes.MISPAR_MESHULASH: 270_951_613,
42 | GematriaTypes.MISPAR_MUSAFI: 2729,
43 | GematriaTypes.MISPAR_PERATI: 794_225,
44 | GematriaTypes.MISPAR_SIDURI: 329,
45 | GematriaTypes.MISPAR_BONEEH: 40_035,
46 | GematriaTypes.MISPAR_HAMERUBAH_HAKLALI: 7_295_401,
47 | GematriaTypes.MISPAR_HAACHOR: 38_294,
48 | GematriaTypes.MISPAR_KATAN_MISPARI: 1,
49 | GematriaTypes.MISPAR_KOLEL: 2708,
50 | GematriaTypes.MISPAR_KIDMI: 10_338,
51 | GematriaTypes.MISPAR_NEELAM: 2745,
52 | GematriaTypes.MISPAR_MISPARI: 13_256,
53 | GematriaTypes.AYAK_BACHAR: 1355,
54 | GematriaTypes.AYAK_BAKAR: 1355,
55 | GematriaTypes.OFANIM: 2453,
56 | GematriaTypes.ACHAS_BETA: 2372,
57 | GematriaTypes.AVGAD: 2096,
58 | GematriaTypes.REVERSE_AVGAD: 4236,
59 | GematriaTypes.MISPAR_SHEMI_MILUI: 5446,
60 | },
61 | }
62 |
63 | # Prepare the test inputs for the pytest parametrize function
64 | params = ["hebrew_text,gematria_method,expected_val", []]
65 | for text, tests in test_values.items():
66 | for method, val in tests.items():
67 | params[1].append((text, method, val))
68 |
69 |
70 | @pytest.mark.parametrize(*params)
71 | def test_gematria_values(
72 | hebrew_text: str, gematria_method: GematriaTypes, expected_val: str
73 | ):
74 | assert Hebrew(hebrew_text).gematria(gematria_method) == expected_val
75 | assert Hebrew(hebrew_text).text_only().gematria(gematria_method) == expected_val
76 | assert (
77 | Hebrew(hebrew_text + " Add english letters").gematria(gematria_method)
78 | == expected_val
79 | )
80 |
81 |
82 | def test_mispar_shemi_milui_change_spelling():
83 | hebrew_text = "בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ׃"
84 | spellings = {
85 | "ב": "בת",
86 | "ג": "גמל",
87 | "ד": "דלית",
88 | "ה": "הי",
89 | "ו": "ויו",
90 | "ח": "חת",
91 | "ט": "טת",
92 | "פ": "פי",
93 | "צ": "צדיק",
94 | "ר": "רש",
95 | "ש": "שין",
96 | "ת": "תיו",
97 | }
98 | assert (
99 | Hebrew(hebrew_text).gematria(
100 | GematriaTypes.MISPAR_SHEMI_MILUI, alt_letter_name_spelling=spellings
101 | )
102 | == 5583
103 | )
104 | assert (
105 | Hebrew(hebrew_text)
106 | .text_only()
107 | .gematria(GematriaTypes.MISPAR_SHEMI_MILUI, alt_letter_name_spelling=spellings)
108 | == 5583
109 | )
110 | assert (
111 | Hebrew(hebrew_text + " Add english letters").gematria(
112 | GematriaTypes.MISPAR_SHEMI_MILUI, alt_letter_name_spelling=spellings
113 | )
114 | == 5583
115 | )
116 | hebrew_text = "אבגדהוזחטיכךלמםנןסעפףצץקרשת"
117 | spellings = {
118 | "ה": "הה",
119 | "ו": "ואו",
120 | "פ": "פה",
121 | "ת": "תאו",
122 | }
123 | assert (
124 | Hebrew(hebrew_text).gematria(
125 | GematriaTypes.MISPAR_SHEMI_MILUI, alt_letter_name_spelling=spellings
126 | )
127 | == 4714
128 | )
129 | assert (
130 | Hebrew(hebrew_text)
131 | .text_only()
132 | .gematria(GematriaTypes.MISPAR_SHEMI_MILUI, alt_letter_name_spelling=spellings)
133 | == 4714
134 | )
135 | assert (
136 | Hebrew(hebrew_text + " Add english letters").gematria(
137 | GematriaTypes.MISPAR_SHEMI_MILUI, alt_letter_name_spelling=spellings
138 | )
139 | == 4714
140 | )
141 |
142 |
143 | def test_mispar_shemi_milui_bad_spelling():
144 | hebrew_text = "בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ׃"
145 | spellings = {
146 | "ב": "בתבתבתבת", # bad name that does not exist for this letter
147 | }
148 | with pytest.raises(ValueError):
149 | Hebrew(hebrew_text).gematria(
150 | GematriaTypes.MISPAR_SHEMI_MILUI, alt_letter_name_spelling=spellings
151 | )
152 |
153 |
154 | def test_mispar_neelam_change_spelling():
155 | hebrew_text = "בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ׃"
156 | spellings = {
157 | "ב": "בת",
158 | "ג": "גמל",
159 | "ד": "דלית",
160 | "ה": "הי",
161 | "ו": "ויו",
162 | "ח": "חת",
163 | "ט": "טת",
164 | "פ": "פי",
165 | "צ": "צדיק",
166 | "ר": "רש",
167 | "ש": "שין",
168 | "ת": "תיו",
169 | }
170 | assert (
171 | Hebrew(hebrew_text).gematria(
172 | GematriaTypes.MISPAR_NEELAM, alt_letter_name_spelling=spellings
173 | )
174 | == 2882
175 | )
176 | assert (
177 | Hebrew(hebrew_text)
178 | .text_only()
179 | .gematria(GematriaTypes.MISPAR_NEELAM, alt_letter_name_spelling=spellings)
180 | == 2882
181 | )
182 | assert (
183 | Hebrew(hebrew_text + " Add english letters").gematria(
184 | GematriaTypes.MISPAR_NEELAM, alt_letter_name_spelling=spellings
185 | )
186 | == 2882
187 | )
188 | hebrew_text = "אבגדהוזחטיכךלמםנןסעפףצץקרשת"
189 | spellings = {
190 | "ה": "הה",
191 | "ו": "ואו",
192 | "פ": "פה",
193 | "ת": "תאו",
194 | }
195 | assert (
196 | Hebrew(hebrew_text).gematria(
197 | GematriaTypes.MISPAR_NEELAM, alt_letter_name_spelling=spellings
198 | )
199 | == 2939
200 | )
201 | assert (
202 | Hebrew(hebrew_text)
203 | .text_only()
204 | .gematria(GematriaTypes.MISPAR_NEELAM, alt_letter_name_spelling=spellings)
205 | == 2939
206 | )
207 | assert (
208 | Hebrew(hebrew_text + " Add english letters").gematria(
209 | GematriaTypes.MISPAR_NEELAM, alt_letter_name_spelling=spellings
210 | )
211 | == 2939
212 | )
213 |
214 |
215 | def test_bad_input():
216 | for t in GematriaTypes:
217 | assert (
218 | Hebrew("Testing a string that contains no hebrew").gematria(t) == 0
219 | ), "gematria should return 0 when the input text is not hebrew"
220 |
221 |
222 | def test_mixed_input():
223 | for t in GematriaTypes:
224 | assert (
225 | Hebrew("Both hebrew: 'שָׁלוֹם' and English: 'Hello dev!'").gematria(t) > 0
226 | ), "gematria should always have a value > 0 when there is any hebrew text in a string"
227 |
--------------------------------------------------------------------------------
/hebrew/grapheme_string.py:
--------------------------------------------------------------------------------
1 | from typing import Iterator, TypeVar
2 |
3 | import grapheme
4 | from grapheme.finder import GraphemeIterator
5 |
6 | GraphemeStringT = TypeVar("GraphemeStringT", bound="GraphemeString")
7 |
8 |
9 | class GraphemeString:
10 | """
11 | An object that unifies the functions available from the grapheme library under an object.
12 | Functions all work as they do in the grapheme library, this is simply an interface.
13 | """
14 |
15 | UNICODE_VERSION: str = grapheme.UNICODE_VERSION
16 |
17 | def __init__(self, string: str):
18 | self.string = string
19 |
20 | @property
21 | def graphemes(self) -> Iterator[GraphemeIterator]:
22 | """
23 | Returns an iterator of all graphemes of given string.
24 |
25 | ``` python
26 | >>> rainbow_flag = "🏳️🌈"
27 | >>> [codepoint for codepoint in rainbow_flag]
28 | ['🏳', '️', '\u200d', '🌈']
29 | >>> list(GraphemeString("multi codepoint grapheme: " + rainbow_flag).graphemes)
30 | ['m', 'u', 'l', 't', 'i', ' ', 'c', 'o', 'd', 'e', 'p', 'o', 'i', 'n', 't', ' ', 'g', 'r', 'a', 'p', 'h', 'e', 'm', 'e', ':', ' ', '🏳️🌈']
31 | ```
32 | """
33 | return grapheme.graphemes(self.string)
34 |
35 | @property
36 | def length(self) -> int:
37 | """
38 | Returns the number of graphemes in the string.
39 |
40 | Note that this functions needs to traverse the full string to calculate the length,
41 | unlike `len(string)` and it's time consumption is linear to the length of the string
42 | (up to the `until` value).
43 |
44 | Only counts up to the `until` argument, if given. This is useful when testing
45 | the length of a string against some limit and the excess length is not interesting.
46 |
47 | ``` python
48 | >>> rainbow_flag = "🏳️🌈"
49 | >>> len(rainbow_flag)
50 | 4
51 | >>> GraphemeString(rainbow_flag).length
52 | 1
53 | ```
54 | """
55 | return grapheme.length(self.string)
56 |
57 | def get_length(self, until: int) -> int:
58 | """
59 | Returns the number of graphemes in the string.
60 |
61 | Note that this functions needs to traverse the full string to calculate the length,
62 | unlike `len(string)` and it's time consumption is linear to the length of the string
63 | (up to the `until` value).
64 |
65 | Only counts up to the `until` argument, if given. This is useful when testing
66 | the length of a string against some limit and the excess length is not interesting.
67 |
68 | ``` python
69 | >>> rainbow_flag = "🏳️🌈"
70 | >>> len(rainbow_flag)
71 | 4
72 | >>> GraphemeString(rainbow_flag).length
73 | 1
74 | >>> GraphemeString("".join(str(i) for i in range(100))).get_length(30)
75 | 30
76 | ```
77 | """
78 | return grapheme.length(self.string, until)
79 |
80 | @property
81 | def grapheme_lengths(self) -> Iterator[int]:
82 | """
83 | Returns an iterator of number of code points in each grapheme of the string.
84 | """
85 | return grapheme.grapheme_lengths(self.string)
86 |
87 | def slice(self, start: int = None, end: int = None) -> str:
88 | """
89 | Returns a substring of the given string, counting graphemes instead of codepoints.
90 |
91 | Negative indices is currently not supported.
92 |
93 | ``` python
94 | >>> string = "tamil நி (ni)"
95 |
96 | >>> string[:7]
97 | 'tamil ந'
98 | >>> GraphemeString(string).slice(end=7)
99 | 'tamil நி'
100 | >>> string[7:]
101 | 'ி (ni)'
102 | >>> GraphemeString(string).slice(start=7)
103 | ' (ni)'
104 | ```
105 | """
106 | return grapheme.slice(self.string, start, end)
107 |
108 | def contains(self, substring: str) -> bool:
109 | """
110 | Returns true if the sequence of graphemes in substring is also present in string.
111 |
112 | This differs from the normal python `in` operator, since the python operator will return
113 | true if the sequence of codepoints are withing the other string without considering
114 | grapheme boundaries.
115 |
116 | Performance notes: Very fast if `substring not in string`, since that also means that
117 | the same graphemes can not be in the two strings. Otherwise this function has linear time
118 | complexity in relation to the string length. It will traverse the sequence of graphemes until
119 | a match is found, so it will generally perform better for grapheme sequences that match early.
120 |
121 | ``` python
122 | >>> "🇸🇪" in "🇪🇸🇪🇪"
123 | True
124 | >>> GraphemeString("🇪🇸🇪🇪").contains("🇸🇪")
125 | False
126 | ```
127 | """
128 | return grapheme.contains(self.string, substring)
129 |
130 | def safe_split_index(self, max_length: int) -> int:
131 | """
132 | Returns the highest index up to `max_len` at which the given string can be sliced, without breaking a grapheme.
133 |
134 | This is useful for when you want to split or take a substring from a string, and don't really care about
135 | the exact grapheme length, but don't want to risk breaking existing graphemes.
136 |
137 | This function does normally not traverse the full grapheme sequence up to the given length, so it can be used
138 | for arbitrarily long strings and high `max_len`s. However, some grapheme boundaries depend on the previous state,
139 | so the worst case performance is O(n). In practice, it's only very long non-broken sequences of country flags
140 | (represented as Regional Indicators) that will perform badly.
141 |
142 | The return value will always be between `0` and `len(string)`.
143 |
144 | ``` python
145 | >>> string = "tamil நி (ni)"
146 | >>> i = GraphemeString(string).safe_split_index(7)
147 | >>> i
148 | 6
149 | >>> string[:i]
150 | 'tamil '
151 | >>> string[i:]
152 | 'நி (ni)'
153 | ```
154 | """
155 | return grapheme.safe_split_index(self.string, max_length)
156 |
157 | def startswith(self, prefix: str) -> bool:
158 | """
159 | Like str.startswith, but also checks that the string starts with the given prefixes sequence of graphemes.
160 |
161 | str.startswith may return true for a prefix that is not visually represented as a prefix if a grapheme cluster
162 | is continued after the prefix ends.
163 |
164 | ``` python
165 | >>> GraphemeString("✊🏾").startswith("✊")
166 | False
167 | >>> "✊🏾".startswith("✊")
168 | True
169 | ```
170 | """
171 | return grapheme.startswith(self.string, prefix)
172 |
173 | def endswith(self, suffix: str) -> bool:
174 | """
175 | Like str.endswith, but also checks that the string ends with the given prefixes sequence of graphemes.
176 |
177 | str.endswith may return true for a suffix that is not visually represented as a suffix if a grapheme cluster
178 | is initiated before the suffix starts.
179 |
180 | ``` python
181 | >>> GraphemeString("🏳️🌈").endswith("🌈")
182 | False
183 | >>> "🏳️🌈".endswith("🌈")
184 | True
185 | ```
186 | """
187 | return grapheme.endswith(self.string, suffix)
188 |
189 | def __str__(self) -> str:
190 | return self.string
191 |
192 | def __repr__(self) -> str:
193 | return self.__str__()
194 |
195 | def __add__(self, other) -> GraphemeStringT:
196 | return GraphemeString(self.string + str(other))
197 |
198 | def __key(self) -> str:
199 | return self.string
200 |
201 | def __eq__(self, other) -> bool:
202 | if isinstance(other, GraphemeString):
203 | return self.__key() == other.__key()
204 | return False
205 |
206 | def __hash__(self):
207 | return hash(self.__key())
208 |
--------------------------------------------------------------------------------
/tests/test_chars.py:
--------------------------------------------------------------------------------
1 | import collections
2 |
3 | from hebrew.chars import *
4 |
5 |
6 | def test_all_hebrew_letters_represented():
7 | all_unicode_chars_defined = [c.char for c in ALL_CHARS if len(c.char) == 1]
8 | all_unicode_chars = [
9 | "֑",
10 | "֒",
11 | "֓",
12 | "֔",
13 | "֕",
14 | "֖",
15 | "֗",
16 | "֘",
17 | "֙",
18 | "֚",
19 | "֛",
20 | "֜",
21 | "֝",
22 | "֞",
23 | "֟",
24 | "֠",
25 | "֡",
26 | "֢",
27 | "֣",
28 | "֤",
29 | "֥",
30 | "֦",
31 | "֧",
32 | "֨",
33 | "֩",
34 | "֪",
35 | "֫",
36 | "֬",
37 | "֭",
38 | "֮",
39 | "֯",
40 | "ְ",
41 | "ֱ",
42 | "ֲ",
43 | "ֳ",
44 | "ִ",
45 | "ֵ",
46 | "ֶ",
47 | "ַ",
48 | "ָ",
49 | "ֹ",
50 | "ֺ",
51 | "ֻ",
52 | "ּ",
53 | "ֽ",
54 | "־",
55 | "ֿ",
56 | "׀",
57 | "ׁ",
58 | "ׂ",
59 | "׃",
60 | "ׄ",
61 | "ׅ",
62 | "׆",
63 | "ׇ",
64 | "א",
65 | "ב",
66 | "ג",
67 | "ד",
68 | "ה",
69 | "ו",
70 | "ז",
71 | "ח",
72 | "ט",
73 | "י",
74 | "ך",
75 | "כ",
76 | "ל",
77 | "ם",
78 | "מ",
79 | "ן",
80 | "נ",
81 | "ס",
82 | "ע",
83 | "ף",
84 | "פ",
85 | "ץ",
86 | "צ",
87 | "ק",
88 | "ר",
89 | "ש",
90 | "ת",
91 | "ׯ",
92 | "װ",
93 | "ױ",
94 | "ײ",
95 | "׳",
96 | "״",
97 | "ℵ",
98 | "ℶ",
99 | "ℷ",
100 | "ℸ",
101 | "יִ",
102 | "ﬞ",
103 | "ײַ",
104 | "ﬠ",
105 | "ﬡ",
106 | "ﬢ",
107 | "ﬣ",
108 | "ﬤ",
109 | "ﬥ",
110 | "ﬦ",
111 | "ﬧ",
112 | "ﬨ",
113 | "﬩",
114 | "שׁ",
115 | "שׂ",
116 | "שּׁ",
117 | "שּׂ",
118 | "אַ",
119 | "אָ",
120 | "אּ",
121 | "בּ",
122 | "גּ",
123 | "דּ",
124 | "הּ",
125 | "וּ",
126 | "זּ",
127 | "טּ",
128 | "יּ",
129 | "ךּ",
130 | "כּ",
131 | "לּ",
132 | "מּ",
133 | "נּ",
134 | "סּ",
135 | "ףּ",
136 | "פּ",
137 | "צּ",
138 | "קּ",
139 | "רּ",
140 | "שּ",
141 | "תּ",
142 | "וֹ",
143 | "בֿ",
144 | "כֿ",
145 | "פֿ",
146 | "ﭏ",
147 | ]
148 |
149 | assert len(all_unicode_chars) == len(
150 | set(all_unicode_chars)
151 | ), "There are duplicate values in all_unicode_chars"
152 | for char in all_unicode_chars:
153 | assert (
154 | len(char) == 1
155 | ), f"all_unicode_chars contains a char that is not a single character: {char}"
156 | assert sorted(all_unicode_chars_defined) == sorted(all_unicode_chars), (
157 | f"The following hebrew related chars are missing from `hebrew.chars`: "
158 | f"{[c for c in all_unicode_chars if c not in all_unicode_chars_defined]}"
159 | )
160 |
161 |
162 | def test_hebrew_char_hebrew_names():
163 | tsadi_sofit = HebrewChar(
164 | char="ץ",
165 | name="Tsadi Sofit",
166 | final_letter=True,
167 | hebrew_name="צַדִי סוֹפִית",
168 | hebrew_name_alts=["צדיק סופית"],
169 | )
170 | assert sorted(tsadi_sofit.hebrew_names) == sorted(["צַדִי סוֹפִית", "צדיק סופית"])
171 |
172 |
173 | def test_hebrew_char_names():
174 | aleph = HebrewChar(char="א", name="Aleph", hebrew_name="אָלֶף", name_alts=["Alef"])
175 | assert sorted(aleph.names) == sorted(["Aleph", "Alef"])
176 |
177 |
178 | def test_hebrew_char_str():
179 | aleph = HebrewChar(char="א", name="Aleph", hebrew_name="אָלֶף", name_alts=["Alef"])
180 | assert str(aleph) == "א"
181 |
182 |
183 | def test_base_letter():
184 | bet_with_dot = HebrewChar(char="בּ", name="Bet")
185 | assert bet_with_dot.base_letter.char == "ב"
186 |
187 |
188 | def test_final_letters():
189 | final_chars = ["ץ", "ף", "ן", "ם", "ך"]
190 | assert len(final_chars) == len(FINAL_LETTERS)
191 | for char in final_chars:
192 | assert char in [c.char for c in FINAL_LETTERS]
193 |
194 |
195 | def test_hebrew_chars():
196 | assert len(HEBREW_CHARS) > 0
197 | for char in HEBREW_CHARS:
198 | assert type(char) == HebrewChar
199 |
200 |
201 | def test_yiddish_chars():
202 | yiddish_letters = ["ױ", "װ", "ײ"]
203 | assert len(yiddish_letters) == len(YIDDISH_CHARS)
204 | for char in yiddish_letters:
205 | assert char in [c.char for c in YIDDISH_CHARS]
206 |
207 |
208 | def test_niqqud_chars():
209 | assert len(NIQQUD_CHARS) > 0
210 | for char in NIQQUD_CHARS:
211 | assert type(char) == NiqqudChar
212 |
213 |
214 | def test_taamim_chars():
215 | assert len(TAAMIM_CHARS) > 0
216 | for char in TAAMIM_CHARS:
217 | assert type(char) == TaamimChar
218 |
219 |
220 | def test_other_chars():
221 | assert len(OTHER_CHARS) > 0
222 | for char in OTHER_CHARS:
223 | assert type(char) == OtherChar
224 |
225 |
226 | def test_char_dict():
227 | assert len(CHARS) == len(
228 | ALL_CHARS
229 | ), "The _ALL_CHARS array may contain values with duplicate char values"
230 |
231 |
232 | def test_char_search():
233 | assert isinstance(
234 | char_search("Aleph"), HebrewChar
235 | ), "HebrewChar.search should return a HebrewChar instance"
236 | assert isinstance(char_search("aLEPH"), HebrewChar), "Should be case insensitive"
237 | assert char_search("Bad Value") is None
238 |
239 |
240 | def test_char_search_use_alt_names():
241 | search_result = char_search("Hei")
242 | assert isinstance(search_result, HebrewChar)
243 | assert search_result.char == "ה"
244 | assert search_result.name != "Hei"
245 |
246 |
247 | def test_char_search_use_char_list():
248 | assert char_search("Aleph") == ALEPH
249 | assert char_search("Alef", NIQQUD_CHARS) is None
250 | assert char_search("Kumatz", NIQQUD_CHARS) == KUMATZ
251 |
252 |
253 | def test_hebrew_char_search():
254 | assert HebrewChar.search("Aleph") == ALEPH
255 | assert HebrewChar.search("Double Vav") is None
256 |
257 |
258 | def test_yiddish_char_search():
259 | assert YiddishChar.search("Double Vav") == DOUBLE_VAV
260 | assert YiddishChar.search("Aleph") is None
261 |
262 |
263 | def test_niqqud_char_search():
264 | assert NiqqudChar.search("Kumatz") == KUMATZ
265 | assert NiqqudChar.search("Double Vav") is None
266 |
267 |
268 | def test_taamim_char_search():
269 | assert TaamimChar.search("Shalshelet") == SHALSHELET
270 | assert TaamimChar.search("Kumatz") is None
271 |
272 |
273 | def test_other_char_search():
274 | assert OtherChar.search("Geresh") == GERESH
275 | assert OtherChar.search("Kumatz") is None
276 |
277 |
278 | def test_hebrew_char_hashable():
279 | assert hash(
280 | HebrewChar(char="א", name="Aleph", hebrew_name="אָלֶף", name_alts=["Alef"])
281 | )
282 |
283 |
284 | def test_yiddish_char_hashable():
285 | assert hash(YiddishChar(char="ײ", name="Double Yod", name_alts=["Saf"]))
286 |
287 |
288 | def test_taamim_char_hashable():
289 | assert hash(TaamimChar(char="֧", name="Darga"))
290 |
291 |
292 | def test_niqqud_char_hashable():
293 | assert hash(NiqqudChar(char="ׂ", name="Sin Dot"))
294 |
295 |
296 | def test_other_char_hashable():
297 | assert hash(OtherChar(char="׃", name="Sof Passuk"))
298 |
299 |
300 | def test_hebrew_char_eq():
301 | hebrew_one = HebrewChar(
302 | char="א", name="Aleph", hebrew_name="אָלֶף", name_alts=["Alef"]
303 | )
304 | hebrew_two = HebrewChar(
305 | char="בּ", name="Bet", hebrew_name="בֵּית", hebrew_name_alts=["בת"]
306 | )
307 | assert hebrew_one == hebrew_one
308 | assert hebrew_one != hebrew_two
309 | assert hebrew_one != 5
310 |
311 |
312 | def test_yiddish_char_eq():
313 | yiddish_one = YiddishChar(char="ױ", name="Vav Yod")
314 | yiddish_two = YiddishChar(
315 | char="װ",
316 | name="Double Vav",
317 | name_alts=["Double Vuv"],
318 | )
319 | assert yiddish_one == yiddish_one
320 | assert yiddish_one != yiddish_two
321 | assert yiddish_one != 5
322 |
323 |
324 | def test_niqqud_char_eq():
325 | niqqud_one = NiqqudChar(char="ׂ", name="Sin Dot")
326 | niqqud_two = NiqqudChar(char="ׁ", name="Shin Dot")
327 | assert niqqud_one == niqqud_one
328 | assert niqqud_one != niqqud_two
329 | assert niqqud_one != 5
330 |
331 |
332 | def test_taamim_char_eq():
333 | taamim_one = TaamimChar(char="֙", name="Pashta")
334 | taamim_two = TaamimChar(char="֚", name="Yetiv")
335 | assert taamim_one == taamim_one
336 | assert taamim_one != taamim_two
337 | assert taamim_one != 5
338 |
339 |
340 | def test_other_char_eq():
341 | other_one = OtherChar(char="־", name="Maqaf")
342 | other_two = OtherChar(char="׀", name="Paseq")
343 | assert other_one == other_one
344 | assert other_one != other_two
345 | assert other_one != 5
346 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Hebrew("בְּרֵאשִׁ֖ית")
2 |
3 | A python package with methods to handle the complexities of Hebrew text, calculate Gematria, and more.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | ---
25 |
26 | **Documentation**: [https://hebrew.aviperl.me/](https://hebrew.aviperl.me/)
27 |
28 | **Repository**: [https://github.com/avi-perl/hebrew](https://github.com/avi-perl/hebrew)
29 |
30 | ---
31 |
32 | # Installation
33 |
34 |
35 |
36 | ```bash
37 | $ pip install hebrew
38 | ```
39 |
40 | # Example
41 |
42 | `Hebrew` assists in working with Hebrew text by providing methods to handle the text according to user-perceived
43 | characteristics. Additionally, methods for common Hebrew text processing are provided.
44 |
45 | ```python
46 | from hebrew import Hebrew
47 | from hebrew.chars import HebrewChar, ALEPH
48 |
49 | hs = Hebrew('בְּרֵאשִׁ֖ית')
50 | print(list(hs.graphemes)) # ['בְּ', 'רֵ', 'א', 'שִׁ֖', 'י', 'ת']
51 | print(hs.text_only()) # בראשית
52 |
53 | print(ALEPH) # HebrewChar(char='א', name='Aleph', hebrew_name='אָלֶף', name_alts=['Alef'], hebrew_name_alts=None, final_letter=False)
54 |
55 | print(HebrewChar.search('bet')) # HebrewChar(char='בּ', name='Bet', hebrew_name='בֵּית', name_alts=None, hebrew_name_alts=None, final_letter=False)
56 | ```
57 |
58 | ## Gematria
59 |
60 | The `Hebrew` class includes a `gematria` function that can return a value for _23_ different variations of Gematria!
61 |
62 | ```python
63 | from hebrew import Hebrew
64 | from hebrew import GematriaTypes
65 |
66 | hs = Hebrew(':מוֹדֶה אֲנִי לְפָנֶֽיךָ מֶֽלֶךְ חַי וְקַיָּם שֶׁהֶחֱזַֽרְתָּ בִּי נִשְׁמָתִי בְּחֶמְלָה, רַבָּה אֱמוּנָתֶֽךָ')
67 |
68 | assert hs.gematria() == 3111
69 | assert hs.gematria(GematriaTypes.MISPAR_GADOL) == 5111
70 | ```
71 |
72 | Messy inputs, such as strings with english text mixed in, is supported. However, do be careful to work with sanitized
73 | strings as much as possible.
74 |
75 | ```python
76 | from hebrew import Hebrew
77 |
78 | hs1 = Hebrew(
79 | '''
80 | Text: ":מוֹדֶה אֲנִי לְפָנֶֽיךָ מֶֽלֶךְ חַי וְקַיָּם שֶׁהֶחֱזַֽרְתָּ בִּי נִשְׁמָתִי בְּחֶמְלָה, רַבָּה אֱמוּנָתֶֽךָ"
81 | Translation: "I give thanks to You living and everlasting King for You have restored my soul with mercy. Great is Your faithfulness."
82 | '''
83 | )
84 | hs2 = Hebrew(':מוֹדֶה אֲנִי לְפָנֶֽיךָ מֶֽלֶךְ חַי וְקַיָּם שֶׁהֶחֱזַֽרְתָּ בִּי נִשְׁמָתִי בְּחֶמְלָה, רַבָּה אֱמוּנָתֶֽךָ')
85 |
86 | assert hs1.gematria() == hs2.gematria() # 2701
87 | ```
88 |
89 | Major kudos goes to [TorahCalc](https://www.torahcalc.com/gematria/) whose calculator and explanations were critical to
90 | the development of this feature.
91 |
92 | ## Numerical Conversions
93 |
94 | You can create a Hebrew object that represents a number using the `from_number` method. This is handy for displaying numbers in Hebrew form.
95 |
96 | ```python
97 | from hebrew import Hebrew
98 |
99 | hs1 = Hebrew.from_number(2)
100 | assert hs1.string == "ב׳"
101 |
102 | # Add an apostrophe instead of the unicode geresh
103 | hs2 = Hebrew.from_number(2, geresh=False)
104 | assert hs2.string == "ב'"
105 |
106 | # Do not add punctuation
107 | hs2 = Hebrew.from_number(2, punctuate=False)
108 | assert hs2.string == 'ב'
109 | ```
110 |
111 | ## Character Normalization
112 | Hidden among hebrew text can be special characters that are visually identical humans, but are made up of different
113 | unicode characters. However, this can cause issues with presentation when there is no support for these characters.
114 |
115 | 
116 |
117 | In this case, the first letter is made up of 2 unicode characters, [sin with a dot](https://en.wiktionary.org/wiki/%D7%A9%D7%82)
118 | and [qamatz](https://en.wiktionary.org/wiki/%D6%B8). The issue here is the sin. By normalizing the sin with a dot to 2 unicode
119 | characters, [ש](https://en.wiktionary.org/wiki/%D7%A9) and the [dot](https://en.wiktionary.org/wiki/%D7%82), the display
120 | will look right!
121 |
122 | 
123 |
124 | To normalize content, use the `Hebrew.normalize` function:
125 | ```python
126 | from hebrew import Hebrew
127 |
128 | hs = Hebrew('שָׂחַקְתִּי כְּמוֹ')
129 |
130 | assert len(hs.string) == 14
131 | assert len(hs.normalize().string) == 18
132 | ```
133 |
134 | ### Normalizing Yiddish
135 |
136 | By default, special yiddish characters such as [ײ](https://en.wiktionary.org/wiki/%D7%B2) (double Yod) are _not_ normalized.
137 | However, [ײַ](https://en.wiktionary.org/wiki/%EF%AC%9F) (double Yod with a Patah) will be converted to [ײַ](https://en.wiktionary.org/wiki/%D7%B2%D6%B7).
138 |
139 | To fully "normalize" yiddish characters, pass `True` to `normalize`.
140 |
141 |
142 | ## Grapheme Characters
143 |
144 | Hebrew text comes in different forms, depending on the context. Hebrew text may appear with Niqqudot
145 | "a system of diacritical signs used to represent vowels or distinguish between alternative pronunciations of letters
146 | of the Hebrew alphabet". [^1] Additionally, Hebrew text may appear with extensive punctuation characters that connect
147 | words, separate them, and cantillation marks "used as a guide for chanting the text, either from the printed text or,
148 | in the case of the public reading of the Torah" [^2].
149 |
150 | Because of the above, from the perspective of a hebrew reader, the following 3 words are the same:
151 |
152 | 1. **בְּרֵאשִׁ֖ית**
153 | 2. **בְּרֵאשִׁית**
154 | 3. **בראשית**
155 |
156 | However, as a unicode string, they are entirely different because of the additional characters.
157 |
158 | ```python
159 | assert len("בְּרֵאשִׁ֖ית") == 12
160 | assert len("בְּרֵאשִׁית") == 11
161 | assert len("בראשית") == 6
162 | ```
163 |
164 | This impacts the user is a number of other ways. For example, if I want to get the root of this hebrew word using a slice:
165 | _Expected: `רֵאשִׁ֖ית`_
166 |
167 | ```python
168 | he = "בְּרֵאשִׁ֖ית"
169 | assert he[-5:] == 'ִׁ֖ית'
170 | ```
171 |
172 | The solution to this is to handle the unicode string as a list of grapheme[^3] characters, where each letter and its
173 | accompanying characters are treated as a single unit.
174 |
175 | ### Working with Grapheme Characters
176 |
177 | Using the [grapheme](https://github.com/alvinlindstam/grapheme) library for python, we can work with the grapheme
178 | characters as units. This allows us to get the right number of characters, slice the string correctly, and more.
179 |
180 | ```python
181 | import grapheme
182 |
183 | assert grapheme.length("בְּרֵאשִׁ֖ית") == 6
184 | assert grapheme.slice("בְּרֵאשִׁ֖ית", start=1, end=6) == 'רֵאשִׁ֖ית'
185 | ```
186 |
187 | This library includes 2 classes. `GraphemeString` is a class that supports all the functions made available by `grapheme`.
188 | The 2nd class `Hebrew` subclasses `GraphemeString` and adds methods for handling Hebrew text. This allows us to
189 | interact with the text like so:
190 |
191 | ```python
192 | from hebrew import Hebrew
193 |
194 | v2 = Hebrew('מוֹדֶה אֲנִי לְפָנֶֽיךָ')
195 | print(v2.no_taamim())
196 | assert v2.no_taamim().string == 'מוֹדֶה אֲנִי לְפָנֶיךָ'
197 | assert v2.text_only().string == 'מודה אני לפניך'
198 |
199 | assert v2.length == 14
200 | assert v2.words() == [Hebrew('מוֹדֶה'), Hebrew('אֲנִי'), Hebrew('לְפָנֶֽיךָ')]
201 | ```
202 |
203 | The text in these examples and used in testing were sourced from [Sefaria](https://github.com/Sefaria/Sefaria-Export).
204 |
205 | ## `hebrew.chars` and Character Constants
206 |
207 | `hebrew.Chars` contains constants for every letter as well as lists by character category's.
208 | Each value is an instance of a class that represents a character in the Hebrew character set with relevant properties.
209 | Since this library seeks to support the use of the Hebrew language in the way it is used, characters such as "בּ" can be
210 | located (`BET`) even though, strictly speaking, "בּ" is not part of the hebrew alphabet; it is a Hebrew letter plus a dot.
211 |
212 | ```python
213 | from hebrew.chars import FINAL_LETTERS, YIDDISH_CHARS, TSADI
214 |
215 | print(TSADI) # HebrewChar(char='צ', name='Tsadi', hebrew_name='צַדִי', name_alts=['Tzadik'], hebrew_name_alts=['צדיק'], final_letter=False)
216 |
217 | assert {c.name: c.char for c in FINAL_LETTERS} == {'Chaf Sofit': 'ך', 'Mem Sofit': 'ם', 'Nun Sofit': 'ן', 'Fe Sofit': 'ף', 'Tsadi Sofit': 'ץ'}
218 |
219 | assert [c.char for c in YIDDISH_CHARS] == ['ײ', 'װ', 'ױ']
220 | ```
221 |
222 | A letter can be retrieved using the `CHARS` dict; A dict of all instances of all supported Char types where the key is
223 | the char and the value is an instance of BaseHebrewChar.
224 |
225 | ```python
226 | from hebrew.chars import CHARS
227 |
228 | print(CHARS.get('בּ')) # HebrewChar(char='בּ', name='Bet', hebrew_name='בֵּית', name_alts=None, hebrew_name_alts=None, final_letter=False)
229 | ```
230 |
231 | Search is also supported so that letters can be retrieved by their name.
232 |
233 | ```python
234 | from hebrew.chars import HebrewChar
235 |
236 | print(HebrewChar.search('bet')) # HebrewChar(char='בּ', name='Bet', hebrew_name='בֵּית', name_alts=None, hebrew_name_alts=None, final_letter=False)
237 | ```
238 |
239 | ## Contributing
240 |
241 | Contributions in the form of pull requests are very welcome! I'm sure many more helpful methods related to hebrew text
242 | could be helpful. More information and instructions for contributing can be found [here](CONTRIBUTING).
243 |
244 | [^1]: [https://en.wikipedia.org/wiki/Niqqud](https://en.wikipedia.org/wiki/Niqqud)
245 | [^2]: [https://en.wikipedia.org/wiki/Hebrew_cantillation](https://en.wikipedia.org/wiki/Hebrew_cantillation)
246 | [^3]: [https://en.wikipedia.org/wiki/Grapheme](https://en.wikipedia.org/wiki/Grapheme)
247 |
--------------------------------------------------------------------------------
/hebrew/gematria.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 | from typing import Dict
3 |
4 |
5 | class GematriaTypes(Enum):
6 | """
7 | Types of Gematria supported in this library.
8 | """
9 |
10 | # Simple methods where the value is calculated off of a value map to each letter
11 | MISPAR_HECHRACHI = "mispar_hechrachi"
12 | MISPAR_GADOL = "mispar_gadol"
13 | MISPAR_SIDURI = "mispar_siduri"
14 | MISPAR_KATAN = "mispar_katan"
15 | MISPAR_PERATI = "mispar_perati"
16 | ATBASH = "atbash"
17 | ALBAM = "albam"
18 | MISPAR_MESHULASH = "mispar_meshulash"
19 | MISPAR_KIDMI = "mispar_kidmi"
20 | MISPAR_MISPARI = "mispar_mispari"
21 | AYAK_BACHAR = "ayak_bachar"
22 | AYAK_BAKAR = AYAK_BACHAR
23 | OFANIM = "ofanim"
24 | ACHAS_BETA = "achas_beta"
25 | AVGAD = "avgad"
26 | REVERSE_AVGAD = "reverse_avgad"
27 |
28 | # Complex methods involving logic on top of MISPAR_HECHRACHI
29 | MISPAR_MUSAFI = "mispar_musafi"
30 | MISPAR_BONEEH = "mispar_boneeh"
31 | MISPAR_HAMERUBAH_HAKLALI = "mispar_hamerubah_haklali"
32 | MISPAR_HAACHOR = "mispar_haachor"
33 | MISPAR_KATAN_MISPARI = "mispar_katan_mispari"
34 | MISPAR_KOLEL = "mispar_kolel"
35 | MISPAR_SHEMI_MILUI = "mispar_shemi_milui"
36 | MISPAR_NEELAM = "mispar_neelam"
37 |
38 |
39 | """
40 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the mispar_hechrachi
41 | gematria method as its value.
42 | """
43 | MISPAR_HECHRACHI: Dict[str, int] = {
44 | "א": 1,
45 | "ב": 2,
46 | "ג": 3,
47 | "ד": 4,
48 | "ה": 5,
49 | "ו": 6,
50 | "ז": 7,
51 | "ח": 8,
52 | "ט": 9,
53 | "י": 10,
54 | "כ": 20,
55 | "ך": 20,
56 | "ל": 30,
57 | "מ": 40,
58 | "ם": 40,
59 | "נ": 50,
60 | "ן": 50,
61 | "ס": 60,
62 | "ע": 70,
63 | "פ": 80,
64 | "ף": 80,
65 | "צ": 90,
66 | "ץ": 90,
67 | "ק": 100,
68 | "ר": 200,
69 | "ש": 300,
70 | "ת": 400,
71 | }
72 |
73 | """
74 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the mispar_gadol
75 | gematria method as its value. Non-final letter values are all the same, but final kaf/chaf, mem, nun, pe/fe are
76 | moved to the end of the alphabet and continue on from where tav left off
77 | """
78 | MISPAR_GADOL: Dict[str, int] = {
79 | "א": 1,
80 | "ב": 2,
81 | "ג": 3,
82 | "ד": 4,
83 | "ה": 5,
84 | "ו": 6,
85 | "ז": 7,
86 | "ח": 8,
87 | "ט": 9,
88 | "י": 10,
89 | "כ": 20,
90 | "ך": 500,
91 | "ל": 30,
92 | "מ": 40,
93 | "ם": 600,
94 | "נ": 50,
95 | "ן": 700,
96 | "ס": 60,
97 | "ע": 70,
98 | "פ": 80,
99 | "ף": 800,
100 | "צ": 90,
101 | "ץ": 900,
102 | "ק": 100,
103 | "ר": 200,
104 | "ש": 300,
105 | "ת": 400,
106 | }
107 |
108 | """
109 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the mispar_siduri
110 | gematria method as its value. This method assigns each letter a number from 1 to 22 in the order of the alphabet.
111 | """
112 | MISPAR_SIDURI: Dict[str, int] = {
113 | "א": 1,
114 | "ב": 2,
115 | "ג": 3,
116 | "ד": 4,
117 | "ה": 5,
118 | "ו": 6,
119 | "ז": 7,
120 | "ח": 8,
121 | "ט": 9,
122 | "י": 10,
123 | "כ": 11,
124 | "ך": 23,
125 | "ל": 12,
126 | "מ": 13,
127 | "ם": 24,
128 | "נ": 14,
129 | "ן": 25,
130 | "ס": 15,
131 | "ע": 16,
132 | "פ": 17,
133 | "ף": 26,
134 | "צ": 18,
135 | "ץ": 27,
136 | "ק": 19,
137 | "ר": 20,
138 | "ש": 21,
139 | "ת": 22,
140 | }
141 |
142 | """
143 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the mispar_katan
144 | gematria method as its value. This method uses the value of the letters but without the zeros after large numbers.
145 | (ex. "Yud" is 1 instead of 10, "Tav" is 4 instead of 400).
146 | """
147 | MISPAR_KATAN: Dict[str, int] = {
148 | "א": 1,
149 | "ב": 2,
150 | "ג": 3,
151 | "ד": 4,
152 | "ה": 5,
153 | "ו": 6,
154 | "ז": 7,
155 | "ח": 8,
156 | "ט": 9,
157 | "י": 1,
158 | "כ": 2,
159 | "ך": 2,
160 | "ל": 3,
161 | "מ": 4,
162 | "ם": 4,
163 | "נ": 5,
164 | "ן": 5,
165 | "ס": 6,
166 | "ע": 7,
167 | "פ": 8,
168 | "ף": 8,
169 | "צ": 9,
170 | "ץ": 9,
171 | "ק": 1,
172 | "ר": 2,
173 | "ש": 3,
174 | "ת": 4,
175 | }
176 |
177 | """
178 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the mispar_perati
179 | gematria method as its value. This method assigns each letter its standard value squared. (ex. "Aleph" = 1 x 1 = 1, "Beis" = 2 x 2 = 4).
180 | """
181 | MISPAR_PERATI: Dict[str, int] = {
182 | "א": 1,
183 | "ב": 4,
184 | "ג": 9,
185 | "ד": 16,
186 | "ה": 25,
187 | "ו": 36,
188 | "ז": 49,
189 | "ח": 64,
190 | "ט": 81,
191 | "י": 100,
192 | "כ": 400,
193 | "ך": 400,
194 | "ל": 900,
195 | "מ": 1_600,
196 | "ם": 1_600,
197 | "נ": 2_500,
198 | "ן": 2_500,
199 | "ס": 3_600,
200 | "ע": 4_900,
201 | "פ": 6_400,
202 | "ף": 6_400,
203 | "צ": 8_100,
204 | "ץ": 8_100,
205 | "ק": 10_000,
206 | "ר": 40_000,
207 | "ש": 90_000,
208 | "ת": 160_000,
209 | }
210 |
211 | """
212 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the AtBash
213 | gematria method as its value. This method exchanges each letter's value for its opposite letter's value.
214 | (ex. "Aleph" switches values with "Tav", "Beis" switches values with "Shin").
215 | """
216 | ATBASH: Dict[str, int] = {
217 | "א": 400,
218 | "ב": 300,
219 | "ג": 200,
220 | "ד": 100,
221 | "ה": 90,
222 | "ו": 80,
223 | "ז": 70,
224 | "ח": 60,
225 | "ט": 50,
226 | "י": 40,
227 | "כ": 30,
228 | "ך": 30,
229 | "ל": 20,
230 | "מ": 10,
231 | "ם": 10,
232 | "נ": 9,
233 | "ן": 9,
234 | "ס": 8,
235 | "ע": 7,
236 | "פ": 6,
237 | "ף": 6,
238 | "צ": 5,
239 | "ץ": 5,
240 | "ק": 4,
241 | "ר": 3,
242 | "ש": 2,
243 | "ת": 1,
244 | }
245 |
246 | """
247 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the AlBam
248 | gematria method as its value. This method splits the alphabet in half and letters from the first half switch
249 | values with letters from the second half. (ex. "Aleph" switches values with "Lamed", "Beis" switches values with "Mem").
250 | """
251 | ALBAM: Dict[str, int] = {
252 | "א": 30,
253 | "ב": 40,
254 | "ג": 50,
255 | "ד": 60,
256 | "ה": 70,
257 | "ו": 80,
258 | "ז": 90,
259 | "ח": 100,
260 | "ט": 200,
261 | "י": 300,
262 | "כ": 400,
263 | "ך": 400,
264 | "ל": 1,
265 | "מ": 2,
266 | "ם": 2,
267 | "נ": 3,
268 | "ן": 3,
269 | "ס": 4,
270 | "ע": 5,
271 | "פ": 6,
272 | "ף": 6,
273 | "צ": 7,
274 | "ץ": 7,
275 | "ק": 8,
276 | "ר": 9,
277 | "ש": 10,
278 | "ת": 20,
279 | }
280 |
281 | """
282 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the AtBash
283 | gematria method as its value. This method splits the alphabet in half and letters from the first half switch
284 | values with letters from the second half. (ex. "Aleph" switches values with "Lamed", "Beis" switches values with "Mem").
285 | """
286 | MISPAR_MESHULASH: Dict[str, int] = {
287 | "א": 1,
288 | "ב": 8,
289 | "ג": 27,
290 | "ד": 64,
291 | "ה": 125,
292 | "ו": 216,
293 | "ז": 343,
294 | "ח": 512,
295 | "ט": 729,
296 | "י": 1_000,
297 | "כ": 8_000,
298 | "ך": 8_000,
299 | "ל": 27_000,
300 | "מ": 64_000,
301 | "ם": 64_000,
302 | "נ": 125_000,
303 | "ן": 125_000,
304 | "ס": 216_000,
305 | "ע": 343_000,
306 | "פ": 512_000,
307 | "ף": 512_000,
308 | "צ": 729_000,
309 | "ץ": 729_000,
310 | "ק": 1_000_000,
311 | "ר": 8_000_000,
312 | "ש": 27_000_000,
313 | "ת": 64_000_000,
314 | }
315 |
316 | """
317 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the Mispar Kidmi
318 | gematria method as its value. This method adds the value of all preceding letters in the alphabet to each
319 | letter's value. (ex. "Aleph" = 1, "Beis" = 1 + 2 = 3, "Gimmel" = 1 + 2 + 3 = 6).
320 | """
321 | MISPAR_KIDMI: Dict[str, int] = {
322 | "א": 1,
323 | "ב": 3,
324 | "ג": 6,
325 | "ד": 10,
326 | "ה": 15,
327 | "ו": 21,
328 | "ז": 28,
329 | "ח": 36,
330 | "ט": 45,
331 | "י": 55,
332 | "כ": 75,
333 | "ך": 75,
334 | "ל": 105,
335 | "מ": 145,
336 | "ם": 145,
337 | "נ": 195,
338 | "ן": 195,
339 | "ס": 255,
340 | "ע": 325,
341 | "פ": 405,
342 | "ף": 405,
343 | "צ": 495,
344 | "ץ": 495,
345 | "ק": 595,
346 | "ר": 795,
347 | "ש": 1095,
348 | "ת": 1495,
349 | }
350 |
351 | """
352 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the Mispar Mispari
353 | gematria method as its value. This method spells out the Hebrew name of each of the letter's standard values and adds
354 | up their values. (ex. "Aleph" = one (Echad) = 1 + 8 + 4 = 13).
355 | """
356 | MISPAR_MISPARI: Dict[str, int] = {
357 | "א": 13,
358 | "ב": 760,
359 | "ג": 636,
360 | "ד": 273,
361 | "ה": 348,
362 | "ו": 600,
363 | "ז": 372,
364 | "ח": 401,
365 | "ט": 770,
366 | "י": 570,
367 | "כ": 620,
368 | "ך": 620,
369 | "ל": 686,
370 | "מ": 323,
371 | "ם": 323,
372 | "נ": 408,
373 | "ן": 408,
374 | "ס": 660,
375 | "ע": 422,
376 | "פ": 446,
377 | "ף": 446,
378 | "צ": 820,
379 | "ץ": 820,
380 | "ק": 46,
381 | "ר": 501,
382 | "ש": 1083,
383 | "ת": 720,
384 | }
385 |
386 | """
387 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the Ayak Bachar
388 | (or Ayak Bakar) gematria method as its value. This method splits the alphabet into three groups of nine with the final
389 | (sofit) letters at the end. The letters in the first group replace the ones in the second group, the letters in the
390 | second group replace the ones in the third group, and the letters in the third group replace the ones in
391 | the first group. (ex. "Aleph" takes the place of "Yud", "Yud" takes the place of "Kuf",
392 | "Kuf" takes the place of "Aleph", "Beis" takes the place of "Chaf" etc.).
393 | """
394 | AYAK_BACHAR: Dict[str, int] = {
395 | "א": 10,
396 | "ב": 20,
397 | "ג": 30,
398 | "ד": 40,
399 | "ה": 50,
400 | "ו": 60,
401 | "ז": 70,
402 | "ח": 80,
403 | "ט": 90,
404 | "י": 100,
405 | "כ": 200,
406 | "ך": 5,
407 | "ל": 300,
408 | "מ": 400,
409 | "ם": 6,
410 | "נ": 500,
411 | "ן": 7,
412 | "ס": 600,
413 | "ע": 700,
414 | "פ": 800,
415 | "ף": 8,
416 | "צ": 900,
417 | "ץ": 9,
418 | "ק": 1,
419 | "ר": 2,
420 | "ש": 3,
421 | "ת": 4,
422 | }
423 |
424 | """
425 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the Ofanim
426 | gematria method as its value. This method replaces each letter with the last letter of its name. (ex. "Aleph" becomes
427 | "Fey", "Beis" becomes "Tav").
428 | """
429 | OFANIM: Dict[str, int] = {
430 | "א": 80,
431 | "ב": 400,
432 | "ג": 30,
433 | "ד": 400,
434 | "ה": 1,
435 | "ו": 6,
436 | "ז": 50,
437 | "ח": 400,
438 | "ט": 400,
439 | "י": 4,
440 | "כ": 80,
441 | "ך": 80,
442 | "ל": 4,
443 | "מ": 40,
444 | "ם": 40,
445 | "נ": 50,
446 | "ן": 50,
447 | "ס": 20,
448 | "ע": 50,
449 | "פ": 1,
450 | "ף": 1,
451 | "צ": 10,
452 | "ץ": 10,
453 | "ק": 80,
454 | "ר": 300,
455 | "ש": 50,
456 | "ת": 6,
457 | }
458 |
459 | """
460 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the Ofanim
461 | gematria method as its value. This method splits the alphabet into groups of 7, 7, and 8 letters.
462 | The letters in the first group replace the ones in the second group, the letters in the second group replace
463 | the ones in the third group, and the letters in the third group replace the ones in the first group. The letter "Tav"
464 | does not change.
465 | """
466 | ACHAS_BETA: Dict[str, int] = {
467 | "א": 8,
468 | "ב": 9,
469 | "ג": 10,
470 | "ד": 20,
471 | "ה": 30,
472 | "ו": 40,
473 | "ז": 50,
474 | "ח": 60,
475 | "ט": 70,
476 | "י": 80,
477 | "כ": 90,
478 | "ך": 90,
479 | "ל": 100,
480 | "מ": 200,
481 | "ם": 200,
482 | "נ": 300,
483 | "ן": 300,
484 | "ס": 1,
485 | "ע": 2,
486 | "פ": 3,
487 | "ף": 3,
488 | "צ": 4,
489 | "ץ": 4,
490 | "ק": 5,
491 | "ר": 6,
492 | "ש": 7,
493 | "ת": 400,
494 | }
495 |
496 | """
497 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the Avgad
498 | gematria method as its value. This method replaces each letter with the next one. (ex. "Aleph" becomes "Beis", "Beis"
499 | becomes "Gimmel", "Tav" becomes "Aleph").
500 | """
501 | AVGAD: Dict[str, int] = {
502 | "א": 2,
503 | "ב": 3,
504 | "ג": 4,
505 | "ד": 5,
506 | "ה": 6,
507 | "ו": 7,
508 | "ז": 8,
509 | "ח": 9,
510 | "ט": 10,
511 | "י": 20,
512 | "כ": 30,
513 | "ך": 30,
514 | "ל": 40,
515 | "מ": 50,
516 | "ם": 50,
517 | "נ": 60,
518 | "ן": 60,
519 | "ס": 70,
520 | "ע": 80,
521 | "פ": 90,
522 | "ף": 90,
523 | "צ": 100,
524 | "ץ": 100,
525 | "ק": 200,
526 | "ר": 300,
527 | "ש": 400,
528 | "ת": 1,
529 | }
530 |
531 | """
532 | A dictionary of values with each letter of the alphabet as a key, and the numerical value used in the Reverse Avgad
533 | gematria method as its value. This method replaces each letter with the previous one. (ex. "Beis" becomes "Aleph",
534 | "Gimmel" becomes "Beis", "Aleph" becomes "Tav").
535 | """
536 | REVERSE_AVGAD: Dict[str, int] = {
537 | "א": 400,
538 | "ב": 1,
539 | "ג": 2,
540 | "ד": 3,
541 | "ה": 4,
542 | "ו": 5,
543 | "ז": 6,
544 | "ח": 7,
545 | "ט": 8,
546 | "י": 9,
547 | "כ": 10,
548 | "ך": 10,
549 | "ל": 20,
550 | "מ": 30,
551 | "ם": 30,
552 | "נ": 40,
553 | "ן": 40,
554 | "ס": 50,
555 | "ע": 60,
556 | "פ": 70,
557 | "ף": 70,
558 | "צ": 80,
559 | "ץ": 80,
560 | "ק": 90,
561 | "ר": 100,
562 | "ש": 200,
563 | "ת": 300,
564 | }
565 |
--------------------------------------------------------------------------------
/hebrew/hebrew_obj.py:
--------------------------------------------------------------------------------
1 | import unicodedata
2 | from functools import reduce
3 | from typing import List, Optional, TypeVar, Dict, Callable, Tuple
4 | from operator import add
5 |
6 | from hebrew.numerical_conversion.substitute import Substitutions
7 |
8 | from .grapheme_string import GraphemeString
9 | from .chars import (
10 | MAQAF,
11 | NIQQUD_CHARS,
12 | TAAMIM_CHARS,
13 | PASEQ,
14 | SOF_PASSUK,
15 | _NON_LETTER_CHARS,
16 | CHARS,
17 | HEBREW_CHARS,
18 | FINAL_MINOR_LETTER_MAPPINGS,
19 | HebrewChar,
20 | SPECIAL_CHARACTER_NORMALIZED_MAPPING,
21 | YiddishChar,
22 | )
23 | from .numerical_conversion.convert import number_to_hebrew_string
24 | from hebrew.gematria import GematriaTypes
25 |
26 | HebrewT = TypeVar("HebrewT", bound="Hebrew")
27 |
28 |
29 | def get_hebrew_name(letter: HebrewChar, name_dict) -> str:
30 | """
31 | Helper function to get the letters name from the library definition
32 | or from the alts provided by the user.
33 |
34 | The name value passed *must* be a name that is defined in the characters `HebrewChar` instance or a
35 | ValueError will be thrown. This is done to make sure that only valid naming is used.
36 | """
37 | if not name_dict:
38 | name_dict = {}
39 |
40 | if name_dict and letter.char in name_dict.keys():
41 | name = name_dict.get(letter.char)
42 | clean_name = Hebrew(name).text_only()
43 | if clean_name not in [Hebrew(nm).text_only() for nm in letter.hebrew_names]:
44 | raise ValueError(f"{name} is not a valid name for {letter}")
45 | return clean_name.string
46 | else:
47 | return letter.hebrew_name
48 |
49 |
50 | class Hebrew(GraphemeString):
51 | """
52 | A class representing a Hebrew String.
53 |
54 | A `Hebrew` string can contain pure Hebrew letters, or can be composed of any additional characters.
55 | """
56 |
57 | def __init__(self, string: str):
58 | super().__init__(string)
59 |
60 | def __str__(self) -> str:
61 | return self.string
62 |
63 | def __repr__(self) -> str:
64 | return self.__str__()
65 |
66 | def no_maqaf(self) -> HebrewT:
67 | """
68 | Replaces all maqafs with spaces.
69 |
70 | This is useful for splitting a string into words when you want words connected by maqafs to be considered as one word.
71 | Example: You may think of "עַל־פְּנֵ֥י" as one word in some cases but want to split it into "עַל" and "פְּנֵי" in other cases.
72 |
73 | :return:
74 | """
75 | return Hebrew(self.string.replace(MAQAF.char, " "))
76 |
77 | def no_sof_passuk(self) -> HebrewT:
78 | """
79 | Removes all sof_passuk chars.
80 |
81 | :return:
82 | """
83 | return Hebrew(self.string.replace(SOF_PASSUK.char, ""))
84 |
85 | def words(self, split_maqaf: bool = False) -> List[HebrewT]:
86 | """
87 | Splits the string into a list of words.
88 |
89 | :param split_maqaf: Whether to split a single word such as "עַל־פְּנֵ֥י" into "עַל" and "פְּנֵי" when a maqaf is encountered.
90 | :return:
91 | """
92 | string = self.string if not split_maqaf else self.no_maqaf().string
93 | return [Hebrew(s) for s in string.split()]
94 |
95 | def text_only(self, remove_maqaf: bool = False) -> HebrewT:
96 | """
97 | Returns a string with all non-letter characters removed.
98 | This will remove both niqqud and punctuation.
99 |
100 | :param remove_maqaf: Whether to remove the maqaf characters if they are encountered
101 | :return:
102 | """
103 | string = self.no_maqaf().string if remove_maqaf else self.string
104 | chars_to_remove = [c.char for c in _NON_LETTER_CHARS if c not in (MAQAF, PASEQ)]
105 | string = string.replace(
106 | f" {PASEQ.char} ", " "
107 | ) # Handled separately to avoid double spaces.
108 | for char in chars_to_remove:
109 | string = string.replace(char, "")
110 | return Hebrew(string)
111 |
112 | def no_niqqud(self) -> HebrewT:
113 | """
114 | Removes all niqqud characters.
115 | This may be useful to practice reading from the torah.
116 |
117 | :return:
118 | """
119 | string = self.string
120 | for char in [c.char for c in NIQQUD_CHARS]:
121 | string = string.replace(char, "")
122 | return Hebrew(string)
123 |
124 | def normalize(self, normalize_yiddish: bool = False) -> HebrewT:
125 | """
126 | Replaces all non-standard hebrew characters with their equivalent values
127 | using normal hebrew letters and symbols. This is important when using hebrew fonts. Some fonts may not
128 | support these special characters, normalization helps by changing all the characters to be ones that would be
129 | supported.
130 |
131 | :param normalize_yiddish: By default, yiddish characters are left alone since they are typically desired.
132 | :return:
133 | """
134 | normalized = unicodedata.normalize("NFC", self.string)
135 | # normalized = self.string
136 | special_chars: dict = (
137 | SPECIAL_CHARACTER_NORMALIZED_MAPPING
138 | if normalize_yiddish
139 | else {
140 | k: v
141 | for k, v in SPECIAL_CHARACTER_NORMALIZED_MAPPING.items()
142 | if not isinstance(k, YiddishChar)
143 | }
144 | )
145 | special_chars = {
146 | k.char: "".join([val.char for val in v]) if isinstance(v, list) else v.char
147 | for k, v in special_chars.items()
148 | }
149 | if any(char in normalized for char in special_chars):
150 | for k, v in special_chars.items():
151 | normalized = normalized.replace(k, v)
152 | self.string = normalized
153 | return self
154 |
155 | def no_taamim(
156 | self, remove_maqaf: bool = False, remove_sof_passuk: bool = False
157 | ) -> HebrewT:
158 | """
159 | Removes all [Ta'amim](https://en.wikipedia.org/wiki/Hebrew_cantillation) characters.
160 | Result is a string with just letters and Niqqud characters.
161 |
162 | :param remove_maqaf: Whether to remove the maqaf characters if they are encountered.
163 | :param remove_sof_passuk: Whether to remove the remove_sof_passuk character if they are encountered.
164 | :return:
165 | """
166 | string = self.no_maqaf().string if remove_maqaf else self.string
167 | string = Hebrew(string).no_sof_passuk().string if remove_sof_passuk else string
168 | chars_to_remove = [
169 | p.char for p in TAAMIM_CHARS if p not in (MAQAF, PASEQ, SOF_PASSUK)
170 | ]
171 | string = string.replace(
172 | f" {PASEQ.char} ", " "
173 | ) # Handled separately to avoid double spaces.
174 | for char in chars_to_remove:
175 | string = string.replace(char, "")
176 | return Hebrew(string)
177 |
178 | def gematria(
179 | self,
180 | method: GematriaTypes = GematriaTypes.MISPAR_HECHRACHI,
181 | alt_letter_name_spelling: Dict[str, str] = None,
182 | ) -> int:
183 | """
184 | Returns the gematria of the string.
185 |
186 | If the contains no hebrew characters, the value returned is 0. Mixing hebrew and english characters is ok!
187 |
188 | :param method: The method to use for calculating the gematria.
189 | :param alt_letter_name_spelling: Used only with MISPAR_SHEMI_MILUI: A dict of alternate spellings for a letter
190 | that should be used to make the calculation. Eg: `{"ו": "ואו"}`.
191 | :return:
192 | """
193 | # Remove non hebrew characters
194 | cleaned_string: str = "".join(
195 | [c for c in self.string if c in [x.char for x in HEBREW_CHARS] or c == " "]
196 | )
197 |
198 | if method == GematriaTypes.MISPAR_MUSAFI:
199 | # Mispar Musafi (Heb: מספר מוספי) adds the number of letters in the word or phrase to the value.
200 | value = self.__calculate_simple_gematria(cleaned_string)
201 | hebrew_letters = [c for c in cleaned_string if c != " "]
202 | return value + len(hebrew_letters)
203 |
204 | elif method == GematriaTypes.MISPAR_KOLEL:
205 | # Mispar Kolel (Heb: מספר כלל) is the value plus the number of words in the phrase.
206 | value = self.__calculate_simple_gematria(cleaned_string)
207 | hebrew_words = cleaned_string.split()
208 | return value + len(hebrew_words)
209 |
210 | elif method == GematriaTypes.MISPAR_BONEEH:
211 | # Mispar Bone'eh (building value) (Heb: מספר בונה) adds the value of all previous letters in the word to the
212 | # value of the current letter as the word is calculated. (ex. Echad is 1 + (1 + 8) + (1 + 8 + 4) = 23).
213 | values = [
214 | self.__calculate_simple_gematria(c)
215 | for c in [x for x in cleaned_string if x != " "]
216 | ]
217 | total = 0
218 | for i, n in enumerate(values):
219 | total += sum(values[:i]) + n
220 | return total
221 |
222 | elif method == GematriaTypes.MISPAR_HAMERUBAH_HAKLALI:
223 | # Mispar HaMerubah HaKlali (Heb: מספר המרובע הכללי) is the standard value squared.
224 | return self.__calculate_simple_gematria(cleaned_string) ** 2
225 |
226 | elif method == GematriaTypes.MISPAR_HAACHOR:
227 | # Mispar Ha'achor (sometimes called Mispar Meshulash, triangular value) (Heb: מספר האחור) values each letter
228 | # as its value multiplied by the position of the letter in the word or phrase.
229 | values = [
230 | self.__calculate_simple_gematria(c)
231 | for c in [x for x in cleaned_string if x != " "]
232 | ]
233 | total = 0
234 | for i, n in enumerate(values):
235 | total += n * (i + 1)
236 | return total
237 |
238 | elif method == GematriaTypes.MISPAR_KATAN_MISPARI:
239 | # Mispar Katan Mispari (integral reduced value) (Heb: מספר קטן מספרי) is the digital root of the standard
240 | # value which is obtained by adding all the digits in the number until the number is a single digit.
241 | # (ex. Echad (13) --> 1 + 3 --> 4).
242 | calculated_value = self.__calculate_simple_gematria(cleaned_string)
243 | while calculated_value > 9:
244 | calculated_value = sum([int(x) for x in str(calculated_value)])
245 | return calculated_value
246 |
247 | elif method == GematriaTypes.MISPAR_SHEMI_MILUI:
248 | # Mispar Shemi (Milui, full name value) (Heb: מספר שמי\מילוי) values each letter as the value of the
249 | # letter's name. (ex. "Aleph" = Aleph + Lamed + Fey = 1 + 30 + 80 = 111).
250 | # [Note: There is more than one way to spell certain letters.]
251 |
252 | # Get list of HebrewChar instances for each letter in string
253 | chars: List[HebrewChar] = [
254 | CHARS[c] for c in [x for x in cleaned_string if x != " "]
255 | ]
256 |
257 | # Convert final letters to non-final since our internal lib naming for final letters
258 | # will ruin the calculation.
259 | replaced_final_letters = [
260 | CHARS[FINAL_MINOR_LETTER_MAPPINGS.get(c.char)] if c.final_letter else c
261 | for c in chars
262 | ]
263 |
264 | # Get internal or user supplied names, and calculate value off them.
265 | values = [
266 | self.__calculate_simple_gematria(
267 | get_hebrew_name(c, alt_letter_name_spelling)
268 | )
269 | for c in replaced_final_letters
270 | ]
271 | return sum(values)
272 |
273 | elif method == GematriaTypes.MISPAR_NEELAM:
274 | # Mispar Ne'elam (hidden value) (Heb: מספר נעלם) values each letter as the value of the letter's name
275 | # without the letter itself. (ex. "Aleph" = Lamed + Fey = 30 + 80 = 110).
276 |
277 | # Get list of HebrewChar instances for each letter in string
278 | chars: List[HebrewChar] = [
279 | CHARS[c] for c in [x for x in cleaned_string if x != " "]
280 | ]
281 |
282 | # Convert final letters to non-final since our internal lib naming for final letters
283 | # will ruin the calculation.
284 | replaced_final_letters = [
285 | CHARS[FINAL_MINOR_LETTER_MAPPINGS.get(c.char)] if c.final_letter else c
286 | for c in chars
287 | ]
288 |
289 | # Get internal or user supplied names.
290 | names = [
291 | get_hebrew_name(c, alt_letter_name_spelling)
292 | for c in replaced_final_letters
293 | ]
294 |
295 | # Remove letter from name and calculate value
296 | values = [self.__calculate_simple_gematria(c[1:]) for c in names]
297 | return sum(values)
298 |
299 | else:
300 | # Simple gematria that can be calculated by simply adding each letters value up to a final number.
301 | return self.__calculate_simple_gematria(self.string, method)
302 |
303 | @classmethod
304 | def from_number(
305 | cls,
306 | number: int,
307 | punctuate: bool = True,
308 | geresh: bool = True,
309 | substitution_functions: Optional[
310 | Tuple[Callable[[str], str], ...]
311 | ] = Substitutions.DEFAULT,
312 | ):
313 | """
314 | Convert a number into its Hebrew letter form, returning it as an instance of Hebrew.
315 |
316 | :param number: The number to convert to Hebrew letters. Must be greater than 0...
317 | :param punctuate: Whether to add punctuation in the appropriate places.
318 | :param geresh: If punctuate is true, whether to use the unicode geresh or an apostrophe.
319 | :param substitution_functions: A tuple of functions that replaces some hebrew values in the result with an
320 | appropriate equivalent. By default, "יה" and "יו" are replaced with "טו" and "טז" respectively. To replace all
321 | values such as שמד ,רע, and others, use `Substitutions.ALL`.
322 | :return:
323 | """
324 | return cls(
325 | number_to_hebrew_string(number, punctuate, geresh, substitution_functions)
326 | )
327 |
328 | @staticmethod
329 | def __calculate_simple_gematria(
330 | string: str, method: GematriaTypes = GematriaTypes.MISPAR_HECHRACHI
331 | ) -> int:
332 | """Calculate Gematria for simple Gematria that use a value map for each letter."""
333 | chars = [
334 | CHARS[c] for c in string if CHARS.get(c) and hasattr(CHARS[c], method.value)
335 | ]
336 | if len(chars) == 0:
337 | # The list will be 0 if there are no letters in the string or if the letters are not hebrew.
338 | return 0
339 | else:
340 | return reduce(add, [getattr(c, method.value) for c in chars])
341 |
--------------------------------------------------------------------------------
/tests/test_hebrew.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from hebrew import Hebrew
4 | from hebrew.chars import *
5 |
6 | taamei_hamikra = [
7 | "בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָרֶץ׃",
8 | "וְהָאָ֗רֶץ הָיְתָ֥ה תֹ֙הוּ֙ וָבֹ֔הוּ וְחֹ֖שֶׁךְ עַל־פְּנֵ֣י תְה֑וֹם וְר֣וּחַ אֱלֹהִ֔ים מְרַחֶ֖פֶת עַל־פְּנֵ֥י הַמָּֽיִם׃",
9 | "וַיֹּ֥אמֶר אֱלֹהִ֖ים יְהִ֣י א֑וֹר וַֽיְהִי־אֽוֹר׃",
10 | "וַיַּ֧רְא אֱלֹהִ֛ים אֶת־הָא֖וֹר כִּי־ט֑וֹב וַיַּבְדֵּ֣ל אֱלֹהִ֔ים בֵּ֥ין הָא֖וֹר וּבֵ֥ין הַחֹֽשֶׁךְ׃",
11 | "וַיִּקְרָ֨א אֱלֹהִ֤ים ׀ לָאוֹר֙ י֔וֹם וְלַחֹ֖שֶׁךְ קָ֣רָא לָ֑יְלָה וַֽיְהִי־עֶ֥רֶב וַֽיְהִי־בֹ֖קֶר י֥וֹם אֶחָֽד׃",
12 | "וַיֹּ֣אמֶר אֱלֹהִ֔ים יְהִ֥י רָקִ֖יעַ בְּת֣וֹךְ הַמָּ֑יִם וִיהִ֣י מַבְדִּ֔יל בֵּ֥ין מַ֖יִם לָמָֽיִם׃",
13 | "וַיַּ֣עַשׂ אֱלֹהִים֮ אֶת־הָרָקִיעַ֒ וַיַּבְדֵּ֗ל בֵּ֤ין הַמַּ֙יִם֙ אֲשֶׁר֙ מִתַּ֣חַת לָרָקִ֔יעַ וּבֵ֣ין הַמַּ֔יִם אֲשֶׁ֖ר מֵעַ֣ל לָרָקִ֑יעַ וַֽיְהִי־כֵֽן׃",
14 | "וַיִּקְרָ֧א אֱלֹהִ֛ים לָֽרָקִ֖יעַ שָׁמָ֑יִם וַֽיְהִי־עֶ֥רֶב וַֽיְהִי־בֹ֖קֶר י֥וֹם שֵׁנִֽי׃",
15 | "וַיֹּ֣אמֶר אֱלֹהִ֗ים יִקָּו֨וּ הַמַּ֜יִם מִתַּ֤חַת הַשָּׁמַ֙יִם֙ אֶל־מָק֣וֹם אֶחָ֔ד וְתֵרָאֶ֖ה הַיַּבָּשָׁ֑ה וַֽיְהִי־כֵֽן׃",
16 | "וַיִּקְרָ֨א אֱלֹהִ֤ים ׀ לַיַּבָּשָׁה֙ אֶ֔רֶץ וּלְמִקְוֵ֥ה הַמַּ֖יִם קָרָ֣א יַמִּ֑ים וַיַּ֥רְא אֱלֹהִ֖ים כִּי־טֽוֹב׃",
17 | "וַיֹּ֣אמֶר אֱלֹהִ֗ים תַּֽדְשֵׁ֤א הָאָ֙רֶץ֙ דֶּ֔שֶׁא עֵ֚שֶׂב מַזְרִ֣יעַ זֶ֔רַע עֵ֣ץ פְּרִ֞י עֹ֤שֶׂה פְּרִי֙ לְמִינ֔וֹ אֲשֶׁ֥ר זַרְעוֹ־ב֖וֹ עַל־הָאָ֑רֶץ וַֽיְהִי־כֵֽן׃",
18 | "וַתּוֹצֵ֨א הָאָ֜רֶץ דֶּ֠שֶׁא עֵ֣שֶׂב מַזְרִ֤יעַ זֶ֙רַע֙ לְמִינֵ֔הוּ וְעֵ֧ץ עֹֽשֶׂה־פְּרִ֛י אֲשֶׁ֥ר זַרְעוֹ־ב֖וֹ לְמִינֵ֑הוּ וַיַּ֥רְא אֱלֹהִ֖ים כִּי־טֽוֹב׃",
19 | "וַֽיְהִי־עֶ֥רֶב וַֽיְהִי־בֹ֖קֶר י֥וֹם שְׁלִישִֽׁי׃",
20 | "וַיֹּ֣אמֶר אֱלֹהִ֗ים יְהִ֤י מְאֹרֹת֙ בִּרְקִ֣יעַ הַשָּׁמַ֔יִם לְהַבְדִּ֕יל בֵּ֥ין הַיּ֖וֹם וּבֵ֣ין הַלָּ֑יְלָה וְהָי֤וּ לְאֹתֹת֙ וּלְמ֣וֹעֲדִ֔ים וּלְיָמִ֖ים וְשָׁנִֽים׃",
21 | "וְהָי֤וּ לִמְאוֹרֹת֙ בִּרְקִ֣יעַ הַשָּׁמַ֔יִם לְהָאִ֖יר עַל־הָאָ֑רֶץ וַֽיְהִי־כֵֽן׃",
22 | "וַיַּ֣עַשׂ אֱלֹהִ֔ים אֶת־שְׁנֵ֥י הַמְּאֹרֹ֖ת הַגְּדֹלִ֑ים אֶת־הַמָּא֤וֹר הַגָּדֹל֙ לְמֶמְשֶׁ֣לֶת הַיּ֔וֹם וְאֶת־הַמָּא֤וֹר הַקָּטֹן֙ לְמֶמְשֶׁ֣לֶת הַלַּ֔יְלָה וְאֵ֖ת הַכּוֹכָבִֽים׃",
23 | "וַיִּתֵּ֥ן אֹתָ֛ם אֱלֹהִ֖ים בִּרְקִ֣יעַ הַשָּׁמָ֑יִם לְהָאִ֖יר עַל־הָאָֽרֶץ׃",
24 | "וְלִמְשֹׁל֙ בַּיּ֣וֹם וּבַלַּ֔יְלָה וּֽלֲהַבְדִּ֔יל בֵּ֥ין הָא֖וֹר וּבֵ֣ין הַחֹ֑שֶׁךְ וַיַּ֥רְא אֱלֹהִ֖ים כִּי־טֽוֹב׃",
25 | "וַֽיְהִי־עֶ֥רֶב וַֽיְהִי־בֹ֖קֶר י֥וֹם רְבִיעִֽי׃",
26 | "וַיֹּ֣אמֶר אֱלֹהִ֔ים יִשְׁרְצ֣וּ הַמַּ֔יִם שֶׁ֖רֶץ נֶ֣פֶשׁ חַיָּ֑ה וְעוֹף֙ יְעוֹפֵ֣ף עַל־הָאָ֔רֶץ עַל־פְּנֵ֖י רְקִ֥יעַ הַשָּׁמָֽיִם׃",
27 | "וַיִּבְרָ֣א אֱלֹהִ֔ים אֶת־הַתַּנִּינִ֖ם הַגְּדֹלִ֑ים וְאֵ֣ת כָּל־נֶ֣פֶשׁ הַֽחַיָּ֣ה ׀ הָֽרֹמֶ֡שֶׂת אֲשֶׁר֩ שָׁרְצ֨וּ הַמַּ֜יִם לְמִֽינֵהֶ֗ם וְאֵ֨ת כָּל־ע֤וֹף כָּנָף֙ לְמִינֵ֔הוּ וַיַּ֥רְא אֱלֹהִ֖ים כִּי־טֽוֹב׃",
28 | "וַיְבָ֧רֶךְ אֹתָ֛ם אֱלֹהִ֖ים לֵאמֹ֑ר פְּר֣וּ וּרְב֗וּ וּמִלְא֤וּ אֶת־הַמַּ֙יִם֙ בַּיַּמִּ֔ים וְהָע֖וֹף יִ֥רֶב בָּאָֽרֶץ׃",
29 | "וַֽיְהִי־עֶ֥רֶב וַֽיְהִי־בֹ֖קֶר י֥וֹם חֲמִישִֽׁי׃",
30 | "וַיֹּ֣אמֶר אֱלֹהִ֗ים תּוֹצֵ֨א הָאָ֜רֶץ נֶ֤פֶשׁ חַיָּה֙ לְמִינָ֔הּ בְּהֵמָ֥ה וָרֶ֛מֶשׂ וְחַֽיְתוֹ־אֶ֖רֶץ לְמִינָ֑הּ וַֽיְהִי־כֵֽן׃",
31 | "וַיַּ֣עַשׂ אֱלֹהִים֩ אֶת־חַיַּ֨ת הָאָ֜רֶץ לְמִינָ֗הּ וְאֶת־הַבְּהֵמָה֙ לְמִינָ֔הּ וְאֵ֛ת כָּל־רֶ֥מֶשׂ הָֽאֲדָמָ֖ה לְמִינֵ֑הוּ וַיַּ֥רְא אֱלֹהִ֖ים כִּי־טֽוֹב׃",
32 | "וַיֹּ֣אמֶר אֱלֹהִ֔ים נַֽעֲשֶׂ֥ה אָדָ֛ם בְּצַלְמֵ֖נוּ כִּדְמוּתֵ֑נוּ וְיִרְדּוּ֩ בִדְגַ֨ת הַיָּ֜ם וּבְע֣וֹף הַשָּׁמַ֗יִם וּבַבְּהֵמָה֙ וּבְכָל־הָאָ֔רֶץ וּבְכָל־הָרֶ֖מֶשׂ הָֽרֹמֵ֥שׂ עַל־הָאָֽרֶץ׃",
33 | "וַיִּבְרָ֨א אֱלֹהִ֤ים ׀ אֶת־הָֽאָדָם֙ בְּצַלְמ֔וֹ בְּצֶ֥לֶם אֱלֹהִ֖ים בָּרָ֣א אֹת֑וֹ זָכָ֥ר וּנְקֵבָ֖ה בָּרָ֥א אֹתָֽם׃",
34 | "וַיְבָ֣רֶךְ אֹתָם֮ אֱלֹהִים֒ וַיֹּ֨אמֶר לָהֶ֜ם אֱלֹהִ֗ים פְּר֥וּ וּרְב֛וּ וּמִלְא֥וּ אֶת־הָאָ֖רֶץ וְכִבְשֻׁ֑הָ וּרְד֞וּ בִּדְגַ֤ת הַיָּם֙ וּבְע֣וֹף הַשָּׁמַ֔יִם וּבְכָל־חַיָּ֖ה הָֽרֹמֶ֥שֶׂת עַל־הָאָֽרֶץ׃",
35 | "וַיֹּ֣אמֶר אֱלֹהִ֗ים הִנֵּה֩ נָתַ֨תִּי לָכֶ֜ם אֶת־כָּל־עֵ֣שֶׂב ׀ זֹרֵ֣עַ זֶ֗רַע אֲשֶׁר֙ עַל־פְּנֵ֣י כָל־הָאָ֔רֶץ וְאֶת־כָּל־הָעֵ֛ץ אֲשֶׁר־בּ֥וֹ פְרִי־עֵ֖ץ זֹרֵ֣עַ זָ֑רַע לָכֶ֥ם יִֽהְיֶ֖ה לְאָכְלָֽה׃",
36 | "וּֽלְכָל־חַיַּ֣ת הָ֠אָרֶץ וּלְכָל־ע֨וֹף הַשָּׁמַ֜יִם וּלְכֹ֣ל ׀ רוֹמֵ֣שׂ עַל־הָאָ֗רֶץ אֲשֶׁר־בּוֹ֙ נֶ֣פֶשׁ חַיָּ֔ה אֶת־כָּל־יֶ֥רֶק עֵ֖שֶׂב לְאָכְלָ֑ה וַֽיְהִי־כֵֽן׃",
37 | "וַיַּ֤רְא אֱלֹהִים֙ אֶת־כָּל־אֲשֶׁ֣ר עָשָׂ֔ה וְהִנֵּה־ט֖וֹב מְאֹ֑ד וַֽיְהִי־עֶ֥רֶב וַֽיְהִי־בֹ֖קֶר י֥וֹם הַשִּׁשִּֽׁי׃",
38 | ]
39 |
40 | nikkud = [
41 | "בְּרֵאשִׁית בָּרָא אֱלֹהִים אֵת הַשָּׁמַיִם וְאֵת הָאָרֶץ׃",
42 | "וְהָאָרֶץ הָיְתָה תֹהוּ וָבֹהוּ וְחֹשֶׁךְ עַל־פְּנֵי תְהוֹם וְרוּחַ אֱלֹהִים מְרַחֶפֶת עַל־פְּנֵי הַמָּיִם׃",
43 | "וַיֹּאמֶר אֱלֹהִים יְהִי אוֹר וַיְהִי־אוֹר׃",
44 | "וַיַּרְא אֱלֹהִים אֶת־הָאוֹר כִּי־טוֹב וַיַּבְדֵּל אֱלֹהִים בֵּין הָאוֹר וּבֵין הַחֹשֶׁךְ׃",
45 | "וַיִּקְרָא אֱלֹהִים לָאוֹר יוֹם וְלַחֹשֶׁךְ קָרָא לָיְלָה וַיְהִי־עֶרֶב וַיְהִי־בֹקֶר יוֹם אֶחָד׃",
46 | "וַיֹּאמֶר אֱלֹהִים יְהִי רָקִיעַ בְּתוֹךְ הַמָּיִם וִיהִי מַבְדִּיל בֵּין מַיִם לָמָיִם׃",
47 | "וַיַּעַשׂ אֱלֹהִים אֶת־הָרָקִיעַ וַיַּבְדֵּל בֵּין הַמַּיִם אֲשֶׁר מִתַּחַת לָרָקִיעַ וּבֵין הַמַּיִם אֲשֶׁר מֵעַל לָרָקִיעַ וַיְהִי־כֵן׃",
48 | "וַיִּקְרָא אֱלֹהִים לָרָקִיעַ שָׁמָיִם וַיְהִי־עֶרֶב וַיְהִי־בֹקֶר יוֹם שֵׁנִי׃",
49 | "וַיֹּאמֶר אֱלֹהִים יִקָּווּ הַמַּיִם מִתַּחַת הַשָּׁמַיִם אֶל־מָקוֹם אֶחָד וְתֵרָאֶה הַיַּבָּשָׁה וַיְהִי־כֵן׃",
50 | "וַיִּקְרָא אֱלֹהִים לַיַּבָּשָׁה אֶרֶץ וּלְמִקְוֵה הַמַּיִם קָרָא יַמִּים וַיַּרְא אֱלֹהִים כִּי־טוֹב׃",
51 | "וַיֹּאמֶר אֱלֹהִים תַּדְשֵׁא הָאָרֶץ דֶּשֶׁא עֵשֶׂב מַזְרִיעַ זֶרַע עֵץ פְּרִי עֹשֶׂה פְּרִי לְמִינוֹ אֲשֶׁר זַרְעוֹ־בוֹ עַל־הָאָרֶץ וַיְהִי־כֵן׃",
52 | "וַתּוֹצֵא הָאָרֶץ דֶּשֶׁא עֵשֶׂב מַזְרִיעַ זֶרַע לְמִינֵהוּ וְעֵץ עֹשֶׂה־פְּרִי אֲשֶׁר זַרְעוֹ־בוֹ לְמִינֵהוּ וַיַּרְא אֱלֹהִים כִּי־טוֹב׃",
53 | "וַיְהִי־עֶרֶב וַיְהִי־בֹקֶר יוֹם שְׁלִישִׁי׃",
54 | "וַיֹּאמֶר אֱלֹהִים יְהִי מְאֹרֹת בִּרְקִיעַ הַשָּׁמַיִם לְהַבְדִּיל בֵּין הַיּוֹם וּבֵין הַלָּיְלָה וְהָיוּ לְאֹתֹת וּלְמוֹעֲדִים וּלְיָמִים וְשָׁנִים׃",
55 | "וְהָיוּ לִמְאוֹרֹת בִּרְקִיעַ הַשָּׁמַיִם לְהָאִיר עַל־הָאָרֶץ וַיְהִי־כֵן׃",
56 | "וַיַּעַשׂ אֱלֹהִים אֶת־שְׁנֵי הַמְּאֹרֹת הַגְּדֹלִים אֶת־הַמָּאוֹר הַגָּדֹל לְמֶמְשֶׁלֶת הַיּוֹם וְאֶת־הַמָּאוֹר הַקָּטֹן לְמֶמְשֶׁלֶת הַלַּיְלָה וְאֵת הַכּוֹכָבִים׃",
57 | "וַיִּתֵּן אֹתָם אֱלֹהִים בִּרְקִיעַ הַשָּׁמָיִם לְהָאִיר עַל־הָאָרֶץ׃",
58 | "וְלִמְשֹׁל בַּיּוֹם וּבַלַּיְלָה וּלֲהַבְדִּיל בֵּין הָאוֹר וּבֵין הַחֹשֶׁךְ וַיַּרְא אֱלֹהִים כִּי־טוֹב׃",
59 | "וַיְהִי־עֶרֶב וַיְהִי־בֹקֶר יוֹם רְבִיעִי׃",
60 | "וַיֹּאמֶר אֱלֹהִים יִשְׁרְצוּ הַמַּיִם שֶׁרֶץ נֶפֶשׁ חַיָּה וְעוֹף יְעוֹפֵף עַל־הָאָרֶץ עַל־פְּנֵי רְקִיעַ הַשָּׁמָיִם׃",
61 | "וַיִּבְרָא אֱלֹהִים אֶת־הַתַּנִּינִם הַגְּדֹלִים וְאֵת כָּל־נֶפֶשׁ הַחַיָּה הָרֹמֶשֶׂת אֲשֶׁר שָׁרְצוּ הַמַּיִם לְמִינֵהֶם וְאֵת כָּל־עוֹף כָּנָף לְמִינֵהוּ וַיַּרְא אֱלֹהִים כִּי־טוֹב׃",
62 | "וַיְבָרֶךְ אֹתָם אֱלֹהִים לֵאמֹר פְּרוּ וּרְבוּ וּמִלְאוּ אֶת־הַמַּיִם בַּיַּמִּים וְהָעוֹף יִרֶב בָּאָרֶץ׃",
63 | "וַיְהִי־עֶרֶב וַיְהִי־בֹקֶר יוֹם חֲמִישִׁי׃",
64 | "וַיֹּאמֶר אֱלֹהִים תּוֹצֵא הָאָרֶץ נֶפֶשׁ חַיָּה לְמִינָהּ בְּהֵמָה וָרֶמֶשׂ וְחַיְתוֹ־אֶרֶץ לְמִינָהּ וַיְהִי־כֵן׃",
65 | "וַיַּעַשׂ אֱלֹהִים אֶת־חַיַּת הָאָרֶץ לְמִינָהּ וְאֶת־הַבְּהֵמָה לְמִינָהּ וְאֵת כָּל־רֶמֶשׂ הָאֲדָמָה לְמִינֵהוּ וַיַּרְא אֱלֹהִים כִּי־טוֹב׃",
66 | "וַיֹּאמֶר אֱלֹהִים נַעֲשֶׂה אָדָם בְּצַלְמֵנוּ כִּדְמוּתֵנוּ וְיִרְדּוּ בִדְגַת הַיָּם וּבְעוֹף הַשָּׁמַיִם וּבַבְּהֵמָה וּבְכָל־הָאָרֶץ וּבְכָל־הָרֶמֶשׂ הָרֹמֵשׂ עַל־הָאָרֶץ׃",
67 | "וַיִּבְרָא אֱלֹהִים אֶת־הָאָדָם בְּצַלְמוֹ בְּצֶלֶם אֱלֹהִים בָּרָא אֹתוֹ זָכָר וּנְקֵבָה בָּרָא אֹתָם׃",
68 | "וַיְבָרֶךְ אֹתָם אֱלֹהִים וַיֹּאמֶר לָהֶם אֱלֹהִים פְּרוּ וּרְבוּ וּמִלְאוּ אֶת־הָאָרֶץ וְכִבְשֻׁהָ וּרְדוּ בִּדְגַת הַיָּם וּבְעוֹף הַשָּׁמַיִם וּבְכָל־חַיָּה הָרֹמֶשֶׂת עַל־הָאָרֶץ׃",
69 | "וַיֹּאמֶר אֱלֹהִים הִנֵּה נָתַתִּי לָכֶם אֶת־כָּל־עֵשֶׂב זֹרֵעַ זֶרַע אֲשֶׁר עַל־פְּנֵי כָל־הָאָרֶץ וְאֶת־כָּל־הָעֵץ אֲשֶׁר־בּוֹ פְרִי־עֵץ זֹרֵעַ זָרַע לָכֶם יִהְיֶה לְאָכְלָה׃",
70 | "וּלְכָל־חַיַּת הָאָרֶץ וּלְכָל־עוֹף הַשָּׁמַיִם וּלְכֹל רוֹמֵשׂ עַל־הָאָרֶץ אֲשֶׁר־בּוֹ נֶפֶשׁ חַיָּה אֶת־כָּל־יֶרֶק עֵשֶׂב לְאָכְלָה וַיְהִי־כֵן׃",
71 | "וַיַּרְא אֱלֹהִים אֶת־כָּל־אֲשֶׁר עָשָׂה וְהִנֵּה־טוֹב מְאֹד וַיְהִי־עֶרֶב וַיְהִי־בֹקֶר יוֹם הַשִּׁשִּׁי׃",
72 | ]
73 |
74 | text_only = [
75 | "בראשית ברא אלהים את השמים ואת הארץ",
76 | "והארץ היתה תהו ובהו וחשך על־פני תהום ורוח אלהים מרחפת על־פני המים",
77 | "ויאמר אלהים יהי אור ויהי־אור",
78 | "וירא אלהים את־האור כי־טוב ויבדל אלהים בין האור ובין החשך",
79 | "ויקרא אלהים לאור יום ולחשך קרא לילה ויהי־ערב ויהי־בקר יום אחד",
80 | "ויאמר אלהים יהי רקיע בתוך המים ויהי מבדיל בין מים למים",
81 | "ויעש אלהים את־הרקיע ויבדל בין המים אשר מתחת לרקיע ובין המים אשר מעל לרקיע ויהי־כן",
82 | "ויקרא אלהים לרקיע שמים ויהי־ערב ויהי־בקר יום שני",
83 | "ויאמר אלהים יקוו המים מתחת השמים אל־מקום אחד ותראה היבשה ויהי־כן",
84 | "ויקרא אלהים ליבשה ארץ ולמקוה המים קרא ימים וירא אלהים כי־טוב",
85 | "ויאמר אלהים תדשא הארץ דשא עשב מזריע זרע עץ פרי עשה פרי למינו אשר זרעו־בו על־הארץ ויהי־כן",
86 | "ותוצא הארץ דשא עשב מזריע זרע למינהו ועץ עשה־פרי אשר זרעו־בו למינהו וירא אלהים כי־טוב",
87 | "ויהי־ערב ויהי־בקר יום שלישי",
88 | "ויאמר אלהים יהי מארת ברקיע השמים להבדיל בין היום ובין הלילה והיו לאתת ולמועדים ולימים ושנים",
89 | "והיו למאורת ברקיע השמים להאיר על־הארץ ויהי־כן",
90 | "ויעש אלהים את־שני המארת הגדלים את־המאור הגדל לממשלת היום ואת־המאור הקטן לממשלת הלילה ואת הכוכבים",
91 | "ויתן אתם אלהים ברקיע השמים להאיר על־הארץ",
92 | "ולמשל ביום ובלילה ולהבדיל בין האור ובין החשך וירא אלהים כי־טוב",
93 | "ויהי־ערב ויהי־בקר יום רביעי",
94 | "ויאמר אלהים ישרצו המים שרץ נפש חיה ועוף יעופף על־הארץ על־פני רקיע השמים",
95 | "ויברא אלהים את־התנינם הגדלים ואת כל־נפש החיה הרמשת אשר שרצו המים למינהם ואת כל־עוף כנף למינהו וירא אלהים כי־טוב",
96 | "ויברך אתם אלהים לאמר פרו ורבו ומלאו את־המים בימים והעוף ירב בארץ",
97 | "ויהי־ערב ויהי־בקר יום חמישי",
98 | "ויאמר אלהים תוצא הארץ נפש חיה למינה בהמה ורמש וחיתו־ארץ למינה ויהי־כן",
99 | "ויעש אלהים את־חית הארץ למינה ואת־הבהמה למינה ואת כל־רמש האדמה למינהו וירא אלהים כי־טוב",
100 | "ויאמר אלהים נעשה אדם בצלמנו כדמותנו וירדו בדגת הים ובעוף השמים ובבהמה ובכל־הארץ ובכל־הרמש הרמש על־הארץ",
101 | "ויברא אלהים את־האדם בצלמו בצלם אלהים ברא אתו זכר ונקבה ברא אתם",
102 | "ויברך אתם אלהים ויאמר להם אלהים פרו ורבו ומלאו את־הארץ וכבשה ורדו בדגת הים ובעוף השמים ובכל־חיה הרמשת על־הארץ",
103 | "ויאמר אלהים הנה נתתי לכם את־כל־עשב זרע זרע אשר על־פני כל־הארץ ואת־כל־העץ אשר־בו פרי־עץ זרע זרע לכם יהיה לאכלה",
104 | "ולכל־חית הארץ ולכל־עוף השמים ולכל רומש על־הארץ אשר־בו נפש חיה את־כל־ירק עשב לאכלה ויהי־כן",
105 | "וירא אלהים את־כל־אשר עשה והנה־טוב מאד ויהי־ערב ויהי־בקר יום הששי",
106 | ]
107 |
108 |
109 | def test_str():
110 | hs = Hebrew("בְּרֵאשִׁ֖ית")
111 | assert hs.__str__() == "בְּרֵאשִׁ֖ית"
112 |
113 |
114 | def test_repr():
115 | hs = Hebrew("בְּרֵאשִׁ֖ית")
116 | assert hs.__repr__() == "בְּרֵאשִׁ֖ית"
117 |
118 |
119 | @pytest.mark.parametrize("pasuk", [(p) for p in taamei_hamikra])
120 | def test_as_str(pasuk):
121 | hs = Hebrew(pasuk)
122 | assert hs.string == pasuk
123 |
124 |
125 | @pytest.mark.parametrize("pasuk", [(p) for p in taamei_hamikra])
126 | def test_no_maqaf(pasuk):
127 | assert Hebrew(pasuk).no_maqaf().string == pasuk.replace(MAQAF.char, " ")
128 |
129 |
130 | @pytest.mark.parametrize("pasuk", [(p) for p in taamei_hamikra])
131 | def test_no_sof_passuk(pasuk):
132 | assert Hebrew(pasuk).no_sof_passuk().string == pasuk.replace(SOF_PASSUK.char, "")
133 |
134 |
135 | @pytest.mark.parametrize(
136 | "pasuk,pasuk_text_only", [p for p in zip(taamei_hamikra, text_only)]
137 | )
138 | def test_text_only(pasuk, pasuk_text_only):
139 | hs = Hebrew(pasuk)
140 | assert hs.text_only(remove_maqaf=False).string == pasuk_text_only
141 | assert hs.text_only(remove_maqaf=True).string == pasuk_text_only.replace(
142 | MAQAF.char, " "
143 | )
144 |
145 |
146 | def test_text_only_with_other_chars():
147 | hs = Hebrew(
148 | "In the beginning of this text is english followed by בְּרֵאשִׁ֖ית\tCool, eh? 😊"
149 | )
150 | assert (
151 | hs.text_only().string
152 | == "In the beginning of this text is english followed by בראשית\tCool, eh? 😊"
153 | )
154 |
155 |
156 | def test_words():
157 | pasuk = Hebrew(taamei_hamikra[1])
158 | assert len(pasuk.words(split_maqaf=False)) == 12
159 | assert len(pasuk.words(split_maqaf=True)) == 14
160 |
161 |
162 | def test_no_niqqud():
163 | hs = Hebrew("וַֽיְהִי־עֶ֥רֶב וַֽיְהִי־בֹ֖קֶר י֥וֹם רְבִיעִֽי׃")
164 | assert hs.no_niqqud().string == "וֽיהי־ע֥רב וֽיהי־ב֖קר י֥ום רביעֽי׃"
165 |
166 |
167 | def test_no_taamim():
168 | hs = Hebrew(taamei_hamikra[1])
169 | assert hs.no_taamim(remove_maqaf=False, remove_sof_passuk=False).string == nikkud[1]
170 | assert hs.no_taamim(remove_maqaf=False, remove_sof_passuk=True).string == nikkud[
171 | 1
172 | ].replace(SOF_PASSUK.char, "")
173 | assert hs.no_taamim(remove_maqaf=True, remove_sof_passuk=False).string == nikkud[
174 | 1
175 | ].replace(MAQAF.char, " ")
176 |
177 |
178 | def test_normalize_single_char():
179 | assert Hebrew("ℵ").normalize().string == "א"
180 | assert Hebrew("ℶ").normalize().string == "ב"
181 | assert Hebrew("ℷ").normalize().string == "ג"
182 | assert Hebrew("ℸ").normalize().string == "ד"
183 | assert Hebrew("יִ").normalize().string == "יִ"
184 | assert Hebrew("ﬠ").normalize().string == "ע"
185 | assert Hebrew("ﬡ").normalize().string == "א"
186 | assert Hebrew("ﬢ").normalize().string == "ד"
187 | assert Hebrew("ﬣ").normalize().string == "ה"
188 | assert Hebrew("ﬤ").normalize().string == "כ"
189 | assert Hebrew("ﬥ").normalize().string == "ל"
190 | assert Hebrew("ﬦ").normalize().string == "ם"
191 | assert Hebrew("ﬧ").normalize().string == "ר"
192 | assert Hebrew("ﬨ").normalize().string == "ת"
193 | assert Hebrew("שׁ").normalize().string == "שׁ"
194 | assert Hebrew("שׂ").normalize().string == "שׂ"
195 | assert Hebrew("שּׁ").normalize().string == "שּׁ"
196 | assert Hebrew("אַ").normalize().string == "אַ"
197 | assert Hebrew("אָ").normalize().string == "אָ"
198 | assert Hebrew("אּ").normalize().string == "אּ"
199 | assert Hebrew("בּ").normalize().string == "בּ"
200 | assert Hebrew("גּ").normalize().string == "גּ"
201 | assert Hebrew("דּ").normalize().string == "דּ"
202 | assert Hebrew("הּ").normalize().string == "הּ"
203 | assert Hebrew("וּ").normalize().string == "וּ"
204 | assert Hebrew("זּ").normalize().string == "זּ"
205 | assert Hebrew("טּ").normalize().string == "טּ"
206 | assert Hebrew("יּ").normalize().string == "יּ"
207 | assert Hebrew("ךּ").normalize().string == "ךּ"
208 | assert Hebrew("כּ").normalize().string == "כּ"
209 | assert Hebrew("לּ").normalize().string == "לּ"
210 | assert Hebrew("מּ").normalize().string == "מּ"
211 | assert Hebrew("נּ").normalize().string == "נּ"
212 | assert Hebrew("סּ").normalize().string == "סּ"
213 | assert Hebrew("ףּ").normalize().string == "ףּ"
214 | assert Hebrew("פּ").normalize().string == "פּ"
215 | assert Hebrew("צּ").normalize().string == "צּ"
216 | assert Hebrew("קּ").normalize().string == "קּ"
217 | assert Hebrew("רּ").normalize().string == "רּ"
218 | assert Hebrew("שּ").normalize().string == "שּ"
219 | assert Hebrew("תּ").normalize().string == "תּ"
220 | assert Hebrew("וֹ").normalize().string == "וֹ"
221 | assert Hebrew("בֿ").normalize().string == "בֿ"
222 | assert Hebrew("כֿ").normalize().string == "כֿ"
223 | assert Hebrew("פֿ").normalize().string == "פֿ"
224 | assert Hebrew("ﭏ").normalize().string == "אל"
225 |
226 |
227 | def test_normalize_yiddish_char():
228 | assert Hebrew("ײַ").normalize(True).string == "יַי"
229 | assert Hebrew("ײ").normalize(True).string == "יי"
230 | assert Hebrew("װ").normalize(True).string == "וו"
231 | assert Hebrew("ױ").normalize(True).string == "יו"
232 | assert Hebrew("ײַ").normalize().string == "ײַ"
233 | assert Hebrew("ײ").normalize().string == "ײ"
234 | assert Hebrew("װ").normalize().string == "װ"
235 | assert Hebrew("ױ").normalize().string == "ױ"
236 |
237 |
238 | def test_normalize_multiple_abnormal_chars():
239 | assert Hebrew("זּטּ").normalize().string == "זּטּ"
240 |
241 |
242 | def test_normalize_mixed_chars():
243 | assert Hebrew("אזּטּ").normalize().string == "אזּטּ"
244 |
--------------------------------------------------------------------------------
/hebrew/chars.py:
--------------------------------------------------------------------------------
1 | """
2 | Constants for each Hebrew character and classes to represent them, and metadata about them.
3 | """
4 |
5 | from dataclasses import dataclass
6 | from typing import Optional, List, Dict, Union
7 |
8 | from hebrew.gematria import (
9 | MISPAR_HECHRACHI,
10 | MISPAR_GADOL,
11 | MISPAR_KATAN,
12 | MISPAR_SIDURI,
13 | MISPAR_PERATI,
14 | ATBASH,
15 | ALBAM,
16 | MISPAR_MESHULASH,
17 | MISPAR_KIDMI,
18 | MISPAR_MISPARI,
19 | AYAK_BACHAR,
20 | OFANIM,
21 | ACHAS_BETA,
22 | AVGAD,
23 | REVERSE_AVGAD,
24 | )
25 |
26 |
27 | # TODO: Future properties:
28 | # - Number/order of the char in aleph bes if the letter is HebrewCharTypes.Letter.
29 | # - Maybe a reference to a minor/final letter when applicable.
30 | # - Gematria value of the letter for future use in `Hebrew` methods such as
31 | # `Hebrew.get_gematria_value(type=Gematria.MisparGadol)`.
32 | # - This is a bit tricky because the gematria value of a letter is not a single value, there are different values
33 | # used by different systems.
34 | @dataclass
35 | class BaseHebrewChar:
36 | """
37 | Base class with the metadata that all Hebrew characters share.
38 | This class should be used internally by `hebrew.Chars` only.
39 | """
40 |
41 | char: str
42 | """Unicode character(s) for this class instance."""
43 |
44 | name: str
45 | """Primary name of the character in English."""
46 |
47 | hebrew_name: Optional[str] = None
48 | """
49 | Primary name of the character in Hebrew.
50 |
51 | The choice of primary name is non trivial as it is used as the primary spelling
52 | for the Mispar Shemi Gematria method.
53 | """
54 |
55 | name_alts: Optional[List[str]] = None
56 | """Alternative names of the character in English."""
57 |
58 | hebrew_name_alts: Optional[List[str]] = None
59 | """Alternative names of the character in Hebrew."""
60 |
61 | @property
62 | def hebrew_names(self) -> List[str]:
63 | """
64 | All Hebrew names for this character.
65 | :return: A list of all Hebrew names for this character made up of the `hebrew_name` and `hebrew_name_alts`.
66 | """
67 | return [self.hebrew_name] + (self.hebrew_name_alts or [])
68 |
69 | @property
70 | def names(self) -> List[str]:
71 | """
72 | All english names for this character.
73 | :return: A list of all english names for this character made up of the `name` and `name_alts`.
74 | """
75 | return [self.name] + (self.name_alts or [])
76 |
77 | def __str__(self):
78 | return self.char
79 |
80 |
81 | @dataclass
82 | class HebrewChar(BaseHebrewChar):
83 | """
84 | A class representing characters that are part of the Hebrew alphabet (to the exclusion of Nekuds, etc).
85 | """
86 |
87 | final_letter: bool = False
88 | """Whether or not the letter is a "final" or "Sofit" letter."""
89 |
90 | @property
91 | def base_letter(self) -> "HebrewChar":
92 | """
93 | Returns the base letter of the character.
94 |
95 | This library provides HebrewChar values for both standard Hebrew letters and user-perceived letters such as "בּ".
96 | This property will always return the base letter of the HebrewChar instance, in the above example, "ב".
97 |
98 | :return: An instance of `HebrewChar` representing a single unicode character; the base letter of
99 | this instance of `HebrewChar`.
100 | """
101 | return CHARS[self.char[0]]
102 |
103 | @property
104 | def mispar_hechrachi(self) -> int:
105 | """
106 | :return: The value of the character for use in the mispar_hechrachi method of gematria.
107 | """
108 | return MISPAR_HECHRACHI.get(self.base_letter.char)
109 |
110 | @property
111 | def mispar_gadol(self) -> int:
112 | """
113 | :return: The value of the character for use in the mispar_gadol method of gematria.
114 | """
115 | return MISPAR_GADOL.get(self.base_letter.char)
116 |
117 | @property
118 | def mispar_siduri(self) -> int:
119 | """
120 | :return: The value of the character for use in the mispar_siduri method of gematria.
121 | """
122 | return MISPAR_SIDURI.get(self.base_letter.char)
123 |
124 | @property
125 | def mispar_katan(self) -> int:
126 | """
127 | :return: The value of the character for use in the mispar_katan method of gematria.
128 | """
129 | return MISPAR_KATAN.get(self.base_letter.char)
130 |
131 | @property
132 | def mispar_perati(self) -> int:
133 | """
134 | :return: The value of the character for use in the mispar_perati method of gematria.
135 | """
136 | return MISPAR_PERATI.get(self.base_letter.char)
137 |
138 | @property
139 | def atbash(self) -> int:
140 | """
141 | :return: The value of the character for use in the AtBash method of gematria.
142 | """
143 | return ATBASH.get(self.base_letter.char)
144 |
145 | @property
146 | def albam(self) -> int:
147 | """
148 | :return: The value of the character for use in the AtBash method of gematria.
149 | """
150 | return ALBAM.get(self.base_letter.char)
151 |
152 | @property
153 | def mispar_meshulash(self) -> int:
154 | """
155 | :return: The value of the character for use in the AtBash method of gematria.
156 | """
157 | return MISPAR_MESHULASH.get(self.base_letter.char)
158 |
159 | @property
160 | def mispar_kidmi(self) -> int:
161 | """
162 | :return: The value of the character for use in the mispar_kidmi method of gematria.
163 | """
164 | return MISPAR_KIDMI.get(self.base_letter.char)
165 |
166 | @property
167 | def mispar_mispari(self) -> int:
168 | """
169 | :return: The value of the character for use in the mispar_mispari method of gematria.
170 | """
171 | return MISPAR_MISPARI.get(self.base_letter.char)
172 |
173 | @property
174 | def ayak_bachar(self) -> int:
175 | """
176 | :return: The value of the character for use in the ayak_bachar method of gematria.
177 | """
178 | return AYAK_BACHAR.get(self.base_letter.char)
179 |
180 | @property
181 | def ofanim(self) -> int:
182 | """
183 | :return: The value of the character for use in the ofanim method of gematria.
184 | """
185 | return OFANIM.get(self.base_letter.char)
186 |
187 | @property
188 | def achas_beta(self) -> int:
189 | """
190 | :return: The value of the character for use in the achas_beta method of gematria.
191 | """
192 | return ACHAS_BETA.get(self.base_letter.char)
193 |
194 | @property
195 | def avgad(self) -> int:
196 | """
197 | :return: The value of the character for use in the avgad method of gematria.
198 | """
199 | return AVGAD.get(self.base_letter.char)
200 |
201 | @property
202 | def reverse_avgad(self) -> int:
203 | """
204 | :return: The value of the character for use in the reverse_avgad method of gematria.
205 | """
206 | return REVERSE_AVGAD.get(self.base_letter.char)
207 |
208 | @classmethod
209 | def search(cls, char_name: str) -> Optional["HebrewChar"]:
210 | """
211 | Searches for an instance of `HebrewChar` by name.
212 | The search input is case insensitive and is compared to `names` list for this search.
213 |
214 | To search for any Hebrew character, use `hebrew.chars.char_search`.
215 |
216 | :param char_name: A single string representing the name of the character to search for.
217 | :return: An instance of `HebrewChar` representing the character with the given name, or `None` if no
218 | character is found.
219 | """
220 | return char_search(char_name, HEBREW_CHARS)
221 |
222 | def __hash__(self):
223 | return hash(self.char)
224 |
225 |
226 | @dataclass
227 | class YiddishChar(BaseHebrewChar):
228 | """
229 | A class representing special characters used in Yiddish text.
230 | """
231 |
232 | @classmethod
233 | def search(cls, char_name: str) -> Optional["YiddishChar"]:
234 | """
235 | Searches for an instance of `YiddishChar` by name.
236 | The search input is case insensitive and is compared to `names` list for this search.
237 |
238 | To search for any Hebrew character, use `hebrew.chars.char_search`.
239 |
240 | :param char_name: A single string representing the name of the character to search for.
241 | :return: An instance of `YiddishChar` representing the character with the given name, or `None` if no
242 | character is found.
243 | """
244 | return char_search(char_name, YIDDISH_CHARS)
245 |
246 | def __hash__(self):
247 | return hash(self.char)
248 |
249 |
250 | @dataclass
251 | class NiqqudChar(BaseHebrewChar):
252 | """
253 | A class representing Niqqud characters used in Hebrew and Yiddish text.
254 | """
255 |
256 | @classmethod
257 | def search(cls, char_name: str) -> Optional["NiqqudChar"]:
258 | """
259 | Searches for an instance of `NiqqudChar` by name.
260 | The search input is case insensitive and is compared to `names` list for this search.
261 |
262 | To search for any Hebrew character, use `hebrew.chars.char_search`.
263 |
264 | :param char_name: A single string representing the name of the character to search for.
265 | :return: An instance of `NiqqudChar` representing the character with the given name, or `None` if no
266 | character is found.
267 | """
268 | return char_search(char_name, NIQQUD_CHARS)
269 |
270 | def __hash__(self):
271 | return hash(self.char)
272 |
273 |
274 | @dataclass
275 | class TaamimChar(BaseHebrewChar):
276 | """
277 | A class representing the "Trup" or [Hebrew cantillation](https://en.wikipedia.org/wiki/Hebrew_cantillation)
278 | characters used alongside Hebrew letters.
279 | """
280 |
281 | @classmethod
282 | def search(cls, char_name: str) -> Optional["TaamimChar"]:
283 | """
284 | Searches for an instance of `TaamimChar` by name.
285 | The search input is case insensitive and is compared to `names` list for this search.
286 |
287 | To search for any Hebrew character, use `hebrew.chars.char_search`.
288 |
289 | :param char_name: A single string representing the name of the character to search for.
290 | :return: An instance of `TaamimChar` representing the character with the given name, or `None` if no
291 | character is found.
292 | """
293 | return char_search(char_name, TAAMIM_CHARS)
294 |
295 | def __hash__(self):
296 | return hash(self.char)
297 |
298 |
299 | @dataclass
300 | class OtherChar(BaseHebrewChar):
301 | """
302 | A class representing the "other" or "uncharacterized" characters used in Hebrew (and Yiddish) text.
303 | """
304 |
305 | @classmethod
306 | def search(cls, char_name: str) -> Optional["OtherChar"]:
307 | """
308 | Searches for an instance of `TaamimChar` by name.
309 | The search input is case insensitive and is compared to `names` list for this search.
310 |
311 | To search for any Hebrew character, use `hebrew.chars.char_search`.
312 |
313 | :param char_name: A single string representing the name of the character to search for.
314 | :return: An instance of `OtherChar` representing the character with the given name, or `None` if no
315 | character is found.
316 | """
317 | return char_search(char_name, OTHER_CHARS)
318 |
319 | def __hash__(self):
320 | return hash(self.char)
321 |
322 |
323 | # TODO:
324 | # - Populate the alt hebrew and english names with additional spellings, this is helpful for the
325 | # `HebrewGlyph.search()` method.
326 | # - Add the rest of the hebrew unicode characters as `HebrewChar` instances instead of plain strings`
327 |
328 |
329 | ALEPH = HebrewChar(char="א", name="Aleph", hebrew_name="אָלֶף", name_alts=["Alef"])
330 | """An instance of `HebrewChar` representing the letter `'א'`"""
331 |
332 | BET = HebrewChar(char="בּ", name="Bet", hebrew_name="בֵּית", hebrew_name_alts=["בת"])
333 | """
334 | An instance of `HebrewChar` representing the letter **`'בּ'`**.
335 | *This is not strictly a letter, but is included because it is often treated as one.*
336 | """
337 |
338 | BES = BET
339 | """Simple pointer to `BET`."""
340 |
341 | VET = HebrewChar(char="ב", name="Vet", hebrew_name="בֵית", hebrew_name_alts=["בת"])
342 | """An instance of `HebrewChar` representing the letter **`'ב'`**."""
343 |
344 | GIMEL = HebrewChar(
345 | char="ג", name="Gimel", hebrew_name="גִימֵל", hebrew_name_alts=["גמל"]
346 | )
347 | """An instance of `HebrewChar` representing the letter **`'ג'`**."""
348 |
349 | DALET = HebrewChar(
350 | char="ד",
351 | name="Dalet",
352 | hebrew_name="דָלֶת",
353 | hebrew_name_alts=["דלית"],
354 | name_alts=["Daled"],
355 | )
356 | """An instance of `HebrewChar` representing the letter **`'ד'`**."""
357 |
358 | DALED = DALET
359 | """Simple pointer to `DALET`."""
360 |
361 | HE = HebrewChar(
362 | char="ה",
363 | name="He",
364 | hebrew_name="הֵא",
365 | hebrew_name_alts=["הי", "הה"],
366 | name_alts=["Hei", "Hey"],
367 | )
368 | """An instance of `HebrewChar` representing the letter **`'ה'`**."""
369 |
370 | HEI = HEY = HE
371 | """Simple pointer to `HE`."""
372 |
373 | VAV = HebrewChar(
374 | char="ו",
375 | name="Vav",
376 | hebrew_name="וָו",
377 | hebrew_name_alts=["ויו", "ואו"],
378 | name_alts=["Vuv"],
379 | )
380 | """An instance of `HebrewChar` representing the letter **`'ו'`**."""
381 |
382 | VUV = VAV
383 | """Simple pointer to `VAV`."""
384 |
385 | ZAYIN = HebrewChar(char="ז", name="Zayin", hebrew_name="זַיִן")
386 | """An instance of `HebrewChar` representing the letter **`'ז'`**."""
387 |
388 | CHET = HebrewChar(
389 | char="ח",
390 | name="Chet",
391 | hebrew_name="חֵית",
392 | hebrew_name_alts=["חת"],
393 | name_alts=["Het", "Ches"],
394 | )
395 | """An instance of `HebrewChar` representing the letter **`'ז'`**."""
396 |
397 | HET = CHES = CHET
398 | """Simple pointer to `CHET`."""
399 |
400 | TET = HebrewChar(
401 | char="ט", name="Tet", hebrew_name="טֵית", hebrew_name_alts=["טת"], name_alts=["Tes"]
402 | )
403 | """An instance of `HebrewChar` representing the letter **`'ט'`**."""
404 |
405 | TES = TET
406 | """Simple pointer to `TET`."""
407 |
408 | YOD = HebrewChar(char="י", name="Yod", hebrew_name="יוֹד", name_alts=["Yud"])
409 | """An instance of `HebrewChar` representing the letter **`'י'`**."""
410 |
411 | YUD = YOD
412 | """Simple pointer to `YOD`."""
413 |
414 | CAF = HebrewChar(char="כּ", name="Kaf", hebrew_name="כַּף")
415 | """
416 | An instance of `HebrewChar` representing the letter **`'כּ'`**.
417 | *This is not strictly a letter, but is included because it is often treated as one.*
418 | """
419 |
420 | KAF_SOFIT = HebrewChar(
421 | char="ךּ",
422 | name="Kaf Sofit",
423 | final_letter=True,
424 | hebrew_name="כַּף סוֹפִית",
425 | name_alts=["Final Kaf"],
426 | )
427 | """
428 | An instance of `HebrewChar` representing the letter **`'ךּ'`**.
429 | *This is not strictly a letter, but is included because it is often treated as one.*
430 | """
431 |
432 | FINAL_KAF = KAF_SOFIT
433 | """Simple pointer to `KAF_SOFIT`."""
434 |
435 | CHAF = HebrewChar(char="כ", name="Chaf", hebrew_name="כַף")
436 | """An instance of `HebrewChar` representing the letter **`'כ'`**."""
437 |
438 | CHAF_SOFIT = HebrewChar(
439 | char="ך",
440 | name="Chaf Sofit",
441 | final_letter=True,
442 | hebrew_name="כַף סוֹפִית",
443 | name_alts=["Final Chaf"],
444 | )
445 | """An instance of `HebrewChar` representing the letter **`'ך'`**."""
446 |
447 | FINAL_CHAF = CHAF_SOFIT
448 | """Simple pointer to `CHAF_SOFIT`."""
449 |
450 | LAMED = HebrewChar(
451 | char="ל",
452 | name="Lamed",
453 | hebrew_name="לָמֶד",
454 | name_alts=["Lamid"],
455 | )
456 | """An instance of `HebrewChar` representing the letter **`'ל'`**."""
457 |
458 | LAMID = LAMED
459 | """Simple pointer to `LAMED`."""
460 |
461 | MEM = HebrewChar(char="מ", name="Mem", hebrew_name="מֵם")
462 | """An instance of `HebrewChar` representing the letter **`'מ'`**."""
463 |
464 | MEM_SOFIT = HebrewChar(
465 | char="ם",
466 | name="Mem Sofit",
467 | final_letter=True,
468 | hebrew_name="מֵם סוֹפִית",
469 | name_alts=["Final Mem"],
470 | )
471 | """An instance of `HebrewChar` representing the letter **`'ם'`**."""
472 |
473 | FINAL_MEM = MEM_SOFIT
474 | """Simple pointer to `MEM_SOFIT`."""
475 |
476 | NUN = HebrewChar(char="נ", name="Nun", hebrew_name="נוּן")
477 | """An instance of `HebrewChar` representing the letter **`'נ'`**."""
478 |
479 | NUN_SOFIT = HebrewChar(
480 | char="ן",
481 | name="Nun Sofit",
482 | final_letter=True,
483 | hebrew_name="נוּן סוֹפִית",
484 | name_alts=["Final Nun"],
485 | )
486 | """An instance of `HebrewChar` representing the letter **`'ן'`**."""
487 |
488 | FINAL_NUN = NUN_SOFIT
489 | """Simple pointer to `NUN_SOFIT`."""
490 |
491 | SAMEKH = HebrewChar(
492 | char="ס",
493 | name="Samekh",
494 | hebrew_name="סָמֶך",
495 | name_alts=["Samach"],
496 | )
497 | """An instance of `HebrewChar` representing the letter **`'ס'`**."""
498 |
499 | SAMACH = SAMEKH
500 | """Simple pointer to `SAMEKH`."""
501 |
502 | AYIN = HebrewChar(char="ע", name="Ayin", hebrew_name="עַיִן")
503 | """An instance of `HebrewChar` representing the letter **`'ע'`**."""
504 |
505 | PE = HebrewChar(char="פּ", name="Pe", hebrew_name_alts=["פי", "פה"])
506 | """
507 | An instance of `HebrewChar` representing the letter **`'פּ'`**.
508 | *This is not strictly a letter, but is included because it is often treated as one.*
509 | """
510 |
511 | FE = HebrewChar(char="פ", name="Fe", hebrew_name="פֵא", hebrew_name_alts=["פי", "פה"])
512 | """An instance of `HebrewChar` representing the letter **`'פ'`**."""
513 |
514 | PE_SOFIT = HebrewChar(
515 | char="ףּ",
516 | name="Fe Sofit",
517 | final_letter=True,
518 | hebrew_name="פֵּא סוֹפִית",
519 | name_alts=["Final Pe"],
520 | )
521 | """
522 | An instance of `HebrewChar` representing the letter **`'ףּ'`**.
523 | *This is not strictly a letter, but is included because it is often treated as one.*
524 | """
525 |
526 | FINAL_PE = PE_SOFIT
527 | """Simple pointer to `PE_SOFIT`."""
528 |
529 | FE_SOFIT = HebrewChar(
530 | char="ף",
531 | name="Fe Sofit",
532 | final_letter=True,
533 | hebrew_name="פֵא סוֹפִית",
534 | name_alts=["Final Fe"],
535 | )
536 | """An instance of `HebrewChar` representing the letter **`'ף'`**."""
537 |
538 | FINAL_FE = FE_SOFIT
539 | """Simple pointer to `FE_SOFIT`."""
540 |
541 | TSADI = HebrewChar(
542 | char="צ",
543 | name="Tsadi",
544 | hebrew_name="צַדִי",
545 | hebrew_name_alts=["צדיק"],
546 | name_alts=["Tzadik"],
547 | )
548 | """An instance of `HebrewChar` representing the letter **`'צ'`**."""
549 |
550 | TZADIK = TSADI
551 | """Simple pointer to `TSADI`."""
552 |
553 | TSADI_SOFIT = HebrewChar(
554 | char="ץ",
555 | name="Tsadi Sofit",
556 | final_letter=True,
557 | hebrew_name="צַדִי סוֹפִית",
558 | hebrew_name_alts=["צדיק סופית"],
559 | )
560 | """An instance of `HebrewChar` representing the letter **`'ץ'`**."""
561 |
562 | FINAL_TSADI = TZADIK_SOFIT = FINAL_TZADIK = TSADI_SOFIT
563 | """Simple pointer to `TSADI_SOFIT`."""
564 |
565 | QOF = HebrewChar(char="ק", name="Qof", hebrew_name="קוֹף", name_alts=["Kuf"])
566 | """An instance of `HebrewChar` representing the letter **`'ק'`**."""
567 |
568 | KUF = QOF
569 | """Simple pointer to `TSADI_SOFIT`."""
570 |
571 | RESH = HebrewChar(char="ר", name="Resh", hebrew_name="רֵישׁ", hebrew_name_alts=["רש"])
572 | """An instance of `HebrewChar` representing the letter **`'ר'`**."""
573 |
574 | # TODO: The naming here might need help. We should definitely support all 3 versions as this is likely to be found
575 | # in text, but the naming might be unexpected.
576 | SHIN = HebrewChar(
577 | char="שׁ", name="Shin", hebrew_name="שִׁן", hebrew_name_alts=["שִׁין"]
578 | )
579 | """
580 | An instance of `HebrewChar` representing the letter **`'שׁ'`**.
581 | *This is not strictly a letter, but is included because it is often treated as one.*
582 | """
583 |
584 | SIN = HebrewChar(char="שׂ", name="Sin", hebrew_name="שִׂן", hebrew_name_alts=["שִׂין"])
585 | """
586 | An instance of `HebrewChar` representing the letter **`'שׂ'`**.
587 | *This is not strictly a letter, but is included because it is often treated as one.*
588 | """
589 |
590 | PLAIN_SIN = HebrewChar(
591 | char="ש", name="Plain Sin", hebrew_name="שִׂן", hebrew_name_alts=["שִׂין"]
592 | )
593 | """An instance of `HebrewChar` representing the letter **`'ש'`**."""
594 |
595 | TAV = HebrewChar(
596 | char="תּ",
597 | name="Tav",
598 | hebrew_name="תּו",
599 | hebrew_name_alts=["תיו", "תאו"],
600 | name_alts=["Taf"],
601 | )
602 | """
603 | An instance of `HebrewChar` representing the letter **`'תּ'`**.
604 | *This is not strictly a letter, but is included because it is often treated as one.*
605 | """
606 |
607 | TAF = TAV
608 | """Simple pointer to `TAV`."""
609 |
610 | SAV = HebrewChar(
611 | char="ת",
612 | name="Sav",
613 | hebrew_name="תָו",
614 | name_alts=["Saf"],
615 | hebrew_name_alts=["תיו", "תאו"],
616 | )
617 | """An instance of `HebrewChar` representing the letter **`'ת'`**."""
618 |
619 | ALEPH_SYMBOL = HebrewChar("ℵ", name="Aleph Symbol")
620 | """An instance of `HebrewChar` representing the letter **`'ℵ'`**. This is a rarely used special character."""
621 | BET_SYMBOL = HebrewChar("ℶ", name="Bet Symbol")
622 | """An instance of `HebrewChar` representing the letter **`'ℶ'`**. This is a rarely used special character."""
623 | GIMEL_SYMBOL = HebrewChar("ℷ", name="Gimel Symbol")
624 | """An instance of `HebrewChar` representing the letter **`'ℷ'`**. This is a rarely used special character."""
625 | DALET_SYMBOL = HebrewChar("ℸ", name="Dalet Symbol")
626 | """An instance of `HebrewChar` representing the letter **`'ℸ'`**. This is a rarely used special character."""
627 | YOD_HIRIQ = HebrewChar("יִ", name="Yod with Hiriq")
628 | """An instance of `HebrewChar` representing the letter **`'יִ'`**. This is a rarely used special character."""
629 | YOD_YOD_PATAH = YiddishChar("ײַ", name="Yod Yod Patah")
630 | """An instance of `YiddishChar` representing the letter **`'ײַ'`**. This is a rarely used special character."""
631 | YOD_YOD_PATAH2 = YiddishChar("ײַ", name="Yod Yod Patah")
632 | """An instance of `YiddishChar` representing the letters **`'ײַ'`**. This is a variation of YOD_YOD_PATAH made up of a double Yud, and a Patah."""
633 | AYIN_ALT = HebrewChar("ﬠ", name="Alternative Ayin")
634 | """An instance of `HebrewChar` representing the letter **`'ﬠ'`**. This is a rarely used special character."""
635 | ALEF_WIDE = HebrewChar("ﬡ", name="Wide Alef")
636 | """An instance of `HebrewChar` representing the letter **`'ﬡ'`**. This is a rarely used special character."""
637 | DALET_WIDE = HebrewChar("ﬢ", name="Wide Dalet")
638 | """An instance of `HebrewChar` representing the letter **`'ﬢ'`**. This is a rarely used special character."""
639 | HE_WIDE = HebrewChar("ﬣ", name="Wide He")
640 | """An instance of `HebrewChar` representing the letter **`'ﬣ'`**. This is a rarely used special character."""
641 | KAF_WIDE = HebrewChar("ﬤ", name="Wide Kaf")
642 | """An instance of `HebrewChar` representing the letter **`'ﬤ'`**. This is a rarely used special character."""
643 | LAMED_WIDE = HebrewChar("ﬥ", name="Wide Lamed")
644 | """An instance of `HebrewChar` representing the letter **`'ﬥ'`**. This is a rarely used special character."""
645 | FINAL_MEM_WIDE = HebrewChar("ﬦ", name="Wide Final Mem")
646 | """An instance of `HebrewChar` representing the letter **`'ﬦ'`**. This is a rarely used special character."""
647 | RESH_WIDE = HebrewChar("ﬧ", name="Wide Resh")
648 | """An instance of `HebrewChar` representing the letter **`'ﬧ'`**. This is a rarely used special character."""
649 | TAV_WIDE = HebrewChar("ﬨ", name="Wide Tav")
650 | """An instance of `HebrewChar` representing the letter **`'ﬨ'`**. This is a rarely used special character."""
651 | SHIN_SHIN_DOT = HebrewChar("שׁ", name="Shin with Shin Dot")
652 | """An instance of `HebrewChar` representing the letter **`'שׁ'`**. This is a rarely used special character."""
653 | SHIN_SIN_DOT = HebrewChar("שׂ", name="Shin with Sin Dot")
654 | """An instance of `HebrewChar` representing the letter **`'שׂ'`**. This is a rarely used special character."""
655 | SHIN_DAGESH_SHIN_DOT = HebrewChar("שּׁ", name="Shin with Dagesh and Shin Dot")
656 | """An instance of `HebrewChar` representing the letter **`'שּׁ'`**. This is a rarely used special character."""
657 | SHIN_DAGESH_SIN_DOT = HebrewChar("שּׂ", name="Shin with Dagesh and Sin Dot")
658 | """An instance of `HebrewChar` representing the letter **`'שּׂ'`**. This is a rarely used special character."""
659 | ALEF_PATAH = HebrewChar("אַ", name="Alef with Patah")
660 | """An instance of `HebrewChar` representing the letter **`'אַ'`**. This is a rarely used special character."""
661 | ALEF_QAMATZ = HebrewChar("אָ", name="Alef with Qamats")
662 | """An instance of `HebrewChar` representing the letter **`'אָ'`**. This is a rarely used special character."""
663 | ALEF_MAPIQ = HebrewChar("אּ", name="Alef with Mapiq")
664 | """An instance of `HebrewChar` representing the letter **`'אּ'`**. This is a rarely used special character."""
665 | BET_DAGESH = HebrewChar("בּ", name="Bet with Dagesh")
666 | """An instance of `HebrewChar` representing the letter **`'בּ'`**. This is a rarely used special character."""
667 | GIMEL_DAGESH = HebrewChar("גּ", name="Gimel with Dagesh")
668 | """An instance of `HebrewChar` representing the letter **`'גּ'`**. This is a rarely used special character."""
669 | DALET_DAGESH = HebrewChar("דּ", name="Dalet with Dagesh")
670 | """An instance of `HebrewChar` representing the letter **`'דּ'`**. This is a rarely used special character."""
671 | HE_MAPIQ = HebrewChar("הּ", name="He with Mapiq")
672 | """An instance of `HebrewChar` representing the letter **`'הּ'`**. This is a rarely used special character."""
673 | VAV_DAGESH = HebrewChar("וּ", name="Vav with Dagesh")
674 | """An instance of `HebrewChar` representing the letter **`'וּ'`**. This is a rarely used special character."""
675 | ZAYIN_DAGESH = HebrewChar("זּ", name="Zayin with Dagesh")
676 | """An instance of `HebrewChar` representing the letter **`'זּ'`**. This is a rarely used special character."""
677 | TET_DAGESH = HebrewChar("טּ", name="Tet with Dagesh")
678 | """An instance of `HebrewChar` representing the letter **`'טּ'`**. This is a rarely used special character."""
679 | YOD_DAGESH = HebrewChar("יּ", name="Yod with Dagesh")
680 | """An instance of `HebrewChar` representing the letter **`'יּ'`**. This is a rarely used special character."""
681 | FINAL_KAF_DAGESH = HebrewChar("ךּ", name="Final Kaf with Dagesh")
682 | """An instance of `HebrewChar` representing the letter **`'ךּ'`**. This is a rarely used special character."""
683 | KAF_DAGESH = HebrewChar("כּ", name="Kaf with Dagesh")
684 | """An instance of `HebrewChar` representing the letter **`'כּ'`**. This is a rarely used special character."""
685 | LAMED_DAGESH = HebrewChar("לּ", name="Lamed with Dagesh")
686 | """An instance of `HebrewChar` representing the letter **`'לּ'`**. This is a rarely used special character."""
687 | MEM_DAGESH = HebrewChar("מּ", name="Mem with Dagesh")
688 | """An instance of `HebrewChar` representing the letter **`'מּ'`**. This is a rarely used special character."""
689 | NUN_DAGESH = HebrewChar("נּ", name="Nun with Dagesh")
690 | """An instance of `HebrewChar` representing the letter **`'נּ'`**. This is a rarely used special character."""
691 | SAMEKH_DAGESH = HebrewChar("סּ", name="Samekh with Dagesh")
692 | """An instance of `HebrewChar` representing the letter **`'סּ'`**. This is a rarely used special character."""
693 | FINAL_PE_DAGESH = HebrewChar("ףּ", name="Final Pe with Dagesh")
694 | """An instance of `HebrewChar` representing the letter **`'ףּ'`**. This is a rarely used special character."""
695 | PE_DAGESH = HebrewChar("פּ", name="Pe with Dagesh")
696 | """An instance of `HebrewChar` representing the letter **`'פּ'`**. This is a rarely used special character."""
697 | TSADI_DAGESH = HebrewChar("צּ", name="Tsadi with Dagesh")
698 | """An instance of `HebrewChar` representing the letter **`'צּ'`**. This is a rarely used special character."""
699 | QOF_DAGESH = HebrewChar("קּ", name="Qof with Dagesh")
700 | """An instance of `HebrewChar` representing the letter **`'קּ'`**. This is a rarely used special character."""
701 | RESH_DAGESH = HebrewChar("רּ", name="Resh with Dagesh")
702 | """An instance of `HebrewChar` representing the letter **`'רּ'`**. This is a rarely used special character."""
703 | SHIN_DAGESH = HebrewChar("שּ", name="Shin with Dagesh")
704 | """An instance of `HebrewChar` representing the letter **`'שּ'`**. This is a rarely used special character."""
705 | TAV_DAGESH = HebrewChar("תּ", name="Tav with Dagesh")
706 | """An instance of `HebrewChar` representing the letter **`'תּ'`**. This is a rarely used special character."""
707 | VAV_HOLAM = HebrewChar("וֹ", name="Vav with Holam")
708 | """An instance of `HebrewChar` representing the letter **`'וֹ'`**. This is a rarely used special character."""
709 | BET_RAFE = HebrewChar("בֿ", name="Bet with Rafe")
710 | """An instance of `HebrewChar` representing the letter **`'בֿ'`**. This is a rarely used special character."""
711 | KAF_RAFE = HebrewChar("כֿ", name="Kaf with Rafe")
712 | """An instance of `HebrewChar` representing the letter **`'כֿ'`**. This is a rarely used special character."""
713 | PE_RAFE = HebrewChar("פֿ", name="Pe with Rafe")
714 | """An instance of `HebrewChar` representing the letter **`'פֿ'`**. This is a rarely used special character."""
715 | ALEPH_LAMED = HebrewChar("ﭏ", name="Alef Lamed")
716 | """An instance of `HebrewChar` representing the letter **`'ﭏ'`**. This is a rarely used special character."""
717 |
718 | SAF = SAV
719 | """Simple pointer to `SAV`."""
720 |
721 | DOUBLE_YOD = YiddishChar(
722 | char="ײ",
723 | name="Double Yod",
724 | name_alts=["Saf"],
725 | )
726 | """An instance of `YiddishChar` representing the letter **`'ײ'`**."""
727 |
728 | DOUBLE_YUD = DOUBLE_YOD
729 | """Simple pointer to `DOUBLE_YOD`."""
730 |
731 | DOUBLE_VAV = YiddishChar(
732 | char="װ",
733 | name="Double Vav",
734 | name_alts=["Double Vuv"],
735 | )
736 | """An instance of `YiddishChar` representing the letter **`'װ'`**."""
737 |
738 | DOUBLE_VUV = DOUBLE_VAV
739 | """Simple pointer to `DOUBLE_VAV`."""
740 |
741 | VAV_YOD = YiddishChar(char="ױ", name="Vav Yod")
742 | """An instance of `YiddishChar` representing the letter **`'ױ'`**."""
743 |
744 | VAV_YUD = VUV_YOD = VUV_YUD = VAV_YOD
745 | """Simple pointer to `VAV_YOD`."""
746 |
747 | YOD_TRIANGLE = HebrewChar(char="ׯ", name="Yod Triangle", name_alts=["Yud Triangle"])
748 | """An instance of `HebrewChar` representing the letter **`'ׯ'`**."""
749 |
750 | YUD_TRIANGLE = YOD_TRIANGLE
751 | """Simple pointer to `YOD_TRIANGLE`."""
752 |
753 | # Niqqudot or Vowel characters
754 | SIN_DOT = NiqqudChar(char="ׂ", name="Sin Dot")
755 | """An instance of `NiqqudChar` representing the Niqqud **`'ׂ'`**."""
756 | SHIN_DOT = NiqqudChar(char="ׁ", name="Shin Dot")
757 | """An instance of `NiqqudChar` representing the Niqqud **`'ׁ'`**."""
758 | DAGESH = NiqqudChar(char="ּ", name="Dagesh")
759 | """An instance of `NiqqudChar` representing the Niqqud **`'ּ'`**."""
760 | QUBUTS = NiqqudChar(char="ֻ", name="Qubuts", name_alts=["Kubutz"])
761 | """An instance of `NiqqudChar` representing the Niqqud **`'ֻ'`**."""
762 | KUBUTZ = QUBUTS
763 | """Simple pointer to `QUBUTS`"""
764 | SHURUK = NiqqudChar(char="וּ", name="Shuruk")
765 | """An instance of `NiqqudChar` representing the Niqqud **`'וּ'`**."""
766 | HOLAM = NiqqudChar(char="ֹ", name="Holam")
767 | """An instance of `NiqqudChar` representing the Niqqud **`'ֹ'`**."""
768 | QAMATS = NiqqudChar(char="ָ", name="Qamats", name_alts=["Kumatz"])
769 | """An instance of `NiqqudChar` representing the Niqqud **`'ָ'`**."""
770 | KUMATZ = QAMATS
771 | """Simple pointer to `QAMATS`"""
772 | QAMATS_KATAN = NiqqudChar(char="ׇ", name="Qamats Qatan", name_alts=["Kumatz Katan"])
773 | """An instance of `NiqqudChar` representing the Niqqud **`'ׇ'`**."""
774 | PATAH = NiqqudChar(char="ַ", name="Patah", name_alts=["Patach"])
775 | """An instance of `NiqqudChar` representing the Niqqud **`'ַ'`**."""
776 | PATACH = PATAH
777 | """Simple pointer to `PATAH`"""
778 | SEGOL = NiqqudChar(char="ֶ", name="Segol")
779 | """An instance of `NiqqudChar` representing the Niqqud **`'ֶ'`**."""
780 | TSERE = NiqqudChar(char="ֵ", name="Tsere")
781 | """An instance of `NiqqudChar` representing the Niqqud **`'ֵ'`**."""
782 | HIRIQ = NiqqudChar(char="ִ", name="Hiriq", name_alts=["Chirik"])
783 | """An instance of `NiqqudChar` representing the Niqqud **`'ִ'`**."""
784 | CHIRIK = HIRIQ
785 | """Simple pointer to `HIRIQ`"""
786 | HATAF_QAMATS = NiqqudChar(char="ֳ", name="Hataf Qamatz", name_alts=["Hataf Kumatz"])
787 | """An instance of `NiqqudChar` representing the Niqqud **`'ֳ'`**."""
788 | HATAF_PATAH = NiqqudChar(char="ֲ", name="Hataf Patah", name_alts=["Hataf Patach"])
789 | """An instance of `NiqqudChar` representing the Niqqud **`'ֲ'`**."""
790 | HATAF_SEGOL = NiqqudChar(char="ֱ", name="Hataf Segol")
791 | """An instance of `NiqqudChar` representing the Niqqud **`'ֱ'`**."""
792 | SHEVA = NiqqudChar(char="ְ", name="Sheva", name_alts=["Shivah"])
793 | """An instance of `NiqqudChar` representing the Niqqud **`'ְ'`**."""
794 | SHIVAH = SHEVA
795 | """Simple pointer to `SHEVA`"""
796 | UPPER_DOT = NiqqudChar(char="ׄ", name="Upper Dot")
797 | """An instance of `NiqqudChar` representing the Niqqud **`'ׄ'`**."""
798 | HOLAM_HASER = NiqqudChar(char="ֺ", name="Holam Haser")
799 | """An instance of `NiqqudChar` representing the Niqqud **`'ֺ'`**."""
800 | LOWER_DOT = NiqqudChar(char="ׅ", name="Lower Dot")
801 | """An instance of `NiqqudChar` representing the Niqqud **`'ׅ'`**."""
802 |
803 | # Other characters
804 | MAQAF = OtherChar(char="־", name="Maqaf")
805 | """An instance of `TaamimChar` representing the character **`'־'`**."""
806 | PASEQ = OtherChar(char="׀", name="Paseq")
807 | """An instance of `TaamimChar` representing the character **`'׀'`**."""
808 | SOF_PASSUK = OtherChar(char="׃", name="Sof Passuk")
809 | """An instance of `TaamimChar` representing the character **`'׃'`**."""
810 | GERSHAYIM = OtherChar(char="״", name="Gershayim")
811 | """An instance of `OtherChar` representing the character **`'״'`**."""
812 | GERESH = OtherChar(char="׳", name="Geresh")
813 | """An instance of `OtherChar` representing the character **`'׳'`**."""
814 | ALTERNATIVE_PLUS_SIGN = OtherChar(char="﬩", name="Alternative Plus Sign")
815 | """An instance of `OtherChar` representing the character **`'﬩'`**."""
816 | INVERTED_NUN = OtherChar(
817 | char="׆", name="Inverted Nun", hebrew_name='נו"ן מנוזרת', name_alts=["Nun Hafukha"]
818 | )
819 | """An instance of `OtherChar` representing the letter **`'׆'`**. This is a rarely used special character."""
820 |
821 | NUN_HAFUKHA = INVERTED_NUN
822 | """Simple pointer to `INVERTED_NUN`."""
823 |
824 | # Taamim characters
825 | ETNAHTA = TaamimChar(char="֑", name="Etnahta")
826 | """An instance of `TaamimChar` representing the Ta'amim **`'֑'`**."""
827 | SEGOL_TOP = TaamimChar(char="֒", name="Segol Top")
828 | """An instance of `TaamimChar` representing the Ta'amim **`'֒'`**."""
829 | SHALSHELET = TaamimChar(char="֓", name="Shalshelet")
830 | """An instance of `TaamimChar` representing the Ta'amim **`'֓'`**."""
831 | ZAQEF_QATAN = TaamimChar(char="֔", name="Zaqef Qatan")
832 | """An instance of `TaamimChar` representing the Ta'amim **`'֔'`**."""
833 | ZAQEF_GADOL = TaamimChar(char="֕", name="Zaqef Gadol")
834 | """An instance of `TaamimChar` representing the Ta'amim **`'֕'`**."""
835 | TIFCHA = TaamimChar(char="֖", name="Tifcha")
836 | """An instance of `TaamimChar` representing the Ta'amim **`'֖'`**."""
837 | REVIA = TaamimChar(char="֗", name="Revia")
838 | """An instance of `TaamimChar` representing the Ta'amim **`'֗'`**."""
839 | ZINOR = TaamimChar(char="֮", name="Zinor")
840 | """An instance of `TaamimChar` representing the Ta'amim **`'֮'`**."""
841 | PASHTA = TaamimChar(char="֙", name="Pashta")
842 | """An instance of `TaamimChar` representing the Ta'amim **`'֙'`**."""
843 | PASHTA_2 = TaamimChar(char="֨", name="Pashta 2", name_alts=["Qadma"])
844 | """An instance of `TaamimChar` representing the Ta'amim **`'֨'`**."""
845 | QADMA = PASHTA_2
846 | """Simple pointer to `PASHTA_2` since they share the same Unicode character."""
847 | YETIV = TaamimChar(char="֚", name="Yetiv")
848 | """An instance of `TaamimChar` representing the Ta'amim **`'֚'`**."""
849 | TEVIR = TaamimChar(char="֛", name="Tevir")
850 | """An instance of `TaamimChar` representing the Ta'amim **`'֛'`**."""
851 | PAZER = TaamimChar(char="֡", name="Pazer")
852 | """An instance of `TaamimChar` representing the Ta'amim **`'֡'`**."""
853 | TELISHA_GEDOLA = TaamimChar(char="֠", name="Telisha Gedola")
854 | """An instance of `TaamimChar` representing the Ta'amim **`'֠'`**."""
855 | TELISHA_KETANNAH = TaamimChar(char="֩", name="Telisha Ketannah")
856 | """An instance of `TaamimChar` representing the Ta'amim **`'֩'`**."""
857 | AZLA_GERESH = TaamimChar(char="֜", name="Azla Geresh")
858 | """An instance of `TaamimChar` representing the Ta'amim **`'֜'`**."""
859 | GERSHAYIM_2 = TaamimChar(char="֞", name="Gershayim 2")
860 | """An instance of `TaamimChar` representing the Ta'amim **`'֞'`**."""
861 | MERCHA = TaamimChar(char="֥", name="Mercha")
862 | """An instance of `TaamimChar` representing the Ta'amim **`'֥'`**."""
863 | MUNACH = TaamimChar(char="֣", name="Munach")
864 | """An instance of `TaamimChar` representing the Ta'amim **`'֣'`**."""
865 | MAHPACH = TaamimChar(char="֤", name="Mahpach")
866 | """An instance of `TaamimChar` representing the Ta'amim **`'֤'`**."""
867 | DARGA = TaamimChar(char="֧", name="Darga")
868 | """An instance of `TaamimChar` representing the Ta'amim **`'֧'`**."""
869 | MERCHA_KEFULA = TaamimChar(char="֦", name="Mercha Kefula")
870 | """An instance of `TaamimChar` representing the Ta'amim **`'֦'`**."""
871 | YERACH_BEN_YOMO = TaamimChar(char="֪", name="Yerach Ben Yomo")
872 | """An instance of `TaamimChar` representing the Ta'amim **`'֪'`**."""
873 | MASORA = TaamimChar(char="֯", name="Masora")
874 | """An instance of `TaamimChar` representing the Ta'amim **`'֯'`**."""
875 | DEHI = TaamimChar(char="֭", name="Dehi")
876 | """An instance of `TaamimChar` representing the Ta'amim **`'֭'`**."""
877 | ZARQA = TaamimChar(char="֘", name="Zarqa")
878 | """An instance of `TaamimChar` representing the Ta'amim **`'֘'`**."""
879 | GERESH_MUQDAM = TaamimChar(char="֝", name="Geresh Muqdam")
880 | """An instance of `TaamimChar` representing the Ta'amim **`'֝'`**."""
881 | QARNEY_PARA = TaamimChar(char="֟", name="Qarney Para", name_alts=["Pazer Gadol"])
882 | """An instance of `TaamimChar` representing the Ta'amim **`'֟'`**."""
883 | PAZER_GADOL = QARNEY_PARA
884 | """Simple pointer to `QARNEY_PARA` since they share the same Unicode character."""
885 | OLA = TaamimChar(char="֫", name="Ola")
886 | """An instance of `TaamimChar` representing the Ta'amim **`'֫'`**."""
887 | ILUY = TaamimChar(char="֬", name="Iluy")
888 | """An instance of `TaamimChar` representing the Ta'amim **`'֬'`**."""
889 | RAFE = TaamimChar(char="ֿ", name="Rafe")
890 | """An instance of `TaamimChar` representing the Ta'amim **`'ֿ'`**."""
891 | METEG = TaamimChar(char="ֽ", name="Meteg")
892 | """An instance of `TaamimChar` representing the Ta'amim **`'ֽ'`**."""
893 | JUDEO_SPANISH_VARIKA = TaamimChar(char="ﬞ", name="Judeo-Spanish Varika")
894 | """An instance of `TaamimChar` representing the Ta'amim **`'ﬞ'`**."""
895 | ATNAH_HAFUKH = TaamimChar(char="֢", name="Atnah Hafukh")
896 | """An instance of `TaamimChar` representing the Ta'amim **`'֢'`**."""
897 |
898 | ALL_CHARS: List[Union[HebrewChar, YiddishChar, NiqqudChar, TaamimChar, OtherChar]] = [
899 | ALEPH,
900 | BET,
901 | VET,
902 | GIMEL,
903 | DALET,
904 | HE,
905 | VAV,
906 | ZAYIN,
907 | CHET,
908 | TET,
909 | YOD,
910 | CAF,
911 | KAF_SOFIT,
912 | CHAF,
913 | CHAF_SOFIT,
914 | LAMED,
915 | MEM,
916 | MEM_SOFIT,
917 | NUN,
918 | NUN_SOFIT,
919 | SAMEKH,
920 | AYIN,
921 | PE,
922 | FE,
923 | PE_SOFIT,
924 | FE_SOFIT,
925 | TSADI,
926 | TSADI_SOFIT,
927 | QOF,
928 | RESH,
929 | SHIN,
930 | SIN,
931 | PLAIN_SIN,
932 | TAV,
933 | SAV,
934 | DOUBLE_YOD,
935 | DOUBLE_VAV,
936 | VAV_YOD,
937 | SIN_DOT,
938 | SHIN_DOT,
939 | DAGESH,
940 | QUBUTS,
941 | SHURUK,
942 | HOLAM,
943 | QAMATS,
944 | PATAH,
945 | SEGOL,
946 | TSERE,
947 | HIRIQ,
948 | HATAF_QAMATS,
949 | HATAF_PATAH,
950 | HATAF_SEGOL,
951 | SHEVA,
952 | UPPER_DOT,
953 | MAQAF,
954 | PASEQ,
955 | SOF_PASSUK,
956 | ETNAHTA,
957 | SEGOL_TOP,
958 | SHALSHELET,
959 | ZAQEF_QATAN,
960 | ZAQEF_GADOL,
961 | TIFCHA,
962 | REVIA,
963 | ZINOR,
964 | PASHTA,
965 | PASHTA_2,
966 | YETIV,
967 | TEVIR,
968 | PAZER,
969 | TELISHA_GEDOLA,
970 | TELISHA_KETANNAH,
971 | GERESH,
972 | AZLA_GERESH,
973 | GERSHAYIM,
974 | GERSHAYIM_2,
975 | MERCHA,
976 | MUNACH,
977 | MAHPACH,
978 | DARGA,
979 | MERCHA_KEFULA,
980 | YERACH_BEN_YOMO,
981 | MASORA,
982 | DEHI,
983 | ZARQA,
984 | GERESH_MUQDAM,
985 | QARNEY_PARA,
986 | OLA,
987 | ILUY,
988 | RAFE,
989 | METEG,
990 | ATNAH_HAFUKH,
991 | HOLAM_HASER,
992 | LOWER_DOT,
993 | INVERTED_NUN,
994 | ALEPH_SYMBOL,
995 | BET_SYMBOL,
996 | GIMEL_SYMBOL,
997 | DALET_SYMBOL,
998 | YOD_HIRIQ,
999 | YOD_YOD_PATAH,
1000 | YOD_YOD_PATAH2,
1001 | AYIN_ALT,
1002 | ALEF_WIDE,
1003 | DALET_WIDE,
1004 | HE_WIDE,
1005 | KAF_WIDE,
1006 | LAMED_WIDE,
1007 | FINAL_MEM_WIDE,
1008 | RESH_WIDE,
1009 | TAV_WIDE,
1010 | SHIN_SHIN_DOT,
1011 | SHIN_SIN_DOT,
1012 | SHIN_DAGESH_SHIN_DOT,
1013 | SHIN_DAGESH_SIN_DOT,
1014 | ALEF_PATAH,
1015 | ALEF_QAMATZ,
1016 | ALEF_MAPIQ,
1017 | BET_DAGESH,
1018 | GIMEL_DAGESH,
1019 | DALET_DAGESH,
1020 | HE_MAPIQ,
1021 | VAV_DAGESH,
1022 | ZAYIN_DAGESH,
1023 | TET_DAGESH,
1024 | YOD_DAGESH,
1025 | FINAL_KAF_DAGESH,
1026 | KAF_DAGESH,
1027 | LAMED_DAGESH,
1028 | MEM_DAGESH,
1029 | NUN_DAGESH,
1030 | SAMEKH_DAGESH,
1031 | FINAL_PE_DAGESH,
1032 | PE_DAGESH,
1033 | TSADI_DAGESH,
1034 | QOF_DAGESH,
1035 | RESH_DAGESH,
1036 | SHIN_DAGESH,
1037 | TAV_DAGESH,
1038 | VAV_HOLAM,
1039 | BET_RAFE,
1040 | KAF_RAFE,
1041 | PE_RAFE,
1042 | ALEPH_LAMED,
1043 | QAMATS_KATAN,
1044 | YOD_TRIANGLE,
1045 | JUDEO_SPANISH_VARIKA,
1046 | ALTERNATIVE_PLUS_SIGN,
1047 | ]
1048 | """
1049 | Every instance of a character class.
1050 | This is used for defining collections with list comprehensions based on the Chars metadata.
1051 | It can be relied on as being a complete list of Unicode characters used in Hebrew (and Yiddish etc).
1052 | """
1053 |
1054 | CHARS: Dict[str, Union[HebrewChar, YiddishChar, NiqqudChar, TaamimChar, OtherChar]] = {
1055 | c.char: c for c in ALL_CHARS
1056 | }
1057 | """
1058 | A dict of all instances of all supported Char types where the key is the char
1059 | and the value is an instance of BaseHebrewChar.
1060 | This is useful for when you have a hebrew char and want to get its metadata class.
1061 |
1062 | ``` python
1063 | assert CHARS['א'] == ALEPH
1064 | ```
1065 | """
1066 |
1067 | FINAL_LETTERS: List[HebrewChar] = [
1068 | c
1069 | for c in ALL_CHARS
1070 | if isinstance(c, HebrewChar) and c.final_letter and len(c.char) == 1
1071 | ]
1072 | """
1073 | A list of all Hebrew characters that are final letters.
1074 | While we do have letters like 'ףּ' defined, they do not return in this array; it contains only the plain final letters.
1075 | """
1076 |
1077 | HEBREW_CHARS: List[HebrewChar] = [
1078 | c
1079 | for c in ALL_CHARS
1080 | if isinstance(c, HebrewChar) and c.char in "אבגדהוזחטיכךלמםנןסעפףצץקרשת"
1081 | ]
1082 | """A List of all instances of `HebrewChar`. This will include letters like 'ףּ'"""
1083 |
1084 | YIDDISH_CHARS: List[YiddishChar] = [
1085 | c for c in ALL_CHARS if isinstance(c, YiddishChar) and c.char in ["ױ", "װ", "ײ"]
1086 | ]
1087 | """A List of all instances of `YiddishChar`."""
1088 |
1089 | NIQQUD_CHARS: List[NiqqudChar] = [c for c in ALL_CHARS if isinstance(c, NiqqudChar)]
1090 | """A List of all instances of `NiqqudChar`."""
1091 |
1092 | TAAMIM_CHARS: List[TaamimChar] = [c for c in ALL_CHARS if isinstance(c, TaamimChar)]
1093 | """A List of all instances of `TaamimChar`."""
1094 |
1095 | OTHER_CHARS: List[OtherChar] = [c for c in ALL_CHARS if isinstance(c, OtherChar)]
1096 | """A List of all instances of `OtherChar`."""
1097 |
1098 | _NON_LETTER_CHARS: List[Union[NiqqudChar, TaamimChar, OtherChar]] = [
1099 | c
1100 | for c in ALL_CHARS
1101 | if not isinstance(c, HebrewChar) and not isinstance(c, YiddishChar)
1102 | ]
1103 | """A List of all chars that are not letters. Used internally for filtering non letter chars."""
1104 |
1105 | FINAL_MINOR_LETTER_MAPPINGS: Dict[str, str] = {
1106 | "כ": "ך",
1107 | "ך": "כ",
1108 | "מ": "ם",
1109 | "ם": "מ",
1110 | "נ": "ן",
1111 | "ן": "נ",
1112 | "פ": "ף",
1113 | "ף": "פ",
1114 | "צ": "ץ",
1115 | "ץ": "צ",
1116 | }
1117 | """A map of final letters to their regular counterparts, and vice versa."""
1118 |
1119 | SPECIAL_CHARACTER_NORMALIZED_MAPPING: Dict[
1120 | BaseHebrewChar, Union[BaseHebrewChar, List[BaseHebrewChar]]
1121 | ] = {
1122 | ALEPH_SYMBOL: ALEPH,
1123 | BET_SYMBOL: VET,
1124 | GIMEL_SYMBOL: GIMEL,
1125 | DALET_SYMBOL: DALET,
1126 | YOD_YOD_PATAH: [YOD, PATAH, YOD],
1127 | YOD_YOD_PATAH2: [YOD, PATAH, YOD],
1128 | AYIN_ALT: AYIN,
1129 | ALEF_WIDE: ALEPH,
1130 | DALET_WIDE: DALET,
1131 | HE_WIDE: HE,
1132 | KAF_WIDE: CHAF,
1133 | LAMED_WIDE: LAMED,
1134 | FINAL_MEM_WIDE: FINAL_MEM,
1135 | RESH_WIDE: RESH,
1136 | TAV_WIDE: SAV,
1137 | SHIN_SIN_DOT: SIN,
1138 | SHIN_DAGESH_SHIN_DOT: [SHIN, DAGESH],
1139 | SHIN_DAGESH_SIN_DOT: [SIN, DAGESH],
1140 | ALEPH_LAMED: [ALEPH, LAMED],
1141 | DOUBLE_YOD: [YOD, YOD],
1142 | DOUBLE_VAV: [VAV, VAV],
1143 | VAV_YOD: [YOD, VAV],
1144 | }
1145 | """A map of special characters to their normal spelled out equivalent. For example, ﭏ becomes אל"""
1146 |
1147 |
1148 | def char_search(
1149 | char_name: str,
1150 | char_list: Optional[
1151 | List[Union[HebrewChar, YiddishChar, NiqqudChar, TaamimChar, OtherChar]]
1152 | ] = None,
1153 | ) -> Optional[Union[HebrewChar, YiddishChar, NiqqudChar, TaamimChar, OtherChar]]:
1154 | """
1155 | Search for a character by its name.
1156 |
1157 | Character classes contain alternate names which are supported by this function!
1158 | Currently, only english names are supported.
1159 | TODO: Support search in hebrew, which will need to support hebrew text with or without nikud.
1160 |
1161 | :param char_name: A string containing the name of the character to search for.
1162 | :param char_list: A list of `BaseHebrewChar` characters to use for this search.
1163 | When None, defaults to all characters (ALL_CHARS).
1164 | :return:
1165 | """
1166 | char_list = char_list if char_list else ALL_CHARS
1167 | for char in char_list:
1168 | if char_name.lower() in [n.lower() for n in char.names]:
1169 | return CHARS[char.char]
1170 | return None
1171 |
--------------------------------------------------------------------------------
/tests/test_numerical_conversion.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from hebrew.numerical_conversion.convert import number_to_hebrew_string
4 | from hebrew.hebrew_obj import Hebrew
5 | from hebrew.numerical_conversion.substitute import Substitutions
6 |
7 |
8 | WITH_GERESH = {
9 | 1: "א׳",
10 | 2: "ב׳",
11 | 3: "ג׳",
12 | 4: "ד׳",
13 | 5: "ה׳",
14 | 6: "ו׳",
15 | 7: "ז׳",
16 | 8: "ח׳",
17 | 9: "ט׳",
18 | 10: "י׳",
19 | 11: "י״א",
20 | 12: "י״ב",
21 | 13: "י״ג",
22 | 14: "י״ד",
23 | 15: "ט״ו",
24 | 16: "ט״ז",
25 | 17: "י״ז",
26 | 18: "י״ח",
27 | 19: "י״ט",
28 | 20: "כ׳",
29 | 21: "כ״א",
30 | 22: "כ״ב",
31 | 23: "כ״ג",
32 | 24: "כ״ד",
33 | 25: "כ״ה",
34 | 26: "כ״ו",
35 | 27: "כ״ז",
36 | 28: "כ״ח",
37 | 29: "כ״ט",
38 | 30: "ל׳",
39 | 31: "ל״א",
40 | 32: "ל״ב",
41 | 33: "ל״ג",
42 | 34: "ל״ד",
43 | 35: "ל״ה",
44 | 36: "ל״ו",
45 | 37: "ל״ז",
46 | 38: "ל״ח",
47 | 39: "ל״ט",
48 | 40: "מ׳",
49 | 41: "מ״א",
50 | 42: "מ״ב",
51 | 43: "מ״ג",
52 | 44: "מ״ד",
53 | 45: "מ״ה",
54 | 46: "מ״ו",
55 | 47: "מ״ז",
56 | 48: "מ״ח",
57 | 49: "מ״ט",
58 | 50: "נ׳",
59 | 51: "נ״א",
60 | 52: "נ״ב",
61 | 53: "נ״ג",
62 | 54: "נ״ד",
63 | 55: "נ״ה",
64 | 56: "נ״ו",
65 | 57: "נ״ז",
66 | 58: "נ״ח",
67 | 59: "נ״ט",
68 | 60: "ס׳",
69 | 61: "ס״א",
70 | 62: "ס״ב",
71 | 63: "ס״ג",
72 | 64: "ס״ד",
73 | 65: "ס״ה",
74 | 66: "ס״ו",
75 | 67: "ס״ז",
76 | 68: "ס״ח",
77 | 69: "ס״ט",
78 | 70: "ע׳",
79 | 71: "ע״א",
80 | 72: "ע״ב",
81 | 73: "ע״ג",
82 | 74: "ע״ד",
83 | 75: "ע״ה",
84 | 76: "ע״ו",
85 | 77: "ע״ז",
86 | 78: "ע״ח",
87 | 79: "ע״ט",
88 | 80: "פ׳",
89 | 81: "פ״א",
90 | 82: "פ״ב",
91 | 83: "פ״ג",
92 | 84: "פ״ד",
93 | 85: "פ״ה",
94 | 86: "פ״ו",
95 | 87: "פ״ז",
96 | 88: "פ״ח",
97 | 89: "פ״ט",
98 | 90: "צ׳",
99 | 91: "צ״א",
100 | 92: "צ״ב",
101 | 93: "צ״ג",
102 | 94: "צ״ד",
103 | 95: "צ״ה",
104 | 96: "צ״ו",
105 | 97: "צ״ז",
106 | 98: "צ״ח",
107 | 99: "צ״ט",
108 | 100: "ק׳",
109 | 101: "ק״א",
110 | 102: "ק״ב",
111 | 103: "ק״ג",
112 | 104: "ק״ד",
113 | 105: "ק״ה",
114 | 106: "ק״ו",
115 | 107: "ק״ז",
116 | 108: "ק״ח",
117 | 109: "ק״ט",
118 | 110: "ק״י",
119 | 111: "קי״א",
120 | 112: "קי״ב",
121 | 113: "קי״ג",
122 | 114: "קי״ד",
123 | 115: "קט״ו",
124 | 116: "קט״ז",
125 | 117: "קי״ז",
126 | 118: "קי״ח",
127 | 119: "קי״ט",
128 | 120: "ק״כ",
129 | 121: "קכ״א",
130 | 122: "קכ״ב",
131 | 123: "קכ״ג",
132 | 124: "קכ״ד",
133 | 125: "קכ״ה",
134 | 126: "קכ״ו",
135 | 127: "קכ״ז",
136 | 128: "קכ״ח",
137 | 129: "קכ״ט",
138 | 130: "ק״ל",
139 | 131: "קל״א",
140 | 132: "קל״ב",
141 | 133: "קל״ג",
142 | 134: "קל״ד",
143 | 135: "קל״ה",
144 | 136: "קל״ו",
145 | 137: "קל״ז",
146 | 138: "קל״ח",
147 | 139: "קל״ט",
148 | 140: "ק״מ",
149 | 141: "קמ״א",
150 | 142: "קמ״ב",
151 | 143: "קמ״ג",
152 | 144: "קמ״ד",
153 | 145: "קמ״ה",
154 | 146: "קמ״ו",
155 | 147: "קמ״ז",
156 | 148: "קמ״ח",
157 | 149: "קמ״ט",
158 | 150: "ק״נ",
159 | 151: "קנ״א",
160 | 152: "קנ״ב",
161 | 153: "קנ״ג",
162 | 154: "קנ״ד",
163 | 155: "קנ״ה",
164 | 156: "קנ״ו",
165 | 157: "קנ״ז",
166 | 158: "קנ״ח",
167 | 159: "קנ״ט",
168 | 160: "ק״ס",
169 | 161: "קס״א",
170 | 162: "קס״ב",
171 | 163: "קס״ג",
172 | 164: "קס״ד",
173 | 165: "קס״ה",
174 | 166: "קס״ו",
175 | 167: "קס״ז",
176 | 168: "קס״ח",
177 | 169: "קס״ט",
178 | 170: "ק״ע",
179 | 171: "קע״א",
180 | 172: "קע״ב",
181 | 173: "קע״ג",
182 | 174: "קע״ד",
183 | 175: "קע״ה",
184 | 176: "קע״ו",
185 | 177: "קע״ז",
186 | 178: "קע״ח",
187 | 179: "קע״ט",
188 | 180: "ק״פ",
189 | 181: "קפ״א",
190 | 182: "קפ״ב",
191 | 183: "קפ״ג",
192 | 184: "קפ״ד",
193 | 185: "קפ״ה",
194 | 186: "קפ״ו",
195 | 187: "קפ״ז",
196 | 188: "קפ״ח",
197 | 189: "קפ״ט",
198 | 190: "ק״צ",
199 | 191: "קצ״א",
200 | 192: "קצ״ב",
201 | 193: "קצ״ג",
202 | 194: "קצ״ד",
203 | 195: "קצ״ה",
204 | 196: "קצ״ו",
205 | 197: "קצ״ז",
206 | 198: "קצ״ח",
207 | 199: "קצ״ט",
208 | 200: "ר׳",
209 | 201: "ר״א",
210 | 202: "ר״ב",
211 | 203: "ר״ג",
212 | 204: "ר״ד",
213 | 205: "ר״ה",
214 | 206: "ר״ו",
215 | 207: "ר״ז",
216 | 208: "ר״ח",
217 | 209: "ר״ט",
218 | 210: "ר״י",
219 | 211: "רי״א",
220 | 212: "רי״ב",
221 | 213: "רי״ג",
222 | 214: "רי״ד",
223 | 215: "רט״ו",
224 | 216: "רט״ז",
225 | 217: "רי״ז",
226 | 218: "רי״ח",
227 | 219: "רי״ט",
228 | 220: "ר״כ",
229 | 221: "רכ״א",
230 | 222: "רכ״ב",
231 | 223: "רכ״ג",
232 | 224: "רכ״ד",
233 | 225: "רכ״ה",
234 | 226: "רכ״ו",
235 | 227: "רכ״ז",
236 | 228: "רכ״ח",
237 | 229: "רכ״ט",
238 | 230: "ר״ל",
239 | 231: "רל״א",
240 | 232: "רל״ב",
241 | 233: "רל״ג",
242 | 234: "רל״ד",
243 | 235: "רל״ה",
244 | 236: "רל״ו",
245 | 237: "רל״ז",
246 | 238: "רל״ח",
247 | 239: "רל״ט",
248 | 240: "ר״מ",
249 | 241: "רמ״א",
250 | 242: "רמ״ב",
251 | 243: "רמ״ג",
252 | 244: "רמ״ד",
253 | 245: "רמ״ה",
254 | 246: "רמ״ו",
255 | 247: "רמ״ז",
256 | 248: "רמ״ח",
257 | 249: "רמ״ט",
258 | 250: "ר״נ",
259 | 251: "רנ״א",
260 | 252: "רנ״ב",
261 | 253: "רנ״ג",
262 | 254: "רנ״ד",
263 | 255: "רנ״ה",
264 | 256: "רנ״ו",
265 | 257: "רנ״ז",
266 | 258: "רנ״ח",
267 | 259: "רנ״ט",
268 | 260: "ר״ס",
269 | 261: "רס״א",
270 | 262: "רס״ב",
271 | 263: "רס״ג",
272 | 264: "רס״ד",
273 | 265: "רס״ה",
274 | 266: "רס״ו",
275 | 267: "רס״ז",
276 | 268: "רס״ח",
277 | 269: "רס״ט",
278 | 270: "ר״ע",
279 | 271: "רע״א",
280 | 272: "רע״ב",
281 | 273: "רע״ג",
282 | 274: "רע״ד",
283 | 275: "רע״ה",
284 | 276: "רע״ו",
285 | 277: "רע״ז",
286 | 278: "רע״ח",
287 | 279: "רע״ט",
288 | 280: "ר״פ",
289 | 281: "רפ״א",
290 | 282: "רפ״ב",
291 | 283: "רפ״ג",
292 | 284: "רפ״ד",
293 | 285: "רפ״ה",
294 | 286: "רפ״ו",
295 | 287: "רפ״ז",
296 | 288: "רפ״ח",
297 | 289: "רפ״ט",
298 | 290: "ר״צ",
299 | 291: "רצ״א",
300 | 292: "רצ״ב",
301 | 293: "רצ״ג",
302 | 294: "רצ״ד",
303 | 295: "רצ״ה",
304 | 296: "רצ״ו",
305 | 297: "רצ״ז",
306 | 298: "רצ״ח",
307 | 299: "רצ״ט",
308 | 300: "ש׳",
309 | 301: "ש״א",
310 | 302: "ש״ב",
311 | 303: "ש״ג",
312 | 304: "ש״ד",
313 | 305: "ש״ה",
314 | 306: "ש״ו",
315 | 307: "ש״ז",
316 | 308: "ש״ח",
317 | 309: "ש״ט",
318 | 310: "ש״י",
319 | 311: "שי״א",
320 | 312: "שי״ב",
321 | 313: "שי״ג",
322 | 314: "שי״ד",
323 | 315: "שט״ו",
324 | 316: "שט״ז",
325 | 317: "שי״ז",
326 | 318: "שי״ח",
327 | 319: "שי״ט",
328 | 320: "ש״כ",
329 | 321: "שכ״א",
330 | 322: "שכ״ב",
331 | 323: "שכ״ג",
332 | 324: "שכ״ד",
333 | 325: "שכ״ה",
334 | 326: "שכ״ו",
335 | 327: "שכ״ז",
336 | 328: "שכ״ח",
337 | 329: "שכ״ט",
338 | 330: "ש״ל",
339 | 331: "של״א",
340 | 332: "של״ב",
341 | 333: "של״ג",
342 | 334: "של״ד",
343 | 335: "של״ה",
344 | 336: "של״ו",
345 | 337: "של״ז",
346 | 338: "של״ח",
347 | 339: "של״ט",
348 | 340: "ש״מ",
349 | 341: "שמ״א",
350 | 342: "שמ״ב",
351 | 343: "שמ״ג",
352 | 344: "שמ״ד",
353 | 345: "שמ״ה",
354 | 346: "שמ״ו",
355 | 347: "שמ״ז",
356 | 348: "שמ״ח",
357 | 349: "שמ״ט",
358 | 350: "ש״נ",
359 | 351: "שנ״א",
360 | 352: "שנ״ב",
361 | 353: "שנ״ג",
362 | 354: "שנ״ד",
363 | 355: "שנ״ה",
364 | 356: "שנ״ו",
365 | 357: "שנ״ז",
366 | 358: "שנ״ח",
367 | 359: "שנ״ט",
368 | 360: "ש״ס",
369 | 361: "שס״א",
370 | 362: "שס״ב",
371 | 363: "שס״ג",
372 | 364: "שס״ד",
373 | 365: "שס״ה",
374 | 366: "שס״ו",
375 | 367: "שס״ז",
376 | 368: "שס״ח",
377 | 369: "שס״ט",
378 | 370: "ש״ע",
379 | 371: "שע״א",
380 | 372: "שע״ב",
381 | 373: "שע״ג",
382 | 374: "שע״ד",
383 | 375: "שע״ה",
384 | 376: "שע״ו",
385 | 377: "שע״ז",
386 | 378: "שע״ח",
387 | 379: "שע״ט",
388 | 380: "ש״פ",
389 | 381: "שפ״א",
390 | 382: "שפ״ב",
391 | 383: "שפ״ג",
392 | 384: "שפ״ד",
393 | 385: "שפ״ה",
394 | 386: "שפ״ו",
395 | 387: "שפ״ז",
396 | 388: "שפ״ח",
397 | 389: "שפ״ט",
398 | 390: "ש״צ",
399 | 391: "שצ״א",
400 | 392: "שצ״ב",
401 | 393: "שצ״ג",
402 | 394: "שצ״ד",
403 | 395: "שצ״ה",
404 | 396: "שצ״ו",
405 | 397: "שצ״ז",
406 | 398: "שצ״ח",
407 | 399: "שצ״ט",
408 | 400: "ת׳",
409 | 401: "ת״א",
410 | 402: "ת״ב",
411 | 403: "ת״ג",
412 | 404: "ת״ד",
413 | 405: "ת״ה",
414 | 406: "ת״ו",
415 | 407: "ת״ז",
416 | 408: "ת״ח",
417 | 409: "ת״ט",
418 | 410: "ת״י",
419 | 411: "תי״א",
420 | 412: "תי״ב",
421 | 413: "תי״ג",
422 | 414: "תי״ד",
423 | 415: "תט״ו",
424 | 416: "תט״ז",
425 | 417: "תי״ז",
426 | 418: "תי״ח",
427 | 419: "תי״ט",
428 | 420: "ת״כ",
429 | 421: "תכ״א",
430 | 422: "תכ״ב",
431 | 423: "תכ״ג",
432 | 424: "תכ״ד",
433 | 425: "תכ״ה",
434 | 426: "תכ״ו",
435 | 427: "תכ״ז",
436 | 428: "תכ״ח",
437 | 429: "תכ״ט",
438 | 430: "ת״ל",
439 | 431: "תל״א",
440 | 432: "תל״ב",
441 | 433: "תל״ג",
442 | 434: "תל״ד",
443 | 435: "תל״ה",
444 | 436: "תל״ו",
445 | 437: "תל״ז",
446 | 438: "תל״ח",
447 | 439: "תל״ט",
448 | 440: "ת״מ",
449 | 441: "תמ״א",
450 | 442: "תמ״ב",
451 | 443: "תמ״ג",
452 | 444: "תמ״ד",
453 | 445: "תמ״ה",
454 | 446: "תמ״ו",
455 | 447: "תמ״ז",
456 | 448: "תמ״ח",
457 | 449: "תמ״ט",
458 | 450: "ת״נ",
459 | 451: "תנ״א",
460 | 452: "תנ״ב",
461 | 453: "תנ״ג",
462 | 454: "תנ״ד",
463 | 455: "תנ״ה",
464 | 456: "תנ״ו",
465 | 457: "תנ״ז",
466 | 458: "תנ״ח",
467 | 459: "תנ״ט",
468 | 460: "ת״ס",
469 | 461: "תס״א",
470 | 462: "תס״ב",
471 | 463: "תס״ג",
472 | 464: "תס״ד",
473 | 465: "תס״ה",
474 | 466: "תס״ו",
475 | 467: "תס״ז",
476 | 468: "תס״ח",
477 | 469: "תס״ט",
478 | 470: "ת״ע",
479 | 471: "תע״א",
480 | 472: "תע״ב",
481 | 473: "תע״ג",
482 | 474: "תע״ד",
483 | 475: "תע״ה",
484 | 476: "תע״ו",
485 | 477: "תע״ז",
486 | 478: "תע״ח",
487 | 479: "תע״ט",
488 | 480: "ת״פ",
489 | 481: "תפ״א",
490 | 482: "תפ״ב",
491 | 483: "תפ״ג",
492 | 484: "תפ״ד",
493 | 485: "תפ״ה",
494 | 486: "תפ״ו",
495 | 487: "תפ״ז",
496 | 488: "תפ״ח",
497 | 489: "תפ״ט",
498 | 490: "ת״צ",
499 | 491: "תצ״א",
500 | 492: "תצ״ב",
501 | 493: "תצ״ג",
502 | 494: "תצ״ד",
503 | 495: "תצ״ה",
504 | 496: "תצ״ו",
505 | 497: "תצ״ז",
506 | 498: "תצ״ח",
507 | 499: "תצ״ט",
508 | 500: "ת״ק",
509 | 501: "תק״א",
510 | 502: "תק״ב",
511 | 503: "תק״ג",
512 | 504: "תק״ד",
513 | 505: "תק״ה",
514 | 506: "תק״ו",
515 | 507: "תק״ז",
516 | 508: "תק״ח",
517 | 509: "תק״ט",
518 | 510: "תק״י",
519 | 511: "תקי״א",
520 | 512: "תקי״ב",
521 | 513: "תקי״ג",
522 | 514: "תקי״ד",
523 | 515: "תקט״ו",
524 | 516: "תקט״ז",
525 | 517: "תקי״ז",
526 | 518: "תקי״ח",
527 | 519: "תקי״ט",
528 | 520: "תק״כ",
529 | 521: "תקכ״א",
530 | 522: "תקכ״ב",
531 | 523: "תקכ״ג",
532 | 524: "תקכ״ד",
533 | 525: "תקכ״ה",
534 | 526: "תקכ״ו",
535 | 527: "תקכ״ז",
536 | 528: "תקכ״ח",
537 | 529: "תקכ״ט",
538 | 530: "תק״ל",
539 | 531: "תקל״א",
540 | 532: "תקל״ב",
541 | 533: "תקל״ג",
542 | 534: "תקל״ד",
543 | 535: "תקל״ה",
544 | 536: "תקל״ו",
545 | 537: "תקל״ז",
546 | 538: "תקל״ח",
547 | 539: "תקל״ט",
548 | 540: "תק״מ",
549 | 541: "תקמ״א",
550 | 542: "תקמ״ב",
551 | 543: "תקמ״ג",
552 | 544: "תקמ״ד",
553 | 545: "תקמ״ה",
554 | 546: "תקמ״ו",
555 | 547: "תקמ״ז",
556 | 548: "תקמ״ח",
557 | 549: "תקמ״ט",
558 | 550: "תק״נ",
559 | 551: "תקנ״א",
560 | 552: "תקנ״ב",
561 | 553: "תקנ״ג",
562 | 554: "תקנ״ד",
563 | 555: "תקנ״ה",
564 | 556: "תקנ״ו",
565 | 557: "תקנ״ז",
566 | 558: "תקנ״ח",
567 | 559: "תקנ״ט",
568 | 560: "תק״ס",
569 | 561: "תקס״א",
570 | 562: "תקס״ב",
571 | 563: "תקס״ג",
572 | 564: "תקס״ד",
573 | 565: "תקס״ה",
574 | 566: "תקס״ו",
575 | 567: "תקס״ז",
576 | 568: "תקס״ח",
577 | 569: "תקס״ט",
578 | 570: "תק״ע",
579 | 571: "תקע״א",
580 | 572: "תקע״ב",
581 | 573: "תקע״ג",
582 | 574: "תקע״ד",
583 | 575: "תקע״ה",
584 | 576: "תקע״ו",
585 | 577: "תקע״ז",
586 | 578: "תקע״ח",
587 | 579: "תקע״ט",
588 | 580: "תק״פ",
589 | 581: "תקפ״א",
590 | 582: "תקפ״ב",
591 | 583: "תקפ״ג",
592 | 584: "תקפ״ד",
593 | 585: "תקפ״ה",
594 | 586: "תקפ״ו",
595 | 587: "תקפ״ז",
596 | 588: "תקפ״ח",
597 | 589: "תקפ״ט",
598 | 590: "תק״צ",
599 | 591: "תקצ״א",
600 | 592: "תקצ״ב",
601 | 593: "תקצ״ג",
602 | 594: "תקצ״ד",
603 | 595: "תקצ״ה",
604 | 596: "תקצ״ו",
605 | 597: "תקצ״ז",
606 | 598: "תקצ״ח",
607 | 599: "תקצ״ט",
608 | 600: "ת״ר",
609 | 601: "תר״א",
610 | 602: "תר״ב",
611 | 603: "תר״ג",
612 | 604: "תר״ד",
613 | 605: "תר״ה",
614 | 606: "תר״ו",
615 | 607: "תר״ז",
616 | 608: "תר״ח",
617 | 609: "תר״ט",
618 | 610: "תר״י",
619 | 611: "תרי״א",
620 | 612: "תרי״ב",
621 | 613: "תרי״ג",
622 | 614: "תרי״ד",
623 | 615: "תרט״ו",
624 | 616: "תרט״ז",
625 | 617: "תרי״ז",
626 | 618: "תרי״ח",
627 | 619: "תרי״ט",
628 | 620: "תר״כ",
629 | 621: "תרכ״א",
630 | 622: "תרכ״ב",
631 | 623: "תרכ״ג",
632 | 624: "תרכ״ד",
633 | 625: "תרכ״ה",
634 | 626: "תרכ״ו",
635 | 627: "תרכ״ז",
636 | 628: "תרכ״ח",
637 | 629: "תרכ״ט",
638 | 630: "תר״ל",
639 | 631: "תרל״א",
640 | 632: "תרל״ב",
641 | 633: "תרל״ג",
642 | 634: "תרל״ד",
643 | 635: "תרל״ה",
644 | 636: "תרל״ו",
645 | 637: "תרל״ז",
646 | 638: "תרל״ח",
647 | 639: "תרל״ט",
648 | 640: "תר״מ",
649 | 641: "תרמ״א",
650 | 642: "תרמ״ב",
651 | 643: "תרמ״ג",
652 | 644: "תרמ״ד",
653 | 645: "תרמ״ה",
654 | 646: "תרמ״ו",
655 | 647: "תרמ״ז",
656 | 648: "תרמ״ח",
657 | 649: "תרמ״ט",
658 | 650: "תר״נ",
659 | 651: "תרנ״א",
660 | 652: "תרנ״ב",
661 | 653: "תרנ״ג",
662 | 654: "תרנ״ד",
663 | 655: "תרנ״ה",
664 | 656: "תרנ״ו",
665 | 657: "תרנ״ז",
666 | 658: "תרנ״ח",
667 | 659: "תרנ״ט",
668 | 660: "תר״ס",
669 | 661: "תרס״א",
670 | 662: "תרס״ב",
671 | 663: "תרס״ג",
672 | 664: "תרס״ד",
673 | 665: "תרס״ה",
674 | 666: "תרס״ו",
675 | 667: "תרס״ז",
676 | 668: "תרס״ח",
677 | 669: "תרס״ט",
678 | 670: "תר״ע",
679 | 671: "תרע״א",
680 | 672: "תרע״ב",
681 | 673: "תרע״ג",
682 | 674: "תרע״ד",
683 | 675: "תרע״ה",
684 | 676: "תרע״ו",
685 | 677: "תרע״ז",
686 | 678: "תרע״ח",
687 | 679: "תרע״ט",
688 | 680: "תר״פ",
689 | 681: "תרפ״א",
690 | 682: "תרפ״ב",
691 | 683: "תרפ״ג",
692 | 684: "תרפ״ד",
693 | 685: "תרפ״ה",
694 | 686: "תרפ״ו",
695 | 687: "תרפ״ז",
696 | 688: "תרפ״ח",
697 | 689: "תרפ״ט",
698 | 690: "תר״צ",
699 | 691: "תרצ״א",
700 | 692: "תרצ״ב",
701 | 693: "תרצ״ג",
702 | 694: "תרצ״ד",
703 | 695: "תרצ״ה",
704 | 696: "תרצ״ו",
705 | 697: "תרצ״ז",
706 | 698: "תרצ״ח",
707 | 699: "תרצ״ט",
708 | 700: "ת״ש",
709 | 701: "תש״א",
710 | 702: "תש״ב",
711 | 703: "תש״ג",
712 | 704: "תש״ד",
713 | 705: "תש״ה",
714 | 706: "תש״ו",
715 | 707: "תש״ז",
716 | 708: "תש״ח",
717 | 709: "תש״ט",
718 | 710: "תש״י",
719 | 711: "תשי״א",
720 | 712: "תשי״ב",
721 | 713: "תשי״ג",
722 | 714: "תשי״ד",
723 | 715: "תשט״ו",
724 | 716: "תשט״ז",
725 | 717: "תשי״ז",
726 | 718: "תשי״ח",
727 | 719: "תשי״ט",
728 | 720: "תש״כ",
729 | 721: "תשכ״א",
730 | 722: "תשכ״ב",
731 | 723: "תשכ״ג",
732 | 724: "תשכ״ד",
733 | 725: "תשכ״ה",
734 | 726: "תשכ״ו",
735 | 727: "תשכ״ז",
736 | 728: "תשכ״ח",
737 | 729: "תשכ״ט",
738 | 730: "תש״ל",
739 | 731: "תשל״א",
740 | 732: "תשל״ב",
741 | 733: "תשל״ג",
742 | 734: "תשל״ד",
743 | 735: "תשל״ה",
744 | 736: "תשל״ו",
745 | 737: "תשל״ז",
746 | 738: "תשל״ח",
747 | 739: "תשל״ט",
748 | 740: "תש״מ",
749 | 741: "תשמ״א",
750 | 742: "תשמ״ב",
751 | 743: "תשמ״ג",
752 | 744: "תשמ״ד",
753 | 745: "תשמ״ה",
754 | 746: "תשמ״ו",
755 | 747: "תשמ״ז",
756 | 748: "תשמ״ח",
757 | 749: "תשמ״ט",
758 | 750: "תש״נ",
759 | 751: "תשנ״א",
760 | 752: "תשנ״ב",
761 | 753: "תשנ״ג",
762 | 754: "תשנ״ד",
763 | 755: "תשנ״ה",
764 | 756: "תשנ״ו",
765 | 757: "תשנ״ז",
766 | 758: "תשנ״ח",
767 | 759: "תשנ״ט",
768 | 760: "תש״ס",
769 | 761: "תשס״א",
770 | 762: "תשס״ב",
771 | 763: "תשס״ג",
772 | 764: "תשס״ד",
773 | 765: "תשס״ה",
774 | 766: "תשס״ו",
775 | 767: "תשס״ז",
776 | 768: "תשס״ח",
777 | 769: "תשס״ט",
778 | 770: "תש״ע",
779 | 771: "תשע״א",
780 | 772: "תשע״ב",
781 | 773: "תשע״ג",
782 | 774: "תשע״ד",
783 | 775: "תשע״ה",
784 | 776: "תשע״ו",
785 | 777: "תשע״ז",
786 | 778: "תשע״ח",
787 | 779: "תשע״ט",
788 | 780: "תש״פ",
789 | 781: "תשפ״א",
790 | 782: "תשפ״ב",
791 | 783: "תשפ״ג",
792 | 784: "תשפ״ד",
793 | 785: "תשפ״ה",
794 | 786: "תשפ״ו",
795 | 787: "תשפ״ז",
796 | 788: "תשפ״ח",
797 | 789: "תשפ״ט",
798 | 790: "תש״צ",
799 | 791: "תשצ״א",
800 | 792: "תשצ״ב",
801 | 793: "תשצ״ג",
802 | 794: "תשצ״ד",
803 | 795: "תשצ״ה",
804 | 796: "תשצ״ו",
805 | 797: "תשצ״ז",
806 | 798: "תשצ״ח",
807 | 799: "תשצ״ט",
808 | 800: "ת״ת",
809 | 801: "תת״א",
810 | 802: "תת״ב",
811 | 803: "תת״ג",
812 | 804: "תת״ד",
813 | 805: "תת״ה",
814 | 806: "תת״ו",
815 | 807: "תת״ז",
816 | 808: "תת״ח",
817 | 809: "תת״ט",
818 | 810: "תת״י",
819 | 811: "תתי״א",
820 | 812: "תתי״ב",
821 | 813: "תתי״ג",
822 | 814: "תתי״ד",
823 | 815: "תתט״ו",
824 | 816: "תתט״ז",
825 | 817: "תתי״ז",
826 | 818: "תתי״ח",
827 | 819: "תתי״ט",
828 | 820: "תת״כ",
829 | 821: "תתכ״א",
830 | 822: "תתכ״ב",
831 | 823: "תתכ״ג",
832 | 824: "תתכ״ד",
833 | 825: "תתכ״ה",
834 | 826: "תתכ״ו",
835 | 827: "תתכ״ז",
836 | 828: "תתכ״ח",
837 | 829: "תתכ״ט",
838 | 830: "תת״ל",
839 | 831: "תתל״א",
840 | 832: "תתל״ב",
841 | 833: "תתל״ג",
842 | 834: "תתל״ד",
843 | 835: "תתל״ה",
844 | 836: "תתל״ו",
845 | 837: "תתל״ז",
846 | 838: "תתל״ח",
847 | 839: "תתל״ט",
848 | 840: "תת״מ",
849 | 841: "תתמ״א",
850 | 842: "תתמ״ב",
851 | 843: "תתמ״ג",
852 | 844: "תתמ״ד",
853 | 845: "תתמ״ה",
854 | 846: "תתמ״ו",
855 | 847: "תתמ״ז",
856 | 848: "תתמ״ח",
857 | 849: "תתמ״ט",
858 | 850: "תת״נ",
859 | 851: "תתנ״א",
860 | 852: "תתנ״ב",
861 | 853: "תתנ״ג",
862 | 854: "תתנ״ד",
863 | 855: "תתנ״ה",
864 | 856: "תתנ״ו",
865 | 857: "תתנ״ז",
866 | 858: "תתנ״ח",
867 | 859: "תתנ״ט",
868 | 860: "תת״ס",
869 | 861: "תתס״א",
870 | 862: "תתס״ב",
871 | 863: "תתס״ג",
872 | 864: "תתס״ד",
873 | 865: "תתס״ה",
874 | 866: "תתס״ו",
875 | 867: "תתס״ז",
876 | 868: "תתס״ח",
877 | 869: "תתס״ט",
878 | 870: "תת״ע",
879 | 871: "תתע״א",
880 | 872: "תתע״ב",
881 | 873: "תתע״ג",
882 | 874: "תתע״ד",
883 | 875: "תתע״ה",
884 | 876: "תתע״ו",
885 | 877: "תתע״ז",
886 | 878: "תתע״ח",
887 | 879: "תתע״ט",
888 | 880: "תת״פ",
889 | 881: "תתפ״א",
890 | 882: "תתפ״ב",
891 | 883: "תתפ״ג",
892 | 884: "תתפ״ד",
893 | 885: "תתפ״ה",
894 | 886: "תתפ״ו",
895 | 887: "תתפ״ז",
896 | 888: "תתפ״ח",
897 | 889: "תתפ״ט",
898 | 890: "תת״צ",
899 | 891: "תתצ״א",
900 | 892: "תתצ״ב",
901 | 893: "תתצ״ג",
902 | 894: "תתצ״ד",
903 | 895: "תתצ״ה",
904 | 896: "תתצ״ו",
905 | 897: "תתצ״ז",
906 | 898: "תתצ״ח",
907 | 899: "תתצ״ט",
908 | 900: "תת״ק",
909 | 901: "תתק״א",
910 | 902: "תתק״ב",
911 | 903: "תתק״ג",
912 | 904: "תתק״ד",
913 | 905: "תתק״ה",
914 | 906: "תתק״ו",
915 | 907: "תתק״ז",
916 | 908: "תתק״ח",
917 | 909: "תתק״ט",
918 | 910: "תתק״י",
919 | 911: "תתקי״א",
920 | 912: "תתקי״ב",
921 | 913: "תתקי״ג",
922 | 914: "תתקי״ד",
923 | 915: "תתקט״ו",
924 | 916: "תתקט״ז",
925 | 917: "תתקי״ז",
926 | 918: "תתקי״ח",
927 | 919: "תתקי״ט",
928 | 920: "תתק״כ",
929 | 921: "תתקכ״א",
930 | 922: "תתקכ״ב",
931 | 923: "תתקכ״ג",
932 | 924: "תתקכ״ד",
933 | 925: "תתקכ״ה",
934 | 926: "תתקכ״ו",
935 | 927: "תתקכ״ז",
936 | 928: "תתקכ״ח",
937 | 929: "תתקכ״ט",
938 | 930: "תתק״ל",
939 | 931: "תתקל״א",
940 | 932: "תתקל״ב",
941 | 933: "תתקל״ג",
942 | 934: "תתקל״ד",
943 | 935: "תתקל״ה",
944 | 936: "תתקל״ו",
945 | 937: "תתקל״ז",
946 | 938: "תתקל״ח",
947 | 939: "תתקל״ט",
948 | 940: "תתק״מ",
949 | 941: "תתקמ״א",
950 | 942: "תתקמ״ב",
951 | 943: "תתקמ״ג",
952 | 944: "תתקמ״ד",
953 | 945: "תתקמ״ה",
954 | 946: "תתקמ״ו",
955 | 947: "תתקמ״ז",
956 | 948: "תתקמ״ח",
957 | 949: "תתקמ״ט",
958 | 950: "תתק״נ",
959 | 951: "תתקנ״א",
960 | 952: "תתקנ״ב",
961 | 953: "תתקנ״ג",
962 | 954: "תתקנ״ד",
963 | 955: "תתקנ״ה",
964 | 956: "תתקנ״ו",
965 | 957: "תתקנ״ז",
966 | 958: "תתקנ״ח",
967 | 959: "תתקנ״ט",
968 | 960: "תתק״ס",
969 | 961: "תתקס״א",
970 | 962: "תתקס״ב",
971 | 963: "תתקס״ג",
972 | 964: "תתקס״ד",
973 | 965: "תתקס״ה",
974 | 966: "תתקס״ו",
975 | 967: "תתקס״ז",
976 | 968: "תתקס״ח",
977 | 969: "תתקס״ט",
978 | 970: "תתק״ע",
979 | 971: "תתקע״א",
980 | 972: "תתקע״ב",
981 | 973: "תתקע״ג",
982 | 974: "תתקע״ד",
983 | 975: "תתקע״ה",
984 | 976: "תתקע״ו",
985 | 977: "תתקע״ז",
986 | 978: "תתקע״ח",
987 | 979: "תתקע״ט",
988 | 980: "תתק״פ",
989 | 981: "תתקפ״א",
990 | 982: "תתקפ״ב",
991 | 983: "תתקפ״ג",
992 | 984: "תתקפ״ד",
993 | 985: "תתקפ״ה",
994 | 986: "תתקפ״ו",
995 | 987: "תתקפ״ז",
996 | 988: "תתקפ״ח",
997 | 989: "תתקפ״ט",
998 | 990: "תתק״צ",
999 | 991: "תתקצ״א",
1000 | 992: "תתקצ״ב",
1001 | 993: "תתקצ״ג",
1002 | 994: "תתקצ״ד",
1003 | 995: "תתקצ״ה",
1004 | 996: "תתקצ״ו",
1005 | 997: "תתקצ״ז",
1006 | 998: "תתקצ״ח",
1007 | 999: "תתקצ״ט",
1008 | 1000: "תת״ר",
1009 | 1001: "תתר״א",
1010 | 1002: "תתר״ב",
1011 | 1003: "תתר״ג",
1012 | 1004: "תתר״ד",
1013 | 1005: "תתר״ה",
1014 | 1006: "תתר״ו",
1015 | 1007: "תתר״ז",
1016 | 1008: "תתר״ח",
1017 | 1009: "תתר״ט",
1018 | 1010: "תתר״י",
1019 | 1011: "תתרי״א",
1020 | 1012: "תתרי״ב",
1021 | 1013: "תתרי״ג",
1022 | 1014: "תתרי״ד",
1023 | 1015: "תתרט״ו",
1024 | 1016: "תתרט״ז",
1025 | 1017: "תתרי״ז",
1026 | 1018: "תתרי״ח",
1027 | 1019: "תתרי״ט",
1028 | 1020: "תתר״כ",
1029 | 1021: "תתרכ״א",
1030 | 1022: "תתרכ״ב",
1031 | 1023: "תתרכ״ג",
1032 | 1024: "תתרכ״ד",
1033 | 1025: "תתרכ״ה",
1034 | 1026: "תתרכ״ו",
1035 | 1027: "תתרכ״ז",
1036 | 1028: "תתרכ״ח",
1037 | 1029: "תתרכ״ט",
1038 | 1030: "תתר״ל",
1039 | 1031: "תתרל״א",
1040 | 1032: "תתרל״ב",
1041 | 1033: "תתרל״ג",
1042 | 1034: "תתרל״ד",
1043 | 1035: "תתרל״ה",
1044 | 1036: "תתרל״ו",
1045 | 1037: "תתרל״ז",
1046 | 1038: "תתרל״ח",
1047 | 1039: "תתרל״ט",
1048 | 1040: "תתר״מ",
1049 | 1041: "תתרמ״א",
1050 | 1042: "תתרמ״ב",
1051 | 1043: "תתרמ״ג",
1052 | 1044: "תתרמ״ד",
1053 | 1045: "תתרמ״ה",
1054 | 1046: "תתרמ״ו",
1055 | 1047: "תתרמ״ז",
1056 | 1048: "תתרמ״ח",
1057 | 1049: "תתרמ״ט",
1058 | 1050: "תתר״נ",
1059 | 1051: "תתרנ״א",
1060 | 1052: "תתרנ״ב",
1061 | 1053: "תתרנ״ג",
1062 | 1054: "תתרנ״ד",
1063 | 1055: "תתרנ״ה",
1064 | 1056: "תתרנ״ו",
1065 | 1057: "תתרנ״ז",
1066 | 1058: "תתרנ״ח",
1067 | 1059: "תתרנ״ט",
1068 | 1060: "תתר״ס",
1069 | 1061: "תתרס״א",
1070 | 1062: "תתרס״ב",
1071 | 1063: "תתרס״ג",
1072 | 1064: "תתרס״ד",
1073 | 1065: "תתרס״ה",
1074 | 1066: "תתרס״ו",
1075 | 1067: "תתרס״ז",
1076 | 1068: "תתרס״ח",
1077 | 1069: "תתרס״ט",
1078 | 1070: "תתר״ע",
1079 | 1071: "תתרע״א",
1080 | 1072: "תתרע״ב",
1081 | 1073: "תתרע״ג",
1082 | 1074: "תתרע״ד",
1083 | 1075: "תתרע״ה",
1084 | 1076: "תתרע״ו",
1085 | 1077: "תתרע״ז",
1086 | 1078: "תתרע״ח",
1087 | 1079: "תתרע״ט",
1088 | 1080: "תתר״פ",
1089 | 1081: "תתרפ״א",
1090 | 1082: "תתרפ״ב",
1091 | 1083: "תתרפ״ג",
1092 | 1084: "תתרפ״ד",
1093 | 1085: "תתרפ״ה",
1094 | 1086: "תתרפ״ו",
1095 | 1087: "תתרפ״ז",
1096 | 1088: "תתרפ״ח",
1097 | 1089: "תתרפ״ט",
1098 | 1090: "תתר״צ",
1099 | 1091: "תתרצ״א",
1100 | 1092: "תתרצ״ב",
1101 | 1093: "תתרצ״ג",
1102 | 1094: "תתרצ״ד",
1103 | 1095: "תתרצ״ה",
1104 | 1096: "תתרצ״ו",
1105 | 1097: "תתרצ״ז",
1106 | 1098: "תתרצ״ח",
1107 | 1099: "תתרצ״ט",
1108 | 1100: "תת״ש",
1109 | 1101: "תתש״א",
1110 | 1102: "תתש״ב",
1111 | 1103: "תתש״ג",
1112 | 1104: "תתש״ד",
1113 | 1105: "תתש״ה",
1114 | 1106: "תתש״ו",
1115 | 1107: "תתש״ז",
1116 | 1108: "תתש״ח",
1117 | 1109: "תתש״ט",
1118 | 1110: "תתש״י",
1119 | 1111: "תתשי״א",
1120 | 1112: "תתשי״ב",
1121 | 1113: "תתשי״ג",
1122 | 1114: "תתשי״ד",
1123 | 1115: "תתשט״ו",
1124 | 1116: "תתשט״ז",
1125 | 1117: "תתשי״ז",
1126 | 1118: "תתשי״ח",
1127 | 1119: "תתשי״ט",
1128 | 1120: "תתש״כ",
1129 | 1121: "תתשכ״א",
1130 | 1122: "תתשכ״ב",
1131 | 1123: "תתשכ״ג",
1132 | 1124: "תתשכ״ד",
1133 | 1125: "תתשכ״ה",
1134 | 1126: "תתשכ״ו",
1135 | 1127: "תתשכ״ז",
1136 | 1128: "תתשכ״ח",
1137 | 1129: "תתשכ״ט",
1138 | 1130: "תתש״ל",
1139 | 1131: "תתשל״א",
1140 | 1132: "תתשל״ב",
1141 | 1133: "תתשל״ג",
1142 | 1134: "תתשל״ד",
1143 | 1135: "תתשל״ה",
1144 | 1136: "תתשל״ו",
1145 | 1137: "תתשל״ז",
1146 | 1138: "תתשל״ח",
1147 | 1139: "תתשל״ט",
1148 | 1140: "תתש״מ",
1149 | 1141: "תתשמ״א",
1150 | 1142: "תתשמ״ב",
1151 | 1143: "תתשמ״ג",
1152 | 1144: "תתשמ״ד",
1153 | 1145: "תתשמ״ה",
1154 | 1146: "תתשמ״ו",
1155 | 1147: "תתשמ״ז",
1156 | 1148: "תתשמ״ח",
1157 | 1149: "תתשמ״ט",
1158 | 1150: "תתש״נ",
1159 | 1151: "תתשנ״א",
1160 | 1152: "תתשנ״ב",
1161 | 1153: "תתשנ״ג",
1162 | 1154: "תתשנ״ד",
1163 | 1155: "תתשנ״ה",
1164 | 1156: "תתשנ״ו",
1165 | 1157: "תתשנ״ז",
1166 | 1158: "תתשנ״ח",
1167 | 1159: "תתשנ״ט",
1168 | 1160: "תתש״ס",
1169 | 1161: "תתשס״א",
1170 | 1162: "תתשס״ב",
1171 | 1163: "תתשס״ג",
1172 | 1164: "תתשס״ד",
1173 | 1165: "תתשס״ה",
1174 | 1166: "תתשס״ו",
1175 | 1167: "תתשס״ז",
1176 | 1168: "תתשס״ח",
1177 | 1169: "תתשס״ט",
1178 | 1170: "תתש״ע",
1179 | 1171: "תתשע״א",
1180 | 1172: "תתשע״ב",
1181 | 1173: "תתשע״ג",
1182 | 1174: "תתשע״ד",
1183 | 1175: "תתשע״ה",
1184 | 1176: "תתשע״ו",
1185 | 1177: "תתשע״ז",
1186 | 1178: "תתשע״ח",
1187 | 1179: "תתשע״ט",
1188 | 1180: "תתש״פ",
1189 | 1181: "תתשפ״א",
1190 | 1182: "תתשפ״ב",
1191 | 1183: "תתשפ״ג",
1192 | 1184: "תתשפ״ד",
1193 | 1185: "תתשפ״ה",
1194 | 1186: "תתשפ״ו",
1195 | 1187: "תתשפ״ז",
1196 | 1188: "תתשפ״ח",
1197 | 1189: "תתשפ״ט",
1198 | 1190: "תתש״צ",
1199 | 1191: "תתשצ״א",
1200 | 1192: "תתשצ״ב",
1201 | 1193: "תתשצ״ג",
1202 | 1194: "תתשצ״ד",
1203 | 1195: "תתשצ״ה",
1204 | 1196: "תתשצ״ו",
1205 | 1197: "תתשצ״ז",
1206 | 1198: "תתשצ״ח",
1207 | 1199: "תתשצ״ט",
1208 | 4567: "תתתתתתתתתתתקס״ז",
1209 | }
1210 | NO_PUNCTUATION = {
1211 | 1: "א",
1212 | 2: "ב",
1213 | 3: "ג",
1214 | 4: "ד",
1215 | 5: "ה",
1216 | 6: "ו",
1217 | 7: "ז",
1218 | 8: "ח",
1219 | 9: "ט",
1220 | 10: "י",
1221 | 11: "יא",
1222 | 12: "יב",
1223 | 13: "יג",
1224 | 14: "יד",
1225 | 15: "טו",
1226 | 16: "טז",
1227 | 17: "יז",
1228 | 18: "יח",
1229 | 19: "יט",
1230 | 20: "כ",
1231 | 21: "כא",
1232 | 22: "כב",
1233 | 23: "כג",
1234 | 24: "כד",
1235 | 25: "כה",
1236 | 26: "כו",
1237 | 27: "כז",
1238 | 28: "כח",
1239 | 29: "כט",
1240 | 30: "ל",
1241 | 31: "לא",
1242 | 32: "לב",
1243 | 33: "לג",
1244 | 34: "לד",
1245 | 35: "לה",
1246 | 36: "לו",
1247 | 37: "לז",
1248 | 38: "לח",
1249 | 39: "לט",
1250 | 40: "מ",
1251 | 41: "מא",
1252 | 42: "מב",
1253 | 43: "מג",
1254 | 44: "מד",
1255 | 45: "מה",
1256 | 46: "מו",
1257 | 47: "מז",
1258 | 48: "מח",
1259 | 49: "מט",
1260 | 50: "נ",
1261 | 51: "נא",
1262 | 52: "נב",
1263 | 53: "נג",
1264 | 54: "נד",
1265 | 55: "נה",
1266 | 56: "נו",
1267 | 57: "נז",
1268 | 58: "נח",
1269 | 59: "נט",
1270 | 60: "ס",
1271 | 61: "סא",
1272 | 62: "סב",
1273 | 63: "סג",
1274 | 64: "סד",
1275 | 65: "סה",
1276 | 66: "סו",
1277 | 67: "סז",
1278 | 68: "סח",
1279 | 69: "סט",
1280 | 70: "ע",
1281 | 71: "עא",
1282 | 72: "עב",
1283 | 73: "עג",
1284 | 74: "עד",
1285 | 75: "עה",
1286 | 76: "עו",
1287 | 77: "עז",
1288 | 78: "עח",
1289 | 79: "עט",
1290 | 80: "פ",
1291 | 81: "פא",
1292 | 82: "פב",
1293 | 83: "פג",
1294 | 84: "פד",
1295 | 85: "פה",
1296 | 86: "פו",
1297 | 87: "פז",
1298 | 88: "פח",
1299 | 89: "פט",
1300 | 90: "צ",
1301 | 91: "צא",
1302 | 92: "צב",
1303 | 93: "צג",
1304 | 94: "צד",
1305 | 95: "צה",
1306 | 96: "צו",
1307 | 97: "צז",
1308 | 98: "צח",
1309 | 99: "צט",
1310 | 100: "ק",
1311 | 101: "קא",
1312 | 102: "קב",
1313 | 103: "קג",
1314 | 104: "קד",
1315 | 105: "קה",
1316 | 106: "קו",
1317 | 107: "קז",
1318 | 108: "קח",
1319 | 109: "קט",
1320 | 110: "קי",
1321 | 111: "קיא",
1322 | 112: "קיב",
1323 | 113: "קיג",
1324 | 114: "קיד",
1325 | 115: "קטו",
1326 | 116: "קטז",
1327 | 117: "קיז",
1328 | 118: "קיח",
1329 | 119: "קיט",
1330 | 120: "קכ",
1331 | 121: "קכא",
1332 | 122: "קכב",
1333 | 123: "קכג",
1334 | 124: "קכד",
1335 | 125: "קכה",
1336 | 126: "קכו",
1337 | 127: "קכז",
1338 | 128: "קכח",
1339 | 129: "קכט",
1340 | 130: "קל",
1341 | 131: "קלא",
1342 | 132: "קלב",
1343 | 133: "קלג",
1344 | 134: "קלד",
1345 | 135: "קלה",
1346 | 136: "קלו",
1347 | 137: "קלז",
1348 | 138: "קלח",
1349 | 139: "קלט",
1350 | 140: "קמ",
1351 | 141: "קמא",
1352 | 142: "קמב",
1353 | 143: "קמג",
1354 | 144: "קמד",
1355 | 145: "קמה",
1356 | 146: "קמו",
1357 | 147: "קמז",
1358 | 148: "קמח",
1359 | 149: "קמט",
1360 | 150: "קנ",
1361 | 151: "קנא",
1362 | 152: "קנב",
1363 | 153: "קנג",
1364 | 154: "קנד",
1365 | 155: "קנה",
1366 | 156: "קנו",
1367 | 157: "קנז",
1368 | 158: "קנח",
1369 | 159: "קנט",
1370 | 160: "קס",
1371 | 161: "קסא",
1372 | 162: "קסב",
1373 | 163: "קסג",
1374 | 164: "קסד",
1375 | 165: "קסה",
1376 | 166: "קסו",
1377 | 167: "קסז",
1378 | 168: "קסח",
1379 | 169: "קסט",
1380 | 170: "קע",
1381 | 171: "קעא",
1382 | 172: "קעב",
1383 | 173: "קעג",
1384 | 174: "קעד",
1385 | 175: "קעה",
1386 | 176: "קעו",
1387 | 177: "קעז",
1388 | 178: "קעח",
1389 | 179: "קעט",
1390 | 180: "קפ",
1391 | 181: "קפא",
1392 | 182: "קפב",
1393 | 183: "קפג",
1394 | 184: "קפד",
1395 | 185: "קפה",
1396 | 186: "קפו",
1397 | 187: "קפז",
1398 | 188: "קפח",
1399 | 189: "קפט",
1400 | 190: "קצ",
1401 | 191: "קצא",
1402 | 192: "קצב",
1403 | 193: "קצג",
1404 | 194: "קצד",
1405 | 195: "קצה",
1406 | 196: "קצו",
1407 | 197: "קצז",
1408 | 198: "קצח",
1409 | 199: "קצט",
1410 | 200: "ר",
1411 | 201: "רא",
1412 | 202: "רב",
1413 | 203: "רג",
1414 | 204: "רד",
1415 | 205: "רה",
1416 | 206: "רו",
1417 | 207: "רז",
1418 | 208: "רח",
1419 | 209: "רט",
1420 | 210: "רי",
1421 | 211: "ריא",
1422 | 212: "ריב",
1423 | 213: "ריג",
1424 | 214: "ריד",
1425 | 215: "רטו",
1426 | 216: "רטז",
1427 | 217: "ריז",
1428 | 218: "ריח",
1429 | 219: "ריט",
1430 | 220: "רכ",
1431 | 221: "רכא",
1432 | 222: "רכב",
1433 | 223: "רכג",
1434 | 224: "רכד",
1435 | 225: "רכה",
1436 | 226: "רכו",
1437 | 227: "רכז",
1438 | 228: "רכח",
1439 | 229: "רכט",
1440 | 230: "רל",
1441 | 231: "רלא",
1442 | 232: "רלב",
1443 | 233: "רלג",
1444 | 234: "רלד",
1445 | 235: "רלה",
1446 | 236: "רלו",
1447 | 237: "רלז",
1448 | 238: "רלח",
1449 | 239: "רלט",
1450 | 240: "רמ",
1451 | 241: "רמא",
1452 | 242: "רמב",
1453 | 243: "רמג",
1454 | 244: "רמד",
1455 | 245: "רמה",
1456 | 246: "רמו",
1457 | 247: "רמז",
1458 | 248: "רמח",
1459 | 249: "רמט",
1460 | 250: "רנ",
1461 | 251: "רנא",
1462 | 252: "רנב",
1463 | 253: "רנג",
1464 | 254: "רנד",
1465 | 255: "רנה",
1466 | 256: "רנו",
1467 | 257: "רנז",
1468 | 258: "רנח",
1469 | 259: "רנט",
1470 | 260: "רס",
1471 | 261: "רסא",
1472 | 262: "רסב",
1473 | 263: "רסג",
1474 | 264: "רסד",
1475 | 265: "רסה",
1476 | 266: "רסו",
1477 | 267: "רסז",
1478 | 268: "רסח",
1479 | 269: "רסט",
1480 | 270: "רע",
1481 | 271: "רעא",
1482 | 272: "רעב",
1483 | 273: "רעג",
1484 | 274: "רעד",
1485 | 275: "רעה",
1486 | 276: "רעו",
1487 | 277: "רעז",
1488 | 278: "רעח",
1489 | 279: "רעט",
1490 | 280: "רפ",
1491 | 281: "רפא",
1492 | 282: "רפב",
1493 | 283: "רפג",
1494 | 284: "רפד",
1495 | 285: "רפה",
1496 | 286: "רפו",
1497 | 287: "רפז",
1498 | 288: "רפח",
1499 | 289: "רפט",
1500 | 290: "רצ",
1501 | 291: "רצא",
1502 | 292: "רצב",
1503 | 293: "רצג",
1504 | 294: "רצד",
1505 | 295: "רצה",
1506 | 296: "רצו",
1507 | 297: "רצז",
1508 | 298: "רצח",
1509 | 299: "רצט",
1510 | 300: "ש",
1511 | 301: "שא",
1512 | 302: "שב",
1513 | 303: "שג",
1514 | 304: "שד",
1515 | 305: "שה",
1516 | 306: "שו",
1517 | 307: "שז",
1518 | 308: "שח",
1519 | 309: "שט",
1520 | 310: "שי",
1521 | 311: "שיא",
1522 | 312: "שיב",
1523 | 313: "שיג",
1524 | 314: "שיד",
1525 | 315: "שטו",
1526 | 316: "שטז",
1527 | 317: "שיז",
1528 | 318: "שיח",
1529 | 319: "שיט",
1530 | 320: "שכ",
1531 | 321: "שכא",
1532 | 322: "שכב",
1533 | 323: "שכג",
1534 | 324: "שכד",
1535 | 325: "שכה",
1536 | 326: "שכו",
1537 | 327: "שכז",
1538 | 328: "שכח",
1539 | 329: "שכט",
1540 | 330: "של",
1541 | 331: "שלא",
1542 | 332: "שלב",
1543 | 333: "שלג",
1544 | 334: "שלד",
1545 | 335: "שלה",
1546 | 336: "שלו",
1547 | 337: "שלז",
1548 | 338: "שלח",
1549 | 339: "שלט",
1550 | 340: "שמ",
1551 | 341: "שמא",
1552 | 342: "שמב",
1553 | 343: "שמג",
1554 | 344: "שמד",
1555 | 345: "שמה",
1556 | 346: "שמו",
1557 | 347: "שמז",
1558 | 348: "שמח",
1559 | 349: "שמט",
1560 | 350: "שנ",
1561 | 351: "שנא",
1562 | 352: "שנב",
1563 | 353: "שנג",
1564 | 354: "שנד",
1565 | 355: "שנה",
1566 | 356: "שנו",
1567 | 357: "שנז",
1568 | 358: "שנח",
1569 | 359: "שנט",
1570 | 360: "שס",
1571 | 361: "שסא",
1572 | 362: "שסב",
1573 | 363: "שסג",
1574 | 364: "שסד",
1575 | 365: "שסה",
1576 | 366: "שסו",
1577 | 367: "שסז",
1578 | 368: "שסח",
1579 | 369: "שסט",
1580 | 370: "שע",
1581 | 371: "שעא",
1582 | 372: "שעב",
1583 | 373: "שעג",
1584 | 374: "שעד",
1585 | 375: "שעה",
1586 | 376: "שעו",
1587 | 377: "שעז",
1588 | 378: "שעח",
1589 | 379: "שעט",
1590 | 380: "שפ",
1591 | 381: "שפא",
1592 | 382: "שפב",
1593 | 383: "שפג",
1594 | 384: "שפד",
1595 | 385: "שפה",
1596 | 386: "שפו",
1597 | 387: "שפז",
1598 | 388: "שפח",
1599 | 389: "שפט",
1600 | 390: "שצ",
1601 | 391: "שצא",
1602 | 392: "שצב",
1603 | 393: "שצג",
1604 | 394: "שצד",
1605 | 395: "שצה",
1606 | 396: "שצו",
1607 | 397: "שצז",
1608 | 398: "שצח",
1609 | 399: "שצט",
1610 | 400: "ת",
1611 | 401: "תא",
1612 | 402: "תב",
1613 | 403: "תג",
1614 | 404: "תד",
1615 | 405: "תה",
1616 | 406: "תו",
1617 | 407: "תז",
1618 | 408: "תח",
1619 | 409: "תט",
1620 | 410: "תי",
1621 | 411: "תיא",
1622 | 412: "תיב",
1623 | 413: "תיג",
1624 | 414: "תיד",
1625 | 415: "תטו",
1626 | 416: "תטז",
1627 | 417: "תיז",
1628 | 418: "תיח",
1629 | 419: "תיט",
1630 | 420: "תכ",
1631 | 421: "תכא",
1632 | 422: "תכב",
1633 | 423: "תכג",
1634 | 424: "תכד",
1635 | 425: "תכה",
1636 | 426: "תכו",
1637 | 427: "תכז",
1638 | 428: "תכח",
1639 | 429: "תכט",
1640 | 430: "תל",
1641 | 431: "תלא",
1642 | 432: "תלב",
1643 | 433: "תלג",
1644 | 434: "תלד",
1645 | 435: "תלה",
1646 | 436: "תלו",
1647 | 437: "תלז",
1648 | 438: "תלח",
1649 | 439: "תלט",
1650 | 440: "תמ",
1651 | 441: "תמא",
1652 | 442: "תמב",
1653 | 443: "תמג",
1654 | 444: "תמד",
1655 | 445: "תמה",
1656 | 446: "תמו",
1657 | 447: "תמז",
1658 | 448: "תמח",
1659 | 449: "תמט",
1660 | 450: "תנ",
1661 | 451: "תנא",
1662 | 452: "תנב",
1663 | 453: "תנג",
1664 | 454: "תנד",
1665 | 455: "תנה",
1666 | 456: "תנו",
1667 | 457: "תנז",
1668 | 458: "תנח",
1669 | 459: "תנט",
1670 | 460: "תס",
1671 | 461: "תסא",
1672 | 462: "תסב",
1673 | 463: "תסג",
1674 | 464: "תסד",
1675 | 465: "תסה",
1676 | 466: "תסו",
1677 | 467: "תסז",
1678 | 468: "תסח",
1679 | 469: "תסט",
1680 | 470: "תע",
1681 | 471: "תעא",
1682 | 472: "תעב",
1683 | 473: "תעג",
1684 | 474: "תעד",
1685 | 475: "תעה",
1686 | 476: "תעו",
1687 | 477: "תעז",
1688 | 478: "תעח",
1689 | 479: "תעט",
1690 | 480: "תפ",
1691 | 481: "תפא",
1692 | 482: "תפב",
1693 | 483: "תפג",
1694 | 484: "תפד",
1695 | 485: "תפה",
1696 | 486: "תפו",
1697 | 487: "תפז",
1698 | 488: "תפח",
1699 | 489: "תפט",
1700 | 490: "תצ",
1701 | 491: "תצא",
1702 | 492: "תצב",
1703 | 493: "תצג",
1704 | 494: "תצד",
1705 | 495: "תצה",
1706 | 496: "תצו",
1707 | 497: "תצז",
1708 | 498: "תצח",
1709 | 499: "תצט",
1710 | 500: "תק",
1711 | 501: "תקא",
1712 | 502: "תקב",
1713 | 503: "תקג",
1714 | 504: "תקד",
1715 | 505: "תקה",
1716 | 506: "תקו",
1717 | 507: "תקז",
1718 | 508: "תקח",
1719 | 509: "תקט",
1720 | 510: "תקי",
1721 | 511: "תקיא",
1722 | 512: "תקיב",
1723 | 513: "תקיג",
1724 | 514: "תקיד",
1725 | 515: "תקטו",
1726 | 516: "תקטז",
1727 | 517: "תקיז",
1728 | 518: "תקיח",
1729 | 519: "תקיט",
1730 | 520: "תקכ",
1731 | 521: "תקכא",
1732 | 522: "תקכב",
1733 | 523: "תקכג",
1734 | 524: "תקכד",
1735 | 525: "תקכה",
1736 | 526: "תקכו",
1737 | 527: "תקכז",
1738 | 528: "תקכח",
1739 | 529: "תקכט",
1740 | 530: "תקל",
1741 | 531: "תקלא",
1742 | 532: "תקלב",
1743 | 533: "תקלג",
1744 | 534: "תקלד",
1745 | 535: "תקלה",
1746 | 536: "תקלו",
1747 | 537: "תקלז",
1748 | 538: "תקלח",
1749 | 539: "תקלט",
1750 | 540: "תקמ",
1751 | 541: "תקמא",
1752 | 542: "תקמב",
1753 | 543: "תקמג",
1754 | 544: "תקמד",
1755 | 545: "תקמה",
1756 | 546: "תקמו",
1757 | 547: "תקמז",
1758 | 548: "תקמח",
1759 | 549: "תקמט",
1760 | 550: "תקנ",
1761 | 551: "תקנא",
1762 | 552: "תקנב",
1763 | 553: "תקנג",
1764 | 554: "תקנד",
1765 | 555: "תקנה",
1766 | 556: "תקנו",
1767 | 557: "תקנז",
1768 | 558: "תקנח",
1769 | 559: "תקנט",
1770 | 560: "תקס",
1771 | 561: "תקסא",
1772 | 562: "תקסב",
1773 | 563: "תקסג",
1774 | 564: "תקסד",
1775 | 565: "תקסה",
1776 | 566: "תקסו",
1777 | 567: "תקסז",
1778 | 568: "תקסח",
1779 | 569: "תקסט",
1780 | 570: "תקע",
1781 | 571: "תקעא",
1782 | 572: "תקעב",
1783 | 573: "תקעג",
1784 | 574: "תקעד",
1785 | 575: "תקעה",
1786 | 576: "תקעו",
1787 | 577: "תקעז",
1788 | 578: "תקעח",
1789 | 579: "תקעט",
1790 | 580: "תקפ",
1791 | 581: "תקפא",
1792 | 582: "תקפב",
1793 | 583: "תקפג",
1794 | 584: "תקפד",
1795 | 585: "תקפה",
1796 | 586: "תקפו",
1797 | 587: "תקפז",
1798 | 588: "תקפח",
1799 | 589: "תקפט",
1800 | 590: "תקצ",
1801 | 591: "תקצא",
1802 | 592: "תקצב",
1803 | 593: "תקצג",
1804 | 594: "תקצד",
1805 | 595: "תקצה",
1806 | 596: "תקצו",
1807 | 597: "תקצז",
1808 | 598: "תקצח",
1809 | 599: "תקצט",
1810 | 600: "תר",
1811 | 601: "תרא",
1812 | 602: "תרב",
1813 | 603: "תרג",
1814 | 604: "תרד",
1815 | 605: "תרה",
1816 | 606: "תרו",
1817 | 607: "תרז",
1818 | 608: "תרח",
1819 | 609: "תרט",
1820 | 610: "תרי",
1821 | 611: "תריא",
1822 | 612: "תריב",
1823 | 613: "תריג",
1824 | 614: "תריד",
1825 | 615: "תרטו",
1826 | 616: "תרטז",
1827 | 617: "תריז",
1828 | 618: "תריח",
1829 | 619: "תריט",
1830 | 620: "תרכ",
1831 | 621: "תרכא",
1832 | 622: "תרכב",
1833 | 623: "תרכג",
1834 | 624: "תרכד",
1835 | 625: "תרכה",
1836 | 626: "תרכו",
1837 | 627: "תרכז",
1838 | 628: "תרכח",
1839 | 629: "תרכט",
1840 | 630: "תרל",
1841 | 631: "תרלא",
1842 | 632: "תרלב",
1843 | 633: "תרלג",
1844 | 634: "תרלד",
1845 | 635: "תרלה",
1846 | 636: "תרלו",
1847 | 637: "תרלז",
1848 | 638: "תרלח",
1849 | 639: "תרלט",
1850 | 640: "תרמ",
1851 | 641: "תרמא",
1852 | 642: "תרמב",
1853 | 643: "תרמג",
1854 | 644: "תרמד",
1855 | 645: "תרמה",
1856 | 646: "תרמו",
1857 | 647: "תרמז",
1858 | 648: "תרמח",
1859 | 649: "תרמט",
1860 | 650: "תרנ",
1861 | 651: "תרנא",
1862 | 652: "תרנב",
1863 | 653: "תרנג",
1864 | 654: "תרנד",
1865 | 655: "תרנה",
1866 | 656: "תרנו",
1867 | 657: "תרנז",
1868 | 658: "תרנח",
1869 | 659: "תרנט",
1870 | 660: "תרס",
1871 | 661: "תרסא",
1872 | 662: "תרסב",
1873 | 663: "תרסג",
1874 | 664: "תרסד",
1875 | 665: "תרסה",
1876 | 666: "תרסו",
1877 | 667: "תרסז",
1878 | 668: "תרסח",
1879 | 669: "תרסט",
1880 | 670: "תרע",
1881 | 671: "תרעא",
1882 | 672: "תרעב",
1883 | 673: "תרעג",
1884 | 674: "תרעד",
1885 | 675: "תרעה",
1886 | 676: "תרעו",
1887 | 677: "תרעז",
1888 | 678: "תרעח",
1889 | 679: "תרעט",
1890 | 680: "תרפ",
1891 | 681: "תרפא",
1892 | 682: "תרפב",
1893 | 683: "תרפג",
1894 | 684: "תרפד",
1895 | 685: "תרפה",
1896 | 686: "תרפו",
1897 | 687: "תרפז",
1898 | 688: "תרפח",
1899 | 689: "תרפט",
1900 | 690: "תרצ",
1901 | 691: "תרצא",
1902 | 692: "תרצב",
1903 | 693: "תרצג",
1904 | 694: "תרצד",
1905 | 695: "תרצה",
1906 | 696: "תרצו",
1907 | 697: "תרצז",
1908 | 698: "תרצח",
1909 | 699: "תרצט",
1910 | 700: "תש",
1911 | 701: "תשא",
1912 | 702: "תשב",
1913 | 703: "תשג",
1914 | 704: "תשד",
1915 | 705: "תשה",
1916 | 706: "תשו",
1917 | 707: "תשז",
1918 | 708: "תשח",
1919 | 709: "תשט",
1920 | 710: "תשי",
1921 | 711: "תשיא",
1922 | 712: "תשיב",
1923 | 713: "תשיג",
1924 | 714: "תשיד",
1925 | 715: "תשטו",
1926 | 716: "תשטז",
1927 | 717: "תשיז",
1928 | 718: "תשיח",
1929 | 719: "תשיט",
1930 | 720: "תשכ",
1931 | 721: "תשכא",
1932 | 722: "תשכב",
1933 | 723: "תשכג",
1934 | 724: "תשכד",
1935 | 725: "תשכה",
1936 | 726: "תשכו",
1937 | 727: "תשכז",
1938 | 728: "תשכח",
1939 | 729: "תשכט",
1940 | 730: "תשל",
1941 | 731: "תשלא",
1942 | 732: "תשלב",
1943 | 733: "תשלג",
1944 | 734: "תשלד",
1945 | 735: "תשלה",
1946 | 736: "תשלו",
1947 | 737: "תשלז",
1948 | 738: "תשלח",
1949 | 739: "תשלט",
1950 | 740: "תשמ",
1951 | 741: "תשמא",
1952 | 742: "תשמב",
1953 | 743: "תשמג",
1954 | 744: "תשמד",
1955 | 745: "תשמה",
1956 | 746: "תשמו",
1957 | 747: "תשמז",
1958 | 748: "תשמח",
1959 | 749: "תשמט",
1960 | 750: "תשנ",
1961 | 751: "תשנא",
1962 | 752: "תשנב",
1963 | 753: "תשנג",
1964 | 754: "תשנד",
1965 | 755: "תשנה",
1966 | 756: "תשנו",
1967 | 757: "תשנז",
1968 | 758: "תשנח",
1969 | 759: "תשנט",
1970 | 760: "תשס",
1971 | 761: "תשסא",
1972 | 762: "תשסב",
1973 | 763: "תשסג",
1974 | 764: "תשסד",
1975 | 765: "תשסה",
1976 | 766: "תשסו",
1977 | 767: "תשסז",
1978 | 768: "תשסח",
1979 | 769: "תשסט",
1980 | 770: "תשע",
1981 | 771: "תשעא",
1982 | 772: "תשעב",
1983 | 773: "תשעג",
1984 | 774: "תשעד",
1985 | 775: "תשעה",
1986 | 776: "תשעו",
1987 | 777: "תשעז",
1988 | 778: "תשעח",
1989 | 779: "תשעט",
1990 | 780: "תשפ",
1991 | 781: "תשפא",
1992 | 782: "תשפב",
1993 | 783: "תשפג",
1994 | 784: "תשפד",
1995 | 785: "תשפה",
1996 | 786: "תשפו",
1997 | 787: "תשפז",
1998 | 788: "תשפח",
1999 | 789: "תשפט",
2000 | 790: "תשצ",
2001 | 791: "תשצא",
2002 | 792: "תשצב",
2003 | 793: "תשצג",
2004 | 794: "תשצד",
2005 | 795: "תשצה",
2006 | 796: "תשצו",
2007 | 797: "תשצז",
2008 | 798: "תשצח",
2009 | 799: "תשצט",
2010 | 800: "תת",
2011 | 801: "תתא",
2012 | 802: "תתב",
2013 | 803: "תתג",
2014 | 804: "תתד",
2015 | 805: "תתה",
2016 | 806: "תתו",
2017 | 807: "תתז",
2018 | 808: "תתח",
2019 | 809: "תתט",
2020 | 810: "תתי",
2021 | 811: "תתיא",
2022 | 812: "תתיב",
2023 | 813: "תתיג",
2024 | 814: "תתיד",
2025 | 815: "תתטו",
2026 | 816: "תתטז",
2027 | 817: "תתיז",
2028 | 818: "תתיח",
2029 | 819: "תתיט",
2030 | 820: "תתכ",
2031 | 821: "תתכא",
2032 | 822: "תתכב",
2033 | 823: "תתכג",
2034 | 824: "תתכד",
2035 | 825: "תתכה",
2036 | 826: "תתכו",
2037 | 827: "תתכז",
2038 | 828: "תתכח",
2039 | 829: "תתכט",
2040 | 830: "תתל",
2041 | 831: "תתלא",
2042 | 832: "תתלב",
2043 | 833: "תתלג",
2044 | 834: "תתלד",
2045 | 835: "תתלה",
2046 | 836: "תתלו",
2047 | 837: "תתלז",
2048 | 838: "תתלח",
2049 | 839: "תתלט",
2050 | 840: "תתמ",
2051 | 841: "תתמא",
2052 | 842: "תתמב",
2053 | 843: "תתמג",
2054 | 844: "תתמד",
2055 | 845: "תתמה",
2056 | 846: "תתמו",
2057 | 847: "תתמז",
2058 | 848: "תתמח",
2059 | 849: "תתמט",
2060 | 850: "תתנ",
2061 | 851: "תתנא",
2062 | 852: "תתנב",
2063 | 853: "תתנג",
2064 | 854: "תתנד",
2065 | 855: "תתנה",
2066 | 856: "תתנו",
2067 | 857: "תתנז",
2068 | 858: "תתנח",
2069 | 859: "תתנט",
2070 | 860: "תתס",
2071 | 861: "תתסא",
2072 | 862: "תתסב",
2073 | 863: "תתסג",
2074 | 864: "תתסד",
2075 | 865: "תתסה",
2076 | 866: "תתסו",
2077 | 867: "תתסז",
2078 | 868: "תתסח",
2079 | 869: "תתסט",
2080 | 870: "תתע",
2081 | 871: "תתעא",
2082 | 872: "תתעב",
2083 | 873: "תתעג",
2084 | 874: "תתעד",
2085 | 875: "תתעה",
2086 | 876: "תתעו",
2087 | 877: "תתעז",
2088 | 878: "תתעח",
2089 | 879: "תתעט",
2090 | 880: "תתפ",
2091 | 881: "תתפא",
2092 | 882: "תתפב",
2093 | 883: "תתפג",
2094 | 884: "תתפד",
2095 | 885: "תתפה",
2096 | 886: "תתפו",
2097 | 887: "תתפז",
2098 | 888: "תתפח",
2099 | 889: "תתפט",
2100 | 890: "תתצ",
2101 | 891: "תתצא",
2102 | 892: "תתצב",
2103 | 893: "תתצג",
2104 | 894: "תתצד",
2105 | 895: "תתצה",
2106 | 896: "תתצו",
2107 | 897: "תתצז",
2108 | 898: "תתצח",
2109 | 899: "תתצט",
2110 | 900: "תתק",
2111 | 901: "תתקא",
2112 | 902: "תתקב",
2113 | 903: "תתקג",
2114 | 904: "תתקד",
2115 | 905: "תתקה",
2116 | 906: "תתקו",
2117 | 907: "תתקז",
2118 | 908: "תתקח",
2119 | 909: "תתקט",
2120 | 910: "תתקי",
2121 | 911: "תתקיא",
2122 | 912: "תתקיב",
2123 | 913: "תתקיג",
2124 | 914: "תתקיד",
2125 | 915: "תתקטו",
2126 | 916: "תתקטז",
2127 | 917: "תתקיז",
2128 | 918: "תתקיח",
2129 | 919: "תתקיט",
2130 | 920: "תתקכ",
2131 | 921: "תתקכא",
2132 | 922: "תתקכב",
2133 | 923: "תתקכג",
2134 | 924: "תתקכד",
2135 | 925: "תתקכה",
2136 | 926: "תתקכו",
2137 | 927: "תתקכז",
2138 | 928: "תתקכח",
2139 | 929: "תתקכט",
2140 | 930: "תתקל",
2141 | 931: "תתקלא",
2142 | 932: "תתקלב",
2143 | 933: "תתקלג",
2144 | 934: "תתקלד",
2145 | 935: "תתקלה",
2146 | 936: "תתקלו",
2147 | 937: "תתקלז",
2148 | 938: "תתקלח",
2149 | 939: "תתקלט",
2150 | 940: "תתקמ",
2151 | 941: "תתקמא",
2152 | 942: "תתקמב",
2153 | 943: "תתקמג",
2154 | 944: "תתקמד",
2155 | 945: "תתקמה",
2156 | 946: "תתקמו",
2157 | 947: "תתקמז",
2158 | 948: "תתקמח",
2159 | 949: "תתקמט",
2160 | 950: "תתקנ",
2161 | 951: "תתקנא",
2162 | 952: "תתקנב",
2163 | 953: "תתקנג",
2164 | 954: "תתקנד",
2165 | 955: "תתקנה",
2166 | 956: "תתקנו",
2167 | 957: "תתקנז",
2168 | 958: "תתקנח",
2169 | 959: "תתקנט",
2170 | 960: "תתקס",
2171 | 961: "תתקסא",
2172 | 962: "תתקסב",
2173 | 963: "תתקסג",
2174 | 964: "תתקסד",
2175 | 965: "תתקסה",
2176 | 966: "תתקסו",
2177 | 967: "תתקסז",
2178 | 968: "תתקסח",
2179 | 969: "תתקסט",
2180 | 970: "תתקע",
2181 | 971: "תתקעא",
2182 | 972: "תתקעב",
2183 | 973: "תתקעג",
2184 | 974: "תתקעד",
2185 | 975: "תתקעה",
2186 | 976: "תתקעו",
2187 | 977: "תתקעז",
2188 | 978: "תתקעח",
2189 | 979: "תתקעט",
2190 | 980: "תתקפ",
2191 | 981: "תתקפא",
2192 | 982: "תתקפב",
2193 | 983: "תתקפג",
2194 | 984: "תתקפד",
2195 | 985: "תתקפה",
2196 | 986: "תתקפו",
2197 | 987: "תתקפז",
2198 | 988: "תתקפח",
2199 | 989: "תתקפט",
2200 | 990: "תתקצ",
2201 | 991: "תתקצא",
2202 | 992: "תתקצב",
2203 | 993: "תתקצג",
2204 | 994: "תתקצד",
2205 | 995: "תתקצה",
2206 | 996: "תתקצו",
2207 | 997: "תתקצז",
2208 | 998: "תתקצח",
2209 | 999: "תתקצט",
2210 | 1000: "תתר",
2211 | 1001: "תתרא",
2212 | 1002: "תתרב",
2213 | 1003: "תתרג",
2214 | 1004: "תתרד",
2215 | 1005: "תתרה",
2216 | 1006: "תתרו",
2217 | 1007: "תתרז",
2218 | 1008: "תתרח",
2219 | 1009: "תתרט",
2220 | 1010: "תתרי",
2221 | 1011: "תתריא",
2222 | 1012: "תתריב",
2223 | 1013: "תתריג",
2224 | 1014: "תתריד",
2225 | 1015: "תתרטו",
2226 | 1016: "תתרטז",
2227 | 1017: "תתריז",
2228 | 1018: "תתריח",
2229 | 1019: "תתריט",
2230 | 1020: "תתרכ",
2231 | 1021: "תתרכא",
2232 | 1022: "תתרכב",
2233 | 1023: "תתרכג",
2234 | 1024: "תתרכד",
2235 | 1025: "תתרכה",
2236 | 1026: "תתרכו",
2237 | 1027: "תתרכז",
2238 | 1028: "תתרכח",
2239 | 1029: "תתרכט",
2240 | 1030: "תתרל",
2241 | 1031: "תתרלא",
2242 | 1032: "תתרלב",
2243 | 1033: "תתרלג",
2244 | 1034: "תתרלד",
2245 | 1035: "תתרלה",
2246 | 1036: "תתרלו",
2247 | 1037: "תתרלז",
2248 | 1038: "תתרלח",
2249 | 1039: "תתרלט",
2250 | 1040: "תתרמ",
2251 | 1041: "תתרמא",
2252 | 1042: "תתרמב",
2253 | 1043: "תתרמג",
2254 | 1044: "תתרמד",
2255 | 1045: "תתרמה",
2256 | 1046: "תתרמו",
2257 | 1047: "תתרמז",
2258 | 1048: "תתרמח",
2259 | 1049: "תתרמט",
2260 | 1050: "תתרנ",
2261 | 1051: "תתרנא",
2262 | 1052: "תתרנב",
2263 | 1053: "תתרנג",
2264 | 1054: "תתרנד",
2265 | 1055: "תתרנה",
2266 | 1056: "תתרנו",
2267 | 1057: "תתרנז",
2268 | 1058: "תתרנח",
2269 | 1059: "תתרנט",
2270 | 1060: "תתרס",
2271 | 1061: "תתרסא",
2272 | 1062: "תתרסב",
2273 | 1063: "תתרסג",
2274 | 1064: "תתרסד",
2275 | 1065: "תתרסה",
2276 | 1066: "תתרסו",
2277 | 1067: "תתרסז",
2278 | 1068: "תתרסח",
2279 | 1069: "תתרסט",
2280 | 1070: "תתרע",
2281 | 1071: "תתרעא",
2282 | 1072: "תתרעב",
2283 | 1073: "תתרעג",
2284 | 1074: "תתרעד",
2285 | 1075: "תתרעה",
2286 | 1076: "תתרעו",
2287 | 1077: "תתרעז",
2288 | 1078: "תתרעח",
2289 | 1079: "תתרעט",
2290 | 1080: "תתרפ",
2291 | 1081: "תתרפא",
2292 | 1082: "תתרפב",
2293 | 1083: "תתרפג",
2294 | 1084: "תתרפד",
2295 | 1085: "תתרפה",
2296 | 1086: "תתרפו",
2297 | 1087: "תתרפז",
2298 | 1088: "תתרפח",
2299 | 1089: "תתרפט",
2300 | 1090: "תתרצ",
2301 | 1091: "תתרצא",
2302 | 1092: "תתרצב",
2303 | 1093: "תתרצג",
2304 | 1094: "תתרצד",
2305 | 1095: "תתרצה",
2306 | 1096: "תתרצו",
2307 | 1097: "תתרצז",
2308 | 1098: "תתרצח",
2309 | 1099: "תתרצט",
2310 | 1100: "תתש",
2311 | 1101: "תתשא",
2312 | 1102: "תתשב",
2313 | 1103: "תתשג",
2314 | 1104: "תתשד",
2315 | 1105: "תתשה",
2316 | 1106: "תתשו",
2317 | 1107: "תתשז",
2318 | 1108: "תתשח",
2319 | 1109: "תתשט",
2320 | 1110: "תתשי",
2321 | 1111: "תתשיא",
2322 | 1112: "תתשיב",
2323 | 1113: "תתשיג",
2324 | 1114: "תתשיד",
2325 | 1115: "תתשטו",
2326 | 1116: "תתשטז",
2327 | 1117: "תתשיז",
2328 | 1118: "תתשיח",
2329 | 1119: "תתשיט",
2330 | 1120: "תתשכ",
2331 | 1121: "תתשכא",
2332 | 1122: "תתשכב",
2333 | 1123: "תתשכג",
2334 | 1124: "תתשכד",
2335 | 1125: "תתשכה",
2336 | 1126: "תתשכו",
2337 | 1127: "תתשכז",
2338 | 1128: "תתשכח",
2339 | 1129: "תתשכט",
2340 | 1130: "תתשל",
2341 | 1131: "תתשלא",
2342 | 1132: "תתשלב",
2343 | 1133: "תתשלג",
2344 | 1134: "תתשלד",
2345 | 1135: "תתשלה",
2346 | 1136: "תתשלו",
2347 | 1137: "תתשלז",
2348 | 1138: "תתשלח",
2349 | 1139: "תתשלט",
2350 | 1140: "תתשמ",
2351 | 1141: "תתשמא",
2352 | 1142: "תתשמב",
2353 | 1143: "תתשמג",
2354 | 1144: "תתשמד",
2355 | 1145: "תתשמה",
2356 | 1146: "תתשמו",
2357 | 1147: "תתשמז",
2358 | 1148: "תתשמח",
2359 | 1149: "תתשמט",
2360 | 1150: "תתשנ",
2361 | 1151: "תתשנא",
2362 | 1152: "תתשנב",
2363 | 1153: "תתשנג",
2364 | 1154: "תתשנד",
2365 | 1155: "תתשנה",
2366 | 1156: "תתשנו",
2367 | 1157: "תתשנז",
2368 | 1158: "תתשנח",
2369 | 1159: "תתשנט",
2370 | 1160: "תתשס",
2371 | 1161: "תתשסא",
2372 | 1162: "תתשסב",
2373 | 1163: "תתשסג",
2374 | 1164: "תתשסד",
2375 | 1165: "תתשסה",
2376 | 1166: "תתשסו",
2377 | 1167: "תתשסז",
2378 | 1168: "תתשסח",
2379 | 1169: "תתשסט",
2380 | 1170: "תתשע",
2381 | 1171: "תתשעא",
2382 | 1172: "תתשעב",
2383 | 1173: "תתשעג",
2384 | 1174: "תתשעד",
2385 | 1175: "תתשעה",
2386 | 1176: "תתשעו",
2387 | 1177: "תתשעז",
2388 | 1178: "תתשעח",
2389 | 1179: "תתשעט",
2390 | 1180: "תתשפ",
2391 | 1181: "תתשפא",
2392 | 1182: "תתשפב",
2393 | 1183: "תתשפג",
2394 | 1184: "תתשפד",
2395 | 1185: "תתשפה",
2396 | 1186: "תתשפו",
2397 | 1187: "תתשפז",
2398 | 1188: "תתשפח",
2399 | 1189: "תתשפט",
2400 | 1190: "תתשצ",
2401 | 1191: "תתשצא",
2402 | 1192: "תתשצב",
2403 | 1193: "תתשצג",
2404 | 1194: "תתשצד",
2405 | 1195: "תתשצה",
2406 | 1196: "תתשצו",
2407 | 1197: "תתשצז",
2408 | 1198: "תתשצח",
2409 | 1199: "תתשצט",
2410 | }
2411 | NO_SUBSTITUTION = {
2412 | 15: "י״ה",
2413 | 16: "י״ו",
2414 | 115: "קי״ה",
2415 | 116: "קי״ו",
2416 | 215: "רי״ה",
2417 | 216: "רי״ו",
2418 | 315: "שי״ה",
2419 | 316: "שי״ו",
2420 | 415: "תי״ה",
2421 | 416: "תי״ו",
2422 | 515: "תקי״ה",
2423 | 516: "תקי״ו",
2424 | 615: "תרי״ה",
2425 | 616: "תרי״ו",
2426 | 715: "תשי״ה",
2427 | 716: "תשי״ו",
2428 | 815: "תתי״ה",
2429 | 816: "תתי״ו",
2430 | 915: "תתקי״ה",
2431 | 916: "תתקי״ו",
2432 | 1015: "תתרי״ה",
2433 | 1016: "תתרי״ו",
2434 | 1115: "תתשי״ה",
2435 | 1116: "תתשי״ו",
2436 | }
2437 | POLITE_SUBSTITUTION = {
2438 | **NO_PUNCTUATION,
2439 | 270: "ער",
2440 | 272: "ערב",
2441 | 275: "ערה",
2442 | 298: "רחצ",
2443 | 304: "דש",
2444 | 344: "שדמ",
2445 | 670: "תער",
2446 | 672: "תערב",
2447 | 698: "תרחצ",
2448 | 744: "תשדמ",
2449 | 1070: "תתער",
2450 | 1072: "תתערב",
2451 | 1098: "תתרחצ",
2452 | 1144: "תתשדמ",
2453 | }
2454 |
2455 |
2456 | def test_no_0_input():
2457 | with pytest.raises(ValueError):
2458 | Hebrew.from_number(0)
2459 | with pytest.raises(ValueError):
2460 | number_to_hebrew_string(0)
2461 |
2462 |
2463 | def test_no_negative_input():
2464 | with pytest.raises(ValueError):
2465 | Hebrew.from_number(-1)
2466 | with pytest.raises(ValueError):
2467 | number_to_hebrew_string(-1)
2468 |
2469 |
2470 | @pytest.mark.parametrize("number, expected_output", NO_SUBSTITUTION.items())
2471 | def test_no_substitutions(number, expected_output):
2472 | assert Hebrew.from_number(
2473 | number, True, True, substitution_functions=None
2474 | ) == Hebrew(expected_output)
2475 |
2476 |
2477 | @pytest.mark.parametrize("number, expected_output", POLITE_SUBSTITUTION.items())
2478 | def test_polite_substitutions(number, expected_output):
2479 | assert Hebrew.from_number(
2480 | number, False, substitution_functions=Substitutions.ALL
2481 | ) == Hebrew(expected_output)
2482 | assert (
2483 | number_to_hebrew_string(number, False, substitution_functions=Substitutions.ALL)
2484 | == expected_output
2485 | )
2486 |
2487 |
2488 | @pytest.mark.parametrize("number, expected_output", WITH_GERESH.items())
2489 | def test_with_geresh(number, expected_output):
2490 | assert Hebrew.from_number(number, True, True) == Hebrew(expected_output)
2491 | assert number_to_hebrew_string(number, True, True) == expected_output
2492 |
2493 |
2494 | @pytest.mark.parametrize(
2495 | "number, expected_output",
2496 | [(i[0], i[1].replace("׳", "'").replace("״", '"')) for i in WITH_GERESH.items()],
2497 | )
2498 | def test_with_english_quote(number, expected_output):
2499 | assert Hebrew.from_number(number, True, False) == Hebrew(expected_output)
2500 | assert number_to_hebrew_string(number, True, False) == expected_output
2501 |
2502 |
2503 | @pytest.mark.parametrize(
2504 | "number, expected_output",
2505 | [(i[0], i[1].replace("׳", "").replace("״", "")) for i in WITH_GERESH.items()],
2506 | )
2507 | def test_with_no_punctuation(number, expected_output):
2508 | assert Hebrew.from_number(number, False) == Hebrew(expected_output)
2509 | assert number_to_hebrew_string(number, False) == expected_output
2510 |
--------------------------------------------------------------------------------