Creating Custom InputForm and ShortInputForm

I often want to see the internal representation of Mathematica graphic objects not in FullForm , but in a much more readable InputForm , which has the ability to select parts of the code by double-clicking on it and easily copy this code to the new Cell input. But by default, an InputForm does not allow this, since an InputForm displayed by default as a String , and not as Mathematica code. Is there a way to show InputForm as Mathematica code?

I also often want to see a shortened version of such an InputForm , where all long lists of coordinates are displayed as the first coordinate, followed by the number of missing coordinate values ​​wrapped in Skeleton , all empty Lists deleted and all numbers are also reduced to display no more than 6 digits. It would be even better to use 6 digits only for coordinates, but for color directives like Hue , only 2 significant digits are displayed. For instance,

 Plot[{Sin[x], .5 Sin[2 x]}, {x, 0, 2 \[Pi]}, Filling -> {1 -> {2}}] // ShortInputForm 

should give:

 Graphics[GraphicsComplex[{{1.28228`*^-7, 1.28228*^-7}, <<1133>>}, {{{EdgeForm[], Directive[{Opacity[0.2], Hue[0.67, 0.6, 0.6]}], GraphicsGroup[{Polygon[{{1133, <<578>>}}]}]}, {EdgeForm[], Directive[{Opacity[0.2], Hue[0.67, 0.6, 0.6]}], GraphicsGroup[{Polygon[{{432, <<556>>}}]}]}}, {{Hue[0.67, 0.6, 0.6], Line[{1, <<431>>}]}, {Hue[0.91, 0.6, 0.6], Line[{432, <<701>>}]}}}], {AspectRatio -> GoldenRatio^(-1), Axes -> True, AxesOrigin -> {0, 0}, Method -> {"AxesInFront" -> True}, PlotRange -> {{0, 2*Pi}, {-1., 1}}, PlotRangeClipping -> True, PlotRangePadding -> {Scaled[0.02], Scaled[0.02]}}] 

(note that -0.9999998592131705 converted to -1. , 1.2822827157509358*^-7 converted to 1.28228*^-7 , and Hue[0.9060679774997897, 0.6, 0.6] converted to Hue[0.91, 0.6, 0.6] ).

Thus, I want to get the InputForm output as Mathematica code, as well as the ShortInputForm function, which will give an abridged version of this code. Can anybody help me?


Regarding the first part of the question, I found one way to achieve what I want:

 Plot[{Sin[x], .5 Sin[2 x]}, {x, 0, 2 \[Pi]}, Filling -> {1 -> {2}}] // InputForm // StandardForm 
+4
source share
2 answers

UPDATE

The latest version of the shortInputForm function can be found here .


Original post

Here is another best solution (Mathematica 5 compatible):

 myInputForm[expr_] := Block[{oldContexts, output, interpretation, skeleton}, output = ToString[expr, InputForm]; oldContexts = {$Context, $ContextPath}; $Context = "myTemp`"; $ContextPath = {$Context}; output = DisplayForm@ToBoxes [ToExpression[output] /. {myTemp`interpretation -> If[$VersionNumber >= 6, System`Interpretation, System` First@ {#} &], myTemp`Row -> System`Row, myTemp`skeleton -> System`Skeleton, myTemp`sequence :> (System`Sequence @@ # &)}, StandardForm]; {$Context, $ContextPath} = oldContexts; output] shortInputForm[expr_] := myInputForm[expr /. {{} -> Sequence[], lst : {x_ /; VectorQ[x, NumberQ], y__} /; (MatrixQ[lst, NumberQ] && Length[lst] > 3) :> {x /. v : {a_, b__} /; Length[v] > 3 :> {a, interpretation[skeleton[Length[{b}]], sequence@ {b}]}, interpretation[skeleton[Length[{y}]], sequence@ {y}]}, lst : {x_, y__} /; VectorQ[lst, NumberQ] && Length[lst] > 3 :> {x, interpretation[skeleton[Length[{y}]], sequence@ {y}]}}] 

How it works

This solution is based on a simple idea: we need to block the conversion of things such as Graphics , Point and others for a set of expressions so that they are displayed in the internal form (in the form of expressions suitable for input). Fortunately, if we do this, we get the result of StandardForm , which will only be formatted (two-dimensional) InputForm original expression. This is what you need!

But how to do that? First of all, this conversion is done by FormatValues defined for Symbol as Graphics , Point , etc. You can get a complete list of such Symbol by evaluating the following:

 list = Symbol /@ Select[DeleteCases[Names["*"], "I" | "Infinity"], ToExpression[#, InputForm, Function[symbol, Length[ FormatValues@symbol ] > 0, HoldAll]] &] 

My first idea was just the Block all these Symbol (and it works!):

 myInputForm[expr_] := With[{list = list}, Block[list, RawBoxes@MakeBoxes @expr]] 

But this method evaluates all of these Symbol , and also evaluates all FormatValues for all Symbol in $ContextPath . I think this should be avoided.

Another way to block these FormatValues is to simply remove the "System`" context from $ContextPath . But it only works if these Symbol are not yet allowed in the context of "System`" . Therefore, we need to first convert our expression to String , and then remove the "System`" context from $ContextPath and finally convert the string back to the original expression. Then all new Symbol will be associated with the current $Context (and Graphics , Point , etc.), since they are not in $ContextPath ). To prevent conflicts of contextual shadow copying and clogging the "Global`" context "Global`" I switch $Context to "myTemp`" , which can be easily cleaned if necessary.

This is how myInputForm works.

Now about shortInputForm . The idea is not only to display the abbreviated version of myInputForm , but also to retain the ability to select and copy parts of the abbreviated code to a new input cell and use this code, since it will be a complete code without abbreviations. In version 6 and above, it can be achieved with Interpretation . For compatibility with pre-6 versions of Mathematica I added a code snippet that removes this ability if $VersionNumber less than 6.

The only problem I encountered while working with Interpretation is that it does not have the SequenceHold attribute, so we cannot just specify Sequence as the second argument to Interpretation . But this problem can be easily avoided by wrapping the sequence in a List , and then Apply ing Sequence to it:

 System`Sequence @@ # & 

Please note that I need to specify the exact context for all the built-in Symbol that I use, because at the time they are called, the "System`" context is not in $ContextPath .

This completes the custom decisions I made when developing these features. Suggestions and comments are welcome!

enter image description here

+7
source

At this point, I came to the following solution:

 round[x_, n_] := (10^-n*Round[10^n*MantissaExponent[x]]) /. {m_, e_} :> N[m*10^e]; ShortInputForm[expr_] := ((expr /. {{} -> Sequence[], lst : {x_ /; VectorQ[x, NumberQ], y__} /; (MatrixQ[lst, NumberQ] && Length[lst] > 2) :> {x, Skeleton[Length[{y}]]}, lst : {x_, y__} /; VectorQ[lst, NumberQ] && Length[lst] > 2 :> {x, Skeleton[Length[{y}]]}} /. {exp : Except[List | Point][x__] /; VectorQ[{x}, MachineNumberQ] :> (round[#, 2] & /@ exp), x_Real /; MachineNumberQ[x] :> round[x, 6]}) // InputForm // StandardForm) 

Now:

screenshot

0
source

All Articles