In MS Word (I'm using MS Word 16.83 for Mac that's part of my Microsoft 365 subscription), in order to paste "unformatted text", you need to select the menu Edit->Paste Special, which opens a dialog box with several options. You choose the "Unformatted Text" option and click OK, which then pastes the source text without any of the source formatting. Is there any way to automate this operation so that I can use a key combination as a shortcut? Thanks for any hints or clue.
You can, albeit with some GUI activity showing up (i.e. there's no way to do it without seeing the dialog box). Here's how I do it in Excel:
-rob.
A simpler approach, bypassing all the GUI widgetry, may just be to rewrite the clipboard before the paste event.
( Overwriting any public.html
or public.rtf
etc pasteboard items with the
public.utf8-plain-text
pasteboard item which will typically also be in the clipboard )
Paste as plain text.kmmacros (6.4 KB)
Expand disclosure triangle to view JS source
return (() => {
"use strict";
// Recopy any plain UTF8 in the clipboard,
// dropping other formats.
ObjC.import("AppKit");
const main = () =>
either(
alert("Reduce clipboard to plain text only")
)(
message => message
)(
fmapLR(copyText)(
clipTextLR()
)
);
// ----------------------- JXA -----------------------
// alert :: String => String -> IO String
const alert = title =>
s => {
const sa = Object.assign(
Application("System Events"), {
includeStandardAdditions: true
});
return (
sa.activate(),
sa.displayDialog(s, {
withTitle: title,
buttons: ["OK"],
defaultButton: "OK"
}),
s
);
};
// clipTextLR :: () -> Either String String
const clipTextLR = () => {
// Either a message, or the plain text
// content of the clipboard.
const
v = ObjC.unwrap(
$.NSPasteboard.generalPasteboard
.stringForType($.NSPasteboardTypeString)
);
return Boolean(v) && 0 < v.length
? Right(v)
: Left("No utf8-plain-text found in clipboard.");
};
// copyText :: String -> IO String
const copyText = s => {
// ObjC.import("AppKit");
const pb = $.NSPasteboard.generalPasteboard;
return (
pb.clearContents,
pb.setStringForType(
$(s),
$.NSPasteboardTypeString
),
s
);
};
// --------------------- GENERIC ---------------------
// Left :: a -> Either a b
const Left = x => ({
type: "Either",
Left: x
});
// Right :: b -> Either a b
const Right = x => ({
type: "Either",
Right: x
});
// either :: (a -> c) -> (b -> c) -> Either a b -> c
const either = fl =>
// Application of the function fl to the
// contents of any Left value in e, or
// the application of fr to its Right value.
fr => e => "Left" in e
? fl(e.Left)
: fr(e.Right);
// fmapLR (<$>) :: (b -> c) -> Either a b -> Either a c
const fmapLR = f =>
// Either f mapped into the contents of any Right
// value in e, or e unchanged if is a Left value.
e => "Left" in e
? e
: Right(f(e.Right));
// MAIN()
return main();
})();
Doesn't the built-in Clipboard filter action do this without needing to script anything, or does it miss some edge cases that the script handles?
Filter Action (v11.0.2)
Have you tried using KM's Clipboard History Switcher? It's not just a store of previous copy ops -- very useful in all kinds of situations -- you can also "Paste Plain" from either the entry's cogwheel or by shift-clicking the Paste icon.
I always forget about Filters -- thanks, @rolian! -- so my more basic version of a macro was
In fact you can paste whatever is in the Clipboard as plain text with a single Keyboard Maestro Action:
This works because the Token %SystemClipboard% only holds the text of the current clipboard - it doesn't hold any formatting of that text.
Rich harvest ...
@roosterboy's (tell MSWord to paste special) seems like the most direct solution of the original problem.
and the
%SystemClipboard%
Filter Clipboard with Remove Styles
have the appeal of being very generally usable, and raise an eyebrow at the hubris of my suggestion that JS might provide a "simpler approach"
If I reflect on why my ⌘⇧V uses JS, I think that (apart from blind force of habit) it's mainly for slightly finer control of white space.
( Code samples sometimes turn out to use tabs, and I generally want to paste those tabs as four spaces, but you can of course, easily apply a tabs -> spaces
search and replace to the clipboard with the help of a Keyboard Maestro action, so my defence of habitual JS looks shaky )
TMTOWTDI...
And, as usual, they'll probably all give slightly different results -- for example, the KM "plain text clipboard" approach leaves in a funky character if the copied piece includes an image while Word's "Paste as plain text" converts that to a space. You can get some different line-break handling, too.
It won't be the fastest, but I think you're right -- @roosterboy's AppleScript is probably the best method, in that is the most faithful reproduction of doing this via Word's GUI.
Thanks all, Nige_S's solution works great for me.
The solution I would use is to call the Paste Special (cmd+cntrl+v) then add two keypresses of "u" to find the "Unformatted Text" option. Then Return. I assigned a keypress of cntrl+u and it worked perfectly.
Paste Special Unformatted Text.kmmacros (3.3 KB)
I need to remove formatting quite a bit in MS applications and I just type Command-Shift-V. Would emulating that key combination work?
Keyboard Maestro had replaced Command-Shift-V with the clipboard switcher. When I disabled that, Command-Shift-V does do what I was looking for. Thanks!