MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Push to clipboard?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg110202] Re: Push to clipboard?
  • From: Derek Yates <yatesd at mac.com>
  • Date: Tue, 8 Jun 2010 07:06:59 -0400 (EDT)
  • References: <hudcjc$d7g$1@smc.vnet.net>

Hi Istvan,

I have also wanted to do what you wish to. magma suggested in a post
to just copy and paste, however, I frequently need to export data to
Excel. Unfortunately, copy and paste does not work well for this, and
doing this via a file is very time-consuming. The only way I found to
copy and paste a matrix properly to Excel was the following:
Print[Grid[matrix]]. Then select the printed output as Plain Text and
then paste it in Excel. After doing this a few times, I decided to
write some code and attach it to a button. You asked for code that
does not open up a new notebook. I could not find a way to do that
(other than writing into the existing notebook). So I open a hidden
notebook, paste the expression there, copy it (via a FrontEnd Token)
and then close the notebook. I doubt there is a way for the kernel to
access the clipboard directly (it could after all be running remotely,
so it would need to ask the front-end to do the work in any case).

I attach a slightly simplified (and untested) version of my code
below. It consists of two functions. One to attach to the button,
which evaluates and then sends whatever is selected to the main
function which does the copying. You may well want to simplify the
functions and change them for your own purposes. There are two things
that I do not know how to fix: (1) for large matrices, the function is
slow. (2) if you use CellContext to localise notebooks, then the code
may not always work. I have caught some of the cases (like having a
Notebook option that changes the CellContext, but do not cater for
styles or individual cells that have set the CellContext.

The codes works for expressions which are not matrices too, but does
extra processing when you pass it a matrix or vector (assuming you set
option Format->True).

Regards,

Derek

CopyAs::usage =
  "Option for ClibboardCopy. Possible values are \"PlainText\", \
\"InputText\", \"CopyAsTeX\", \"MathML\", \"CellExpression\", \
\"NotebookExpression\", \"MGF\", \"EMF\", \"WAV\"";

Options[ClipboardCopy] = {CopyAs -> "PlainText",
   Transpose -> Automatic, Style -> "Output", Format -> False};
ClipboardCopy::usage =
  "ClipboardCopy[expression] will evaluate expression and place it on
\
the clipboard in the format specified by the option CopyAs. Works \
well for pasting vectors and matrices to Excel if you use CopyAs\
\[ThinSpace]\[Rule]\[ThinSpace]\"PlainText\" and Format\[ThinSpace]\
\[Rule]\[ThinSpace]True";

ClipboardCopy[expr_, opts : OptionsPattern[]] :=
 With[{
   nb = CreateDocument[Null, Visible -> False,
     WindowSelected -> True,
     FilterRules[Flatten[{opts, Options[ClipboardCopy]}],
      Options[CreateDocument]]
     ],
   rules = {
     n_Real :>
      NumberForm[n, DigitBlock -> \[Infinity],
       ExponentFunction -> (Null &)],
     \[CenterEllipsis] -> "..."
     },
   transposefunc = Switch[OptionValue@Transpose,
     Automatic, (If[Length[#[[1]]] > 50 && Length[#[[1]]] > Length[#],
         Transpose[#], #] &),
     True, Transpose,
     _, (# &)
     ],
   cellstyle = OptionValue@Style,
   celloptions = Sequence[ShowCellBracket -> False]
   },
  NotebookWrite[nb,
   Replace[expr, {
     Except[_Cell | {__Cell}] :>
      Cell[BoxData@ToBoxes[
         Switch[{OptionValue@Format, expr},
          {True, _?MatrixQ}, Grid[transposefunc[expr /. rules]],
          {True, _?VectorQ}, Grid[transposefunc[{expr} /. rules]],
          {True, {{__?AtomQ} ..}},
          Grid[transposefunc[
            PadRight[expr /. rules, Automatic, ""]]],
          _, ExpressionCell[expr]
          ]
         ], cellstyle, celloptions],
     cell_Cell :> Append[cell, celloptions],
     celllist : {__Cell} :> (Append[#, celloptions] &) /@ celllist
     }], All];
  FrontEndExecute[
   FrontEndToken[nb, "CopySpecial", OptionValue@CopyAs]];
  NotebookClose[nb]
  ]

ClipboardPalette::usage = "ClipboardPalette[] creates a palette with \
a button which will ClipboardCopy the selection."

ClipboardPalette[] :=
 (CreatePalette[
    With[{prefunc =
       Quiet@Check[ToExpression[#], #, ToExpression::notstrbox] &},
     DynamicModule[{transposesetting},
      Row[{
        Row[{"Transpose: ",
          SetterBar[
           Dynamic[transposesetting], {Automatic, True, False}]}],
        Button["Copy for Excel",
         ClipboardCopy[
          Replace[prefunc[NotebookRead@InputNotebook[]],
           Grid[x_, ___] :> x], CopyAs -> "PlainText",
          Transpose -> transposesetting, Format -> True]],
        Button["Copy as Bitmap",
         ClipboardCopy[prefunc[NotebookRead@InputNotebook[]],
          CopyAs -> "MGF", Transpose -> transposesetting,
          Format -> False]],
        Button["Copy as Metafile",
         ClipboardCopy[prefunc[NotebookRead@InputNotebook[]],
          CopyAs -> "EMF", Transpose -> transposesetting,
          Format -> False]]
        }]
      ]
     ], WindowTitle -> None, Saveable -> False,
    CellContext :>
     Dynamic[OptionValue[Options[InputNotebook[], CellContext],
       CellContext]]
    ];)





  • Prev by Date: Re: Push to clipboard?
  • Next by Date: name this algorithm please
  • Previous by thread: Re: Push to clipboard?
  • Next by thread: Re: Push to clipboard?