From 051b7b0d21ad8ac1fe42dfd09cd773b48b8fd8ea Mon Sep 17 00:00:00 2001 From: "john.j.camilleri" Date: Wed, 21 Nov 2012 11:22:35 +0000 Subject: [PATCH] Syntax editor: start with initial grammar, startcat, to: languages --- src/www/syntax-editor/README.md | 27 +++++- src/www/syntax-editor/editor.js | 43 ++++++--- src/www/syntax-editor/editor_menu.js | 132 ++++++++++++++------------- 3 files changed, 122 insertions(+), 80 deletions(-) diff --git a/src/www/syntax-editor/README.md b/src/www/syntax-editor/README.md index dec633476..5da1f507f 100644 --- a/src/www/syntax-editor/README.md +++ b/src/www/syntax-editor/README.md @@ -11,8 +11,30 @@ An improved version of the [old syntax editor][1]. - Tested with latest Chrome and Firefox (only). +## Available startup options + + var editor_options = { + target: "editor", + initial: { + grammar: "http://localhost:41296/grammars/Foods.pgf", + startcat: "Kind", + languages: ["Eng","Swe","Mlt"], + ast: null, + node_id: null + }, + show: { + grammar_menu: true, + startcat_menu: true, + to_menu: true, + random_button: true + } + } + ## TODO +- Link to jump into minibar +- Start with initial grammar, startcat, ast +- Compatibility with grammars with dependent category types - Clicking on tokens to select tree node - Use local caching - Enter string/float/int literals @@ -21,10 +43,7 @@ An improved version of the [old syntax editor][1]. - ambiguity: (optionally) parse all the resulting linearizations/variants and point out those which are ambiguous - try to retain subtree when replacing node - add undo/redo (or back/forward) navigation -- structure the set of fridge magnets some more. Even though they -are alphabetically sorted, it's difficult to find the one that I want, -maybe put a newline before the magnet whose first letter is different -with respect to the previous magnet +- structure fridge magnets some more (eg newline before the magnet whose first letter is different) - The formal-looking funs and cats are not linked/aligned to the linearizations. Maybe a possible UI could be where the user is clicking on the linearization (in a chosen language) and the tree is diff --git a/src/www/syntax-editor/editor.js b/src/www/syntax-editor/editor.js index 33b8b496c..9fa7ad737 100644 --- a/src/www/syntax-editor/editor.js +++ b/src/www/syntax-editor/editor.js @@ -13,7 +13,20 @@ function Editor(server,opts) { // default values for options: this.options={ - target: "editor" + target: "editor", + initial: { + grammar: null, + startcat: null, + languages: null, + ast: null, + node_id: null + }, + show: { + grammar_menu: true, + startcat_menu: true, + to_menu: true, + random_button: true + } } // Apply supplied options @@ -35,11 +48,14 @@ function Editor(server,opts) { this.server = server; this.ast = null; this.grammar = null; + this.startcat = null; this.languages = []; - this.local = {}; // local settings which may override grammar /* --- Main program, this gets things going ----------------------------- */ - this.menu = new EditorMenu(this); + this.menu = new EditorMenu(this, this.options); + + /* --- Apply supplied initial settings (if any) ------------------------- */ +// if (this.options.initial.grammar) } @@ -65,24 +81,25 @@ Editor.prototype.get_ast=function() { } Editor.prototype.get_startcat=function() { - return this.local.startcat || this.grammar.startcat; + return this.startcat || this.grammar.startcat; } /* --- These get called from EditorMenu, or some custom code */ Editor.prototype.change_grammar=function(grammar_info) { - with(this) { - grammar = grammar_info; - local.startcat = null; - get_grammar_constructors(bind(start_fresh,this)); - } + var t = this; + t.grammar = grammar_info; + var startcat0 = t.options.initial.startcat + if (elem(startcat0, grammar_info.categories)) + t.startcat = startcat0; + else + t.startcat = null; + t.get_grammar_constructors(bind(t.start_fresh,t)); } Editor.prototype.change_startcat=function(startcat) { - with(this) { - local.startcat = startcat; - start_fresh(); - } + this.startcat = startcat; + this.start_fresh(); } // Called after changing grammar or startcat diff --git a/src/www/syntax-editor/editor_menu.js b/src/www/syntax-editor/editor_menu.js index ded47f54e..e8d39ae37 100644 --- a/src/www/syntax-editor/editor_menu.js +++ b/src/www/syntax-editor/editor_menu.js @@ -14,8 +14,9 @@ function EditorMenu(editor,opts) { /* --- Creating UI components ------------------------------------------- */ this.container = editor.ui.menubar; this.ui = { + grammar_menu: empty_id("select","grammar_menu"), startcat_menu: empty("select"), - to_toggle: button("...", function(){ + to_toggle: button("Languages...", function(){ var sel = t.ui.to_menu; if (sel.classList.contains("hidden")) sel.classList.remove("hidden") @@ -35,12 +36,22 @@ function EditorMenu(editor,opts) { }), }; with(this.ui) { - appendChildren(this.container, [text(" Startcat: "),startcat_menu]); - appendChildren(this.container, [text(" To: "), to_toggle, to_menu]); - appendChildren(this.container, [clear_button, random_button]); - // appendChildren(this.container, [clear_button]); - startcat_menu.onchange=bind(this.change_startcat,this); - to_menu.onchange=bind(this.change_language,this); + if (this.options.show.grammar_menu) { + appendChildren(this.container, [text(" Grammar: "), grammar_menu]); + grammar_menu.onchange = bind(this.change_grammar,this); + } + if (this.options.show.startcat_menu) { + appendChildren(this.container, [text(" Startcat: "), startcat_menu]); + startcat_menu.onchange = bind(this.change_startcat,this); + } + if (this.options.show.to_menu) { + appendChildren(this.container, [text(" To: "), to_toggle, to_menu]); + to_menu.onchange = bind(this.change_language,this); + } + appendChildren(this.container, [clear_button]); + if (this.options.show.random_button) { + appendChildren(this.container, [random_button]); + } } /* --- Client state initialisation -------------------------------------- */ @@ -53,12 +64,14 @@ function EditorMenu(editor,opts) { } } +/* --- Grammar menu --------------------------------------------------------- */ + +// Basically called once, when initializing // Copied from minibar.js EditorMenu.prototype.show_grammarlist=function(dir,grammar_names,dir_count) { var t=this; - var first_time= !t.grammar_menu + var first_time=t.ui.grammar_menu.options.length == 0; if(first_time) { - t.grammar_menu=empty_id("select","grammar_menu"); t.grammars=[]; t.grammar_dirs=[]; } @@ -70,29 +83,12 @@ EditorMenu.prototype.show_grammarlist=function(dir,grammar_names,dir_count) { } function opt(g) { return option(glabel(g),dir+g); } appendChildren(grammar_menu,map(opt,grammar_names)); - function pick() { - var grammar_url=grammar_menu.value - if(window.localStorage) - localStorage["gf.minibar.last_grammar"]=grammar_url; - t.select_grammar(grammar_url); - } function pick_first_grammar() { if(t.timeout) clearTimeout(t.timeout),t.timeout=null; - if(t.grammar_menu.length>1 && !t.grammar_menu.parentElement) { - t.grammar_menu.onchange=pick; -// insertFirst(t.menubar,button("i",bind(t.show_grammarinfo,t))) - insertFirst(t.container,t.grammar_menu); - insertFirst(t.container,text("Grammar: ")); - } - var grammar0=t.options.initial_grammar - if(!grammar0 && window.localStorage) { - var last_grammar=localStorage["gf.minibar.last_grammar"]; - if(last_grammar && elem(last_grammar,t.grammars)) - grammar0=last_grammar; - } + var grammar0=t.options.initial.grammar; if(!grammar0) grammar0=t.grammars[0]; - t.grammar_menu.value=grammar0; - t.select_grammar(grammar0); + t.ui.grammar_menu.value=grammar0; + t.change_grammar(); } // Wait at most 1.5s before showing the grammar menu. if(first_time) t.timeout=setTimeout(pick_first_grammar,1500); @@ -101,9 +97,9 @@ EditorMenu.prototype.show_grammarlist=function(dir,grammar_names,dir_count) { } // Copied from minibar.js -EditorMenu.prototype.select_grammar=function(grammar_url) { +EditorMenu.prototype.change_grammar=function() { var t=this; - //debug("select_grammar "); + var grammar_url = t.ui.grammar_menu.value; t.server.switch_to_other_grammar(grammar_url, function() { t.server.grammar_info(function(grammar){ t.update_language_menu(t.ui.to_menu, grammar); @@ -115,29 +111,63 @@ EditorMenu.prototype.select_grammar=function(grammar_url) { }); } +/* --- Start category menu -------------------------------------------------- */ + +// Called each time the current grammar is changed! // Copied from minibar_input.js EditorMenu.prototype.update_startcat_menu=function(grammar) { + var t=this; var menu=this.ui.startcat_menu; menu.innerHTML=""; var cats=grammar.categories; for(var cat in cats) menu.appendChild(option(cats[cat],cats[cat])) // var startcat=this.local.get("startcat") || grammar.startcat; - var startcat= grammar.startcat; - if(startcat) menu.value=startcat; - else { - insertFirst(menu,option("Default","")); - menu.value=""; - } + var startcat0 = t.options.initial.startcat; + if (elem(startcat0, cats)) + menu.value = startcat0; + else + menu.value = grammar.startcat; + // else { + // insertFirst(menu,option("Default","")); + // menu.value=""; + // } } // -EditorMenu.prototype.change_startcat=function () { +EditorMenu.prototype.change_startcat=function() { var new_startcat = this.ui.startcat_menu.value; this.editor.change_startcat(new_startcat); } +/* --- Langugage (to) menu -------------------------------------------------- */ + +// Called each time the current grammar is changed! +// Copied from minibar_support.js +EditorMenu.prototype.update_language_menu=function(menu,grammar) { + var t = this; + function langpart(conc,abs) { // langpart("FoodsEng","Foods") == "Eng" + return hasPrefix(conc,abs) ? conc.substr(abs.length) : conc; + } + // Replace the options in the menu with the languages in the grammar + var langs=grammar.languages; + menu.innerHTML=""; + + for(var i=0; i