Running Javascript Sorting via Apple Automator
I am trying to use the following code in Apple Automator
var lnRange = getSelectedLineRange();
var ln = getTextInRange(lnRange[0],lnRange[1]);
var lines = ln.split('\n').sort(function(a, b)
{
var parsedA = a.replace(/\*\s(<s>)?(The )?/, "* ");
var parsedB = b.replace(/\*\s(<s>)?(The )?/, "* ");
return parsedA.localeCompare(parsedB);
});
setTextInRange(lnRange[0],lnRange[1],lines.join('\n'));
I know the code sounds like it sounds and achieves the results I need (Executing it in drafts on the iPhone gives exactly the results I want, namely sorting the list of labels, ignoring the use of <s>
and / or "at the beginning of the line. * Should remain, to delay the list).
Passing it from iPhone to Automator is where things fall apart as Automator can't find the getSelectedLineRange variable. I'm guessing this is a conflict between how Automator handles text input and how the script wants to accept and process it, but I'm stumped as to how to resolve it.
For example (in case my whole approach is wrong) I need this list, in any text field that I can throw on it
* Armadillo
* The aardvark
* <s>Rhino</s>
* <s>The Zebra</s>
* The Giraffe
* Hedgehog
if selected to step through the script running as a service and exit like this
* The aardvark
* Armadillo
* The Giraffe
* Hedgehog
* <s>Rhino</s>
* <s>The Zebra</s>
I am certainly not married to a javascript solution, but this is a starting point.
source to share
The " Run JavaScript " action in Automator needs a function run(input, parameters)
.
input is an array containing one element (text).
function run(input, parameters) {
var lines = input[0].split('\n').sort(function(a, b)
{
var parsedA = a.replace(/\*\s(<s>)?(The )?/, "* ");
var parsedB = b.replace(/\*\s(<s>)?(The )?/, "* ");
return parsedA.localeCompare(parsedB);
});
return lines.join('\n');
}
source to share
I'm not familiar with JavaScript well enough to help with this, but this AppleScript should work inside the Run AppleScript activity :
on run {input}
set rawParagraphs to every paragraph of (input as text)
set recordsForSorting to {}
repeat with eachPara in rawParagraphs
if (eachPara as text) length > 0 then
set end of recordsForSorting to my CheckText(eachPara as text)
end if
end repeat
set sortedRecords to my bubblesort(recordsForSorting)
set sortedText to ""
repeat with eachRecord in sortedRecords
set sortedText to sortedText & (eachRecord ActualWord) & return
end repeat
return sortedText
end run
to CheckText(txt)
if txt contains "<s>" then
set sortRecord to {SortWord:((characters 4 thru -1 of txt) as text), ActualWord:txt}
else if txt contains "the" then
set sortRecord to {SortWord:((characters 5 thru -1 of txt) as text), ActualWord:txt}
else
set sortRecord to {SortWord:txt, ActualWord:txt}
end if
return sortRecord
end CheckText
-------------------------
on bubblesort(array)
repeat with i from length of array to 2 by -1 --> go backwards
repeat with j from 1 to i - 1 --> go forwards
tell array
if (item j) SortWord > (item (j + 1)) SortWord then
set {item j, item (j + 1)} to {item (j + 1), item j} -- swap
end if
end tell
end repeat
end repeat
return array
end bubblesort
The script creates an entry for each paragraph that contains the actual text, and the same text with the "or" removed. It then uses bubble sort on the target member, returning a string of actual text times in sorted order.
I did not make any provisions for the asterisk; I was not sure about your post if this was part of the original problem or formatting.
I haven't tested it as a Service, but it worked in Automator with standard input text and then output to a text file.
Good luck,
source to share
Working with @ Craig's answer I found the following script deals with my problem and hopefully helps others.
on run {input}
set rawParagraphs to every paragraph of (input as text)
set recordsForSorting to {}
repeat with eachPara in rawParagraphs
if (eachPara as text) length > 0 then
set end of recordsForSorting to my CheckText(eachPara as text)
end if
end repeat
set sortedRecords to my bubblesort(recordsForSorting)
set sortedText to ""
repeat with eachRecord in sortedRecords
set sortedText to sortedText & (eachRecord ActualWord) & return
end repeat
return sortedText
end run
to CheckText(txt)
if txt starts with " * <s>The " then
set sortRecord to {SortWord:((characters 11 thru -1 of txt) as text), ActualWord:txt}
else if txt starts with " * The " then
set sortRecord to {SortWord:((characters 8 thru -1 of txt) as text), ActualWord:txt}
else if txt starts with " * <s>" then
set sortRecord to {SortWord:((characters 7 thru -1 of txt) as text), ActualWord:txt}
else if txt starts with " * " then
set sortRecord to {SortWord:((characters 4 thru -1 of txt) as text), ActualWord:txt}
else if txt starts with "* <s> The " then
set sortRecord to {SortWord:((characters 11 thru -1 of txt) as text), ActualWord:txt}
else if txt starts with "* The " then
set sortRecord to {SortWord:((characters 7 thru -1 of txt) as text), ActualWord:txt}
else if txt starts with "* <s>" then
set sortRecord to {SortWord:((characters 6 thru -1 of txt) as text), ActualWord:txt}
else if txt starts with "* " then
set sortRecord to {SortWord:((characters 3 thru -1 of txt) as text), ActualWord:txt}
else
set sortRecord to {SortWord:txt, ActualWord:txt}
end if
return sortRecord
end CheckText
-------------------------
on bubblesort(array)
repeat with i from length of array to 2 by -1 --> go backwards
repeat with j from 1 to i - 1 --> go forwards
tell array
if (item j) SortWord > (item (j + 1)) SortWord then
set {item j, item (j + 1)} to {item (j + 1), item j} -- swap
end if
end tell
end repeat
end repeat
return array
end bubblesort`
I suspect there are some terrible bugs that I am only to blame for hiding in there, but it seems to work.
source to share