ToBoxes Respect Spaces Code

Is there a way to force either ToBoxes or MakeBoxes to respect the spacing that occurs in the code?

For example is there a way to force the following to print the code like so.

CellPrint@Cell[
BoxData@MakeBoxes[
f[
y
]
], "Input"]


would output

f[
y
]

-
The argument of MakeBoxes (or ToBoxes) is a Mathematica expression. At the parsed expression level, spaces don't exist any more, having been either ignored or interpreted as multiplication by the parser, when the code was parsed (which, of course, happens at an earlier stage). Therefore, the general answer, AFAICT, is no, unless you provide an alternative parser, that would preserve the information about the spaces, and the appropriately modified MakeBoxes function. –  Leonid Shifrin Jul 31 '13 at 1:49
@LeonidShifrin Then what technique would you advise instead? –  William Jul 31 '13 at 1:50
I don't really know, this depends on what exactly you want to achieve. If it is some kind of code formatting, you have to specify your formatting rules, and generally produce a custom box expression. For general formatting, I did similar thing here, so you can have a look at what's involved. But it isn't exactly simple, and for your specific case that may be an overkill. Generally, convert your code to boxes and try to find a transformation to the box expression that would suit you. –  Leonid Shifrin Jul 31 '13 at 1:54

If you are willing to enter your code as a String you can use this function:

parseStringRaw[s_String] :=
FrontEndExecute @ UndocumentedTestFEParserPacket[s, False]


Now:

Note that the " characters were entered last; if you enter them earlier the auto-indenting will not be the same and neither will the output. Alternatively you could manually paste \[IndentingNewLine] into a single-line String to make the line breaks.

-

Here is a literal answer to your question in which I just insert the "spaces" code as a String:

CellPrint@Cell[BoxData@MakeBoxes[f["\n" y "\n"]], "Output"]


This may not be what you need, but I thought it may be worth mentioning.

Edit

Another simple-minded idea is to define the new-line output for a specific function, say f, as follows:

f /: MakeBoxes[f[y_], StandardForm] :=
RowBox[{"f", "[",
RowBox[{"\<\"\\n\"\>", " ", ToBoxes[y], " ", "\<\"\\n\"\>"}], "]"}]

f[y]


-
I was aware of such solution, but I do appreciate the answer. –  William Jul 31 '13 at 3:30
Yes, I thought so - maybe there's a third way between this simple-minded approach and the full-fledged parser development... –  Jens Jul 31 '13 at 3:33