Skip to main content
added 297 characters in body
Source Link
b3m2a1
  • 47.1k
  • 3
  • 95
  • 244
FrontEnd`UnicodeCopy[c : {__Cell}]$unicodeTR =
  FrontEnd`FindFileOnPath["UnicodeCharacters.tr", 
    "PrivatePathsTextResources"] // FrontEndExecute;
$unicodeReplacements :=
  Replace[
 #[[2]] -> MathLink`CallFrontEnd[
    ExportPacket[Cell[CellGroupData[c]], "InputText"]ToExpression[
    ], {
  "\"" <> {s_StringStringReplace[#[[1]], __}{"x" :->
     FrontEnd`unicodeCopy@
      StringReplace[s":",
    
    char : ("\\[" ~~ WordCharacter ..StartOfString ~~ "]")"0" :->
     "\\"}] <> "\""] ToExpression["\""& <>/@
 char <> "\""]Rest[
     StringSplit@StringSplit[Import[$unicodeTR, "String"], ]"\n"]
    }];
FrontEnd`UnicodeCopy[c_Cell]
FrontEnd`UnicodeCopy[c : {__Cell}] :=
  Replace[
   MathLink`CallFrontEnd[
    ExportPacket[cExportPacket[Cell[CellGroupData[c]], "InputText"]
    ], {
    {s_String, __} :>
     FrontEnd`unicodeCopy@
      StringReplace[s,$unicodeReplacements]
    }];
FrontEnd`UnicodeCopy[c_Cell] :=
  charReplace[
 : ("\\[" ~~MathLink`CallFrontEnd[
 WordCharacter .. ~~ "]")ExportPacket[c, :>"InputText"]
     ], {
  ToExpression["\"" <> char{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

(fixed, now, by doing a more selective replacement from UnicodeCharacters.tr)

FrontEnd`UnicodeCopy[c : {__Cell}] :=
  Replace[
   MathLink`CallFrontEnd[
    ExportPacket[Cell[CellGroupData[c]], "InputText"]
    ], {
    {s_String, __} :>
     FrontEnd`unicodeCopy@
      StringReplace[s,
       char : ("\\[" ~~ WordCharacter .. ~~ "]") :>
        ToExpression["\"" <> char <> "\""]
       ]
    }];
FrontEnd`UnicodeCopy[c_Cell] :=
  Replace[
   MathLink`CallFrontEnd[
    ExportPacket[c, "InputText"]
    ], {
    {s_String, __} :>
     FrontEnd`unicodeCopy@
      StringReplace[s,
       char : ("\\[" ~~ WordCharacter .. ~~ "]") :>
        ToExpression["\"" <> char <> "\""]
       ]
    }];
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
$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

(fixed, now, by doing a more selective replacement from UnicodeCharacters.tr)

added 264 characters in body
Source Link
b3m2a1
  • 47.1k
  • 3
  • 95
  • 244

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)

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)

Source Link
b3m2a1
  • 47.1k
  • 3
  • 95
  • 244

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:

FrontEnd`UnicodeCopy[c : {__Cell}] :=
  Replace[
   MathLink`CallFrontEnd[
    ExportPacket[Cell[CellGroupData[c]], "InputText"]
    ], {
    {s_String, __} :>
     FrontEnd`unicodeCopy@
      StringReplace[s,
       char : ("\\[" ~~ WordCharacter .. ~~ "]") :>
        ToExpression["\"" <> char <> "\""]
       ]
    }];
FrontEnd`UnicodeCopy[c_Cell] :=
  Replace[
   MathLink`CallFrontEnd[
    ExportPacket[c, "InputText"]
    ], {
    {s_String, __} :>
     FrontEnd`unicodeCopy@
      StringReplace[s,
       char : ("\\[" ~~ WordCharacter .. ~~ "]") :>
        ToExpression["\"" <> char <> "\""]
       ]
    }];
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:

copy as

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αβγ"]]

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\α\β\γ"