Following this post, I want to use code to generate an input cell with new code. However, unlike the linked post, I want my code to dynamically determine the new code to be printed in the input cell.
The use of Defer
is making this difficult. For example, the following works:
makeImportCell[filename_] :=
CellPrint[ExpressionCell[
Defer[data = Import[filename]], "Input"]]
makeImportCell["myData.txt"]
Output (as an input cell):
data = Import["myData.txt"]
But if I want the function to manipulate the string filename
, it breaks:
makeImportCell[filename_] := Module[{file},
file = filename <> ".txt";
CellPrint[ExpressionCell[Defer[data = Import[file]], "Input"]]]
makeImportCell["myData"]
Output (as an input cell):
data = Import[file$45844993]
I'd also like to use If
statements based on some other variables to alter the code that gets generated, but if I put any If
s into Defer
, they'll be left unevaluated. Maybe the best solution would be to have the function construct a large string containing exactly the code I want to print, and then print this string as input code rather than a string. But I can't figure out how to do this.
I just realized I could use
makeImportCell[filename_] :=
CellPrint[ExpressionCell[
Defer[data = Import[filename <> ".txt"]], "Input"]]
to accomplish the same thing the second function is trying to do. But this doesn't generalize. I want to be able to manipulate the code (and strings within the code) that is to be generated, inside the body of Module
, and then CellPrint
exactly the code I want.
EDIT
J.M.'s answer prompted me to ask a more general version of this question, and the answer given there is particularly simple and elegant. It solves the problem of converting any arbitrary string of code into an input cell.
With[{file = filename <> ".txt"}, CellPrint[...]]
$\endgroup$