1
0
forked from GitHub/gf-rgl

RGL Browser: small user guide, less crash-prone

This commit is contained in:
john.j.camilleri
2012-05-14 14:29:11 +00:00
parent 89f9565617
commit 066a0f2b3e
5 changed files with 167 additions and 105 deletions

View File

@@ -10,23 +10,35 @@ basedir=${dir}/../../src
tagsdir=${dir}/tags tagsdir=${dir}/tags
index=${dir}/index.json index=${dir}/index.json
removeprefix="/home/john/repositories/GF" removeprefix="/home/john/repositories/GF"
ignore="demo old-demo tmp"
# Function for testing array membership
in_ignore() {
local search="$1"
for i in $ignore; do
if [ "$i" = "$search" ]; then
return 0
fi
done
return 1
}
# Iterate and build all the tags (takes some time) # Iterate and build all the tags (takes some time)
rm -f $index rm -f $index
echo "{\n\"languages\": {" >> $index echo "{\n\"languages\": {" >> $index
for dir in `ls "$basedir/"` for dir in `ls "$basedir/"`
do do
if [ -d "$basedir/$dir" ]; then if ! in_ignore $dir && [ -d "$basedir/$dir" ] ; then
cd $basedir/$dir cd $basedir/$dir
echo "Processing folder:" `pwd` echo "Processing folder:" `pwd`
echo " \"${dir}\": [" >> $index echo " \"${dir}\": [" >> $index
find -maxdepth 1 -name '*.gf' | while read -r file find -maxdepth 1 -name '*.gf' | while read -r file
do do
gf --batch --quiet --tags --output-dir=${tagsdir} $file 2>/dev/null gf --batch --quiet --tags --output-dir=${tagsdir} $file 2>/dev/null
echo " \""`echo $file | sed 's|./||;s|.gf||'`"\"," >> $index echo " \""`echo $file | sed 's|./||;s|.gf||'`"\"," >> $index
done done
echo " \"\"\n ]," >> $index echo " \"\"\n ]," >> $index
fi fi
done done
echo " \"\":{}\n}\n}" >> $index echo " \"\":{}\n}\n}" >> $index

View File

@@ -12,15 +12,13 @@
<body> <body>
<header> <header>
<h1>GF RGL Browser</h1> <h1>GF RGL Browser</h1>
<p style="font-style:italic;margin-top:-0.5em;">Updated 2012-05-11. <a href="#footer">About this tool</a></p> <p style="font-style:italic;margin-top:-0.5em;">Updated 2012-05-14</p>
</header> </header>
<div role="main"> <div role="main">
<div class="pane left"> <div class="pane left">
<div id="languages"></div> <div id="languages"></div>
<div id="modules"></div> <div id="modules"></div>
</div> </div>
<div class="pane right"> <div class="pane right">
<div id="tabbar"> <div id="tabbar">
<h2></h2> <h2></h2>
@@ -30,26 +28,60 @@
</div> </div>
<div id="scope" class="panel scope"> <div id="scope" class="panel scope">
<input type="text" id="search" /> <input type="text" id="search" />
<input type="submit" id="submit" value="Filter" />
<input type="reset" id="clear" value="Clear" />
<input type="checkbox" id="case_sensitive" checked="checked" /> <input type="checkbox" id="case_sensitive" checked="checked" />
<label for="case_sensitive">Case sensitive?</label> <label for="case_sensitive">Case sensitive?</label>
<dl></dl> <div><span id="scope_count">0</span> items</div>
<dl id="scope_list"></dl>
</div> </div>
<div id="code" class="panel code"></div> <div id="code" class="panel code"></div>
<div id="help" class="panel help">
<h3>Understanding the scope information</h3>
<p>The scope information shown by this tool is basically the output of running GF with the <code>--tags</code> flag. This lists all the functions visible in the scope of a module, one per line. Each line can have two possible forms:</p>
<h4>1. Local functions</h4>
<pre>mkPrep oper-type /lib/src/english/ParadigmsEng.gf:204 Str -> {s : Str; lock_Prep : {}}</pre>
<p>For locally defined functions, the second column <code>oper-type</code> indicates the judgement type, followed by the location in the souce file and its type information.</p>
<h4>2. External functions</h4>
<pre>Number indir ResEng R /lib/doc/browse/tags/ParamX.gf-tags</pre>
<p>The <code>indir</code> indicates this function is defined in an external module (note that no distinction is made between functions from opened modules and inherited ones.) <code>ResEng</code> is the name of the opened or inherited module, while <code>R</code> is the alias under which it was opened. The final column points to another tags file where the type information for this function can be found. Note that though the function is available in the given context via the <code>ResEng</code> module, it is actually originally defined in <code>ParamX</code>.</p>
<h3>The RGL directory structure</h3>
<p>The drop-down at the top left lists all child directories under <code><a href="http://www.grammaticalframework.org/lib/src/">/lib/src</a></code> in the GF source code repository. Most directories represent individual languages, however many have special functions:</p>
<dl>
<dt><code>abstract</code></dt><dd>Abstract syntaxes shared by all resource grammars</dd>
<dt><code>api</code></dt><dd>The RGL API and instantiations of the API modules in all languages</dd>
<dt><code>common</code></dt><dd>Resource modules common to all languages</dd>
<dt><code>parametric</code></dt><dd></dd>
<dt><code>prelude</code></dt><dd>Common low-level functions</dd>
</dl>
In addition, the following directories are not individual languages but language functors, shared by resource grammars for related language families:
<dl>
<dt><code>hindustani</code></dt><dd>Used by Hindi, Persian, Punjabi, Urdu</dd>
<dt><code>romance</code></dt><dd>Used by Catalan, French, Italian, Romanian, Spanish</dd>
<dt><code>scandinavian</code></dt><dd>Used by Danish, Norwegian, Swedish</dd>
</dl>
<h3>About</h3>
<p>A basic tool for looking up module scopes and quickly looking at module sources, created out of necessity. It is experimental and has only been tested on the latest Chrome under Ubuntu. Even then, the page sometimes crashes and has to be closed. All feedback is welcome.</p>
<h3>Known issues and To-do</h3>
<ul>
<li>The page sometimes stalls when handling large files (in particular the dictionary modules)</li>
<li>Jump directly to line in file</li>
<li>Line numbers and syntax highlighting for source code would be cool</li>
</ul>
</div>
</div> </div>
<br style="clear:both" />
<br style="clear:both">
</div> </div>
<footer id="footer"> <footer id="footer">
<h3>About the GF RGL Browser</h3> <p><em>John J. Camilleri, 2012</em></p>
<p>A basic tool for looking up module scopes and quickly looking at module sources, created out of necessity. It is experimental and has only been tested on the latest Chrome under Ubuntu. Even then, the page sometimes crashes and has to be closed. All feedback welcome.<br/>
To do:</p>
<ul>
<li>Test from other browsers</li>
<li>Stop from crashing occasionally</li>
<li>Line numbers and syntax highlighting for source code would be cool</li>
</ul>
<p><em>John J. Camilleri, 2012</em></p>
</footer> </footer>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="script.js"></script> <script src="script.js"></script>

View File

@@ -376,32 +376,6 @@
"SymbolDan", "SymbolDan",
"" ""
], ],
"demo": [
"DemoDut",
"DemoSpa",
"DemoIna",
"DemoHin",
"DemoNor",
"DemoFre",
"DemoPol",
"DemoRon",
"DemoLat",
"DemoTur",
"DemoDan",
"DemoGer",
"DemoUrd",
"DemoCat",
"DemoEng",
"DemoRus",
"Demo",
"DemoIta",
"DemoFin",
"DemoTha",
"DemoBul",
"DemoAra",
"DemoSwe",
""
],
"dutch": [ "dutch": [
"NounDut", "NounDut",
"IrregDutAbs", "IrregDutAbs",
@@ -846,11 +820,6 @@
"ExtraMlt", "ExtraMlt",
"" ""
], ],
"mini": [
"MiniGrammar",
"MiniGrammarEng",
""
],
"nepali": [ "nepali": [
"IdiomNep", "IdiomNep",
"AllNepAbs", "AllNepAbs",
@@ -1313,10 +1282,6 @@
"ConjunctionTha", "ConjunctionTha",
"" ""
], ],
"tmp": [
"CompatibilityEng",
""
],
"turkish": [ "turkish": [
"LangTur", "LangTur",
"ResTur", "ResTur",

View File

@@ -1,38 +1,54 @@
/* /*
GF RGL Browser GF RGL Browser
John J. Camiller, 2012 John J. Camilleri, 2012
*/ */
$(document).ready(function() { $(document).ready(function() {
// var urlPrefix = "/GF"; // local // var urlPrefix = "/GF"; // local
var urlPrefix = ""; // live var urlPrefix = ""; // live
var loading = function(b){
if (b)
$("#loading").show();
else
$("#loading").hide();
}
var scrollToTop = function(){ var scrollToTop = function(){
$("html, body").animate({ scrollTop: 0 }, "slow"); $("html, body").animate({ scrollTop: 0 }, "slow");
} }
var current_language = undefined; var current_language = undefined;
var index; var index;
$.getJSON("index.json", function(data){ $.ajax({
index = data; url: "index.json",
dataType: "json",
type: "GET",
success: function(data){
index = data;
// Initialize the language list // Initialize the language list
var lang_select = $("<select>") var lang_select = $("<select>")
.attr('id', 'language_select') .attr('id', 'language_select')
.change(function(){ .change(function(){
setLanguage($(this).val()); setLanguage($(this).val());
}) })
.appendTo("#languages") .appendTo("#languages")
var language_list = data['languages']; var language_list = data['languages'];
for (i in language_list) { for (i in language_list) {
if (!i) continue; if (!i) continue;
var lang = i; var lang = i;
$('<option>') $('<option>')
.html(lang) .html(lang)
.appendTo(lang_select); .appendTo(lang_select);
}
setLanguage("english");
loading(false);
},
error: function(){
alert("Error getting index. Try reloading page, or just give up.");
loading(false);
} }
setLanguage("english");
$("#loading").hide();
}); });
var setLanguage = function(lang){ var setLanguage = function(lang){
@@ -44,7 +60,7 @@ $(document).ready(function() {
// Initialize the module list // Initialize the module list
var initModules = function(lang){ var initModules = function(lang){
index['languages'][lang] = index['languages'][lang].sort(); index['languages'][lang] = index['languages'][lang].sort();
$("#modules").html(""); $("#modules").empty();
for (i in index['languages'][lang]) { for (i in index['languages'][lang]) {
var module = index['languages'][lang][i]; var module = index['languages'][lang][i];
if (!module) continue; if (!module) continue;
@@ -66,20 +82,28 @@ $(document).ready(function() {
$(obj).show(); // obj can be just a plain selector or a jQuery object $(obj).show(); // obj can be just a plain selector or a jQuery object
} }
$(".panel").each(function(a,b){ $(".panel").each(function(a,b){
$("<span>") $("<a>")
.addClass('tab').addClass($(b).attr('id')) .addClass('tab')
.addClass($(b).attr('id'))
.attr('href', '#'+$(b).attr('id'))
.html($(b).attr('id')) .html($(b).attr('id'))
.click(function(){ .click(function(){
showPanel(b); showPanel(b);
return false;
}) })
.insertBefore("#loading"); .insertBefore("#loading");
}); });
showPanel(".panel:first"); showPanel(".panel:first");
var setTitle = function(s){ var setTitle = function(s){
$('#tabbar h2').html(s); $('#tabbar h2').html(s);
} }
var updateScopeCount = function(){
$('#scope_count').text( $("#scope_list dt:visible").length );
}
// Load both scope & source for a file
var loadFile = function(lang, module){ var loadFile = function(lang, module){
setTitle(lang+"/"+module); setTitle(lang+"/"+module);
loadTagsFile(module); loadTagsFile(module);
@@ -89,17 +113,21 @@ $(document).ready(function() {
// Load a tags file // Load a tags file
var loadTagsFile = function(module) { var loadTagsFile = function(module) {
$('#search').val(""); $('#search').val("");
$('#scope dl').html(""); $('#scope dl').empty();
$("#loading").show(); updateScopeCount();
loading(true);
$.ajax({ $.ajax({
url: "tags/"+module+".gf-tags", url: "tags/"+module+".gf-tags",
type: "GET", type: "GET",
dataType: "text", dataType: "text",
success: function(data){ success: function(data){
var data = data.replace(/^(\S+)\s+(.+)$/gm, '<dt name="$1">$1</dt><dd name="$1">$2</dd>'); data = data.replace(/^(\S+)\s+(.+)$/gm, '<dt name="$1">$1</dt><dd name="$1">$2</dd>');
// data = data.replace(/^(\S+)\s(\S+)\s(\S+)(.+)?$/gm, function(a,b,c,d,e){
// return '<tr name="'+b+'"><th>'+b+'</th><td>'+c+'</td><td>'+d+'</td><td>'+e+'</td></tr>'
// });
data = data.replace(/\s(\/lib\/\S+?\.gf(-tags)?)/gm, '<a href="$1">$1</a>'); data = data.replace(/\s(\/lib\/\S+?\.gf(-tags)?)/gm, '<a href="$1">$1</a>');
$('#scope dl').html(data); $('#scope_list').html(data);
$('#scope dl a').click(function(){ $('#scope_list a').click(function(){
var href = $(this).attr('href'); var href = $(this).attr('href');
var m = href.match(/([^\/]+)\/([^\/]+)\.(gf(-tags)?)$/); var m = href.match(/([^\/]+)\/([^\/]+)\.(gf(-tags)?)$/);
if (m[3]=="gf") { if (m[3]=="gf") {
@@ -116,7 +144,7 @@ $(document).ready(function() {
onerror: function(){ onerror: function(){
// Load just tags (we don't know source) // Load just tags (we don't know source)
setTitle(m[2]+" (scope only)"); setTitle(m[2]+" (scope only)");
$('#code').html(""); $('#code').empty();
loadTagsFile(m[2]); loadTagsFile(m[2]);
} }
}); });
@@ -124,15 +152,17 @@ $(document).ready(function() {
scrollToTop(); scrollToTop();
return false; return false;
}); });
$("#loading").hide(); updateScopeCount();
loading(false);
}, },
error: function(data){ error: function(data){
$('#scope dl').html("<em>No scope available</em>"); $('#scope_list').html("<em>No scope available</em>");
$("#loading").hide(); loading(false);
}, },
}); });
} }
// Just get the HTTP headers to see if a file exists
var checkSourceFile = function(args) { var checkSourceFile = function(args) {
$.ajax({ $.ajax({
url: urlPrefix + "/lib/src/"+args.lang+"/"+args.module+".gf", url: urlPrefix + "/lib/src/"+args.lang+"/"+args.module+".gf",
@@ -144,19 +174,19 @@ $(document).ready(function() {
// Load a source module // Load a source module
var loadSourceFile = function(lang, module) { var loadSourceFile = function(lang, module) {
$('#code').html(""); $('#code').empty();
$("#loading").show(); loading(true);
$.ajax({ $.ajax({
url: urlPrefix + "/lib/src/"+lang+"/"+module+".gf", url: urlPrefix + "/lib/src/"+lang+"/"+module+".gf",
type: "GET", type: "GET",
dataType: "text", dataType: "text",
success: function(data){ success: function(data){
$('#code').html(data); $('#code').html(data);
$("#loading").hide(); loading(false);
}, },
error: function(data){ error: function(data){
$('#code').html("<em>No code available</em>"); $('#code').html("<em>No code available</em>");
$("#loading").hide(); loading(false);
} }
}); });
} }
@@ -175,11 +205,33 @@ $(document).ready(function() {
var runfilter = function() { var runfilter = function() {
// Hide anything which doesn't match // Hide anything which doesn't match
var s = $("#search").val(); var s = $("#search").val();
$("#scope dl *").show(); loading(true);
if (s) try {
$("#scope dl *:not(:match(\""+s+"\"))").hide(); if (s) {
$("#scope_list").children( ":match(\""+s+"\")").show();
$("#scope_list").children(":not(:match(\""+s+"\"))").hide();
//$("#scope_list tr:not(:match(\""+s+"\"))").hide();
} else {
$("#scope_list").children().show();
}
} catch (error) {
alert(error.message);
}
updateScopeCount();
loading(false);
} }
$("#search").keyup(runfilter); // $("#search").keyup(runfilter);
$("#search").keypress(function(e){
var code = (e.keyCode ? e.keyCode : e.which);
if(code == 13) { // Enter
runfilter();
}
});
$("#submit").click(runfilter);
$("#clear").click(function(){
$("#search").val('');
runfilter();
});
$("#case_sensitive").change(runfilter); $("#case_sensitive").change(runfilter);
}); });

View File

@@ -88,12 +88,13 @@ input#search
{ {
padding: 1em; padding: 1em;
} }
#scope dl #scope_list
{ {
font-family:monospace; font-family:monospace;
} }
#scope dl a #scope_list dt
{ {
float:left;
} }
#code #code
{ {