Advertisement
applehelpwriter

Slack message previewer (requires BBEdit)

Feb 23rd, 2018
928
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #######################
  2. -->> ABOUT
  3. #######################
  4. (*
  5.  
  6.  Phil Stokes -- 2018
  7.  applehelpwriter.com
  8.  sqwarq.com
  9.  
  10. *)
  11. #######################
  12. -->> DESCRIPTION
  13. #######################
  14. (*
  15.  
  16. If you use Slack, this script will allow you to write Slack-style formatting
  17. in a BBEDit document and then, through the 'Preview in BBEdit' menu item in BBEdit's
  18. 'Markdown' menu, it'll produce a simulation of what your message would look like in Slack.
  19. Useful if you're in a Slack group with editing timeouts but you have to post lengthy or heavily formatted messages.
  20.  
  21. DEPENDENCIES: BBEdit either while still in trial mode or with a license, as you need the Markdown features.
  22. This script does NOT require Slack.app, but does assume you know how to format Slack messages.
  23.  
  24. *)
  25. #######################
  26. -->> USAGE
  27. #######################
  28. (*
  29.  
  30. For a full description of how to use it, see the blog post and video
  31. 'BBEdit: how to preview Slack messages' on applehelpwriter.com at
  32. http://applehelpwriter.com/2018/02/23/bbedit-how-to-preview-slack-messages/
  33.  
  34. *)
  35. #######################
  36. -->> IMPORT STATEMENTS
  37. #######################
  38.  
  39. use AppleScript version "2.4" -- Yosemite (10.10) or later
  40. use scripting additions
  41. use framework "Foundation"
  42.  
  43.  
  44. #######################
  45. -->> GLOBALS, CONSTANTS, etc
  46. #######################
  47. property NSMutableArray : a reference to current application's NSMutableArray
  48. property NSCharacterSet : a reference to current application's NSCharacterSet
  49. property NSString : a reference to current application's NSString
  50. property NSArray : a reference to current application's NSArray
  51. set previewDivider to "<strong><span style=\"color:darkBlue\">Slack Preview:</span></strong>"
  52. set breakLine to "<br></br>"
  53. set newLine to "
  54. "
  55. # debug symobls
  56. # set debugArray to NSArray's arrayWithArray:{}
  57. # set debugString to NSString's stringWithString:""
  58.  
  59. #######################
  60. -->> HANDLERS
  61. #######################
  62. on replaceFormatString:oldFormat withTag:htmlTag inStr:aString
  63.     set tagCount to 0
  64.     set theMutant to NSMutableArray's new()
  65.     set mStr to NSString's stringWithString:aString
  66.     set slackStr to NSString's stringWithString:oldFormat
  67.     set htmlStrOpen to NSString's stringWithFormat_("<%@>", htmlTag)
  68.     set htmlStrClose to NSString's stringWithFormat_("</%@>", htmlTag)
  69.     set theArray to mStr's componentsSeparatedByString:slackStr
  70.     # set my debugArray to NSArray's arrayWithArray:theArray
  71.     set tagCount to ((count of theArray) as list)
  72.     repeat with i from 1 to tagCount
  73.         set index_ to (i - 1)
  74.         if index_ is greater than 0 and index_ mod 2 is not 0 then -- we're looking for odd numbers, 1, 3, 5...
  75.             if oldFormat is "+++" then -- our dummy tag, remember, for Slack's '>>>'
  76.                 try
  77.                     set theFormatString to (theArray's objectAtIndex:index_)
  78.                 on error
  79.                     set theFormatString to (theArray's objectAtIndex:(index_ - 1))
  80.                 end try
  81.                 set theFormatString to (theFormatString's stringByReplacingOccurrencesOfString:(my newLine) withString:(NSString's stringWithFormat_("%@&nbsp;", my newLine)))
  82.                 set theNewString to NSString's stringWithFormat_("%@&nbsp;%@%@", htmlStrOpen, theFormatString, htmlStrClose)
  83.             end if
  84.            
  85.             -- this is actually for Slack's '>' code
  86.             if oldFormat is ">>>" then
  87.                 try
  88.                     set theFormatString to (theArray's objectAtIndex:index_)
  89.                 on error
  90.                     set theFormatString to (theArray's objectAtIndex:(index_ - 1))
  91.                 end try
  92.                 set nl to (theFormatString's rangeOfString:(my newLine))
  93.                 if nl's |length| is greater than 0 then
  94.                     set preStr to (theFormatString's substringToIndex:(nl's location))
  95.                     set postStr to (theFormatString's substringFromIndex:((nl's location) + (nl's |length|)))
  96.                     set theNewString to NSString's stringWithFormat_("%@&nbsp;%@%@%@%@", htmlStrOpen, preStr, htmlStrClose, my newLine, postStr)
  97.                 end if
  98.             end if
  99.            
  100.             -- everything except the quote and @mentions tags, which are non-surrounding and a PIA!, we can deal with here:
  101.             if tagCount is greater than 2 then
  102.                 set theFormatString to (theArray's objectAtIndex:index_)
  103.                 set theNewString to NSString's stringWithFormat_("%@%@%@", htmlStrOpen, theFormatString, htmlStrClose)
  104.             end if
  105.             try
  106.                 if ((count of theMutant) as list) < index_ then
  107.                     (theMutant's addObjectsFromArray:theArray)
  108.                 end if
  109.             on error errMsg number errNum
  110.                 display dialog errNum & return & errMsg buttons "OK" default button "OK" with icon 1 with title "Slack Preview script"
  111.                 error number -128
  112.             end try
  113.             try
  114.                 (theMutant's replaceObjectAtIndex:index_ withObject:theNewString)
  115.             on error errMsg
  116.                 display dialog errMsg & return & return & "Perhaps more helpfully: Is one of the " & oldFormat & " tags missing?" buttons "OK" default button "OK" with icon 1 with title "Slack Preview script"
  117.                 error number -128
  118.             end try
  119.         end if
  120.     end repeat
  121.     set theArray to (NSArray's arrayWithArray:theMutant)
  122.     -- at last lets return and get out of here!
  123.     return theArray's componentsJoinedByString:" "
  124. end replaceFormatString:withTag:inStr:
  125.  
  126.  
  127. on removePreviousPreviewOf:aText
  128.     -- hmm, nothing much to say here, does what it says on the tin
  129.     set m to NSString's stringWithString:aText
  130.     set curtail to (m's rangeOfString:"<br></br>")
  131.     if curtail's |length| > 0 then
  132.         set m to (m's substringToIndex:(curtail's location))
  133.     end if
  134.     set m to m's stringByTrimmingCharactersInSet:(NSCharacterSet's whitespaceAndNewlineCharacterSet())
  135.     return m as text
  136. end removePreviousPreviewOf:
  137.  
  138.  
  139. on colourMentions:aNSString startsWith:aBool
  140.     set theMutant to NSMutableArray's new()
  141.     set anArray to aNSString's componentsSeparatedByString:"@"
  142.     (theMutant's addObjectsFromArray:anArray)
  143.     set tagCount to ((count of anArray) as list)
  144.     -- some finicking about because AS lists are 1-indexed but Obj-C arrays are 0-indexed
  145.     set tagCount to tagCount - 1
  146.     if tagCount > 0 then
  147.         repeat with i from 1 to tagCount
  148.             set index_ to i
  149.             set theFormatString to (anArray's objectAtIndex:index_)
  150.             set mentionString to theFormatString
  151.             set spaceRange to (theFormatString's rangeOfString:" ")
  152.             if spaceRange's |length| > 0 then
  153.                 set mentionString to (theFormatString's substringToIndex:(spaceRange's location))
  154.                 set theRest to (theFormatString's substringFromIndex:(spaceRange's location))
  155.             else
  156.                 set theRest to ""
  157.             end if
  158.             set theNewString to NSString's stringWithFormat_("<span style=\"color:#0074BC; background-color: #EAF5FC;\">@%@</span>%@", mentionString, theRest)
  159.             (theMutant's replaceObjectAtIndex:index_ withObject:theNewString)
  160.         end repeat
  161.         set anArray to (NSArray's arrayWithArray:theMutant)
  162.         return anArray's componentsJoinedByString:" "
  163.     else
  164.         return aNSString
  165.     end if
  166. end colourMentions:startsWith:
  167.  
  168.  
  169. on showPreview()
  170.     tell application "BBEdit"
  171.         set mentionStart to false -- default assumption that the content doesn't start with an '@' sign
  172.         -- list of formatting we're currently supporting
  173.         set tagList to {{slack:"```", html:"pre"}, {slack:"`", html:"code"}, {slack:"*", html:"strong"}, {slack:"_", html:"em"}, {slack:"~", html:"del"}, {slack:">>>", html:"blockquote"}, {slack:"+++", html:"blockquote"}} # '+++' is a dummy here, not a real Slack formatting option
  174.         set m to contents of front document
  175.         if m's text item 1 is "@" then set mentionStart to true
  176.        
  177.         -- if this isn't the first run, remove any previous preview
  178.         set m to my removePreviousPreviewOf:m
  179.         set m to m & my newLine
  180.        
  181.         -- reassign and replace the  quote tags so that we can process them properly later
  182.         set mStr to (NSString's stringWithString:m)
  183.         set mStr to mStr's stringByReplacingOccurrencesOfString:">>>" withString:"+++"
  184.         set mStr to mStr's stringByReplacingOccurrencesOfString:">" withString:">>>"
  185.        
  186.         repeat with aTag in tagList
  187.             -- does the text contain the current tag word in the repeat loop? Let's remove unwanted detritus created by previous iterations through the loop
  188.             if (mStr's containsString:(aTag's slack)) then
  189.                 set previewRange to (mStr's rangeOfString:(my previewDivider))
  190.                 set loc to previewRange's location
  191.                 if previewRange's |length| is 0 then
  192.                     set loc to mStr's |length| as integer
  193.                 end if
  194.                 set mStr to (mStr's substringToIndex:(loc))
  195.                 -- most of the heavy lifting is done here:
  196.                 set mStr to (my replaceFormatString:(aTag's slack) withTag:(aTag's html) inStr:mStr)
  197.             end if
  198.         end repeat
  199.        
  200.         -- now that we have the correct HTML tags, we can add styling to suit here
  201.         set mStr to mStr's stringByReplacingOccurrencesOfString:"<blockquote>" withString:"<blockquote style=\"border-left: 5px solid; border-color:lightgrey;\">"
  202.         set mStr to mStr's stringByReplacingOccurrencesOfString:"<code>" withString:"<code style=\"color:red; background-color: snow;font-size:1.2em; padding: 2px; border-style:solid;border-color: #d9d5d5; border-radius: 5px ;border-width: 2px;\">"
  203.         set mStr to mStr's stringByReplacingOccurrencesOfString:"<pre>" withString:"<pre style=\"background-color: snow; font-size: 1.3em; padding: 6px; border-style:solid;border-color: #d9d5d5; border-radius: 5px ;border-width: 2px; color: #5a5a5a\">"
  204.         set mStr to mStr's stringByReplacingOccurrencesOfString:(my newLine) withString:"<br/>"
  205.         set spanOpen to "<span style=\"font-size:1em; font-family:Lucida Grande;line-height: 1.6em;\">"
  206.         set spanClose to "</span>"
  207.         set mStr to NSString's stringWithFormat_("%@%@%@", spanOpen, mStr, spanClose)
  208.         -- one last bit of processing is to style the '@someone' keywords
  209.         set mStr to my colourMentions:mStr startsWith:mentionStart
  210.        
  211.         -- at last, let's load up our formatted text!
  212.         set m to m as text
  213.         set contents of front document to m & my newLine & my newLine & my breakLine & my newLine & my previewDivider & my newLine & my breakLine & mStr
  214.     end tell
  215. end showPreview
  216.  
  217.  
  218. #######################
  219. -->> COMMANDS
  220. #######################
  221. my showPreview() # call everything above!
  222.  
  223. -- let's make the Preview window frontmost if it exists
  224. tell application "BBEdit"
  225.     set didOpen to false
  226.     set winList to every window
  227.     repeat with win in winList
  228.         set f to name of win
  229.         if f contains "Preview" then
  230.             set visible of win to true
  231.             set didOpen to true
  232.             activate
  233.         end if
  234.     end repeat
  235.     -- if it doesn't exist,, lets say so:
  236.     if didOpen is false then
  237.         display dialog "Please open the Preview window in BBEdit (Control-Command-P), or from the menu bar, choose 'Markup > Preview in BBEdit'." buttons "OK" default button "OK" with icon 1 with title "Slack Preview script"
  238.     end if
  239. end tell
  240. #EOF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement