Add macro operator (#9520)

* Add macro operator

* Replace unnecessary usage of wikify widget

* Simplify multiple let widget

* fixup! Replace unnecessary usage of wikify widget

* Update tests

* Update change note

* fixup! Replace unnecessary usage of wikify widget

* Update docs

* fixup! Update tests
This commit is contained in:
XLBilly
2026-01-04 19:31:30 +08:00
committed by GitHub
parent 921c0174fb
commit 3c8ee86e23
9 changed files with 80 additions and 31 deletions

View File

@@ -0,0 +1,27 @@
/*\
title: $:/core/modules/filters/macro.js
type: application/javascript
module-type: filteroperator
Filter operator returning those input titles that are returned from a javascript macro
\*/
"use strict";
/*
Export our filter function
*/
exports.macro = function(source,operator,options) {
const macroName = operator.operands[0],
results = [];
if($tw.macros[macroName] !== undefined) {
results.push($tw.macros[macroName].run(...operator.operands.slice(1)));
} else {
// Return the input list if the macro wasn't found
source((tiddler,title) => {
results.push(title);
});
}
return results;
};

View File

@@ -4,13 +4,11 @@ description: create a new journal tiddler
\whitespace trim
\function get-tags() [<textFieldTags>] [<tagsFieldTags>] +[join[ ]]
<$let journalTitleTemplate={{$:/config/NewJournal/Title}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}} journalText={{$:/config/NewJournal/Text}}>
<$wikify name="journalTitle" text="<$transclude $variable='now' format=<<journalTitleTemplate>>/>">
<$let journalTitleTemplate={{$:/config/NewJournal/Title}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}} journalText={{$:/config/NewJournal/Text}} journalTitle={{{ [macro[now],<journalTitleTemplate>] }}}>
<$reveal type="nomatch" state=<<journalTitle>> text="">
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<get-tags>> text={{{ [<journalTitle>get[]] }}}/>
</$reveal>
<$reveal type="match" state=<<journalTitle>> text="">
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=<<get-tags>> text=<<journalText>>/>
</$reveal>
</$wikify>
</$let>

View File

@@ -6,28 +6,19 @@ tags: $:/tags/EditTemplate
\procedure lingo-base() $:/language/EditTemplate/
\procedure tag-body-inner(colour,fallbackTarget,colourA,colourB,icon,tagField:"tags")
<$wikify name="foregroundColor"
text="""<$macrocall $name="contrastcolour"
target=<<colour>>
fallbackTarget=<<fallbackTarget>>
colourA=<<colourA>>
colourB=<<colourB>>/>
"""
>
<$let backgroundColor=<<colour>> >
<span class="tc-tag-label tc-tag-list-item tc-small-gap-right"
data-tag-title=<<currentTiddler>>
style=`color:$(foregroundColor)$; background-color:$(backgroundColor)$;`
>
<$transclude tiddler=<<icon>>/>
<$view field="title" format="text"/>
<$button class="tc-btn-invisible tc-remove-tag-button">
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter="-[{!!title}]"/>
{{$:/core/images/close-button}}
</$button>
</span>
</$let>
</$wikify>
<$let backgroundColor=<<colour>> foregroundColor={{{ [macro[contrastcolour],<colour>,<fallbackTarget>,<colourA>,<colourB>] }}}>
<span class="tc-tag-label tc-tag-list-item tc-small-gap-right"
data-tag-title=<<currentTiddler>>
style=`color:$(foregroundColor)$; background-color:$(backgroundColor)$;`
>
<$transclude tiddler=<<icon>>/>
<$view field="title" format="text"/>
<$button class="tc-btn-invisible tc-remove-tag-button">
<$action-listops $tiddler=<<saveTiddler>> $field=<<tagField>> $subfilter="-[{!!title}]"/>
{{$:/core/images/close-button}}
</$button>
</span>
</$let>
\end
\procedure tag-body(colour,palette,icon,tagField:"tags")

View File

@@ -16,15 +16,13 @@ title: $:/core/ui/TagPickerTagTemplate
<$set name="backgroundColor"
value={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
>
<$wikify name="foregroundColor"
text="""<$macrocall $name="contrastcolour" target=<<backgroundColor>> fallbackTarget=<<fallbackTarget>> colourA=<<colourA>> colourB=<<colourB>>/>"""
>
<$let foregroundColor={{{ [macro[contrastcolour],<backgroundColor>,<fallbackTarget>,<colourA>,<colourB>] }}}>
<span class="tc-tag-label tc-btn-invisible"
style=<<tag-pill-styles>>
data-tag-title=<<currentTiddler>>
>
{{||$:/core/ui/TiddlerIcon}}<$view field="title" format="text"/>
</span>
</$wikify>
</$let>
</$set>
</$button>

View File

@@ -6,7 +6,7 @@ description: {{$:/language/Buttons/NewJournalHere/Hint}}
\whitespace trim
\procedure journalButton()
<$button tooltip={{$:/language/Buttons/NewJournalHere/Hint}} aria-label={{$:/language/Buttons/NewJournalHere/Caption}} class=<<tv-config-toolbar-class>>>
<$wikify name="journalTitle" text="""<$transclude $variable="now" format=<<journalTitleTemplate>>/>""">
<$let journalTitle={{{ [macro[now],<journalTitleTemplate>] }}}>
<$action-sendmessage $message="tm-new-tiddler" title=<<journalTitle>> tags=`[[$(currentTiddlerTag)$]] $(journalTags)$`/>
<%if [<tv-config-toolbar-icons>match[yes]] %>
{{$:/core/images/new-journal-button}}
@@ -16,7 +16,7 @@ description: {{$:/language/Buttons/NewJournalHere/Hint}}
<$text text={{$:/language/Buttons/NewJournalHere/Caption}}/>
</span>
<%endif%>
</$wikify>
</$let>
</$button>
\end
<$let journalTitleTemplate={{$:/config/NewJournal/Title}} journalTags={{$:/config/NewJournal/Tags}} currentTiddlerTag=<<currentTiddler>>>

View File

@@ -1088,6 +1088,10 @@ Tests the filtering mechanism.
expect(wiki.filterTiddlers("[[representation]makepatches[misreprehensionisation]]").join(" ")).toBe("@@ -1,13 +1,21 @@\n+mis\n repre\n-sent\n+hensionis\n atio\n");
expect(wiki.filterTiddlers("[[the cat sat on the mat]makepatches[the hat saw in every category]]").join(" ")).toBe("@@ -1,22 +1,29 @@\n the \n-c\n+h\n at sa\n-t on the mat\n+w in every category\n");
});
it("should handle the macro operator", () => {
expect(wiki.filterTiddlers("[macro[makedatauri],[some example text],[text/plain]]").join("")).toBe("data:text/plain,some%20example%20text");
});
it("should parse filter variable parameters", function(){
expect($tw.utils.parseFilterVariable("currentTiddler")).toEqual(

View File

@@ -0,0 +1,7 @@
created: 20260104045032090
modified: 20260104045240842
tags: [[macro Operator]]
title: macro Operator (Examples)
type: text/vnd.tiddlywiki
<<.operator-example 1 "[macro[now],{$:/config/NewJournal/Title}]">>

View File

@@ -0,0 +1,14 @@
caption: macro
created: 20260104043647022
modified: 20260104045136808
op-input: ignored
op-output: the result of the javascript macro
op-parameter: first parameter is the javascript macro, subsequent parameters are passed to the macro by position
op-purpose: return the result from a javascript macro (with indirect parameters support)
tags: [[Filter Operators]]
title: macro Operator
type: text/vnd.tiddlywiki
<<.from-version "5.4.0">> The <<.op macro>> operator applies a javascript macro to the input titles, and returns the result from the macro. The function is invoked once with all of the input titles.
<<.operator-examples "macro">>

View File

@@ -0,0 +1,10 @@
title: $:/changenotes/5.4.0/#9520
description: Add macro operator
release: 5.4.0
tags: $:/tags/ChangeNote
change-type: feature
change-category: filters
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/9520
github-contributors: Leilei332
Added [[macro Operator]] for evaluating javascript macros in filters.