Skip to content

Commit

Permalink
[dactylo] n-grams (#63)
Browse files Browse the repository at this point in the history
* [dactylo] n-grams

* s/wount/count/

* code factorization
  • Loading branch information
fabi1cazenave authored Feb 15, 2024
1 parent 8b3fa15 commit 1e7d764
Show file tree
Hide file tree
Showing 40 changed files with 84 additions and 54 deletions.
16 changes: 8 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
all:
@for file in layouts/*.toml; do \
kalamine make $$file --out "layouts/$$(basename $${file%.*}).json"; \
@for file in data/layouts/*.toml; do \
kalamine make $$file --out "data/layouts/$$(basename $${file%.*}).json"; \
done
@for file in layouts/*.yaml; do \
kalamine make $$file --out "layouts/$$(basename $${file%.*}).json"; \
@for file in data/layouts/*.yaml; do \
kalamine make $$file --out "data/layouts/$$(basename $${file%.*}).json"; \
done

watch:
@inotifywait -m layouts -e close_write | while read -r _path _action file; do \
@inotifywait -m data/layouts -e close_write | while read -r _path _action file; do \
case $$file in \
*yaml) kalamine make "layouts/$$file" --out "layouts/$$(basename "$${file%.*}").json";; \
*toml) kalamine make "layouts/$$file" --out "layouts/$$(basename "$${file%.*}").json";; \
*yaml) kalamine make "data/layouts/$$file" --out "data/layouts/$$(basename "$${file%.*}").json";; \
*toml) kalamine make "data/layouts/$$file" --out "data/layouts/$$(basename "$${file%.*}").json";; \
esac \
done

Expand All @@ -25,7 +25,7 @@ clean:
install:
@echo "Installer script for XKB (GNU/Linux). Requires super-user privileges."
@echo
xkalamine install layouts/ergol.yaml
xkalamine install data/layouts/ergol.yaml

uninstall:
@echo "Unistaller script for XKB (GNU/Linux). Requires super-user privileges."
Expand Down
18 changes: 9 additions & 9 deletions dactylo.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ <h1 class="key_list">·</h1>
<option>lafayette</option>
</select>
<select id="dict">
<option selected>french_1k</option>
<option>french_10k</option>
<option>english_1k</option>
<option>english_10k</option>
<option value="fr,french_1k" selected>Français 1k</option>
<option value="fr,french_10k">Français 10k</option>
<option value="en,english_1k">English 1k</option>
<option value="en,english_10k">English 10k</option>
</select>
</span>
<select id="geometry">
<option value="iso" selected> ISO </option>
<option value="ansi"> ANSI </option>
<option value="ol60"> TMx </option>
<option value="ol50"> 4×6 </option>
<option value="ol40"> 3×6 </option>
<option value="iso" selected>ISO</option>
<option value="ansi">ANSI</option>
<option value="ol60">TMx</option>
<option value="ol50">4×6</option>
<option value="ol40">3×6</option>
</select>
</p>
</div>
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ <h1>Ergo‑L</h1>

<dialog id="demo">
<input spellcheck="false" placeholder="zone de saisie Ergo‑L" />
<x-keyboard src="layouts/ergol.json"></x-keyboard>
<x-keyboard src="data/layouts/ergol.json"></x-keyboard>
</dialog>

<h2 id="objectifs">Objectifs</h2>
Expand Down
98 changes: 64 additions & 34 deletions js/dactylo.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const g30Keys = [
const STARTING_LEVEL = 4;
const MIN_WORD_COUNT = 42;
const ALL_30_KEYS = [
'KeyF', 'KeyJ',
'KeyD', 'KeyK',
'KeyS', 'KeyL',
Expand Down Expand Up @@ -30,69 +32,92 @@ window.addEventListener('DOMContentLoaded', () => {
const gInput = document;

let gKeyLayout = undefined;
let gDictionary = undefined;
let gDictionary = {
words: undefined,
trigrams: undefined,
bigrams: undefined,
};

let gLessonLevel = 12;
let gLessonWords = [];
let gLessonCurrent = undefined;
let gLessonLevel = STARTING_LEVEL;
let gLessonWords = [];
let gLessonCurrent = undefined;
let gLessonStartTime = undefined;
let gPendingError = false;
let gPendingError = false;

const setLayout = () => {
fetch(`layouts/${gLayout.value}.json`)
// fetch a kalamine corpus: symbols, bigrams, trigrams
const fetchNgrams = () => {
const ngrams = gDict.value.split(',')[0];
return fetch(`data/corpus/${ngrams}.json`)
.then(response => response.json())
.then(layout => {
gKeyboard.setKeyboardLayout(layout.keymap, layout.deadkeys, gGeometry.value);
gKeyboard.theme = 'hints';
gKeyLayout = layout;
setLessonLevel();
.then(data => {
gDictionary.trigrams = Object.keys(data.trigrams);
gDictionary.bigrams = Object.keys(data.digrams);
});
};

const setDict = () => {
fetch(`dicts/${gDict.value}.json`)
// fetch MonkeyType words
const fetchWords = () => {
const words = gDict.value.split(',')[1];
return fetch(`data/dicts/${words}.json`)
.then(response => response.json())
.then(data => {
gDictionary = data.words;
setLessonLevel();
gDictionary.words = data.words;
});
};

// fetch a kalamine keyboard layout
const fetchLayout = () => {
return fetch(`data/layouts/${gLayout.value}.json`)
.then(response => response.json())
.then(layout => {
gKeyboard.setKeyboardLayout(layout.keymap, layout.deadkeys, gGeometry.value);
gKeyboard.theme = 'hints';
gKeyLayout = layout;
});
};

gLayout.addEventListener('change', setLayout);
setLayout();
gLayout.addEventListener('change', () => {
fetchLayout().then(setLessonLevel);
});

gDict.addEventListener('change', setDict);
setDict();
gDict.addEventListener('change', () => {
Promise.all([fetchNgrams(), fetchWords()]).then(setLessonLevel);
});

gGeometry.addEventListener('change', event => {
gKeyboard.geometry = gGeometry.value;
});

gKeyList.addEventListener('click', event => {
if (event.target.nodeName.toLowerCase() == 'kbd') {
setLessonLevel(event.target.dataset.level);
gLessonLevel = event.target.dataset.level;
setLessonLevel();
}
});

const setLessonLevel = (level = gLessonLevel) => {
if (!gKeyLayout || !gDictionary) {
return;
}

const keys = g30Keys.slice(0, level);
const rawLetters = keys.flatMap(key => gKeyLayout.keymap[key]);
const setLessonLevel = () => {
const keys = ALL_30_KEYS.slice(0, gLessonLevel);
// const rawLetters = keys.flatMap(key => gKeyLayout.keymap[key]);
const rawLetters = keys.map(key => gKeyLayout.keymap[key][0]);

const odk = gKeyLayout.deadkeys['**'];
const has1dk = keys.some(key => gKeyLayout.keymap[key].indexOf('**') >= 0);
const deadkeyLetters = !has1dk ? [] :
rawLetters
.filter(letter => letter in odk)
.map(letter => odk[letter]);
const lessonLetters = rawLetters.concat(deadkeyLetters);

gLessonLevel = level;
gLessonWords = gDictionary.filter(word =>
Array.from(word).every(letter => lessonLetters.indexOf(letter) >= 0));
const lessonLetters = rawLetters.concat(deadkeyLetters);
const lessonFilter = word =>
Array.from(word).every(letter => lessonLetters.indexOf(letter) >= 0);

gLessonWords = [];
for (dict of [gDictionary.words, gDictionary.trigrams, gDictionary.bigrams, rawLetters]) {
gLessonWords = gLessonWords.concat(dict.filter(lessonFilter));
if (gLessonWords.length > MIN_WORD_COUNT) {
break;
}
}

showLesson();
showKeys();
Expand All @@ -105,7 +130,7 @@ window.addEventListener('DOMContentLoaded', () => {
const state = idx < gLessonLevel ? '' : 'inactive';
return `<kbd data-level="${idx + 1}" class="${state}">${char}</kbd>`;
};
gKeyList.innerHTML = g30Keys.map(serializeKey).join('');
gKeyList.innerHTML = ALL_30_KEYS.map(serializeKey).join('');
};

const showLesson = () => {
Expand Down Expand Up @@ -168,6 +193,11 @@ window.addEventListener('DOMContentLoaded', () => {
}
};

// startup
Promise.all([fetchNgrams(), fetchWords(), fetchLayout()])
.then(setLessonLevel);


/**
* Keyboard highlighting & layout emulation
*/
Expand Down
4 changes: 2 additions & 2 deletions js/heatmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ window.addEventListener('DOMContentLoaded', () => {
const setProp = (key, value) => {
if (key === 'layout') {
if (value) {
fetch(`layouts/${value}.json`)
fetch(`data/layouts/${value}.json`)
.then(response => response.json())
.then(data => {
inputField.placeholder = `Zone de saisie ${value}`;
Expand All @@ -479,7 +479,7 @@ window.addEventListener('DOMContentLoaded', () => {
}
} else if (key === 'corpus') {
if (value && value !== corpusName) {
fetch(`corpus/${value}.json`)
fetch(`data/corpus/${value}.json`)
.then(response => response.json())
.then(data => {
corpus = data.symbols;
Expand Down

0 comments on commit 1e7d764

Please sign in to comment.