diff options
| author | Camil Staps | 2016-01-04 23:20:50 +0100 | 
|---|---|---|
| committer | Camil Staps | 2016-01-04 23:20:50 +0100 | 
| commit | 7a93b44c6cb2f1e1f335d93ddf62a149ebd5f1d9 (patch) | |
| tree | ea606ac400db5aced2a83f65efa247372ad164d5 | |
| parent | Models, migrations and seeds for root, roottranslation, stem, tense, verb (diff) | |
Training app
| -rw-r--r-- | app/Http/Controllers/RandomVerbController.php | 30 | ||||
| -rw-r--r-- | app/Http/routes.php | 12 | ||||
| -rw-r--r-- | public/audio/negative.wav | bin | 0 -> 216736 bytes | |||
| -rw-r--r-- | public/audio/positive.wav | bin | 0 -> 151198 bytes | |||
| -rw-r--r-- | public/css/hebrewparsetrainer.css | 12 | ||||
| -rw-r--r-- | public/js/hebrewparsetrainer.js | 189 | ||||
| -rw-r--r-- | resources/views/trainer.php | 79 | 
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.wavBinary files differ new file mode 100644 index 0000000..8718ca9 --- /dev/null +++ b/public/audio/negative.wav diff --git a/public/audio/positive.wav b/public/audio/positive.wavBinary files differ new file mode 100644 index 0000000..ea09f84 --- /dev/null +++ b/public/audio/positive.wav 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 | 
