Trying to pull a list with ^action()^ and it each item is quotes, how do I get rid of the quotes

I’m using the following to generate a list,

^action($MyList=collect(children("Appendix B: Summary of Relevant Theories"),$ShortTitle+" "+$Citation);)^ ^value($MyList.replace(";",", "))^.

The list is coming out with each item items quotes “Attitude Theory (Rosenberg, 1956)”, “Diffusion of Innovation Theory (Rogers, 1962)”, “Theory of Propositional Control (Dulany, 1967)”, “Theory of Reasoned Action (Fishbein & Ajzen, 1975)”, “Protective Motivation Theory (Core) (Rogers, 1975)”, “Self-efficacy Theory (Bandura, 1977)”, “Theory of Interpersonal Behavior (Triandis, 1977)”, “Use and Gratification Theory (Blumler, 1979)”, “Theory of Planned Behavior (Ajzen, 1985), (Blumler, 1979)”, “Social Cognitive Theory (Bandura, 1986)”, .

How do I get rid of the quotes?

Michael

Tinderbox implicitly removes quotes in many contexts. But those parens are (I think) frightening it.

This will be easier in Tinderbox 9.

1 Like

Isn’t this the problem that Mark A and I found with markdown clickable links yesterday? () in lists automatically triggers quotes around that string.

Briefly, Mark found an answer that worked: we had to substitute {} for () in the list and then .replace("\{","(").replace("\}",")") once the list had been built. (The {} has to be escaped because they are special characters in regex, of course.)

In our case we’d been adding the parentheses in the collect statement, while it looks like yours are already in $Citation, so you’ll have to do an initial transform (would $Citation.replace("\(","{").replace("\)","}") do it in the collect statement so that you’re not disturbing the real contents of $Citation?).

The thread is here for the background: Tinderbox Training Video 31 - Integrating Export Code & Action Code in Your Text - #26 by mwra

Does that help?

So the $ShortTitle+" "+$Citation is what is seems to be causing the issue here. To my recollection, collect was intended for fetching all the values of an attribute from the nominated group of notes. Witness the general syntax: collect(group,attribute). The attribute is singular!

One of its prime roles was later replaces by values(), and the arrival of find() use in a designator (IOW a custom query designator) also eroded the role of collect_if().

So the first point here is should we trying (even if we want to) to use collect for string concatenations? Anyway, as the attached TBX’s test confirms, it is the presence of parentheses () anywhere in the collected attribute(s) value(s) that generated the (unwanted) quotes. There is a fix though—read on.

Firstly, unless we really want to export the list as a list, rather than use .replace(";",", ") we should use `.format(", "). Now we have a single string with a comma+space between each list item. Now, we can use .replace to string the quotes with:

.replace('\"',"")

Note in this case we do need to escape the double quote to tell Tinderbox we are citing a literal character and not opening a doube-quote-enclosed sub-string in the input parameter. The latter code also shows two further syntax points. Firstly, you can enclose the input strings in either single or double quotes as long as properly paired. Secondly you don’t have to use the same enclosing quote type for each input.

The revised action is here (line breaks in code to better fit on screen):

^action(
$MyList=collect(children("Appendix B: Summary of Relevant Theories"),$ShortTitle+" "+Citation);
)^
^value($MyList.format(", ").replace('\"',""))^

See the detail in this demo file: collect-quotes-problem.tbx (119.3 KB)

@brookter’s suggestion is also correct, but since my solution given in the thread recommended, I’ve (above) now got a better appreciation of the source problem and a simpler problem in the form of fewer replace calls.

Interesting problem, happily now solved.

1 Like

Thanks. It is getting close, but I still have a few issues.

In a few of my collected notes now the ’ is showing up and in some of the me the $ShortTitle is not returning. Also, the sort order is not the same as that of the source.

OK, at this point a sample file would help. This sort of edge case it hard to diagnose textually. I don’t see any apostrohe’s in your original example so can’t test the issue. :slight_smile:

Sort. What order are you expecting? My presumption is collect would return children in outline order (i.e. sibling order).

There isn’t one, I think this is a byproduct of using the ’ in the action code.

I was expecting the sort order to be the same out the outline (sibling order), it is not.

I’ll work up a test file in a bit.

Nothing seen here:

Could you provide an example that generates the problem on demand?

We tracked it down. One of @satikusala’s source notes was showing in a list like above with straight single quotes. The source note’s $Citation looked like this:

"(Rodgers 2007; Smith 2009)"

Note the quotes in the value. Removing those, the above list code worked. The next problem is the code making the citation string is adding back the quotes is they are removed. Why? Likely it’s because this looks a lot like a list in parentheses, i.e.:

(item 1;item 2)

But Tinderbox knows it’s a string so puts double quotes around the literal string. Essentially, this:

"(Rodgers 2007; Smith 2009)"

Is Tinderbox telling itself the string value means this (or something like that)

\(Rodgers 2007\; Smith 2009\)

So the task is now to fix the code creating the en-quoted $Citation value string.

1 Like

I found this thread because I’m dealing with the identical issue in 9.5.1

I have a properly functioning agent and its query gathers arbitrary number of notes daily. I’d like to show the items by line in a dashboard-type Subtitle, as well as have another agent that collects this list (and other info) and make a composite daily. Trouble is that I’m getting these quotes around the string on each line also.

I don’t have double quotes in the strings being collected, so I’m a little confused give the above.

The agent’s action works:

$MyList = collect(children, $Full_text); 
$Subtitle="";$MyList.each(x) {$Subtitle=$Subtitle +x+"\n" ;}

That gets the expected info and makes each $Full_Text content on a line each. Exactly what I want. But then, it has those quotes… so the dashboard shows, if it collected three items:

“First Item of interest, a block, cherry, and tortoise shells.”
“Third item of interest, out of order because I need to fix the sort.”
“Second item of interest, more information, and so on.”

Reading the above made me think I shouldn’t be seeing this behavior. Do I need to manually trim the quotes? If so, I’m a little stumped on that.

Using your test values, and this Rule code in the agent (changing a few names for clarity):

$MyList = collect(children, $FullText); 
$Subtitle=;
$MyList.each(anItem){
   $Subtitle=$Subtitle+anItem+"\n" ;
};

and after checking, tidied to this (we don’t need to store the list)

$Subtitle=;
collect(children,$FullText).each(anItem){
   $Subtitle+=anItem+"\n" ;
};

gives:

The reason line #2 of the subtitle has unclosing quotes is due to a source note’s $FullText value (in fact it is enclosing single and double quotes):

The extra pair of single quotes is Tinderbox escaping the quotes as these normally act as string delimiters (i.e. defining the start/end of the value. In an input box like in Displayed Attributes (as above) the you don’t add quotes. In code you do, e.g. to set note ‘3’ $FullText value:

$FullText = "Third item of interest, out of order because I need to fix the sort.";

By typing the quotes into the value you’re doing the action code equivalent of:

$FullText = '"Third item of interest, out of order because I need to fix the sort."';

where an outer pair of single quotes allow you to use double quotes in a string.

Here’s my v9.5.1 test document: subtitle-quote-test.tbx (140.3 KB)

I hope I’ve interpreted the problem correctly. If not just ask. :slight_smile:

†. The code could be used in a Rule, Edict or stamp but not the agent’s AgentAction. Why? Because the action is applied to the child alias(es) and not to the agent itself. This is important as $Subtitle in code for the form applies to the agent, but in an agent action would apply to the alias being processed.

2 Likes

Okay! Thanks. I see several things to learn here.

I had tried setting the Subtitle directly as you’ve done, but I likely had a typo because I could never get it to work so I switched to the $MyList method (as found on your aTBref).

The equal sign on the index is something I had not noticed in examples.

I appreciate seeing the single quote to escape the quotes - I saw that mentioned on aTBref when trying to figure out how I was mangling this!

Will try this all… thank you!

1 Like

If you’re getting stuck, it can help to upload a small demo TBX (like mine above) showing your code in context to its use. Sometimes, when learning new parts of the program it is easy to unintentionally describe the problem is a way that doesn’t make sense to other users: every program tends to have some terminology that differs form other apps that do the same thing but using a different description.

I’m not sure what this method is. In my examples I normally use attribute names for general use that indicate the data type expected. I use the attribute names with a ‘My’ prefix as it makes the code more likely to work copy/pasted without having to add too many additional attributes. You also have a Full_text attribute. The name is valid but I changed it to a more Tinderbox-style name (using CamelCase) so as to make the example more useable to more readers here.

The point of code like :slight_smile: ```

$MyList = collect(children, $FullText);

is to inform a new user that collect() returns List-type data. Saving to a list can be useful initial testing to ensure you’ve configured your collect() call correctly and are getting the list you expect. Once the latter is tested, there’s little point saving and keeping the data in $MyList. You could reset the list as the end, i.e. using $MyList=;). Simpler is to dump the list stage altogether and chain the .each(). onto the collect(), as shown in my last post above.

I’m not sure to what that relates, but it might be that these are equivalents:

$Subtitle = $Subtritle + ...

and

$Subtitle += ...

The latter is newer so won’t be seen in older examples. Both work the same way so it doesn’t matter which you use. Note that as well as the increment/add-to += operator, there is a negative equivalent -= operator.

1 Like

So, I tried it with a new agent using your code, and I get the same result – all of mine are wrapped with double quotes.

In this instance, I had imported a CSV that came to be 1200 notes. The $Full_text attribute was filled with a stamp that set it to be the $Text. My intention was to save the previously calculated strings in this attribute, thereby leaving me free to edit those notes later but still have the original text.

None of the notes show this $Text or $Full_text attribute to be wrapped in double quotes, but I suspect that because this was imported from a CSV, and in the CSV those strings were wrapped in double quotes that somehow, it affected this and is causing this result.

TO TEST THE THEORY, I created a note with the Prototype and the features that would make the agent’s query find it, and manually entered $Text and $Full_text. the result on the dashboard had no quotes… i.e. it works as expected.

So, importing from CSV is causing this.

TO TEST A REMEDY, I tried selecting an offending note’s $Text, deleting, and then pasting. There are no quotes in the note’s Text window. There are no quotes in the relevant attribute, BUT, the dashboard results in being wrapped in quotes. THEN, I went back to the new note I made and whose $Text and/or $Full_text attribute appeared with no quotes wrapping in the dashboard agent. As soon as I pasted the Text from the CSV imported note into the new note, then it also had wrapping quote marks in the dashboard agent! YIKES!

So, something from the CSV import has marked these and is causing them to put wrapping quotes here. I’m not sure how to clear/clean the imported notes.

Following Mark Anderson’s suggestions, why not make a CVS with just a few lines of the file you’re importing, and upload it?

Done. These are silly notes, but it’s the same structure. The CSV was made by a Numbers > Export to CSV. In other words, the CSV originated from a Numbers spreadsheet.

This tinderbox file is even worse than the one I’m working on, because all the lines have quotes wrapping them.
example for tinderbox quotes.tbx (272.8 KB)

It’s not letting me upload the csv file… the uploader just won’t activate the upload button if I try to select the CSV. hmmm…

with the query for the agent manually set to February 1, you should see:

here’s the raw csv:

Thing or Event,Full Text,"Radio Button for Thing, Event (label)",Year,Month (label),Day,Details
Smigos Bigos ,"Smigos Bigos , 2010. (Something random written.).",Thing,2010,February,1,Something random written.
Polka Time,"Polka Time, 1994. (Everyone loves to polka, if they learn how.).",Event,1994,February,1,"Everyone loves to polka, if they learn how."
Accordion Anniversary,"Accordion Anniversary, 2003. (Can’t stop tapping your foot.).",Event,2003,February,2,Can’t stop tapping your foot.
Sliwka Commemoration,"Sliwka Commemoration, 2012. (Who wouldn’t commemorate them?).",Thing,2012,February,2,Who wouldn’t commemorate them?
Excellent Thing,"Excellent Thing, 2019. (Success in motion.).",Thing,2019,February,2,Success in motion.
Sold the super beetle,"Sold the super beetle, 2011. (that was a fun car, should have never sold it.).",Event,2011,February,3,"that was a fun car, should have never sold it."
X-Files,"X-Files, 2007. (dang it.).",Event,2007,February,3,dang it.

It’s the parentheses!

D’oh! Parentheses in the attribute or $Text appear to be causing the wrapping quotes.

Check the results of this new version of the tinderbox file above:
example for tinderbox quotes 2.tbx (306.7 KB)
and the screen shots:
set it to February 1 in the query - the second line is not wrapped in quotes - because it doesn’t have parentheses in the string?:

set to Feb 2, and from a different note, but again, the top line has not parentheses … and it’s not wrapped:

Sorry about that. The forum is configured to only allow certain types of file. zips are supported, so that’s the method I use if i need to share/upload an unsupported type (even if reduced file size isn’t needed).

1 Like

Turns out my earlier reply was the right answer to the wrong question. Turns out it is more subtle…

This is an interesting interconnection of issues and gives me flashbacks to a previous career as a data emergency plumber (“I just need to to move from [system] to [system], how hard can it be? <eye roll/sigh>”). To be clear, there is no deliberate error here, only assumptions that in hindsight proved sun-optimal (for app and user0.

Before going into the weeds of the problem, I think it worthwhile stating the Tinderbox calls itself a ‘toolbox for notes’ and whilst it has automation in Action code, that Action code is not a programming language. It may look like one, and essentially act like one, but it is dangerous to work as it it is one. Why does that matter? Because Action code has accreted features over time, which have left some hard-to-backfill oddities, and UI-based (can’t see it → it doesn’t exist) users and automation users can pull the poor developer in conflicting directions with their feature requests. A case in point is summed up here: Problematic Characters for Action code in $Name and $Path. It isn’t the problem here but the latter neatly illustrates the nature of preceding point, and gives a hint of what is to follow…

With attribute values, if Tinderbox knows no better it gets treated as a string (of characters). Strings are stored as (straight) single/double quote enclosed values. Thus, either of these:

$MyString = "some value":
$MyString = 'some value';

If typing a value directly into an input box (Quickstamp, Get Info, Displayed Attributes table, etc.) the outer quotes are assumed and to don’t type them. I’m using code to avoid a slaw of screen grabs being needed.

As long as matched in type their can be used, leading us to the ability for one type to enclose the other:

$MyString = "It was Peter's fault.";
$MyString = 'A loud "Huzzah!" was heard';

As long as the outer pair of quotes are the same type and not used in-value, further variations of in-string quote use are are available. Note (as we’ll come back this) that the default/assumed form of delimited quote is straight double quotes.

But what about the parentheses? Stay with me, a bit more scaffolding explantation first…

A list in Tinderbox (used by List, Set and Dictionary data types) is essentially a string where the semicolon act as as the delimiter:

$MyList = "winken;blinken;nod";

But, you say, need a list item called ‘winken;blinken’. We can do that:

$MyList = 'winken';'blinken;nod';
//or
$MyList = '"winken;blinken;nod';

… gives a 2-item list. Note the outer quotes (the set you don’t type if typing not a Displayed Attributes table value box) are single quotes. So can a list have parentheses (BrE: brackets) in a value? Yes:

$MyList = "winken(blinken);nod";

gives 2 items: winken(blinken) and nod.

So why does your code fail? It turns out that whilst a simple list-based attribute can happily hold parentheses, the collect(), .format() and an unknown number of other list-operators cannot safely handle parentheses in item values. So, they first sanitise the string by enclosing ‘bad’ items in double-straight-quotes for onward processing. But, unhelpfully, the process doesn’t then remove them when done and thus—finally!—we find out why you have the stray quotes.

What to do then? It turns out it is quite simple, now we know how/why the unwanted quotes are arising. This works:

$Subtitle=;
collect(children,$Text).each(anItem){
   $Subtitle+=anItem+'\n' ;
};
$Subtitle=$Subtitle.replace('"',"");

N.B. the first argument in the .replace() call needs to use single quotes as they have to enclose a double-quote character (and Tinderbox has no escape mechanism for straight single/double quote characters).

Now that is out of the way, you really don’t need the .each() here, as there is a simpler approach. What you want to do is get all the child values and make them into a one-source-value-per-line price of text. IOW, you want to join all the list items into one string using a line space character as the join. You do that using .format():

$Subtitle=collect(children,$Text).format("\n").replace('"',"");

There’s no single ‘right` way! for the doubting, here is the last above, applied in @jbmanos’ test doc:

See, no stray quotes. though removing them was easy, knowing why they occurred and thus where in the process to remove them proved more complex.

To avoid those awful imported attribute names , see here and here. If you can’t edit the source process (e.g. someone else made the data it’s a closed system), I would, having first read the two preceding pages, edit the CSV file in something like BBEdit from:

Thing or Event,Full Text,"Radio Button for Thing, Event (label)",Year,Month (label),Day,Details

to

Name,FullText,ThingType,Year,MonthNumber,Day,Details

As we know the month is a number (e.g. 2 now February) we’d pre-make a number-type user attribute MonthNumber as auto generated attributes generally default to a String type. In this case you could just the data-type of ~MonthNumber` after import as a string won’t alter numbers passed to it; but, learning on my old data-plumbing days, don’t make the software guess when you can easily provide the correct answer and save yourself work.

Sorry for the answer but the simple solution tat the end would have made little sense without some explanation and exploration (where did my morning disappear to?).

HTH :slight_smile:

(I’ll check with the developer before editing aTbref as I know this parentheses-leading-to-quotes issue is new (it’s more an awkwardly handled edge case than a simple bug) and I’m not sure if there is/will be a fix.)

2 Likes