Merge branch 'master' into polymorphic-filters

This commit is contained in:
jeremy@jermolene.com 2022-09-02 18:23:04 +01:00
commit ce0b6c40c0
17 changed files with 367 additions and 35 deletions

View File

@ -18,6 +18,8 @@ CopyToClipboard/Caption: copy to clipboard
CopyToClipboard/Hint: Copy this text to the clipboard
Delete/Caption: delete
Delete/Hint: Delete this tiddler
DeleteTiddlers/Caption: delete tiddlers
DeleteTiddlers/Hint: Delete tiddlers
Edit/Caption: edit
Edit/Hint: Edit this tiddler
Encryption/Caption: encryption

View File

@ -8,6 +8,7 @@ CloseAll/Button: close all
ColourPicker/Recent: Recent:
ConfirmCancelTiddler: Do you wish to discard changes to the tiddler "<$text text=<<title>>/>"?
ConfirmDeleteTiddler: Do you wish to delete the tiddler "<$text text=<<title>>/>"?
ConfirmDeleteTiddlers: Are you sure you wish to delete <<resultCount>> tiddler(s)?
ConfirmOverwriteTiddler: Do you wish to overwrite the tiddler "<$text text=<<title>>/>"?
ConfirmEditShadowTiddler: You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit "<$text text=<<title>>/>"?
ConfirmAction: Do you wish to proceed?

View File

@ -3,7 +3,7 @@ tags: $:/tags/AdvancedSearch/FilterButton
\whitespace trim
<$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
<$button popup=<<qualify "$:/state/filterDeleteDropdown">> class="tc-btn-invisible">
<$button tooltip={{$:/language/Buttons/DeleteTiddlers/Hint}} popup=<<qualify "$:/state/filterDeleteDropdown">> class="tc-btn-invisible">
{{$:/core/images/delete-button}}
</$button>
</$reveal>
@ -13,13 +13,13 @@ tags: $:/tags/AdvancedSearch/FilterButton
<div class="tc-block-dropdown tc-edit-type-dropdown">
<div class="tc-dropdown-item-plain">
<$set name="resultCount" value="""<$count filter={{$:/temp/advancedsearch}}/>""">
Are you sure you wish to delete <<resultCount>> tiddler(s)?
{{$:/language/ConfirmDeleteTiddlers}}
</$set>
</div>
<div class="tc-dropdown-item-plain">
<$button class="tc-btn">
<$action-deletetiddler $filter={{$:/temp/advancedsearch}}/>
Delete these tiddlers
{{$:/language/Buttons/DeleteTiddlers/Hint}}
</$button>
</div>
</div>

View File

@ -84,23 +84,7 @@ describe("json filter tests", function() {
expect(wiki.filterTiddlers("[{First}jsontype[d],[f],[4]]")).toEqual(["null"]);
});
it("should support the jsontypecheck operator", function() {
expect(wiki.filterTiddlers("[{First}jsontypecheck[string]]")).toEqual(['{"a":"one","b":"","c":1.618,"d": {"e": "four","f": ["five","six",true,false,null]}}']);
expect(wiki.filterTiddlers("[{First}jsonget[]jsontypecheck[object]]")).toEqual(['{"a":"one","b":"","c":1.618,"d":{"e":"four","f":["five","six",true,false,null]}}']);
expect(wiki.filterTiddlers("[{First}jsonget[a]jsontypecheck[string]]")).toEqual(["one"]);
expect(wiki.filterTiddlers("[{First}jsonget[b]jsontypecheck[string]]")).toEqual([""]);
expect(wiki.filterTiddlers("[{First}jsonget[c]jsontypecheck[number]]")).toEqual(["1.618"]);
expect(wiki.filterTiddlers("[{First}jsonget[d]jsontypecheck[object]]")).toEqual(['{"e":"four","f":["five","six",true,false,null]}']);
expect(wiki.filterTiddlers("[{First}jsonget[d],[e]jsontypecheck[string]]")).toEqual(["four"]);
expect(wiki.filterTiddlers("[{First}jsonget[d],[f]jsontypecheck[array]]")).toEqual(['["five","six",true,false,null]']);
expect(wiki.filterTiddlers("[{First}jsonget[d],[f],[0]jsontypecheck[string]]")).toEqual(["five"]);
expect(wiki.filterTiddlers("[{First}jsonget[d],[f],[1]jsontypecheck[string]]")).toEqual(["six"]);
expect(wiki.filterTiddlers("[{First}jsonget[d],[f],[2]jsontypecheck[boolean]]")).toEqual(["true"]);
expect(wiki.filterTiddlers("[{First}jsonget[d],[f],[3]jsontypecheck[boolean]]")).toEqual(["false"]);
expect(wiki.filterTiddlers("[{First}jsonget[d],[f],[4]jsontypecheck[null]]")).toEqual(["null"]);
});
it("should support the jsontype operator", function() {
it("should support the format:json operator", function() {
expect(wiki.filterTiddlers("[{First}format:json[]]")).toEqual(["{\"a\":\"one\",\"b\":\"\",\"c\":1.618,\"d\":{\"e\":\"four\",\"f\":[\"five\",\"six\",true,false,null]}}"]);
expect(wiki.filterTiddlers("[{First}format:json[4]]")).toEqual(["{\n \"a\": \"one\",\n \"b\": \"\",\n \"c\": 1.618,\n \"d\": {\n \"e\": \"four\",\n \"f\": [\n \"five\",\n \"six\",\n true,\n false,\n null\n ]\n }\n}"]);
expect(wiki.filterTiddlers("[{First}format:json[ ]]")).toEqual(["{\n \"a\": \"one\",\n \"b\": \"\",\n \"c\": 1.618,\n \"d\": {\n \"e\": \"four\",\n \"f\": [\n \"five\",\n \"six\",\n true,\n false,\n null\n ]\n }\n}"]);

View File

@ -1,5 +1,5 @@
created: 20201020102735123
modified: 20210524044020645
modified: 20220611104737314
tags: [[Operator Examples]] [[format Operator]]
title: format Operator (Examples)
type: text/vnd.tiddlywiki
@ -18,9 +18,12 @@ Modified date shown as a relative date:
A tiddler title with spaces formatted as a title list:
<<.operator-example 4 """[[Hello There]format:titlelist[]]""">>
All tiddler titles tagged with <<tag TableOfContents>> formatted as a title list :
All tiddler titles tagged with <<tag TableOfContents>> formatted as a title list:
<<.operator-example 5 """[tag[TableOfContents]format:titlelist[]]""">>
A JSON string formatted as JSON note how the JSON string is normalised to remove the duplicated properties:
<<.operator-example 6 """[[{"one":"first","one":"another","two":"second"}]format:json[]]""">>
<<.tip "To create a string to save a [[title list|Title List]] into a list field, use `format:titlelist[]` with the [[join operator|join Operator]]">>
<<.operator-example 6 """[tag[TableOfContents]format:titlelist[]join[ ]]""">>
For example, to save titles tagged `TableOfContents` to the titles field of the tiddler [[format titlelist test]]:

View File

@ -1,6 +1,6 @@
caption: format
created: 20201020100834443
modified: 20220523075550449
modified: 20220611104737314
op-input: a [[selection of titles|Title Selection]]
op-output: input strings formatted according to the specified suffix <<.place B>>
op-parameter: optional format string for the formats
@ -17,9 +17,10 @@ type: text/vnd.tiddlywiki
The suffix <<.place B>> is one of the following supported string formats:
|!Format |!Description |
|^`date` |The input string is interpreted as a UTC date and displayed according to the DateFormat specified in the optional operator parameter. (Defaults to "YYYY MM DD 0hh:0mm") |
|^`relativedate` |The input string is interpreted as a UTC date and displayed as the interval from the present instant. Any operator parameters are ignored. |
|^`titlelist` |<<.from-version "5.2.0">>The input string wrapped in double square brackets if it contains a space. Appropriate for use in a [[title list|Title List]]. |
|^`date` |The input string is interpreted as a UTC date and displayed according to the DateFormat specified in the optional operator operand. (Defaults to "YYYY MM DD 0hh:0mm") |
|^`json` |<<.from-version "5.2.4">> The input string is interpreted as JSON and displayed with standard formatting. The optional operator operand specifies the number of spaces to use for indenting, or a string to use for indenting. Nothing is returned if the input string is not valid JSON |
|^`relativedate` |The input string is interpreted as a UTC date and displayed as the interval from the present instant. Any operator parameters are ignored |
|^`titlelist` |<<.from-version "5.2.0">> The input string wrapped in double square brackets if it contains a space. Appropriate for use in a [[title list|Title List]]. |
<<.warning """The [[Title List]] format cannot reliably represent items that contain certain specific character sequences such as `]] `. Thus it should not be used where there is a possibility of such sequences occurring.""">>

View File

@ -0,0 +1,86 @@
created: 20220611104737314
modified: 20220611104737314
tags: [[Filter Operators]] [[JSON Operators]]
title: jsonget Operator
caption: jsonget
op-purpose: retrieve the value of a property from JSON strings
op-input: a selection of JSON strings
op-parameter: one or more indexes of the property to retrieve
op-output: the values of each of the retrieved properties
<<.from-version "5.2.4">> See [[JSON in TiddlyWiki]] for background.
The <<.op jsonget>> operator is used to retrieve values from JSON data. See also the following related operators:
* <<.olink jsontype>> to retrieve the type of a JSON value
* <<.olink jsonindexes>> to retrieve the names of the fields of a JSON object, or the indexes of a JSON array
Properties within a JSON object are identified by a sequence of indexes. In the following example, the value at `[a]` is `one`, and the value at `[d][f][0]` is `five`.
```
{
"a": "one",
"b": "",
"c": "three",
"d": {
"e": "four",
"f": [
"five",
"six",
true,
false,
null
],
"g": {
"x": "max",
"y": "may",
"z": "maize"
}
}
}
```
The following examples assume that this JSON data is contained in a variable called `jsondata`.
The <<.op jsonget>> operator uses multiple operands to specify the indexes of the property to retrieve:
```
[<jsondata>jsonget[a]] --> "one"
[<jsondata>jsonget[d],[e]] --> "four"
[<jsondata>jsonget[d],[f],[0]] --> "five"
```
Indexes can be dynamically composed from variables and transclusions:
```
[<jsondata>jsonget<variable>,{!!field},[0]]
```
Boolean values and null are returned as normal strings. The <<.olink jsontype>> operator can be used to retrieve a string identifying the original type. Thus:
```
[<jsondata>jsontype[a]] --> "string"
[<jsondata>jsontype[d]] --> "object"
[<jsondata>jsontype[d],[f]] --> "array"
[<jsondata>jsontype[d],[f],[2]] --> "boolean"
```
Using the <<.op jsonget>> operator to retrieve an object or an array returns a JSON string of the values. For example:
```
[<jsondata>jsonget[d],[f]] --> `["five","six",true,false,null]`
[<jsondata>jsonget[d],[g]] --> `{"x": "max","y": "may","z": "maize"}`
```
The <<.olink jsonindexes>> operator retrieves the corresponding indexes:
```
[<jsondata>jsonindexes[d],[f]] --> "0", "1", "2", "3", "4"
[<jsondata>jsonindexes[d],[g]] --> "x", "y", "z"
```
A subtlety is that the special case of a single blank operand is used to identify the root object. Thus:
```
[<jsondata>jsonindexes[]] --> "a", "b", "c", "d"
```

View File

@ -0,0 +1,64 @@
created: 20220611104737314
modified: 20220611104737314
tags: [[Filter Operators]] [[JSON Operators]]
title: jsonindexes Operator
caption: jsonindexes
op-purpose: retrieve the value of a property from JSON strings
op-input: a selection of JSON strings
op-parameter: one or more indexes of the property to retrieve
op-output: the values of each of the retrieved properties
<<.from-version "5.2.4">> See [[JSON in TiddlyWiki]] for background.
The <<.op jsonindexes>> operator is used to retrieve the property names of JSON objects or the index names of JSON arrays. See also the following related operators:
* <<.olink jsonget>> to retrieve the values of a property in JSON data
* <<.olink jsontype>> to retrieve the type of a JSON value
Properties within a JSON object are identified by a sequence of indexes. In the following example, the value at `[a]` is `one`, and the value at `[d][f][0]` is `five`.
```
{
"a": "one",
"b": "",
"c": "three",
"d": {
"e": "four",
"f": [
"five",
"six",
true,
false,
null
],
"g": {
"x": "max",
"y": "may",
"z": "maize"
}
}
}
```
The following examples assume that this JSON data is contained in a variable called `jsondata`.
The <<.op jsonindexes>> operator uses multiple operands to specify the indexes of the property to retrieve:
```
[<jsondata>jsonindexes[d],[f]] --> "0", "1", "2", "3", "4"
[<jsondata>jsonindexes[d],[g]] --> "x", "y", "z"
```
Indexes can be dynamically composed from variables and transclusions:
```
[<jsondata>jsonindexes<variable>,{!!field}]
```
Retrieving the indexes of JSON properties that are not objects or arrays will return nothing.
A subtlety is that the special case of a single blank operand is used to identify the root object. Thus:
```
[<jsondata>jsonindexes[]] --> "a", "b", "c", "d"
```

View File

@ -0,0 +1,73 @@
created: 20220611104737314
modified: 20220611104737314
tags: [[Filter Operators]] [[JSON Operators]]
title: jsontype Operator
caption: jsontype
op-purpose: retrieve the type of a property from JSON strings
op-input: a selection of JSON strings
op-parameter: one or more indexes of the property whose type is to be retrieved
op-output: the types of each of the retrieved properties
<<.from-version "5.2.4">> See [[JSON in TiddlyWiki]] for background.
The <<.op jsontype>> operator is used to retrieve the type of a property in JSON data. See also the following related operators:
* <<.olink jsonget>> to retrieve the values of a property in JSON data
* <<.olink jsonindexes>> to retrieve the names of the fields of a JSON object, or the indexes of a JSON array
JSON supports the following data types:
* ''string'' - a Unicode string
* ''number'' - a floating point number
* ''boolean'' - Boolean value (true or false)
* ''array'' - an array of values
* ''object'' - an object of name/value pairs
* ''null'' - a special type representing a missing value
Properties within a JSON object are identified by a sequence of indexes. In the following example, the value at `[a]` is `one`, and the value at `[d][f][0]` is `five`.
```
{
"a": "one",
"b": "",
"c": "three",
"d": {
"e": "four",
"f": [
"five",
"six",
true,
false,
null
],
"g": {
"x": "max",
"y": "may",
"z": "maize"
}
}
}
```
The following examples assume that this JSON data is contained in a variable called `jsondata`.
The <<.op jsontype>> operator uses multiple operands to specify the indexes of the property whose type is to be retrieved:
```
[<jsondata>jsontype[a]] --> "string"
[<jsondata>jsontype[d]] --> "object"
[<jsondata>jsontype[d],[f]] --> "array"
[<jsondata>jsontype[d],[f],[2]] --> "boolean"
```
Indexes can be dynamically composed from variables and transclusions:
```
[<jsondata>jsontype<variable>,{!!field},[0]]
```
A subtlety is that the special case of a single blank operand is used to identify the root object. Thus:
```
[<jsondata>jsontype[]] --> "object"
```

View File

@ -18,6 +18,8 @@ CopyToClipboard/Caption: copier dans le presse-papier
CopyToClipboard/Hint: Copie ce texte dans le presse-papier
Delete/Caption: supprimer
Delete/Hint: Supprime ce tiddler
DeleteTiddlers/Caption: supprimer les tiddlers
DeleteTiddlers/Hint: Supprime ces tiddlers
Edit/Caption: éditer
Edit/Hint: Édite ce tiddler
Encryption/Caption: chiffrement

View File

@ -7,8 +7,9 @@ ClassicWarning/Upgrade/Caption: mettre à jour
CloseAll/Button: tout fermer
ColourPicker/Recent: Récent :
ConfirmCancelTiddler: Souhaitez-vous annuler les modifications apportées au tiddler « <$text text=<<title>>/> » ?
ConfirmDeleteTiddler: Souhaitez-vous supprimer le tiddler « <$text text=<<title>>/> » ?
ConfirmOverwriteTiddler: Souhaitez-vous supplanter le tiddler « <$text text=<<title>>/> » ?
ConfirmDeleteTiddler: Souhaitez-vous supprimer le tiddler « <$text text=<<title>>/> » ?
ConfirmDeleteTiddlers: Êtes-vous sûr•e de vouloir supprimer <<resultCount>> tiddler(s) ?
ConfirmOverwriteTiddler: Souhaitez-vous supplanter le tiddler « <$text text=<<title>>/> » ?
ConfirmEditShadowTiddler: Vous êtes sur le point d'éditer un ShadowTiddler. Toute modification supplantera la version par défaut du système, rendant les prochaines mises à jour non-triviales. Êtes-vous sûr(e) de vouloir éditer "<$text text=<<title>>/>"?
ConfirmAction: Souhaitez-vous poursuivre ?
Count: total

View File

@ -18,6 +18,8 @@ CopyToClipboard/Caption: 复制到剪贴板
CopyToClipboard/Hint: 将此文本复制到剪贴板
Delete/Caption: 删除
Delete/Hint: 删除此条目
DeleteTiddlers/Caption: 删除条目
DeleteTiddlers/Hint: 删除条目
Edit/Caption: 编辑
Edit/Hint: 编辑此条目
Encryption/Caption: 加密

View File

@ -8,6 +8,7 @@ CloseAll/Button: 全部关闭
ColourPicker/Recent: 最近︰
ConfirmCancelTiddler: 您确定要放弃对条目 "<$text text=<<title>>/>" 的更改?
ConfirmDeleteTiddler: 您确定要删除条目 "<$text text=<<title>>/>"
ConfirmDeleteTiddlers: 您确定要删除 <<resultCount>> 个条目?
ConfirmOverwriteTiddler: 您确定要复写条目 "<$text text=<<title>>/>"
ConfirmEditShadowTiddler: 您即将要编辑默认条目,任何更改将会复盖默认的系统,使未来的升级不寻常。您确定要编辑 "<$text text=<<title>>/>"?
ConfirmAction: 是否要继续?

View File

@ -18,6 +18,8 @@ CopyToClipboard/Caption: 複製到剪貼簿
CopyToClipboard/Hint: 將此文字複製到剪貼簿
Delete/Caption: 刪除
Delete/Hint: 刪除此條目
DeleteTiddlers/Caption: 刪除條目
DeleteTiddlers/Hint: 刪除條目
Edit/Caption: 編輯
Edit/Hint: 編輯此條目
Encryption/Caption: 加密

View File

@ -8,6 +8,7 @@ CloseAll/Button: 全部關閉
ColourPicker/Recent: 最近︰
ConfirmCancelTiddler: 您確定要放棄對條目 "<$text text=<<title>>/>" 的更改?
ConfirmDeleteTiddler: 您確定要刪除條目 "<$text text=<<title>>/>"
ConfirmDeleteTiddlers: 您確定要刪除 <<resultCount>> 個條目?
ConfirmOverwriteTiddler: 您確定要覆寫條目 "<$text text=<<title>>/>"
ConfirmEditShadowTiddler: 您即將要編輯預設條目,任何更改將會覆蓋預設的系統,使未來的升級不尋常。您確定要編輯 "<$text text=<<title>>/>"?
ConfirmAction: 是否要繼續?

View File

@ -3,13 +3,121 @@ tags: $:/tags/EditPreview
list-after: $:/core/ui/EditTemplate/body/preview/output
caption: parse tree
\define preview(mode)
<$wikify name="preview-text" text={{!!text}} type={{!!type}} mode="$mode$" output="parsetree">
<pre>
<code>
<$text text=<<preview-text>>/>
</code>
</pre>
\whitespace trim
\procedure preview-node-properties(node)
<$let excludeProperties="text type tag children attributes orderedAttributes">
<$list filter="[<node>jsonindexes[]] -[subfilter<excludeProperties>] +[limit[1]]" variable="ignore">
<table>
<tbody>
<$list filter="[<node>jsonindexes[]] -[subfilter<excludeProperties>] +[sort[]]" variable="index">
<tr>
<td>
<$text text=<<index>>/>
</td>
<td>
<$text text={{{ [<node>jsonget<index>] }}}/>
</td>
</tr>
</$list>
</tbody>
</table>
</$list>
</$let>
\end
\procedure preview-node-attribute-string(attribute)
<$text text={{{ [<attribute>jsonget[value]] }}}/>
\end
\procedure preview-node-attribute-indirect(attribute)
{{<$text text={{{ [<attribute>jsonget[textReference]] }}}/>}}
\end
\procedure preview-node-attribute-macro(attribute)
&lt;&lt;
<$text text={{{ [<attribute>jsonget[value],[name]] }}}/>
<$list filter="[<attribute>jsonindexes[value],[params]]" variable="index">
&nbsp;
<$list filter="[<attribute>jsonget[value],[params],<index>,[name]]" variable="ignore">
<$text text={{{ [<attribute>jsonget[value],[params],<index>,[name]] }}}/>
:
</$list>
<$text text={{{ [<attribute>jsonget[value],[params],<index>,[value]] }}}/>
</$list>
>>
\end
\procedure preview-node-attributes(node)
<$list filter="[<node>jsonindexes[attributes]limit[1]]" variable="ignore">
<table>
<tbody>
<$list filter="[<node>jsonindexes[attributes]sort[]]" variable="index">
<tr>
<td>
<$text text=<<index>>/>
</td>
<td>
<$let type={{{ [<node>jsonget[attributes],<index>,[type]] }}}>
<$transclude $variable={{{ [<type>match[string]then[preview-node-attribute-string]] :else[<type>match[indirect]then[preview-node-attribute-indirect]] :else[<type>match[macro]then[preview-node-attribute-macro]] }}} attribute={{{ [<node>jsonget[attributes],<index>] }}}/>
</$let>
</td>
</tr>
</$list>
</tbody>
</table>
</$list>
\end
\procedure preview-node-children(node)
<div style="padding:4px 4px 0 4px;">
<$transclude $variable="preview-node-properties" node=<<node>>/>
<$transclude $variable="preview-node-attributes" node=<<node>>/>
<$transclude $variable="preview-node-list" nodeList={{{ [<node>jsonget[children]] }}}/>
</div>
\end
\procedure preview-node-title-widget(node)
<div style="border:2px solid red;margin:4px;">
<div style="background:red;color:white;padding:4px;">
<$<$text text={{{ [<node>jsonget[type]] }}}/>>
</div>
<$transclude $variable="preview-node-children" node=<<node>>/>
</div>
\end
\procedure preview-node-title-element(node)
<div style="border:2px solid purple;margin:4px;">
<div style="background:purple;color:white;padding:4px;">
&lt;<$text text={{{ [<node>jsonget[tag]] }}}/>>
</div>
<$transclude $variable="preview-node-children" node=<<node>>/>
</div>
\end
\procedure preview-node-title-text(node)
<div style="border:2px solid green;margin:4px;">
<div style="background:green;color:white;padding:4px;">
<span style="color:#ff0;font-weight:bold;">"</span><span style="white-space:pre-wrap;"><$text text={{{ [<node>jsonget[text]] }}}/></span><span style="color:#ff0;font-weight:bold;">"</span>
</div>
</div>
\end
\procedure preview-node(node)
<$let type={{{ [<node>jsonget[type]] }}}>
<$transclude $variable={{{ [<type>match[element]then[preview-node-title-element]] :else[<type>match[text]then[preview-node-title-text]] :else[[preview-node-title-widget]] }}} node=<<node>>/>
</$let>
\end
\procedure preview-node-list(nodeList)
<$list filter="[<nodeList>jsonindexes[]]" variable="index">
<$transclude $variable="preview-node" node={{{ [<nodeList>jsonget<index>] }}}/>
</$list>
\end
\procedure preview(mode)
<$wikify name="preview-json" text={{!!text}} type={{!!type}} mode=<<mode>> output="parsetree">
<$transclude $variable="preview-node-list" nodeList=<<preview-json>>/>
</$wikify>
\end

View File

@ -397,6 +397,7 @@ a.tc-tiddlylink {
font-weight: 500;
color: <<colour tiddler-link-foreground>>;
-webkit-user-select: inherit; /* Otherwise the draggable attribute makes links impossible to select */
-webkit-touch-callout: none; /* Prevents long presses from bringing up a link preview */
}
.tc-sidebar-lists a.tc-tiddlylink {