/** * HebrewParseTrainer - practice Hebrew verbs * Copyright (C) 2015 Camil Staps * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ $(document).ready(function(){ var audio_positive = new Audio('public/audio/positive.wav'); var audio_negative = new Audio('public/audio/negative.wav'); var correct_answers; var input_count = 0; var checked = false; function addInput() { input_count++; var html = "
\
\
\ \ \
\
\
\
\ \ \
\
\
"; $('#trainer-input-container').append(html); $('#trainer-input-'+input_count).keyup(function(e){ if (e.keyCode == 13) { if (!checked) { checked = checkInput(); } else { reloadVerb(); $(this) .val('') .css({backgroundColor:'transparent'}) .parent().removeClass('has-error has-success'); checked = false; } } else { $(this) .css({backgroundColor:'transparent'}) .parent().removeClass('has-error has-success'); checked = false; processInput(); } }).focus(); } function removeInputs() { $('.trainer-input').remove(); input_count = 0; } function reloadVerb() { $('#trainer-404').hide(); $('#trainer-verb').css({color: 'gray'}); $('#trainer-answer').text(''); removeInputs(); var stems = $('input[name="stem"]:checked').map(function(){return this.value;}); var tenses = $('input[name="tense"]:checked').map(function(){return this.value;}); var roots = $('input[name="root"]:checked').map(function(){return this.value;}); $.ajax('verb/random', { data: { stem: $.makeArray(stems).join(), tense: $.makeArray(tenses).join(), root: $.makeArray(roots).join() }, dataType: 'json', error: function(jqxhr, status, error) { $('#trainer-404').fadeIn(); }, success: function(data, status, jqxhr) { $('#trainer-verb').text(data.verb.verb).css({color: 'black'}); correct_answers = []; for (var i in data.answers) { var answer = { stem: data.answers[i].stem, tense: data.answers[i].tense, person: data.answers[i].person, gender: data.answers[i].gender, number: data.answers[i].number }; correct_answers.push(answer); } addInput(); } }); } var stems = []; var tenses = []; var tenses_abbr = []; function findStem(stem) { var stems_ = stems.filter(function(s){return s.indexOf(stem) == 0;}); if (stems_.length == 1) return stems_[0]; } function findTense(tense) { if (tenses.indexOf(tense) != -1) return tense; if (tenses_abbr.indexOf(tense) != -1) return tenses[tenses_abbr.indexOf(tense)]; } function parseAnswer(parsing) { var persons = ['1', '2', '3', null]; var genders = ['m', 'f', 'c', null]; var numbers = ['s', 'p', null]; var re = /^\s*(\w+)\s+(\w+)(?:\s+(?:([123])\s*)?([mf])\s*([sp])\s*)?$/; var match = parsing.match(re); if (match == null) return false; var stem = findStem(match[1]); var tense = findTense(match[2]); var person = match[3] ? match[3] : null; var gender = match[4] ? match[4] : null; var number = match[5] ? match[5] : null; if (typeof stem === 'undefined' || typeof tense === 'undefined' || $.inArray(person, persons) == -1 || $.inArray(gender, genders) == -1 || $.inArray(number, numbers) == -1) return false; if (tense.indexOf('infinitive') == 0 && (person != null || gender != null || number != null)) return false; if (tense.indexOf('infinitive') != 0) { if (gender == null || number == null) return false; if (tense.indexOf('participle') == 0 && person != null) return false; if (tense.indexOf('participle') != 0 && person == null) return false; } return { stem: stem, tense: tense, person: person, gender: gender, number: number }; } function parsingToString(parsing, extended) { var genders = { 'm': 'masculine', 'f': 'feminine' }; var numbers = { 's': 'singular', 'p': 'plural' }; if (extended === true) { return parsing.stem + ' ' + parsing.tense + (parsing.person ? (' ' + parsing.person) : '') + (parsing.gender ? (' ' + genders[parsing.gender]) : '') + (parsing.number ? (' ' + numbers[parsing.number]) : ''); } else { return parsing.stem + ' ' + parsing.tense + (parsing.person ? (' ' + parsing.person) : '') + (parsing.gender ? (' ' + parsing.gender) : '') + (parsing.number ? (' ' + parsing.number) : ''); } } function processInput() { var input = $('#trainer-input-' + input_count); var answer = parseAnswer(input.val()); if (answer === false) { input.parent().addClass('has-error'); $('#trainer-parsed-' + input_count).val('Parsing error'); } else { input.parent().removeClass('has-error'); $('#trainer-parsed-' + input_count).val(parsingToString(answer, true)); } return answer; } function checkInput() { var answer = processInput(); for (var i in correct_answers) { var correct_answer = correct_answers[i]; if (JSON.stringify(answer) == JSON.stringify(correct_answer)) { $('#trainer-input-'+input_count) .css({backgroundColor: '#dff0d8'}) .parent().addClass('has-success'); if ($('#settings-audio').prop('checked')) audio_positive.play(); correct_answers.splice(i,1); if (correct_answers.length > 0) { console.log(correct_answers); addInput(); return false; } else { return true; } } } $('#trainer-input-'+input_count) .css({backgroundColor: '#f2dede'}) .parent().addClass('has-error'); if ($('#settings-audio').prop('checked')) audio_negative.play(); $('#trainer-answer').text(' - ' + correct_answers.map(parsingToString).join(', ')); return true; } function init() { $.ajax('stem', { dataType: 'json', success: function(data, status, jqxhr) { stems = data.map(function(d){return d.name;}); } }); $.ajax('tense', { dataType: 'json', success: function(data, status, jqxhr) { tenses = data.map(function(d){return d.name;}); tenses_abbr = data.map(function(d){return d.abbreviation;}); } }); reloadVerb(); } $('#hebrewparsetrainer-settings input.reload-verb').change(function(){ reloadVerb(); }); init(); });