ugarit-texts 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ugarit-texts contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,95 @@
1
+ Metadata-Version: 2.4
2
+ Name: ugarit-texts
3
+ Version: 0.1.0
4
+ Summary: Browse a local Markdown extraction of the Ugaritic Baal Cycle
5
+ License: MIT License
6
+
7
+ Copyright (c) 2026 ugarit-texts contributors
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Keywords: ugaritic,baal cycle,ancient texts
28
+ Classifier: Programming Language :: Python :: 3
29
+ Classifier: Topic :: Text Processing
30
+ Classifier: Topic :: Religion
31
+ Requires-Python: >=3.9
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+ Dynamic: license-file
35
+
36
+ # ugarit-texts
37
+
38
+ Browse a locally supplied Markdown extraction of *The Ugaritic Baal Cycle*, Volumes I and II, using Python. Look up tablet columns, retrieve PDF pages, and search page text. Python 3.9 or later is required; there are no runtime dependencies.
39
+
40
+ ## Install
41
+
42
+ ```sh
43
+ python -m pip install ugarit-texts
44
+ ```
45
+
46
+ The package contains code only. It does **not** include the books or a text corpus. You must supply the matching Markdown extraction yourself. By default, `Corpus()` looks for `Ugaritic Baal Cycle Volumes I and II.md` in your home directory's `Documents` folder. Alternatively, pass a path:
47
+
48
+ ```python
49
+ from ugarit import Corpus
50
+
51
+ corpus = Corpus(r"C:\path\to\Ugaritic Baal Cycle Volumes I and II.md")
52
+ ```
53
+
54
+ The input must have the volume, section, PDF-page and fenced text headings used by that extraction; this is not a general parser for arbitrary Ugaritic editions. A missing file raises `FileNotFoundError`.
55
+
56
+ ## Browse tablet columns
57
+
58
+ ```python
59
+ from ugarit import Corpus
60
+
61
+ corpus = Corpus()
62
+ print(corpus.tablets()) # ('1.1', '1.2', '1.3', '1.4')
63
+ section = corpus.get('KTU 1.3', 'IV') # CAT prefix also accepted
64
+ print(section.tablet, section.column, section.volume)
65
+ print(section.text)
66
+
67
+ for section in corpus.sections('1.2'):
68
+ print(section.column, section.volume)
69
+ ```
70
+
71
+ `sections()` returns all indexed sections in source order; pass a tablet identifier to filter them. `get(tablet, column)` returns a `Section` with `tablet`, `column`, `volume`, and `text` attributes, or raises `KeyError`. Roman column numbers are case-insensitive.
72
+
73
+ Sections are taken from the extraction's headings. They include commentary, notes and page markers, and may include material outside the named column. They are not clean verse-level transcriptions or isolated translations.
74
+
75
+ ## Retrieve and search pages
76
+
77
+ ```python
78
+ page = corpus.page(1, 2) # volume 1, PDF page 2
79
+ print(page.text)
80
+
81
+ for page in corpus.search('Baal', volume=2):
82
+ print(page.volume, page.number)
83
+
84
+ all_pages = corpus.pages() # or corpus.pages(volume=1)
85
+ ```
86
+
87
+ Page numbers refer to PDF pages, not printed book pages. Search performs a case-insensitive literal substring match and returns matching `Page` objects with `volume`, `number`, and `text` attributes. An empty query or invalid volume raises `ValueError`; a missing page raises `KeyError`.
88
+
89
+ ## Scope and source
90
+
91
+ The source describes Mark S. Smith, *The Ugaritic Baal Cycle*, Volume I (Brill, 1994), covering KTU 1.1–1.2; and Smith and Wayne T. Pitard, Volume II (Brill, 2009), covering KTU/CAT 1.3–1.4. KTU 1.5–1.6 and the wider Ugaritic corpus are not included. The Markdown is a mechanical PDF extraction with OCR errors, disrupted columns, missing images, and section headings placed at page boundaries. Consult the original editions when accuracy matters.
92
+
93
+ ## License
94
+
95
+ The library code is available under the [MIT License](LICENSE). The ancient Ugaritic works are distinct from modern editions, translations and commentaries. The supplied Brill edition is not licensed here and is not distributed with this package; no CC BY license is claimed for it. Obtain and use your source copy under its applicable rights.
@@ -0,0 +1,60 @@
1
+ # ugarit-texts
2
+
3
+ Browse a locally supplied Markdown extraction of *The Ugaritic Baal Cycle*, Volumes I and II, using Python. Look up tablet columns, retrieve PDF pages, and search page text. Python 3.9 or later is required; there are no runtime dependencies.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ python -m pip install ugarit-texts
9
+ ```
10
+
11
+ The package contains code only. It does **not** include the books or a text corpus. You must supply the matching Markdown extraction yourself. By default, `Corpus()` looks for `Ugaritic Baal Cycle Volumes I and II.md` in your home directory's `Documents` folder. Alternatively, pass a path:
12
+
13
+ ```python
14
+ from ugarit import Corpus
15
+
16
+ corpus = Corpus(r"C:\path\to\Ugaritic Baal Cycle Volumes I and II.md")
17
+ ```
18
+
19
+ The input must have the volume, section, PDF-page and fenced text headings used by that extraction; this is not a general parser for arbitrary Ugaritic editions. A missing file raises `FileNotFoundError`.
20
+
21
+ ## Browse tablet columns
22
+
23
+ ```python
24
+ from ugarit import Corpus
25
+
26
+ corpus = Corpus()
27
+ print(corpus.tablets()) # ('1.1', '1.2', '1.3', '1.4')
28
+ section = corpus.get('KTU 1.3', 'IV') # CAT prefix also accepted
29
+ print(section.tablet, section.column, section.volume)
30
+ print(section.text)
31
+
32
+ for section in corpus.sections('1.2'):
33
+ print(section.column, section.volume)
34
+ ```
35
+
36
+ `sections()` returns all indexed sections in source order; pass a tablet identifier to filter them. `get(tablet, column)` returns a `Section` with `tablet`, `column`, `volume`, and `text` attributes, or raises `KeyError`. Roman column numbers are case-insensitive.
37
+
38
+ Sections are taken from the extraction's headings. They include commentary, notes and page markers, and may include material outside the named column. They are not clean verse-level transcriptions or isolated translations.
39
+
40
+ ## Retrieve and search pages
41
+
42
+ ```python
43
+ page = corpus.page(1, 2) # volume 1, PDF page 2
44
+ print(page.text)
45
+
46
+ for page in corpus.search('Baal', volume=2):
47
+ print(page.volume, page.number)
48
+
49
+ all_pages = corpus.pages() # or corpus.pages(volume=1)
50
+ ```
51
+
52
+ Page numbers refer to PDF pages, not printed book pages. Search performs a case-insensitive literal substring match and returns matching `Page` objects with `volume`, `number`, and `text` attributes. An empty query or invalid volume raises `ValueError`; a missing page raises `KeyError`.
53
+
54
+ ## Scope and source
55
+
56
+ The source describes Mark S. Smith, *The Ugaritic Baal Cycle*, Volume I (Brill, 1994), covering KTU 1.1–1.2; and Smith and Wayne T. Pitard, Volume II (Brill, 2009), covering KTU/CAT 1.3–1.4. KTU 1.5–1.6 and the wider Ugaritic corpus are not included. The Markdown is a mechanical PDF extraction with OCR errors, disrupted columns, missing images, and section headings placed at page boundaries. Consult the original editions when accuracy matters.
57
+
58
+ ## License
59
+
60
+ The library code is available under the [MIT License](LICENSE). The ancient Ugaritic works are distinct from modern editions, translations and commentaries. The supplied Brill edition is not licensed here and is not distributed with this package; no CC BY license is claimed for it. Obtain and use your source copy under its applicable rights.
@@ -0,0 +1,16 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ugarit-texts"
7
+ version = "0.1.0"
8
+ description = "Browse a local Markdown extraction of the Ugaritic Baal Cycle"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = {file = "LICENSE"}
12
+ keywords = ["ugaritic", "baal cycle", "ancient texts"]
13
+ classifiers = ["Programming Language :: Python :: 3", "Topic :: Text Processing", "Topic :: Religion"]
14
+
15
+ [tool.setuptools]
16
+ packages = ["ugarit"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,77 @@
1
+ """Browse the locally supplied Ugaritic Baal Cycle extraction."""
2
+ from dataclasses import dataclass
3
+ from pathlib import Path
4
+ import re
5
+
6
+ DEFAULT_SOURCE = Path.home() / "Documents" / "Ugaritic Baal Cycle Volumes I and II.md"
7
+ _HEADING = re.compile(r"^#{1,3} .+$", re.MULTILINE)
8
+ _COLUMN = re.compile(r"^## (?:(?:CAT|KTU) )?(1\.[1-4]) (I{1,3}|IV|V|VI{0,3})(?: and CAT 1\.8)?$", re.MULTILINE)
9
+ _PAGE = re.compile(r"^### PDF page (\d+)\s*\n\s*```text\s*\n(.*?)\n```", re.MULTILINE | re.DOTALL)
10
+
11
+ @dataclass(frozen=True)
12
+ class Page:
13
+ volume: int
14
+ number: int
15
+ text: str
16
+
17
+ @dataclass(frozen=True)
18
+ class Section:
19
+ tablet: str
20
+ column: str
21
+ volume: int
22
+ text: str
23
+
24
+ class Corpus:
25
+ def __init__(self, source=DEFAULT_SOURCE):
26
+ self.source = Path(source)
27
+ self._text = self.source.read_text(encoding="utf-8-sig")
28
+ marker = self._text.find("\n# Volume II\n")
29
+ if marker < 0:
30
+ raise ValueError("Source is missing the Volume II heading")
31
+ self._volumes = {1: self._text[:marker], 2: self._text[marker:]}
32
+
33
+ def tablets(self):
34
+ """Return tablet identifiers represented by column sections."""
35
+ return tuple(dict.fromkeys(s.tablet for s in self.sections()))
36
+
37
+ def sections(self, tablet=None):
38
+ """Return sections in source order; each includes commentary and page markers."""
39
+ result = []
40
+ for volume, text in self._volumes.items():
41
+ matches = list(_COLUMN.finditer(text))
42
+ for match in matches:
43
+ end = _HEADING.search(text, match.end())
44
+ # Page headings occur within sections; stop only at the next level-2 heading.
45
+ next_section = re.search(r"^## ", text[match.end():], re.MULTILINE)
46
+ stop = match.end() + next_section.start() if next_section else len(text)
47
+ item = Section(match.group(1), match.group(2), volume, text[match.end():stop].strip())
48
+ if tablet is None or item.tablet == str(tablet).removeprefix("KTU ").removeprefix("CAT "):
49
+ result.append(item)
50
+ return tuple(result)
51
+
52
+ def get(self, tablet, column):
53
+ """Get a tablet column, e.g. get('1.3', 'IV'); raises KeyError if absent."""
54
+ for section in self.sections(tablet):
55
+ if section.column == str(column).upper():
56
+ return section
57
+ raise KeyError(f"No section for {tablet} column {column}")
58
+
59
+ def pages(self, volume=None):
60
+ """Return extracted PDF pages, optionally restricted to volume 1 or 2."""
61
+ if volume is not None and volume not in self._volumes:
62
+ raise ValueError("volume must be 1 or 2")
63
+ volumes = self._volumes.items() if volume is None else [(volume, self._volumes[volume])]
64
+ return tuple(Page(v, int(m.group(1)), m.group(2)) for v, text in volumes for m in _PAGE.finditer(text))
65
+
66
+ def page(self, volume, number):
67
+ for page in self.pages(volume):
68
+ if page.number == number:
69
+ return page
70
+ raise KeyError(f"No PDF page {number} in volume {volume}")
71
+
72
+ def search(self, query, volume=None):
73
+ """Return pages containing a case-insensitive literal query."""
74
+ if not query:
75
+ raise ValueError("query must not be empty")
76
+ needle = query.casefold()
77
+ return tuple(page for page in self.pages(volume) if needle in page.text.casefold())
@@ -0,0 +1,95 @@
1
+ Metadata-Version: 2.4
2
+ Name: ugarit-texts
3
+ Version: 0.1.0
4
+ Summary: Browse a local Markdown extraction of the Ugaritic Baal Cycle
5
+ License: MIT License
6
+
7
+ Copyright (c) 2026 ugarit-texts contributors
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Keywords: ugaritic,baal cycle,ancient texts
28
+ Classifier: Programming Language :: Python :: 3
29
+ Classifier: Topic :: Text Processing
30
+ Classifier: Topic :: Religion
31
+ Requires-Python: >=3.9
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+ Dynamic: license-file
35
+
36
+ # ugarit-texts
37
+
38
+ Browse a locally supplied Markdown extraction of *The Ugaritic Baal Cycle*, Volumes I and II, using Python. Look up tablet columns, retrieve PDF pages, and search page text. Python 3.9 or later is required; there are no runtime dependencies.
39
+
40
+ ## Install
41
+
42
+ ```sh
43
+ python -m pip install ugarit-texts
44
+ ```
45
+
46
+ The package contains code only. It does **not** include the books or a text corpus. You must supply the matching Markdown extraction yourself. By default, `Corpus()` looks for `Ugaritic Baal Cycle Volumes I and II.md` in your home directory's `Documents` folder. Alternatively, pass a path:
47
+
48
+ ```python
49
+ from ugarit import Corpus
50
+
51
+ corpus = Corpus(r"C:\path\to\Ugaritic Baal Cycle Volumes I and II.md")
52
+ ```
53
+
54
+ The input must have the volume, section, PDF-page and fenced text headings used by that extraction; this is not a general parser for arbitrary Ugaritic editions. A missing file raises `FileNotFoundError`.
55
+
56
+ ## Browse tablet columns
57
+
58
+ ```python
59
+ from ugarit import Corpus
60
+
61
+ corpus = Corpus()
62
+ print(corpus.tablets()) # ('1.1', '1.2', '1.3', '1.4')
63
+ section = corpus.get('KTU 1.3', 'IV') # CAT prefix also accepted
64
+ print(section.tablet, section.column, section.volume)
65
+ print(section.text)
66
+
67
+ for section in corpus.sections('1.2'):
68
+ print(section.column, section.volume)
69
+ ```
70
+
71
+ `sections()` returns all indexed sections in source order; pass a tablet identifier to filter them. `get(tablet, column)` returns a `Section` with `tablet`, `column`, `volume`, and `text` attributes, or raises `KeyError`. Roman column numbers are case-insensitive.
72
+
73
+ Sections are taken from the extraction's headings. They include commentary, notes and page markers, and may include material outside the named column. They are not clean verse-level transcriptions or isolated translations.
74
+
75
+ ## Retrieve and search pages
76
+
77
+ ```python
78
+ page = corpus.page(1, 2) # volume 1, PDF page 2
79
+ print(page.text)
80
+
81
+ for page in corpus.search('Baal', volume=2):
82
+ print(page.volume, page.number)
83
+
84
+ all_pages = corpus.pages() # or corpus.pages(volume=1)
85
+ ```
86
+
87
+ Page numbers refer to PDF pages, not printed book pages. Search performs a case-insensitive literal substring match and returns matching `Page` objects with `volume`, `number`, and `text` attributes. An empty query or invalid volume raises `ValueError`; a missing page raises `KeyError`.
88
+
89
+ ## Scope and source
90
+
91
+ The source describes Mark S. Smith, *The Ugaritic Baal Cycle*, Volume I (Brill, 1994), covering KTU 1.1–1.2; and Smith and Wayne T. Pitard, Volume II (Brill, 2009), covering KTU/CAT 1.3–1.4. KTU 1.5–1.6 and the wider Ugaritic corpus are not included. The Markdown is a mechanical PDF extraction with OCR errors, disrupted columns, missing images, and section headings placed at page boundaries. Consult the original editions when accuracy matters.
92
+
93
+ ## License
94
+
95
+ The library code is available under the [MIT License](LICENSE). The ancient Ugaritic works are distinct from modern editions, translations and commentaries. The supplied Brill edition is not licensed here and is not distributed with this package; no CC BY license is claimed for it. Obtain and use your source copy under its applicable rights.
@@ -0,0 +1,8 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ ugarit/__init__.py
5
+ ugarit_texts.egg-info/PKG-INFO
6
+ ugarit_texts.egg-info/SOURCES.txt
7
+ ugarit_texts.egg-info/dependency_links.txt
8
+ ugarit_texts.egg-info/top_level.txt