I have a simple string that lists items separated by commas. Before the last item, I would like to include the word "and".
Example comma separated string:
green apple, red strawberry, orange grapefruit, yellow banana
I would like to display this instead:
green apple, red strawberry, orange grapefruit, and yellow banana
Also, if there are only two items I would like to remove the comma (i.e. green apple and red strawberry).
Any ideas on how I can get started with this?
Thank you!
One way is to use text item delimiters, count the number, and then handle each situation. This assumes no extraneous commas.
set s to "green apple, red strawberry, orange grapefruit, yellow banana"
set otid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set s to text items of s
set n to count of s
if n = 1 then
set r to s as string
else if n = 2 then
set r to item 1 of s & " and" & item 2 of s
else
set item -1 of s to (" and" & item -1 of s)
set r to s as string
end if
set AppleScript's text item delimiters to otid
return r
Related
Newbie to AppleScript here, I've learned the following method from other online sources that allows me to extract a string that is between two strings I can define, see code:
to ExText(searchText, startText, endText)
set spaceholder to "x"
set searchText to ("x" & searchText)
set AppleScript's text item delimiters to spaceholder
set endItems to text item -1 of searchText
set AppleScript's text item delimiters to endText
set beginningToEnd to text item 1 of endItems
set AppleScript's text item delimiters to startText
set finalText to (text items 2 thru -1 of beginningToEnd) as text
set AppleScript's text item delimiters to ""
return finalText
end ExText
I'm using this method to extract user's first and last name from an html string obtained by running Javascript id search. I'll do
Set SourceString to "<span>firstname lastname</span>"
ExText(SourceString, "<span>", "</span>")
It works 90% of the time, but in a few instances, depending on the user's name, it'll get an error with this message
Can’t make text items 2 thru -1 of "(part of the name)" into type text.
Here are some sample names that'll break this method
<span>Xu Chang</span>
<span>Maxim Smith</span>
In further testing, I confirmed that any names containing the letter "X" would fail this method. I've examined the actual source strings side by side with the names that contain X and the ones that don't, so it's not the source string but the method itself.
It's worth noting that this error is reproducible everytime.
A rather bizarre behavior. Any ideas?
changing the variable of spaceholder from "x" to "xx" should work
to ExText(searchText, startText, endText)
set spaceholder to "xx"
set searchText to ("xx" & searchText)
set AppleScript's text item delimiters to spaceholder
set endItems to text item -1 of searchText
set AppleScript's text item delimiters to endText
set beginningToEnd to text item 1 of endItems
set AppleScript's text item delimiters to startText
set finalText to (text items 2 thru -1 of beginningToEnd) as text
set AppleScript's text item delimiters to ""
return finalText
end ExText
My goal here is to apply the no break parameter of Illustrator with AppleScript to two words in a text frame.
I'm able to detect the non-breaking space in a string. Then I need to apply the no break parameter to the word after and before the character 202 as no break space isn't supported by Illustrator
Open this Scriplet in your Editor:
set ourText to "Hello my friend Jon<non-breaking-space>Doe."
set findThis to (ASCII character 202)
set MW to words of ourText
repeat with aWord in MW
if findThis is in aWord then
set myWord to aWord
exit repeat
end if
end repeat
myWord
--> display: Jon Doe
Then I would like to search in the text frame for "Jon Doe" apply the no break parameter. I tried manually in Illustrator, this would work.
Your script doesn’t work because you are building a list of words. Spaces (including no-break spaces) are word delimiters, so they are not in your word list (MW).
It will work if we use the no-break space as text item delimiter:
use scripting additions
set theResult to {}
set ourText to "Hello my friends Jon Doe, Jane Doe and Joe Doe!" # Each name contains a no-break space
set findThis to character id 160 # Decimal notation of U+00A0 (no-break space)
set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to findThis # The no-break space
set countTextItems to count of text items of ourText
if countTextItems > 1 then
repeat with i from 1 to countTextItems - 1
set end of theResult to word -1 of text item i of ourText & findThis & word 1 of text item (i + 1) of ourText
end repeat
else
set theResult to "[no character id " & id of findThis & " found]"
end if
set AppleScript's text item delimiters to linefeed
display dialog theResult as text
set AppleScript's text item delimiters to saveTID
Input (ourText):
Hello my friends Jon[noBreakSpace]Doe, Jane[noBreakSpace]Doe and Joe[noBreakSpace]Doe!
Output:
Please note that this will fail in cases like
my friends J.[noBreakSpace]Doe
because we are using word inside the repeat loop.
If you often have cases like these then replace word -1 and word 1 with text -1 and text 1. The output then will only contain the two characters around the spaces, but for searching purposes this is still enough.
I have many esoteric CDs whose track names are not always in CDDB. So I'm trying to write a an Applescript that will take a list of song titles that I copy from AllMusic and paste them as track names in iTunes. When copying a list of track names from AllMusic, the format is ALMOST always:
track #
Title
Composer
Track length
A link to Spotify or Amazon
This repeats for as many tracks as the album contains. I wrote the following Applescript which works when the above format does not change:
set tid to AppleScript's text item delimiters
set txt to the clipboard
set p to count paragraphs of (the clipboard)
set i to 2
tell application "iTunes"
activate
if selection is not {} then -- there ARE tracks selected...
set mySelection to selection
repeat with aTrack in mySelection
if i is less than p then
set AppleScript's text item delimiters to ASCII character 13 -- (a carriage return)
set newTxt to text items of txt -- not text of, text items of
set AppleScript's text item delimiters to tid -- restore text delimiters
set name of aTrack to item i of newTxt
set i to i + 5
end if
end repeat
end if
end tell
The problem is that sometimes there is one or two more or less categories (e.g. missing composer) which throws my script off. Ideally, there would be a way to have the script go through the list of text items, find track #1, paste in the very next text item, find track 2, paste in the very next text item, etc. Any ideas on how to accomplish this?
Thanks for any help.
Here is the altered code based on my comment below:
…I tried adding "set k to 1" at the top, changing "set i to i + 5" to "set i to i + 4", and adding:
if i is equal to k then
set i to i + 1
set k to k + 1
end if
at the end of the repeat loop. Then the script would jump by 4 paragraphs. If counter 'k' didn't match the paragraph it was looking at (e.g. if k was "2" and paragraph i was not "2", it must mean that it was a group of 5 paragraphs, so "i" would advance by one. Not good scripting, but it would probably work in most cases. The trouble was that I could never get "if i is equal to k" to return as true, even when it was. Here is the code in full:
set tid to AppleScript's text item delimiters
set txt to the clipboard
set p to count paragraphs of (the clipboard)
set k to 1
set i to 2
tell application "iTunes"
activate
if selection is not {} then -- there ARE tracks selected...
set mySelection to selection
repeat with aTrack in mySelection
if i is less than p then
set AppleScript's text item delimiters to ASCII character 13 -- (a carriage return)
set newTxt to text items of txt -- not text of, text items of
set AppleScript's text item delimiters to tid -- restore text delimiters
set name of aTrack to item i of newTxt
set i to i + 4
if i is equal to k then
set i to i + 1
set k to k + 1
end if
end if
end repeat
end if
end tell
Thanks for confirmation about the format. The main issue is that it is not an easy format ! So, the script must look what are the next tab or return sequence to determine what is what.
I made the script bellow which does what you need. I included many comments to make it clear (I hope !). The first rows explain what could be the 4 possible text formats that the script must handle for composer and link ( yes/no for each).
I have tested the script with the 4 formats all in sequence in the same text. You must add your iTunes routine, which can use the defined variables : TTrack, TComposer (could be empty), TArtist, TLength and TLink (could be empty).
I insert a comment where your iTunes routine must be added.
The script loops until all txt from clipboard has been used.
(* format of input text is made of :
track# <tab> title <return> composer <return> artist <return> track_length <tab> link <tab>
- title, artist and track_length are mandatory
- composer and link are optional
Therefore, there are 4 possible formats :
track# <tab> title <return> composer <return> artist <return> track_length <tab> link <tab> (= complete)
track# <tab> title <return> artist <return> track_length <tab> link <tab> ( = no composer)
track# <tab> title <return> composer <return> artist <return> track_length <tab> ( = no link)
track# <tab> title <return> artist <return> track_length <tab> ( = no link, no composer)
*)
set Ctab to ASCII character 9
set Creturn to ASCII character 13
set txt to the clipboard
repeat while length of txt > 1
set AppleScript's text item delimiters to Creturn
set Track_Title to text item 1 of txt -- the first item always contains Track# tab Title
set L to (length of Track_Title) + 1 -- L will be the ofset for next track
set T2 to text item 2 of txt -- the second item could be composer or artist
set T3 to text item 3 of txt -- the third item could be artist or (track_length tab link tab track# tab title)
if (offset of Ctab in T3) = 0 then -- the third item is artist
set TComposer to T2
set TArtist to T3
set L to L + (length of TComposer) + 1 + (length of TArtist) + 1
set NextT to text item 4 of txt -- NextT = (track_length tab link tab track# tab title) or (track_length tab track# tab title)
else -- the third item is (track_length tab link tab track# tab title) or (track_length tab track# tab title)
set TComposer to ""
set TArtist to T2
set L to L + (length of TArtist) + 1
set NextT to text item 3 of txt
end if
set AppleScript's text item delimiters to Ctab
set TTrack to text item 1 of Track_Title
set TTitle to text item 2 of Track_Title
set TLength to text item 1 of NextT
set L to L + (length of TLength) + 1
if (count of text items of NextT) is 4 then -- format is (track_length tab link tab track# tab title)
set TLink to text item 2 of NextT
set L to L + (length of TLink) + 1
else -- format is (track_length tab track# tab title)
set TLink to ""
end if
-- replace this dialog by your iTunes procedure !!!!!!
display dialog "track=" & TTrack & return & "title=" & TTitle & return & "composer=" & TComposer & return & "Artist=" & TArtist & return & "length=" & TLength & return & "Link=" & TLink & return & "L=" & L
if length of txt > (L + 1) then
set txt to text (L + 1) thru -1 of txt -- remove all current track from text
else
set txt to ""
end if
end repeat
I have the following code, which prompts user for a comma separated list of places:
set AppleScript's text item delimiters to {","}
set thePlaces to the text items of the text returned of (display dialog "Insert referenced places separated by commas" default answer "")
This will result on a list with several items ("Paris","London", ...).
My intention is to prefix every item of this list with a string (for eg. "plc:".
In the end, I would like the list to be composed by items such as:
"plc:Paris", "plc:London".
Have been trying but with no luck so far. Can anyone point me in the right direction?
Thanks.
Looks a little brutal, but works as wished:
repeat with i from 1 to count thePlaces
set item i of thePlaces to "plc:" & item i of thePlaces
end repeat
The repeat loop loops through the items and add "plc:" in front of the content...
Enjoy, Michael / Hamburg
This is how you can do it with text item delimiters, we box each item, with a unique value for the front, and one for the end, so that we can differentiate between the two. No use for this with so small lists, really. I just wanted to show you how it can be done.
set astid to text item delimiters
set the places to "Paris,London,Rome"
set text item delimiters to ","
set lstItms to text items of the places
-- we "box" the text items, so that every one is prepended with a return, and has a linefeed appended to it.
set text item delimiters to return & linefeed
set places to lstItms as text
set text item delimiters to astid
set places to linefeed & places & return
-- our list is in shape, time to do the actual replacement.
set text item delimiters to linefeed
set lstItms to text items of places
set text item delimiters to "plc:"
set places to lstItms as text
set text item delimiters to return
set lstItms to text items of places
set text item delimiters to astid
log item 1 of lstItms
(*plc:Paris*)
Is there a way, say using a space char as the string delimiter, set a string to the first three words of a paragraph including spaces.
For example
set a to "This is my test string"
set b to words 1 thru to 3 of a
set c to words 1 thru to 3 of a as rich text
return {b,c}
Returns {{"This","is","my"},"Thisismy"}
I want to set a variable so in this case of a, it would be set to "This is my".
First let's explain what happens. words 1 thru 3 of a as rich text is getting a range of words as an list. Then as rich text (which should be as string) coerces the list into an string. When you coerce an list (or record) to an string AppleScript will use an separator called text item delimiter. By default it is set to "". This means there is no separator (delimiter) used and the words are glued together. But let's see what happens when we set temporarily the text item delimiters to space.
set a to "This is my test string"
set b to words 1 thru 3 of a
set {oldTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, space}
set c to words 1 thru 3 of a as string
set AppleScript's text item delimiters to oldTID
return {b, c}
now it returns {{"This", "is", "my"}, "This is my"}