Jermolene / TiddlyWiki5

A self-contained JavaScript wiki for the browser, Node.js, AWS Lambda etc.
https://tiddlywiki.com/
Other
7.81k stars 1.16k forks source link

[IDEA] native support for handling key=value and key:value pairs in tiddlywiki #6674

Open AnthonyMuscio opened 2 years ago

AnthonyMuscio commented 2 years ago

Is your feature request related to a problem? Please describe.

Background There are various places in tiddlywiki where we provide key=value pairs and the alternative key:value pairs. In both cases the the value and arguably the key can be specified with the various quotes eg

The problem is this is not available from within wiki-text, nor is the return to "give a set of keys have it return say variable(s) with the keys name set to the value from the pair". Constructing key=value pairs can be done (see below to a limited extent) but the reverse is difficult.

If the following support to natively handle key/value pairs were available, various solutions, fields containing a list of key/value pairs and smart macros can be built and interchanged between wikis without needing share bespoke key/value pair handling tools.

Describe the solution you'd like I would like an easy to use mechanism to and from key=value pairs but I also want this a available in the core so future solutions can include solutions that leverage this "standard". A filter or macro that can be given one or more key=value and key:value pair(s) and parse them will all appropriate quote handling. A filter or macro that can be given a list of variables or list of fields and return key=value or key:value pairs appropriate quote handling.

Describe alternatives you've considered Building alternative using existing primitive's is long winded and error prone and would not be part of the core facilities. Building such a solution that leverages javascript quote handling would be more reliable and appropriate for core inclusion.

Additional context What follows is an attempt to construct key value pairs with filters but I am forced to compromise by using tripple quotes and rely on the content not using other than ' and " eg; """value"""

Here is a variables to key value pairs filter; {{{ [[var1]] [[var2]] :map[getvariable[]addprefix[="""]addprefix<currentTiddler>addsuffix[""" ]] +[join[ ]] }}}

returns var1="""A. content of var 1""" var2="""B. Content of var2"""

Here is a fields to key values pairs filter; {{{ caption "one two" :map[<..currentTiddler>get<currentTiddler>addprefix[="""]addprefix<currentTiddler>addsuffix["""]] +[join[ ]] }}}

Returns caption="""caption for field=value pairs""" one two="""content of one two"""

How can I reliable inject the key=value and key:value pairs and reverse this?

This code to achieve this must already exist somewhat in the core, it has just not being made available to users

Imagine a field containing;

https://tiddlywiki.com/#getvariable%20Operator name="getvariable Operator" target="tiddly doco"

then with parsing this into

<a href=https://tiddlywiki.com/#getvariable%20Operator target=<<target>> ><<name>></a>

Jermolene commented 2 years ago

Your intuition is correct that the core contains code for parsing name/value pairs. The problem is actually in writing them out again – you will appreciate that there are parameter values that cannot be expressed with any of the quoting patterns that we support. For example: These are all quote "'""" symbols cannot be expressed as "name=value" pair. So, any facility to write out these name value pairs would need to provide a way to detect and cope with those cases that can't be expressed.

Meanwhile, there are a number of other alternatives:

Besides those concerns about feasibility, it would be helpful to understand more about the use cases you have in mind.

AnthonyMuscio commented 2 years ago

Thanks, Perhaps you could share how to use the alternatives?

My key use case is providing users with a way to capture on input information in key value pairs then subsequently use them to provide variables to wikitext or to widgets and macros. In the example I provide with a url in a field the first parameter is the link and the rest is a set of key values. It shows how being able to include additional parameter info in the same field, with the help of the proposed tool would be much simpler than say needing additional fields for the target and name values.

Users could be given a field to edit in which they enter arbitrary key value pairs and they can be parsed in to variables of content.

It is another way of grouping and labelling content eg an address field containing number="1" streetaddress="my street" city="my town"

The difficult part in building something to parse the above list pf pairs with current tools. the pairs are space delimited and the key value "=" delimited but there is no simple way to separate the first value from the second key as there is no way that I am aware of to avoid the spaces between the quotes of any type.

Perhaps there is some regex that can do it but it would be best a simple way perhaps a custom split operator that returned from number="1" streetaddress="my street" city="my town"

To;

number="1"
streetaddress="my street"
city="my town"

Or perhaps a special feature of the set multiple variables widget that accepted a key/value list and set the key/value to variable name/value ?

AnthonyMuscio commented 2 years ago

If with these features we can interrogate or set key/value pairs in a text field that is exported as a config file.

Jermolene commented 2 years ago

Hi @AnthonyMuscio providing key/value pairs to provide variables to wikitext or to widgets and macros is exactly the use case that lay behind the <$setmultiplevariables> widget.

The basic idea I'm trying to put across is pretty simple. For these use cases of storing and setting variables, instead of a single string:

number="1" streetaddress="my street" city="my town"

We use two lists, one of names, and one of values:

names: number streetaddress city
values: 1 [[my street]] [[my town]]
AnthonyMuscio commented 2 years ago

@Jermolene I understand your use of setmultiple variables widgets but having the two lists in the first place is the problem especialy if I were provided a list/set of key/value pairs.

If there were a way to split a list of key/value pairs into seperate key/value pairs I could then use the delimiter to get each key and each value and use the setvariables widget with two filters as follows;

[split[=]first[]] And [split[=]last[]]

Perhaps if we cant support all the quote alternatives perhaps if we only support the double quotes only? Single quotes can be embeded in a double quote just not the other way. This should cover 95% of cases (guestimate).

Perhaps if I use commas to seperate pairs but with current tools this would mean we cant use commas in the values.

Jermolene commented 2 years ago

This should cover 95% of cases (guestimate).

That's the problem here: as I explained above, quoted name/value strings are brittle. For the core, we aim for mechanisms that are universal and consistent.

AnthonyMuscio commented 2 years ago

I am confident in the intuitive sense that a solution to this is possible however it is achieved. Thus I will continue to identify an algorithm to do this and solve it. Once available I will see how we may implement it as a standard feature.

AnthonyMuscio commented 2 years ago

Now this below does not work, perhaps of transcludes and the way let operates perhaps;

\define display-vars(fieldname)
<$let 
{{!!$fieldname$}}
>
1=<<1>> a=<<a>> c=<<c>> filtervalue=<<filter>>

</$let>
\end

<<display-vars key-values>>

But it illustrates how a lot of tiddlywiki widgets via javascript parsing have the ability to parse key-value pairs and convert them to parameters or variables they use, including dealing with all the different quotation methods.

It could be as simple as giving let an input or key-values parameter, it parses in addition to its own parameters to find the variable names and set the variables. This it would allow us to retrieve the values as variables, optionally with a prefix added to the variable names. and we could insist on "=" or ":" only between pairs.

So basically with key=value to variable facility, we have the suite of tools needed to manipulate such data, as it is easy to go from field or variable to a key=value pair.