# Programmatically copy code so that all output is commented out

UPDATE: The final palette has a new home here! Please test and provide feedback (usability, suggestions, bugs)

A note to the readers and voters: This is intended for community use, so please test the palettes in practice! I encourage all answerers to "steal" from each others, and come up with a solution that is the most pleasant / practical to use.

Sjoerd suggested that when we want to post input lines that alternate with output lines, instead of including the In/Out labels, we could simply comment out the output.

Read his suggestion here:

I have seen several people use this style in the past few days. The only problem with it that it requires a lot of manual editing (too much work for my taste).

How can we automate this process?

The challenge is:

Create a palette button that will copy the selection in the format suggested by Sjoerd. Two-dimensional expressions (i.e. things like $\int x^2 \; dx$) should be converted to plain text or input form. The notebook contents must not be modified/destroyed.

An example (directly copied from Sjoerd's post):

In[108]:= D[Cos[x] Exp[x], x]
Out[108]= E^x Cos[x] - E^x Sin[x]


should be copied as

D[Cos[x] Exp[x], x]

(*
===> E^x Cos[x] - E^x Sin[x]
*)


Let us ignore cells that are neither input nor output for now (text, headings, etc.)

Can we create a tool that is good enough to be of practical use to the community?

-
I could take this sometime next week, but I don't have time right now... I believe this could become something that many of us will use regularly. –  Szabolcs Jan 22 '12 at 16:17
We could make a SE palette, that includes this, the image uploader and any other useful tools. One thing I'd like in this code (and is trivial to add to the answers below) is to automatically rewrite \[Pi] as Pi and \[Infinity] as Infinity etc... –  Simon Jan 22 '12 at 23:11
How well accepted is the ===> standard for denoting output becoming? I used it for the first time in an answer recently, and somebody quite quickly edited my answer to remove it, and simply leave the output in comments. –  John Fultz Jun 10 '12 at 8:48
@JohnFultz I am not sure who came up with this notation first, but I'd say it's pretty common. I use it often. There isn't really a "recommended" or "standard" way. Some out In/Out (inconvenient to copy), some use comments, maybe with ==>, and some just use a quotation block (again, inconvenient to copy, and personally I don't like it if it's not in a fixed width font). Don't be discouraged from using that notation if you like it. –  Szabolcs Jun 11 '12 at 15:53

This is inspired by Rolfs answer, but uses the "Copy As Input" functionality as the starting point. My impression is that using that approach will keep more of the original formatting (concerning linebreaks) but it still isn't perfect in that concern. To see the problems, I didn't change what it does to the its own code (it added some empty lines).

Other differences are that it will look at the current selection instead of using all the content of the selected notebook. And it adds the spaces at the begining of each line so it will directly be recognized as code when pasted into the edit window.

It can't handle correctly anything except input and output cells that have an In/Out tag, otherwise the splitting in input and output cells will not work (although I think it will create something that's not completely useless in those cases...).

CreatePalette[
Tooltip[
Button[
"Copy for MSE",
FrontEndTokenExecute[SelectedNotebook[], "CopySpecial",
"InputText"];
Map[
CreateDocument[TextCell[#, "Text", FontFamily -> "Courier"]] &,
Cases[
NotebookGet[ClipboardNotebook[]],
Cell[c_String, ___] :> "    " <> StringReplace[
StringJoin[Riffle[
StringReplace[

StringTrim[
StringSplit[
c, ("In" | "Out") ~~ "[" ~~ DigitCharacter .. ~~ "]"]], {

StartOfString ~~ ":=" ~~ WhitespaceCharacter ~~ input__ :>
input,

StartOfString ~~ "=" ~~ WhitespaceCharacter ~~ output__ :>
"(*\n==> " <> output <> "\n*)"
}
],
"\n\n"
]],
"\n" -> "\n    "
],
Infinity
]
],
Method -> "Queued"
],
"Copy formatted for use in MSE"
],
Saveable -> False
]

-
I think you should set Saveable->False on that Palette, otherwise it will ask you if you want to save it when you close it. –  celtschk Jan 23 '12 at 17:02
@celtschk Ideally one does save the palette: check the Palettes -> Install Palette... menu item. Then you won't need to re-evaluate this every time you need the palette. Personally I prefer using PaletteNotebook instead of CreateDocument (try it and you'll see why ;) –  Szabolcs Jan 26 '12 at 18:45
Albert, is there any reason you are using Method -> "Queued"? It would be ideal if this could work even while an evaluation is running. –  Szabolcs Jan 26 '12 at 18:58
Albert, I made some cosmetic changes to the palette, and put it in a meta post. Please review it and feel free to edit it, or suggest more changes. –  Szabolcs Jan 26 '12 at 19:15
@Szabolcs: I thought it would be safer to use Method "Queued" in case it would take long. I think for all relevant cases that shouldn't be the case, so I don't think it makes a difference... –  Albert Retey Jan 27 '12 at 0:23

Copied from applying the palette on its own source code (kind of self-referential button -:) ):

CreatePalette[
{"Copy In/Out as String",
Button["Select Notebook and click",
(SelectionMove[CreateDocument[#1], All, Notebook] & )
[StringJoin @@
Riffle[
Select[
Partition[
Cases[
NotebookGet[SelectedNotebook[]],
Cell[_, "Input", ___] | Cell[_, "Output", ___], -1
], 2
],
MatchQ[#1, {Cell[_, "Input", ___], Cell[_, "Output", ___]}] &
] /.
{Cell[a_, "Input", ___], Cell[b_, "Output", ___]} :>
StringJoin[
(StringJoin[
(StringTake[#1, {6, -2}] &)
[ToString[InputForm[ToExpression[a, StandardForm,Hold]]]],
"\n\n(*\n==> ", StringTake[#1, {6, -2}]] &
)[ToString[
InputForm[ToExpression[ b, StandardForm, Hold] ]
]
],
"\n*)\n"
],
"\n"]]]}]

(*
==> NotebookObject[FrontEndObject[LinkObject["jtc_shm", 1, 1]], 48]
*)

-
Nice one Rolf. Pretty complicated to read too. I did some formatting (pending review) but still pretty difficult too grasp. BTW You loose any formatting you had with this method. (I now realize that by formatting your code I have obfuscated that particular problem ;-( ) Any idea how to improve that? –  Sjoerd C. de Vries Jan 22 '12 at 18:36
I have an idea how to get the formatting right, but I do not know how to do it: The nicest formatting of InputForm code you get in Eclipse (with Wolfram Workbench plugin) by selecting the code, right click / Source / Format Now, if Eclipse would be part of Mathematica - as I unsuccessfully tried to convince some high-level-person at WRI last year - then it would be easier probably. Maybe someone else has an idea how to get InputForm formatted nicely for the purpose of SO/SE. JavaScript? Java? –  Rolf Mertig Jan 23 '12 at 1:41
And just using on the InputForm expression in a Cell[BoxData[" ..."],"Input"] cell the FrontEndToken Convert To / InputForm might be an idea, but the last time I tried to do something like this programmatically it did not work well (for larger notebooks). –  Rolf Mertig Jan 23 '12 at 1:46
@RolfMertig: would you see the problems you have seen for large notebooks relevant for this very application? I don't think it will make sense to convert large notebooks and send them to MSE -- at least I hope I'll never see such a post :-) –  Albert Retey Jan 23 '12 at 10:54
Again @RolfMertig: I like your idea to use the existing functionallity in workbench for the formatting. I think it would be an additional advantage that it would produce a standard formatting compared to just conserve the posters habits. If it can be done I don't think it would be a big problem if one had to install the workbench to use the functionality. –  Albert Retey Jan 23 '12 at 10:59