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 050c8b7396
commit d6ae92f1df
5 changed files with 167 additions and 105 deletions

View File

@@ -10,23 +10,35 @@ basedir=${dir}/../../src
tagsdir=${dir}/tags
index=${dir}/index.json
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)
rm -f $index
echo "{\n\"languages\": {" >> $index
for dir in `ls "$basedir/"`
do
if [ -d "$basedir/$dir" ]; then
cd $basedir/$dir
echo "Processing folder:" `pwd`
echo " \"${dir}\": [" >> $index
find -maxdepth 1 -name '*.gf' | while read -r file
do
gf --batch --quiet --tags --output-dir=${tagsdir} $file 2>/dev/null
echo " \""`echo $file | sed 's|./||;s|.gf||'`"\"," >> $index
done
echo " \"\"\n ]," >> $index
fi
if ! in_ignore $dir && [ -d "$basedir/$dir" ] ; then
cd $basedir/$dir
echo "Processing folder:" `pwd`
echo " \"${dir}\": [" >> $index
find -maxdepth 1 -name '*.gf' | while read -r file
do
gf --batch --quiet --tags --output-dir=${tagsdir} $file 2>/dev/null
echo " \""`echo $file | sed 's|./||;s|.gf||'`"\"," >> $index
done
echo " \"\"\n ]," >> $index
fi
done
echo " \"\":{}\n}\n}" >> $index

View File

@@ -12,15 +12,13 @@
<body>
<header>
<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>
<div role="main">
<div class="pane left">
<div id="languages"></div>
<div id="modules"></div>
</div>
<div class="pane right">
<div id="tabbar">
<h2></h2>
@@ -30,26 +28,60 @@
</div>
<div id="scope" class="panel scope">
<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" />
<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 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>
<br style="clear:both">
<br style="clear:both" />
</div>
<footer id="footer">
<h3>About the GF RGL Browser</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 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>
<p><em>John J. Camilleri, 2012</em></p>
</footer>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="script.js"></script>

View File

@@ -376,32 +376,6 @@
"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": [
"NounDut",
"IrregDutAbs",
@@ -846,11 +820,6 @@
"ExtraMlt",
""
],
"mini": [
"MiniGrammar",
"MiniGrammarEng",
""
],
"nepali": [
"IdiomNep",
"AllNepAbs",
@@ -1313,10 +1282,6 @@
"ConjunctionTha",
""
],
"tmp": [
"CompatibilityEng",
""
],
"turkish": [
"LangTur",
"ResTur",

View File

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

View File

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