20

Select the following Mathematica code and paste it into a notebook. In Windows 7(Mathematica 8) the line breaks are not interpreted in the expression. In fact any data copipasted from stackexchange loses it's formatting. How do I paste content from stackexchange into Mathematica while keeping the formatting?

Print[
  "text"
]

EDIT: I don't particularly like Code Cells because they don't auto format and don't wrap when over 80 characters naturally. Another option which I had forgotten is AutoSpacing->True although I'd like to preserve line breaks and not white spaces entirely.

William
  • 7,595
  • 2
  • 22
  • 70
  • Prior question: http://mathematica.stackexchange.com/questions/29525/toboxes-respect-spaces-code – Mr.Wizard Aug 16 '13 at 23:35
  • @Mr.Wizard that's fair if you really want. The other question though I wouldn't mark as a duplicate. Formatting data in strings doesn't seem like an appropriate solution to the other issue IMO. I just wanted people to find the question if they search for formatting issues. I would mark this as duplicate http://mathematica.stackexchange.com/questions/13317/how-can-i-get-the-unchanged-box-form-of-an-arbitrary-expression/13371#13371 But not the question I asked. – William Aug 16 '13 at 23:39
  • @Mr.Wizard Modified the question. It is up for grabs if you want it ;) I think this would be valuable for users. Also I wouldn't mark this as a duplicate because your solution breaks automatic formatting and expression highlighting. – William Aug 16 '13 at 23:42
  • I'm going to reopen this question. I would encourage you to include something about making this easy to use, perhaps as a palette button, as that seems like an easier goal. Sorry for the hasty close. – Mr.Wizard Aug 16 '13 at 23:51
  • i just create a Code cell, which preserves the formatting. it'd be nice if these kinds of tricks weren't necessary though. i assume Mathematica eats the formatting primarily to delete spaces, which don't mix well with the pretty-form display – amr Aug 19 '13 at 03:11
  • 1
    @amr Yes I am not sure why M doesn't respect spaces. You mean Ctrl+Shift+E form like BoxData form yes? The funny thing is that the clipboard holds the appropriate data and M even interprets it with spaces. For example you can do NotebookGet@ClipboardNotebook[] and get the correctly formatted data. I'm not sure what is going :| – William Aug 19 '13 at 03:14
  • @Liam nah i mean right-click -> Insert New Cell -> Code – amr Aug 19 '13 at 03:28
  • 1
    @William Could you please explain why CMD+8 is not a good choice for you? This is the same as as right-click -> Insert New Cell -> Code. This type of cell preserves formatting on paste and was created for that. – Vitaliy Kaurov Feb 24 '16 at 07:57
  • 1
    @VitaliyKaurov I'm quit happy as how Mathematica works now. I don't particularly like Code Cells because they don't auto format and don't wrap when over 80 characters naturally. Another option which I had forgotten is AutoSpacing->True although I'd like to preserve line breaks and not white spaces entirely. – William Feb 25 '16 at 07:25
  • @VitaliyKaurov, do you know a shortcut for this in the linux version? Ctrl-8 does not insert a new code cell. My current workaround is to put a starting quotation mark, paste the code, then go up and remove the quotation mark. I can't get the answers below, or in the linked posts to work when I want to paste a long, formatted code block in a notebook. – Jason B. Feb 26 '16 at 10:29

2 Answers2

15

As Mr.Wizard showed me here. You use UndocumentedTestFEParserPacket to print the pasted data. For example:

FixSpacesAndLineBreaksFormatting[t_] := (StringReplace[t, {
     RegularExpression["^[ ]+$"] -> "",
     "\n" -> "\[IndentingNewLine]"}]);

CellPrint@Cell[
  Replace[
   First@FrontEndExecute@UndocumentedTestFEParserPacket[
      Catch[NotebookGet@ClipboardNotebook[]
        /. Cell[r_, ___] :> Block[{}, Throw[r, tag] /; True];
       $Failed, tag]
      , False]
   , t_String :> FixSpacesAndLineBreaksFormatting[t], Infinity]
  , "Input"]

If you want a shortcut you can run the following to assign it to Ctrl+Shift+V as described here.

FixSpacesAndLineBreaksFormatting[t_] := (StringReplace[t, {
     RegularExpression["^[ ]+$"] -> "",
     "\n" -> "\[IndentingNewLine]"}]);

FrontEndExecute[
 FrontEnd`AddMenuCommands[
  "DuplicatePreviousOutput", {Delimiter,
   MenuItem["Raw Paste Clipboard",
    FrontEnd`KernelExecute[NotebookWrite[InputNotebook[],
      Replace[
       First@FrontEndExecute@UndocumentedTestFEParserPacket[
          Catch[NotebookGet@ClipboardNotebook[]
            /. Cell[r_, ___] :> Block[{}, Throw[r, tag] /; True];
           $Failed, tag]
          , False]
       , t_String :> FixSpacesAndLineBreaksFormatting[t], Infinity]
      ]], MenuKey["v", Modifiers -> {"Control", "Shift"}],
    System`MenuEvaluator -> Automatic]}]]

Or do the add the following to KeyEventTranslations as described here. EDIT: This doesn't seem to be working currently and advised fix would be great. You can the put the AddMenuCommands in init.m as workaround.

William
  • 7,595
  • 2
  • 22
  • 70
  • Thanks a lot for sharing this. This seems to solve one of my current problems. Big +1. – Leonid Shifrin Aug 16 '13 at 23:20
  • @LeonidShifrin Yes every time I copy data from stackexchange I begin the process of reformatting and adding linbreaks, etc.. Not anymore. ;) – William Aug 16 '13 at 23:21
  • @Leonid I've been spewing UndocumentedTestFEParserPacket all over the site ever since I learned it from John Fultz. Please don't tell me this is the first time you've seen it. – Mr.Wizard Aug 16 '13 at 23:22
  • @Mr.Wizard I had seen it several times, I just never connected the dots to fix the problem. It would probably be best to modify the internal paste function so you don't have to run this everytime – William Aug 16 '13 at 23:23
  • 1
    @Mr.Wizard No, not the first time, but I did not realize before that it preserves spaces and linebreaks. I just thought that it is simply a direct parser to boxes (which it is too), which is by itself nice enough. – Leonid Shifrin Aug 16 '13 at 23:24
  • @Liam For me, it would allow me to connect to my code formatter, so that it can now also consume the string code and the spaces and line breaks will be preserved. This is nice for a number of reasons. – Leonid Shifrin Aug 16 '13 at 23:25
  • @Mr.Wizard Sorry, I did read that answer of yours, but it just did not connect for me at that time. I upvoted it too, of course. – Leonid Shifrin Aug 17 '13 at 19:02
  • @Leonid Pardon me. I was testy yesterday, and I thought Liam had taken my previous answer, without Accepting it, and posted the same question again just so he could use it as his own. Now I know he had quite a different direction in mind. – Mr.Wizard Aug 17 '13 at 19:17
  • 1
    @Liam Have you tried your code for KeyEventTranslations.tr? It gives a warning message "Serious Startup Error" when Mathematica starts (I use v. 8.0.4). – Alexey Popkov Aug 17 '13 at 22:07
  • @AlexeyPopkov I would start with this page http://web.ift.uib.no/~szhorvat/mmatricks.php to get something that I believe should work and then edit appropriately to add the formatting feature. – William Aug 17 '13 at 22:14
  • @Liam Unfortunately the updated code produces the same message. I thought that adding KernelExecute and MenuEvaluator->Automatic might help (ref) but it does not change anything too. – Alexey Popkov Aug 17 '13 at 22:27
  • 2
    @AlexeyPopkov I have to many windows open right now to want to mess with mathematica's internals but you could use this as a workaround for now http://mathematica.stackexchange.com/questions/1606/how-make-addmenucommands-work-in-an-init-m – William Aug 18 '13 at 04:12
9

As a start we can create a basic paste function using the ClipboardNotebook as follows:

pasteRaw[] :=
 NotebookGet[ClipboardNotebook[]] /.
  Notebook[{Cell[BoxData[data_] | data_, ___]}, ___] :>
   (CellPrint[Cell[BoxData[data], "Input"]];)

After copying the desired text you can evaluate pasteRaw[] to paste it as input. At present no syntax checking is done and you will get an error box if the input is invalid or incomplete.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • 1
    Do you know of anyway to force getting the string representation of data from the clipbaord instead of getting the parsed cell data from ClipboardNotebook[]? For example if you use both my code and yours extra spaces are added to the BoxData which wouldn't occur if you used UndocumentedTestFEParserPacket[str], False] – William Aug 25 '13 at 03:18
  • @Liam I'll have to think about that; perhaps after the weekend. – Mr.Wizard Aug 25 '13 at 03:22
  • Figured out why Mathematica kept adding the additional spaces. I wasn't really aware of the differences between IndentingNewLine and \n and how it modified the the spaces and other outputs. Again thanks for the help with UndocumentedTestFEParserPacket. – William Oct 18 '14 at 08:54
  • @Liam Sorry that I never returned to this, but I am glad you solved your own problem. – Mr.Wizard Oct 18 '14 at 17:31