amharic-segmenter 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,15 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ build/
5
+ dist/
6
+ .pytest_cache/
7
+ .mypy_cache/
8
+ .ruff_cache/
9
+ .coverage
10
+ htmlcov/
11
+ .venv/
12
+ venv/
13
+ .idea/
14
+ .vscode/
15
+ .DS_Store
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
5
+ project uses [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [0.1.0] - Unreleased
8
+
9
+ ### Added
10
+ - NLTK-style API: `sent_tokenize`, `word_tokenize`, `stem`, `stem_words`, `AmharicStemmer`,
11
+ and `amharic-segmenter --stem`. Stemming also works on words outside the lexicon.
12
+ - Function words (`ነው`, `ናቸው`, `ውስጥ` …) are never split.
13
+ - Word tokenizer for Ethiopic script: letters, Ethiopic punctuation (`፡ ። ፣ ፤ ፧` …), Ethiopic
14
+ and Arabic numerals, Latin text. No character is ever dropped.
15
+ - Sentence splitter for `።`, `፧`, `፨`, `!`, `?` and the old-style `፡፡`.
16
+ - Optional morpheme segmentation for nouns and noun phrases: prepositions (`በ ከ ለ የ ስለ`),
17
+ plural, definite article, possessive suffixes, object marker `ን`, conjunctions `ና`/`ም`.
18
+ - Three splitting strategies: `lexicon` (default), `rules`, `none`.
19
+ - Optional homophone normalisation (`ሐ→ሀ`, `ሠ→ሰ`, `ዐ→አ`, `ፀ→ጸ`).
20
+ - Token offsets (`tokenize_spans`), command line interface, typed package (`py.typed`).
21
+ - Pronoun contractions (`በኔ`, `ከኛ`, `እንዳንተ`), fused feminine `ዋ` (`ሐኪሟ`), irregular and
22
+ reduplicated-adjective plurals, and `lemma()`.
23
+ - Tests from chapter 4 examples (`ጓዳውንና`, `ባለቤቶቹን`, `ሴትዮዋ`).
24
+ - `docs/BOOK_COVERAGE.md`: section-by-section record of what the source book covers.
25
+ - Seed lexicon built from the examples of *አማርኛ ሠዋሰው* (1963 E.C.).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ali Kibret Muhamed
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,340 @@
1
+ Metadata-Version: 2.5
2
+ Name: amharic-segmenter
3
+ Version: 0.1.0
4
+ Summary: Sentence/word tokenization, morpheme splitting and stemming for Amharic (አማርኛ), NLTK-style and dependency-free.
5
+ Project-URL: Homepage, https://github.com/Alki45/amharic-segmenter
6
+ Project-URL: Documentation, https://github.com/Alki45/amharic-segmenter#readme
7
+ Project-URL: Issues, https://github.com/Alki45/amharic-segmenter/issues
8
+ Project-URL: Changelog, https://github.com/Alki45/amharic-segmenter/blob/main/CHANGELOG.md
9
+ Author-email: Ali Kibret Muhamed <alikibretmuhamed@gmail.com>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: amharic,ethiopic,ge'ez,low-resource,morphology,nlp,stemmer,stemming,tokenizer,አማርኛ
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Text Processing :: Linguistic
25
+ Classifier: Typing :: Typed
26
+ Requires-Python: >=3.9
27
+ Provides-Extra: dev
28
+ Requires-Dist: build; extra == 'dev'
29
+ Requires-Dist: mypy; extra == 'dev'
30
+ Requires-Dist: pytest-cov; extra == 'dev'
31
+ Requires-Dist: pytest>=7; extra == 'dev'
32
+ Requires-Dist: ruff; extra == 'dev'
33
+ Requires-Dist: twine; extra == 'dev'
34
+ Description-Content-Type: text/markdown
35
+
36
+ <div align="center">
37
+
38
+ # amharic-segmenter
39
+
40
+ **Sentence and word tokenization, morpheme splitting and stemming for Amharic (አማርኛ)**
41
+ as easy as English NLP, built on real grammar rules, with zero dependencies.
42
+
43
+ [![PyPI](https://img.shields.io/pypi/v/amharic-segmenter.svg)](https://pypi.org/project/amharic-segmenter/)
44
+ [![Python](https://img.shields.io/pypi/pyversions/amharic-segmenter.svg)](https://pypi.org/project/amharic-segmenter/)
45
+ [![CI](https://github.com/Alki45/amharic-segmenter/actions/workflows/ci.yml/badge.svg)](https://github.com/Alki45/amharic-segmenter/actions/workflows/ci.yml)
46
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
47
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-261230.svg)](https://github.com/astral-sh/ruff)
48
+
49
+ [Install](#installation) · [Quickstart](#quickstart) · [Features](#features) · [API](#api-reference) · [CLI](#command-line) · [How it works](#how-it-works) · [Contributing](#contributing)
50
+
51
+ </div>
52
+
53
+ > **በአማርኛ:** አማርኛ ጽሑፍን ወደ ዓረፍተ ነገሮችና ቃላት የሚከፋፍል፣ እንዲሁም ቃላትን ወደ ሞርፊሞች
54
+ > (`በ`፣ `ከ`፣ `ለ`፣ `ን`፣ `ና`፣ `ዎች`…) የሚሰብር ቀላል የፓይቶን ጥቅል። ለማንኛውም የአማርኛ ቋንቋ ፕሮጀክት ነጻ ነው።
55
+
56
+ ---
57
+
58
+ ## Why this exists
59
+
60
+ General-purpose tokenizers split on whitespace or learn subwords from data. For Amharic that
61
+ leaves two problems:
62
+
63
+ 1. **Ethiopic punctuation is not ASCII.** `።` (full stop), `፣` (comma), `፧` (question mark) and
64
+ the old word separator `፡` are missed or glued to words by generic tools.
65
+ 2. **Amharic is morphologically rich.** Prepositions, plural, possessives, the object marker
66
+ `ን` and conjunctions are written *attached* to the word, so `ለተማሪዎቻችን` ("for our
67
+ students") is one whitespace token but five units of meaning.
68
+
69
+ `amharic-segmenter` handles both with transparent, documented rules taken from an Amharic
70
+ grammar book, so results are explainable and easy to improve.
71
+
72
+ ## Features
73
+
74
+ - **NLTK-style API**: `sent_tokenize`, `word_tokenize`, `stem`, `AmharicStemmer`. Works right
75
+ after `pip install`: no model downloads, no setup
76
+ - **Stemming** that strips prefixes and suffixes, also for words it has never seen
77
+ - **Sentence splitting** on `።`, `፧`, `፨`, `!`, `?` and the old-style `፡፡`
78
+ - **Word tokenization** that understands Ethiopic letters, punctuation and numerals
79
+ (`፩፻`), plus Latin text and decimals, and **never drops a character**
80
+ - **Morpheme segmentation** of nouns and noun phrases: prepositions `በ ከ ለ የ ስለ`, plural
81
+ (`ች`, `ዎች`), definite article, possessive suffixes, object marker `ን`, conjunctions `ና`/`ም`
82
+ - **Precision-first design:** words are only split when the stem is known, so names like
83
+ `ከበደ` and words like `ወንድም` stay intact. An opt-in `rules` mode trades precision for recall
84
+ - Handles **pronoun contractions** (`በኔ → በ + እኔ`), **fused feminine forms** (`ሐኪሟ → ሐኪም + ዋ`)
85
+ and **irregular plurals** (`መጻሕፍትን`, `ቃላቶች`), with `lemma()` to get the dictionary form
86
+ - **Token offsets** for aligning tokens with the original text
87
+ - **Optional normalization** of homophone letters (`ሐ→ሀ`, `ሠ→ሰ`, `ዐ→አ`, `ፀ→ጸ`)
88
+ - **Extensible lexicon**: bring your own words, no retraining needed
89
+ - **Command line tool**, fully typed (`py.typed`), pure Python, **no dependencies**,
90
+ Python 3.9+
91
+
92
+ ## Installation
93
+
94
+ ```bash
95
+ pip install amharic-segmenter
96
+ ```
97
+
98
+ ## Quickstart
99
+
100
+ If you have used NLTK on English text, you already know how to use it. Install, import, call:
101
+
102
+ ```python
103
+ from amharic_segmenter import word_tokenize, sent_tokenize, stem
104
+
105
+ text = "ተማሪዎቹ መጻሕፍትን አነበቡ። ከበደና አበበ ለተማሪዎቻቸው ሰጡ።"
106
+
107
+ sent_tokenize(text)
108
+ # ['ተማሪዎቹ መጻሕፍትን አነበቡ።', 'ከበደና አበበ ለተማሪዎቻቸው ሰጡ።']
109
+
110
+ word_tokenize(text)
111
+ # ['ተማሪዎቹ', 'መጻሕፍትን', 'አነበቡ', '።', 'ከበደና', 'አበበ', 'ለተማሪዎቻቸው', 'ሰጡ', '።']
112
+
113
+ [stem(w) for w in word_tokenize(text)]
114
+ # ['ተማሪ', 'መጻሕፍት', 'አነበቡ', '።', 'ከበደ', 'አበበ', 'ተማሪ', 'ሰጡ', '።']
115
+ ```
116
+
117
+ Or with a stemmer object, the way you would use `PorterStemmer`:
118
+
119
+ ```python
120
+ from amharic_segmenter import AmharicStemmer
121
+
122
+ stemmer = AmharicStemmer()
123
+ stemmer.stem("ተማሪዎችን") # 'ተማሪ'
124
+ stemmer.stem_words(["ተማሪዎች", "ላሞች"]) # ['ተማሪ', 'ላም']
125
+ ```
126
+
127
+ | English (NLTK) | Amharic (this package) |
128
+ |----------------|------------------------|
129
+ | `nltk.sent_tokenize(text)` | `sent_tokenize(text)` |
130
+ | `nltk.word_tokenize(text)` | `word_tokenize(text)` |
131
+ | `PorterStemmer().stem(word)` | `AmharicStemmer().stem(word)` or `stem(word)` |
132
+ | `nltk.download("punkt")` | **nothing to download**: rules and data ship inside the package |
133
+
134
+ ### More examples
135
+
136
+ ```python
137
+ from amharic_segmenter import tokenize, sentence_tokenize
138
+
139
+ text = "ተማሪዎቹ በከተማ ውስጥ ይኖራሉ። ከበደና አበበ ለተማሪዎቻችን መጽሐፎችን ሰጡ።"
140
+
141
+ sentence_tokenize(text)
142
+ # ['ተማሪዎቹ በከተማ ውስጥ ይኖራሉ።', 'ከበደና አበበ ለተማሪዎቻችን መጽሐፎችን ሰጡ።']
143
+
144
+ tokenize(text)
145
+ # ['ተማሪዎቹ', 'በከተማ', 'ውስጥ', 'ይኖራሉ', '።', 'ከበደና', 'አበበ', 'ለተማሪዎቻችን', 'መጽሐፎችን', 'ሰጡ', '።']
146
+
147
+ tokenize(text, morphemes=True)
148
+ # ['ተማሪ', 'ዎች', 'ው', 'በ', 'ከተማ', 'ውስጥ', 'ይኖራሉ', '።', 'ከበደ', 'ና', 'አበበ',
149
+ # 'ለ', 'ተማሪ', 'ዎች', 'ችን', 'መጽሐፍ', 'ች', 'ን', 'ሰጡ', '።']
150
+
151
+ tokenize(text, morphemes=True, mark_affixes=True)
152
+ # ['ተማሪ', '+ዎች', '+ው', 'በ+', 'ከተማ', 'ውስጥ', 'ይኖራሉ', '።', 'ከበደ', '+ና', 'አበበ',
153
+ # 'ለ+', 'ተማሪ', '+ዎች', '+ችን', 'መጽሐፍ', '+ች', '+ን', 'ሰጡ', '።']
154
+ ```
155
+
156
+ Analyse a single word:
157
+
158
+ ```python
159
+ from amharic_segmenter import analyze
160
+
161
+ analyze("ለተማሪዎቻችን")
162
+ # Analysis(word='ለተማሪዎቻችን', prefixes=('ለ',), stem='ተማሪ', suffixes=('ዎች', 'ችን'))
163
+ ```
164
+
165
+ Token offsets:
166
+
167
+ ```python
168
+ from amharic_segmenter import tokenize_spans
169
+
170
+ tokenize_spans("ከበደን አየ።")
171
+ # [Token(text='ከበደን', start=0, end=4, kind='word'),
172
+ # Token(text='አየ', start=5, end=7, kind='word'),
173
+ # Token(text='።', start=7, end=8, kind='punct')]
174
+ ```
175
+
176
+ ## Command line
177
+
178
+ ```console
179
+ $ amharic-segmenter -m "ለተማሪዎቻችን መጽሐፎችን ሰጡ።"
180
+ ለ ተማሪ ዎች ችን መጽሐፍ ች ን ሰጡ ።
181
+
182
+ $ amharic-segmenter --sentences --json "አበበ መጣ። ከበደ ሄደ።"
183
+ ["አበበ መጣ።", "ከበደ ሄደ።"]
184
+
185
+ $ amharic-segmenter --stem "ተማሪዎቹ መጻሕፍትን አነበቡ።"
186
+ ተማሪ መጻሕፍት አነበቡ ።
187
+
188
+ $ echo "ተማሪውንም አየሁ።" | amharic-segmenter -m --mark-affixes
189
+ ተማሪ +ው +ን +ም አየሁ ።
190
+ ```
191
+
192
+ Run `amharic-segmenter --help` for all options (`--strategy`, `--lexicon`, `--normalize`,
193
+ `--no-punct`, `--json`). `python -m amharic_segmenter` works too.
194
+
195
+ ## API reference
196
+
197
+ ### Module-level functions
198
+
199
+ | Function | Returns | Description |
200
+ |----------|---------|-------------|
201
+ | `sent_tokenize(text)` | `list[str]` | Sentences (NLTK-style name for `sentence_tokenize`) |
202
+ | `word_tokenize(text)` | `list[str]` | Words and punctuation (NLTK-style, same as `tokenize(text)`) |
203
+ | `stem(word, *, aggressive=True)` | `str` | Stem of one word. `aggressive=False` leaves words outside the lexicon alone |
204
+ | `stem_words(words)` | `list[str]` | Stems of many words |
205
+ | `AmharicStemmer().stem(word)` | `str` | Stemmer object, `.stem()` and `.stem_words()` |
206
+ | `tokenize(text, *, morphemes=False, include_punct=True, mark_affixes=False)` | `list[str]` | Split text into tokens, optionally down to morphemes |
207
+ | `tokenize_spans(text, *, include_punct=True)` | `list[Token]` | Word-level tokens with `start`/`end` offsets and `kind` |
208
+ | `sentence_tokenize(text)` | `list[str]` | Split text into sentences |
209
+ | `analyze(word)` | `Analysis` | Prefixes, stem and suffixes of one word |
210
+ | `split_morphemes(word)` | `list[str]` | Morphemes of one word |
211
+ | `lemma(word)` | `str` | Dictionary form of the stem (`መጻሕፍትን → መጽሐፍ`) |
212
+ | `normalize_homophones(text)` | `str` | Collapse `ሐ ኀ → ሀ`, `ሠ → ሰ`, `ዐ → አ`, `ፀ → ጸ` (length-preserving) |
213
+
214
+ ### `AmharicTokenizer`
215
+
216
+ ```python
217
+ from amharic_segmenter import AmharicTokenizer
218
+
219
+ tok = AmharicTokenizer(
220
+ lexicon=["መምህር", "ጓደኛ"], # extra stems that may be split off
221
+ default_lexicon=True, # include the built-in seed lexicon
222
+ strategy="lexicon", # "lexicon" | "rules" | "none"
223
+ normalize=False, # collapse homophone letters first
224
+ )
225
+
226
+ tok.tokenize("መምህራችንን አየሁ።", morphemes=True)
227
+ tok.add_words(["ጋዜጣ"])
228
+ tok = AmharicTokenizer.from_file("my_words.txt") # one word per line, '#' comments
229
+ ```
230
+
231
+ | `strategy` | Behaviour |
232
+ |------------|-----------|
233
+ | `"lexicon"` *(default)* | Accept a split only if the stem is in the lexicon. High precision. |
234
+ | `"rules"` | Also accept unknown stems of at least `min_stem` letters. Higher recall, more false splits. |
235
+ | `"none"` | Never split words into morphemes. |
236
+
237
+ ### `Analysis` and `Token`
238
+
239
+ - `Analysis(word, prefixes, stem, suffixes)` with `.morphemes` and `.is_split`
240
+ - `Token(text, start, end, kind)` where `kind` is `word`, `latin`, `number`, `punct` or `other`
241
+
242
+ > **Note:** morphemes are *underlying forms*. `ልጆች` becomes `ልጅ + ች` because the plural rule
243
+ > changes the stem's last letter, so joining the morphemes does not always give back the
244
+ > surface word. Use `tokenize_spans` when you need exact offsets.
245
+
246
+ ## How it works
247
+
248
+ ```
249
+ raw text
250
+ │
251
+ ▼
252
+ ┌──────────────────────────┐ Layer 1: rule-based, always on
253
+ │ sentences and word tokens │ Ethiopic punctuation, numerals, Latin, no loss
254
+ └─────────────┬────────────┘
255
+ │ (optional, morphemes=True)
256
+ ▼
257
+ ┌──────────────────────────┐ Layer 2: morphology
258
+ │ generate candidate splits │ prefixes ← stem → plural → possessive → ን → ና/ም
259
+ │ accept if stem is known │ lexicon check keeps precision high
260
+ └──────────────────────────┘
261
+ ```
262
+
263
+ The morphology layer works on the structure of the Ethiopic script itself: every letter has
264
+ seven vowel *orders*, and the plural and possessive rules are defined in terms of them
265
+ (`ሰው → ሰዎች`, `አገር → አገራችሁ`). The rules are listed with book references in
266
+ [`docs/GRAMMAR_RULES.md`](docs/GRAMMAR_RULES.md).
267
+
268
+ The rules are based on the grammar book *አማርኛ ሠዋሰው* (1963 E.C.).
269
+
270
+ ## How it relates to other Amharic tools
271
+
272
+ | Project (PyPI) | Approach | Good for |
273
+ |----------------|----------|----------|
274
+ | **`amharic-segmenter`** (this package) | Grammar rules from a printed grammar book, NLTK-style API | Sentence and word splitting, morpheme splitting, stemming, explainable output |
275
+ | `amharic-tokenizer` | BPE-like merges learned from a corpus | Subword vocabularies for training language models |
276
+ | `amseg` | Rule-based sentence and word splitter, with normalizer and romanizer | Sentence/word splitting and transliteration |
277
+
278
+ They solve different problems and can be used together, for example `amharic-segmenter` for
279
+ sentences and stems and a trained BPE model for model vocabularies.
280
+
281
+ ## Current scope and limitations
282
+
283
+ This is an early release (`0.1`, alpha). Please read this before using it in production:
284
+
285
+ - Only **printed pages 7-110** of the source book have been used so far (chapters 1-5 and the
286
+ start of chapter 6; the punctuation chapter is still missing). See [`docs/BOOK_COVERAGE.md`](docs/BOOK_COVERAGE.md) for exactly what is
287
+ and is not covered, e.g. the book's chapter on punctuation.
288
+ - Stemming is a **noun-oriented** suffix stripper, like a light English stemmer. Verbs are
289
+ left alone rather than guessed. Prefixes (`በ ከ ለ የ`) are only stripped when the rest is a
290
+ known word, so unknown words lose suffixes only. For unknown nouns it can pick the wrong stem when the
291
+ last letter is ambiguous (`ጋዜጦች` could come from `ጋዜጣ` or `ጋዜጥ`).
292
+ - Morphology covers **nouns and noun phrases**. **Verb morphology is not implemented yet.**
293
+ - The built-in lexicon is a small seed. Unknown stems are left unsplit in the default mode,
294
+ so coverage grows as the lexicon grows. Add your own words or send a pull request.
295
+ - Some forms are ambiguous without context (a final `ም` can be a conjunction or part of the
296
+ word, as in `ወንድም`). The lexicon resolves most cases, not all.
297
+ - Rules reflect one grammar book. Modern usage and dialects may differ; native-speaker
298
+ review is very welcome.
299
+
300
+ ## Roadmap
301
+
302
+ - [ ] Punctuation rules from chapter 7 of the source book (pages still to be added)
303
+ - [ ] Verb morphology (agreement, tense, negation, relative `የ…`) from an additional source
304
+ - [ ] Larger open lexicon and a test corpus of annotated sentences
305
+ - [ ] Reduplicated plurals and internal plurals as rules
306
+ - [ ] Subword-vocabulary export for use with ML tokenizers
307
+ - [ ] Evaluation scripts against annotated Amharic data
308
+
309
+ ## Contributing
310
+
311
+ Contributions are very welcome, especially from Amharic speakers and linguists. The easiest
312
+ first contribution is adding words to
313
+ [`src/amharic_segmenter/data/lexicon.txt`](src/amharic_segmenter/data/lexicon.txt).
314
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, rules for adding grammar rules, and the pull
315
+ request checklist.
316
+
317
+ ```bash
318
+ git clone https://github.com/Alki45/amharic-segmenter.git
319
+ cd amharic-segmenter
320
+ pip install -e ".[dev]"
321
+ pytest
322
+ ```
323
+
324
+ ## Citation
325
+
326
+ If you use this package in research, please cite it:
327
+
328
+ ```bibtex
329
+ @software{amharic_segmenter,
330
+ title = {amharic-segmenter: Sentence, word and morpheme tokenization for Amharic},
331
+ author = {Ali Kibret Muhamed},
332
+ year = {2026},
333
+ url = {https://github.com/Alki45/amharic-segmenter}
334
+ }
335
+ ```
336
+
337
+ ## License
338
+
339
+ [MIT](LICENSE). The grammar rules are re-implemented in original code; the source book is
340
+ credited above and its text is not redistributed.