Here's a method that's really no different from the standard ones except it's generalized for copying cells and, theoretically, for Windows and Unix.
We'll use RunProcess because this exists now, and tweak the ProcessEnvironment to make it work for Mac:
FrontEnd`unicodeCopy[s_String,
enc : _String | Automatic : Automatic,
lang : _String | Automatic : Automatic
] :=
With[{
encoding = Replace[enc, Automatic :> $CharacterEncoding],
language = Replace[lang, Automatic :> $Language]
},
If[#["ExitCode"] =!= 0,
FrontEnd`unicodeCopy::copyerr = "error in copy process:\n ``";
Message[FrontEnd`unicodeCopy::copyerr, #["StandardError"]];,
#["StandardOuput"];
] &@
RunProcess[
Switch[$OperatingSystem,
"Windows",
"clip",
"MacOSX",
"pbcopy",
"Unix",
{"xsel", "-b"}
],
All,
ExportString[s,
"String",
CharacterEncoding -> encoding
],
ProcessEnvironment -> <|
"LANG" ->
Replace[ToLowerCase@language,
"english" -> "en_US"
] <> "." <>
Replace[encoding, {
"UTF8" -> "UTF-8",
"Unicode" -> "UTF-16"
}],
"PATH" -> Environment["PATH"]
|>
]
];
(I'm using FrontEnd` for when I dump to "MenuSetup.tr", just so it looks consistent)
Now we'll define a bunch of junk to generalize to make it work across an NB:
$unicodeTR =
FrontEnd`FindFileOnPath["UnicodeCharacters.tr",
"PrivatePathsTextResources"] // FrontEndExecute;
$unicodeReplacements = #[[2]] ->
ToExpression[
"\"" <> StringReplace[#[[1]], {"x" -> ":",
StartOfString ~~ "0" -> "\\"}] <> "\""] & /@
Rest[
StringSplit@StringSplit[Import[$unicodeTR, "String"], "\n"]
];
FrontEnd`UnicodeCopy[c : {__Cell}] :=
Replace[
MathLink`CallFrontEnd[
ExportPacket[Cell[CellGroupData[c]], "InputText"]
], {
{s_String, __} :>
FrontEnd`unicodeCopy@
StringReplace[s,$unicodeReplacements]
}];
FrontEnd`UnicodeCopy[c_Cell] :=
Replace[
MathLink`CallFrontEnd[
ExportPacket[c, "InputText"]
], {
{s_String, __} :>
FrontEnd`unicodeCopy@
StringReplace[s,$unicodeReplacements]
}];
FrontEnd`UnicodeCopy[b_BoxData | _TextData] :=
FrontEnd`UnicodeCopy@Cell[b];
FrontEnd`UnicodeCopy[b_RowBox] :=
FrontEnd`UnicodeCopy@Cell[BoxData@b];
FrontEnd`UnicodeCopy[
nb : _NotebookObject | _FrontEnd`NotebookObject | \
_FrontEnd`SelectedNotebook | _FrontEnd`InputNotebook | \
_FrontEnd`ButtonNotebook | _FrontEnd`EvaluationNotebook | \
_FrontEnd`MessagesNotebook | _FrontEnd`HelpBrowserNotebook | \
_FrontEnd`ClipboardNotebook
] :=
FrontEnd`UnicodeCopy[Evaluate@NotebookRead@nb];
FrontEnd`UnicodeCopy[
nb : _InputNotebook | _EvaluationNotebook | _ClipboardNotebook | \
_ButtonNotebook | _MessagesNotebook | _HelpBrowserNotebook] :=
FrontEnd`UnicodeCopy@Evaluate@nb;
FrontEnd`UnicodeCopy[Optional[Automatic, Automatic]] :=
FrontEnd`UnicodeCopy@InputNotebook[];
FrontEnd`UnicodeCopy[s_String] :=
FrontEnd`unicodeCopy[s];
FrontEnd`UnicodeCopy[e_] :=
FrontEnd`UnicodeCopy[Evaluate@ToString[Unevaluated[e], InputForm]];
FrontEnd`UnicodeCopy~SetAttributes~HoldFirst
Then I'll add this to my MenuSetup using the framework I wrote up here and whose up-to-date implementation lives here
FEMenuSetupAdd[
{"Edit", "Copy As", 5},
"Unicode" -> KernelExecute[ToExpression["FrontEnd`UnicodeCopy[]"]],
MenuEvaluator -> Automatic,
System`MenuKey["C", System`Modifiers -> {"Control"}]
]
This now lives under the "Copy As" menu:

And it can be used by function:
FrontEnd`UnicodeCopy["asdasd\[Alpha]\[Beta]\[Gamma]"]
asdasdαβγ
FrontEnd`UnicodeCopy[Cell["asdasd\[Alpha]\[Beta]\[Gamma]"]]
asdasdαβγ
Or by Control-C:
FrontEnd`UnicodeCopy[Cell["asdasdαβγ"]]
(fixed, now, by doing a more selective replacement from UnicodeCharacters.tr)
One issue here is that I was a bit over zealous with some replacements when copying from cells and boxes (has to do with what comes out of the ExportPacket):
(Command-C): "asdasd\\[Alpha]\\[Beta]\\[Gamma]"
(Control-C): "asdasd\α\β\γ"
And just to include the original example:
\[Alpha]\[Beta] +
Mod[\[Delta]\[CapitalPsi], 2\[InvisibleTimes]\[Rho]^2]
becomes:
αβ +
Mod[δΨ, 2ρ^2]
(note how, unfortunately, the added spacing from the cell copy is preserved)
CopyToClipboardfunction, but it doesn't seem to work, at least on Linux. – Mechanical snail May 21 '13 at 01:46Plot[\[Alpha], {\[Alpha], 0, 10}]orCell[BoxData["\<\"Plot[\\\\[Alpha], {\\\\[Alpha], 0, 10}]\"\>"], "Output"}]to Unicode Form? Because I use one function something likeInputCell2SE@cellExpression//CopyToClipboardcopy InputCell to SE which turns outPlot[\[Alpha], {\[Alpha], 0, 10}], and I used FrontEnd..."InputText" – HyperGroups Jun 19 '13 at 15:08pbcopy(similar toclip, I think). But I would say that a more modular design would be to letcopyUnicodeonly acceptStringin the first place, and leave it to the calling function to provide the string. I.e., I wouldn't need to useHoldFirstoncopyUnicodeitself then. Anyway, it depends on how it's going to be used. Should I try to write a combined version of our Mac/PC solutions? – Jens Jun 19 '13 at 19:36RunProcess["clip", All, ExportString["αβ + Mod[δΨ, 2 ρ^2]", "Text", CharacterEncoding -> "Unicode"]]– Stephen Powell Oct 07 '21 at 09:44