mirror of
https://github.com/Jermolene/TiddlyWiki5.git
synced 2025-12-06 02:30:46 -08:00
Merge c3451195c1 into 4c27c09b4d
This commit is contained in:
commit
d481056ded
5 changed files with 156 additions and 53 deletions
21
core/modules/filters/images.js
Normal file
21
core/modules/filters/images.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*\
|
||||
title: $:/core/modules/filters/images.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator for returning all the images used in image widgets in a tiddler
|
||||
|
||||
\*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.images = function(source,operator,options) {
|
||||
const results = new $tw.utils.LinkedList();
|
||||
source(function(tiddler,title) {
|
||||
results.pushTop(options.wiki.getTiddlerImages(title));
|
||||
});
|
||||
return results.makeTiddlerIterator(options.wiki);
|
||||
};
|
||||
|
|
@ -496,27 +496,49 @@ exports.forEachTiddler = function(/* [options,]callback */) {
|
|||
};
|
||||
|
||||
/*
|
||||
Return an array of tiddler titles that are directly linked within the given parse tree
|
||||
*/
|
||||
exports.extractLinks = function(parseTreeRoot) {
|
||||
// Count up the links
|
||||
var links = [],
|
||||
checkParseTree = function(parseTree) {
|
||||
for(var t=0; t<parseTree.length; t++) {
|
||||
var parseTreeNode = parseTree[t];
|
||||
if(parseTreeNode.type === "link" && parseTreeNode.attributes.to && parseTreeNode.attributes.to.type === "string") {
|
||||
var value = parseTreeNode.attributes.to.value;
|
||||
if(links.indexOf(value) === -1) {
|
||||
links.push(value);
|
||||
Extracts values from selected nodes of a parse tree based on a predicate and value extractor.
|
||||
predicate: function(parseTreeNode, parentNode, title) => boolean
|
||||
extractValue: function(parseTreeNode, parentNode, title) => value
|
||||
*/
|
||||
exports.extractFromParseTree = function(parseTreeRoot, predicate, extractValue, title) {
|
||||
const results = new Set(),
|
||||
checkParseTree = (parseTree, parentNode = null) => {
|
||||
for(const parseTreeNode of parseTree) {
|
||||
if(predicate(parseTreeNode, parentNode, title)) {
|
||||
const value = extractValue(parseTreeNode, parentNode, title);
|
||||
if(value) {
|
||||
results.add(value);
|
||||
}
|
||||
}
|
||||
if(parseTreeNode.children) {
|
||||
checkParseTree(parseTreeNode.children);
|
||||
checkParseTree(parseTreeNode.children, parseTreeNode);
|
||||
}
|
||||
}
|
||||
};
|
||||
checkParseTree(parseTreeRoot);
|
||||
return links;
|
||||
return [...results];
|
||||
};
|
||||
|
||||
/*
|
||||
Return an array of image tiddler titles that are directly referenced within the given parse tree using image widgets.
|
||||
*/
|
||||
exports.extractImages = function(parseTreeRoot) {
|
||||
return this.extractFromParseTree(
|
||||
parseTreeRoot,
|
||||
(node) => node.type === "image" && node.attributes.source && node.attributes.source.type === "string",
|
||||
(node) => node.attributes.source.value
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
Return an array of tiddler titles that are directly linked within the given parse tree
|
||||
*/
|
||||
exports.extractLinks = function(parseTreeRoot) {
|
||||
return this.extractFromParseTree(
|
||||
parseTreeRoot,
|
||||
(node) => node.type === "link" && node.attributes.to && node.attributes.to.type === "string",
|
||||
(node) => node.attributes.to.value
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -555,54 +577,56 @@ exports.getTiddlerBacklinks = function(targetTitle) {
|
|||
return backlinks;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Return an array of tiddler titles that are directly transcluded within the given parse tree. `title` is the tiddler being parsed, we will ignore its self-referential transclusions, only return
|
||||
*/
|
||||
*/
|
||||
exports.extractTranscludes = function(parseTreeRoot, title) {
|
||||
// Count up the transcludes
|
||||
var transcludes = [],
|
||||
checkParseTree = function(parseTree, parentNode) {
|
||||
for(var t=0; t<parseTree.length; t++) {
|
||||
var parseTreeNode = parseTree[t];
|
||||
if(parseTreeNode.type === "transclude") {
|
||||
if(parseTreeNode.attributes.$tiddler) {
|
||||
if(parseTreeNode.attributes.$tiddler.type === "string") {
|
||||
var value;
|
||||
// if it is Transclusion with Templates like `{{Index||$:/core/ui/TagTemplate}}`, the `$tiddler` will point to the template. We need to find the actual target tiddler from parent node
|
||||
if(parentNode && parentNode.type === "tiddler" && parentNode.attributes.tiddler && parentNode.attributes.tiddler.type === "string") {
|
||||
// Empty value (like `{{!!field}}`) means self-referential transclusion.
|
||||
value = parentNode.attributes.tiddler.value || title;
|
||||
} else {
|
||||
value = parseTreeNode.attributes.$tiddler.value;
|
||||
}
|
||||
}
|
||||
} else if(parseTreeNode.attributes.tiddler) {
|
||||
if (parseTreeNode.attributes.tiddler.type === "string") {
|
||||
// Old transclude widget usage
|
||||
value = parseTreeNode.attributes.tiddler.value;
|
||||
}
|
||||
} else if(parseTreeNode.attributes.$field && parseTreeNode.attributes.$field.type === "string") {
|
||||
// Empty value (like `<$transclude $field='created'/>`) means self-referential transclusion.
|
||||
value = title;
|
||||
} else if(parseTreeNode.attributes.field && parseTreeNode.attributes.field.type === "string") {
|
||||
// Old usage with Empty value (like `<$transclude field='created'/>`)
|
||||
value = title;
|
||||
}
|
||||
// Deduplicate the result.
|
||||
if(value && transcludes.indexOf(value) === -1) {
|
||||
$tw.utils.pushTop(transcludes,value);
|
||||
return this.extractFromParseTree(
|
||||
parseTreeRoot,
|
||||
(node, parentNode) => node.type === "transclude",
|
||||
(node, parentNode) => {
|
||||
let value;
|
||||
if(node.attributes.$tiddler) {
|
||||
if(node.attributes.$tiddler.type === "string") {
|
||||
// if it is Transclusion with Templates like `{{Index||$:/core/ui/TagTemplate}}`, the `$tiddler` will point to the template. We need to find the actual target tiddler from parent node
|
||||
if(parentNode && parentNode.type === "tiddler" && parentNode.attributes.tiddler && parentNode.attributes.tiddler.type === "string") {
|
||||
// Empty value (like `{{!!field}}`) means self-referential transclusion.
|
||||
value = parentNode.attributes.tiddler.value || title;
|
||||
} else {
|
||||
value = node.attributes.$tiddler.value;
|
||||
}
|
||||
}
|
||||
if(parseTreeNode.children) {
|
||||
checkParseTree(parseTreeNode.children,parseTreeNode);
|
||||
} else if(node.attributes.tiddler) {
|
||||
// Old transclude widget usage
|
||||
if(node.attributes.tiddler.type === "string") {
|
||||
value = node.attributes.tiddler.value;
|
||||
}
|
||||
} else if(
|
||||
(node.attributes.$field && node.attributes.$field.type === "string") ||
|
||||
(node.attributes.field && node.attributes.field.type === "string")
|
||||
) {
|
||||
// Empty value (like `<$transclude $field='created'/>`) means self-referential transclusion.
|
||||
value = title;
|
||||
}
|
||||
};
|
||||
checkParseTree(parseTreeRoot);
|
||||
return transcludes;
|
||||
return value;
|
||||
},
|
||||
title
|
||||
);
|
||||
};
|
||||
|
||||
/*
|
||||
Return an array of images that are used in image widgets in the specified tiddler
|
||||
*/
|
||||
exports.getTiddlerImages = function(title) {
|
||||
const self = this;
|
||||
return this.getCacheForTiddler(title,"images",() => {
|
||||
const parser = self.parseTiddler(title);
|
||||
if(parser) {
|
||||
return self.extractImages(parser.tree);
|
||||
}
|
||||
return [];
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Return an array of tiddler titles that are transcluded from the specified tiddler
|
||||
|
|
|
|||
28
editions/test/tiddlers/tests/data/filters/Images.tid
Normal file
28
editions/test/tiddlers/tests/data/filters/Images.tid
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
title: Filters/images
|
||||
description: Test images operator
|
||||
type: text/vnd.tiddlywiki-multiple
|
||||
tags: [[$:/tags/wiki-test-spec]]
|
||||
|
||||
title: Tiddler1
|
||||
|
||||
TiddlyWiki <$image source="https://tiddlywiki.com/images/tiddlywiki-logo.png" alt="TiddlyWiki logo" width="100px" height="100px"/><$image source="Image4" alt="Image4" width="100px" height="100px"/>.
|
||||
+
|
||||
title: Tiddler2
|
||||
|
||||
This is an image <$image source="Image1"/> and this is another image [img[Image2]] but this image won't be picked up <img src="Image3" alt="Image3" width="100px" height="100px"/> nor will this one {{Image4}}
|
||||
+
|
||||
title: Image4
|
||||
type: image/png
|
||||
|
||||
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=
|
||||
+
|
||||
title: Output
|
||||
|
||||
\whitespace trim
|
||||
(<$text text={{{ [[Tiddler1]images[]join[,]] }}}/>)
|
||||
(<$text text={{{ [[Tiddler2]images[]join[,]] }}}/>)
|
||||
+
|
||||
title: ExpectedResult
|
||||
|
||||
<p>(https://tiddlywiki.com/images/tiddlywiki-logo.png,Image4)
|
||||
(Image1,Image2)</p>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
created: 20250802195938592
|
||||
modified: 20250802195948223
|
||||
tags: [[Operator Examples]] [[images Operator]]
|
||||
title: images Operator (Examples)
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.operator-example 1 "[all[current]images[]]" "image tiddlers embedded in the current one using hard references">>
|
||||
|
||||
Here are some images using hard references:
|
||||
|
||||
* [img[Motovun Jack.jpg]]
|
||||
* <$image source="Favicon template.svg"/>
|
||||
18
editions/tw5.com/tiddlers/filters/images Operator.tid
Normal file
18
editions/tw5.com/tiddlers/filters/images Operator.tid
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
caption: images
|
||||
created: 20250802195117221
|
||||
modified: 20250802200627718
|
||||
op-input: a [[selection of titles|Title Selection]]
|
||||
op-output: the image tiddlers to which the input tiddlers contain hard references using image widgets
|
||||
op-parameter: none
|
||||
op-purpose: find the images used by each input title
|
||||
tags: [[Filter Operators]] [[Common Operators]]
|
||||
title: images Operator
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
<<.from-version "5.4.0">>
|
||||
|
||||
Each input title is processed in turn. The corresponding tiddler's list of images is generated, in the order in which they appear in the tiddler's text, and [[dominantly appended|Dominant Append]] to the operator's overall output.
|
||||
|
||||
Images used as hard references in an image widget or the `[img[title]]` syntax are detected.
|
||||
|
||||
<<.operator-examples "images">>
|
||||
Loading…
Add table
Add a link
Reference in a new issue