Added ability to transclude fields of data tiddlers

This allows us to transclude colours into CSS
print-window-tiddler
Jeremy Ruston 2013-01-15 17:50:47 +00:00
rodzic 965cebf195
commit baff901685
7 zmienionych plików z 110 dodań i 47 usunięć

Wyświetl plik

@ -33,7 +33,11 @@ exports.parse = function() {
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
// Get the match details
var targetTitle = $tw.utils.trim(this.match[1]),
var textRef = $tw.utils.trim(this.match[1]),
tr = $tw.utils.parseTextReference(textRef),
targetTitle = tr.title,
targetField = tr.field,
targetIndex = tr.index,
tooltip = this.match[2],
template = $tw.utils.trim(this.match[3]),
style = this.match[4],
@ -47,6 +51,12 @@ exports.parse = function() {
},
isBlock: true
};
if(targetField) {
node.attributes.field = {type: "string", value: targetField};
}
if(targetIndex) {
node.attributes.index = {type: "string", value: targetIndex};
}
if(tooltip) {
node.attributes.tooltip = {type: "string", value: tooltip};
}

Wyświetl plik

@ -33,7 +33,11 @@ exports.parse = function() {
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
// Get the match details
var targetTitle = $tw.utils.trim(this.match[1]),
var textRef = $tw.utils.trim(this.match[1]),
tr = $tw.utils.parseTextReference(textRef),
targetTitle = tr.title,
targetField = tr.field,
targetIndex = tr.index,
tooltip = this.match[2],
template = $tw.utils.trim(this.match[3]),
style = this.match[4],
@ -46,6 +50,12 @@ exports.parse = function() {
target: {type: "string", value: targetTitle}
}
};
if(targetField) {
node.attributes.field = {type: "string", value: targetField};
}
if(targetIndex) {
node.attributes.index = {type: "string", value: targetIndex};
}
if(tooltip) {
node.attributes.tooltip = {type: "string", value: tooltip};
}

Wyświetl plik

@ -349,26 +349,30 @@ exports.hyphenateCss = function(propName) {
};
/*
Parse a text reference in the format "title!!field" into its constituent parts
Parse a text reference of one of these forms:
* title
* !!field
* title!!field
* title##index
* etc
Returns an object with the following fields, all optional:
* title: tiddler title
* field: tiddler field name
* index: JSON property index
*/
exports.parseTextReference = function(textRef) {
// Look for a metadata field separator
var pos = textRef.indexOf("!!");
if(pos !== -1) {
if(pos === 0) {
// Just a field
return {
field: textRef.substring(2)
};
} else {
// Field and title
return {
title: textRef.substring(0,pos),
field: textRef.substring(pos + 2)
};
}
// Separate out the title, field name and/or JSON indices
var reTextRef = /^\s*([^\s!#]+)?(?:(?:!!([^\s]+))|(?:##([^\s]+)))?\s*/mg,
match = reTextRef.exec(textRef);
if(match && reTextRef.lastIndex === textRef.length) {
// Return the parts
return {
title: match[1],
field: match[2],
index: match[3]
};
} else {
// Otherwise, we've just got a title
// If we couldn't parse it (eg it started with a)
return {
title: textRef
};

Wyświetl plik

@ -57,7 +57,8 @@ TranscludeWidget.prototype.generate = function() {
var tr, templateParseTree, templateTiddler;
// Get the render target details
this.targetTitle = this.renderer.getAttribute("target",this.renderer.getContextTiddlerTitle());
this.targetField = this.renderer.getAttribute("field","text");
this.targetField = this.renderer.getAttribute("field");
this.targetIndex = this.renderer.getAttribute("index");
// Get the render tree for the template
this.templateTitle = undefined;
if(this.renderer.parseTreeNode.children && this.renderer.parseTreeNode.children.length > 0) {
@ -67,21 +68,27 @@ TranscludeWidget.prototype.generate = function() {
this.templateTitle = this.renderer.getAttribute("template",this.targetTitle);
// Check for recursion
if(this.renderer.checkContextRecursion({
tiddlerTitle: this.targetTitle,
templateTitle: this.templateTitle
})) {
tiddlerTitle: this.targetTitle,
templateTitle: this.templateTitle
})) {
templateParseTree = [{type: "text", text: "Tiddler recursion error in transclude widget"}];
} else {
var parser;
if(this.targetField === "text") {
parser = this.renderer.renderTree.wiki.parseTiddler(this.templateTitle,{parseAsInline: !this.renderer.parseTreeNode.isBlock})
if(this.targetField === "text" || (!this.targetField && !this.targetIndex)) {
parser = this.renderer.renderTree.wiki.parseTiddler(this.templateTitle,{parseAsInline: !this.renderer.parseTreeNode.isBlock});
} else {
var tiddler = this.renderer.renderTree.wiki.getTiddler(this.targetTitle),
var tiddler,text;
if(this.targetField) {
tiddler = this.renderer.renderTree.wiki.getTiddler(this.targetTitle);
text = tiddler ? tiddler.fields[this.targetField] : "";
if(text === undefined) {
text = ""
if(text === undefined) {
text = "";
}
parser = this.renderer.renderTree.wiki.parseText("text/vnd.tiddlywiki",text,{parseAsInline: !this.renderer.parseTreeNode.isBlock});
} else if(this.targetIndex) {
text = this.renderer.renderTree.wiki.extractTiddlerDataItem(this.targetTitle,this.targetIndex,"");
parser = this.renderer.renderTree.wiki.parseText("text/plain",text);
}
parser = this.renderer.renderTree.wiki.parseText("text/vnd.tiddlywiki",text,{parseAsInline: !this.renderer.parseTreeNode.isBlock});
}
templateParseTree = parser ? parser.tree : [];
}

Wyświetl plik

@ -28,18 +28,24 @@ last dispatched. Each entry is a hashmap containing two fields:
/*
Get the value of a text reference. Text references can have any of these forms:
<tiddlertitle>
<tiddlertitle>##<fieldname>
##<fieldname> - specifies a field of the current tiddlers
<tiddlertitle>!!<fieldname>
!!<fieldname> - specifies a field of the current tiddlers
<tiddlertitle>##<field>
*/
exports.getTextReference = function(textRef,defaultText,currTiddlerTitle) {
var tr = $tw.utils.parseTextReference(textRef),
title = tr.title || currTiddlerTitle,
field = tr.field || "text",
tiddler = this.getTiddler(title);
if(tiddler && $tw.utils.hop(tiddler.fields,field)) {
return tiddler.fields[field];
title = tr.title || currTiddlerTitle;
if(tr.field) {
var tiddler = this.getTiddler(title);
if(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {
return tiddler.fields[tr.field];
} else {
return defaultText;
}
} else if(tr.index) {
return this.extractTiddlerDataItem(title,tr.index,defaultText);
} else {
return defaultText;
return this.getTiddlerText(title);
}
};
@ -283,24 +289,46 @@ exports.getTiddlersWithTag = function(tag) {
Get a tiddlers content as a JavaScript object. How this is done depends on the type of the tiddler:
application/json: the tiddler JSON is parsed into an object
application/x-tiddler-dictionary: the tiddler is parsed as sequence of name:value pairs
Other types currently just return null.
*/
exports.getTiddlerData = function(title,defaultData) {
var tiddler = this.tiddlers[title],
data;
if(tiddler && tiddler.fields.text && tiddler.fields.type === "application/json") {
// JSON tiddler
try {
data = JSON.parse(tiddler.fields.text);
} catch(ex) {
return defaultData;
if(tiddler && tiddler.fields.text) {
switch(tiddler.fields.type) {
case "application/json":
// JSON tiddler
try {
data = JSON.parse(tiddler.fields.text);
} catch(ex) {
return defaultData;
}
return data;
case "application/x-tiddler-dictionary":
return $tw.utils.parseFields(tiddler.fields.text);
}
return data;
}
return defaultData;
};
/*
Extract an indexed field from within a data tiddler
*/
exports.extractTiddlerDataItem = function(title,index,defaultText) {
var data = this.getTiddlerData(title,{}),
text;
if(data && $tw.utils.hop(data,index)) {
text = data[index];
}
if(typeof text === "string" || typeof text === "number") {
return text.toString();
} else {
return defaultText;
}
};
/*
Set a tiddlers content to a JavaScript object. Currently this is done by setting the tiddler's type to "application/json" and setting the text to the JSON text of the data.
*/
@ -619,11 +647,11 @@ exports.handleSyncerEvent = function(event) {
/*
Trigger a load for a tiddler if it is skinny. Returns the text, or undefined if the tiddler is missing, null if the tiddler is being lazily loaded.
*/
exports.getTiddlerText = function(title) {
exports.getTiddlerText = function(title,defaultText) {
var tiddler = this.getTiddler(title);
// Return undefined if the tiddler isn't found
if(!tiddler) {
return undefined;
return defaultText;
}
if(tiddler.fields.text !== undefined) {
// Just return the text if we've got it

Wyświetl plik

@ -24,7 +24,7 @@ html body {
.tw-tiddler-frame {
padding: 30px 30px 30px 30px;
margin: 0px;
background-color: #fff;
background-color: {{$:/core/styles/colours##primary}};
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
border-bottom: 1px solid #ddd;

Wyświetl plik

@ -0,0 +1,4 @@
title: $:/core/styles/colours
type: application/x-tiddler-dictionary
primary: #80ffff