Paste Styled Text To Comment Action Without Losing Layout

JMichaelTX,

Thanks for the quick response!

Pasting styled text causes the "corruption" or shift of all the prior modification statements. To better present the situation, below is the macro I actually use to add new comments to the modification history comment action. You'll see it already uses a number of your shared actions to 1) get the selected macro which has been edited and 2) is attempting to use your actions for applying style to the comment I want added.

Keyboard Maestro Actions.kmactions (26 KB)

Unfortunately, both pasting from the system clipboard or inserting styled text has previously caused the "corruption" or shift of all the statements (I show both statement options in red above which need to be replaced with the correct action that works successfully). Perhaps, you are suggesting I should paste parts of the comment using separate variables?

That is NOT the behavior I am seeing, running Keyboard Maestro 9.2 on macOS 10.14.6 (Mojave).

May I suggest this:

  • Copy and Paste your Comment Action into my Macro
  • Click in your Comment, and add a new line where you want to insert the new log entry
  • Trigger my Macro (unchanged other than add your Comment Action).

Does that work as you expect?

If not – please record a video or animated GIF showing your process and post it here.

If it does work then there is something else you are doing in your macro that is causing the problem.

JMichaelTX,

I'm still getting the "corruption" as you can see from video. I've trimmed the video down to enable its uploading, but you'll see the problem still exists.

KM Styled Text Entry Screen Recording.zip (6.1 MB)

I appreciate your assistance!

Solved! Used "Copy as Text" on comment action and pasted copied text into MS Word which revealed that each modification entry was "bullet'd" (for some unknown reason). Once text was "unbullet'd", pasting stylized text was successful without "corruption". Also, must ensure added text matches the text style (i.e. font) of prior entries like so thanks to JMichaelTX:
image

Glad to hear you worked it out.
Just to be clear, there was no "corruption" in the pasting -- it was simply pasting in a format that you did not want. All operations were normal.

JMichaelTX,

Correct, there never was any actual corruption of the text pasted. The newly pasted text was simply adhering to the (unrecognized and undesired) bullet formatting of the comment text block. I guess I realized that corruption was probably not the best descriptor which was why I used quotes around the word.

Lastly, until you pointed it out with your solution, I hadn't realized that the variable and other styled text font and size of the Insert action needed to match the existing comment text format unless a difference is desired for any reason.

Thanks again for you help.

1 Like

While JM solved KM's initial problem, I've been wanting to style comment text in a wide variety of ways (which is how I found this thread).

I've discovered that I can format text almost any way that I want in TextEdit and past the RTF into the KBM Comment field and the formatting is preserved.

What I'm looking for now is a pair of macros that will open the existing comment text in TextEdit and then paste it back when I'm done. I'll keep looking...

There's not much point in looking and further.

At this stage the only way to move style-text between KM and an editor is to copy the text in the desired action and paste it into a TextEdit document – and vice versa.

All brute force and no finesse.

I was hoping TextEdit or Jedit Ω supported AppleScripted paste-from-clipboard, or in the case of JeO insert as styled text. Unfortunately it looks like they don't support any of those features.

What is it you're looking to do in the editor?

Change fonts including bold and italic, create headings of different levels, add nested bullet lists, create hyperlinks, etc.

I want to use the comments for my development to-do lists, for my notes on things I've learned, links to the Forum post where I got the source idea, etc.

I can munge around and get something marginally usable in the text format of straight typing into the Comments text field, but it's often not what I want to have to do.

The Use Case

Just today I was looking at a group of macros that included a couple of downloaded examples and several working and not working attempts of my own, and the names were not telling me where I had left off or what progress I had made. The individual macros had notes that helped me sort it out, and I wanted to create an overview for the group, making notes of what I had figured out today in looking through them.

I created a Status Overview macro consisting of a single comment. I used an OCR macro to capture the list of macro names and paste them into the comment. I started adding notes and quickly realized that it would be more readable if the names of the macros were in a different font or maybe a bulleted list.

I copied the comment text into TextEdit where I selected all the macro names and pressed the Bulleted List tool button. I then kept the TE file open while I looked through the macros again and copied bits from their internal comments and added more notes to each entry. And then I copied the whole TE text from that file and pasted it into the comment field of the Status Overview macro Comment action. That got me the nicely organized and formatted comment text display that I wanted.

The Desire

It seems to me that a pair of macros, or even a single macro that does one thing if KBM is in front and another if TE is the focussed app, could do the swapping in and out very nicely, as well as taking care of the overhead like going back and deleting the temporary TE file, etc.

It seems like such an obvious KBM utility that I thought there was a good possibility that someone else had already built one.

The Solution

And I just now find out that it's already built-in to comment editing as described by the late JMichaelTX in his answer in this thread:
Wish list: multi-level lists in comments

I tried it and it works. The KBM menu sequence:
Edit > Format > Text > Show Ruler
turns the Comment action's main Comment field into a mini-TextEdit window. JM defines a simple macro that uses the Select or Show a Menu Item action:

Here's my status comment with the ruler shown:

image

I suspect this will do a lot of what I need. The "Show Ruler" shortcut in TE is ⌘R so I think I'll use that as the trigger for the macro that JM shows at the end of the thread above.

Future Directions

I see that ⌘R is already used by KBM for Record, which I have use very occasionally. So I need to find a different trigger for the macro or find out how to change the Record hotkey.

I also see that this embedded tool does not insert links. For now, that requires the TextEdit switch. As @DanThomas describes in Quick Tip: Put Links to Macros in Comments!, links can even be direct to another KBM macro! That's useful enough that I may write some macros for that (if no one else has already).

1 Like

Wait, what?!?! How the eff didn't I know this before? OMG that's so helpful! Thanks!

2 Likes

Have you seen this?

It looks like Jim had some AppleScript that lets you put an RTF hyperlink on the clipboard. His macro does a lot more than that, but I suspect if you looked closely enough, you could extract something to let you make links.

1 Like

I know, right?

No, I had not seen that. Thanks!

Bold, Italic, and Underline keyboard shortcuts all work in a comment action – with or without the ruler showing.

Comment actions have always had a ruler, but I think the ability to make it visible is fairly new. Thanks for pointing it out.

You don't need to move to an RTF editor to manage links, you can make them with a macro.

Create RTF Link for Keyboard Maestro Forum Thread Title and URL and Place on the Clipboard

This will create a pasteable link on the clipboard:

--------------------------------------------------------
# Auth: Christopher Stone <scriptmeister@thestoneforge.com>
# dCre: 2019/04/17 02:19
# dMod: 2021/01/16 19:00
# Appl: Google Chrome, Keyboard Maestro
# Task: Create RTF Link for Keyboard Maestro Forum Thread Title and URL and Place on the Clipboard.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @Google_Chrome, @Keyboard_Maestro, @Create, @RTF, @Link, @Forum, @Thread, @Title, @URL, @Clipboard
--------------------------------------------------------

try
   set clipboardText to the clipboard as text
on error
   set clipboardText to null
end try

tell application "Google Chrome"
   tell front window
      set theTitle to its title
      
      if clipboardText ≠ null and clipboardText starts with "http" then
         
         set theURL to clipboardText
         
      else
         
         set theURL to active tab's URL
         
      end if
      
   end tell
end tell

tell application "Keyboard Maestro Engine"
   set theTitle to search theTitle for " +- .+$" replace "" with regex
end tell

--------------------------------------------------------


set shCMD to text 2 thru -1 of "
echo '<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">
<html>
  <head>
  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
  <meta http-equiv=\"Content-Style-Type\" content=\"text/css\">
  <title>'\"$myTitle\"'</title>
  <meta name=\"Generator\" content=\"Cocoa HTML Writer\">
  <meta name=\"CocoaVersion\" content=\"1038.11\">
  <style type=\"text/css\">
    span.s1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Lucida Grande}
  </style>
  </head>
  <body>
    <span class=\"s1\"><a href='\"" & theURL & "\"'>'\"" & theTitle & "\"'</a></span>
  </body>
</html>' \\
| textutil -convert rtf -inputencoding UTF-8 -format html -stdin -stdout \\
| pbcopy -Prefer rtf
"


--------------------------------------------------------

do shell script shCMD

display notification "Link Copied to the Clipboard" with title "Google Chrome" subtitle "Script" sound name "Tink"

--------------------------------------------------------

(*

NOTES:

2020/12/18 10:24 -- Added ability to use a URL on the clipboard as the link.

*)

--------------------------------------------------------

Once you've pasted a link into the comments action you can right-click on it and edit it.

The script has the pieces to build all kinds of tools.

  • Link from a browser tab.
  • Link from selected text.
  • Link from the clipboard and selected text.
  • User Prompt.
  • Etcetera.

There are no keyboard shortcuts available for lists, nor does KM make them available in a menu to be used with a select-menu action – however you can create stubs with the ruler you want and save to a named clipboard for later use.

I just tried this with a styled-text snippet in Typinator, and it worked nicely.

Many things are possible.

1 Like

Thanks Chris,

I didn't need to use your script. I highlighted the title on the page, pressed ⌘C, and pasted it into the Comment text field. As you say, it's editable from there.

Your script eliminates the need to highlight the exact text, it creates a link to the current browser page with the current page title.

Thanks.

Ah...

I didn't know you could just paste in a URL and then turn it into a link with a title. The way that process works is a bit awkward though.

I have my AppleScript set up in both Google Chrome and Keyboard Maestro, so I can quickly grab a link without having to move around much.

I do need to figure out how @JMichaelTX put both a RTF link and a MarkDown link on the clipboard at the same time though.

@ComplexPoint has a monster Copy-as-Markdown link macro, and @_jims also has one.

I need to look at those more closely...

Here's the basic process, which assumes ObjC.import("AppKit"):

// setClipOfTextType :: String -> String -> IO String
const setClipOfTextType = utiOrBundleID =>
    txt => {
        const pb = $.NSPasteboard.generalPasteboard;

        return (
            pb.clearContents,
            pb.setStringForType(
                $(txt),
                utiOrBundleID
            ),
            txt
        );
    };

To add additional pasteBoard items (not replacing the incumbents),
just omit the line:

pb.clearContents

above.

1 Like

Nice.

What are the values for utiOrBundleID? Are they listed somewhere? I know the list can be extensive, but it would be nice to have a place to start. Thanks!

Some basics are system-declared, see: System-Declared Uniform Type Identifiers

and others are defined by the writers of particular applications.

To find them, I typically:

  • copy something in the relevant application, and then
  • inspect the pasteBoard items and their identifiers with something like the code below:
Expand disclosure triangle to view JS source
(() => {
    "use strict";

    // Rob Trew @2021

    ObjC.import("AppKit");

    // ----------- VIEW OF TYPES IN CLIPBOARD ------------

    // main :: IO ()
    const main = () => (
        pBoard => {
            const dict = cartesianProduct(
                ObjC.deepUnwrap(
                    pBoard.pasteboardItems.js[0].types
                )
            )([
                "string"
                // "propertyList", "string", "data"
            ])
            .reduce(
                (a, [bundleID, k]) => (
                    a[`${bundleID} as ${k}`] = ObjC.deepUnwrap(
                        k !== "data" ? (
                            pBoard[`${k}ForType`](bundleID)
                        ) : $.NSString.alloc.initWithDataEncoding(
                            pBoard.dataForType(bundleID),
                            $.NSUTF8StringEncoding
                        )
                    ),
                    a
                ), {}
            );

            return Object.keys(dict).map(
                k => [
                    `${k}:\n`,
                    dict[k]
                ]
                .join("\n")
            )
            .join("\n\n");
        }
    )($.NSPasteboard.generalPasteboard);

    // -------------- GENERIC FUNCTIONS --------------

    // cartesianProduct :: [a] -> [b] -> [[a, b]]
    const cartesianProduct = xs =>
        ys => xs.flatMap(
            x => ys.flatMap(
                y => [
                    [x, y]
                ]
            )
        );


    // MAIN ---
    return main();
})();

1 Like

I don't know that a URL is exactly what it is that I am pasting. In the Forum case, I highlight and copy the title. When I paste that into TextEdit, email, or KBM Comments, it comes in as the title text with a hotlink to the hidden URL.

I have been presuming that what's literally on the clipboard is HTML or RTF or some other "standard" link format that is then interpreted by the pasting app into its own format.

I found out more information about the format of links on the clipboard from JMichaelTX and @ccstone in:
How to Use RegEx to Extract URL and Link Text from HTML Anchor Code?
from 2015.

I see. I missed that bit.

Copying the forum title puts both plain text and HTML on the clipboard, and savvy apps will paste the HTML as an RTF link.

You can also:

  • Paste a plain-text URL into the TextEdit or a KM comment,
  • Select it,
  • Right-click and select “Make Link” from the contextual menu
  • From there you can edit the title, although that can be just a little tricky sometimes.