TextWrangler: comparing two documents ignoring whitespace with the help of AppleScript - compare

I was looking for a way to compare two documents ignoring the whitespace in TextWrangler. While the interface of TextWrangler doesn't provide that option I found this https://groups.google.com/d/msg/bbedit/ER3VdOf2xOs/IcKi3ccA90oJ
Now this was not a fully working solution. While this script:
tell application "TextWrangler"
compare document 1 against document 2 options ¬
{case sensitive:true, ignore curly quotes:true, ignore extra spaces:true, ignore leading spaces:true, ignore trailing spaces:true}
end tell
works, it is somewhat inflexible. So I tried to make the second stub working:
set compOpts to {"All Options:false", "case sensitive:true", "ignore curly quotes:true", "ignore extra spaces:true", "ignore leading spaces:true", "ignore trailing spaces:true"}
tell application "TextWrangler"
tell me to set compOpts to choose from list compOpts ¬
with title "Compare Front Two Documents" with prompt ¬
"Select Options" default items (items 2 thru -1 of compOpts) ¬
multiple selections allowed true ¬
with empty selection allowed
display dialog compOpts as string
set compareOptions to make new Compare Options with properties compOpts
compare document 1 against document 2 options compareOptions
end tell
but here I get the Error:
error "TextWrangler got an error: Can’t make class Compare Options." number -2710 from Compare Options to class
what I am doing wrong here?
I want to add that the following script also works:
tell application "TextWrangler"
set compareOptions to ¬
{case sensitive:true, ignore curly quotes:true, ignore extra spaces:true, ignore leading spaces:true, ignore trailing spaces:true} ¬
compare document 1 against document 2 options compareOptions
end tell
but this doesn't work:
set compareOptions to {All Options:false, case sensitive:true, ignore curly quotes:true, ignore extra spaces:true, ignore leading spaces:true, ignore trailing spaces:true}
it just doesn't compile. What the … ?

These options are only known to TextWrangler and as such you'll have to create them in the TextWrangler tell block. You can't build the options from string representations of the options, so if you want to choose them from a list then you'll need to build them dynamically from the chosen strings. Take a look how I did this.
Good luck.
set compOptsList to {"All Options:false", "case sensitive:true", "ignore curly quotes:true", "ignore extra spaces:true", "ignore leading spaces:true", "ignore trailing spaces:true"}
set compOpts to choose from list compOptsList ¬
with title "Compare Front Two Documents" with prompt ¬
"Select Options" default items (items 2 thru -1 of compOptsList) ¬
multiple selections allowed true ¬
with empty selection allowed
tell application "TextWrangler"
set chosenOptions to {}
repeat with i from 1 to count of compOpts
set thisOption to item i of compOpts
if thisOption is item 2 of compOptsList then
set chosenOptions to chosenOptions & {case sensitive:true}
else if thisOption is item 3 of compOptsList then
set chosenOptions to chosenOptions & {ignore curly quotes:true}
else if thisOption is item 4 of compOptsList then
set chosenOptions to chosenOptions & {ignore extra spaces:true}
else if thisOption is item 5 of compOptsList then
set chosenOptions to chosenOptions & {ignore leading spaces:true}
else if thisOption is item 6 of compOptsList then
set chosenOptions to chosenOptions & {ignore trailing spaces:true}
end if
end repeat
if chosenOptions is not {} then
compare document 1 against document 2 options chosenOptions
else
compare document 1 against document 2
end if
end tell

Related

AppleScript "if contain"

I have a script which look for the name and search for a match with a another variable.
It's working fine however if the variable 1 is "Name Demo" and variable 2 is "Demo Name" then the script don't find a match.
set nameMatchTXT to ""
if NameOnDevice contains theName then
set nameMatch to theName & " : Name Match"
end if
Is there anyway to change this to find the match whatever the order ?
PS the script is looking for word wild name, and sometime handle dual bit characters which can be a difficulty.
Your request stated:
if the variable 1 is "Name Demo" and variable 2 is "Demo Name" then
the script don't find a match.
This will solve that problem:
set var1 to "Name Demo"
set var2 to "Demo Name"
if (var2 contains (word 1 of var1)) and (var2 contains (word 2 of var1)) then
-- you have a match
display dialog "var1 and var2 match"
else
display dialog "no match"
end if
You will have to have make a separate check for each condition. There are other ways to do it (such as a complex regex), but this is the easiest and most readable.
set nameMatch1 to "Name"
set nameMatch2 to "Demo"
if (NameOnDevice contains nameMatch1) and (NameOnDevice contains nameMatch2) then
set nameMatch to NameOnDevice & " : Name Match"
end if
If you are adding matching criteria, you may eventually add more. Instead of adding more variables, and more conditions, you may want to put all of your words in a list and check against that. In the future, if you need to add more words, you can simply add the word to the list. I've extracted it into a separate sub-routine here for easier reading:
on name_matches(nameOnDevice)
set match_words to {"Name", "Demo"}
repeat with i from 1 to (count match_words)
if nameOnDevice does not contain item i of match_words then
return false
end if
end repeat
return true
end name_matches
if name_matches(nameOnDevice) then
set nameMatch to nameOnDevice & " : Name Match"
end if
Edit after clarification
If you have no control over the matching text (if it comes from an outside source, and is not coded by you), you can split that text into words and use those as the wordlist in the second example. For instance:
on name_matches(nameOnDevice, match_text)
set match_words to words of match_text
repeat with i from 1 to (count match_words)
if nameOnDevice does not contain item i of match_words then
return false
end if
end repeat
return true
end name_matches
if name_matches(nameOnDevice, match_text_from_some_other_source) then
set nameMatch to nameOnDevice & " : Name Match"
end if

Enumerate existing text in Vim (make numbered list out of existing text)

I have a source document with the following text
Here is a bunch of text
...
Collect underpants
???
Profit!
...
More text
I would like to visually select the middle three lines and insert numbers in front of them:
Here is a bunch of text
...
1. Collect underpants
2. ???
3. Profit!
...
More text
All the solutions I found either put the numbers on their own new lines or prepended the actual line of the file.
How can I prepend a range of numbers to existing lines, starting with 1?
It makes for a good macro.
Add the first number to your line, and put your cursor back at the beginning.
Start a macro with qq (or q<any letter>)
Copy the number with yf<space> (yank find )
Move down a line with j
Paste your yank with P
Move back to the beginning of the line with 0
Increment the number with Ctrl-a
Back to the beginning again with 0 (incrementing positions you at the end of the number)
End the macro by typing q again
Play the macro with #q (or #<the letter you picked>)
Replay the macro as many times as you want with <number>## (## replays the last macro)
Profit!
To summarize the fun way, this GIF image is i1. <Esc>0qqyf jP0^a0q10#q.
To apply enumeration for all lines:
:let i=1 | g/^/s//\=i.'. '/ | let i=i+1
To enumerate only selected lines:
:let i=1 | '<,'>g/^/s//\=i.'. '/ | let i=i+1
Set non recursive mapping with following command and type ,enum in command mode when cursor is inside the lines you are going to enumerate.
:nn ,enum {j<C-v>}kI0. <Esc>vipg<C-a>
TL;DR
You can type :help CTRL-A to see an answer on your question.
{Visual}g CTRL-A Add [count] to the number or alphabetic character in
the highlighted text. If several lines are
highlighted, each one will be incremented by an
additional [count] (so effectively creating a
[count] incrementing sequence).
For Example, if you have this list of numbers:
1.
1.
1.
1.
Move to the second "1." and Visually select three
lines, pressing g CTRL-A results in:
1.
2.
3.
4.
If you have a paragraph (:help paragraph) you can select it (look at :help object-select). Suppose each new line in the paragraph needs to be enumerated.
{ jump to the beginning of current paragraph
j skip blank line, move one line down
<C-v> emulates Ctrl-v, turns on Visual mode
} jump to the end of current paragraph
k skip blank line, move one line up
required region selected, we can make multi row edit:
I go into Insert mode and place cursor in the beginning of each line
0. is added in the beginning of each line
<Esc> to change mode back to Normal
You should get list prepended with zeros. If you already have such, you can omit this part.
vip select inner paragraph (list prepended with "0. ")
g<C-a> does the magic
I have found it easier to enumerate with zeroes instead of omitting first line of the list to enumerate as said in documentation.
Note: personally I have no mappings. It is easier to remember what g <C-a> does and use it directly. Answer above describes usage of pure <C-a> which requires you to manually count whatever, on the other hand g <C-a> can increment numbers with given value (aka step) and have it's "internal counter".
Create a map for #DmitrySandalov solution:
vnoremap <silent> <Leader>n :<C-U>let i=1 \| '<,'>g/^/s//\=i.'. '/ \| let i=i+1 \| nohl<CR>

Sorting an Applescript list in ascending order by indexing

I am trying to sort a list of file names in a created from one folder. Here is the code as it's simplest form. If I run this the 10 always comes after the 1 rather then the 9. What am I over looking.
set composer_list to {"Filename_1", "Filename_2", "Filename_3", "Filename_4", "Filename_5", "Filename_6", "Filename_7", "Filename_8", "Filename_9", "Filename_10", "Filename_11"}
simple_sort(composer_list)
--======================================= Sorting Handler =====================================
on simple_sort(my_list)
set the index_list to {}
set the sorted_list to {}
repeat (the number of items in my_list) times
set the low_item to ""
repeat with i from 1 to (number of items in my_list)
if i is not in the index_list then
set this_item to item i of my_list as text
if the low_item is "" then
set the low_item to this_item
set the low_item_index to i
else if this_item comes before the low_item then
set the low_item to this_item
set the low_item_index to i
end if
end if
end repeat
set the end of sorted_list to the low_item
set the end of the index_list to the low_item_index
end repeat
return the sorted_list
end simple_sort
Result:
{"Filename_1", "Filename_10", "Filename_11", "Filename_2", "Filename_3", "Filename_4", "Filename_5", "Filename_6", "Filename_7", "Filename_8", "Filename_9"}
Use:
considering numeric strings
simple_sort(composer_list)
end considering
Result:
{"Filename_1", "Filename_2", ..., "Filename_9", "Filename_10", "Filename_11"}
However, one variant to this problem that I had:
I had a list with hyphenated sections and subsections, using numbers separated by hyphens (section1, section1-3, section1-3-5, section2-0). Using the original simple_sort, 1-3-5 was coming in before 1-3. However, using "considering numeric strings" instead treated the hyphens as minus signs, and things were all jumbled. However, I added another subroutine to pre-treat the compared strings by removing the hypens before comparing:
on removeHyphens(theText)
set AppleScript's text item delimiters to "-"
set theReturn to every text item of theText
set AppleScript's text item delimiters to ""
set theReturn to theReturn as string
return theReturn
end removeHyphens
Then in the simple_sort function, I changed one line to this:
else if removeHyphens(this_item) comes before removeHyphens(low_item) then
This worked like a charm for this specific circumstance.
It's because
"Filename_11" comes before "Filename_2" -- true
If you zero pad the list, it should work.
"Filename_11" comes before "Filename_02" -- false
You should download Nigel Garvey's "A Dose of Sorts" for the best sorting routines.
how about
ignoring hyphen
...
end ignoring
but the best answer is: use Filename_01 (leading 0 padding)

RegEx Notepad++

I have series of line in following format:
LINE: 5190 STNO: 22669 SI: VOICE
CCT LINE STNO SI BUS TYPE
003 6269 OPTI ONLY
MULTLINE 8. . . . . . . . . . . . . . .
001 SUBUNIT . . . . . DIGITE MAIN DEFIL/TRS
(ALT_ROUT: N) (OPTIIP )
LINE: 5291 STNO: 29956 SI: VOICE
What I need to find through regex (notepad++) are the numbers just after "STNO:"
There are approximately 100 of such matches.
I tired STNO:\s+\d{4,5} but it is taking STNO also into the match which i do not want. Please help.
I need to keep the matched result only and rest i want to delete or copy the matched items to a new file whichever is easier.
I suggest a two step approach. First get all the lines with the STNO and a number. Second remove everything except the number.
Select the Mark tab in the find dialogue. Ensure Bookmark line is ticked. In the Find what box enter STNO:\s*\d+ and then click Mark all.
Access Menu => Search => Bookmark => Copy bookmarked lines. Then paste into another buffer. Alternatively, to work in the same file use Menu => Search => Bookmark => Remove unmarked lines. Now you should have all the wanted lines in a buffer.
Do a regular expression search and replace setting Find what to be ^.*STNO:\s*(\d+).*$ and Replace with to \1. Then click Replace all.
The above assumes that there is only one number to be found per line.
=========================
As only the numbers are wanted, another method would be to put line breaks plus a marker around the wanted numbers, then delete any lines without the marker, finally delete the markers.
Let the marker be keep. Do a search and replace setting Find what to be keep and Replace with to a single space character, make sure Match case is not selected; then click Replace all. Next, do a regular expression search and replace setting Find what to be ^STNO:\s*(\d+) and Replace with to \r\nkeep\1\r\n. You might want Match case ticked; then click Replace all. Next do a mark lines (as described above) with Find what set to keep, followed by Menu => Search => Bookmark => Remove unmarked lines. Finally, do a search and replace setting Find what to be keep and Replace with to be empty.

applescript choose from list result

I have created a 'choose from list' in Applescript where the choices are lines in a .txt file. It looks like this:
set listofUrls to {}
set Urls to paragraphs of (read urlList)
repeat with nextLine in Urls
if length of nextLine is greater than 0 then
copy nextLine to the end of listofUrls
end if
end repeat
choose from list listofUrls with title "Refine URL list" with prompt "Please select the URLs that will comprise your corpus." with multiple selections allowed
This works very nicely, and if I 'return result', I get a list in the results window in the formal "urlx", "urlb" etc.
The problem is thaat when I try to save this list to a textfile, with, for example:
write result to newList
the formatting of the file is bizarre:
listutxtÇhttp://url1.htmlutxtÇhttp://url2.htmlutxt~http://url3.htmlutxtzhttp:// ...
It seems that null characters have been inserted, too. So, does anybody know what's going on? Can anybody think of a way to either:
a) write results as clean (preferably newline delimited) txt?
b) clean this output so that it is back to normal?
Thanks for your time!
Daniel
without seeing what you are to write to file I think you just need to convert the result to a string with paragraphs
pseudo code
set listofUrls to {}
set urlList to ":Users:loaner:Documents:urllist.txt" as alias
set Urls to paragraphs of (read urlList)
repeat with nextLine in Urls
if length of nextLine is greater than 0 then
copy nextLine to the end of listofUrls
end if
end repeat
choose from list listofUrls with title "Refine URL list" with prompt "Please select the URLs that will comprise your corpus." with multiple selections allowed
set choices to the result
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to return
set list_2_string to choices as text
set AppleScript's text item delimiters to tid
log list_2_string
write list_2_string to newList