I have a repeating-list-datafield with a list of entries of unknown length (or length n). The concept is #party, and I have the datafield #party^is-a-shareholder as a true/false-repeating-list.
If I display the list, using @list(#party^is-a-shareholder), I get (for example, depending on the data):
“Parties X hereinafter referred to as “Shareholders”.
Because the Parties are numberd sequentially, X needs to refer to the repeating-list-datafield index of all entries set to “true”, and skip any entry set to “false”. Ideally, using the above example data, I want to display:
*1. Parties 1 and 3 hereinafter referred to as “Shareholders”*
Parties 1 through 4 and 7 hereinafter referred to as “Shareholders”*
Parties 1 through 3 and 7 through 10 hereinafter referred to as “Shareholders”*
I have tried using @count, turning the list into a string with @str and using @regex or working with a @for loop, without success. I am sure there is a way to achieve this.
I would greatly appreciate some ideas here, as this really has me stumped.
What you are trying to achieve is not exactly advanced when looking at it from a legal perspective (such paragraphs are produced every day), but from a technical perspective this is actually quite advanced.
Clause9 offers several advanced tools that solve several of those advanced use cases, but you should be aware that there are limits. In fact, these kinds of challanges are usually solved with a traditional general-purpose programming language. We also embed one within the software (Clojure), and you can actually use it to compose paragraphs with even the weirdest logic you can think of, but it’s something you want to avoid, due to the complexity involved and the difficulty to maintain.
So let’s try to use the standard (although advanced) tools in Clause 9.
Have a look at the way I solved it in the screenshot below (I use slightly different concept-names & fields, but ignore that).
Make sure to read the page about for-loops — I assume you already did, but probably that’s a good starting point for a future reader.
Let’s suppose there are 4 parties in total, with party 1 and party 4 being natural persons.
The ALL-INDICES loops over each of the 4 parties, and then for each party invokes the SNIP. Notice that I’m using @for-calc and not @for, because @for-calc returns a number (instead of a piece of text), which is easier to work with later on, for comparison reasons.
The SNIP looks at a party and then checks whether it is a natural person, by using @get into the repeating list #cparty^natural, with the current index (1, 2, 3 or 4).
I’m using @when to check the condition, because that returns either the index as a natural number (?INDEX, which is a number), or nothing if the condition is not met. If I would have used something like {#cparty^natural: ?INDEX}, then that would result into a piece of text (everything after the colon will ultimately become text, or even text with formatting inside), which is more difficult to compare. Hence the reason to use @when, because it does not convert ?INDEX into a piece of text.
ALL-INDICES will thus result in a list that contains four elements: 1, nothing, nothing and 4.
FILTERED-INDICES then takes the ALL-INDICES and removes the two “nothing” elements, by comparing with “undefined” (i.e., nothing). It thus results in a list with just two elements: 1 and 4.
In the actual paragraph, I then do a check on the number of elements within FILTERED-INDICES:
if that number of elements is zero, then I give an ugly warning in red (perhaps you instead want to generate nothing in that scenario, instead of an ugly warning)
if that number of elements is exactly one, I produce a text referring to that party in singular
if the number of elements is more than one, I produce a text referring to the parties in plural, and nicely concatenating the results with @enumerate-and
This works well, except for one scenario: your example with “Parties 1 through 3 and 7 through 10”, i.e. where you want to group contiguous parties together. This cannot be resolved with simple for-loops, you really need a general-purpose programming language — and even then it’s not exactly super simple.
We use Clojure as an embedded programming language, but this is what it could roughly look like in Javascript (quickly done with the help of GPT-4), to illustrate the level of complexity.
We could envisage creating a new special function that performs these kinds of “contiguous number grouping” things (i.e., where the complex programming stuff is prepared by the ClauseBase-team and “hidden” behind an easier-to-use special function), but I suppose the use case for it is fairly limited among our users, so let’s leave that for the future.