Single conditional with two runs?

Hello all, I have this procedure:

\procedure adjusted-fp-cost(character, spell)
<$let spellbook={{{ [<character>get[spellbook]] }}} advbook={{{ [<character>get[advbook]] }}} IQcp={{{ [<character>get[IQ-cp]] }}}>
<$wikify name="baseskill" text="<$macrocall $name='spell-base-skill' spellbook=<<spellbook>> spellitem=<<spell>> advbook=<<advbook>> IQcp=<<IQcp>> />">
	<% if [<spellbook>has:index<spell>] %>
		<% if [<spell>!match[Reflex]] +[<spell>get[class]!match[Blocking]] %>
			<% if [<baseskill>compare::gt[14]compare::lt[20]] %>
				<$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]subtract[1]max[0]] }}}/> (adj. from <$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]] }}}/>)
			<% elseif [<baseskill>compare::gt[19]compare::lt[25]] %>
				<$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]subtract[2]max[0]] }}}/> (adj. from <$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]] }}}/>)
			<% elseif [<baseskill>compare::gt[24]compare::lt[30]] %>
				<$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]subtract[3]max[0]] }}}/> (adj. from <$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]] }}}/>)
			<% elseif [<baseskill>compare::gt[29]] %><$let baseskillexcedent={{{ [<baseskill>subtract[25]divide[5]trunc[]] }}}> (adj. from <$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]] }}}/>)
				<$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]subtract[3]subtract<baseskillexcedent>max[0]] }}}/></$let> (adj. from <$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]] }}}/>)
			<% else %>
				<$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]] }}}/>
			<% endif %>
		<% else %><$macrocall $name="cost-fp" value={{{ [<spell>get[base_cost]] }}}/>
		<% endif %>
	<% else %>
		Spell not in <<character>>'s Spellbook.
	<% endif %>
</$wikify></$let>
\end

The second conditional <% if [<spell>!match[Reflex]] +[<spell>get[class]!match[Blocking]] %> holds two runs to exclude the tiddler “Reflex”, as well as any <spell> whose field class is “Blocking”. The second run works fine, but the first one (the simplest, actually), doesn’t.

It does work when I remove the second run; so I’m assuming one cannot formulate a single conditional with two runs to check; am I correct?

No, this should work as intended:

<% if [<spell>!match[Reflex]] [<spell>!class[Blocking]] %>

First point: Any filter run with the +/:and prefix takes all outputs of prior runs as its inputs and further filters/transforms them. As a simple example:

  1. [tag[HelloThere]] [tag[Community]]

  2. [tag[HelloThere]] +[tag[Community]]
    image

Here you can see that [tag[HelloThere]] +[tag[Community]] isn’t equivalent to [tag[HelloThere]] [tag[Community]]: it restricts the results of the [tag[HelloThere]] run to only those tiddlers that also have the Community tag. To get the combined results of both runs, you need a blank/:or filter run. This is also the default behavior when you don’t specify a different filter run prefix.

In your case, since you want to remove a single title from the filter results, you could also try this slightly simpler alternative:

<% if [<spell>!class[Blocking]] -[[Reflex]] %>

Second point: The get operator replaces each of its inputs with the non-blank value of that tiddler’s field (as specified by get's parameter). This means that [<spell>get[class]!match[Blocking]] won’t return the name of the <<spell>> tiddler if its class field doesn’t match Blocking; instead, it will give you the value of that field. In this case, since you only care about the field value for true/false display purposes, [<spell>get[class]!match[Blocking]] will work just as well in your conditional. But it’s good to keep the difference in mind for instances in which you do want to preserve <<spell>> in the results.

Also, [<spell>!class[Blocking]] (short for [<spell>!field:class[Blocking]]) is a bit shorter. :slight_smile:

Third, least crucial point:

class is actually one of the fields with a special meaning in the TW core: it’s intended to hold CSS classes, which will be applied to the tiddler as whole. Assuming you haven’t defined a .Blocking class in your CSS, you probably won’t see any unwanted effects even if you’re “misusing” the field. But it’s good to be aware of the possible consequences, and personally I’d recommend using a different field name (perhaps spell-class?) instead.

And if you don’t already have it installed, the Commander plugin is invaluable for renaming fields, as well as a host of other bulk operations.

4 Likes

You least crucial point, the third, seems very crucial in my fearful mind :stuck_out_tongue_winking_eye: I updated the field name as you suggested (while trembling about forgetting a place where it’s called upon, but I seem fine for now ;P)

Thanks for the clear explanations on the rest.