diff --git a/src/main/java/com/metaweb/gridworks/expr/controls/With.java b/src/main/java/com/metaweb/gridworks/expr/controls/With.java
index d311d1e08..31d41b7a1 100644
--- a/src/main/java/com/metaweb/gridworks/expr/controls/With.java
+++ b/src/main/java/com/metaweb/gridworks/expr/controls/With.java
@@ -43,7 +43,7 @@ public class With implements Control {
writer.key("description"); writer.value(
"Evaluates expression o and binds its value to variable name v. Then evaluates expression e and returns that result"
);
- writer.key("params"); writer.value("expression o, variable v, expression eNonBlank, expression eBlank");
+ writer.key("params"); writer.value("expression o, variable v, expression e");
writer.key("returns"); writer.value("Depends on actual arguments");
writer.endObject();
}
diff --git a/src/main/java/com/metaweb/gridworks/protograph/Protograph.java b/src/main/java/com/metaweb/gridworks/protograph/Protograph.java
index 236266193..9c553a26e 100644
--- a/src/main/java/com/metaweb/gridworks/protograph/Protograph.java
+++ b/src/main/java/com/metaweb/gridworks/protograph/Protograph.java
@@ -50,11 +50,13 @@ public class Protograph implements Serializable, Jsonizable {
String columnName = o.getString("columnName");
if ("cell-as-topic".equals(nodeType)) {
- node = new CellTopicNode(
- columnName,
- o.getBoolean("createForNoReconMatch"),
- reconstructType(o.getJSONObject("type"))
- );
+ if (o.has("type")) {
+ node = new CellTopicNode(
+ columnName,
+ o.getBoolean("createForNoReconMatch"),
+ reconstructType(o.getJSONObject("type"))
+ );
+ }
} else if ("cell-as-value".equals(nodeType)) {
node = new CellValueNode(
columnName,
diff --git a/src/main/webapp/scripts/project/expression-preview-dialog.js b/src/main/webapp/scripts/project/expression-preview-dialog.js
index 65ea302d5..5df517f1d 100644
--- a/src/main/webapp/scripts/project/expression-preview-dialog.js
+++ b/src/main/webapp/scripts/project/expression-preview-dialog.js
@@ -81,33 +81,70 @@ ExpressionPreviewDialog.prototype._renderHelpTab = function() {
ExpressionPreviewDialog.prototype._renderHelp = function(data) {
var elmt = this._elmts.helpTabBody.empty();
+ $('
').text("Variables").appendTo(elmt);
+ var varTable = $('').appendTo(elmt)[0];
+ var vars = [
+ { name: "cell",
+ description: "The current cell. It has a few fields: 'value' and 'recon'."
+ },
+ { name: "value",
+ description: "The current cell's value. This is a shortcut for 'cell.value'."
+ },
+ { name: "row",
+ description: "The current row. It has 4 fields: 'flagged', 'starred', 'index', and 'cells'."
+ },
+ { name: "cells",
+ description: "The cells of the current row. This is a shortcut for 'row.cells'. " +
+ "A particular cell can be retrieved with 'cells.' if the is a single word, " +
+ "or with 'cells[\"\"] otherwise."
+ },
+ { name: "rowIndex",
+ description: "The current row's index. This is a shortcut for 'row.index'."
+ }
+ ];
+ for (var i = 0; i < vars.length; i++) {
+ var variable = vars[i];
+ var tr = varTable.insertRow(varTable.rows.length);
+ $(tr.insertCell(0)).addClass("expression-preview-doc-item-title").text(variable.name);
+ $(tr.insertCell(1)).addClass("expression-preview-doc-item-desc").text(variable.description);
+ }
+
var renderEntry = function(table, name, entry) {
var tr0 = table.insertRow(table.rows.length);
var tr1 = table.insertRow(table.rows.length);
var tr2 = table.insertRow(table.rows.length);
- $(tr0.insertCell(0)).text(name);
- $(tr0.insertCell(1)).text("(" + entry.params + ")");
+ $(tr0.insertCell(0)).addClass("expression-preview-doc-item-title").text(name);
+ $(tr0.insertCell(1)).addClass("expression-preview-doc-item-params").text("(" + entry.params + ")");
$(tr1.insertCell(0));
- $(tr1.insertCell(1)).text("returns: " + entry.returns);
+ $(tr1.insertCell(1)).addClass("expression-preview-doc-item-returns").text("returns: " + entry.returns);
$(tr2.insertCell(0));
- $(tr2.insertCell(1)).text(entry.description);
+ $(tr2.insertCell(1)).addClass("expression-preview-doc-item-desc").text(entry.description);
+ };
+ var renderEntries = function(table, map) {
+ var names = [];
+ for (var n in map) {
+ if (map.hasOwnProperty(n)) {
+ names.push(n);
+ }
+ }
+ names.sort();
+
+ for (var i = 0; i < names.length; i++) {
+ var name = names[i];
+ renderEntry(table, name, map[name]);
+ }
};
$('').text("Functions").appendTo(elmt);
- var functionTable = $('').appendTo(elmt)[0];
+ var functionTable = $('').appendTo(elmt)[0];
+ renderEntries(functionTable, data.functions);
$('').text("Controls").appendTo(elmt);
- var controlTable = $('').appendTo(elmt)[0];
-
- for (var n in data.functions) {
- renderEntry(functionTable, n, data.functions[n]);
- }
- for (var n in data.controls) {
- renderEntry(controlTable, n, data.controls[n]);
- }
+ var controlTable = $('').appendTo(elmt)[0];
+ renderEntries(controlTable, data.controls);
};
ExpressionPreviewDialog.prototype._scheduleUpdate = function() {
diff --git a/src/main/webapp/styles/expression-preview-dialog.css b/src/main/webapp/styles/expression-preview-dialog.css
index 77dbd70bc..3a4e2faa7 100644
--- a/src/main/webapp/styles/expression-preview-dialog.css
+++ b/src/main/webapp/styles/expression-preview-dialog.css
@@ -2,11 +2,6 @@
padding: 7px;
}
-.expression-preview-help-container {
- height: 300px;
- padding: 5px;
- overflow: auto;
-}
.expression-preview-container {
height: 300px;
padding: 5px;
@@ -26,4 +21,30 @@ td.expression-preview-heading {
.expression-preview-empty {
color: #aaa;
+}
+
+.expression-preview-help-container {
+ height: 300px;
+ padding: 5px;
+ overflow: auto;
+}
+
+.expression-preview-help-container h3 {
+ background: white;
+ padding: 3px 10px;
+}
+
+.expression-preview-doc-item-title {
+ font-weight: bold;
+ text-align: right;
+}
+
+.expression-preview-doc-item-params {
+}
+
+.expression-preview-doc-item-returns {
+}
+
+.expression-preview-doc-item-desc {
+ color: #666;
}
\ No newline at end of file