How to create a list that may appear or be skipped (solved)

Hi,

I have run into the following problem.

I have species that may hate/like/be neutral towards each other with -3 fierce hatred, 0 = neutral and 3 = worshiped.

This is stored in a field with the species name.

So the attitude towards Duks by Draeks is stored in {{R-Draek!!R-Duks}}.

I want to list those relationships in order, starting with fierce hatred.

The problem here that a given race may or may not have fierce hatred towards another species.

So ideally I would like to skip the fierce hatred line if no such relationship is present.

I tried to solve this with a fierce hatred text that should only appear with the first[1] operator and not with the rest[1] operator.

That failed because when matching the species with an if statement, every species was in effect the first one.

Next I tried changing the hatred text to empty after the first one. This failed because after the let went out of scope the old text returned. This might work with a global variable, but I try to avoid those.

Lastly I tried using a seperate if to detect the presence, print the text and then list the species. this failed because without a list I could not detect if the -3 was present or not.

Conceptually it should be easy but it is proving hard to implement.

Any ideas how I can solve this? current code below.


<$let oldcurrentTiddler=<<currentTiddler>> Fierce="have Fierce Hatred towards "  >

The <$text text={{{ [{!!title}removeprefix[R-]] }}} />
      &nbsp;<<Fierce>>
     <$list filter= "[tag[Species]]">
      <% if [<oldcurrentTiddler>get{!!title}match[-3]] %>
          <$text text={{{ [{!!title}removeprefix[R-]] }}}/>
     <% endif %>
     </$list>

</$let>

The following code assumes you’re using it as part of a template on e.g. R-Draek - so <<currentTiddler>> = R-Draek throughout.

<$list filter="[<currentTiddler>fields[]prefix[R-]] :sort:integer[<..currentTiddler>get{!!title}]" variable=field>
<$let
	target={{{ [<field>removeprefix[R-]] }}}
	value={{{ [<currentTiddler>get<field>] }}}
>

<<currentTiddler>>
	<% if [<value>match[-3]] %>
		have fierce hatred towards
	<% elseif [<value>match[3]] %>
		worship 
	<% else %>
		are neutral towards
	<% endif %>
<<target>>.
</$let>
</$list>

You could alternately store your relationship values as indexes in a dictionary tiddler, e.g.

title: SpeciesAttitudes
text:
-3: have fierce hatred towards
0: are neutral towards
3: worship

And then look up the corresponding index value like this:

<$list filter="[<currentTiddler>fields[]prefix[R-]] :sort:integer[<..currentTiddler>get{!!title}]" variable=field>
<$let
	target={{{ [<field>removeprefix[R-]] }}}
	value={{{ [<currentTiddler>get<field>] }}}
	attitude={{{ [[SpeciesAttitudes]getindex<value>]
>

<<currentTiddler>> <<attitude>> <<target>>.

</$let>
</$list>
1 Like

Thank you for the reply. The data tiddler method looks promising for other data.

But this is not yet the solution.

When using it as view template, I got the following output for R-Duks:

R-Duks

have fierce hatred towards

Daemon.

R-Duks

have fierce hatred towards

Faerie.

R-Duks

are neutral towards

Khaer.

R-Duks

are neutral towards

Baestmen.

R-Duks

are neutral towards

Centaer.

R-Duks

are neutral towards

Shaep.

R-Duks

are neutral towards

Golaemer.

R-Duks

are neutral towards

Humaen.

R-Duks

are neutral towards

Octoids.

R-Duks

are neutral towards

Draek.

R-Duks

are neutral towards

Giaent.

R-Duks

are neutral towards

Maermen.

R-Duks

are neutral towards

Moonfolk.

R-Duks

are neutral towards

Oger.

R-Duks

are neutral towards

Rockr.

R-Duks

are neutral towards

Slimaer.

R-Duks

are neutral towards

Duks.

R-Duks

worship

Elohim.

On the bright side, it is doing them in order, with all fierce hatred ones first and worship ones last.

But the desired output would be something like:

The Duks have Fierce Hatred towards Daemon Faerie
they are neutral towards Khaer Baestmen (etc long list)
they worship Elohim

Now if one of those has no matches the line would have to be skipped.

When I try R-Draek, the output is:

R-Draek

are neutral towards

Daemon.

R-Draek

are neutral towards

Shaep.

R-Draek

are neutral towards

Duks.

R-Draek

are neutral towards

Khaer.

R-Draek

are neutral towards

Oger.

R-Draek

are neutral towards

Golaemer.

R-Draek

are neutral towards

Humaen.

R-Draek

are neutral towards

Octoids.

R-Draek

are neutral towards

Baestmen.

R-Draek

are neutral towards

Centaer.

R-Draek

are neutral towards

Elohim.

R-Draek

are neutral towards

Faerie.

R-Draek

are neutral towards

Giaent.

R-Draek

are neutral towards

Maermen.

R-Draek

are neutral towards

Moonfolk.

R-Draek

are neutral towards

Rockr.

R-Draek

are neutral towards

Slimaer.

R-Draek

are neutral towards

Draek.

As R-Drak have no fierce hatred or worship values, this is the correct outcome if presented in the form:

The Draek are neutral towards Baestmen Centaer (etc long list)

But the originator and the relationship are repeated every time, which is something I wanted to avoid…

Ah, I see. I didn’t realize how many species you were working with!

I also forgot to replace <<currentTiddler>> with something “prettier”, I’m now realizing, but I assume you have the display name for each race saved somewhere… perhaps in {{!!caption}}? If not, replace it with the field/variable of your choice.

Here’s take 2:

\function attitude.value(num) [enlist<species>] :filter[<current>get{!!title}match<num>] +[join[ ]]

\procedure list-species()
<$list filter="[enlist<condition>]" join=", "><$link>{{!!caption}}</$link></$list>
\end

<$let
	current=<<currentTiddler>>
	species={{{ [<current>fields[]tag[Species]] +[join[ ]] }}}
	negative=<<attitude.value -3>>
	neutral=<<attitude.value 0>>
	positive=<<attitude.value 3>>
>

The {{!!caption}}
<% if [<negative>!match[]] %>

* have fierce hatred towards <<list-species>>
<% endif %>
<% if [<neutral>!match[]] %>

* are neutral towards <<list-species>>
<% endif %>
<% if [<positive>!match[]] %>

* worship <<list-species>>
<% endif %>

</$let>

I’m assuming that all your species tiddlers follow the format R-Name, without spaces. If you do have any species tiddlers with spaces in the title, you’ll need to add format:titlelist[] before each join[ ] above.

I’ve also used a function and a procedure to reduce redundancy; let me know if you have any questions about that.

2 Likes

That worked like a charm.

I added all the possible relationships, and the output is now:

Thank you for taking the time to solve this.