mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-23 18:17:20 +00:00
Initial commit of freelinks plugin
This commit is contained in:
parent
5a5c967a39
commit
447cd56da9
2
plugins/tiddlywiki/freelinks/config-Freelinks-Enable.tid
Normal file
2
plugins/tiddlywiki/freelinks/config-Freelinks-Enable.tid
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
title: $:/config/Freelinks/Enable
|
||||||
|
text: yes
|
4
plugins/tiddlywiki/freelinks/macros-view.tid
Normal file
4
plugins/tiddlywiki/freelinks/macros-view.tid
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
title: $:/plugins/tiddlywiki/freelinks/macros/view
|
||||||
|
tags: $:/tags/Macro/View
|
||||||
|
|
||||||
|
<$set name="tv-freelinks" value={{$:/config/Freelinks/Enable}}/>
|
62
plugins/tiddlywiki/freelinks/plain-text.js
Normal file
62
plugins/tiddlywiki/freelinks/plain-text.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/plain-text.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
A copy of the core text widget under a different name
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||||
|
|
||||||
|
var PlainTextNodeWidget = function(parseTreeNode,options) {
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
PlainTextNodeWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Render this widget into the DOM
|
||||||
|
*/
|
||||||
|
PlainTextNodeWidget.prototype.render = function(parent,nextSibling) {
|
||||||
|
this.parentDomNode = parent;
|
||||||
|
this.computeAttributes();
|
||||||
|
this.execute();
|
||||||
|
var text = this.getAttribute("text",this.parseTreeNode.text || "");
|
||||||
|
text = text.replace(/\r/mg,"");
|
||||||
|
var textNode = this.document.createTextNode(text);
|
||||||
|
parent.insertBefore(textNode,nextSibling);
|
||||||
|
this.domNodes.push(textNode);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compute the internal state of the widget
|
||||||
|
*/
|
||||||
|
PlainTextNodeWidget.prototype.execute = function() {
|
||||||
|
// Nothing to do for a text node
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||||
|
*/
|
||||||
|
PlainTextNodeWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
|
var changedAttributes = this.computeAttributes();
|
||||||
|
if(changedAttributes.text) {
|
||||||
|
this.refreshSelf();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports["plain-text"] = PlainTextNodeWidget;
|
||||||
|
|
||||||
|
})();
|
6
plugins/tiddlywiki/freelinks/plugin.info
Normal file
6
plugins/tiddlywiki/freelinks/plugin.info
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"title": "$:/plugins/tiddlywiki/freelinks",
|
||||||
|
"name": "Freelinks",
|
||||||
|
"description": "Freelinking of tiddler titles",
|
||||||
|
"list": "readme settings"
|
||||||
|
}
|
12
plugins/tiddlywiki/freelinks/readme.tid
Normal file
12
plugins/tiddlywiki/freelinks/readme.tid
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
title: $:/plugins/tiddlywiki/freelinks/readme
|
||||||
|
|
||||||
|
This plugin adds automatic generation of links to tiddler titles.
|
||||||
|
|
||||||
|
''Note that automatic link generation can be very slow when there are a large number of tiddlers''.
|
||||||
|
|
||||||
|
Freelinking is activated for runs of text that have the following variables set:
|
||||||
|
|
||||||
|
* `tv-wikilinks` is NOT equal to `no`
|
||||||
|
* `tv-freelinks` is set to `yes`
|
||||||
|
|
||||||
|
Within view templates, the variable `tv-freelinks` is automatically set to the content of $:/config/Freelinks/Enable, which can be set via the settings panel of this plugin.
|
3
plugins/tiddlywiki/freelinks/settings.tid
Normal file
3
plugins/tiddlywiki/freelinks/settings.tid
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
title: $:/plugins/tiddlywiki/freelinks/settings
|
||||||
|
|
||||||
|
<$checkbox tiddler="$:/config/Freelinks/Enable" field="text" checked="yes" unchecked="no" default="no"> <$link to="$:/config/Freelinks/Enable">Enable freelinking within tiddler view templates</$link> </$checkbox>
|
148
plugins/tiddlywiki/freelinks/text.js
Executable file
148
plugins/tiddlywiki/freelinks/text.js
Executable file
@ -0,0 +1,148 @@
|
|||||||
|
/*\
|
||||||
|
title: $:/core/modules/widgets/text.js
|
||||||
|
type: application/javascript
|
||||||
|
module-type: widget
|
||||||
|
|
||||||
|
An override of the core text widget that automatically linkifies the text
|
||||||
|
|
||||||
|
\*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
/*jslint node: true, browser: true */
|
||||||
|
/*global $tw: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||||
|
|
||||||
|
var TextNodeWidget = function(parseTreeNode,options) {
|
||||||
|
this.initialise(parseTreeNode,options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inherit from the base widget class
|
||||||
|
*/
|
||||||
|
TextNodeWidget.prototype = new Widget();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Render this widget into the DOM
|
||||||
|
*/
|
||||||
|
TextNodeWidget.prototype.render = function(parent,nextSibling) {
|
||||||
|
this.parentDomNode = parent;
|
||||||
|
this.computeAttributes();
|
||||||
|
this.execute();
|
||||||
|
this.renderChildren(parent,nextSibling);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compute the internal state of the widget
|
||||||
|
*/
|
||||||
|
TextNodeWidget.prototype.execute = function() {
|
||||||
|
var self = this;
|
||||||
|
// Get our parameters
|
||||||
|
var childParseTree = [{
|
||||||
|
type: "plain-text",
|
||||||
|
text: this.getAttribute("text",this.parseTreeNode.text || "")
|
||||||
|
}];
|
||||||
|
// Only process links if not disabled
|
||||||
|
if(this.getVariable("tv-wikilinks",{defaultValue:"yes"}).trim() !== "no" && this.getVariable("tv-freelinks",{defaultValue:"no"}).trim() === "yes") {
|
||||||
|
// Get the information about the current tiddler titles, and construct a regexp
|
||||||
|
this.tiddlerTitleInfo = this.wiki.getGlobalCache("tiddler-title-info",function() {
|
||||||
|
var titles = [],
|
||||||
|
reparts = [],
|
||||||
|
sortedTitles = self.wiki.allTitles().sort(function(a,b) {
|
||||||
|
var lenA = a.length,
|
||||||
|
lenB = b.length;
|
||||||
|
// First sort by length, so longer titles are first
|
||||||
|
if(lenA !== lenB) {
|
||||||
|
if(lenA < lenB) {
|
||||||
|
return +1;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Then sort alphabetically within titles of the same length
|
||||||
|
if(a < b) {
|
||||||
|
return -1;
|
||||||
|
} else if(a > b) {
|
||||||
|
return +1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$tw.utils.each(sortedTitles,function(title) {
|
||||||
|
if(title.substring(0,3) !== "$:/") {
|
||||||
|
titles.push(title);
|
||||||
|
reparts.push("(\\b" + $tw.utils.escapeRegExp(title) + "\\b)");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
titles: titles,
|
||||||
|
regexp: new RegExp(reparts.join("|"),"")
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// Repeatedly linkify
|
||||||
|
if(this.tiddlerTitleInfo.titles.length > 0) {
|
||||||
|
var index,text,match,matchEnd;
|
||||||
|
do {
|
||||||
|
index = childParseTree.length - 1;
|
||||||
|
text = childParseTree[index].text;
|
||||||
|
match = this.tiddlerTitleInfo.regexp.exec(text);
|
||||||
|
if(match) {
|
||||||
|
// Make a text node for any text before the match
|
||||||
|
if(match.index > 0) {
|
||||||
|
childParseTree[index].text = text.substring(0,match.index);
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
// Make a link node for the match
|
||||||
|
childParseTree[index] = {
|
||||||
|
type: "link",
|
||||||
|
attributes: {
|
||||||
|
to: {type: "string", value: match[0]}
|
||||||
|
},
|
||||||
|
children: [{
|
||||||
|
type: "plain-text", text: match[0]
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
index += 1;
|
||||||
|
// Make a text node for any text after the match
|
||||||
|
matchEnd = match.index + match[0].length;
|
||||||
|
if(matchEnd < text.length) {
|
||||||
|
childParseTree[index] = {
|
||||||
|
type: "plain-text",
|
||||||
|
text: text.substring(matchEnd)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(match && childParseTree[childParseTree.length - 1].type === "plain-text");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Make the child widgets
|
||||||
|
this.makeChildWidgets(childParseTree);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||||
|
*/
|
||||||
|
TextNodeWidget.prototype.refresh = function(changedTiddlers) {
|
||||||
|
var self = this,
|
||||||
|
changedAttributes = this.computeAttributes(),
|
||||||
|
titlesHaveChanged = false;
|
||||||
|
$tw.utils.each(changedTiddlers,function(change,title) {
|
||||||
|
if(change.isDeleted) {
|
||||||
|
titlesHaveChanged = true
|
||||||
|
} else {
|
||||||
|
titlesHaveChanged = titlesHaveChanged || !self.tiddlerTitleInfo || self.tiddlerTitleInfo.titles.indexOf(title) === -1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(changedAttributes.text || titlesHaveChanged) {
|
||||||
|
this.refreshSelf();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.text = TextNodeWidget;
|
||||||
|
|
||||||
|
})();
|
Loading…
Reference in New Issue
Block a user