BBEdit AppleScript for reformatting multiple files - applescript

I'm looking to write an Applescript which will utilize BBEdit — loop through a ton of HTML files and autoformat them (so the indentation is easier to read).
So far I have:
tell application "BBEdit"
activate
open {file "Macintosh HD:TEST DIRECTORY:testfile copy 2.html"} with LF translation
(format mode hierarchical)
beep
display alert "Finished!"
end tell
This applies the transformation to a single file, but has anyone got any suggestions how to apply this to an unknown number of HTML files?

You've almost got it; the trick is that you want to loop through the files returned by open. Thus, you need something like this:
tell application "BBEdit"
set docs to open LIST_OF_FILES with LF translation
repeat with doc in docs
-- format doc
save doc
end repeat
beep -- Or even `say "Finished!" without waiting until completion`
-- if you want your computer to talk to you
display alert "Finished!"
end tell
As you can see, all you need to do is place your formatting code inside this loop (and don't forget to save the files!); the loop will set doc to each element of the list docs in turn, and run the body with that element. If you're not sure how to select the files, one way is choose file with multiple selections allowed; this will pop up a dialog box which will allow you to select as many files as you want. To use it, just replace LIST_OF_FILES with (choose file with multiple selections allowed).

BBEdit will perform a find/replace on any group of files you want. Just hit command+shift+f to bring up Multi-File Search instead of the basic find/replace window.
If you have more than one set of find/replace commands that you need to execute at the same time, you need a Text Factory. See here for details on how to set one up: http://www.barebones.com/products/bbedit/benefitsexercise.html
Does that help?

You should use the Text Factory feature for this. Under "File > New > Text Factory". Any operation you can perform on a single file can be done on any number of files and you can save the operation for future use.

Related

(NO mystery:) How Automator transfers "invisible" information to Script-Editor

( I have been pushed to an obvious answer to my "Mystery" from a friendly member here.
I feel a little ashamed not to have found this solution myself, but will leave this posting online if there aren't too many irritated folks around. Maybe someone else can learn from this … apologies to every "know-it-alls"!)
I have recorded these actions with Automator:
– Cmd-tab to bring TextEdit to front (must have some lines typed)
– Pressed left arrow 7 times using shift down
– Stopped the recording
Next I selected and copied (Cmd-c) all action icons in Automator's "Record my actions" window.
I switched to Script-Editor and pasted (Cmd-v) them into a new window.
Then, I repeated above recording with 3 times UP arrow and copied icons into another new window.
I took only the two "set uiScript to …" lines and appended them in the first script.
THEY READ IDENTICAL:
set uiScript to "keystroke \"\t\" using command down"
my doWithTimeout(uiScript)
set uiScript to "keystroke \"\" using shift down" -- 7 times left-arrow
my doWithTimeout(uiScript)
set uiScript to "keystroke \"\" using shift down" -- 3 times up-arrow
my doWithTimeout(uiScript)
on doWithTimeout(uiScript)
set endDate to (current date)
repeat
try
run script "tell application \"System Events\"\n" & uiScript & "\nend tell"
exit repeat
end try
end repeat
end doWithTimeout
(To make resulting code more readable I omitted error code and "delays".)
Now, if I disable one of the "keystroke" lines (=> --my doWith…) the script somehow knows that it either has to do Shift-leftArrow 7 times OR Shift-upArrow 3 times.
I tried this after computer restart, even copied the code from this web page and pasted it into a new Script Editor window – it still knew what to do!
HOW CAN THAT BE ???
My only idea is: there must be some internal Applescript database that recognises content even if copied/pasted.
Does anybody know ?
Only if I re-write the code identically will there happen NOTHING – until I copy the first line of either recording ("set uiScript to …"). So the information must be linked to this first line somehow.
(BTW: first two lines that bring TextEdit –or, e.g. a Finder window– to the front work only from opened Script Editor; you have to bring TextEdit to the front yourself, if you start the saved-as-program script from Script-Editor's menu icon subfolder. Nevertheless the script won't work without them…)
It "knows" because the keystrokes are in the string - keystrokes using control type keys (such as arrow keys) just don’t have a text representation, so they wind up being invisible. Some text editors such as BBEdit can show these invisible characters, but they don’t show up in the Script Editor.
Apple has obviously made Automator's Watch Me Do action able to capture some of these control keys in a string, but for the rest of us it is more difficult, since the control keys will actually perform their function when pressed. If you need to use these kinds of keys, the key code command can be used, since it refers to the actual keyboard key, for example:
tell application "System Events"
repeat 3 times
key code 126 using shift down -- up arrow
end repeat
end tell
As the answer is quite simple but may still be interesting to some, I'll explain it shortly:
red_menace (in his comment above) pointed out that strings may contain invisible elements (like arrow keys), therefore I next checked the obvious:
If you "cursor-walk" along the "set uiScript …" strings the cursor will actually "pause" for 7 or 3 "steps" respectively on its way.
I hadn't thought/heard of any "invisible" string-chars (apart from obvious ones in Word etc.).

How to replace in selection using AppleScript for BBEdit?

Is there a way to replace text within a selection using Applescript for BBEdit? I have a replace script, and I'd like to run it for only selected text. I know you can replace in selection using the find menu, but I can't find anything that says it does this in the AppleScript dictionary for BBEdit. Thanks.
To use an application's scripting dictionary, specific commands aren't necessarily declared, just their syntax and options. Usually you can look at a command to see what the parameters are, which also defines the data types that it is expecting - in this case for example, the replace command has a searching in parameter, which can be anything.
The answer is similar to the one to your other topic, you just need to further define where to search. For example, the selection is a property of a window, and a window is a property of a document:
tell application "BBEdit"
tell front document
replace "12:" using "{#pl}:" searching in its window's selection
end tell
end tell

Xcode AppleScript : change label which content of variable

Here is my script :
property MyLabel : missing value
on buttonClicked_(sender)
set the plistfile_path to "~/Desktop/MY_DATA.plist"
tell application "System Events"
set p_list to property list file (plistfile_path)
-- read the plist data
set theMyDataFromPlist to value of property list item "DATA1" of p_list
end tell
end buttonClicked_
This gonna take the data I want from a plist and set in a variable (theMyDataFromPlist).
How can I print this variable on the label "MyLabel" and make the script auto refresh when the data change ?
also, when I click on the text (or another button), can I copy the value to the clipboard. (would set the clipboard to theMyDataFromPlist work?)
I also wonder is that possible to do the same with Swift?
How can I print this variable on the label "MyLabel"
Where would you like to print the variable? You can make AppleScript display a dialog:
set variable to 42
display dialog "The value of variable is " & variable
AppleScript is not designed as a terminal language, it is for UI scripting, so it's not like most scripting languages that just offer a print as where would the user see the printed value.
and make the script auto refresh when the data change ?
Not quite sure what you expect here. That your system magically runs your script whenever the content of a file changes? That's not going to happen. You can create a launchd job and have launchd monitor that file and then execute your script when the file changes; this is described here:
https://discussions.apple.com/message/13182902#13182902
But some process will have to monitor the file and if your script should do so, it has to be running all the time, non-stop. Then you could make some code run once every X seconds, checking the file last modification date and whenever that changes, re-read the plist. This polling is super ugly but the best thing that AS can do out of the box.
BTW where is the rest? You say
also, when I click on the text (or another button),
can I copy the value to the clipboard.
Which text? Which button? Sound like you have a whole application there but all you showed us are 11 lines script code. You didn't even mention that you have a whole application with a UI. Your question starts with "Here is my script", so you make it sound like this 11 lines is all that you have.
(would set the clipboard to theMyDataFromPlist work?)
Why don't you simply try it out? Pasting that line into ScriptEditor would have taken equally long than asking this question. I just tried it and it turns out that you can only set strings.
This code won't work:
-- bad code
set variable to 42
set the clipboard to variable
But this code does work:
-- good code
set variable to 42
set the clipboard to "" & variable
I also wonder is that possible to do the same with Swift?
Personally I would not even consider writing an application in AppleScript; I'd rather stop writing code before I do that. Of course this can be done in Swift or in Obj-C. Everything you can do in AS can be done in these other two languages and no, the opposite doesn't hold true.
Using Obj-C or Swift, you can also use GCD and with GCD monitoring a file for changes is easy. Just see
https://stackoverflow.com/a/11447826/15809

How to combine two image (png) files to print them in duplex using AppleScript

Right, so I'll try and explain this as clearly as possible;
As soon as two files are placed in the folder, I want a Folder Action to
print these files - got that...
but, and this is my problem. At the moment it prints the files after each other, and I want to make sure that they are printed together, duplex.
so far I've got this:
on adding folder items to this_folder after receiving added_items
do shell script "defaults write com.apple.print.custompresets com.apple.print.lastPresetPref Duplex"
tell application "Finder" to print these_items
end adding folder items to
so I reckon I need to combine/append the two files - so the printer sees them as one, and only one print job is the result, thus creating a duplex printed file :D
would be awesome if you have tips/ideas on how to solve this!
cheers!
I found a python script written by Martin Michel which will combine multiple images into one file. It should help you solve your problem... find it here. You may want to use image events to resize the images first before passing it to this script so they will fit properly on one printed page.
You could create a simple Automator Folder action, which would create a multipage PDF from the added image files, then either print it directly in Automator, or pass it on to an AppleScript in order to set your printer preferences.

Manipulating text in XCode, moving one line

In emacs I have various functions to manipulate text. Now that I'm using xcode, I suppose I could make emacs my default editor, but I want to browse obj-c objects and such, so I'd rather just implement my most used text manipulation commands for xcode.
First on my list, I'd like a command that moves the text of the current line up/down one line, keeping the cursor on the current line.
In emacs this is:
(defun move-one-line-downward ()
"Move current line downward once."
(interactive)
(forward-line)
(transpose-lines 1)
(forward-line -1))
I'd be happiest if I could write a script in Python that would do the equivalent in XCode, but as far as I can tell, I need to talk to AppleScript to do this.
Can someone walk me through how to do this with XCode?
Xcode 4 has a new set of command for moving the line where the cursor is or the selected text with command + option + [ or ]
⌥⌘[ or ⌥⌘]
http://developer.apple.com/library/mac/#documentation/IDEs/Conceptual/xcode_help-command_shortcuts/MenuCommands/MenuCommands014.html
What you’re wanting to do can be achieved through Xcode’s “User Scripts”—and it helpfully comes with a pair of scripts that almost do what you want. (I’m using Xcode 3.2 here, but I think these were also there in 3.1)
Look in /Developer/Library/Xcode/User Scripts/; there are two applescripts there, Move Line Up.scpt and Move Line Down.scpt. Here’s what’s in Move Line Up:
(*
To edit this script, choose Save As... and save it in your home directory, then re-add it to the User Scripts list.
*)
using terms from application "Xcode"
tell first text document
set {startLine, endLine} to selected paragraph range
if startLine > 1 then
set theText to (paragraphs startLine through endLine)
set theText to (theText as string)
delete (paragraphs startLine through endLine)
make new paragraph at beginning of paragraph (startLine - 1) with data theText
set selected paragraph range to {startLine - 1, endLine - 1}
else
beep 1
end if
end tell
end using terms from
These almost do what you want, except they select the whole line afterwards; I’m no applescript expert, but you probably want to store the selected character range. Have a look at the Xcode scripting dictionary (in AppleScript Editor, File -> Open Dictionary -> Xcode) to find out the types of objects you can manipulate.
You can add your own scripts to Xcode with the “Edit User Scripts”menu item in the script menu; and assign shortcut keys to the scripts in that window also, by double-clicking in the right-hand column beside the entry for the script menu item.
You can also use shell scripts (perl, python, bash, whatever) in the User Scripts menu, but these process only the selection or the whole file, so might be a bit heavyweight for moving a single line up or down.
See all the docuemntation on User Scripts here: http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeWorkspace/310-User_Scrips/user_scripts.html
I hope this helps!
I think your question is more generic that Xcode/emacs. Most IDE can't do stuff that editors can do and vice versa.
What I do is to use Xcode for 'simple' stuff and compile/debug. When I want to do lot's of coding (hm ... text editing) I open multiple files in one Vim (no offense to emacs ... vim is my editor of choice) and use all the vim tricks available.
I follow the same process when I need to do lots of coding on Windows (Visual Studio). I have VS opened just for compiling/debugging but I do most coding in separate Vim window.
I don't need to do any of that on Unix because I just open file in Vim and run Makefile from within Vim, jumping directly to errors and so on (:mak) ...
I'm sure that there are some extremely clever things to get Xcode do stuff that are already in Vim and Vim to do stuff that Xcode can do but I'm focusing on coding so not much time to play around.
Also, you can hook up emacs (or vi, or bbedit, or ed, I imagine) to xcode, so that they will talk to each other. When you tell xcode to open a file it will call emacsclient, etc. You can even get emacs to tell xcode where to put a breakpoint (I don't remember how, but I asked a question here a while back, and it works great)

Resources