mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 03:57:21 +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