mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-12-27 18:40:28 +00:00
parent
33d973fb91
commit
4966f6ab62
36
core/modules/filters/duplicateslugs.js
Normal file
36
core/modules/filters/duplicateslugs.js
Normal file
@ -0,0 +1,36 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/duplicateslugs.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter function for [duplicateslugs[]]
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.duplicateslugs = function(source,operator,options) {
|
||||
var slugs = Object.create(null), // Hashmap by slug of title, replaced with "true" if the duplicate title has already been output
|
||||
results = [];
|
||||
source(function(tiddler,title) {
|
||||
var slug = options.wiki.slugify(title);
|
||||
if(slug in slugs) {
|
||||
if(slugs[slug] !== true) {
|
||||
results.push(slugs[slug]);
|
||||
slugs[slug] = true;
|
||||
}
|
||||
results.push(title);
|
||||
} else {
|
||||
slugs[slug] = title;
|
||||
}
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
23
core/modules/filters/slugify.js
Normal file
23
core/modules/filters/slugify.js
Normal file
@ -0,0 +1,23 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/static/filters/slugify.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator for slugifying a tiddler title
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.slugify = function(source,operator,options) {
|
||||
var results = [];
|
||||
source(function(tiddler,title) {
|
||||
results.push(options.wiki.slugify(title));
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
@ -1503,5 +1503,30 @@ exports.doesPluginInfoRequireReload = function(pluginInfo) {
|
||||
}
|
||||
};
|
||||
|
||||
exports.slugify = function(title,options) {
|
||||
var tiddler = this.getTiddler(title),
|
||||
slug;
|
||||
if(tiddler && tiddler.fields.slug) {
|
||||
slug = tiddler.fields.slug;
|
||||
} else {
|
||||
slug = $tw.utils.transliterate(title.toString().toLowerCase()) // Replace diacritics with basic lowercase ASCII
|
||||
.replace(/\s+/g,"-") // Replace spaces with -
|
||||
.replace(/[^\w\-\.]+/g,"") // Remove all non-word chars except dash and dot
|
||||
.replace(/\-\-+/g,"-") // Replace multiple - with single -
|
||||
.replace(/^-+/,"") // Trim - from start of text
|
||||
.replace(/-+$/,""); // Trim - from end of text
|
||||
}
|
||||
// If the resulting slug is blank (eg because the title is just punctuation characters)
|
||||
if(!slug) {
|
||||
// ...then just use the character codes of the title
|
||||
var result = [];
|
||||
$tw.utils.each(title.split(""),function(char) {
|
||||
result.push(char.charCodeAt(0).toString());
|
||||
});
|
||||
slug = result.join("-");
|
||||
}
|
||||
return slug;
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
|
@ -94,6 +94,7 @@ function setupWiki(wikiOptions) {
|
||||
tags: ["one"],
|
||||
cost: "123",
|
||||
value: "120",
|
||||
slug: "tiddler-one",
|
||||
authors: "Joe Bloggs",
|
||||
modifier: "JoeBloggs",
|
||||
modified: "201304152222"});
|
||||
@ -103,6 +104,7 @@ function setupWiki(wikiOptions) {
|
||||
tags: ["two"],
|
||||
cost: "42",
|
||||
value: "190",
|
||||
slug: "tiddler-two",
|
||||
authors: "[[John Doe]]",
|
||||
modifier: "John",
|
||||
modified: "201304152211"});
|
||||
@ -669,6 +671,14 @@ function runTests(wiki) {
|
||||
expect(wiki.filterTiddlers("b a b c +[sortby[b a c b]]").join(",")).toBe("b,a,c");
|
||||
});
|
||||
|
||||
it("should handle the slugify operator", function() {
|
||||
expect(wiki.filterTiddlers("[[Joe Bloggs]slugify[]]").join(",")).toBe("joe-bloggs");
|
||||
expect(wiki.filterTiddlers("[[Joe Bloggs2]slugify[]]").join(",")).toBe("joe-bloggs2");
|
||||
expect(wiki.filterTiddlers("[[@£$%^&*((]slugify[]]").join(",")).toBe("64-163-36-37-94-38-42-40-40");
|
||||
expect(wiki.filterTiddlers("One one ONE O!N!E +[slugify[]]").join(",")).toBe("one,one,one,one");
|
||||
expect(wiki.filterTiddlers("TiddlerOne $:/TiddlerTwo +[slugify[]]").join(",")).toBe("tiddler-one,tiddler-two");
|
||||
});
|
||||
|
||||
it("should handle the sortsub operator", function() {
|
||||
var widget = require("$:/core/modules/widgets/widget.js");
|
||||
var rootWidget = new widget.widget({ type:"widget", children:[ {type:"widget", children:[]} ] },
|
||||
|
@ -0,0 +1,22 @@
|
||||
caption: duplicateslugs
|
||||
created: 20200509141702846
|
||||
modified: 20200509141702846
|
||||
op-input: a [[selection of titles|Title Selection]]
|
||||
op-output: the input titles transformed so that they only contain lower case letters, numbers, periods, dashes and underscores
|
||||
op-purpose: returns each item in the list in a human-readable form for use in URLs or filenames
|
||||
tags: [[Filter Operators]]
|
||||
title: duplicateslugs Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version "5.1.23">> The <<.olink slugify>> can be used to transform arbitrary tiddler titles into human readable strings suitable for use in URLs or filenames. However, itis possible for multiple different titles to slugify to the same string. The <<.olink duplicateslugs>> operator can be used to display a warning. For example:
|
||||
|
||||
<$macrocall $name='wikitext-example-without-html'
|
||||
src='<$list filter="[!is[system]duplicateslugs[]limit[1]]" emptyMessage="There are no duplicate slugs">
|
||||
The following tiddlers have duplicate slugs:
|
||||
|
||||
<ul>
|
||||
<$list filter="[!is[system]duplicateslugs[]]">
|
||||
<li><$link><$text text=<<currentTiddler>>/></$link></li>
|
||||
</$list>
|
||||
</ul>
|
||||
</$list>'/>
|
24
editions/tw5.com/tiddlers/filters/slugify Operator.tid
Normal file
24
editions/tw5.com/tiddlers/filters/slugify Operator.tid
Normal file
@ -0,0 +1,24 @@
|
||||
caption: slugify
|
||||
created: 20200509141702846
|
||||
modified: 20200509141702846
|
||||
op-input: a [[selection of titles|Title Selection]]
|
||||
op-output: the input titles transformed so that they only contain lower case letters, numbers, periods, dashes and underscores
|
||||
op-purpose: returns each item in the list in a human-readable form for use in URLs or filenames
|
||||
tags: [[Filter Operators]]
|
||||
title: slugify Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version "5.1.23">> The transformation applied by the slugify operator follows these steps:
|
||||
|
||||
* If there is a tiddler with the same title that has a ''slug'' field, then return that field instead of running the following steps
|
||||
* Replace uppercase letters with lowercase equivalents
|
||||
* Transliterate diacritics to their basic lowercase ASCII equivalents (for example, "Æ" is transliterated to "AE")
|
||||
* Replace spaces with dashes
|
||||
* Remove all non-word characters except dashes and periods
|
||||
* Replace multiple sequential dashes with a single dash
|
||||
* Trim dashes from start and end
|
||||
* If the result is the empty string then character codes are used instead (eg. "&£@" transforms to "38-163-64")
|
||||
|
||||
Note that it is possible for more than one title to slugify to the same string. The <<.olink duplicateslugs>> can be used to alert authors to any clashes.
|
||||
|
||||
<<.operator-examples "slugify">>
|
Loading…
Reference in New Issue
Block a user