Re: Push to clipboard?
- To: mathgroup at smc.vnet.net
- Subject: [mg110234] Re: Push to clipboard?
- From: István Zachar <zac at freemail.hu>
- Date: Thu, 10 Jun 2010 08:05:54 -0400 (EDT)
- References: <hudcjc$d7g$1@smc.vnet.net> <hul88a$ibi$1@smc.vnet.net>
Dear Derek (and all), thanks for the code, I managed to streamline it to my taste and aim: CopyToClipboard[expr_] := Module[{nb}, nb = CreateDocument[Null, Visible -> False, WindowSelected -> True]; NotebookWrite[nb, Cell[ToBoxes@expr, "Output"], All]; FrontEndExecute[FrontEndToken[nb, "CopySpecial"]]; NotebookClose@nb ]; I was unaware of the fact that I can call for invisible notebooks. Now this function does the copying without any obtrusive notebook appearing onscreen. I got rid of all the options and wrappers, but surely with time I will expand this code to cover the functionality you encoded in it! Thanks again, Istvan On Jun 8, 1:06 pm, Derek Yates <yat... at mac.com> wrote: > 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]] > ];)