aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamil Staps2016-01-04 23:20:50 +0100
committerCamil Staps2016-01-04 23:20:50 +0100
commit7a93b44c6cb2f1e1f335d93ddf62a149ebd5f1d9 (patch)
treeea606ac400db5aced2a83f65efa247372ad164d5
parentModels, migrations and seeds for root, roottranslation, stem, tense, verb (diff)
Training app
-rw-r--r--app/Http/Controllers/RandomVerbController.php30
-rw-r--r--app/Http/routes.php12
-rw-r--r--public/audio/negative.wavbin0 -> 216736 bytes
-rw-r--r--public/audio/positive.wavbin0 -> 151198 bytes
-rw-r--r--public/css/hebrewparsetrainer.css12
-rw-r--r--public/js/hebrewparsetrainer.js189
-rw-r--r--resources/views/trainer.php79
7 files changed, 321 insertions, 1 deletions
diff --git a/app/Http/Controllers/RandomVerbController.php b/app/Http/Controllers/RandomVerbController.php
new file mode 100644
index 0000000..e14d012
--- /dev/null
+++ b/app/Http/Controllers/RandomVerbController.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: camil
+ * Date: 1/4/16
+ * Time: 8:30 PM
+ */
+
+namespace App\Http\Controllers;
+
+use HebrewParseTrainer\Verb;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Input;
+use Laravel\Lumen\Routing\Controller as BaseController;
+
+class RandomVerbController extends BaseController {
+
+ public function show()
+ {
+ $verbs = Verb::all();
+ foreach (Input::get() as $col => $val) {
+ $val = explode(',', $val);
+ $verbs = $verbs->filter(function(Verb $item) use ($col, $val) {
+ return in_array($item->getAttribute($col), $val);
+ });
+ }
+ return $verbs->random();
+ }
+
+} \ No newline at end of file
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 5ecfcd1..5e6bc5a 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -12,5 +12,15 @@
*/
$app->get('/', function () use ($app) {
- return $app->welcome();
+ return view('trainer');
});
+
+$app->get('/stem', function () use ($app) {
+ return \HebrewParseTrainer\Stem::all();
+});
+
+$app->get('/tense', function () use ($app) {
+ return \HebrewParseTrainer\Tense::all();
+});
+
+$app->get('/verb/random', 'RandomVerbController@show');
diff --git a/public/audio/negative.wav b/public/audio/negative.wav
new file mode 100644
index 0000000..8718ca9
--- /dev/null
+++ b/public/audio/negative.wav
Binary files differ
diff --git a/public/audio/positive.wav b/public/audio/positive.wav
new file mode 100644
index 0000000..ea09f84
--- /dev/null
+++ b/public/audio/positive.wav
Binary files differ
diff --git a/public/css/hebrewparsetrainer.css b/public/css/hebrewparsetrainer.css
new file mode 100644
index 0000000..eb4e5bf
--- /dev/null
+++ b/public/css/hebrewparsetrainer.css
@@ -0,0 +1,12 @@
+#trainer-404 {
+ display: none;
+ padding: 15px;
+}
+
+.hebrew {
+ font-family: 'Ezra SIL', David;
+}
+
+.hebrew-large {
+ font-size: 40px;
+} \ No newline at end of file
diff --git a/public/js/hebrewparsetrainer.js b/public/js/hebrewparsetrainer.js
new file mode 100644
index 0000000..d583fa7
--- /dev/null
+++ b/public/js/hebrewparsetrainer.js
@@ -0,0 +1,189 @@
+/**
+ * Created by camil on 1/4/16.
+ */
+$(document).ready(function(){
+ var audio_positive = new Audio('/public/audio/positive.wav');
+ var audio_negative = new Audio('/public/audio/negative.wav');
+
+ var correct_answer;
+
+ function reloadVerb() {
+ $('#trainer-404').hide();
+ $('#trainer-verb').css({color: 'gray'});
+ $('#trainer-answer').text('');
+
+ 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).css({color: 'black'});
+ correct_answer = {
+ stem: data.stem,
+ tense: data.tense,
+ person: data.person,
+ gender: data.gender,
+ number: data.number
+ };
+ }
+ });
+ }
+
+ 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'];
+ var numbers = ['s', 'p'];
+
+ var re = /^\s*(\w+)\s+(\w+)\s+(?:([123])\s*)?([mfc])\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];
+ var number = match[5];
+
+ if (typeof stem === 'undefined' || typeof tense === 'undefined' || $.inArray(person, persons) == -1 ||
+ !$.inArray(gender, genders) == -1 || !$.inArray(number, numbers) == -1)
+ 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',
+ 'c': 'communis generis'
+ };
+ var numbers = {
+ 's': 'singular',
+ 'p': 'plural'
+ };
+ if (extended === true) {
+ return parsing.stem + ' ' + parsing.tense + ' ' + parsing.person +
+ ' ' + genders[parsing.gender] + ' ' + numbers[parsing.number];
+ } else {
+ return parsing.stem + ' ' + parsing.tense + ' ' + parsing.person + ' ' + parsing.gender + ' ' + parsing.number;
+ }
+ }
+
+ function processInput() {
+ var input = $('#trainer-input');
+ var answer = parseAnswer(input.val());
+ if (answer === false) {
+ input.parent().addClass('has-error');
+ $('#trainer-parsed').val('Parsing error');
+ } else {
+ input.parent().removeClass('has-error');
+ $('#trainer-parsed').val(parsingToString(answer, true));
+ }
+ return answer;
+ }
+
+ function checkInput() {
+ var answer = processInput();
+ if (JSON.stringify(answer) == JSON.stringify(correct_answer)) {
+ $('#trainer-input')
+ .css({backgroundColor: '#dff0d8'})
+ .parent().addClass('has-success');
+ if ($('#settings-audio').prop('checked')) audio_positive.play();
+ } else {
+ $('#trainer-input')
+ .css({backgroundColor: '#f2dede'})
+ .parent().addClass('has-error');
+ if ($('#settings-audio').prop('checked')) audio_negative.play();
+ $('#trainer-answer').text(' - ' + parsingToString(correct_answer));
+ }
+ }
+
+ 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();
+
+ $('#trainer-input').focus();
+ }
+
+ $('#hebrewparsetrainer-settings input.reload-verb').change(function(){
+ reloadVerb();
+ });
+
+ var checked = false;
+ $('#trainer-input').keyup(function(e){
+ if (e.keyCode == 13) {
+ if (!checked) {
+ checkInput();
+ checked = true;
+ } 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();
+ }
+ });
+
+ init();
+}); \ No newline at end of file
diff --git a/resources/views/trainer.php b/resources/views/trainer.php
new file mode 100644
index 0000000..a989750
--- /dev/null
+++ b/resources/views/trainer.php
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>HebrewParseTrainer</title>
+ <link rel="stylesheet" href="/vendor/twbs/bootstrap/dist/css/bootstrap.min.css">
+ <link rel="stylesheet" href="/vendor/twbs/bootstrap/dist/css/bootstrap-theme.min.css">
+ <link rel="stylesheet" href="/public/css/hebrewparsetrainer.css">
+ </head>
+ <body role="application">
+ <div class="container" role="main">
+ <div class="page-header">
+ <h1>HebrewParseTrainer</h1>
+ </div>
+
+ <div class="row">
+ <div class="col-md-2 col-sm-4">
+ <form id="hebrewparsetrainer-settings">
+ <div class="form-group">
+ <h3>Stems</h3>
+ <?php foreach (\HebrewParseTrainer\Stem::all() as $stem){ $stem = $stem->name; ?>
+ <div class="checkbox">
+ <label><input class="reload-verb" type="checkbox" name="stem" value="<?=$stem?>" checked="checked"/> <?=$stem?></label>
+ </div>
+ <?php } ?>
+ </div>
+
+ <div class="form-group">
+ <h3>Tenses</h3>
+ <?php foreach (\HebrewParseTrainer\Tense::all() as $tense){ $tense = $tense->name; ?>
+ <div class="checkbox">
+ <label><input class="reload-verb" type="checkbox" name="tense" value="<?=$tense?>" checked="checked"/> <?=$tense?></label>
+ </div>
+ <?php } ?>
+ </div>
+
+ <div class="form-group">
+ <h3>Roots</h3>
+ <?php foreach (\HebrewParseTrainer\Root::all() as $root){ $root = $root->root; ?>
+ <div class="checkbox">
+ <label class="hebrew"><input class="reload-verb" type="checkbox" name="root" value="<?=$root?>" checked="checked"/> <?=$root?></label>
+ </div>
+ <?php } ?>
+ </div>
+
+ <div class="form-group">
+ <h3>Settings</h3>
+ <div class="checkbox">
+ <label><input type="checkbox" id="settings-audio" checked="checked"/> Audio</label>
+ </div>
+ </div>
+ </form>
+ </div>
+ <div class="col-md-10 col-sm-8">
+ <p class="bg-danger" id="trainer-404">There are no verbs matching the criteria in our database.</p>
+ <p class="lead"><span class="hebrew hebrew-large" id="trainer-verb"></span><span id="trainer-answer"></span></p>
+ <div class="row">
+ <div class="col-md-8">
+ <div class="form-group">
+ <label for="trainer-input">Parse:</label>
+ <input type="text" class="form-control" id="trainer-input" placeholder="Q pf 3 m s"/>
+ </div>
+ </div>
+ <div class="col-md-4">
+ <div class="form-group">
+ <label for="trainer-parsed">Interpreted as:</label>
+ <input type="text" class="form-control" id="trainer-parsed" readonly="readonly"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <script src="/vendor/components/jquery/jquery.min.js"></script>
+ <script src="/vendor/twbs/bootstrap/dist/js/bootstrap.min.js"></script>
+ <script src="/public/js/hebrewparsetrainer.js"></script>
+ </body>
+</html> \ No newline at end of file