Would it be possible to add an “Open this script in your Script Editor link” when there is a script in a post?
It would be nice. At least we can copy-and-paste without extra Web detritus being inserted.
Hey Ed,
I think someone proficient with JavaScript could manage to use Xpath and Hover/Selection to extract the text out of the code-block in Safari and perhaps Google Chrome.
I’ve seen this sort of thing done in different contexts, but I don’t have the js-chops to do it myself just yet.
A basic non-dynamic example extracting the outer-html of Shane’s code-block on this page:
--------------------------------------------------------------------------------
set jStr to "document.getElementsByClassName('hljs applescript')[0].outerHTML"
set theHTML to doJavaScriptInSafari(jStr)
--------------------------------------------------------------------------------
--» HANDLERS
--------------------------------------------------------------------------------
on doJavaScriptInSafari(javascriptStr)
try
tell application "Safari" to do JavaScript javascriptStr in front document
on error e
error "Error in handler doJavaScriptInSafari() of library NLb!" & return & return & e
end try
end doJavaScriptInSafari
--------------------------------------------------------------------------------
-Chris
I wonder how Macscriptor does it. If I put a script in a post it automatically formats it and adds the link to open it in my script editor.
So the question is can discourse do that?
I guess they wrap the script around
applescript://com.apple.scripteditor?action=new&script=<your script percent encoded>
I think MattNeu might know something about that.
So this is probably more for amusement than everyday use, but it extracts the scripts from the current Safari page, and if more than one, gives you the ugliest choose from list
dialog you’ve ever seen. Because it re-downloads everything, it’s also a bit slow. But it works, and it’s a bit of fun.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "WebKit"
use scripting additions
-- This handler must be run on the main thread
on makeWebViewWithURL:thePageURL
-- make a WebView
set theView to current application's WebView's alloc()'s initWithFrame:{origin:{x:0, y:0}, |size|:{width:100, height:100}}
-- tell it call delegate methods on me
theView's setFrameLoadDelegate:me
-- load the page
theView's setMainFrameURL:thePageURL
end makeWebViewWithURL:
-- called when the WebView loads a frame
on WebView:aWebView didFinishLoadForFrame:webFrame
-- the main frame is our interest
if webFrame = aWebView's mainFrame() then
-- get the web archive data
set theData to webFrame's dataSource()'s webArchive()'s |data|()
-- make HTML
set {xmlDoc, theError} to current application's NSXMLDocument's alloc()'s initWithData:theData options:(current application's NSXMLDocumentTidyHTML) |error|:(reference)
-- extract scripts
set theScripts to xmlDoc's nodesForXPath:".//pre/code" |error|:(missing value)
set theSources to {}
set theSourcesFull to {}
if (count of theScripts) > 1 then
repeat with aScript in theScripts
set theSource to aScript's stringValue()
set end of theSources to theSource as text
set theSource to (theSource's stringByReplacingOccurrencesOfString:linefeed withString:"\\r")
set end of theSourcesFull to (theSource's stringByReplacingOccurrencesOfString:(space & space & "+") withString:space options:(current application's NSRegularExpressionSearch) range:{0, theSource's |length|()}) as text
end repeat
-- pick script
set theResult to (choose from list theSourcesFull with prompt "Choose a script")
if theResult is false then
beep
error number -128
end if
set theResult to item 1 of theResult
repeat with i from 1 to count of theSourcesFull
if item i of theSourcesFull = theResult then
set finalSource to item i of theSources
exit repeat
end if
end repeat
else
set finalSource to (item 1 of theScripts)'s stringValue() as text
end if
-- make SD document
tell application id "com.latenightsw.ScriptDebugger6" -- Script Debugger.app
activate
make new document
set source text of document 1 to finalSource
compile document 1
end tell
end if
end WebView:didFinishLoadForFrame:
tell application id "com.apple.Safari" -- Safari.app
set theURL to URL of document 1
end tell
my performSelectorOnMainThread:"makeWebViewWithURL:" withObject:theURL waitUntilDone:true
Darn, it Shane. Now you’ve gone and distracted me from what I should be doing…
I think your script assumes that the CSS is defined in the header. That won’t work with web pages on sites like mine, e.g,
because it’s hosted by wordpress.com, and all CSS has to be in-line (it’s a right royal pain, and I really should migrate off of wordpress.com, but the pain barrier is just too high for me to jump).
A typical line of AppleScript looks like this:
repeat with i from 1 to count of items in aText
which renders as
repeat with i from 1 to count of items in aText
on the actual page.
I might be able to adapt your script to deal with both, though. EDIT: on second thoughts, I’m not sure I can.
And you’re right about that choose from list dialog – boy is that a pig. I don’t know why choose from list can’t have parameters to limit the vertical and horizontal sizes (I might file an ER against it in Sierra just for laughs).
Sorry, I should have been specific: it’s designed (and lightly tested) only for this forum.
Hey Folks,
This works in Safari.
Click in the code block.
Run the script with FastScripts, Keyboard Maestro, etc.
-Chris
--------------------------------------------------------------------------------
# Auth: Christopher Stone { JavaScript by @Complexpoint on the Keyboard Maestro forum }
# dCre: 2016/07/12 05:01
# dMod: 2016/07/12 05:16
# Appl: Safari, Script Debugger
# Task: Extract Code from Code Blocks in Discourse Forums.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @Safari, @Script_Debugger, @Extract, @Code, @Discourse
--------------------------------------------------------------------------------
set jsStr to "
(function () {
var oSeln = window.getSelection(),
nodeTable = document.evaluate(
'./ancestor-or-self::code',
oSeln.anchorNode,
null, 0, 0
).iterateNext(),
rngDoc = nodeTable ?
document.createRange() : null;
if (nodeTable) {
oSeln.removeAllRanges();
rngDoc.selectNode(nodeTable);
oSeln.addRange(rngDoc);
}
})();
window.getSelection()+'';
"
tell application "Safari"
tell front document
set selectedText to do JavaScript jsStr
end tell
end tell
if selectedText ≠ "" then
tell application "Script Debugger"
activate
make new document with properties {source text:selectedText}
set bounds of front window to {606, 23, 1920, 1196}
end tell
end if
--------------------------------------------------------------------------------
Hey Ed,
What scriptlet?
-Chris
Ed’s line should be a link (it is here).
The problem, though, is that the Discourse software doesn’t generally support this approach at present.
Hey Shane,
It shows as an apparent link in Safari and Chrome, but there’s nothing connected to it – even when you inspect the source.
-Chris
Ah – I could have sworn it was working earlier.
Trying again:
Open this Scriplet in your Editor:
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
timer(“Start”)
YOUR CODE
— NOTE: The below shell scripts have nothing to do with the timer() handler —
set cmdStr to "perl -e ‘use Time::HiRes qw(time); print time’"
set timeStart to do shell script cmdStr
timer(“After First Shell Script”)
set timeStop to do shell script cmdStr
timer(“STOP”)
Maybe Discourse can’t handle html in a post?
Discourse forum software does not, in general, support HTML by users in a post. There are a few exceptions, like HTML tables (requires Admin to enable). Markdown is the primary formatting system for user posts:
The Discourse software does not allow non http/https URL schemes in URLs. When something like applescript://...
appears within a Markdown URL or an HTML href, Discourse strips it out.
There appears to be movement within the Discourse developers to relax this restriction in some future version of Discourse.
OK, what I would like to achieve is being able to select text in Script Debugger and run a script that grabs the selection (or the entire script) from the front window, and formats it for discourse, with all the color and style attributes, and drops it into an appleScript:// type link that displays the formatted script and when a user clicks on it, it will open the script in their script editor.
Is this doable with the current version of discourse, using HTML or Markdown?
We all share the same desire. For the time being, this is beyond our abilities for technical reasons having to do with the Discourse software. The Discourse folks are talking about fixing the issue where non-http/https URL schemes are filtered.
Once that issue is resolved, when we can generate applescript://
URLs. The final step will be to get the code which pretty-prints AppleScript for us to also generate the applescript://
URL string as well. I’m pretty confident I can make that JS/Ruby code work when the time comes.