From: István Zachar on
Dear Group,

is there any programmatical way to push an expression to the
clipboard? I would like to have a button which sends a variable to the
clipboard without opening a new notebook, or without selecting
anything, much like this hypothetical code would do:

var = "this text has been copied"
Button["Copy to clipboard", copy[var]]

Of course the question is what to write in place of the copy function.
Any idea?

Istvan

From: telefunkenvf14 on
On Jun 5, 6:31 am, Istv=E1n Zachar <z...(a)freemail.hu> wrote:
> Dear Group,
>
> is there any programmatical way to push an expression to the
> clipboard? I would like to have a button which sends a variable to the
> clipboard without opening a new notebook, or without selecting
> anything, much like this hypothetical code would do:
>
> var = "this text has been copied"
> Button["Copy to clipboard", copy[var]]
>
> Of course the question is what to write in place of the copy function.
> Any idea?
>
> Istvan

A Google search leads back to an old post in MathGroup that may help.
Here's the URL:

http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread=
/thread/24ff8cd2d9d1193a/89cb5f216f9daa00?hl=en&lnk=gst&q=A+simple+ho=
rizontal+palette+with+two+buttons%3A#89cb5f216f9daa00

The particular code that I thought *might* be similar to what you're
looking for:

ButtonBox["Test4",
ButtonFunction:>
NotebookPut@
Notebook[{Cell[BoxData[GridBox[{{ButtonBox["1"],ButtonBox["2"]}}]]]},
WindowSize->{Fit,Fit},WindowElements->{},
ShowCellBracket->False,WindowFrame->"Palette",
WindowClickSelect->False,
CellMargins->{{0,0},{0,0}},
WindowFrameElements->"CloseBox",
GridBoxOptions->{ColumnSpacings->0,RowSpacings->0}],
ButtonEvaluator->None,
Active->True]//DisplayForm

....although, after re-reading your post, it sounds like what you're
wanting to do would involve a FrontEndToken. IMO, the documentation is
not very helpful (i.e., no 'real' example uses, just tells you that a
typical use is: FrontEndExecute[FrontEndToken["Copy"]])

Hmmm... I think it would be really cool to make a function,
initialized when Mathematica starts up, that would dynamically copy to the
clipboard whatever you select in the current notebook. Perhaps one
could even configure the function with several temp storage variables,
so that, for example, Ctrl+p pasted the most recently highlighted bit
and, say, Ctrl+p+1 would paste the next previous selection, and so
on.

Come to think of it, maybe a dynamically generated pallette with
buttons showing an abbreviated version of the n different clipboard
variables would be useful. The function PasteButton comes to mind...
Also, I *believe* (just a hunch) such a feature could be evaluated
using only the front end, avoiding potential variable collisions in
the Global' context.

Get to coding! :)

-RG


From: István Zachar on
Yes, I'm aware of the method you suggested below, but since it does
not satisfy my needs, I've come to the very same conclusion: a
FrontEndToken must be used. Although I have no idea how to do that.
What I know is that I don't want to manually select anything, just
send the value of any named variable in memory to the clipboard. So no
manual selection, no extra notebook appearing, not any visual feedback
on the process. Actually ths functionality seems so obvious I wonder
why there isn't any established method to cover it.
i


>
> A Google search leads back to an old post in MathGroup that may help.
> Here's the URL:
>
> http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_...
> rizontal+palette+with+two+buttons%3A#89cb5f216f9daa00
>
> The particular code that I thought *might* be similar to what you're
> looking for:
>
> ButtonBox["Test4",
> ButtonFunction:>
> NotebookPut@
> Notebook[{Cell[BoxData[GridBox[{{ButtonBox["1"],ButtonBox["2"]}}]]]},
> WindowSize->{Fit,Fit},WindowElements->{},
> ShowCellBracket->False,WindowFrame->"Palette",
> WindowClickSelect->False,
> CellMargins->{{0,0},{0,0}},
> WindowFrameElements->"CloseBox",
> GridBoxOptions->{ColumnSpacings->0,RowSpacings->0}],
> ButtonEvaluator->None,
> Active->True]//DisplayForm
>
> ...although, after re-reading your post, it sounds like what you're
> wanting to do would involve a FrontEndToken. IMO, the documentation is
> not very helpful (i.e., no 'real' example uses, just tells you that a
> typical use is: FrontEndExecute[FrontEndToken["Copy"]])
>
> Hmmm... I think it would be really cool to make a function,
> initialized when Mathematica starts up, that would dynamically copy to the
> clipboard whatever you select in the current notebook. Perhaps one
> could even configure the function with several temp storage variables,
> so that, for example, Ctrl+p pasted the most recently highlighted bit
> and, say, Ctrl+p+1 would paste the next previous selection, and so
> on.
>
> Come to think of it, maybe a dynamically generated pallette with
> buttons showing an abbreviated version of the n different clipboard
> variables would be useful. The function PasteButton comes to mind...
> Also, I *believe* (just a hunch) such a feature could be evaluated
> using only the front end, avoiding potential variable collisions in
> the Global' context.
>
> Get to coding! :)
>
> -RG


From: magma on
On Jun 5, 1:31 pm, Istv=E1n Zachar <z...(a)freemail.hu> wrote:
> Dear Group,
>
> is there any programmatical way to push an expression to the
> clipboard? I would like to have a button which sends a variable to the
> clipboard without opening a new notebook, or without selecting
> anything, much like this hypothetical code would do:
>
> var = "this text has been copied"
> Button["Copy to clipboard", copy[var]]
>
> Of course the question is what to write in place of the copy function.
> Any idea?
>
> Istvan

The clipboard is meant to be used for things that have been selected
(manually or programmatically) from some place (in Mathematica: a notebook).
Any other unconventional use would not adhere to the standard GUI
conventions (tautologically) and probably reflects a not very well
thought out interface.

In practice: ask yourself why do you want to copy a variable (I
suppose you mean the value of a variable) to the clipboard? To paste
it somewhere else I bet. OK, where to?
1- If it is another notebook, than you do not need the clip, just type
the variable in the other notebook.
2- If it is another place in another program (Word, email,ect), just
select what you want , type ctrl-C and than paste it in the other
program.
3- If you get tired to type ctrl-C you can make a button which copies
to the clip the current selection. But also in this case you need to
have something selected, so that the operation makes sense.
4- You may also consider Saving/Exporting your variable in a specific
format ,so it can be read into another program.

So, you see, you only need the clip in case number 2 and 3. In these
cases you need to select something which has been already calculated
and is displayed on a notebook. The selection can be done
programmatically, maybe using cell tags, but one way or the other you
must select something.
There is no direct way to place an expression on the clip, as far as I
know.
Of course, what you can always do, is a button which creates a
temporary nb, places your variable there, selects it and copies it,
than erases the nb. Perhaps the temporay nb could be more or less
invisible (I am not sure about this).

From: Derek Yates on
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(a)Transpose,
Automatic, (If[Length[#[[1]]] > 50 && Length[#[[1]]] > Length[#],
Transpose[#], #] &),
True, Transpose,
_, (# &)
],
cellstyle = OptionValue(a)Style,
celloptions = Sequence[ShowCellBracket -> False]
},
NotebookWrite[nb,
Replace[expr, {
Except[_Cell | {__Cell}] :>
Cell[BoxData(a)ToBoxes[
Switch[{OptionValue(a)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(a)CopyAs]];
NotebookClose[nb]
]

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

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