# ganapati


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

ganapati reads Sanskrit texts and describes them in ways a search index
can use. It finds where each verse ends in a GRETIL, TEI, DCS or
vedicreader file and cuts the text into chunks on those boundaries. It
works out the metre of every verse from the weights of its syllables,
and it records the lemmas (dictionary forms) and English glosses behind
the words. It also maps an epithet such as Pārtha to the name a
translation uses, and it can derive a word through Pāṇini’s grammar.

ganapati is built to work with litesearch, but only the search profiles
and filters in `ganapati.lemma` need it. When both are installed,
litesearch finds ganapati through a package entry point, so a Sanskrit
file added to an index is chunked by verse and each chunk gets its metre
as metadata, which `by_meter` can then filter on:

``` python
from litesearch import Index
from ganapati import Meter

ix = Index('vault.db')
ix.add('mahabharata.htm')
ix.search('dharma')[:3]
ix.db.by_meter(meter=Meter.ANUSTUBH)[:3]
```

    /Users/71293/code/personal/orgs/ganapati/.venv/lib/python3.13/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
      from .autonotebook import tqdm as notebook_tqdm

    [{'content': 'nārāyaṇaṃ namaskṛtya naraṃ caiva narottamam\ndevīṃ sarasvatīṃ caiva tato jayam udīrayet',
      'metadata': '{"meter": "anuṣṭubh", "variant": "pathyā", "gana": "ta_ra_ga_ga", "pada": "8"}',
      'node_id': '73a63025c7fc3d14#0',
      'doc_id': '73a63025c7fc3d14',
      'page': 0},
     {'content': 'samāsīnān abhyagacchad brahmarṣīn saṃśitavratān\nvinayāvanato bhūtvā kadā cit sūtanandanaḥ',
      'metadata': '{"meter": "anuṣṭubh", "variant": "pathyā ra-vipulā", "gana": "ya_ta_ga_ga", "pada": "8"}',
      'node_id': '73a63025c7fc3d14#0',
      'doc_id': '73a63025c7fc3d14',
      'page': 2},
     {'content': 'tam āśramam anuprāptaṃ naimiṣāraṇyavāsinaḥ\ncitrāḥ śrotuṃ kathās tatra parivavrus tapasvinaḥ',
      'metadata': '{"meter": "anuṣṭubh", "variant": "pathyā", "gana": "ja_sa_ga_ga", "pada": "8"}',
      'node_id': '73a63025c7fc3d14#0',
      'doc_id': '73a63025c7fc3d14',
      'page': 3}]

[`verse_meta`](https://vedicreader.github.io/ganapati/metre.html#verse_meta)
writes that metadata. For Gītā 1.1 it finds an anuṣṭubh, the metre of
the epics, in its regular form (pathyā), with eight syllables to the
pāda (quarter-verse):

``` python
verse_meta('dharmakṣetre kurukṣetre samavetā yuyutsavaḥ '
           'māmakāḥ pāṇḍavāścaiva kimakurvata sañjaya')
```

    {'meter': 'anuṣṭubh', 'variant': 'pathyā', 'gana': 'ma_ra_ga_ga', 'pada': '8'}

Behind it is the scansion.
[`scan`](https://vedicreader.github.io/ganapati/metre.html#scan) marks
each syllable heavy (`g`, guru) or light (`l`, laghu), and
[`detect_meter`](https://vedicreader.github.io/ganapati/metre.html#detect_meter)
compares the whole pattern with the metres it knows. Here it recognises
the first verse of the Meghadūta as mandākrāntā:

``` python
scan('dharmakṣetre kurukṣetre')     # g for heavy, l for light
```

    'gggglggg'

``` python
detect_meter('kaścit kāntāvirahaguruṇā svādhikārātpramattaḥ '
             'śāpenāstaṃgamitamahimā varṣabhogyeṇa bhartuḥ '
             'yakṣaścakre janakatanayāsnānapuṇyodakeṣu '
             'snigdhacchāyātaruṣu vasatiṃ rāmagiryāśrameṣu')['name']
```

    <Meter.MANDAKRANTA: 'mandākrāntā'>

## A line at a time

Aligned recordings and speech recognition give you lines, not verses.
[`match_pada`](https://vedicreader.github.io/ganapati/metre.html#match_pada)
names the metres a single pāda could belong to, and
[`group_verses`](https://vedicreader.github.io/ganapati/metre.html#group_verses)
works out how many lines make a verse.

``` python
padas = ['kaścit kāntāvirahaguruṇā svādhikārātpramattaḥ',
         'śāpenāstaṃgamitamahimā varṣabhogyeṇa bhartuḥ',
         'yakṣaścakre janakatanayāsnānapuṇyodakeṣu',
         'snigdhacchāyātaruṣu vasatiṃ rāmagiryāśrameṣu']
match_pada(padas[0]), group_verses(padas).size
```

## Names and terms

A reader may ask about Sri Ranganatha where the translation writes
Viṣṇu, or about anumana where it says inference.
[`canonical`](https://vedicreader.github.io/ganapati/names.html#canonical)
and
[`term_gloss`](https://vedicreader.github.io/ganapati/names.html#term_gloss)
connect the two:

``` python
canonical('Sri Ranganatha'), canonical('Partha'), term_gloss('anumana')
```

    (('viṣṇu', 'nārāyaṇa', 'hari'), ('arjuna',), ('inference',))

## The modules

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<thead>
<tr>
<th>module</th>
<th>what is in it</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>ganapati.sanskrit</code></td>
<td>Vedic accent removal, an ASCII search key for a word in any script,
citation ids</td>
</tr>
<tr>
<td><code>ganapati.text</code></td>
<td>verse boundaries, verse layout by pāda, the two chunkers, readers
for GRETIL, TEI, vedicreader XML and JSON, and DCS</td>
</tr>
<tr>
<td><code>ganapati.metre</code></td>
<td>IAST transliteration, syllable weights, the gaṇas, 100 fixed-pattern
metres, the āryā family, checks against recorded audio</td>
</tr>
<tr>
<td><code>ganapati.lemma</code></td>
<td>vidyut lemmas, Monier-Williams glosses, a source’s own word-by-word
analysis and its repair, the litesearch profiles and search filters</td>
</tr>
<tr>
<td><code>ganapati.names</code></td>
<td>one key for every spelling of a name, epithets of deities and
heroes, English for śāstra and jyotiṣa terms</td>
</tr>
<tr>
<td><code>ganapati.vyakarana</code></td>
<td>derivations through the Aṣṭādhyāyī, a word-by-word analysis matched
to its line, the sandhi rule at a join, two words joined into their
saṃhitā</td>
</tr>
</tbody>
</table>

`from ganapati import *` brings in every module except
`ganapati.sanskrit`, which you import by name.

## Install

``` sh
pip install ganapati
```

Use `pip install 'ganapati[search]'` to install litesearch with it.
Lemmas need vidyut’s data, an 81 MB download made the first time you ask
for a lemma, and glosses need Monier-Williams, downloaded the first time
you call
[`mw_lexicon`](https://vedicreader.github.io/ganapati/lemma.html#mw_lexicon).
Without either, an index still gets each verse’s metre, its audio
timings, and any analysis the source itself carries.

## Credits

The joiner in `ganapati.vyakarana` reads vidyut’s table of sandhi rules,
shipped as `ganapati/data/vidyut_sandhi_rules.csv`. vidyut is by
ambuda.org (https://github.com/ambuda-org/vidyut) and is MIT licensed.
Its copyright notice and licence travel with the table in
`ganapati/data/LICENSE-vidyut`.
