From what I know from the rules, abilities are tied to paragraphs, not lines. So you should be using:
length(card_style.rule_text.layout.paragraph)
instead of
card_style.text.content_lines
to count the number of abilities. However, this is not good for at least three reasons:
1) The card_style variable has buggy behavior and should be avoided if able.
2) Keywords are abilities, but break the rule of having their own paragraph. There can be multiple inside a single paragraph.
3) If there are abilities above the backup ability, they will be counted when they should not, because backup only cares about abilities "printed below" it. [CR 702.165a]
To address 1) I had written a function that breaks text into a list of paragraphs. Paragraphs in MSE are denoted by hard line breaks:
split_paragraphs := replace@(match: "<soft-line>", replace: "_SOFTTAG_") + #Transform this tag so it doesn't get removed by the next part
remove_tags + #Remove all tags
replace@(match: "_SOFTTAG_\n", replace: "") + #Remove soft line breaks which contain a new line character, but do not create a new paragraph
replace@(match: "_SOFTTAG_", replace: "") + #Remove lingering soft line tags
split_text@(match: "\n") #Cut the text at each remaining new line character
To address 2) we can observe that paragraphs that are a list of keywords are the only ones that do not end with a dot. We also need to account for cards like Nesting Dragon which can have quotation marks after their dot. Keywords are either separated by a comma or a semi-colon:
ends_with_dot := match@(match: "\\.[’'”\"]*$")
split_keywords := split_text@(match: "[,;]")
To address 3) we can just iterate over the paragraphs and don't start counting until we see the backup ability:
contains_backup := match@(match: "[Bb]ackup [1-9]")
We also should get rid of reminder text, because we don't want to count anything inside it:
remove_reminders := replace@(match: " ?(<i>|<i-auto>).*?(</i>|</i-auto>)", replace: "")
Putting it all together we get:
backup_is_plural :=
{
started_counting := false
abilities_count := 0
paragraphs := split_paragraphs(remove_reminders(card.rule_text))
paragraphs_count := length(paragraphs) - 1
for x from 0 to paragraphs_count do
(
paragraph := paragraphs[x]
if not started_counting and contains_backup(paragraph) then started_counting := true
else if started_counting and paragraph != "" then
(
if ends_with_dot(paragraph) then abilities_count := abilities_count + 1
else abilities_count := abilities_count + length(split_keywords(paragraph))
)
)
abilities_count > 1
}
After adding all these function definitions to /data/magic.mse-game/script, our reminder text simply becomes:
{ if backup_is_plural() then "abilities" else "ability" }
All of this is, of course, unoptimized and buggy as all heck. (Also if you want to copy and paste this, make sure to replace the indentation spaces with tabs or MSE will freak out)