KM8: Script to Get Plain Text from Comment Action (Rich Text)


KM 8 was a great update, bringing us a ton of new features, including the ability to script the KM Editor app. This has opened the door to many new opportunities.

However, one of the changes in KM8 was to make the text content of many Actions, like the Comment Action, to be rich text. While this is a great UI feature, it makes getting the Comment text by script much harder.

This script solves that problem. It reads the rich text (aka "StyledText") of the first Action, and converts it to plain text.
Please feel free to post your questions, issues, and suggestions.

Use Case

  • Read ReleaseNotes in first Comment Action to auto-insert into Macro upload.
  • I wanted to post this script here as an example that might be used for many other purposes.

Script: Get Plain Text from First Comment Action Rich Text Field

VER: 2.0 2017-11-15 ~~~


@KM @Action Get @Plain Text From First Comment Action in Macro (13.3 KB)


  • This script was made possible by the extensive help and scripts provided by @peternlewis and @ShaneStanley (ASObjC guru who hangs out in the Script Debugger 6 Forum. ).


property ptyScriptName : "Get Plain Text from First Comment Action Rich Text Field"
property ptyScriptVer : "2.0"
property ptyScriptDate : "2017-11-15"
property ptyScriptAuthor : "JMichaelTX"



  • For the First Action in the Selected Macro, convert the Rich Text of the Action's
    "<StyledText>" field into Plain Text.
  • This was original built to extract the ReleaseNotes in the first Comment Action
      of a Macro.

  1.  macOS 10.11.6+
  2.  Mac Applications
      • KM Editor App 8.0.4+
        • ASObjC Handler kmActionRichTextToPlainText()

REF:  The following were used in some way in the writing of this script.
  1. Script by ShaneStanley
      • How Do I base64 Decode and Encode Multiple Lines?



use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"
use scripting additions

tell application "Keyboard Maestro"
  set oMacro to item 1 of (get selected macros)
  set actionList to actions in oMacro
  set oAction to item 1 in actionList
  tell oAction
    set actXML to xml
    set actName to name
  end tell -- oAction
  set actPlainText to my kmActionRichTextToPlainText(actName, actXML)
end tell

return actPlainText

--~~~~~~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~~~~~

on kmActionRichTextToPlainText(pActionName, pXMLStr)
  local theString, stringData, mutableDict, theError, theData, mutableAttString, plainString, richTextKeyStr
  set LF to linefeed
  --- Dictionary Key for Rich Text Block ---
  set richTextKeyStr to "StyledText"
  set theString to pXMLStr
  set theString to current application's NSString's stringWithString:theString
  -- convert string to data
  set stringData to theString's dataUsingEncoding:(current application's NSUTF8StringEncoding)
  -- convert plist to mutable dictionary
  set {mutableDict, theError} to current application's NSPropertyListSerialization's propertyListWithData:stringData options:(current application's NSPropertyListMutableContainersAndLeaves) |format|:(missing value) |error|:(reference)
  if mutableDict is missing value then error (theError's localizedDescription() as text)
  -- extract RTFD data and convert to a mutable atributed string
  set theData to mutableDict's objectForKey:richTextKeyStr
  if (theData is not missing value) then
    --- Decode Rich Text ---
    set mutableAttString to current application's NSMutableAttributedString's alloc()'s initWithRTFD:theData documentAttributes:(missing value)
    --- GET PLAIN TEXT from Rich Text ---
    set plainString to (mutableAttString's |string|()) as text
  else -- ERROR: "StyledText" key was NOT found
    set msgStr to "❯❯❯ ERROR ❮❮❮" & LF & ¬
      "'StyledText' key was NOT found in XML for Action: " & pActionName
    set titleStr to "Handler: kmActionRichTextToPlainText"
    set plainString to msgStr
    display dialog msgStr ¬
      with title titleStr ¬
      buttons {"Cancel", "OK"} ¬
      default button ¬
      "OK" cancel button ¬
      "Cancel" with icon stop
  end if
  return plainString
end kmActionRichTextToPlainText