1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-07-08 04:42:45 +00:00

Compare commits

..

5 Commits

Author SHA1 Message Date
saqimtiaz f76ec0b2c6 fix: whitespace 2026-03-24 14:51:18 +01:00
saqimtiaz 69005a904d fix: restore mistakenly commited files 2026-03-24 14:48:55 +01:00
saqimtiaz ed33625407 tests: added missing test 2026-03-24 14:45:41 +01:00
saqimtiaz f848d8c368 wip: non-existent variables as attributes should be undefined 2026-03-24 14:41:43 +01:00
saqimtiaz 729d4b6374 wip: non-existent variables as attributes should be undefined 2026-03-24 14:13:31 +01:00
12 changed files with 87 additions and 92 deletions
+63 -79
View File
@@ -107,7 +107,7 @@ exports.parseStringLiteral = function(source,pos) {
type: "string",
start: pos
};
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')|\[\[((?:[^\]]|\](?!\]))*)\]\]/y;
var reString = /(?:"""([\s\S]*?)"""|"([^"]*)")|(?:'([^']*)')|\[\[((?:[^\]]|\](?!\]))*)\]\]/g;
reString.lastIndex = pos;
var match = reString.exec(source);
if(match && match.index === pos) {
@@ -221,7 +221,7 @@ exports.parseMacroInvocationAsTransclusion = function(source,pos) {
orderedAttributes: []
};
// Define our regexps
var reVarName = /([^\s>"'=:]+)/y;
var reVarName = /([^\s>"'=:]+)/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for a double opening angle bracket
@@ -237,11 +237,9 @@ exports.parseMacroInvocationAsTransclusion = function(source,pos) {
}
$tw.utils.addAttributeToParseTreeNode(node,"$variable",token.match[1]);
pos = token.end;
// Check that the tag is terminated by a space or >>, and that there is a closing >> somewhere ahead
if(!(source.charAt(pos) === ">" && source.charAt(pos + 1) === ">") ) {
if(!$tw.utils.parseWhiteSpace(source,pos) || source.indexOf(">>",pos) === -1) {
return null;
}
// Check that the tag is terminated by a space or >>
if(!$tw.utils.parseWhiteSpace(source,pos) && !(source.charAt(pos) === ">" && source.charAt(pos + 1) === ">") ) {
return null;
}
// Process attributes
pos = $tw.utils.parseMacroParametersAsAttributes(node,source,pos);
@@ -269,7 +267,7 @@ exports.parseMVVReferenceAsTransclusion = function(source,pos) {
orderedAttributes: []
};
// Define our regexps
var reVarName = /([^\s>"'=:)]+)/y;
var reVarName = /([^\s>"'=:)]+)/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for a double opening parenthesis
@@ -325,17 +323,17 @@ exports.parseMacroParameterAsAttribute = function(source,pos) {
start: pos
};
// Define our regexps
var reAttributeName = /([^\/\s>"'`=:]+)/y,
reUnquotedAttribute = /((?:(?:>(?!>))|[^\s>"'])+)/y,
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/y,
reIndirectValue = /\{\{([^\}]+)\}\}/y,
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/y;
var reAttributeName = /([^\/\s>"'`=:]+)/g,
reUnquotedAttribute = /((?:(?:>(?!>))|[^\s>"'])+)/g,
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
reIndirectValue = /\{\{([^\}]+)\}\}/g,
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/g;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Get the attribute name and the separator token
var nameToken = $tw.utils.parseTokenRegExp(source,pos,reAttributeName),
namePos = nameToken && $tw.utils.skipWhiteSpace(source,nameToken.end),
separatorToken = nameToken && $tw.utils.parseTokenRegExp(source,namePos,/=|:/y),
separatorToken = nameToken && $tw.utils.parseTokenRegExp(source,namePos,/=|:/g),
isNewStyleSeparator = false; // If there is no separator then we don't allow new style values
// If we have a name and a separator then we have a named attribute
if(nameToken && separatorToken) {
@@ -347,78 +345,64 @@ exports.parseMacroParameterAsAttribute = function(source,pos) {
}
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
do {
// Look for a string literal
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
if(stringLiteral) {
pos = stringLiteral.end;
node.type = "string";
node.value = stringLiteral.value;
// Mark the value as having been quoted in the source
node.quoted = true;
break;
}
if(isNewStyleSeparator) {
// Look for a filtered value
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
if(filteredValue) {
pos = filteredValue.end;
node.type = "filtered";
node.filter = filteredValue.match[1];
break;
}
// Look for a string literal
var stringLiteral = $tw.utils.parseStringLiteral(source,pos);
if(stringLiteral) {
pos = stringLiteral.end;
node.type = "string";
node.value = stringLiteral.value;
// Mark the value as having been quoted in the source
node.quoted = true;
} else {
// Look for a filtered value
var filteredValue = $tw.utils.parseTokenRegExp(source,pos,reFilteredValue);
if(filteredValue && isNewStyleSeparator) {
pos = filteredValue.end;
node.type = "filtered";
node.filter = filteredValue.match[1];
} else {
// Look for an indirect value
var indirectValue = $tw.utils.parseTokenRegExp(source,pos,reIndirectValue);
if(indirectValue) {
if(indirectValue && isNewStyleSeparator) {
pos = indirectValue.end;
node.type = "indirect";
node.textReference = indirectValue.match[1];
break;
}
// Look for a macro invocation value
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
if(macroInvocation) {
pos = macroInvocation.end;
node.type = "macro";
node.value = macroInvocation;
break;
}
// Look for an MVV reference value
var mvvReference = $tw.utils.parseMVVReferenceAsTransclusion(source,pos);
if(mvvReference) {
pos = mvvReference.end;
node.type = "macro";
node.value = mvvReference;
node.isMVV = true;
break;
}
// Look for a substituted value
var substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);
if(substitutedValue) {
pos = substitutedValue.end;
node.type = "substituted";
node.rawValue = substitutedValue.match[1] || substitutedValue.match[2];
break;
} else {
// Look for a macro invocation value
var macroInvocation = $tw.utils.parseMacroInvocationAsTransclusion(source,pos);
if(macroInvocation && isNewStyleSeparator) {
pos = macroInvocation.end;
node.type = "macro";
node.value = macroInvocation;
} else {
// Look for an MVV reference value
var mvvReference = $tw.utils.parseMVVReferenceAsTransclusion(source,pos);
if(mvvReference && isNewStyleSeparator) {
pos = mvvReference.end;
node.type = "macro";
node.value = mvvReference;
node.isMVV = true;
} else {
var substitutedValue = $tw.utils.parseTokenRegExp(source,pos,reSubstitutedValue);
if(substitutedValue && isNewStyleSeparator) {
pos = substitutedValue.end;
node.type = "substituted";
node.rawValue = substitutedValue.match[1] || substitutedValue.match[2];
} else {
// Look for a unquoted value
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
if(unquotedValue) {
pos = unquotedValue.end;
node.type = "string";
node.value = unquotedValue.match[1];
} else {
}
}
}
}
}
}
// Look for a unquoted value
var unquotedValue = $tw.utils.parseTokenRegExp(source,pos,reUnquotedAttribute);
if(unquotedValue) {
pos = unquotedValue.end;
node.type = "string";
node.value = unquotedValue.match[1];
break; // redundant, but leaving for consistency
}
} while(false);
}
// Bail if we don't have a value
if(!node.type) {
return null;
+2 -2
View File
@@ -61,7 +61,7 @@ LogWidget.prototype.log = function() {
$tw.utils.each(this.parseTreeNode.attributes,function(attribute,name) {
if(name.substring(0,2) !== "$$") {
var resultList = self.computeAttribute(attribute,{asList: true});
if(resultList.length <= 1) {
if(resultList && resultList.length <= 1) {
data[name] = resultList[0] || "";
} else {
data[name] = resultList;
@@ -75,7 +75,7 @@ LogWidget.prototype.log = function() {
allVars[v] = variable.value;
} else {
var variableInfo = this.getVariableInfo(v);
allVars[v] = variableInfo.resultList.length > 1 ? variableInfo.resultList : variableInfo.text;
allVars[v] = variableInfo && variableInfo.resultList && variableInfo.resultList.length > 1 ? variableInfo.resultList : variableInfo.text;
}
}
if(this.filter) {
+2 -2
View File
@@ -189,7 +189,7 @@ Widget.prototype.getVariableInfo = function(name,options) {
}
return {
text: text,
resultList: [text]
resultList: text === undefined ? text : [text]
};
};
@@ -338,7 +338,7 @@ Widget.prototype.makeFakeWidgetWithVariables = function(vars = {}) {
const value = vars[name];
return Array.isArray(value)
? { text: value[0], resultList: value }
: { text: value, resultList: [value] };
: { text: value, resultList: value === undefined ? value : [value] };
}
opts = opts || {};
opts.variables = Object.assign({}, vars, opts.variables || {});
@@ -0,0 +1,13 @@
title: Transclude/MissingTiddlerAttributeVariable
description: Missing Tiddler Attribute Variable
type: text/vnd.tiddlywiki-multiple
tags: [[$:/tags/wiki-test-spec]]
title: Output
description: hello
<$transclude tiddler=<<nonExistentVariable>> field="description"/>
+
title: ExpectedResult
<p>hello</p>
@@ -1,7 +1,7 @@
title: HelloThumbnail - Community Survey 2025
tags: HelloThumbnail
color: rgb(234, 205, 183)
image: Community Survey 2025 Image
image: Community Survey 2025
caption: Community Survey
link: Community Survey 2025
ribbon-text: NEW
@@ -1,7 +1,7 @@
background-color: #EDB431
caption: Intertwingled Innovations
color: #ff0
image: Intertwingled Innovations Image
image: Intertwingled Innovations
link: Intertwingled Innovations
tags: HelloThumbnail
title: HelloThumbnail - Intertwingled Innovations

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

@@ -1,4 +1,4 @@
alt-text: Shape the future by taking the TiddlyWiki Community Survey 2025
tags: picture
title: Community Survey 2025 Image
title: Community Survey 2025
type: image/webp
@@ -1,3 +0,0 @@
title: Intertwingled Innovations Image
type: image/webp
tags: picture

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,3 @@
title: Intertwingled Innovations
type: image/webp
tags: picture
+1 -3
View File
@@ -646,6 +646,4 @@ Rishu kumar, @rishu-7549, 2025/10/25
@hsteve11, 2025/12/30
@kjharcombe, 2026/03/16
Himmel, @NotHimmel, 2026/03/19
@kjharcombe, 2026/03/16