3
$\begingroup$

Short version of the question: Is there a way to have an escape-sequence alias (or user-defined keyboard shortcut) pop up a dialog box or other type of input structure allowing the selection of a single item from a list, where the selection made specifies what gets pasted into the input cell?

Background: I have an application where I need to maintain a user-specifiable list of associations between labels and internal symbols. I need to be able to use these labels in both input and output. The hard part is that the format of the labels runs counter enough to standard Mathematica notation that one cannot enter them through the keyboard (as an example, enter image description here, which when entered using standard Mathematica shortcuts, puts extra spaces between the f and the H and between the 2 and the O, thinking there is multiplication involved). I have an infrastructure built up to allow this using the Notation package, a custom style, and some minor hacking of the box structure (TemplateBox with a tag specifying the style, Editable->False, and Selectable->False). In order to allow the usage of these labels in input cells, I have the user send a list of all of the associations to a function that calls Notation to make the associations and then generates a palette from that list. The palette is composed of PasteButtons that pastes the label, complete with TemplateBox. This works, but is somewhat unwieldy. This is a set of routines that my students use, and so they do lots of debugging, adding and removing symbols all the time. This suggests that I either need to have a dynamically-updatable palette, have them regenerate the palette regularly, or find another approach for them to select what they want pasted from a menu/dialog/something. As someone who prefers keyboard shortcuts to nearly everything myself, I balk at palettes generally, but didn't see another option as I was developing this package. But now that I have the underlying label/symbol architecture working, I am beginning to think more about user interface, and so would love to hear about other options.

Paste-able Code For Testing:

<< Notation`
SetOptions[EvaluationNotebook[], 
           StyleDefinitions -> Notebook[{Cell[StyleData[
           StyleDefinitions -> FrontEnd`FileName[{"Report"}, 
           "StandardReport.nb", CharacterEncoding -> "UTF-8"]]], 
           Cell[StyleData["chemical"], StyleMenuListing -> None, 
           TagBoxOptions -> {SyntaxForm -> "symbol"}, 
           ShowStringCharacters -> False, ShowAutoStyles -> False, 
           ZeroWidthTimes -> True, TemplateBoxOptions -> 
           {DisplayFunction -> (RowBox[{#}] &), 
           SyntaxForm -> "symbol"}]}]]
AssignLabels[list_] := Block[{}, 
    Do[Notation[DoubleLongLeftRightArrow[
        ParsedBoxWrapper@
        TemplateBox[{"\"" <> list[[i, 1]] <> "\""}, "chemical", 
        Editable -> False, Selectable -> False], 
        ParsedBoxWrapper@SymbolName[list[[i, 2]]]]], {i, Length[list]}]; 
    CreatePalette[Column[PasteButton @@@ (list), Spacings -> 0]]]

assignments = {{"\!\(\*SubscriptBox[\(C\), \
      \(6\)]\)\!\(\*SubscriptBox[\(H\), \(6\)]\)O", 
      C6H6O}, {"(\!\(\*SubscriptBox[\(NH\), \(4\)]\)\!\(\*SubscriptBox[\
      \()\), \(2\)]\)\!\(\*SubscriptBox[\(SO\), \(4\)]\)", 
      AmmoniumSulfate}, {"\!\(\*SubsuperscriptBox[\(SO\), \(4\), \
      \(\(2\)\(-\)\)]\)", Sulfate}, {"\!\(\*SubscriptBox[\(H\), 
      \(2\)]\)O (g)", WaterVapor}, {"\!\(\*SubscriptBox[\(\[CapitalDelta]\), 
      \(f\)]\)\!\\(\*SubsuperscriptBox[\(H\), \(\*SubscriptBox[\(H\), 
      \(2\)] O \((g)\)\\), \(o\)]\)", \[CapitalDelta]fHWaterVapor}, \
      {"\!\(\*SubsuperscriptBox[\(k\), \(sq\), SubscriptBox[\(C\), \(60\)]]\
      \)", ksqC60}, {"\!\(\*SubsuperscriptBox[\(\[Null]\), \(6\), \
      \(12\)]\)C", Carbon12}, {"[\!\(\*SuperscriptBox[\(H\), \(+\)]\)]", 
      HplusConc}};

That last line looks like this in Mathematica:

enter image description here

AssignLabels[assignments];

At that point a palette is created, and clicking any of the items pastes the symbol I need.

Edited to add: A detail that may not be clear from how I asked the question... once a selection is made, I want the result of the selection to be the only thing that is inserted at the cursor location. I do not want to have a call to create a dialog box in one cell, and the results of that getting pasted into another cell. I want someone to be typing along, like they are writing a chemical reaction, and do something like Esc-chem-Esc, they select a label for a reactant from a list, type "+ 2" Esc-chem-Esc and select another label for a reactant from the same list, etc., and through that process build up a complex structure.

Output from CurrentValue[EvaluationNotebook[], InputAliases], as requested in comments:

enter image description here

$\endgroup$
  • $\begingroup$ It is up to you where notation initialization happens, you can put it in init.m or run it at the top of your notebook. About inserting, I suggest trying my Live code templates I don't get much feedback about them but I use them on daily basis and they seem to work. $\endgroup$ – Kuba Apr 16 at 7:45
  • $\begingroup$ That looks like a phenomenal utility for coders. In fact, I wrote something very similar in the 1980s for the Pascal environment I used at the time, so I am extremely supportive of such tools. It looks unwieldy for my application here, though. I am teaching students physical chemistry, and am having them use Mathematica as a tool, and the focus must be on the chemistry. The label/symbol associations that the students will need will vary significantly from problem to problem, so I really need them to be able to make a list of these associations and just call a function to make the associations. $\endgroup$ – Kevin Ausman Apr 19 at 19:14
5
$\begingroup$

Here's something you can try:

CurrentValue[EvaluationNotebook[], {InputAliases,"ch"}] = ActionMenuBox[
    "g1",
    {
    "g1":>NotebookWrite[EvaluationBox[], "g1"],
    "g2":>NotebookWrite[EvaluationBox[], "g2"]
    },
    Appearance->"PopupMenu",
    AutoAction->True
]

A short animation:

enter image description here

The left hand side of the rule is what you see in the menu, and the right hand side is the box expression to be pasted.

$\endgroup$
  • $\begingroup$ That looks extremely promising! I will give that a shot; thank you! $\endgroup$ – Kevin Ausman Apr 15 at 19:17
  • $\begingroup$ When I try to execute your example code, it immediately crashes Mathematica when I type Esc-ch (before I even hit the second esc). $\endgroup$ – Kevin Ausman Apr 15 at 20:11
  • $\begingroup$ @KevinAusman Mathematica version and OS? Also, what does CurrentValue[EvaluationNotebook[], InputAliases] return? What happens if you change the alias from "ch" to something else? $\endgroup$ – Carl Woll Apr 15 at 20:25
  • $\begingroup$ Mathematica 11.3.0.0. Windows 8.1 Pro. Results from that call too long for a comment, so I will add it to the main question. And same problem when I change the alias to something else. $\endgroup$ – Kevin Ausman Apr 15 at 20:33
  • $\begingroup$ @KevinAusman It crashed for me just once. Does it always crash for you? If not, can you characterize when it does and doesn't crash? At any rate, you could probably write to support with the issue. Also, does it crash when you don't have the Notation package loaded? $\endgroup$ – Carl Woll Apr 15 at 20:52

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.