# Letter at

> letterAt(text, info) says which letter of a text is under the pointer: to spell a word, or to pick a word of dialogue.

Example `letter-at`, running at https://nacatamalon.com/en/examples/letter-at. The whole catalogue: https://nacatamalon.com/llms/examples.md.

`letterAt(text, info)` is the letter of a text under the pointer: `{ index, char, line }`, with `text.text[index]` the one touched, or `null` on a space, between two letters or outside the text.

Above, a word to spell: each letter touched is added to what is spelled, and touching what is spelled clears it. Below, a line of dialogue broken by `maxWidth`: touching it says which letter, where it is in the text, on which line, and the whole word around it, found from its index.

## Code

`index.ts`:

```ts
import { createGame } from 'nacatamalon';
import { WIDTH, HEIGHT } from './settings';

import { Level } from './scenes/demo';

const game = createGame('#app', {
    width: WIDTH,
    height: HEIGHT,
    background: '#14182c'
});

// Declare Scenes
game({
    Level
});
```

`components/spelling.ts`:

```ts
import { createText, getColor, letterAt, listen } from 'nacatamalon';
import * as Settings from '../settings';

export const Spelling = () => {
    // A word to spell.
    const word = createText({
        text: Settings.WORD,
        style: {
            fontSize: 16
        },
        tint: '#ffc450',
        transform: {
            x: 16,
            y: 20
        }
    });

    const spelled = createText({
        text: 'TAP THE LETTERS',
        tint: Settings.DIM,
        transform: {
            x: 16,
            y: 46
        }
    });

    let spelling = '';

    listen(word, {
        onClick: (info) => {
            const letter = letterAt(word, info);

            if (letter === null) {
                return;
            }

            spelling += letter.char;
            spelled.text = spelling;
            spelled.tint = getColor('#ffffff');
        },
    });
    listen(spelled, {
        onClick: () => {
            spelling = '';
            spelled.text = 'TAP THE LETTERS';
            spelled.tint = Settings.DIM;
        },
    });
};
```

`components/wordpicker.ts`:

```ts
import { createText, getColor, letterAt, listen } from 'nacatamalon';
import * as Settings from '../settings';

export const WordPicker = () => {
    // A line of dialogue to pick words from.
    const speech = createText({
        text: Settings.SPEECH,
        style: {
            maxWidth: 288,
            lineSpacing: 6
        },
        transform: {
            x: 16,
            y: 90
        },
    });

    const found = createText({
        text: 'TOUCH A WORD',
        tint: Settings.DIM,
        style: {
            lineSpacing: 4
        },
        transform: {
            x: 16,
            y: 150
        }
    });

    listen(speech, {
        onClick: (info) => {
            const letter = letterAt(speech, info);

            if (letter === null) {
                found.text = 'NOT ON A LETTER';
                found.tint = Settings.DIM;

                return;
            }

            // The word is the letters either side of it, up to a space or a sign.
            const all = speech.text;
            let start = letter.index;
            let end = letter.index + 1;

            while (start > 0 && /[A-Z]/.test(all[start - 1])) {
                start--;
            }

            while (end < all.length && /[A-Z]/.test(all[end])) {
                end++;
            }

            found.text = letter.char + ' AT ' + letter.index + ', LINE ' + letter.line + '\nWORD ' + all.slice(start, end);
            found.tint = getColor('#7be38f');
        },
    });
};
```

`scenes/demo.ts`:

```ts
import { createScene, useSpawn } from 'nacatamalon';

import { Spelling } from '../components/spelling';
import { WordPicker } from '../components/wordpicker';

export const Level = () => {
    useSpawn(Spelling)();
    useSpawn(WordPicker)();

    return createScene();
};
```

`settings.ts`:

```ts
export const WIDTH = 320;
export const HEIGHT = 200;
import { getColor } from 'nacatamalon';

export const DIM = getColor('#6a6488');
export const WORD = 'NACATAMAL';
export const SPEECH = 'THE TAMALES ARE READY, BUT THE NACATAMAL TAKES ALL NIGHT IN THE POT';
```
