6
$\begingroup$

I need a convenient interface to interactively explore very large expressions. I am aware of Short and Shallow, and appreciate the front-end feature that allows to show a large expression in initially concise and gradually expandable form, with placeholders for collapsed expressions. I would like something similar to this, but with some additional features. In particular, I would like to be able to both expand and collapse sub-expressions, view a summary of a collapsed sub-expression in its tooltip (Head, Length, Depth, LeafCount — ideally, customizable), and have a way to copy a sub-expression to the clipboard. Is there anything similar to this?

$\endgroup$
  • $\begingroup$ One particular scenario where I could use it is large expression simplification. Sometimes FullSimplify cannot make much progress in a reasonable time, but I found that if I manually identify sub-expressions that seems "simplifiable" and apply FullSimplify specifically to them, then I can often achieve significant simplification much faster. $\endgroup$ – Vladimir Reshetnikov Sep 4 '19 at 22:45
  • 1
    $\begingroup$ maybe something like expr1= RandomInteger[5,{2,2}]; expr2=Partition[{a,b,c,d},2]; labels= {"expr 1","expr 2"}; fview =FlipView[{ Tooltip[Iconize[#,#2],Grid@#],#}]&; MapThread[fview,{{expr1,expr2}, labels}]? $\endgroup$ – kglr Sep 5 '19 at 4:38
6
$\begingroup$

The following code does what I think you want:

  1. Right clicking converts the selected portion into a button with a ».
  2. Clicking on the » expands the button back into the selected portion.
  3. The "HotKeys" option allows you to define rules so that a hot key will apply a desired function on the selected portion.
  4. The tooltip that is created can be customized by modifying the $ExpandableInformation global variable.

Here is an animation of the code in action:

enter image description here

You will see expressions collapsed when right-clicking, and simplified when using the "F" key.

One issue is that quitting the kernel will disable the form.

Here is the code:

Options[ExpandableForm] = {"HotKeys" -> {}};

ExpandableForm /: MakeBoxes[ExpandableForm[expr_, OptionsPattern[]], StandardForm] := With[
    {
    events = 
        {
        {"MouseClicked", 2} :> NotebookApply[
            SelectedNotebook[],
            collapsedBoxes[NotebookRead[SelectedNotebook[]]],
            All
        ], (* right clicking collapses the selected expression *)
        Sequence @@ addEvents[OptionValue[ExpandableForm, "HotKeys"]]
        (* process "HotKeys" options *)
        }
    },
    With[{boxes = MakeBoxes[expr, StandardForm]},
        TemplateBox[
            {
            (* setup EventHandler *)
            TagBox[boxes, EventHandlerTag[events]],
            boxes
            },
            "FOO",
            DisplayFunction -> (#1&),
            InterpretationFunction -> (#2&)
        ]
    ]
]

(* make ExpandableForm a wrapper *)
Unprotect[$OutputForms];
	$OutputForms = DeleteDuplicates @ Append[$OutputForms, ExpandableForm];
	Protect[$OutputForms];

(* code to process and implement hot keys *)

addEvents[key_Rule] := addEvents[{key}]
addEvents[keys:{___Rule}] := Replace[
    keys,
    Rule[key_, f_] :> key :> applyFunctionToSelection[f],
    {1}
]

applyFunctionToSelection[f_] := Module[{expr},
    expr = ToExpression[NotebookRead[SelectedNotebook[]], StandardForm, Hold];
    If[MatchQ[expr, _Hold],
        NotebookWrite[
            SelectedNotebook[], 
        Replace[expr, Hold[a_] :> ToBoxes@f[a]]
        ]
    ]
]

(* code to collapse boxes *)
collapsedBoxes[boxes_] := TemplateBox[
    {"»", boxes},
    "Collapse",
    DisplayFunction -> (ButtonBox[
        #,
        ButtonFunction :> NotebookWrite[ParentBox @ EvaluationBox[], #2, All],
        Evaluator -> Automatic
    ]&),
    InterpretationFunction -> (#2&),
    Tooltip -> ToBoxes @ boxInfo[boxes]
]

(* gather expression information *)
boxInfo[boxes_] := Quiet[
    Check[
        ToExpression[boxes, StandardForm, expressionInfo],
        {}
    ],
    ToExpression::esntx
]

SetAttributes[expressionInfo, HoldAll];

expressionInfo[expr_] := Grid[
    Replace[
        $ExpandableInformation,
        (label_ -> h_) :> {Row[{label,":"}], h[Unevaluated @ expr]},
        {1}
    ],
    Alignment -> {{Right, Left}, Baseline}
]

(* customizable global variable to control what the tooltip shows *)

$ExpandableInformation = {
    "Head" -> Head,
    "Length" -> Length,
    "Depth" -> Depth,
    "LeafCount" -> LeafCount
};
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.