One idea is to use a style sheet to enable MATLAB-type matrix input. The following is an extension of @xzczd's idea. Here is the style sheet:
Notebook[{
Cell[StyleData[StyleDefinitions->"Default.nb"]],
Cell[StyleData["MATLAB", StyleDefinitions->StyleData["Input"]],
(* Use a private context so that $Line doesn't increment during processing *)
CellContext->Cell,
(* Add a tag to the evaluation cell, and hence to its generated cells *)
CellProlog:>SetOptions[EvaluationCell[],CellTags->"MATLAB"],
(* Clear tags *)
CellEpilog:>(SetOptions[#1,CellTags->{}]&)/@Cells[CellTags->"MATLAB"],
CellEvaluationFunction->Function[
Module[{m},
ToExpression[
# //. RowBox[{"[", b__}] -> RowBox[{ToString[m],"[",b}],
StandardForm,
Function[Null,
Defer@@(Hold[#1]
//. {
m[a_CompoundExpression] :> With[
{tmp = Replace[Defer[a], {CompoundExpression->List,Times->List}, 3, Heads->True]},
tmp/;True
],
m[a_]:>With[{tmp=Replace[Defer[a], {Times->List}, 2, Heads->True]}, tmp/;True]
}
//. Defer[x_]:>x),
HoldAll
]
]
]
],
(* MATInput style looks like input, but it has a working CellAutoOverwrite option *)
System`GeneratedCellStyles->{"Output"->"MATInput"},
(* No need to show In for this cell *)
ShowCellLabel->False,
(* Make the cell look like text *)
FontFamily->"Arial",
FontSize->14,
FontWeight->"Plain",
AutoMultiplicationSymbol->False
],
Cell[StyleData["MATInput", StyleDefinitions->StyleData["Output"]],
(* Convert to regular Input cell before evaluation *)
CellProlog:>SetOptions[EvaluationCell[],CellStyle->"Input"],
(* Disappear if the MATLAB cell generating the MATInput is reevaluated *)
GeneratedCell->True,
CellAutoOverwrite->True,
(* No need to show cell label until after it is converted to an Input cell *)
ShowCellLabel->False,
(* Make it look like an Input cell*)
ShowStringCharacters->True,
NumberMarks->True,
FontWeight->"DemiBold"
]
},
WindowSize->{808,689},
WindowMargins->{{Automatic,274},{28,Automatic}},
FrontEndVersion->"10.3 for Mac OS X x86 (32-bit, 64-bit Kernel) (December 10, 2015)",
StyleDefinitions->"PrivateStylesheetFormatting.nb"
];
NotebookPut @ %;
Here is how it works. The following is a MATLAB-style cell:
a = [1 2 3 4 5 ; 2 3 4 5 6^2]
After evaluation of the above cell, we have the original MATLAB cell and a generated MATInput cell:
a = [1 2 3 4 5 ; 2 3 4 5 6^2]
a={{1,2,3,4,5},{2,3,4,5,6^2}}
If we edit the MATLAB cell, and then reevaluate, the old generated MATInput cell is overwritten by the new MATInput cell. Also, note that the generated cell hasn't evaluated, 6^2 is not 36 yet, and a has no OwnValue:
OwnValues[a]
{}
If we select the generated cell and evaluate it, then everything works as expected:
a = {{1, 2, 3, 4, 5}, {2, 3, 4, 5, 6^2}}
{{1, 2, 3, 4, 5}, {2, 3, 4, 5, 36}}
Note that the above "Input" cell has now become a real Input cell, and will no longer be overwritten when the MATLAB cell that generated it is reevaluated.
So, the work flow is to create a MATLAB cell, populate it with a MATLAB-style matrix, and then evaluate the MATLAB cell to generate the equivalent unevaluated Mathematica Input cell. This Input cell can then be evaluated to generate results.
Some advantages of this approach are that the MATLAB cell can contain arbitrary Mathematica code, and you can use CompoundExpression
and Times
in the matrix entries since they are only replaced at the top levels. For example, @xzczd's problematic examples can be handled as follows:
[Times[a b] ; c (d e)]
{{a b},{c,d e}}
[Times[i = 1 ; i + 1]]
{i=1;i+1}