Skip to content

Add \ion, \positiveion, \negativeion commands for chemistry notation#45

Open
drdrew42 wants to merge 5 commits into
openwebwork:mainfrom
drdrew42:feature/chem-ions
Open

Add \ion, \positiveion, \negativeion commands for chemistry notation#45
drdrew42 wants to merge 5 commits into
openwebwork:mainfrom
drdrew42:feature/chem-ions

Conversation

@drdrew42

Copy link
Copy Markdown
Member

What

Adds three LaTeX commands for chemistry ion-charge notation:

  • \ion[sign]{charge} — a superscript-only command: an editable charge block followed by a fixed +/- sign, rendering e.g. the "2+" of a 2+ cation.
  • \positiveion / \negativeion — sign-bound shorthands that canonicalize to \ion[+]{…} / \ion[-]{…}.

Why

These commands existed in a downstream MathQuill fork used for WeBWorK chemistry problems — the chemistry answer-entry toolbars drive \positiveion/\negativeion for entering ion charges. They were lost when that work moved onto @openwebwork/mathquill, silently breaking those toolbar buttons. Restoring them upstream lets the downstream work drop the private fork.

How

Ion extends SupSub, mirroring the existing subscript/superscript classes in commands.tssupsub = 'sup', an htmlTemplate carrying the editable charge block plus a .mq-ion-classed sign span, and a parser() built on latexMathParser.optBlock / .block exactly like NthRoot. latex() serializes to \ion[sign]{charge}; an absent optional sign defaults to +, and an empty charge block to 1.

.mq-ion is a styling hook on the sign span — no CSS rule is added; it renders correctly with the existing mq-sup styles.

Testing

  • npm run build, npm run lint:check, and npm run format:check all pass.
  • Round-trip parse tests added to test/latex.test.ts (the ion charges test), following the existing assertParsesLatex pattern.

🤖 Generated with Claude Code

Ion charge notation — `\ion[+]{2}` rendering the "2+" of a 2+ cation — is a superscript-only command: an editable charge block followed by a fixed sign. `\positiveion` and `\negativeion` are sign-bound shorthands.

These commands existed in a downstream MathQuill fork used for WeBWorK chemistry problems (the chemQuill answer-entry toolbars); this restores them on @openwebwork/mathquill so that work can drop the private fork.

Ion extends SupSub, mirroring the existing subscript/superscript classes. latex() serializes to \ion[sign]{charge}; \positiveion / \negativeion canonicalize to the same. Round-trip tests added to test/latex.test.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@drgrice1

Copy link
Copy Markdown
Member

I think you need to add some explanation of how to use this, and how this would work with PG. This isn't something that can be directly typed into a MathQuill input.

@drdrew42

drdrew42 commented Jun 8, 2026

Copy link
Copy Markdown
Member Author

Originally, LibreTexts wanted to implement a toolbar for chemistry problems (see repo for foundations), and looped in Davide to help improve contextReaction.pl (which includes implementation of ions, compatible with this extension of MathQuill)... and some of that work has now been folded into PG official.

They're finally pulled up to date with PG, but that migration has hit a snag -- as it seems I never submitted the ions implementation to our fork of MathQuill.

Ions are not "real" LaTeX, and it is unexpected that any student would type them in (though they could...), rather it is expected that mathquill toolbar entries be added for them (LibreTexts has macros for this already):

{ 	id: 'positiveion',
	latex: '\\positiveion',
	tooltip: 'postitive ion',
	icon: '\\text{ }^{\\text{ }+}' 
},
{ 	id: 'negativeion',
	latex: '\\negativeion',
	tooltip: 'negative ion',
	icon: '\\text{ }^{\\text{ }-}' 
},

I have a similar request to add a \sci command -- enabling the toolbar-triggering of a scientific notation entry (which I can extend on this PR, or file separately). Clearly students can individually enter the multiplication, base 10, and exponent -- but there is no way for the toolbar to facilitate a "combo move" like this without a dedicated command. Or maybe I've missed something?

@drgrice1

drgrice1 commented Jun 8, 2026

Copy link
Copy Markdown
Member

Now that the toolbar is part of this repository, you should merge in the main branch to get it and demonstrate the usage, or how to implement a toolbar button. Currently with this pull request I am not able to get anything to work with the toolbar.

drdrew42 and others added 2 commits June 8, 2026 13:07
\sci{exp} renders a fixed ×10 followed by an editable exponent block;
the scientific-notation answer toolbar (chemQuillMath.pl) drives it.
Mirrors the existing \ion classes (SupSub subclass). latex() serializes
to \sci{exp}; text() serializes to *10^exp — explicit multiplication and
power, the operations scientific notation denotes — so answers parse
through the MathObjects scientific-notation context's mantissa/power
checks rather than bypassing them via E-notation. Restores a command the
old 0.10 private fork carried. Round-trip tests added to test/latex.test.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@drdrew42

drdrew42 commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

Sorry, I had the triple-layer escaping going there, only need the double for input-test.js

I had no problems adding the following to input-test.js

mathField.options.addToolbarButtons([                                                                                                                                                                                                                                                
    { id: 'sci', latex: '\\sci', tooltip: 'scientific notation', icon: '\\times10^\\text{ }' },                                                                                                                                                                                        
    { id: 'positiveion', latex: '\\positiveion', tooltip: 'positive ion', icon: '\\text{ }^{\\text{ }+}' },                                                                                                                                                                            
    { id: 'negativeion', latex: '\\negativeion', tooltip: 'negative ion', icon: '\\text{ }^{\\text{ }-}' }                                                                                                                                                                             
]);                                                                                                                                                                                                                                                                                  

Well, I say no problems -- there's some issue with the appearance of the icons, I'm working on that. With the ions, it's a matter of combining whitespace with another glyph...

  1. Do you want these buttons actually added to input-test.js in this PR?
  2. Do you want me to fix the whitespace+glyph spacing?

@drgrice1

drgrice1 commented Jun 9, 2026

Copy link
Copy Markdown
Member

No, I think those buttons shouldn't be added to the input-test.html file. I only added the subscript button to demonstrate the way to add buttons.

I figured out how to use this. What was confusing me was that since these define from SupSubs the supSubsRequireOperand applies. So something needs to be typed first to use these.

One thing that is going to be needed for these is mathspeak.

drdrew42 and others added 2 commits June 9, 2026 16:15
Addresses review feedback on the chemistry/scientific-notation commands:

- mathspeak() on Ion and ScientificNotation so screen readers announce
  them meaningfully ("charge 2 positive", "times ten to the 8th power")
  instead of the inherited SupSub "Superscript, ..., Baseline".
- public/input-test.js demonstrates the commands as toolbar buttons
  (\sci, \positiveion, \negativeion) via options.addToolbarButtons.
- toolbar.scss: let an icon's super/subscript carry a real glyph (the ion
  +/- charge) rather than clipping it to placeholder-box size, so the
  charge is visible on the button.
- aria.test.ts: mathspeak assertions for the new commands.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mocha.run() was called from a mid-body inline script, before the
mathquill.test.js bundle (included at the end of the body) registered
any suites — so opening the page ran 0 tests. Move the run into a
window 'load' listener so the suites are registered first. Setup and
teardown stay inline (they only define globals).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@drdrew42

drdrew42 commented Jun 9, 2026

Copy link
Copy Markdown
Member Author

Okay, I've added mathspeak for \sci and the ions. But in writing the corresponding tests, I found that the unit-test.html wasn't running the suite -- so I added that fix as a follow-up commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants