+ $genesis>
+ <$genesis $type=<> style="background:white;color:black;padding:4px;">
+
+ <$list filter="[<@params>jsonindexes[]] :filter[prefix[$]] +[limit[1]]" variable="ignore" emptyMessage="""
+
+ <$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget]" recursionMarker="no" mode=<>>
+
+ <$slot $name="ts-raw" $depth="2"/>
+ $genesis>
+ """>
+
+ <$genesis $type="$transclude" $remappable="no" $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsonget]" $$recursionMarker="no" $$mode=<>>
+
+ <$slot $name="ts-raw" $depth="2"/>
+ $genesis>
+ $list>
+ $genesis>
+ $genesis>
+ $let>
+$parameters>
+\end
diff --git a/core/wiki/macros/tabs.tid b/core/wiki/macros/tabs.tid
index f439e541d..bc8a0255f 100644
--- a/core/wiki/macros/tabs.tid
+++ b/core/wiki/macros/tabs.tid
@@ -60,4 +60,4 @@ code-body: yes
$let>
$qualify>
-\end
+\end
\ No newline at end of file
diff --git a/editions/prerelease/tiddlers/Release 5.2.8.tid b/editions/prerelease/tiddlers/Release 5.2.8.tid
deleted file mode 100644
index 18ca202b5..000000000
--- a/editions/prerelease/tiddlers/Release 5.2.8.tid
+++ /dev/null
@@ -1,60 +0,0 @@
-caption: 5.2.8
-created: 20230326093239710
-modified: 20230326093239710
-tags: ReleaseNotes
-title: Release 5.2.8
-type: text/vnd.tiddlywiki
-
-//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/v5.2.7...master]]//
-
-! Major Improvements
-
-! Translation Improvements
-
-Improvements to the following translations:
-
-*
-
-! Plugin Improvements
-
-*
-
-! Accessibility Improvements
-
-*
-
-! Usability Improvements
-
-*
-
-! Widget Improvements
-
-*
-
-! Filter improvements
-
-*
-
-! Hackability Improvements
-
-*
-
-! Bug Fixes
-
-*
-
-! Node.js Improvements
-
-*
-
-! Performance Improvements
-
-*
-
-! Acknowledgements
-
-[[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki:
-
-<<.contributors """
-
-""">>
\ No newline at end of file
diff --git a/editions/prerelease/tiddlers/Release 5.3.0.tid b/editions/prerelease/tiddlers/Release 5.3.0.tid
new file mode 100644
index 000000000..63a57cd4d
--- /dev/null
+++ b/editions/prerelease/tiddlers/Release 5.3.0.tid
@@ -0,0 +1,83 @@
+caption: 5.3.0
+created: 20230419103154368
+modified: 20230419103154368
+tags: ReleaseNotes
+title: Release 5.3.0
+type: text/vnd.tiddlywiki
+
+//[[See GitHub for detailed change history of this release|https://github.com/Jermolene/TiddlyWiki5/compare/master...parameterised-transclusions]]//
+
+! About v5.3.0
+
+This pre-release introduces a number of significant improvements and new features related to some of TiddlyWiki's most fundamental components: macros, widgets, operators and transclusion.
+
+! Introduction to v5.3.0
+
+The motivation of these changes is to fix one of ~TiddlyWiki 5's early design flaws: the reliance on macros using textual substitution as the primary way to modularise and reuse wikitext and filters.
+
+Experience has shown that while macros are a good match for a small number of tasks, they are brittle and error prone for many common operations. See [[Macro Pitfalls]] for a discussion of the problems that accompany this approach. Over the years we have introduced mitigations for the worst problems but these have come at a cost of increased complexity.
+
+The changes in this release provide powerful new ways to achieve common tasks, and unlock completely new capabilities that were previously impossible in wikitext.
+
+* [[Procedures]], which are essentially what macros should have been; they work in exactly the same way except that parameters are exposed as simple variables (without the double underscores) and no textual substitution takes place
+* [[Custom Widgets]], allowing the creation of widgets in wikitext, and the redefinition of built-in widgets
+* [[Functions]], a new way to encapsulate filter expressions with named parameters, including the ability to make custom filter operators
+* Parameterised [[Transclusions|Transclusion]], allowing strings and wikitext trees to be passed to transclusions
+
+The approach taken by this release is to add new functionality by extending and augmenting the system without disturbing existing functionality. All of these changes are thus intended to be backwards compatible. While they represent a new field of opportunities for wikitext authors, it is possible for authors to ignore all these new features and continue to use ~TiddlyWiki 5 in the way that they have always done.
+
+These changes lay the groundwork for macros and related features to be deprecated (which is the point at which users are advised not to use old features, and instead given clear pointers to the equivalent modern functionality).
+
+The new transclusion architecture is not by itself sufficient to enable us to fully deprecate macros yet. To handle the remaining use cases we propose a new backtick quoted attribute format that allows for the substitution of variable values. See https://github.com/Jermolene/TiddlyWiki5/issues/6663 for details.
+
+! Plugin Improvements
+
+*
+
+! Translation improvement
+
+Improvements to the following translations:
+
+*
+
+! Accessibility Improvements
+
+*
+
+! Usability Improvements
+
+*
+
+! Widget Improvements
+
+*
+
+! Filter improvements
+
+*
+
+! Hackability Improvements
+
+*
+
+! Bug Fixes
+
+*
+
+! Developer Improvements
+
+*
+
+! Node.js Improvements
+
+*
+
+! Performance Improvements
+
+*
+! Acknowledgements
+
+[[@Jermolene|https://github.com/Jermolene]] would like to thank the contributors to this release who have generously given their time to help improve TiddlyWiki:
+
+<<.contributors """
+""">>
diff --git a/editions/test/tiddlers/tests/data/custom-operators/NestedParameterised.tid b/editions/test/tiddlers/tests/data/custom-operators/NestedParameterised.tid
new file mode 100644
index 000000000..3e4d610d0
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/custom-operators/NestedParameterised.tid
@@ -0,0 +1,24 @@
+title: CustomOperators/NestedParameterised
+description: Nested parameterised custom operator usage
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+\function .dividebysomething(first:ignored,factor:0.5)
+[divide[2]multiply]
+\end
+
+\function .multiplebysomething(first:ignored,factor:2)
+[multiply[2].dividebysomething[],]
+\end
+
+<$text text={{{ [[123].multiplebysomething[]] }}}/>
+-
+<$text text={{{ [[123].multiplebysomething[x],[4]] }}}/>
+
++
+title: ExpectedResult
+
+
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/custom-operators/Simple.tid b/editions/test/tiddlers/tests/data/custom-operators/Simple.tid
new file mode 100644
index 000000000..089701295
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/custom-operators/Simple.tid
@@ -0,0 +1,21 @@
+title: CustomOperators/Simple
+description: Simple custom operator usage
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+
+\function .multiplybytwo()
+[multiply[2]]
+\end
+
+<$text text={{{ [[123].multiplybytwo[]] }}}/>
+|
+<$text text={{{ [[123]function[.multiplybytwo]] }}}/>
+
++
+title: ExpectedResult
+
+
246|246
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/functions/FunctionAttributes.tid b/editions/test/tiddlers/tests/data/functions/FunctionAttributes.tid
new file mode 100644
index 000000000..2deb49bdc
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/functions/FunctionAttributes.tid
@@ -0,0 +1,24 @@
+title: Functions/FunctionAttributes
+description: Attributes specified as function invocations
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+\function .dividebysomething(factor:0.5)
+[divide]
+\end
+
+\function multiplebysomething(first:ignored,factor:2)
+[multiply[2].dividebysomething[0.25]]
+\end
+
+<$text text=<>/>
+|
+<$text text=<>/>
+
++
+title: ExpectedResult
+
+
16|32
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/functions/FunctionOperator.tid b/editions/test/tiddlers/tests/data/functions/FunctionOperator.tid
new file mode 100644
index 000000000..e2a0038dc
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/functions/FunctionOperator.tid
@@ -0,0 +1,24 @@
+title: Functions/FunctionOperator
+description: Calling a function via the function operator
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+\function .dividebysomething(factor:0.5)
+[divide]
+\end
+
+\function multiplebysomething(first:ignored,factor:2)
+[multiplymultiply[2].dividebysomething[0.25]]
+\end
+
+<$text text={{{ [[4]function[multiplebysomething]] }}}/>
+|
+<$text text={{{ [[6]function[multiplebysomething],[ignored],[4]] }}}/>
+
++
+title: ExpectedResult
+
+
64|192
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/functions/MissingFunction.tid b/editions/test/tiddlers/tests/data/functions/MissingFunction.tid
new file mode 100644
index 000000000..25498e452
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/functions/MissingFunction.tid
@@ -0,0 +1,15 @@
+title: Functions/MissingFunction
+description: Calling a missing function via the function operator
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+
+<$text text={{{ [[23]function[missing]] }}}/>
+
++
+title: ExpectedResult
+
+23
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/functions/RunawayRecursiveFunctions.tid b/editions/test/tiddlers/tests/data/functions/RunawayRecursiveFunctions.tid
new file mode 100644
index 000000000..81be22f16
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/functions/RunawayRecursiveFunctions.tid
@@ -0,0 +1,18 @@
+title: Functions/RunawayRecursiveFunctions
+description: Runaway recursive functions
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+\function .buffalo(p)
+[.buffalo
]
+\end
+
+<$text text=<<.buffalo 8>>/>
+
++
+title: ExpectedResult
+
+/**-- Excessive filter recursion --**/
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/functions/UndefinedParameters.tid b/editions/test/tiddlers/tests/data/functions/UndefinedParameters.tid
new file mode 100644
index 000000000..8a2b0a91a
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/functions/UndefinedParameters.tid
@@ -0,0 +1,22 @@
+title: Functions/UndefinedParameters
+description: Undefined function parameters
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\function greet(who)
+[[hello ]addsuffix]
+\end
+
+<$text text={{{[function[greet],[world]]}}}/>
+
+<>
+
+<$text text={{{[function[greet]]}}}/>
+
+<>
++
+title: ExpectedResult
+
+hello world
hello world
hello
hello
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/functions/WikifiedFunctions.tid b/editions/test/tiddlers/tests/data/functions/WikifiedFunctions.tid
new file mode 100644
index 000000000..733fbdaef
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/functions/WikifiedFunctions.tid
@@ -0,0 +1,36 @@
+title: Functions/WikifiedFunctions
+description: Wikified functions
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+\function fn-buffalo(param)
+[addsuffix[ with a ''buffalo'']]
+\end
+
+\procedure proc-buffalo(param)
+<> with a ''buffalo''
+\end
+
+\define macro-buffalo(param)
+$param$ with a ''buffalo''
+\end
+
+<>
+
+<>
+
+<>
+
+<$transclude $variable="fn-buffalo" param="Going to lunch" $output="text/plain"/>
+
+<$transclude $variable="proc-buffalo" param="Going to breakfast" $output="text/plain"/>
+
+<$transclude $variable="macro-buffalo" param="Going to dinner" $output="text/plain"/>
+
++
+title: ExpectedResult
+
+
Going to lunch with a ''buffalo''
Going to breakfastwith abuffalo
Going to dinner with a buffalo
Going to lunch with a buffalo with a buffaloGoing to dinner with a buffalo
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid b/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid
new file mode 100644
index 000000000..f6834998d
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/genesis-widget/RedefineLet.tid
@@ -0,0 +1,31 @@
+title: Genesis/RedefineLet
+description: Using the genesis widget to override the let widget
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+\widget $let()
+\whitespace trim
+<$parameters $params="@params">
+<$setmultiplevariables $names="[<@params>jsonindexes[]]" $values="[<@params>jsonindexes[]] :map[<@params>jsongetaddprefix[--]addsuffix[--]]">
+<$slot $name="ts-raw"/>
+$setmultiplevariables>
+$parameters>
+\end
+<$let
+ one="Elephant"
+ $two="Kangaroo"
+ $$three="Giraffe"
+>
+(<$text text=<>/>)
+(<$text text=<<$two>>/>)
+(<$text text=<<$$three>>/>)
+$let>
++
+title: ExpectedResult
+
+
(--Elephant--)
+(--Kangaroo--)
+(--Giraffe--)
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/procedures/Nested.tid b/editions/test/tiddlers/tests/data/procedures/Nested.tid
new file mode 100644
index 000000000..f63c634af
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/procedures/Nested.tid
@@ -0,0 +1,20 @@
+title: Procedures/Nested
+description: Nested Procedures
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+\procedure alpha(x)
+\procedure beta(y)
+<$text text=<>/>
+\end beta
+<$transclude $variable="beta" y={{{ [addprefix] }}}/>
+\end alpha
+
+<>
++
+title: ExpectedResult
+
+
ElephantElephant
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/transclude/CustomWidget-ActionWidget.tid b/editions/test/tiddlers/tests/data/transclude/CustomWidget-ActionWidget.tid
new file mode 100644
index 000000000..0be77a9a3
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/transclude/CustomWidget-ActionWidget.tid
@@ -0,0 +1,27 @@
+title: Transclude/CustomWidget/ActionWidget
+description: Custom widget definition
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+<$transclude $tiddler='Result'>
+$transclude>
++
+title: Actions
+
+\whitespace trim
+
+\widget $$action-mywidget(one:'Jaguar')
+\whitespace trim
+<$action-setfield $tiddler="Result" $field="text" $value=<>/>
+\end
+
+<$$action-mywidget one="Dingo">
+ Crocodile
+$$action-mywidget>
++
+title: ExpectedResult
+
+
Dingo
\ No newline at end of file
diff --git a/editions/test/tiddlers/tests/data/transclude/CustomWidget-Fail.tid b/editions/test/tiddlers/tests/data/transclude/CustomWidget-Fail.tid
new file mode 100644
index 000000000..3d0759013
--- /dev/null
+++ b/editions/test/tiddlers/tests/data/transclude/CustomWidget-Fail.tid
@@ -0,0 +1,26 @@
+title: Transclude/CustomWidget/Fail
+description: Custom widget failed definition
+type: text/vnd.tiddlywiki-multiple
+tags: [[$:/tags/wiki-test-spec]]
+
+title: Output
+
+\whitespace trim
+
+\widget $non-existent-widget(one:'Jaguar')
+\whitespace trim
+<$text text=<>/>
+<$slot $name="ts-raw">
+ Whale
+$slot>
+\end
+<$non-existent-widget one="Dingo">
+ Crocodile
+$non-existent-widget>
+<$non-existent-widget one="BumbleBee">
+ Squirrel
+$non-existent-widget>
++
+title: ExpectedResult
+
+
!! ''Testimonials & Reviews''
diff --git a/editions/tw5.com/tiddlers/howtos/Visible Transclusions.tid b/editions/tw5.com/tiddlers/howtos/Visible Transclusions.tid
new file mode 100644
index 000000000..e3f46440e
--- /dev/null
+++ b/editions/tw5.com/tiddlers/howtos/Visible Transclusions.tid
@@ -0,0 +1,14 @@
+created: 20220909111836951
+modified: 20230419103154329
+tags: Learning
+title: Visible Transclusions
+type: text/vnd.tiddlywiki
+
+!! Visible Transclusions
+
+Block transclusions are shown in red, and inline transclusions are shown in green.
+
+<$button>
+<$action-setfield $tiddler="$:/temp/VisibleTransclusions" tags="$:/tags/Macro/View/Body" text={{$:/core/ui/VisibleTransclude}}/>
+Click here to make transclusions visible within story river tiddlers
+$button>
diff --git a/editions/tw5.com/tiddlers/images/New Release Banner.png b/editions/tw5.com/tiddlers/images/New Release Banner.png
index 74e2557d8..b75c8fc19 100644
Binary files a/editions/tw5.com/tiddlers/images/New Release Banner.png and b/editions/tw5.com/tiddlers/images/New Release Banner.png differ
diff --git a/editions/tw5.com/tiddlers/images/Open Collective Logo.tid b/editions/tw5.com/tiddlers/images/Open Collective Logo.tid
new file mode 100644
index 000000000..25e91161a
--- /dev/null
+++ b/editions/tw5.com/tiddlers/images/Open Collective Logo.tid
@@ -0,0 +1,4 @@
+title: Open Collective Logo
+tags: picture
+
+
\ No newline at end of file
diff --git a/editions/tw5.com/tiddlers/macros/import/say-hi-using-variables.tid b/editions/tw5.com/tiddlers/macros/import/say-hi-using-variables.tid
index 4aa265fa3..11064f388 100644
--- a/editions/tw5.com/tiddlers/macros/import/say-hi-using-variables.tid
+++ b/editions/tw5.com/tiddlers/macros/import/say-hi-using-variables.tid
@@ -1,3 +1,4 @@
+code-body: yes
created: 20150221145447000
modified: 20150221145626000
title: $:/editions/tw5.com/macro-examples/say-hi-using-variables
diff --git a/editions/tw5.com/tiddlers/macros/import/say-hi.tid b/editions/tw5.com/tiddlers/macros/import/say-hi.tid
index 2d2d31afc..55db4cc9a 100644
--- a/editions/tw5.com/tiddlers/macros/import/say-hi.tid
+++ b/editions/tw5.com/tiddlers/macros/import/say-hi.tid
@@ -1,8 +1,9 @@
+code-body: yes
created: 20150221145803000
modified: 20150221221536000
title: $:/editions/tw5.com/macro-examples/say-hi
type: text/vnd.tiddlywiki
-\define sayhi(name:"Bugs Bunny" address:"Rabbit Hole Hill")
+\define sayhi(name:"Bugs Bunny",address:"Rabbit Hole Hill")
Hi, I'm $name$ and I live in $address$.
\end
diff --git a/editions/tw5.com/tiddlers/macros/import/tags-of-current-tiddler.tid b/editions/tw5.com/tiddlers/macros/import/tags-of-current-tiddler.tid
index b1bfc753c..860ad33db 100644
--- a/editions/tw5.com/tiddlers/macros/import/tags-of-current-tiddler.tid
+++ b/editions/tw5.com/tiddlers/macros/import/tags-of-current-tiddler.tid
@@ -1,3 +1,4 @@
+code-body: yes
created: 20150221145803000
title: $:/editions/tw5.com/macro-examples/tags-of-current-tiddler
type: text/vnd.tiddlywiki
diff --git a/editions/tw5.com/tiddlers/macros/import/tv-wikilink-tooltip.tid b/editions/tw5.com/tiddlers/macros/import/tv-wikilink-tooltip.tid
index 11b442b8c..9687f4b15 100644
--- a/editions/tw5.com/tiddlers/macros/import/tv-wikilink-tooltip.tid
+++ b/editions/tw5.com/tiddlers/macros/import/tv-wikilink-tooltip.tid
@@ -1,5 +1,5 @@
+code-body: yes
created: 20150228120252000
-modified: 20150228120554000
title: $:/editions/tw5.com/macro-examples/tv-wikilink-tooltip
type: text/vnd.tiddlywiki
diff --git a/editions/tw5.com/tiddlers/pragmas/Pragma_ _define.tid b/editions/tw5.com/tiddlers/pragmas/Pragma_ _define.tid
new file mode 100644
index 000000000..6058b7905
--- /dev/null
+++ b/editions/tw5.com/tiddlers/pragmas/Pragma_ _define.tid
@@ -0,0 +1,51 @@
+created: 20220917112233317
+modified: 20230419103154328
+tags: Pragmas
+title: Pragma: \define
+type: text/vnd.tiddlywiki
+
+The ''\define'' [[pragma|Pragmas]] is used to [[define macros|Macro Definitions]]. It is a shortcut syntax for the SetVariableWidget.
+
+The usual form allows macros to span multiple lines.
+
+```
+\define ([:],[:]...)
+
+\end []
+```
+
+Note that the `\end` marker can optionally specify the name of the macro to which it relates which allows macro definitions to be nested.
+
+There is also a single line form for shorter macros:
+
+```
+\define ([:],[:]...)
+```
+
+The first line of the definition specifies the macro name and any parameters. Each parameter has a name and, optionally, a default value that is used if no value is supplied on a particular call to the macro.
+
+The lines that follow contain the text of the macro text (i.e. the snippet represented by the macro name), until `\end` appears on a line by itself:
+
+<$codeblock code={{$:/editions/tw5.com/macro-examples/say-hi}}/>
+
+Alternatively, the entire definition can be presented on a single line without an `\end` marker:
+
+```
+\define sayhi(name:"Bugs Bunny") Hi, I'm $name$.
+```
+
+Macro definitions can be nested by specifying the name of the macro in the `\end` marker. For example:
+
+<
+\end actions
+<$button actions=<>>
+$caption$
+$button>
+\end special-button
+
+<>
+""">>
+
+A more formal [[presentation|Macro Definition Syntax]] of this syntax is also available.
diff --git a/editions/tw5.com/tiddlers/pragmas/Pragma_ _function.tid b/editions/tw5.com/tiddlers/pragmas/Pragma_ _function.tid
new file mode 100644
index 000000000..253c8b452
--- /dev/null
+++ b/editions/tw5.com/tiddlers/pragmas/Pragma_ _function.tid
@@ -0,0 +1,27 @@
+created: 20221009162634214
+modified: 20230419103154329
+tags: Pragmas
+title: Pragma: \function
+type: text/vnd.tiddlywiki
+
+<<.from-version "5.3.0">> The ''\function'' [[pragma|Pragmas]] is used to [[define custom functions|Functions]]. It is a shortcut syntax for the SetVariableWidget.
+
+The usual form allows custom functions to span multiple lines:
+
+```
+\function ([:],[:]...)
+
+\end []
+```
+
+Note that the `\end` marker can optionally specify the name of the function to which it relates, enabling function definitions to be nested inside procedures, macros or widget definitions.
+
+There is also a single line form for shorter functions:
+
+```
+\function ([:],[:]...)
+```
+
+The first line of the definition specifies the function name and any parameters. Each parameter has a name and, optionally, a default value that is used if no value is supplied on a particular call to the function. The lines that follow contain the text of the function (i.e. the snippet represented by the function name), until `\end` appears on a line by itself:
+
+See [[Functions]] for more details.
\ No newline at end of file
diff --git a/editions/tw5.com/tiddlers/pragmas/Pragma_ _import.tid b/editions/tw5.com/tiddlers/pragmas/Pragma_ _import.tid
new file mode 100644
index 000000000..5971a5490
--- /dev/null
+++ b/editions/tw5.com/tiddlers/pragmas/Pragma_ _import.tid
@@ -0,0 +1,17 @@
+created: 20220917113054582
+modified: 20230419103154329
+tags: Pragmas
+title: Pragma: \import
+type: text/vnd.tiddlywiki
+
+The ''\import'' [[pragma|Pragmas]] is used to import definitions from other tiddlers that are identified with a filter. It is a shortcut syntax for the ImportVariablesWidget.
+
+```
+\import
+```
+
+For example:
+
+```
+\import [all[shadows+tiddlers]tag[$:/tags/Macro]]
+```
diff --git a/editions/tw5.com/tiddlers/pragmas/Pragma_ _parameters.tid b/editions/tw5.com/tiddlers/pragmas/Pragma_ _parameters.tid
new file mode 100644
index 000000000..5f32b06eb
--- /dev/null
+++ b/editions/tw5.com/tiddlers/pragmas/Pragma_ _parameters.tid
@@ -0,0 +1,18 @@
+created: 20220917113154900
+modified: 20230419103154329
+tags: Pragmas
+title: Pragma: \parameters
+type: text/vnd.tiddlywiki
+
+<<.from-version "5.3.0">> The ''\parameters'' [[pragma|Pragmas]] is used within [[procedure|Procedure Definitions]] and [[widget|Widget Definitions]] definitions to declare the parameters that are expected, and their default values. It is a shortcut syntax for the ParametersWidget.
+
+```
+\parameters ([:],[:]...)
+```
+
+For example:
+
+```
+\parameters (firstname:"Joe",lastname:"Blogs")
+```
+
diff --git a/editions/tw5.com/tiddlers/pragmas/Pragma_ _procedure.tid b/editions/tw5.com/tiddlers/pragmas/Pragma_ _procedure.tid
new file mode 100644
index 000000000..082bc466d
--- /dev/null
+++ b/editions/tw5.com/tiddlers/pragmas/Pragma_ _procedure.tid
@@ -0,0 +1,55 @@
+created: 20221007132845007
+modified: 20230419103154329
+tags: Pragmas
+title: Pragma: \procedure
+type: text/vnd.tiddlywiki
+
+<<.from-version "5.3.0">> The ''\procedure'' [[pragma|Pragmas]] is used to [[define procedures|Procedure Definitions]]. It is a shortcut syntax for the SetVariableWidget with an implicit ParametersWidget.
+
+The usual form allows procedures to span multiple lines:
+
+```
+\procedure ([:],[:]...)
+
+\end []
+```
+
+Note that the `\end` marker can optionally specify the name of the procedure to which it relates which allows procedure definitions to be nested.
+
+There is also a single line form for shorter procedures:
+
+```
+\define ([:],[:]...)
+```
+
+The first line of the definition specifies the procedure name and any parameters. Each parameter has a name and, optionally, a default value that is used if no value is supplied on a particular call to the procedure. The lines that follow contain the text of the procedure text (i.e. the snippet represented by the procedure name), until `\end` appears on a line by itself:
+
+For example:
+
+```
+\procedure sayhi(name:"Bugs Bunny")
+Hi, I'm <>.
+\end
+
+<>
+```
+
+Alternatively, the entire definition can be presented on a single line without an `\end` marker:
+
+```
+\procedure sayhi(name:"Bugs Bunny") Hi, I'm <>.
+```
+
+Procedure definitions can be nested by specifying the name of the procedure in the `\end` marker. For example:
+
+<
+\end actions
+<$button actions=<>>
+<
>
+$button>
+\end special-button
+
+<>
+""">>
\ No newline at end of file
diff --git a/editions/tw5.com/tiddlers/pragmas/Pragma_ _rules.tid b/editions/tw5.com/tiddlers/pragmas/Pragma_ _rules.tid
new file mode 100644
index 000000000..799c9b71c
--- /dev/null
+++ b/editions/tw5.com/tiddlers/pragmas/Pragma_ _rules.tid
@@ -0,0 +1,25 @@
+created: 20220917112931273
+modified: 20230419103154329
+tags: Pragmas
+title: Pragma: \rules
+type: text/vnd.tiddlywiki
+
+The ''\rules'' [[pragma|Pragmas]] adjusts the set of parser rules used to parse the remaining text.
+
+```
+\rules only|expect
+```
+
+The list of available parser rules can be consulted in $:/ControlPanel -> Info -> Advanced -> Parsing.
+
+For example, in stylesheets it is typical to only use the rules associated with macros and transclusions:
+
+```
+\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline
+```
+
+Some users prefer not to use CamelCase links:
+
+```
+\rules except prettylink
+```
\ No newline at end of file
diff --git a/editions/tw5.com/tiddlers/pragmas/Pragma_ _whitespace.tid b/editions/tw5.com/tiddlers/pragmas/Pragma_ _whitespace.tid
new file mode 100644
index 000000000..273a35bea
--- /dev/null
+++ b/editions/tw5.com/tiddlers/pragmas/Pragma_ _whitespace.tid
@@ -0,0 +1,20 @@
+created: 20220917113002350
+modified: 20230419103154329
+tags: Pragmas
+title: Pragma: \whitespace
+type: text/vnd.tiddlywiki
+
+<<.from-version "5.1.15">> The ''\whitespace'' [[pragma|Pragmas]] determines how spaces and newlines are treated within wikitext. Note that this only applies to the printable text, and not to other text, such as the values of attributes.
+
+* ''notrim'' -- whitespace text is not subject to special processing (the default)
+* ''trim'' -- whitespace text is removed
+
+```
+\whitespace trim|notrim
+```
+
+For example:
+
+```
+\whitespace trim
+```
diff --git a/editions/tw5.com/tiddlers/pragmas/Pragma_ _widget.tid b/editions/tw5.com/tiddlers/pragmas/Pragma_ _widget.tid
new file mode 100644
index 000000000..f8e589d4a
--- /dev/null
+++ b/editions/tw5.com/tiddlers/pragmas/Pragma_ _widget.tid
@@ -0,0 +1,27 @@
+created: 20221009121950630
+modified: 20230419103154329
+tags: Pragmas
+title: Pragma: \widget
+type: text/vnd.tiddlywiki
+
+<<.from-version "5.3.0">> The ''\widget'' [[pragma|Pragmas]] is used to [[define custom widgets|Custom Widgets]]. It is a shortcut syntax for the SetVariableWidget with an implicit ParametersWidget.
+
+The usual form allows custom widgets to span multiple lines:
+
+```
+\widget ([:],[:]...)
+
+\end []
+```
+
+Note that the `\end` marker can optionally specify the name of the widget to which it relates which allows widget definitions to be nested.
+
+There is also a single line form for shorter widgets:
+
+```
+\widget ([:],[:]...)
+```
+
+The first line of the definition specifies the widget name and any parameters. Each parameter has a name and, optionally, a default value that is used if no value is supplied on a particular call to the widget. The lines that follow contain the text of the widget text (i.e. the snippet represented by the widget name), until `\end` appears on a line by itself:
+
+See [[Custom Widgets]] for more details.
\ No newline at end of file
diff --git a/editions/tw5.com/tiddlers/pragmas/Pragmas.tid b/editions/tw5.com/tiddlers/pragmas/Pragmas.tid
new file mode 100644
index 000000000..46981c51e
--- /dev/null
+++ b/editions/tw5.com/tiddlers/pragmas/Pragmas.tid
@@ -0,0 +1,13 @@
+created: 20220917112416666
+modified: 20230419103154329
+tags: Concepts [[WikiText Parser Modes]]
+title: Pragmas
+type: text/vnd.tiddlywiki
+
+A <<.def pragma>> is a special component of WikiText that provides control over the way the remaining text is parsed.
+
+Pragmas occupy lines that start with `\`. They can only appear at the start of the text of a tiddler, but blank lines and comments are allowed between them. If a pragma appears in the main body of the text, it is treated as if it was ordinary text.
+
+The following pragmas are available:
+
+<>
diff --git a/editions/tw5.com/tiddlers/procedures/Procedure Calls.tid b/editions/tw5.com/tiddlers/procedures/Procedure Calls.tid
new file mode 100644
index 000000000..d66d8f274
--- /dev/null
+++ b/editions/tw5.com/tiddlers/procedures/Procedure Calls.tid
@@ -0,0 +1,56 @@
+caption: Macro Calls
+created: 20221007130006705
+modified: 20230419103154329
+tags: WikiText Procedures
+title: Procedure Calls
+type: text/vnd.tiddlywiki
+
+!! Introduction
+
+This tiddler describes the different ways in which [[macros|Procedures]] can be called.
+
+!! Procedure Call Transclusion Shortcut
+
+To call a [[procedure|Procedures]], place `<<`double angle brackets`>>` around the name and any parameter values.
+
+```
+<>
+```
+
+By default, parameters are listed in the same order as in the procedure definition. A parameter can be labelled with its name and a colon to allow them to be listed in a different order.
+
+If no value is specified for a parameter, the default value given for that parameter in the [[procedure definition|Procedure Definitions]] is used instead. (If no default value was defined, the parameter is blank).
+
+Each parameter value can be enclosed in `'`single quotes`'`, `"`double quotes`"`, `"""`triple double quotes`"""` or `[[`double square brackets`]]`. Triple double quotes allow a value to contain almost anything. If a value contains no spaces or single or double quotes, it requires no delimiters.
+
+See the discussion about [[parser modes|WikiText parser mode: macro examples]]
+
+!! Procedure Calls with <<.wlink TranscludeWidget>> Widget
+
+The shortcut syntax expands to the <<.wlink TranscludeWidget>> widget with the `$variable` attribute specifying the name of the procedure to transclude.
+
+```
+<$transclude $variable="my-procedure" param="This is the parameter value"/>
+```
+
+The widget itself offers greater flexibility than the shortcut syntax, including the ability to specify dynamic parameter values.
+
+!! Assigning Procedure Calls to Attribute Values
+
+The text of a procedure can be directly assigned to an attribute of a widget or HTML element. The result of the procedure is not wikified, which means that [[parameter handling|Procedure Parameter Handling]] does not take place.
+
+```
+
>>
+...
+
+```
+
+!! Using Procedure Calls in Filters
+
+Procedure calls can be used in filters. The text is not wikified which again means that the parameters will be ignored.
+
+```
+<$list filter="[]">
+...
+$list>
+```
\ No newline at end of file
diff --git a/editions/tw5.com/tiddlers/procedures/Procedure Definitions.tid b/editions/tw5.com/tiddlers/procedures/Procedure Definitions.tid
new file mode 100644
index 000000000..e108f219d
--- /dev/null
+++ b/editions/tw5.com/tiddlers/procedures/Procedure Definitions.tid
@@ -0,0 +1,43 @@
+created: 20221007125701001
+modified: 20230419103154329
+tags: WikiText Procedures
+title: Procedure Definitions
+type: text/vnd.tiddlywiki
+
+!! Introduction
+
+This tiddler describes the different ways in which [[macros|Procedures]] can be defined.
+
+!! Procedure Definition Pragma
+
+Macros are created using the [[Pragma: \procedure]] at the start of a tiddler. The definitions are available in the rest of the tiddler that defines them, plus any tiddlers that it transcludes.
+
+```
+\define my-procedure(param)
+This is the macro text (param=<>)
+\end
+```
+
+!! Procedure Definition with Set Widget
+
+Procedures are implemented as a special kind of [[variable|Variables]] and so internally are actually defined with a <<.wlink SetWidget>> widget.
+
+```
+<$set name="my-procedure" value="This is the procedure text">
+...
+$set>
+```
+
+<<.note """that it is not currently possible to specify parameters when defining a procedure with the <<.wlink SetWidget>> widget.""">>
+
+!! Importing Procedure Definitions
+
+The [[Pragma: \import]] or <<.wlink ImportVariablesWidget>> widget can be used to copy procedure definitions from another tiddler.
+
+!! `$:/tags/Macro` Tag
+
+Global procedures can be defined using the [[SystemTag: $:/tags/Macro]].
+
+The tag [[SystemTag: $:/tags/Macro/View]] is used to define procedures that should only be available within the main view template and the preview panel.
+
+The tag [[SystemTag: $:/tags/Macro/View/Body]] is used to define procedures that should only be available within the main view template body and the preview panel.
diff --git a/editions/tw5.com/tiddlers/procedures/Procedure Parameter Handling.tid b/editions/tw5.com/tiddlers/procedures/Procedure Parameter Handling.tid
new file mode 100644
index 000000000..f4841e4e9
--- /dev/null
+++ b/editions/tw5.com/tiddlers/procedures/Procedure Parameter Handling.tid
@@ -0,0 +1,24 @@
+created: 20221007130538285
+modified: 20230419103154329
+tags: WikiText Procedures
+title: Procedure Parameter Handling
+type: text/vnd.tiddlywiki
+
+!! Introduction
+
+[[Procedure|Procedures]] parameters are made available as variables when the procedure contents are wikified.
+
+!! Accessing Parameters as Variables
+
+When procedures are wikified, the parameters can be accessed as variables.
+
+For example:
+
+<$macrocall $name="wikitext-example-without-html" src="""\procedure say-hi(name,address)
+Hi, I'm <> and I live in <>.
+\end
+
+<>
+"""/>
+
+Accessing parameters as variables only works in procedures that are wikified and not, for example, when a procedure is used as an attribute value.
diff --git a/editions/tw5.com/tiddlers/procedures/Procedures.tid b/editions/tw5.com/tiddlers/procedures/Procedures.tid
new file mode 100644
index 000000000..15b422647
--- /dev/null
+++ b/editions/tw5.com/tiddlers/procedures/Procedures.tid
@@ -0,0 +1,35 @@
+created: 20221007124007426
+modified: 20230419103154329
+tags: Concepts Reference
+title: Procedures
+type: text/vnd.tiddlywiki
+
+!! Introduction
+
+<<.from-version "5.3.0">> A <<.def procedure>> is a named snippet of text. They are typically defined with the [[Pragma: \procedure]]:
+
+```
+\procedure my-procedure(parameter:"Default value")
+This is the procedure, and the parameter is <>.
+\end
+```
+
+The name wrapped in double angled [[brackets|Brackets]] is used a shorthand way of [[transcluding|Transclusion]] the snippet. Each of these <<.def "procedure calls">> can supply a different set of parameters:
+
+```
+<>
+<>
+```
+
+The parameters that are specified in the procedure call are made available as variables.
+
+!! How Procedures Work
+
+Procedures are implemented as a special kind of [[variable|Variables]]. The only thing that distinguishes them from ordinary variables is the way that the parameters are handled.
+
+!! Using Procedures
+
+* [[Procedure Definitions]] describes how to create procedures
+* [[Procedure Calls]] describes how to use procedures
+* [[Procedure Parameter Handling]] describes how procedure parameters work
+
diff --git a/editions/tw5.com/tiddlers/variables/Variable Usage.tid b/editions/tw5.com/tiddlers/variables/Variable Usage.tid
new file mode 100644
index 000000000..2166f206a
--- /dev/null
+++ b/editions/tw5.com/tiddlers/variables/Variable Usage.tid
@@ -0,0 +1,154 @@
+created: 20230421020225031
+modified: 20230422144812613
+tags:
+title: Variable Usage
+type: text/vnd.tiddlywiki
+
+\define m1(a1) $a1$ - <<__a1__>> - <>
+\procedure p1(a1) $a1$ - <<__a1__>> - <>
+\function f1(a1) "$a1$" "-" [<__a1__>] ="-" [] :and[join[ ]]
+
+!Ways to define variables and parameters
+|! how declared|! how parameters are defined|! accessing parameter values in the body|
+|\define|`()`|`$param$, <<__param__>>`|
+|~|<<.wlink ParametersWidget>> or `\parameters`|`<>`|
+|<<.wlink SetWidget>>, <<.wlink LetWidget>>, <<.wlink VarsWidget>>|<<.wlink ParametersWidget>> or `\parameters`|`<>`|
+|\procedure, \widget|`()`, <<.wlink ParametersWidget>> or `\parameters`|`<>`|
+|\function|`()`|``|
+|javascript macros|`exports.params` javascript property array|passed as normal javascript function parameter and so accessed as a normal javascript variable|
+
+!!Examples
+These examples are meant to provide insight into the various ways of defining and using parameters. In many cases they do not illustrate best practices.
+
+!!! \define
+
+<$let eg='\define mp1(a1) $a1$ - <<__a1__>>
+
+\define mp2() <$parameters a1><>$parameters>
+
+\define mp3()
+\parameters(a1)
+<>
+\end
+
+|<>|<>|<>|
+'>
+<$macrocall $name="copy-to-clipboard-above-right" src=<>/>
+<$codeblock code=<>/>
+$let>
+
+!!! $set, $let, $vars
+
+<$let eg='<$set name="sp1" value="<$parameters a1><>$parameters>">
+<$set name="sp2" value="""
+\parameters(a1)
+<$parameters a1><>$parameters>
+""">
+<$vars vp1="<$parameters a1><>$parameters>" vp2="""
+\parameters(a1)
+<$parameters a1><>$parameters>
+""">
+<$let lp1="<$parameters a1><>$parameters>" lp2="""
+\parameters(a1)
+<$parameters a1><>$parameters>
+""">
+
+|<>|<>|
+|<>|<>|
+|<>|<>|
+$let>
+$vars>
+$set>
+$set>
+'>
+<$macrocall $name="copy-to-clipboard-above-right" src=<>/>
+<$codeblock code=<>/>
+$let>
+
+!!! \procedure, \widget
+
+<$let eg='\procedure pp1(a1) <>
+
+\procedure pp2() <$parameters a1><>$parameters>
+
+\procedure pp3()
+\parameters(a1)
+<>
+\end
+
+\procedure wp1(a1) <>
+
+\widget wp2() <$parameters a1><>$parameters>
+
+\widget wp3()
+\parameters(a1)
+<>
+\end
+
+|<>|<>|<>|
+|<>|<>|<>|
+'>
+<$macrocall $name="copy-to-clipboard-above-right" src=<>/>
+<$codeblock code=<>/>
+$let>
+
+!!! \function
+<$let eg='\function fp1(a1) []
+|<>|'>
+<$macrocall $name="copy-to-clipboard-above-right" src=<>/>
+<$codeblock code=<>/>
+$let>
+
+
+!Behavior of invoked variables depends on how the variable was declared
+
+|!how invoked|!how declared|!behavior|
+|`<$transclude $variable=macro/>` or `<>` in normal wikitext context|\define|All wikitext and variable substitution and textual substitution takes place|
+|~|<<.wlink SetWidget>>, <<.wlink LetWidget>>, <<.wlink VarsWidget>>, \procedure, \widget|All wikitext and variable substitution takes place|
+|~|\function|Invoking a function in this way (`<>`) is a synonym for `<$text text={{{[function[macro]]}}}/>`. As with any filtered transclusion (i.e. triple curly braces), all results except the first are discarded.|
+||||
+|widget attribute: `
>/>`|\define|Textual substitution of parameters is performed on the body text. No further processing takes place. The result after textual substitution is used as the attribute's value|
+|~|<<.wlink SetWidget>>, <<.wlink LetWidget>>, <<.wlink VarsWidget>>, \procedure, \widget|Body text is retrieved as-is and used as the attribute's value.|
+|~|\function|When a function is invoked as `
>/>`, it is a synonym for `
`. As with any filtered transclusion (i.e. triple curly braces), all results except the first are discarded. That first result is used as the attribute's value. Note that functions are recursively processed even when invoked in this form. In other words a filter expression in a function can invoke another function and the processing will continue|
+||||
+|filter operator parameter: `[]`|\define|Textual substitution of parameters is performed on the body text. No further processing takes place. The result after textual substitution is used as the filter operator's parameter.|
+|~|<<.wlink SetWidget>>, <<.wlink LetWidget>>, <<.wlink VarsWidget>>, \procedure, \widget|Body text is retrieved as-is and used as the filter operator's parameter.|
+|~|\function|The body text of the function is treated as a filter expression and evaluated. The first result is passed to the operator as a parameter. The remaining results are discarded|
+||||
+|function call in a filter expression: `[function[macro]]`|\define, <<.wlink SetWidget>>, <<.wlink LetWidget>>, <<.wlink VarsWidget>>, \procedure, \widget|Every function is a variable, but only variables defined using \function are invokable using the <<.olink function>> filter operator. Attempts to use a non-function variable is the same as if the function doesn't exist. The behavior in this case is like the identity function. All filter input is passed unchanged to the output.|
+|~|\function|The body text of the function is treated as a filter expression and evaluated. This filter expression can itself contain a function call. Filter expressions can be factored out into functions arbitrarily deep.|
+
+!! Examples
+
+Below is an example macro, procedure and function definition. All three forms of parameter substitution `$a1$`, `<<__a1__>>`, and `<>` are included in each definition. The output helps illustrate when each form of substitution will or will not have affect.
+
+```
+\define m1(a1) $a1$ - <<__a1__>> - <>
+\procedure p1(a1) $a1$ - <<__a1__>> - <>
+\function f1(a1) $a1$ "-" [<__a1__>] ="-" [] :and[join[ ]]
+```
+
+| !Variable transclusion|!output |
+| `<>`|<>|
+| `<>`|<>|
+| `<>`|<>|
+| !Widget attribute|!output |
+| `<$text text=<>/>`|<$text text=<>/>|
+| `<$text text=<>/>`|<$text text=<>/>|
+| `<$text text=<>/>`|<$text text=<>/>|
+| !Filter operator parameter|!output |
+| `[]`|<$text text={{{[]}}}/>|
+| `[]`|<$text text={{{[]}}}/>|
+| `[]`|<$text text={{{[]}}}/>|
+| !Function call in filter expression|!output |
+| `[function[m1],[foo]]`|<$text text={{{[function[m1],[foo]]}}}/>|
+| `[function[p1],[foo]]`|<$text text={{{[function[p1],[foo]]}}}/>|
+| `[function[f1],[foo]]`|<$text text={{{[function[f1],[foo]]}}}/>|
+
+!Namespaces
+
+*''tiddler titles'' - tiddlers are uniquely identified by their title. The namespace for tiddler titles and variable names are completely separate.
+*''variables'' - \define, <<.wlink SetWidget>>, <<.wlink LetWidget>>, <<.wlink VarsWidget>>, \procedure, \widget, \function all create variables. If the same name is used, then later define will overwrite earlier defined
+ *''<<.op function>> filter operator parameter'' - only variables defined using \function can be called using the <<.olink function>> operator
+ *''filter operators'' - only the [[javascript defined filter operators|Filter Operators]] and variables defined using \function with name starting with a dot can be called
+ *''widgets'' - variables defined using \widget can be invoked using `<$widget/>` syntax ONLY if the name starts a dollar sign (to override existing javascript defined widgets) or double dollar sign (to define [[custom widgets|Custom Widgets]]). Without the dollar sign prefix, defining variables using \widget is no different than using \procedure.
diff --git a/editions/tw5.com/tiddlers/variables/Variables.tid b/editions/tw5.com/tiddlers/variables/Variables.tid
index 2e80f2678..65ad96b31 100644
--- a/editions/tw5.com/tiddlers/variables/Variables.tid
+++ b/editions/tw5.com/tiddlers/variables/Variables.tid
@@ -1,23 +1,142 @@
created: 20141002133113496
-modified: 20221221175615776
-tags: Concepts Reference
+modified: 20230422150445336
+tags: Concepts Reference WikiText
title: Variables
type: text/vnd.tiddlywiki
-A <<.def variable>> is a snippet of text that can be accessed by name within a particular branch of the [[widget tree|Widgets]]. The snippet is known as the variable's <<.def value>>.
+!! Introduction
-A new variable is defined using a <<.wlink SetWidget>> or <<.wlink LetWidget>> widget, and is then available to any of the children of that widget, including transcluded content. A <<.wid set>> widget can reuse an existing name, thus binding a different snippet to that name for the duration of the widget's children.
+A <<.def variable>> is a snippet of text that can be accessed by name. The text is referred to as the variable's <<.def value>>.
-The <<.wlink ListWidget>> widget by default sets a particular variable <<.var currentTiddler>> to each listed title in turn.
+Variables are defined by [[widgets|Widgets]]. Several core widgets define variables, the most common being the <<.wlink SetWidget>>, <<.wlink LetWidget>> and <<.wlink ListWidget>> widgets.
-For an overview of how to use variables, see [[Variables in WikiText]].
+The values of variables are available to descendant widgets, including transcluded content. For example, within each tiddler in the main story river the variable "currentTiddler" is set to the title of the tiddler.
-Despite the term <<.word variable>>, ''each snippet is a constant string''. The apparent variability is actually the result of the presence of multiple variables with the same name in different parts of the widget tree.
+Variables can also be overwritten by descendent widgets defining variables of the same name, thus binding a different snippet to that name for the scope of the children of the widget.
-[[Macros]] are a special form of variable whose value can contain placeholders that get filled in with parameters whenever the macro is used.
+!! Special Kinds of Variables
-By themselves, the snippets are <<.em not>> parsed as WikiText. However, a variable reference will transclude a snippet into a context where ~WikiText parsing <<.em may>> be occurring. Within a snippet, the only markup detected is `$name$` for a macro parameter transclusion and `$(name)$` for a variable transclusion.
+There are several special kinds of variable that extend their basic capabilities:
-The <<.mlink dumpvariables>> macro lists all variables (including macros) that are available at that position in the widget tree.
+* [[Procedures]] are snippets of text that can be passed parameters when wikified
+* [[Functions]] are snippets of text containing [[filters|Filters]] with optional named parameters
+* [[Custom Widgets]] are snippets of text containing definitions of custom [[widget|Widgets]]
+* [[Macros]] are snippets of text that can contain placeholders that are filled in with parameters whenever the macro is used
+
+Note that these special kinds of variable can only be created with the associated shortcut definition syntax.
+
+For a more detailed comparison of these special kinds of variables, see [[Variable Usage]].
+
+!! Defining Variables
+
+The following core widgets are commonly used to define variables:
+
+* <<.wlink LetWidget>> widget -- the easiest way to define multiple variables
+* <<.wlink SetWidget>> widget -- the most flexible way to define a single variable
+* <<.wlink ParametersWidget>> widget -- used to declare parameter variables within [[procedures|Procedures]] and [[custom widgets|Custom Widgets]]
+* <<.wlink ListWidget>> widget -- defines a loop variable and optional counter variable
+* <<.wlink SetMultipleVariablesWidget>> widget -- allows creation of multiple variables at once where the names and values are not known in advance
+
+!! Using Variables
+
+Once a variable is defined there are several ways to access it.
+
+!!! Transcluding Variables
+
+Transcluding a variable renders the text contents of the variable as if it replaced the call. It is a shortcut syntax for the <<.wlink TranscludeWidget>> widget with the `$variable` attribute.
+
+```
+<>
+```
+
+Parameters can be passed to the transclusion as follows:
+
+```
+<>
+<>
+<>
+```
+
+The handling of these parameters depends on the kind of variable:
+
+* [[Procedures]] assign the parameters to variables that are available within the procedure
+* [[Macros]] replace the text of the special markers `$param$` with the values passed to the macro for those parameters (see [[Macro Parameter Handling]] for the details)
+
+The parameters are ignored for other kinds of variable.
+
+!!! Macro Variable Substitutions
+
+Before the text of a macro is used, the special markers `$(variable)$` are replaced with the values of the named variable.
+
+!!! Variable Attributes
+
+Variables can be used as the value of attributes of widgets or HTML elements:
+
+```
+
>>
+```
+
+Parameters can be passed:
+
+```
+
>>
+...
+
>>
+...
+
>>
+...
+```
+
+The handling of these parameters depends on the kind of variable:
+
+* [[Functions]] assign the parameters to variables that are available within the function
+* [[Macros]] replace the text of the special markers `$param$` with the values passed to the macro for those parameters (see [[Macro Parameter Handling]] for the details)
+
+The parameters are ignored for other kinds of variable.
+
+!!! Variables in Filters
+
+Variables can be accessed within [[Filters]] using angle brackets to quote the name:
+
+```
+[]
+```
+
+Parameters can be passed in the usual way:
+
+```
+[]
+[]
+[]
+...
+```
+
+!! See Also
+
+* The <<.mlink dumpvariables>> macro lists all variables that are available at that position in the widget tree
+* Complete listing of ~TiddlyWiki's built-in [[Core Variables]]
+
+!! Examples
+
+!!! Example of Defining a Variable
+
+<$macrocall $name=".example" n="1"
+eg="""<$set name=animal value=zebra>
+<>
+$set>"""/>
+
+!!! Example of Defining a Macro
+
+The `\define` pragma below [[defines a macro|Macro Definitions]] called <<.var tags-of-current-tiddler>>. The macro returns the value of the tiddler's <<.field tags>> field, and can be accessed from anywhere else in the same tiddler (or in any tiddler that [[imports|ImportVariablesWidget]] it).
+
+<$importvariables filter="$:/editions/tw5.com/macro-examples/tags-of-current-tiddler">
+<$codeblock code={{$:/editions/tw5.com/macro-examples/tags-of-current-tiddler}}/>
+<$macrocall $name=".example" n="2" eg="""The tags are: <>"""/>
+$importvariables>
+
+!!! Example of Using a Variable as a Filter Parameter
+
+This example uses the <<.olink backlinks>> [[operator|Filter Operators]] to list all tiddlers that link to this one.
+
+<$macrocall $name=".example" n="3" eg="""<backlinks[]]">>"""/>
-~TiddlyWiki's core has [[several variables|Core Variables]] built in.
diff --git a/editions/tw5.com/tiddlers/widgets/Custom Widgets.tid b/editions/tw5.com/tiddlers/widgets/Custom Widgets.tid
new file mode 100644
index 000000000..c220302cf
--- /dev/null
+++ b/editions/tw5.com/tiddlers/widgets/Custom Widgets.tid
@@ -0,0 +1,84 @@
+created: 20221007144237585
+modified: 20230419103154328
+tags: Concepts Reference
+title: Custom Widgets
+type: text/vnd.tiddlywiki
+
+!! Introduction
+
+<<.from-version "5.3.0">> A <<.def "custom widget">> is a special kind of [[procedure|Procedures]] that can be called using the same syntax as widgets.
+
+Custom widgets can also be used to override built-in JavaScript widgets to customise their behaviour.
+
+!! Defining Custom Widgets
+
+Custom widgets are usually defined with the [[Pragma: \widget]]:
+
+```
+\widget $$my-widget(attribute:"Default value")
+This is the widget, and the attribute is <>.
+\end
+```
+
+The name of the widget must start with one or two dollar signs:
+
+* A ''single dollar sign'' is used to override existing core widgets
+** for example, `$text` or `$codeblock`
+* ''Double dollar signs'' are used to define a custom widget
+** for example, `$$mywidget` or `$$acme-logger`
+
+!! Using Custom Widgets
+
+Custom widgets are called in the same way as ordinary built-in widgets:
+
+```
+<$my-widget/>
+
+<$my-widget attribute="The parameter"/>
+```
+
+The attributes that are specified in the widget call are made available as parameter variables.
+
+!! Accessing Content of Custom Widgets
+
+Within the definition of a custom widget the content of the calling widget is available via the `<$slot $name="ts-raw"/>` widget. The contents of the <<.wlink SlotWidget>> widget is used as the default content if the widget was called without any content.
+
+For example:
+
+<>/>
+<$slot $name="ts-raw">
+ Whale
+$slot>
+\end
+
+<$$mywidget one="Dingo">
+ Crocodile
+$$mywidget>
+
+<$$mywidget/>""">>
+
+!! How Custom Widgets Work
+
+Custom widgets are implemented as a special kind of [[variable|Variables]]. The only thing that distinguishes them from ordinary variables is the way that they can be called as a custom widget with attributes mapped to parameters.
+
+!! Overriding Core ~JavaScript Widgets
+
+Custom widgets can use the <<.wlink "GenesisWidget">> widget to invoke the original widget, bypassing the override. For example, here we override the <<.wlink CodeBlockWidget>> widget to add `≤≥` symbols around each string of text.
+
+
+<addprefix[≤]addsuffix[≥]] }}}/>
+\end
+
+<$codeblock code="Kangaroo"/>
+
+<$codeblock code={{$:/SiteTitle}}/>
+
+```
+Python
+```
+
+<$let test="Tiger">
+<$codeblock code=<>/>
+$let>""">>
diff --git a/editions/tw5.com/tiddlers/widgets/ErrorWidget.tid b/editions/tw5.com/tiddlers/widgets/ErrorWidget.tid
index aee5617d2..d6afb86ed 100644
--- a/editions/tw5.com/tiddlers/widgets/ErrorWidget.tid
+++ b/editions/tw5.com/tiddlers/widgets/ErrorWidget.tid
@@ -1,6 +1,6 @@
caption: error
created: 20220909111836951
-modified: 20220909111836951
+modified: 20230419103154328
tags: Widgets
title: ErrorWidget
type: text/vnd.tiddlywiki
diff --git a/editions/tw5.com/tiddlers/widgets/FillWidget.tid b/editions/tw5.com/tiddlers/widgets/FillWidget.tid
new file mode 100644
index 000000000..3fffd51f0
--- /dev/null
+++ b/editions/tw5.com/tiddlers/widgets/FillWidget.tid
@@ -0,0 +1,21 @@
+caption: fill
+created: 20220909111836951
+modified: 20230419103154328
+tags: Widgets
+title: FillWidget
+type: text/vnd.tiddlywiki
+
+! Introduction
+
+<<.from-version "5.3.0">> The <<.wlink FillWidget>> widget is used within a <<.wlink TranscludeWidget>> widget to specify the content that should be copied to the named "slot". Slots are defined by the <<.wlink SlotWidget>> widget within the transcluded content.
+
+See the <<.wlink TranscludeWidget>> widget for details.
+
+! Attributes
+
+The content of the <<.wlink FillWidget>> widget is used as the content to be passed to the transclusion.
+
+|!Attribute |!Description |
+|$name |The name of the slot to be filled |
+
+<<.warning """The $name attribute must be specified as a literal string""">>
diff --git a/editions/tw5.com/tiddlers/widgets/ImportVariablesWidget.tid b/editions/tw5.com/tiddlers/widgets/ImportVariablesWidget.tid
index a9451bc63..93ae44ae4 100644
--- a/editions/tw5.com/tiddlers/widgets/ImportVariablesWidget.tid
+++ b/editions/tw5.com/tiddlers/widgets/ImportVariablesWidget.tid
@@ -34,7 +34,7 @@ So-called global macros are implemented within the main page template ([[$:/core
! `\import` Pragma
-<<.from-version "5.1.18">> The `\import` [[pragma|Pragma]] is an alternative syntax for using the ImportVariablesWidget. For example, the previous example could be expressed as:
+<<.from-version "5.1.18">> The [[Pragma: \import]] is an alternative syntax for using the ImportVariablesWidget. For example, the previous example could be expressed as:
```
\import [[$:/core/ui/PageMacros]] [all[shadows+tiddlers]tag[$:/tags/Macro]!has[draft.of]]
diff --git a/editions/tw5.com/tiddlers/widgets/MacroCallWidget.tid b/editions/tw5.com/tiddlers/widgets/MacroCallWidget.tid
index e163c1d41..e06e3601d 100644
--- a/editions/tw5.com/tiddlers/widgets/MacroCallWidget.tid
+++ b/editions/tw5.com/tiddlers/widgets/MacroCallWidget.tid
@@ -1,48 +1,31 @@
caption: macrocall
created: 20131024141900000
-modified: 20220122193731433
-tags: Widgets
+modified: 20230419103154328
+tags: Widgets $:/deprecated
title: MacroCallWidget
type: text/vnd.tiddlywiki
-! Introduction
+<<.deprecated-since "5.3.0" "TranscludeWidget">>
-The macro call widget provides a more flexible alternative syntax for invoking macros compared to the usual `<>` syntax documented in [[Macros in WikiText]].
+The <<.wlink MacroCallWidget>> widget is deprecated. While it will continue to work, users are now advised to use the <<.wlink TranscludeWidget>> widget, converting the `$name` attribute to `$variable`.
-For example, a macro called `italicise` that takes a single parameter called `text` would usually be invoked like this:
+For example,
```
-<>
-<>
+<$macrocall $name="my-macro" my-parameter="Elephant"/>
```
-The same macro can be invoked using the macro call widget like this:
+should be changed to:
```
-<$macrocall $name="italicise" text="Text to be made into italics"/>
-<$macrocall $name="italicise" text={{Title of tiddler containing text to be italicised}}/>
-<$macrocall $name="italicise" text=<>/>
+<$transclude $variable="my-macro" my-parameter="Elephant"/>
```
-The advantages of the widget formulation are:
-
-* Macro parameters are specified as widget attributes, thus allowing indirection via `{{title!!field}}`, `<>` or `{{{filter}}}`
-* The output format can be chosen from several options:
-** `text/html` wikifies the result of the macro
-** `text/plain` wikifies the result of the macro and then extracts the plain text characters (ie. ignoring HTML tags)
-** <<.from-version "5.1.23">> `text/raw` returns the result of the macro, without wikification
-
-You can see several examples of the macro call widget within the core:
-
-* Listing module information: [[$:/snippets/modules]]
-* Listing field information: [[$:/snippets/allfields]]
-* Generating `data:` URIs: [[$:/themes/tiddlywiki/starlight/styles.tid]]
-
-See also [[WikiText parser mode: macro examples]]
+Internally, the <<.wlink MacroCallWidget>> widget is implemented via the <<.wlink TranscludeWidget>> widget.
! Content and Attributes
-The content of the `<$macrocall>` widget is ignored.
+The content of the <<.wlink MacroCallWidget>> widget is ignored.
|!Attribute |!Description |
|$name |Name of the macro to invoke |
diff --git a/editions/tw5.com/tiddlers/widgets/ParametersWidget.tid b/editions/tw5.com/tiddlers/widgets/ParametersWidget.tid
new file mode 100644
index 000000000..8ddee3151
--- /dev/null
+++ b/editions/tw5.com/tiddlers/widgets/ParametersWidget.tid
@@ -0,0 +1,61 @@
+caption: parameters
+created: 20220909111836951
+modified: 20230419103154328
+tags: Widgets
+title: ParametersWidget
+type: text/vnd.tiddlywiki
+
+<<.from-version "5.3.0">> The <<.wlink ParametersWidget>> widget is used within transcluded content to declare the parameters to be made available to the <<.wlink TranscludeWidget>> widget.
+
+There are shortcuts for common scenarios that can often make it unnecessary to use the <<.wlink ParametersWidget>> widget directly:
+
+* the [[Pragma: \parameters]]
+* the [[Pragma: \procedure]] for declaring procedure
+* the [[Pragma: \widget]] for declaring custom widgets
+
+The <<.wlink ParametersWidget>> widget must be used directly in the following situations:
+
+* When the default value of a parameter must be computed dynamically
+* When the `$depth` attribute is used to retrieve parameters from a parent transclusion (see below)
+
+! Content and Attributes
+
+The content of the <<.wlink ParametersWidget>> widget is the scope within which the values of the parameters can be accessed as ordinary variables.
+
+|!Attribute |!Description |
+|$depth |The index of the parent transclusion from which to obtain the parameters (defaults to 1). See below |
+|$parseMode |Optional name of a variable in which is made available the parse mode of the content of the parent transclusion (the parse mode can be "inline" or "block") |
+|$parseTreeNodes |Optional name of a variable in which is made available the JSON representation of the parse tree nodes contained within the parent transclusion |
+|$slotFillParseTreeNodes |Optional name of a variable in which is made available the JSON representation of the parse tree nodes corresponding to each fill widget contained within the parent transclusion (as an object where the keys are the slot names and the values are the parse tree nodes) |
+|$params |Optional name of a variable in which is made available the JSON representation of the parameters passed to the parent transclusion (as an object where the keys are the parameter names and the values are the coresponding values) |
+|//{attributes not starting with $}// |Any attributes that do not start with a dollar are used as parameters, with the value specifying the default to be used for missing parameters |
+|//{other attributes starting with $}// |Other attributes starting with a single dollar sign are reserved for future use |
+|//{attributes starting with $$}// |Attributes starting with two dollar signs are used as parameters to the transclusion, but with the name changed to use a single dollar sign. The value specifies the default to be used for missing parameters |
+
+<<.note "Note the special treatment required for parameters names that start with a `$`; this can be avoided by using one of the pragmas">>
+
+!! `$depth` Attribute
+
+By default, the <<.wlink ParametersWidget>> widget retrieves parameters from the immediate parent transclusion. The `$depth` attribute permits access to the parameters of parent transclusions by specifying an index to the parent to be inspected ("1" is the immediate parent, "2" is the parent of that parent, etc.). This is useful in some situations where an intervening transclusion prevents immediate access to desired parameters.
+
+!! `$parseMode`, `$parseTreeNodes`, `$slotFillParseTreeNodes` and `$params` Attributes
+
+These attributes provide low level access to the contents of the transcluding widget:
+
+* The `$params` attribute provides access to the raw parameters provided to the transcluding widget. Represented in JSON as an object with keys of the parameter names and values of the corresponding parameter values
+* The `$parseMode` attribute contains `block` or `inline` to indicate whether the contents was parsed in block or inline mode
+* The `$parseTreeNodes` attribute provides access to the raw parse tree nodes that represent the contents of the transcluding widget. Represented in JSON as an array of parse tree nodes
+* The `$slotFillParseTreeNodes` attribute provides access to the raw parse tree nodes corresponding to the filled slots within the contents of the transcluding widget. Represented in JSON as an object with keys of the slot name and values being an array of parse tree nodes
+
+! Examples
+
+Here the <<.wlink ParametersWidget>> widget is used to declare a parameter whose default value is transcluded from another tiddler.
+
+<$macrocall $name='wikitext-example-without-html'
+src="""\procedure mymacro()
+<$parameters name={{$:/SiteTitle}} age="21">
+My name is <