summaryrefslogtreecommitdiff
path: root/src/editor
diff options
context:
space:
mode:
authorhallgren <hallgren@chalmers.se>2011-10-12 17:03:54 +0000
committerhallgren <hallgren@chalmers.se>2011-10-12 17:03:54 +0000
commit44d1a5a9f71b03d9aceeccd760a63fcdc45f8bad (patch)
treed51076a708997d6f1af6ac0deefd535bbc25f804 /src/editor
parent0aba45560d2033c37c3d2e876e6f3ef89e1554d6 (diff)
Improvements of "gf -server" mode and related setup
"gf -server" mode now contains everything needed to run the minibar and the grammar editor (including example-based grammar writing). The Setup.hs script installs the required files where gf -server can find them. These files have been moved to a new directory: src/www. The separate server program pgf-http is now obsolete.
Diffstat (limited to 'src/editor')
-rw-r--r--src/editor/simple/Makefile7
-rw-r--r--src/editor/simple/P/1306856253_weather_06.pngbin2311 -> 0 bytes
-rw-r--r--src/editor/simple/P/1307545089_weather_04.pngbin2376 -> 0 bytes
-rw-r--r--src/editor/simple/P/w1s.jpgbin26163 -> 0 bytes
-rw-r--r--src/editor/simple/P/w2s.jpgbin25953 -> 0 bytes
-rw-r--r--src/editor/simple/P/w3s.jpgbin29664 -> 0 bytes
-rw-r--r--src/editor/simple/P/w4s.jpgbin22005 -> 0 bytes
-rw-r--r--src/editor/simple/TODO43
-rw-r--r--src/editor/simple/about.html243
-rw-r--r--src/editor/simple/cloud.js148
-rw-r--r--src/editor/simple/cloud2.js159
-rw-r--r--src/editor/simple/editor.css88
-rw-r--r--src/editor/simple/editor.js1114
-rw-r--r--src/editor/simple/example_based.js158
-rw-r--r--src/editor/simple/gf_abs.js226
-rw-r--r--src/editor/simple/gfse.manifest4
-rw-r--r--src/editor/simple/grammars.cgi19
-rw-r--r--src/editor/simple/index.html48
-rw-r--r--src/editor/simple/localstorage.js21
-rw-r--r--src/editor/simple/molto.css82
-rw-r--r--src/editor/simple/save.hs25
-rw-r--r--src/editor/simple/share.html27
-rw-r--r--src/editor/simple/slideshow.js86
-rw-r--r--src/editor/simple/upload.cgi252
24 files changed, 0 insertions, 2750 deletions
diff --git a/src/editor/simple/Makefile b/src/editor/simple/Makefile
deleted file mode 100644
index 00a97b337..000000000
--- a/src/editor/simple/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-
-save: save.hs
- ghc --make save.hs
-
-install::
- @make save
- rsync -avz --exclude .DS_Store P *.html *.css *.js ../../runtime/javascript/minibar/support.js *.cgi *.manifest save www.grammaticalframework.org:/usr/local/www/GF/demos/gfse
diff --git a/src/editor/simple/P/1306856253_weather_06.png b/src/editor/simple/P/1306856253_weather_06.png
deleted file mode 100644
index 3f01afcaa..000000000
--- a/src/editor/simple/P/1306856253_weather_06.png
+++ /dev/null
Binary files differ
diff --git a/src/editor/simple/P/1307545089_weather_04.png b/src/editor/simple/P/1307545089_weather_04.png
deleted file mode 100644
index 8a7f1e3ae..000000000
--- a/src/editor/simple/P/1307545089_weather_04.png
+++ /dev/null
Binary files differ
diff --git a/src/editor/simple/P/w1s.jpg b/src/editor/simple/P/w1s.jpg
deleted file mode 100644
index 199fcb7ba..000000000
--- a/src/editor/simple/P/w1s.jpg
+++ /dev/null
Binary files differ
diff --git a/src/editor/simple/P/w2s.jpg b/src/editor/simple/P/w2s.jpg
deleted file mode 100644
index 9673758c0..000000000
--- a/src/editor/simple/P/w2s.jpg
+++ /dev/null
Binary files differ
diff --git a/src/editor/simple/P/w3s.jpg b/src/editor/simple/P/w3s.jpg
deleted file mode 100644
index 1a8680ec7..000000000
--- a/src/editor/simple/P/w3s.jpg
+++ /dev/null
Binary files differ
diff --git a/src/editor/simple/P/w4s.jpg b/src/editor/simple/P/w4s.jpg
deleted file mode 100644
index 5c685c134..000000000
--- a/src/editor/simple/P/w4s.jpg
+++ /dev/null
Binary files differ
diff --git a/src/editor/simple/TODO b/src/editor/simple/TODO
deleted file mode 100644
index 22974ebe0..000000000
--- a/src/editor/simple/TODO
+++ /dev/null
@@ -1,43 +0,0 @@
-+ Safety question before deleting a grammar
-+ Check identifier syntax
-+ Allow lincat for deleted cat to be deleted
-+ Allow lin for deleted fun to be deleted
-+ Apply category alpha conversion in concrete syntax
-+ Remove a concrete syntax
-+ Apply function alpha conversion in concrete syntax
-+ Change lhs of lins when function type is changed
-
-+ Allow languages other than the ones in the given list to be added
-+ Export as plain text
-+ Allow definitions to be reordered
-
-+ 1. possibility to compile the grammar set, returning a URL to a translator app
-+ 2a. possibility to import modules - resource libraries
-- 2b. possibility to import modules - user's own auxiliaries
-- 3. possibility to upload own modules
-+ 4. access to the created files in an on-line shell (making testing possible)
-- 5. rule-to-rule type checking and guidance (e.g. with library oper
- suggestions)
-+ Try grammars in the Translation Quiz
-+ Show lincat and lin before params and opers below
-+ Create a new concrete syntax by copying an existing one.
-- Easy access to compute_concrete from the editor
-- Instead of starting with an empty grammar, start a new grammar by copying
- an example.
-+ Cloning grammars
-- Allow grammars to contain a resoure module. Create the resource module by
- factoring out common parts of the concrete syntaxes.
-- Integrate example-based concrete syntax construction (using Ramona's tool)
-- Open lexicon modules? They are not installed by default!
- DictEng, MorphalouFre, DictSwe, DictTur, DictBul, DictFun, DictLav
-
-+ compile only the uploaded grammar even if other grammars are present
-+ 'flags startcat' is needed for grammars with only one category (since the
- default startcat is S, even if it doesn't exist)
-
-- Bug! After adding a 2nd def of a fun with a different type and then deleting
- the old fun, the corresponding lin will have the wrong lhs.
-
-+ Bug! The startcat menu shows the first category by default, but the startcat
- flag is actually not set until a selection is made from the menu.
-
diff --git a/src/editor/simple/about.html b/src/editor/simple/about.html
deleted file mode 100644
index 8660621a3..000000000
--- a/src/editor/simple/about.html
+++ /dev/null
@@ -1,243 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>About: GF online editor for simple multilingual grammars</title>
-<link rel="stylesheet" type="text/css" href="editor.css" title="Cloud">
-<link rel="alternate stylesheet" type="text/css" href="molto.css" title="MOLTO">
-
-<link rel=author href="http://www.cse.chalmers.se/~hallgren/" title="Thomas Hallgren">
-
-<meta name = "viewport" content = "width = device-width">
-<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
-<meta charset="UTF-8">
-
-<script type="text/javascript" src="slideshow.js"></script>
-
-</head>
-
-<body>
-<h1>GF online editor for simple multilingual grammars</h1>
-
-<div class=right>
- <div class=slideshow>
- <img onload="start_slideshow(this,{delay:5,fade:0.3})" src="P/w1s.jpg" alt="[GF online editor screen shoot]">
- <img class=hidden src="P/w2s.jpg" alt="[GF online editor screen shoot]">
- <img class=hidden src="P/w3s.jpg" alt="[GF online editor screen shoot]">
- <img class=hidden src="P/w4s.jpg" alt="[GF online editor screen shoot]">
- </div>
-</div>
-<h2>Introduction</h2>
-
-Traditionally, <a href="http://www.grammaticalframework.org/">GF</a>
-grammars are created in a text editor and tested in the
-GF shell. Text editors know very little (if anything) about the syntax of
-GF grammars, and thus provide little guidance for novice GF users. Also, the
-grammar author has to download and install the GF software on his/her own
-computer.
-
-<p>
-In contrast, the
-<a href="."><em>GF online editor for simple multilingual grammars</em></a>
-is available online, making it easier to get started. All that
-is needed is a reasonably modern web browser. Even Android and iOS devices
-can be used.
-<p>
-The editor
-also guides the grammar author by showing a skeleton grammar file and
-hinting how the parts should be filled in. When a new part is added to the
-grammar, it is immediately checked for errors.
-
-<p>
-Editing operations are accessed by clicking on editing symbols embedded
-in the grammar display:
-<span class=more>+</span>=Add an item,
-<span class=delete>×</span>=Delete an item,
-<span class=edit>%</span>=Edit an item.
-These are revealed when hovering over items. On touch devices, hovering is
-in some cases simulated by tapping, but there is also a button at the bottom
-of the display to "Enable editing on touch devices" that reveals all editing
-symbols.
-
-<p>
-In spite of its name, the editor runs entierly in the web
-browser, so once you have opened the web page, you can
-<strong>continue editing</strong> grammars even while you are
-<strong>offline</strong>.
-
-<h3>Current status</h3>
-
-<p>
-At the moment, the editor supports only a small subset of the GF grammar
-notation.
-Proper error checking is done for abstract syntax, but not (yet) for concrete
-syntax.
-
-<p>
-The grammars created with this editor always consists of one file for the
-abstract syntax, and one file for each concrete syntax.
-
-<h4>Abstract syntax</h4>
-
-The supported abstract syntax corresponds to context-free grammars
-(no dependent types). The definition of an abstract syntax is limited to
-<ul>
- <li>a list of <em>category names</em>,
- <var>Cat<sub>1</sub></var> ; ... ; <var>Cat<sub>n</sub></var>,
- <li>a list of <em>functions</em> of the form
- <var>Fun</var> : <var>Cat<sub>1</sub></var> -> ... ->
- <var>Cat<sub>n</sub></var>,
- <li>and a <em>start category</em>.
-</ul>
-
-Available editing operations:
-<ul>
- <li>Categories can be added, removed and renamed. When renaming a category,
- occurences of it in function types will be updated accordingly.
- <li>Functions can be added, removed and edited. Concrete syntaxes are updated
- to reflect changes.
- <li>Functions can be reordered using drag-and-drop.
-</ul>
-
-Error checks:
-
-<ul>
- <li>Syntactically incorrect function definitions are refused.
- <li>Semantic problem such as duplicated definitions or references to
- undefined categories, are highlighted.
-</ul>
-
-<h4>Concrete syntax</h4>
-
-At the moment, the concrete syntax for a language <var>L</var> is limited to
-<ul>
- <li>opening the Resource Grammar Library modules
- <code>Syntax</code><var>L</var> and <code>Paradigms</code><var>L</var>,
- <code>Lexicon</code><var>L</var> and <code>Extra</code><var>L</var>,
- <li><em>linearization types</em> for the categories in the abstract syntax,
- <li><em>linearizations</em> for the functions in the abstract syntax,
- <li><em>parameter type definitions</em>,
- <var>P</var> = <var>C<sub>1</sub></var> | ... |<var>C<sub>n</sub></var>,
- <li>and <em>operation definitions</em>, <var>op</var> = <var>expr</var>,
- <var>op</var> : <var>type</var> = <var>expr</var>,
-</ul>
-
-Available editing operations:
-<ul>
- <li>The LHSs of the linearization types and linearizations are determined by
- the abstract syntax and do not need to be entered manually.
- The RHSs can
- be edited.
- <li>Parameter types can be added, removed and edited.
- <li>Operation definitons can be added, removed and edited.
- <li>Definitions can be reordered (using drag-and-drop)
-</ul>
-Also,
-
-<ul>
- <li>When a new concrete syntax is added to the grammar, a copy of the
- currently open concrete syntax is created, since copying and modifying
- is usually easier than creating something new from scratch.
- (If the abstract syntax is currently open, the new conrete syntax will
- start out empty.)
- <li>When adding a new concrete syntax, you normally pick one of the supported
- languages from a list. The language code and the file name is determined
- automatically. But you can also pick <em>Other</em> from the list and change
- the language code afterwards to add a concrete syntax for a language
- that is not in the list.
-</ul>
-
-Error checks:
-<ul>
- <li>The RHSs in the concrete syntax are checked
- for syntactic correctness by the editor as they are entered.
- (TODO: the syntax of parameter types is not check at the moment.)
- <li>Duplicated definitions are highlighted. Checks for other
- semantic errors are delayed until the grammar is compiled.
-</ul>
-
-<h3>Compiling and testing grammars</h3>
-
-When pressing the <strong>Compile</strong> button, the grammar will be compiled
-with GF, and any errors not detected by the editor will be reported.
-If the grammar is free from errors the user can then
-test the grammar by clicking on links to the online GF shell, the Minibar or
-the Translation Quiz.
-
-<h3><img class=right src="P/1307545089_weather_04.png" alt="">
-<img class=right src="P/1306856253_weather_06.png" alt="">Grammars in the
-cloud</h3>
-
-While the editor normally stores grammars locally in the browser, it is also
-possible to store grammars in the cloud. Grammars can be stored in the cloud
-just for backup, or to make them accessible from multiple devices.
-
-<p>
-There is no automatic synchronization between local grammars and the cloud.
-Instead, the user should press
-<img src="P/1306856253_weather_06.png" alt="[Cloud Upload]">
-to upload the grammars to the cloud, and press
-<img src="P/1307545089_weather_04.png" alt="[Cloud download]">
-to download grammars from the cloud. In both cases, complete grammars
-are copied and older versions at the destination will be overwritten.
-When a grammar is deleted, both the local copy and the copy in the cloud
-is deleted.
-
-<p>
-Each device is initially assigned to its own unique cloud. Each device can thus
-have its own set of grammars that are not available on other devices. It is
-also possible to merge clouds and share a common set of grammars between
-multiple devices: when uploading grammars to the cloud, a link to this grammar
-cloud appears. Accessing this link from another device will cause the clouds of
-the two devices to be merged. After this, grammars uploaded from one of the
-devices can be downloaded on the other devices. Any number devices can join the
-same grammar cloud in this way.
-
-<p>
-<strong>Note</strong> that while it is possible to copy grammars between
-multiple devices, there is no way to merge concurrent edits from multiple
-devices. If the same grammar is uploaded to the
-cloud from multiple devices, the last upload wins. Thus the current
-implementation is suitable for a single user switching between different
-devices, but not recommended for sharing grammars between multiple users.
-
-<p>
-Also <strong>note</strong> that each grammar is assigned a unique identity
-when it is first created. Renaming a grammar does not change its identity.
-This means that name changes are propagated between devices like other changes.
-
-<h3>Example-based grammar writing</h3>
-
-This is work in progress...
-
-<h3>Future work</h3>
-
-This prototype gives an idea of how a web based GF grammar editor could work.
-While this editor is implemented in JavaScript and runs in the web browser,
-we do not expect to create a full implementation of GF that runs in the
-web browser, but let the editor communicate with a server running GF.
-<p>
-By developing a GF server with an appropriate API, it should
-be possible to extend the editor to support a larger fragment of GF,
-to do proper error checking and make more of the existing GF shell functionality
-accessible directly from the editor.
-<p>
-The current grammar cloud service is very primitive. In particular, it is not
-suitable for multiple users developing a grammar in collaboration.
-
-<h3>Related documents</h3>
-<ul>
- <li><a href="http://www.grammaticalframework.org/~hallgren/Talks/GF/gf-ide.html">GF Grammar Development Tools</a>. Slides from a presentation at the MOLTO meeting in Göteborg, March 2011.
- <li><a href="http://www.grammaticalframework.org/grammar-ide/">The GF Grammar IDE</a>. MOLTO deliverable.
- <li><a href="http://www.grammaticalframework.org/compiler-api">The GF Grammar
- Compiler API</a>. MOLTO deliverable.
-</ul>
-
-<hr>
-<div class=modtime><small>
-<!-- hhmts start --> Last modified: Fri Oct 7 14:06:14 CEST 2011 <!-- hhmts end -->
- </small></div>
-<address>
-<a href="http://www.cse.chalmers.se/~hallgren/">TH</a>
-<img src="http://www.altocumulus.org/~hallgren/online.cgi?icon" alt="">
-</address>
-</body> </html>
diff --git a/src/editor/simple/cloud.js b/src/editor/simple/cloud.js
deleted file mode 100644
index f19b6ee37..000000000
--- a/src/editor/simple/cloud.js
+++ /dev/null
@@ -1,148 +0,0 @@
-
-function with_dir(cont) {
- var dir=local.get("dir","");
- if(dir) cont(dir);
- else ajax_http_get("upload.cgi?dir",
- function(dir) {
- local.put("dir",dir);
- cont(dir);
- });
-}
-
-function remove_cloud_grammar(g) {
- var dir=local.get("dir")
- if(dir && g.unique_name) {
- var path=dir+"/"+g.unique_name+".json"
- ajax_http_get("upload.cgi?rm="+encodeURIComponent(path),debug);
- }
-}
-
-// Upload the grammar to the server and check it for errors
-function upload(g) {
- function upload2(dir) {
- var form=node("form",{method:"post",action:"upload.cgi"+dir},
- [hidden(g.basename+".gf",show_abstract(g))])
- for(var i in g.concretes)
- form.appendChild(hidden(g.basename+g.concretes[i].langcode+".gf",
- show_concrete(g.basename)(g.concretes[i])));
- editor.appendChild(form);
- form.submit();
- form.parentNode.removeChild(form);
- }
-
- with_dir(upload2);
-}
-
-// Upload the grammar to store it in the cloud
-function upload_json(cont) {
- function upload3(resptext,status) {
- local.put("json_uploaded",Date.now());
- //debug("Upload complete")
- if(cont) cont();
- else {
- var sharing=element("sharing");
- if(sharing) sharing.innerHTML=resptext;
- }
- }
- function upload2(dir) {
- var prefix=dir.substr(10)+"-" // skip "/tmp/gfse."
- //debug("New form data");
- //var form=new FormData(); // !!! Doesn't work on Android 2.2!
- var form="",sep="";
- //debug("Preparing form data");
- for(var i=0;i<local.count;i++) {
- var g=local.get(i,null);
- if(g) {
- if(!g.unique_name) {
- g.unique_name=prefix+i;
- save_grammar(g)
- }
- //form.append(g.unique_name+".json",JSON.stringify(g));
- form+=sep+encodeURIComponent(g.unique_name+".json")+"="+
- encodeURIComponent(JSON.stringify(g))
- sep="&"
- }
- }
- //debug("Upload to "+prefix);
- ajax_http_post("upload.cgi"+dir,form,upload3,cont)
- }
-
- with_dir(upload2);
-}
-
-function download_json() {
- var dir=local.get("dir");
- var index=grammar_index();
- var downloading=0;
-
- function get_list(ok,err) {
- ajax_http_get("upload.cgi?ls="+dir,ok,err);
- }
-
- function get_file(file,ok,err) {
- downloading++;
- ajax_http_get("upload.cgi?download="+encodeURIComponent(dir+"/"+file),ok,err);
- }
-
- function file_failed(errormsg,status) {
- debug(errormsg)
- downloading--;
- }
- function file_downloaded(grammar) {
- downloading--;
- var newg=JSON.parse(grammar);
- debug("Downloaded "+newg.unique_name)
- var i=index[newg.unique_name];
- if(i!=undefined) merge_grammar(i,newg)
- else {
- debug("New")
- newg.index=null;
- save_grammar(newg);
- }
- if(downloading==0) done()
- }
-
- function done() {
- setTimeout(function(){location.href="."},2000);
- }
-
- function download_files(ls) {
- local.put("current",0);
- if(ls) {
- //debug("Downloading "+ls);
- var files=ls.split(" ");
- cleanup_deleted(files);
- for(var i in files) get_file(files[i],file_downloaded,file_failed);
- }
- else {
- debug("No grammars in the cloud")
- done()
- }
- }
-
- get_list(download_files);
-}
-
-function link_directories(newdir,cont) {
- with_dir(function(olddir) {
- ajax_http_get("upload.cgi?rmdir="+olddir+"&newdir="+newdir,cont)
- })
-}
-
-/* -------------------------------------------------------------------------- */
-
-// Send a command to the GF shell
-function gfshell(cmd,cont) {
- alert("gfshell(...) not implmemented!!!")
-}
-
-// Check the syntax of an expression
-function check_exp(s,cont) {
- function check(gf_message) {
- //debug("cc "+s+" = "+gf_message);
- cont(/parse error/.test(gf_message) ? "parse error" : null);
- }
- if(navigator.onLine)
- ajax_http_get("upload.cgi?cc="+encodeURIComponent(s),check)
- else cont(null)
-}
diff --git a/src/editor/simple/cloud2.js b/src/editor/simple/cloud2.js
deleted file mode 100644
index e32749dc1..000000000
--- a/src/editor/simple/cloud2.js
+++ /dev/null
@@ -1,159 +0,0 @@
-
-function with_dir(cont) {
- var dir=local.get("dir","");
- if(/^\/tmp\//.test(dir)) cont(dir);
- else ajax_http_get("/new",
- function(dir) {
- local.put("dir",dir);
- cont(dir);
- });
-}
-
-function remove_cloud_grammar(g) {
- var dir=local.get("dir")
- if(dir && g.unique_name) {
- var path=g.unique_name+".json"
- gfcloud("rm",{file:path},debug);
- }
-}
-
-// Upload the grammar to the server and check it for errors
-function upload(g) {
- function upload2(dir) {
- var form=node("form",{method:"post",action:"/cloud"},
- [hidden("dir",dir),hidden("command","make"),
- hidden(g.basename+".gf",show_abstract(g))])
- var files = [g.basename+".gf"]
- for(var i in g.concretes) {
- var cname=g.basename+g.concretes[i].langcode+".gf";
- files.push(cname);
- form.appendChild(hidden(cname,
- show_concrete(g.basename)(g.concretes[i])));
- }
- editor.appendChild(form);
- form.submit();
- form.parentNode.removeChild(form);
- }
-
- function upload3(message) { if(message) alert(message); }
-
- with_dir(upload2)
-}
-
-// Upload the grammar to store it in the cloud
-function upload_json(cont) {
- function upload3(resptext,status) {
- local.put("json_uploaded",Date.now());
- //debug("Upload complete")
- if(cont) cont();
- else {
- var sharing=element("sharing");
- if(sharing) sharing.innerHTML=resptext;
- }
- }
- function upload2(dir) {
- var prefix=dir.substr(10)+"-" // skip "/tmp/gfse."
- //debug("New form data");
- //var form=new FormData(); // !!! Doesn't work on Android 2.2!
- var form={dir:dir};
- //debug("Preparing form data");
- for(var i=0;i<local.count;i++) {
- var g=local.get(i,null);
- if(g) {
- if(!g.unique_name) {
- g.unique_name=prefix+i;
- save_grammar(g)
- }
- //form.append(g.unique_name+".json",JSON.stringify(g));
- form[encodeURIComponent(g.unique_name+".json")]=JSON.stringify(g)
- }
- }
- //debug("Upload to "+prefix);
- ajax_http_post("/cloud","command=upload"+encodeArgs(form),upload3,cont)
- }
-
- with_dir(upload2);
-}
-
-function download_json() {
- var dir=local.get("dir");
- var index=grammar_index();
- var downloading=0;
-
- function get_list(ok,err) { gfcloud("ls",{},ok,err) }
-
- function get_file(file,ok,err) {
- downloading++;
- gfcloud("download",{file:encodeURIComponent(file)},ok,err);
- }
-
- function file_failed(errormsg,status) {
- debug(errormsg)
- downloading--;
- }
- function file_downloaded(grammar) {
- downloading--;
- var newg=JSON.parse(grammar);
- debug("Downloaded "+newg.unique_name)
- var i=index[newg.unique_name];
- if(i!=undefined) merge_grammar(i,newg)
- else {
- debug("New")
- newg.index=null;
- save_grammar(newg);
- }
- if(downloading==0) done()
- }
-
- function done() {
- setTimeout(function(){location.href="."},2000);
- }
-
- function download_files(ls) {
- local.put("current",0);
- if(ls) {
- //debug("Downloading "+ls);
- var files=ls.split(" ");
- cleanup_deleted(files);
- for(var i in files) get_file(files[i],file_downloaded,file_failed);
- }
- else {
- debug("No grammars in the cloud")
- done()
- }
- }
-
- get_list(download_files);
-}
-
-function link_directories(newdir,cont) {
- gfcloud("link_directories",{newdir:newdir},cont)
-}
-
-/* -------------------------------------------------------------------------- */
-
-// Request GF cloud service
-function gfcloud(cmd,args,cont,err) {
- with_dir(function(dir) {
- var enc=encodeURIComponent;
- var url="/cloud?dir="+enc(dir)+"&command="+enc(cmd)+encodeArgs(args)
- ajax_http_get(url,cont,err)
- })
-}
-
-// Send a command to the GF shell
-function gfshell(cmd,cont) {
- with_dir(function(dir) {
- var enc=encodeURIComponent;
- ajax_http_get("/gfshell?dir="+enc(dir)+"&command="+enc(cmd),cont)
- })
-}
-
-// Check the syntax of an expression
-function check_exp(s,cont) {
- function check(gf_message) {
- //debug("cc "+s+" = "+gf_message);
- cont(/parse error/.test(gf_message) ? "parse error" : null);
- }
- gfshell("cc "+s,check);
-}
diff --git a/src/editor/simple/editor.css b/src/editor/simple/editor.css
deleted file mode 100644
index ef12fe8f5..000000000
--- a/src/editor/simple/editor.css
+++ /dev/null
@@ -1,88 +0,0 @@
-body { background: #eee; }
-h1 { font-size: 175%; }
-h1,h2,h3,h4,small { font-family: sans-serif; }
-h1:first-child, h2:first-child { margin-top: 0; margin-bottom: 1ex; }
-
-#editor { max-width: 50em; }
-div.home, div.grammar { border: 1px solid black; background: #9df; }
-div.home { padding: 5px; }
-div.files { margin: 0 8px 8px 8px; }
-
-div#file { border: 2px solid #009; border-top-width: 0; }
-pre.plain { border: 2px solid #009; }
-div#file, pre.plain { background: white; padding: 0.6ex; }
-
-.slideshow .hidden { display: none; }
-
-img.cloud, img.right, div.right, div.modtime { float: right; }
-.modtime { color: #999; white-space: nowrap; }
-
-div.namebar { background: #9df; }
-div.namebar table { width: 100%; }
-.namebar h3, .home h3 { margin: 0; color: #009; }
-
-td.right { text-align: right; }
-
-.kw { font-weight: bold; font-family: sans-serif; color: #009; }
-.sep { font-weight: bold; color: #009; }
-
-div.indent { padding-left: 1em; min-width: 1em; min-height: 1em; }
-
-div.fun:hover, div.param:hover, div.lincat:hover, div.oper:hover, div.lin:hover,
-div.template:hover
-{ background: #def;}
-
-.lin input[type=button],
-.template input[type=button] { float: right; clear: right; margin: 0; }
-.exb_output { background: #dfd; float: right; margin: 0 10px; }
-
-.more, .delete { font-weight: bold; font-family: sans-serif; }
-.more, .delete, .edit { cursor: pointer; }
-
-.hover .more, .hover .delete, .hover .edit { visibility: hidden }
-
-.hover .hidden, .nohover .ifhover { display: none; }
-
-.editable:hover, .deletable:hover { background: #ff9; }
-
-.extensible:hover .more,.editable:hover > .edit ,.deletable:hover > .delete
- { visibility: visible; }
-
-.more { color: green; }
-.edit { color: orange; }
-.delete { color: red; }
-.error_message,.inError { color: red; }
-.template, .template .sep { color: #999; }
-form { display: inline-block; }
-
-table.tabs {
- width: 100%;
- border-width: 0; border-spacing: 0; empty-cells: show;
-}
-
-table.tabs td { text-align: center; border: 2px solid #009; padding: 2px; }
-table.tabs td.active { background: white; border-bottom-width: 0; }
-table.tabs td.inactive {
- background: #cef;
- border-top-color: #66c; border-left-color: #66c; border-right-color: #66c;
-}
-
- table.tabs td.gap
-{ border-top-width: 0; border-left-width: 0; border-right-width: 0; }
-
-table.tabs input[type=button] {
- border: 0;
- background: inherit;
- color: #009;
- font-size: inherit;
- font-weight: bold;
- /*text-decoration: underline;*/
-}
-
-input.string_edit { font-family: inherit; font-size: inherit; }
-
-ul.languages { -moz-column-width: 20em; }
-
-li { margin-top: 0.5ex; margin-bottom: 0.5ex; }
-
-#sharing h1, #sharing .footer { display: none; } \ No newline at end of file
diff --git a/src/editor/simple/editor.js b/src/editor/simple/editor.js
deleted file mode 100644
index 859f33a04..000000000
--- a/src/editor/simple/editor.js
+++ /dev/null
@@ -1,1114 +0,0 @@
-
-
-var editor=element("editor");
-
-/* -------------------------------------------------------------------------- */
-
-function initial_view() {
- var current=local.get("current");
- if(current>0) open_grammar(current-1);
- else draw_grammar_list();
- //debug(local.get("dir","no server directory yet"));
-}
-
-function draw_grammar_list() {
- local.put("current",0);
- editor.innerHTML="";
- var uploaded=local.get("dir") && local.get("json_uploaded");
- var cloud_upload=
- a(jsurl("upload_json()"),
- [node("img",{"class":"cloud",
- src:"P/1306856253_weather_06.png",alt:"[Up Cloud]",
- title: uploaded
- ? "Click to upload grammar updates to the cloud"
- : "Click to store your grammars in the cloud"},
- [])]);
- var home=div_class("home",[node("h3",{},
- [text("Your grammars"),cloud_upload])]);
- if(uploaded) {
- var cloud_download=
- a(jsurl("download_json()"),
- [node("img",{"class":"cloud",
- src:"P/1307545089_weather_04.png",alt:"[Down Cloud]",
- title:"Click to download grammar updates from the cloud"},
- [])]);
- insertAfter(cloud_download,cloud_upload);
- }
- editor.appendChild(home)
- var gs=ul([]);
- function del(i) { return function () { delete_grammar(i); } }
- function clone(i) { return function (g,b) { clone_grammar(i); } }
- for(var i=0;i<local.count;i++) {
- var grammar=local.get(i,null);
- if(grammar && grammar.basename) {
- var link=a(jsurl("open_grammar("+i+")"),[text(grammar.basename)]);
- gs.appendChild(
- node("li",{"class":"extensible"},
- [deletable(del(i),link,"Delete this grammar"),
- more(grammar,clone(i),"Clone this grammar")]))
- }
- }
- if(local.get("count",null)==null)
- home.appendChild(text("You have not created any grammars yet."));
- else if(local.count==0)
- home.appendChild(text("Your grammar list is empty."));
- home.appendChild(gs);
-
- home.appendChild(
- ul([li([a(jsurl("new_grammar()"),[text("New grammar")])])]));
- //editor.appendChild(text(local.count));
- home.appendChild(empty_id("div","sharing"));
-}
-
-function new_grammar() {
- var g={basename:"Unnamed",
- abstract:{cats:[],funs:[]},
- concretes:[]}
- edit_grammar(g);
-}
-
-function remove_local_grammar(i) {
- local.remove(i);
- while(local.count>0 && !local.get(local.count-1))
- local.count--;
-}
-
-function delete_grammar(i) {
- var g=local.get(i);
- var ok=confirm("Do you really want to delete the grammar "+g.basename+"?")
- if(ok) {
- remove_local_grammar(i)
- remove_cloud_grammar(g)
- initial_view();
- }
-}
-
-function clone_grammar(i) {
- var old=local.get(i);
- var g={basename:old.basename,abstract:old.abstract,concretes:old.concretes}
- save_grammar(g);
- draw_grammar_list();
-}
-
-function open_grammar(i) {
- var g=local.get(i);
- g.index=i;
- local.put("current",i+1);
- edit_grammar(g);
-}
-
-function close_grammar(g) { save_grammar(g); draw_grammar_list(); }
-function reload_grammar(g) { save_grammar(g); edit_grammar(g); }
-
-function save_grammar(g) {
- if(g.index==null) g.index=local.count++;
- local.put(g.index,g);
-}
-
-function edit_grammar(g) {
- editor.innerHTML="";
- editor.appendChild(draw_grammar(g));
-}
-
-
-function draw_grammar(g) {
- var files=div_class("files",[draw_filebar(g),draw_file(g)]);
- return div_class("grammar",[draw_namebar(g,files),files])
-
-}
-
-function draw_namebar(g,files) {
- return div_class("namebar",
- [table([tr([td(draw_name(g)),
- td_right([draw_plainbutton(g,files),
- upload_button(g),
- draw_closebutton(g)])])])])
-}
-
-function draw_name(g) {
- return editable("h3",text(g.basename),g,edit_name,"Rename grammar");
-}
-
-function draw_closebutton(g) {
- var b=button("X",function(){close_grammar(g);});
- b.title="Save and Close this grammar";
- return b;
-}
-
-function draw_plainbutton(g,files) {
- var b2;
- function show_editor() { edit_grammar(g); }
- function show_plain() {
- files.innerHTML="<pre class=plain>"+show_grammar(g)+"</pre>"
- b.style.display="none";
- if(b2) b2.style.display="";
- else {
- b2=button("Show editor",show_editor);
- insertAfter(b2,b);
- }
- }
- var b=button("Show plain",show_plain);
- b.title="Show plain text representaiton of the grammar";
- return b;
-}
-
-function upload_button(g) {
- var b=button("Compile",function(){upload(g);});
- b.title="Upload the grammar to the server to check it in GF and test it in the minibar";
- return b;
-}
-
-function lang(code,name) { return { code:code, name:name} }
-function lang1(name) {
- var ws=name.split("/");
- return ws.length==1 ? lang(name.substr(0,3),name) : lang(ws[0],ws[1]);
-}
-var languages =
- map(lang1,"Amharic Arabic Bulgarian Catalan Danish Dutch English Finnish French German Hindi Ina/Interlingua Italian Latin Norwegian Polish Ron/Romanian Russian Spanish Swedish Thai Turkish Urdu".split(" "));
-languages.push(lang("Other","Other"));
-
-var langname={};
-for(var i in languages)
- langname[languages[i].code]=languages[i].name
-
-function concname(code) { return langname[code] || code; }
-
-function add_concrete(g,el) {
- var file=element("file");
- file.innerHTML="";
- var dc={};
- for(var i in g.concretes)
- dc[g.concretes[i].langcode]=true;
- var list=[]
- for(var i in languages) {
- var l=languages[i], c=l.code;
- if(!dc[c])
- list.push(li([a(jsurl("add_concrete2("+g.index+",'"+c+"')"),
- [text(l.name)])]));
- }
- var from= g.current>0
- ? "a copy of "+concname(g.concretes[g.current-1].langcode)
- :"scratch";
- file.appendChild(p(text("You are about to create a new concrete syntax by starting from "+from+".")));
- file.appendChild(p(text("Pick a language for the new concrete syntax:")));
- file.appendChild(node("ul",{"class":"languages"},list));
-}
-
-function new_concrete(code) {
- return { langcode:code,params:[],lincats:[],opers:[],lins:[] };
-}
-
-function adjust_opens(cnc,oldcode,code) {
- for(var oi in cnc.opens)
- for(var li in rgl_modules)
- if(cnc.opens[oi]==rgl_modules[li]+oldcode)
- cnc.opens[oi]=rgl_modules[li]+code;
-}
-
-function add_concrete2(ix,code) {
- var g=local.get(ix);
- var cs=g.concretes;
- var ci;
- for(var ci=0;ci<cs.length;ci++) if(cs[ci].langcode==code) break;
- if(ci==cs.length) {
- if(g.current>0) {
- cs.push(cs[g.current-1]); // old and new are shared at this point
- save_grammar(g); // serialization loses sharing
- g=local.get(ix); // old and new are separate now
- var oldcode=cs[g.current-1].langcode;
- var cnc=g.concretes[ci];
- cnc.langcode=code;
- adjust_opens(cnc,oldcode,code);
- timestamp(cnc)
- }
- else
- cs.push(new_concrete(code))
- save_grammar(g);
- }
- open_concrete(g,ci);
-}
-
-function open_abstract(g) { g.current=0; reload_grammar(g); }
-function open_concrete(g,i) { g.current=i+1; reload_grammar(g); }
-
-function td_gap(c) {return wrap_class("td","gap",c); }
-function gap() { return td_gap(text(" ")); }
-
-function tab(active,link) {
- return wrap_class("td",active ? "active" : "inactive",link);
-}
-
-function delete_concrete(g,ci) {
- var c=g.concretes[ci];
- var ok=c.params.length==0 && c.lincats.length==0 && c.opers.length==0
- && c.lins.length==0
- || confirm("Do you really want to delete the concrete syntax for "+
- concname(c.langcode)+"?");
- if(ok) {
- g.concretes=delete_ix(g.concretes,ci)
- if(g.current && g.current-1>=ci) g.current--;
- reload_grammar(g);
- }
-}
-
-function draw_filebar(g) {
- var cur=(g.current||0)-1;
- var filebar = empty_class("tr","extensible")
- filebar.appendChild(gap());
- filebar.appendChild(
- tab(cur== -1,button("Abstract",function(){open_abstract(g);})));
- var cs=g.concretes;
- function del(ci) { return function() { delete_concrete(g,ci); }}
- function open_conc(i) { return function() {open_concrete(g,1*i); }}
- for(var i in cs) {
- filebar.appendChild(gap());
- filebar.appendChild(
- tab(i==cur,deletable(del(i),button(concname(cs[i].langcode),open_conc(i)),"Delete this concrete syntax")));
- }
- filebar.appendChild(td_gap(more(g,add_concrete,"Add a concrete syntax")));
- return wrap_class("table","tabs",filebar);
-}
-
-function draw_file(g) {
- return g.current>0 // && g.current<=g.concretes.length
- ? draw_concrete(g,g.current-1)
- : draw_abstract(g);
-}
-
-function draw_startcat(g) {
- var abs=g.abstract;
- var startcat = abs.startcat || abs.cats[0];
- function opt(cat) { return option(cat,cat); }
- var m= node("select",{},map(opt,abs.cats));
- m.value=startcat;
- m.onchange=function() {
- if(m.value!=abs.startcat) {
- abs.startcat=m.value;
- timestamp(abs);
- save_grammar(g);
- }
- }
- return indent([kw("flags startcat"),sep(" = "),m]);
-}
-
-function draw_abstract(g) {
- var kw_cat = kw("cat");
- kw_cat.title = "The categories (nonterminals) of the grammar are enumerated here. [C.3.2]";
- var kw_fun = kw("fun");
- kw_fun.title = "The functions (productions) of the grammar are enumerated here. [C.3.4]";
- var flags=g.abstract.startcat || g.abstract.cats.length>1
- ? draw_startcat(g)
- : text("");
- function sort_funs() {
- g.abstract.funs=sort_list(this,g.abstract.funs,"name");
- timestamp(g.abstract);
- save_grammar(g);
- }
- return div_id("file",
- [kw("abstract "),ident(g.basename),sep(" = "),
- draw_timestamp(g.abstract),
- flags,
- indent([extensible([kw_cat,
- indent(draw_cats(g))]),
- extensible([kw_fun,
- indent_sortable(draw_funs(g),sort_funs)])])]);
-}
-
-function add_cat(g,el) {
- function add(s) {
- var cats=s.split(/\s*(?:\s|[;])\s*/); // allow separating spaces or ";"
- if(cats.length>0 && cats[cats.length-1]=="") cats.pop();
- for(var i in cats) {
- var err=check_name(cats[i],"Category");
- if(err) return err;
- }
- for(var i in cats) g.abstract.cats.push(cats[i]);
- timestamp(g.abstract);
- reload_grammar(g);
- return null;
- }
- string_editor(el,"",add);
-}
-
-function delete_cat(g,ix) {
- with(g.abstract) cats=delete_ix(cats,ix);
- timestamp(g.abstract);
- reload_grammar(g);
-}
-
-function rename_cat(g,el,cat) {
- function ren(newcat) {
- if(newcat!="" && newcat!=cat) {
- var err=check_name(newcat,"Category");
- if(err) return err;
- var dc=defined_cats(g);
- if(dc[newcat]) return newcat+" is already in use";
- g=rename_category(g,cat,newcat);
- timestamp(g.abstract);
- reload_grammar(g);
- }
- return null;
- }
- string_editor(el,cat,ren);
-}
-
-function draw_cats(g) {
- var cs=g.abstract.cats;
- var es=[];
- var defined={};
- function eident(cat) {
- function ren(g,el) { rename_cat(g,el,cat); }
- return editable("span",ident(cat),g,ren,"Rename category");
- }
- function check(cat,el) {
- return ifError(defined[cat],"Same category named twice",el);
- }
- function del(i) { return function() { delete_cat(g,i); }}
- for(var i in cs) {
- es.push(deletable(del(i),check(cs[i],eident(cs[i])),"Delete this category"));
- defined[cs[i]]=true;
- es.push(sep("; "));
- }
- es.push(more(g,add_cat,"Add more categories"));
- return es;
-}
-
-function add_fun(g,el) {
- function add(s) {
- var p=parse_fun(s);
- if(p.ok) {
- g.abstract.funs.push(p.ok);
- timestamp(g.abstract);
- reload_grammar(g);
- return null;
- }
- else
- return p.error
- }
- string_editor(el,"",add);
-}
-
-function edit_fun(i) {
- return function (g,el) {
- function replace(s) {
- var p=parse_fun(s);
- if(p.ok) {
- var old=g.abstract.funs[i];
- g.abstract.funs[i]=p.ok;
- if(p.ok.name!=old.name) g=rename_function(g,old.name,p.ok.name);
- if(show_type(p.ok.type)!=show_type(old.type))
- g=change_lin_lhs(g,p.ok);
- timestamp(g.abstract);
- reload_grammar(g);
- return null;
- }
- else
- return p.error;
- }
- string_editor(el,show_fun(g.abstract.funs[i]),replace);
- }
-}
-
-function delete_fun(g,ix) {
- with(g.abstract) funs=delete_ix(funs,ix);
- timestamp(g.abstract);
- reload_grammar(g);
-}
-
-function draw_funs(g) {
- var funs=g.abstract.funs;
- var es=[];
- var dc=defined_cats(g);
- var df={};
- function del(i) { return function() { delete_fun(g,i); }}
- function draw_efun(i,df) {
- return editable("span",draw_fun(funs[i],dc,df),g,edit_fun(i),"Edit this function");
- }
- for(var i in funs) {
- es.push(node_sortable("fun",funs[i].name,[deletable(del(i),draw_efun(i,df),"Delete this function")]));
- df[funs[i].name]=true;
- }
- es.push(more(g,add_fun,"Add a new function"));
- return es;
-}
-
-function draw_fun(fun,dc,df) {
- function check(el) {
- return ifError(dc[fun.name],
- "Function names must be distinct from category names",
- ifError(df[fun.name],"Same function defined twice",el));
- }
- return node("span",{},
- [check(ident(fun.name)),sep(" : "),draw_type(fun.type,dc)]);
-}
-
-function draw_type(t,dc) {
- var el=empty("span");
- function check(t,el) {
- return ifError(!dc[t],"Undefined category",el);
- }
- for(var i in t) {
- if(i>0) el.appendChild(sep(" → "));
- el.appendChild(check(t[i],ident(t[i])));
- }
- return el;
-}
-
-function edit_name(g,el) {
- function change_name(name) {
- if(name!=g.basename && name!="") {
- var err=check_name(name,"Grammar");
- if(err) return err;
- g.basename=name
- reload_grammar(g);
- }
- return null;
- }
- string_editor(el,g.basename,change_name)
-}
-/* -------------------------------------------------------------------------- */
-
-function draw_concrete(g,i) {
- var conc=g.concretes[i];
- function edit_langcode(g,el) {
- function change_langcode(code) {
- var err=check_name(g.basename+code,"Name of concrete syntax");
- if(err) return err;
- adjust_opens(conc,conc.langcode,code);
- conc.langcode=code;
- timestamp(conc);
- reload_grammar(g);
- }
- string_editor(el,conc.langcode,change_langcode)
- }
- var kw_lincat=kw("lincat")
- kw_lincat.title="The linearization type for each catagory in the abstract syntax is given here. [C.3.8]"
- var kw_lin=kw("lin")
- kw_lin.title="The linearization function for each function in the abstract syntax is given here. [C.3.9]"
- var kw_param=kw("param")
- kw_param.title="Parameter type definitions can be added here. [C.3.12]"
- var kw_oper=kw("oper")
- kw_oper.title="Operation definitions can be added here. [C.3.14]"
- return div_id("file",
- [kw("concrete "),
- ident(g.basename),
- editable("span",ident(conc.langcode),g,
- edit_langcode,"Change language"),
- kw(" of "),ident(g.basename),sep(" = "),
- draw_timestamp(conc),
- indent([extensible([kw("open "),draw_opens(g,i)])]),
- indent([kw_lincat,draw_lincats(g,i)]),
- indent([kw_lin,draw_lins(g,i)]),
- indent([extensible([kw_param,draw_params(g,i)])]),
- indent([extensible([kw_oper,draw_opers(g,i)])]),
- exb_extra(g,i)
- ])
-}
-
-var rgl_modules=["Paradigms","Syntax","Lexicon","Extra"];
-
-function add_open(ci) {
- return function (g,el) {
- var conc=g.concretes[ci];
- var os=conc.opens;
- var ds={};
- for(var i in os) ds[os[i]]=true;
- var list=[]
- for(var i in rgl_modules) {
- var b=rgl_modules[i], m=b+conc.langcode;
- if(!ds[m])
- list.push(li([a(jsurl("add_open2("+g.index+","+ci+",'"+m+"')"),
- [text(m)])]));
- }
- if(list.length>0) {
- var file=element("file");
- file.innerHTML="";
- file.appendChild(p(text("Pick a resource library module to open:")));
- file.appendChild(node("ul",{},list));
- }
- }
-}
-
-function add_open2(ix,ci,m) {
- var g=local.get(ix);
- var conc=g.concretes[ci];
- conc.opens || (conc.opens=[]);
- conc.opens.push(m);
- timestamp(conc);
- save_grammar(g);
- open_concrete(g,ci);
-}
-
-function delete_open(g,ci,ix) {
- with(g.concretes[ci]) opens=delete_ix(opens,ix);
- timestamp(g.concretes[ci]);
- reload_grammar(g);
-}
-
-function draw_opens(g,ci) {
- var conc=g.concretes[ci];
- var os=conc.opens || [] ;
- var es=[];
- function del(i) { return function() { delete_open(g,ci,i); }}
- var first=true;
- for(var i in os) {
- if(!first) es.push(sep(", "))
- es.push(deletable(del(i),ident(os[i]),"Don't open this module"));
- first=false;
- }
- es.push(more(g,add_open(ci),"Open more modules"));
- return indent(es);
-}
-
-function draw_param(p,dp) {
- function check(el) {
- return ifError(dp[p.name],"Same parameter type defined twice",el);
- }
- return node("span",{},[check(ident(p.name)),sep(" = "),text(p.rhs)]);
-}
-
-function add_param(g,ci,el) {
- function add(s) {
- var p=parse_param(s);
- if(p.ok) {
- g.concretes[ci].params.push(p.ok);
- timestamp(g.concretes[ci]);
- reload_grammar(g);
- return null;
- }
- else
- return p.error
- }
- string_editor(el,"",add);
-}
-
-function edit_param(ci,i) {
- return function (g,el) {
- function replace(s) {
- var p=parse_param(s);
- if(p.ok) {
- g.concretes[ci].params[i]=p.ok;
- timestamp(g.concretes[ci]);
- reload_grammar(g);
- return null;
- }
- else
- return p.error;
- }
- string_editor(el,show_param(g.concretes[ci].params[i]),replace);
- }
-}
-
-
-function delete_param(g,ci,ix) {
- with(g.concretes[ci]) params=delete_ix(params,ix);
- timestamp(g.concretes[ci]);
- reload_grammar(g);
-}
-
-function draw_params(g,ci) {
- var conc=g.concretes[ci];
- conc.params || (conc.params=[]);
- var params=conc.params;
- var es=[];
- var dp={};
- function del(i) { return function() { delete_param(g,ci,i); }}
- function draw_eparam(i,dp) {
- return editable("span",draw_param(params[i],dp),g,edit_param(ci,i),"Edit this parameter type");
- }
- for(var i in params) {
- es.push(div_class("param",[deletable(del(i),draw_eparam(i,dp),"Delete this parameter type")]));
- dp[params[i].name]=true;
- }
- es.push(more(g,function(g,el) { return add_param(g,ci,el)},
- "Add a new parameter type"));
- return indent(es);
-}
-
-function delete_lincat(g,ci,cat) {
- var i;
- var c=g.concretes[ci];
- for(i=0;i<c.lincats.length && c.lincats[i].cat!=cat;i++);
- if(i<c.lincats.length) c.lincats=delete_ix(c.lincats,i);
- timestamp(c);
- reload_grammar(g);
-}
-
-function draw_lincats(g,i) {
- var conc=g.concretes[i];
- function edit(c) {
- return function(g,el) {
- function check(s,cont) {
- function check2(msg) {
- if(!msg) {
- if(c.template) conc.lincats.push({cat:c.cat,type:s});
- else c.type=s;
- reload_grammar(g);
- }
- cont(msg);
- }
- check_exp(s,check2);
- }
- string_editor(el,c.type,check,true)
- }
- }
- function del(c) { return function() { delete_lincat(g,i,c); } }
- function dlc(c,cls) {
- var t=editable("span",text_ne(c.type),g,edit(c),"Edit lincat for "+c.cat);
- return node("span",{"class":cls},
- [ident(c.cat),sep(" = "),t]);
- }
- var dc=defined_cats(g);
- function draw_lincat(c) {
- var cat=c.cat;
- var err=!dc[cat];
- var l1=dlc(c,"lincat");
- var l2= deletable(del(cat),l1,"Delete this lincat");
- var l=ifError(err,"lincat for undefined category",l2);
- delete dc[cat];
- return node_sortable("lincat",cat,[l]);
- }
- function dtmpl(c) {
- return wrap("div",dlc({cat:c,type:"",template:true},"template")); }
- var lcs=map(draw_lincat,conc.lincats);
- for(var c in dc)
- lcs.push(dtmpl(c));
- function sort_lincats() {
- conc.lincats=sort_list(this,conc.lincats,"cat");
- timestamp(conc);
- save_grammar(g);
- }
- return indent_sortable(lcs,sort_lincats);
-}
-
-/* -------------------------------------------------------------------------- */
-
-function draw_oper(p,dp) {
- function check(el) {
- return ifError(dp[p.name],"Same operator definition defined twice",el);
- }
- return node("span",{},[check(ident(p.name)),text(" "),text(p.rhs)]);
-}
-
-function check_oper(s,ok,err) {
- var p=parse_oper(s);
- function check2(msg) {
- if(msg) err(msg);
- else ok(p.ok)
- }
- if(p.ok) {
- // Checking oper syntax by checking an expression with a local
- // definition. Some valid opers will be rejected!!
- var e=p.ok.name+" where { "+p.ok.name+" "+p.ok.rhs+" }";
- check_exp(e,check2);
- }
- else
- err(p.error);
-}
-
-function add_oper(g,ci,el) {
- function check(s,cont) {
- function ok(oper) {
- g.concretes[ci].opers.push(oper);
- timestamp(g.concretes[ci]);
- reload_grammar(g);
- cont(null);
- }
- check_oper(s,ok,cont)
- }
- string_editor(el,"",check,true);
-}
-
-function edit_oper(ci,i) {
- return function (g,el) {
- function check(s,cont) {
- function ok(oper) {
- g.concretes[ci].opers[i]=oper;
- timestamp(g.concretes[ci]);
- reload_grammar(g);
- cont(null);
- }
- check_oper(s,ok,cont)
- }
- string_editor(el,show_oper(g.concretes[ci].opers[i]),check,true);
- }
-}
-
-function delete_oper(g,ci,ix) {
- with(g.concretes[ci]) opers=delete_ix(opers,ix);
- timestamp(g.concretes[ci]);
- reload_grammar(g);
-}
-
-function draw_opers(g,ci) {
- var conc=g.concretes[ci];
- conc.opers || (conc.opers=[]);
- var opers=conc.opers;
- var es=[];
- var dp={};
- function del(i) { return function() { delete_oper(g,ci,i); }}
- function draw_eoper(i,dp) {
- return editable("span",draw_oper(opers[i],dp),g,edit_oper(ci,i),"Edit this operator definition");
- }
- for(var i in opers) {
- es.push(node_sortable("oper",opers[i].name,
- [deletable(del(i),draw_eoper(i,dp),
- "Delete this operator definition")]));
- dp[opers[i].name]=true;
- }
- es.push(more(g,function(g,el) { return add_oper(g,ci,el)},
- "Add a new operator definition"));
- function sort_opers() {
- conc.opers=sort_list(this,conc.opers,"name");
- timestamp(conc);
- save_grammar(g);
- }
- return indent_sortable(es,sort_opers);
-}
-
-function delete_lin(g,ci,fun) {
- var i;
- var c=g.concretes[ci];
- for(i=0;i<c.lins.length && c.lins[i].fun!=fun;i++);
- if(i<c.lins.length) c.lins=delete_ix(c.lins,i);
- timestamp(c);
- reload_grammar(g);
-}
-
-/* -------------------------------------------------------------------------- */
-function arg_names(type) {
- function lower(s) { return s.toLowerCase(); }
- var names=map(lower,type);
- names.pop(); // remove result type
- var n,count={},use={};
- for(var i in names) n=names[i],count[n]=0,use[n]=0;
- for(var i in names) count[names[i]]++;
- function unique(n) {
- return count[n]>1 ? n+(++use[n]) : n;
- }
- return map(unique,names);
-}
-
-function draw_lins(g,ci) {
- var conc=g.concretes[ci];
- function edit(f) {
- return function(g,el) {
- function check(s,cont) {
- function check2(msg) {
- if(!msg) {
- if(f.template)
- conc.lins.push({fun:f.fun,args:f.args,lin:s});
- else { f.lin=s; f.eb_lin=null; }
- reload_grammar(g);
- }
- cont(msg);
- }
- check_exp(s,check2);
- }
- string_editor(el,f.lin,check,true)
- }
- }
- function del(fun) { return function () { delete_lin(g,ci,fun); } }
- function dl(f,cls) {
- var l=[ident(f.fun)]
- for(var i in f.args) {
- l.push(text(" "));
- l.push(ident(f.args[i]));
- }
- l.push(sep(" = "));
- var t=editable("span",text_ne(f.lin),g,edit(f),"Edit lin for "+f.fun);
- appendChildren(t,exb_linbuttons(g,ci,f));
- l.push(t);
- return node("span",{"class":cls},l);
- }
- var df=defined_funs(g);
- function draw_lin(f) {
- var fun=f.fun;
- var err= !df[fun];
- var l= deletable(del(fun),dl(f,"lin"),"Delete this linearization function")
- var l=ifError(err,"Function "+fun+" is not part of the abstract syntax",l);
- delete df[fun];
- return node_sortable("lin",fun,[l]);
- }
- function largs(f) {
- var funs=g.abstract.funs;
- for(var i=0;i<funs.length && funs[i].name!=f;i++);
- return arg_names(funs[i].type);
- }
- function dtmpl(f) {
- return div_class("template",
- [dl({fun:f,args:largs(f),lin:"",template:true},"template")]);
- }
- function sort_lins() {
- conc.lins=sort_list(this,conc.lins,"fun");
- timestamp(conc);
- save_grammar(g);
- }
- var ls=map(draw_lin,conc.lins);
- for(var f in df)
- ls.push(dtmpl(f));
- return indent_sortable(ls,sort_lins);
-}
-
-/* -------------------------------------------------------------------------- */
-
-function find_langcode(concs,langcode) {
- for(var ci in concs)
- if(concs[ci].langcode==langcode)
- return concs[ci];
- return null;
-}
-
-function cleanup_deleted(files) {
- var keep={}
- for(var i in files) keep[files[i]]=true;
- //debug("cleanup_deleted "+JSON.stringify(files))
- //debug("keep "+JSON.stringify(keep))
- for(var i=0;i<local.count;i++) {
- var g=local.get(i,null)
- if(g && g.unique_name && !keep[g.unique_name+".json"]) {
- debug("cleanup "+i+" "+g.unique_name);
- remove_local_grammar(i)
- }
- }
-}
-
-function grammar_index() {
- var index={}
- var count=local.count
- for(var i=0;i<count;i++) {
- var g=local.get(i,null)
- if(g && g.unique_name) index[g.unique_name]=i
- }
- return index
-}
-
-function merge_grammar(i,newg) {
- var oldg=local.get(i);
- var keep="";
- debug("Merging at "+i);
- if(oldg) {
- oldg.basename=newg.basename;
- if(newg.abstract.timestamp<oldg.abstract.timestamp) {
- newg.abstract=newg.abstract
- keep+=" "+oldg.basename
- }
- for(var ci in newg.concretes) {
- var conc=newg.concretes[ci];
- var oldconc=find_langcode(oldg.concretes,conc.langcode);
- if(oldconc && conc.timestamp<oldconc.timestamp) {
- newg.concretes[ci]=oldconc;
- keep+=" "+oldg.basename+conc.langcode;
- }
- }
- }
- local.put(i,newg)
- return keep;
-}
-
-function timestamp(obj,prop) {
- obj[prop || "timestamp"]=Date.now();
-}
-
-function draw_timestamp(obj) {
- var t=obj.timestamp;
- return node("small",{"class":"modtime"},
- [text(t ? " -- "+new Date(t).toLocaleString() : "")]);
-}
-
-/* -------------------------------------------------------------------------- */
-
-function delete_ix(old,ix) {
- var a=[];
- for(var i in old) if(i!=ix) a.push(old[i]);
- return a;
-}
-
-function sort_list(list,olditems,key) {
- var items=[];
- function find(fun) {
- for(var i=0;i<olditems.length;i++)
- if(olditems[i][key]==fun) return olditems[i];
- return null;
- }
- for(var el=list.firstChild;el;el=el.nextSibling) {
- var name=el.getAttribute("ident")
- if(name) {
- var old=find(name);
- if(old) items.push(old)
- else debug("Bug: did not find "+name+" while sorting");
- }
- }
- if(items.length==olditems.length)
- return items;
- else {
- debug("Bug: length changed while sorting")
- return olditems;
- }
-}
-
-function string_editor(el,init,ok,async) {
- var p=el.parentNode;
- function restore() {
- e.parentNode.removeChild(e);
- el.style.display="";
- }
- function done() {
- var edited=e.it.value;
- restore();
- function cont(msg) { if(msg) start(msg); }
- if(async) ok(edited,cont)
- else cont(ok(edited));
- return false;
- }
- function start(msg) {
- el.style.display="none";
- m.innerHTML=msg;
- insertAfter(e,el);
- e.it.focus();
- }
- var m=empty_class("span","error_message");
- var i=node("input",{"class":"string_edit",name:"it",value:init},[]);
- if(init.length>10) i.size=init.length+5;
-// var i=node("textarea",{name:"it",rows:"2",cols:"60"},[text(init)]);
- var e=node("form",{},
- [i,
- node("input",{type:"submit",value:"OK"},[]),
- button("Cancel",restore),
- text(" "),
- m])
- e.onsubmit=done
- start("");
-}
-
-function ifError(b,msg,el) { return b ? inError(msg,el) : el; }
-
-function inError(msg,el) {
- return node("span",{"class":"inError",title:msg},[el]);
-}
-
-function kw(txt) { return wrap_class("span","kw",text(txt)); }
-function sep(txt) { return wrap_class("span","sep",text(txt)); }
-function ident(txt) { return wrap_class("span","ident",text(txt)); }
-function indent(cs) { return div_class("indent",cs); }
-
-function indent_sortable(cs,sort) {
- var n= indent(cs);
- n.onsort=sort;
- return n;
-}
-
-function node_sortable(cls,name,ls) {
- return node("div",{"class":cls,"ident":name},ls);
-}
-
-function extensible(cs) { return div_class("extensible",cs); }
-
-function more(g,action,hint) {
- var b=node("span",{"class":"more","title":hint || "Add more"},
- [text(" + ")]);
- b.onclick=function() { action(g,b); }
- return b;
-}
-
-function text_ne(s) { // like text(s), but force it to be non-empty
- return text(s ? s : "\xa0\xa0\xa0")
-}
-
-function editable(tag,cs,g,f,hint) {
- var b=edit_button(function(){f(g,e)},hint);
- var e=node(tag,{"class":"editable"},[cs,b]);
- //e.onclick=b.onclick;
- return e;
-}
-
-function edit_button(action,hint) {
- var b=node("span",{"class":"edit","title":hint || "Edit"},[text("%")]);
- b.onclick=action;
- return b;
-}
-
-function deletable(del,el,hint) {
- var b=node("span",{"class":"delete",title:hint || "Delete"},[text("×")])
- b.onclick=del;
- return node("span",{"class":"deletable"},[b,el])
-}
-
-function touch_edit() {
- var b=node("input",{type:"checkbox"},[]);
- function touch() {
- document.body.className=b.checked ? "nohover" : "hover";
- }
- b.onchange=touch;
- insertAfter(b,editor);
- insertAfter(wrap("small",text("Enable editing on touch devices. ")),b);
-}
-/* --- DOM Support ---------------------------------------------------------- */
-
-function div_id(id,cs) { return node("div",{id:id},cs); }
-function div_class(cls,cs) { return node("div",{"class":cls},cs); }
-function a(url,linked) { return node("a",{href:url},linked); }
-function ul(lis) { return node("ul",{},lis); }
-function li(xs) { return node("li",{},xs); }
-function table(rows) { return node("table",{},rows); }
-function td_right(cs) { return node("td",{"class":"right"},cs); }
-function jsurl(js) { return "javascript:"+js; }
-
-function hidden(name,value) {
- return node("input",{type:"hidden",name:name,value:value},[])
-}
-
-function insertBefore(el,ref) { ref.parentNode.insertBefore(el,ref); }
-
-function insertAfter(el,ref) {
- ref.parentNode.insertBefore(el,ref.nextSibling);
-}
-/* -------------------------------------------------------------------------- */
-
-function download_from_cloud() {
- var newdir="/tmp/"+location.hash.substr(1)
-
- function download2(olddir) {
- //debug("Starting grammar sharing in the cloud")
- if(newdir!=olddir) link_directories(newdir,download3)
- else download4()
- }
- function download3() {
- //debug("Uploading local grammars to cloud");
- upload_json(download4)
- }
- function download4() {
- //debug("Downloading grammars from the cloud");
- download_json()
- }
-
- with_dir(download2)
-}
-
-/* --- Initialization ------------------------------------------------------- */
-
-//document.body.appendChild(empty_id("div","debug"));
-
-function dir_bugfix() {
- // remove trailing newline caused by bug in older version
- var dir=local.get("dir");
- if(dir) {
- var n=dir.length;
- while(dir[dir.length-1]=="\n" || dir[dir.length-1]=="\r")
- dir=dir.substr(0,dir.length-1)
- if(dir.length<n) {
- debug("removing trailing newline")
- local.put("dir",dir);
- }
- //debug("Server directory: "+JSON.stringify(dir))
- }
- else debug("No server directory yet")
-}
-
-if(editor) {
- initial_view();
- touch_edit();
- dir_bugfix();
-}
-
-//console.log("hi")
diff --git a/src/editor/simple/example_based.js b/src/editor/simple/example_based.js
deleted file mode 100644
index 5922b60ea..000000000
--- a/src/editor/simple/example_based.js
+++ /dev/null
@@ -1,158 +0,0 @@
-
-var example_based=[];
-
-/*
--- cat lincat fun lin fun cat cat
-environ :: ([(CId, CId)],[(CId, Expr)],[((CId, CId), [CId])]) -> Environ
-*/
-function exb_state(g,ci) {
- var conc=g.concretes[ci]
- function show_list(show1,xs) {
- return "["+map(show1,xs).join(",")+"]";
- }
- function show_fun(fun) {
- var t=fun.type
- var res=t[t.length-1]
- var args=t.slice(0,length-1);
- return "(("+fun.name+","+res+"),["+args.join(",")+"])"
- }
- function show_lincat(lincat) {
- return "("+lincat.cat+","+lincat.type+")"
- }
- function show_lin(lin) {
- return "("+lin.fun+","+(lin.eb_lin||"?")+")"
- }
- function show_funs(funs) { return show_list(show_fun,funs) }
- function show_lincats(lincats) { return show_list(show_lincat,lincats); }
- function show_lins(lins) { return show_list(show_lin,lins) }
- return "("+show_lincats(conc.lincats)
- +","+show_lins(conc.lins)
- +","+show_funs(g.abstract.funs)+")"
-}
-
-function exb_call(g,ci,command,args,cont) {
- var url=window.exb_url || "exb/exb.fcgi";
- var q=encodeArgs(args);
- var cmd="?command="+command+"&state="+encodeURIComponent(exb_state(g,ci))+q;
- http_get_json(url+cmd,cont)
-}
-
-function ask_possibilities(g,ci) {
- var conc=g.concretes[ci];
-
- function show_poss(poss) {
- //debug("possibilities: "+JSON.stringify(poss))
- var exready={}
- for(var i in poss[0]) exready[poss[0][i]]=true;
- var testable={}
- for(var i in poss[1]) testable[poss[1][i]]=true;
- example_based[ci]={exready:exready,testable:testable}
- conc.example_based=true;
- conc.example_lang=g.concretes[0].langcode;
- reload_grammar(g);
- }
-
- exb_call(g,ci,"possibilities",{},show_poss)
-}
-
-function exb_extra(g,ci) {
- var conc=g.concretes[ci];
- function stop_exb() {
- conc.example_based=false;
- reload_grammar(g);
- }
-
- function exblangmenu() {
- function opt(conc) { return option(conc.langcode,conc.langcode); }
- // skip target language
- var m =node("select",{},map(opt,g.concretes));
- m.onchange=function() { conc.example_lang=m.value }
- return m
- }
-
- function ask_poss() { ask_possibilities(g,ci) }
-
- if(navigator.onLine && conc.example_based && !example_based[ci]) ask_poss();
- return conc.langcode=="Eng"
- ? indent([text("Example based editing: "),
- conc.example_based
- ? node("span",{},[button("Stop",stop_exb),
- text(" Example language: "),
- exblangmenu()
- ])
- : button("Start",ask_poss)])
- : text("")
-}
-
-function exb_linbuttons(g,ci,f) {
- var conc=g.concretes[ci];
- var fun=f.fun;
- var eb=example_based[ci];
- var exb_output;
- function fill_example(maybetree) {
- var tree=maybetree.Just
- if(tree) {
- if(f.template)
- conc.lins.push({fun:f.fun,args:f.args,
- lin:tree[0],eb_lin:tree[1]});
- else {
- f.lin=tree[0];
- f.eb_lin=tree[1];
- }
- ask_possibilities(g,ci)
- }
- else exb_output.innerHTML="Bug: no tree found"
- }
- function show_example(example){
- exb_output.innerHTML="";
- var s=prompt(example[1]);
- if(s) {
- var t=function_type(g,fun);
- var abscat=t[t.length-1]
- var cat=cat_lincat(conc,abscat)
- exb_output.innerHTML="...";
- //server.parse({from:"ParseEng",cat:cat,input:s},fill_example)
- exb_call(g,ci,"abstract_example",
- {cat:cat,input:s,
- params:"["+f.args.join(",")+"]",
- abstract:example[0]},
- fill_example)
- }
- }
- function by_example() {
- var dir=local.get("dir")
- if(dir) {
- if(exb_output) {
- exb_output.innerHTML="...";
- exb_call(g,ci,"provide_example",
- {lang:g.basename+conc.example_lang,
- fun:fun,
- grammar:dir+"/"+g.basename+".pgf"},
- show_example)
- }
- }
- else exb_output.innerHTML="Compile the grammar first!"
- }
- function show_test(txt) {
- exb_output.innerHTML="";
- exb_output.appendChild(text(txt))
- }
- function test_it(b) {
- if(exb_output) {
- exb_output.innerHTML="...";
- exb_call(g,ci,"test_function",{fun:fun},show_test)
- }
- }
- var buttons=[];
- if(conc.example_based && eb) {
- if(eb.exready[fun])
- buttons.push(button("By example",by_example))
- if(eb.testable[fun] && f.eb_lin) {
- var b=button("Test it",test_it);
- buttons.push(b)
- }
- var exb_output=node("span",{"class":"exb_output"},[]);
- buttons.push(exb_output)
- }
- return buttons
-}
diff --git a/src/editor/simple/gf_abs.js b/src/editor/simple/gf_abs.js
deleted file mode 100644
index 4efaab89a..000000000
--- a/src/editor/simple/gf_abs.js
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Abstract syntax for a small subset of GF grammars in JavaScript */
-
-function defined_cats(g) {
- var dc={};
- with(g.abstract)
- for(var i in cats) dc[cats[i]]=true;
- return dc;
-}
-
-function defined_funs(g) {
- var df={};
- with(g.abstract)
- for(var i in funs) df[funs[i].name]=true;
- return df;
-}
-
-function function_type(g,fun) {
- with(g.abstract)
- for(var i in funs) if(funs[i].name==fun) return funs[i].type
- return null;
-}
-
-function cat_lincat(conc,cat) {
- with(conc)
- for(var i in lincats) if(lincats[i].cat==cat) return lincats[i].type
- return null;
-}
-
-function rename_category(g,oldcat,newcat) {
- function rename_cats(cats) {
- for(var i in cats) if(cats[i]==oldcat) cats[i]=newcat;
- }
- function rename_type(t) {
- for(var i in t) if(t[i]==oldcat) t[i]=newcat;
- }
- function rename_funs(funs) {
- for(var i in funs) rename_type(funs[i].type)
- }
- function rename_abstract(a) {
- rename_cats(a.cats);
- rename_funs(a.funs);
- }
- function rename_lincat(lc) {
- if(lc.cat==oldcat) lc.cat=newcat;
- }
- function rename_concrete(c) {
- for(var i in c.lincats) rename_lincat(c.lincats[i]);
- }
- function rename_concretes(cs) {
- for(var i in cs) rename_concrete(cs[i]);
- }
- rename_abstract(g.abstract)
- rename_concretes(g.concretes);
- return g;
-}
-
-function rename_function(g,oldfun,newfun) {
- function rename_lin(lin) {
- if(lin.fun==oldfun) lin.fun=newfun;
- }
- function rename_concrete(c) {
- for(var i in c.lins) rename_lin(c.lins[i]);
- }
- for(var i in g.concretes) rename_concrete(g.concretes[i]);
- return g;
-}
-
-function change_lin_lhs(g,fun) {
- function change_lin(lin) {
- if(lin.fun==fun.name) lin.args=arg_names(fun.type);
- }
- function change_concrete(c) {
- for(var i in c.lins) change_lin(c.lins[i]);
- }
- for(var i in g.concretes) change_concrete(g.concretes[i]);
- return g;
-}
-
-/* --- Parsing -------------------------------------------------------------- */
-
-// GF idenfifier syntax:
-var lex_id=/^[A-Za-z][A-Za-z0-9_']*$/
-// See https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions
-
-function check_id(s) { return lex_id.test(s); }
-
-function check_name(s,kind) {
- return check_id(s)
- ? null
- : s+"? "+kind+" names must start with a letter and can contain letters, digits, _ and '"
-}
-
-
-function parse_fun(s) {
- var ws=s.split(/\s+/);
- var fun={name:"",type:[]};
- /* Use a state machine to parse function definitions */
- /* f : T1 -> ... -> Tn */
- var state="name";
- var ok=true;
- for(var i=0;ok && i<ws.length;i++) {
- if(ws[i]!="") {
- switch(state) {
- case "name": fun.name=ws[i]; state=":"; break;
- case ":": ok=ws[i]==":"; state="type"; break;
- case "type": fun.type.push(ws[i]); state="->"; break;
- case "->": ok=ws[i]=="->"; state="type"; break;
- }
- }
- }
- var err=check_name(fun.name,"Function");
- if(err) return {error: err};
- return ok && state=="->"
- ? {ok:fun}
- : { error : "Fun : Cat<sub>1</sub> -> ... -> Cat<sub>n</sub>" }
-}
-
-
-function parse_param(s) {
- var ws=s.split("=");
- if(ws.length==2) {
- var name=ws[0].trim();
- var err=check_name(name,"Parameter type");
- return err ? { error:err } : { ok: { name:name,rhs:ws[1].trim() } }
- }
- else
- return { error: "P = C1 | ... | Cn" }
-}
-
-function parse_oper(s) {
- var i=s.indexOf(" ");
- var operr = { error: "op = expr" }
- if(i>0 && i<s.length-1) {
- var name=s.substr(0,i).trim();
- var rhs=s.substr(i).trim();
- var err=check_name(name,"Operator");
- return err
- ? {error:err}
- : rhs!="" ? {ok: {name:name, rhs:rhs}}
- : operr
- }
- else return operr
-
-}
-
-/* --- Print as plain text (normal GF concrete syntax) ---------------------- */
-
-function show_type(t) {
- var s="";
- for(var i in t) {
- if(i>0) s+=" -> ";
- s+=t[i];
- }
- return s;
-}
-
-function show_fun(fun) {
- return fun.name+" : "+show_type(fun.type);
-}
-
-function show_grammar(g) {
- return show_abstract(g)+"\n"+show_concretes(g)
-}
-
-function show_abstract(g) {
-// var startcat= g.abstract.cats.length==1 ? g.abstract.cats[0] : g.abstract.startcat;
- var startcat= g.abstract.startcat || g.abstract.cats[0];
- return "abstract "+g.basename+" = {\n\n"
- +"flags coding = utf8 ;\n\n"
- +show_startcat(startcat)
- +show_cats(g.abstract.cats)
- +show_funs(g.abstract.funs)
- +"}\n";
-}
-
-function show_startcat(startcat) {
- return startcat ? "flags startcat = "+startcat+";\n\n" : "";
-}
-
-function show_cats(cats) {
- return cats.length>0 ? "cat\n "+cats.join("; ")+";\n\n" : "";
-}
-
-function show_funs(funs) { return show_list("fun",show_fun,funs); }
-
-function show_concretes(g) {
- return map(show_concrete(g.basename),g.concretes).join("\n\n");
-}
-
-function show_concrete(basename) {
- return function(conc) {
- return "--# -path=.:present\n"
- + "concrete "+basename+conc.langcode+" of "+basename+" ="
- +show_opens(conc.opens)
- +" {\n\nflags coding = utf8 ;\n\n"
- +show_params(conc.params)
- +show_lincats(conc.lincats)
- +show_opers(conc.opers)
- +show_lins(conc.lins)
- +"}\n"
- }
-}
-
-function show_list(kw,show1,list) {
- return list.length>0
- ? kw+"\n "+map(show1,list).join(";\n ")+";\n\n"
- : ""
-}
-
-function show_opens(opens) {
- return opens && opens.length>0 ? "\n\nopen "+opens.join(", ")+" in" : ""
-}
-
-function show_params(params) { return show_list("param",show_param,params); }
-function show_lincats(lincats) { return show_list("lincat",show_lincat,lincats); }
-function show_opers(opers) { return show_list("oper",show_oper,opers); }
-function show_lins(lins) { return show_list("lin",show_lin,lins); }
-
-
-function show_param(p) { return p.name + " = " + p.rhs; }
-function show_oper(p) { return p.name + " " + p.rhs; }
-function show_lincat(p) { return p.cat + " = " + p.type; }
-
-function show_lin(lin) {
- return lin.fun + " " + lin.args.join(" ")+ " = " + lin.lin;
-} \ No newline at end of file
diff --git a/src/editor/simple/gfse.manifest b/src/editor/simple/gfse.manifest
deleted file mode 100644
index 60c6f3757..000000000
--- a/src/editor/simple/gfse.manifest
+++ /dev/null
@@ -1,4 +0,0 @@
-CACHE MANIFEST
-# 5
-NETWORK:
-*
diff --git a/src/editor/simple/grammars.cgi b/src/editor/simple/grammars.cgi
deleted file mode 100644
index 9f1aa22a6..000000000
--- a/src/editor/simple/grammars.cgi
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-echo "Content-Type: text/javascript"
-echo ""
-
-case "$QUERY_STRING" in
- jsonp=*) prefix="${QUERY_STRING#jsonp=}("; suffix=")" ;;
- *) prefix=""; suffix=""
-esac
-
-echo -n "$prefix"
-sep="["
-for g in *.pgf ; do
- echo -n "$sep\"$g\""
- sep=", "
-done
-echo "]$suffix"
-#echo "/*"
-#set
-#echo "*/"
diff --git a/src/editor/simple/index.html b/src/editor/simple/index.html
deleted file mode 100644
index 27b053300..000000000
--- a/src/editor/simple/index.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<html> <!-- manifest="gfse.manifest" -->
-<head>
-<title>GF online editor for simple multilingual grammars</title>
-<meta charset="UTF-8">
-<link rel="stylesheet" type="text/css" href="editor.css" title="Cloud">
-<link rel="alternate stylesheet" type="text/css" href="molto.css" title="MOLTO">
-
-<link rel=author href="http://www.cse.chalmers.se/~hallgren/" title="Thomas Hallgren">
-
-<meta name = "viewport" content = "width = device-width">
-<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
-
-</head>
-
-<body class=hover>
-
-<h2>GF online editor for simple multilingual grammars</h2>
-<div id=editor>
-</div>
-<small class="hidden">
-<span class=more>+</span>=Add an item,
-<span class=delete>×</span>=Delete item,
-<span class=edit>%</span>=Edit item.
-</small>
-<small class="ifhover">Hover over items for hints and editing options.</small>
-
-<noscript>
-This page does not work without JavaScript.
-</noscript>
-
-<hr>
-<div class=modtime><small>
-HTML
-<!-- hhmts start --> Last modified: Mon Oct 10 17:54:37 CEST 2011 <!-- hhmts end -->
-</small></div>
-<a href="about.html">About</a>
-<pre id=debug></pre>
-<script type="text/javascript" src="config.js"></script> <!-- optional -->
-<script type="text/javascript" src="support.js"></script>
-<script type="text/javascript" src="localstorage.js"></script>
-<script type="text/javascript" src="gf_abs.js"></script>
-<script type="text/javascript" src="example_based.js"></script>
-<script type="text/javascript" src="editor.js"></script>
-<script type="text/javascript" src="cloud.js"></script>
-<script type="text/javascript" src="sort.js"></script>
-</body>
-</html>
diff --git a/src/editor/simple/localstorage.js b/src/editor/simple/localstorage.js
deleted file mode 100644
index 31201998c..000000000
--- a/src/editor/simple/localstorage.js
+++ /dev/null
@@ -1,21 +0,0 @@
-
-// We use localStorage to store the grammars,
-// see http://diveintohtml5.org/storage.html
-
-var local={
- prefix:"gf.editor.simple.grammar",
- get: function (name,def) {
- var id=this.prefix+name
- return localStorage[id] ? JSON.parse(localStorage[id]) : def;
- },
- put: function (name,value) {
- var id=this.prefix+name;
- localStorage[id]=JSON.stringify(value);
- },
- remove: function(name) {
- var id=this.prefix+name;
- localStorage.removeItem(id);
- },
- get count() { return this.get("count",0); },
- set count(v) { this.put("count",v); }
-}
diff --git a/src/editor/simple/molto.css b/src/editor/simple/molto.css
deleted file mode 100644
index 052dda431..000000000
--- a/src/editor/simple/molto.css
+++ /dev/null
@@ -1,82 +0,0 @@
-body { color: #413b36;
- background: #fffcfa;
- }
-h1 { font-size: 175%; }
-h1,h2,h3,h4,small { font-family: sans-serif; }
-h1,h2,h3,h4,a { color: #5c1a1a; }
-
-h1:first-child, h2:first-child { margin-top: 0; margin-bottom: 1ex; }
-
-#editor { max-width: 50em; }
-div.grammar { border: 2px solid #b09779; background: #642121; }
-div.files { margin: 0 8px 8px 8px; }
-
-div#file { border: 2px solid #b0977d; border-top-width: 0; }
-pre.plain { border: 2px solid #b0977d; }
-div#file, pre.plain { background: #fffcfa; padding: 0.6ex; }
-
-.slideshow .hidden { display: none; }
-
-img.right, div.right, div.modtime { float: right; }
-.modtime { color: #999; white-space: nowrap; }
-
-/*div.namebar { background: #642121; }*/
-div.namebar table { width: 100%; }
-.namebar h3 { margin: 0; color: white; }
-
-td.right { text-align: right; }
-
-.kw { font-weight: bold; font-family: sans-serif; color: #642121; }
-.sep { font-weight: bold; color: #642121; }
-
-div.indent { padding-left: 1em; min-width: 1em; min-height: 1em; }
-
-/*
-div.fun, div.param, div.lincat, div.oper, div.lin
-{ padding-left: 2em; text-indent: -2em; }
-*/
-.more, .delete { font-weight: bold; font-family: sans-serif; }
-.more, .delete, .edit { cursor: pointer; }
-
-.hover .more, .hover .delete, .hover .edit { visibility: hidden }
-
-.hover .hidden, .nohover .ifhover { display: none; }
-
-.editable:hover, .deletable:hover { background: #ff9; }
-.namebar .editable:hover { background: #04b; }
-
-.extensible:hover .more,.editable:hover > .edit ,.deletable:hover > .delete
- { visibility: visible; }
-
-.more { color: green; }
-.edit { color: orange; }
-.delete { color: red; }
-.error_message,.inError { color: red; }
-.template, .template .sep { color: #999; }
-form { display: inline-block; }
-
-table.tabs {
- width: 100%;
- border-width: 0; border-spacing: 0; empty-cells: show;
-}
-
-table.tabs td { text-align: center; border: 2px solid #b09779; padding: 2px; }
-table.tabs td.active { background: white; border-bottom-width: 0; }
-table.tabs td.inactive {
- background: #e1e1e1;
- border-top-color: #b09779; border-left-color: #b09779; border-right-color: #b09779;
-}
-
- table.tabs td.gap
-{ border-top-width: 0; border-left-width: 0; border-right-width: 0; }
-
-table.tabs input[type=button] {
- border: 0;
- background: inherit;
- color: #642121;
- font-size: inherit;
- font-weight: bold;
- /*text-decoration: underline;*/
-}
-
-input.string_edit { font-family: inherit; font-size: inherit; } \ No newline at end of file
diff --git a/src/editor/simple/save.hs b/src/editor/simple/save.hs
deleted file mode 100644
index 0472ff5e8..000000000
--- a/src/editor/simple/save.hs
+++ /dev/null
@@ -1,25 +0,0 @@
-import System(getArgs)
-import CGI(getQuery,string)
-import MUtils(apSnd)
-
-main = save2 =<< getArgs
-
-{-
-save1 [dir] =
- do fs@[ns,_] <- readIO =<< getContents
- nes <- save_all fs
- putStrLn $ unwords nes
- where
- save_all [ns,cs] = mapM (write1 dir) (zip ns cs)
--}
-
-write1 dir (n,c) =
- do writeFile (dir++"/"++ne) c
- return ne
- where
- ne=if '.' `elem` n then n else n++".gf"
-
-save2 [dir] =
- do nfs <- getQuery
- nes <- mapM (write1 dir . apSnd string) nfs
- putStrLn $ unwords nes
diff --git a/src/editor/simple/share.html b/src/editor/simple/share.html
deleted file mode 100644
index 643d298ba..000000000
--- a/src/editor/simple/share.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html> <head>
-<title>Download from Grammar Cloud</title>
-<link rel="stylesheet" type="text/css" href="editor.css" title="Cloud">
-<link rel="alternate stylesheet" type="text/css" href="molto.css" title="MOLTO">
-
-</head>
-
-<body>
-<h1><img src="P/1307545048_weather_09.png" alt="">Download from Grammar Cloud</h1>
-
-<pre id=debug></pre>
-
-<hr>
-<address></address>
-<!-- hhmts start --> Last modified: Mon Aug 1 16:24:44 CEST 2011 <!-- hhmts end -->
-<script type="text/javascript" src="support.js"></script>
-<script type="text/javascript" src="localstorage.js"></script>
-<script type="text/javascript" src="gf_abs.js"></script>
-<script type="text/javascript" src="editor.js"></script>
-<script type="text/javascript" src="cloud.js"></script>
-<script type="text/javascript" src="sort.js"></script>
-<script type="text/javascript">
-download_from_cloud();
-</script>
-</body>
-</html>
diff --git a/src/editor/simple/slideshow.js b/src/editor/simple/slideshow.js
deleted file mode 100644
index 307bcd98f..000000000
--- a/src/editor/simple/slideshow.js
+++ /dev/null
@@ -1,86 +0,0 @@
-
-var internet_explorer=navigator.appName=="Microsoft Internet Explorer";
-
-/* How to change opacity in IE:
-http://joseph.randomnetworks.com/archives/2006/08/16/css-opacity-in-internet-explorer-ie/
-*/
-
-var set_opacity =
- internet_explorer
- ? function(el,o) { el.style.filter="alpha(opacity="+Math.round(o*100)+")";}
- : function(el,o) { el.style.opacity=o; };
-
-function start_slideshow(img,options) {
- var p=img.parentNode;
- if(p.tagName=="A") p=p.parentNode;
- var is=p.getElementsByTagName("img");
- if(is.length>1) {
- var cur=0;
- var w=img.width;
- var h=img.height;
- //p.style.position="relative";
- p.style.minWidth=w+"px";
- p.style.minHeight=h+"px";
- var images=[];
- for(var i=0;i<is.length;i++) {
- images[i]=is[i];
- var c=images[i];
- if(internet_explorer) c.style.zoom=1;
- c.style.position="absolute";
- }
- var timeout=1000*(options.delay || 5);
- var ft=options.fade==null ? 1 : options.fade;
- var tick=function() {
- var c=images[cur];
- cur= (cur+1) % images.length;
- var n=images[cur];
- set_opacity(n,0);
- //n.style.position="static";
- n.style.zIndex=1;
- n.className="";
- if(n.width>w) { w=n.width; p.style.minWidth=w+"px"; }
- if(n.height>h) { h=n.height; p.style.minHeight=h+"px"; }
- c.style.position="absolute";
- c.style.zIndex=0;
- fade(n,0,1,ft,function() {
- if(c.width>n.width || c.height>n.height) fade(c,1,0,ft,null);
- else set_opacity(c,0); });
- //debug.innerHTML=w+"x"+h;
- //for(var i=0;i<images.length;i++)
- //debug.appendChild(text(" "+images[i].style.position));
- }
- //var debug=document.createElement("div");
- //p.parentNode.insertBefore(debug,p);
- //debug.innerHTML=w+"x"+h;
- setInterval(tick,timeout);
- }
- //else alert("No slideshow!");
-}
-
-function fade(el,start,stop,t,after) {
- // el: which element to fade
- // start: starting opacity [0..1]
- // stop: ending opacity [0..1]
- // t: duration of fade (in seconds), default 1s
- // after: function to call when done fading, optional
- var dt=40; // Animation granularity, 1/40ms = 25fps
- el.step=(stop-start)*dt/(1000*(t==null ? 1 : t));
- el.stop=stop;
- //alert("fade "+start+" "+stop+" "+el.step);
- var done=function() {
- clearInterval(el.timer);
- el.timer=null;
- if(after) after();
- }
- var f=function() {
- var next=el.current+el.step;
- if(next>=1) { next=1; done(); }
- if(next<=0) { next=0; done(); }
- set_opacity(el,next);
- el.current=next
- }
- if(!el.timer) {
- el.current=start;
- el.timer=setInterval(f,dt);
- }
-}
diff --git a/src/editor/simple/upload.cgi b/src/editor/simple/upload.cgi
deleted file mode 100644
index 87b868f53..000000000
--- a/src/editor/simple/upload.cgi
+++ /dev/null
@@ -1,252 +0,0 @@
-#!/bin/bash
-
-bin=/Users/hallgren/www/bin
-
-charset="UTF-8"
-AUTOHEADER=no
-
-. $bin/cgistart.sh
-export LC_CTYPE="UTF-8"
-style_url="editor.css"
-
-tmp="$documentRoot/tmp"
-
-make_dir() {
- dir="$(mktemp -d "$tmp/gfse.XXXXXXXXXX")"
-# chmod a+rxw "$dir"
- chmod a+rx "$dir"
- cp "grammars.cgi" "$dir"
-}
-
-
-check_grammar() {
- pagestart "Uploaded"
-# echo "$PATH_INFO"
- chgrp everyone "$dir"
- chmod g+ws "$dir"
- umask 002
-# files=( $(Reg from-url | LC_CTYPE=sv_SE.ISO8859-1 ./save "$dir") )
- files=( $(LC_CTYPE=sv_SE.ISO8859-1 ./save "$dir") )
- gffiles=( )
- otherfiles=( )
- for f in ${files[*]} ; do
- case "$f" in
- *.gf) gffiles=( ${gffiles[*]} "$f" ) ;;
- *) otherfiles=( ${otherfiles[*]} "$f" ) ;;
- esac
- done
-
- if [ ${#otherfiles} -gt 0 -a -n "$PATH_INFO" ] ; then
- echo "Use the following link for shared access to your grammars from multiple devices:"
- begin ul
- case "$SERVER_PORT" in
- 80) port="" ;;
- *) port=":$SERVER_PORT"
- esac
- parent="http://$SERVER_NAME$port${REQUEST_URI%/upload.cgi/tmp/gfse.*}"
- cloudurl="$parent/share.html#${dir##*/}"
- li; link "$cloudurl" "$cloudurl"
- end
- #begin dl
- #dt ; echo "◂"; link "javascript:history.back()" "Back to Editor"
- #end
- fi
-
- cd $dir
- if [ ${#gffiles} -gt 0 ] ; then
- begin pre
- echo "gf -s -make ${gffiles[*]}"
- if gf -s -make ${gffiles[*]} 2>&1 ; then
- end
- h3 OK
- begin dl
- [ -z "$minibar_url" ] || { dt; echo "▸"; link "$minibar_url?/tmp/${dir##*/}/" "Minibar"; }
- [ -z "$transquiz_url" ] || { dt; echo "▸"; link "$transquiz_url?/tmp/${dir##*/}/" "Translation Quiz"; }
- [ -z "$gfshell_url" ] || { dt; echo "▸"; link "$gfshell_url?dir=${dir##*/}" "GF Shell"; }
- dt ; echo "◂"; link "javascript:history.back()" "Back to Editor"
-
- end
- sed=();
- for pgf in *.pgf ; do
- sed=("${sed[@]}" -e "s%$pgf%<a href=\"${dir##*/}/$pgf\">$pgf</a>%")
- done
- begin pre
- ls -l *.pgf | sed "${sed[@]}"
- end
- else
- end
- begin h3 class=error_message; echo Error; end
- for f in ${gffiles[*]} ; do
- h4 "$f"
- begin pre class=plain
- cat -n "$f"
- end
- done
- fi
- fi
- begin div class=footer
- hr
- date
- end
-# begin pre ; env
- endall
-}
-
-error400() {
- echo "Status: 400"
- pagestart "Error"
- echo "What do you want?"
- endall
-}
-
-error404() {
- echo "Status: 404"
- pagestart "Not found"
- echo "Not found"
- endall
-}
-
-if [ -z "$tmp" ] || ! [ -d "$tmp" ] ; then
- pagestart "Error"
- begin pre
- echo "upload.cgi is not properly configured:"
- if [ -z "$tmp" ] ; then
- echo "cgiconfig.sh must define tmp"
- elif [ ! -d "$tmp" ] || [ ! -w "$tmp" ] ; then
- echo "$tmp must be a writeable directory"
- fi
- # cgiconfig.sh should define minibar & gfshell to allow grammars to be tested.
- endall
-else
-case "$REQUEST_METHOD" in
- POST)
- case "$PATH_INFO" in
- /tmp/gfse.*)
- style_url="../../$style_url"
- dir="$tmp/${PATH_INFO##*/}"
- check_grammar
- ;;
- *)
- make_dir
- echo >&2 "Using temporary directory $dir"
- check_grammar
- rm -rf "$dir"
- esac
- ;;
- GET)
- case "$QUERY_STRING" in
- dir) make_dir
- ContentType="text/plain"
- cgiheaders
- echo_n "/tmp/${dir##*/}"
- ;;
- ls=*)
- dir=$(qparse "$QUERY_STRING" ls)
- case "$dir" in
- /tmp/gfse.*) # shouldn't allow .. in path !!!
- path="$documentRoot$dir"
- if [ -d "$path" ] ; then
- ContentType="text/plain; charset=$charset"
- cgiheaders
- cd "$path"
- shopt -s nullglob
- echo_n *-*.json
- else
- error404
- fi
- ;;
- *) error400
- esac
- ;;
- rmdir=*)
- dir=$(qparse "$QUERY_STRING" rmdir)
- case "$dir" in
- /tmp/gfse.*) # shouldn't allow .. in path !!!
- path="$documentRoot$dir"
- if [ -d "$path" ] ; then
- ContentType="text/plain; charset=$charset"
- cgiheaders
- if [ -h "$path" ] ; then
- cd "$path"
- cd ..
- rm "$path"
- else
- cd "$path"
- shopt -s nullglob
- rm *.gf *.gfo *-*.json *.pgf grammars.cgi
- cd ..
- rmdir "$path"
- fi
- newdir=$(qparse "$QUERY_STRING" newdir)
- case "$newdir" in
- /tmp/gfse.*) # shouldn't allow .. in path !!!
- newnode="${newdir##*/}"
- oldnode="${path##*/}"
- ln -s "$newnode" "$oldnode"
- esac
- else
- error404
- fi
- ;;
- *) error400
- esac
- ;;
- download=*)
- file=$(qparse "$QUERY_STRING" download)
- case "$file" in
- /tmp/gfse.*/*.json) # shouldn't allow .. in path !!!
- path="$documentRoot$file"
- if [ -r "$path" ] ; then
- ContentType="text/javascript; charset=$charset"
- cgiheaders
- cat "$path"
- else
- error404
- fi
- ;;
- *) error400
- esac
- ;;
- rm=*)
- file=$(qparse "$QUERY_STRING" rm)
- case "$file" in
- /tmp/gfse.*/*.json) # shouldn't allow .. in path !!!
- path="$documentRoot$file"
- if [ -r "$path" ] ; then
- ContentType="text/javascript; charset=$charset"
- cgiheaders
- rm "$path"
- else
- error404
- fi
- ;;
- *) error400
- esac
- ;;
- cc=*)
- # Just to check an expression for syntax errors
- exp=$(qparse "$QUERY_STRING" cc)
- ContentType="text/plain; charset=$charset"
- cgiheaders
- echo "cc $exp" | GF_RESTRICTED=True gf -run
- ;;
- "")
- case "$PATH_INFO" in
- /tmp/gfse.*/*.pgf)
- path="$documentRoot$PATH_INFO"
- if [ -r $path ] ; then
- ContentType="application/binary"
- cgiheaders
- cat "$path"
- else
- error404
- fi
- ;;
- *)
- error400
- esac
- ;;
- *) error400
- esac
-esac
-fi