@pie-lib/math-input-mathlive 1.1.5-beta.12 → 1.1.5-beta.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -94,6 +94,28 @@ var LabelHolder = (0, _styles.styled)('span', {
94
94
  // MathQuill shaded `.mq-empty`.
95
95
  '& [data-pie-empty]': {
96
96
  opacity: 0.5
97
+ },
98
+ // A fraction is taller than the label's 1em line box, so its numerator sat
99
+ // flush against (and was clipped by) the top edge. Extra room above it grows
100
+ // the box, which the keypad then centres, so the fraction moves down a little.
101
+ '&:has(.ML__mfrac)': {
102
+ paddingTop: '0.25em'
103
+ },
104
+ // Centre a fraction's bar between its empty slots (see `placeholderStyles`).
105
+ '& .ML__mfrac:has([data-pie-empty]) .ML__frac-line': {
106
+ position: 'relative',
107
+ top: '0.16em'
108
+ },
109
+ // A real numerator (`x`) is lighter than an empty box and its ink ends at the
110
+ // baseline, so the full drop overshoots: it needs a smaller drop. The numerator is
111
+ // the second `.ML__center` (MathLive emits the denominator first).
112
+ '& .ML__mfrac:has([data-pie-empty]):not(:has(.ML__center ~ .ML__center [data-pie-empty])) .ML__frac-line': {
113
+ top: '0.13em'
114
+ },
115
+ // Same for a mixed number (`x` then the fraction): the leading `x` is a sibling
116
+ // of the fraction, which a lone `\frac{}{}` does not have.
117
+ '& .ML__mfrac:has([data-pie-empty]):not(:only-child) .ML__frac-line': {
118
+ top: '0.13em'
97
119
  }
98
120
  }, _commonStyles.rootIndexStyles);
99
121
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_react","_interopRequireDefault","require","_propTypes","_Button","_IconButton","_styles","_debug","_lodashEs","_renderUi","_keys","_keysLayout","_commonStyles","_mathliveInstance","_longdiv","_callSuper","t","o","e","_getPrototypeOf2","_possibleConstructorReturn2","_isNativeReflectConstruct","Reflect","construct","constructor","apply","Boolean","prototype","valueOf","call","ownKeys","r","Object","keys","getOwnPropertySymbols","filter","getOwnPropertyDescriptor","enumerable","push","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","log","debug","SLANTED_LABELS","SLANT","SLANTED_STROKE","SLANTED_SCALE_Y","LabelHolder","styled","shouldForwardProp","prop","_ref","slanted","transform","concat","WebkitTextStroke","pointerEvents","textTransform","color","text","display","textAlign","lineHeight","maxWidth","overflow","backgroundColor","keypadEmptyPlaceholder","undefined","opacity","rootIndexStyles","LatexLabel","exports","_React$Component","props","_this","_classCallCheck2","state","markup","latexToMarkup","latex","labelRef","React","createRef","_inherits2","_createClass2","key","value","_componentDidMount","_asyncToGenerator2","_regenerator","mark","_callee","wrap","_context","prev","next","fixLongDivisionWhenReady","current","abrupt","loadMathLive","unmounted","setState","warned","stop","componentDidMount","componentDidUpdate","prevProps","prevState","componentWillUnmount","render","createElement","ref","includes","dangerouslySetInnerHTML","__html","Component","PropTypes","string","isRequired","createCustomLayout","layoutObj","gridTemplateColumns","columns","gridTemplateRows","rows","gridAutoFlow","KeyPadContainer","commonKeyboardStyles","width","gridRowGap","gridColumnGap","fontFamily","buttonBackground","category","keypadButtonOperator","keypadButton","keypadButtonOperatorHover","keypadButtonHover","StyledButton","Button","_ref2","isDelete","isComma","isDot","minWidth","fontSize","borderRadius","StyledLatexButtonWrapper","_ref3","padding","margin","StyledIconButton","IconButton","_ref4","height","KeyPad","_React$Component2","_this2","setKeypadInteraction","onPress","base","extras","flatten","_toConsumableArray2","sortKeys","noDecimal","write","label","keypadRef","_this$keypadRef","keyPadElement","mainContainer","closest","currentToolbar","controlledKeypadMode","mainContainerPosition","getBoundingClientRect","currentToolbarPosition","difference","top","totalHeight","style","addEventListener","handleKeypadInteraction","_this$keypadRef2","removeEventListener","_this3","_this$props","className","baseSet","additionalKeys","layoutForKeyPad","onFocus","mode","noBaseSet","keysWithoutBaseSet","allKeys","flowKeys","shift","Math","floor","join","map","k","index","command","extra","actions","extraProps","onClick","buttonClick","bind","disabled","keyIsNotAllowed","ariaLabel","name","_extends2","Icon","icon","tabIndex","size","bool","array","object","func","oneOfType","number","_default"],"sources":["../../src/keypad/index.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport { styled } from '@mui/material/styles';\nimport debug from 'debug';\nimport { flatten } from 'lodash-es';\nimport { color } from '@pie-lib/render-ui';\n\nimport { baseSet } from '../keys';\nimport { sortKeys } from './keys-layout';\nimport { commonKeyboardStyles, rootIndexStyles } from '../mf/common-styles';\nimport { loadMathLive, latexToMarkup } from '../mathlive-instance';\nimport { fixLongDivisionWhenReady } from '../longdiv';\n\nconst log = debug('pie-lib:math-input-mathlive:keypad');\n\n/**\n * A LaTeX keypad label.\n *\n * The MathQuill implementation rendered every LaTeX label as its own\n * `MQ.StaticMath` instance. Here each label is static HTML produced once by\n * `convertLatexToMarkup`, so a 40-key keypad no longer creates 40 live math\n * instances.\n */\n// Labels that the legacy keypad drew slanted. MathQuill styled `\\parallel` as\n// italic, which slants the two bars; MathLive draws it upright. A skew is used\n// rather than `font-style: italic` so the slant does not depend on the font\n// having an italic face for this glyph.\nconst SLANTED_LABELS = ['\\\\parallel'];\nconst SLANT = 'skewX(-15deg)';\n// MathLive's `∥` has hairline bars next to the radical sign and the other keys, so\n// they are thickened with a text stroke and stretched a little taller.\nconst SLANTED_STROKE = '0.03em currentColor';\nconst SLANTED_SCALE_Y = 1.25;\n\n// The `color.*()` helpers must be called lazily, inside the styled callback.\n// Evaluating them in a plain object literal runs them at module load, which\n// breaks any consumer that mocks a subset of @pie-lib/render-ui.\nconst LabelHolder = styled('span', { shouldForwardProp: (prop) => prop !== 'slanted' })(({ slanted }) => ({\n ...(slanted && {\n transform: `${SLANT} scaleY(${SLANTED_SCALE_Y})`,\n '& *': { WebkitTextStroke: SLANTED_STROKE },\n }),\n pointerEvents: 'none',\n textTransform: 'none',\n color: color.text(),\n // Deliberately inline-block, NOT inline-flex: MathLive's markup relies on\n // normal inline flow. Making its spans flex items collapses their width, and\n // stretchy accents render an <svg width=\"100%\" preserveAspectRatio=\"none\">\n // that then squeezes into a spike instead of spanning the content.\n display: 'inline-block',\n textAlign: 'center',\n lineHeight: 1,\n // Keep a label from sizing its grid column. `overflow: hidden` also collapses\n // the label's min-content contribution, so a wide accent cannot drag the\n // column across the screen. The svg's own positioning is left to\n // mathlive-static.css (injected by the package) - duplicating it here broke\n // the accent's containing block.\n maxWidth: '100%',\n overflow: 'hidden',\n // Answer-block / empty-slot boxes inside a label.\n '& .ML__placeholder': {\n backgroundColor: color.keypadEmptyPlaceholder ? color.keypadEmptyPlaceholder() : undefined,\n },\n // The stand-in glyph for an empty argument slot (see EMPTY_SLOT). Muted so it\n // reads as \"a slot goes here\" rather than as part of the symbol, matching how\n // MathQuill shaded `.mq-empty`.\n '& [data-pie-empty]': {\n opacity: 0.5,\n },\n // A readable index on the nth-root key. Carried by the label itself, not only\n // by the keypad container, so it holds wherever a LatexLabel is mounted.\n ...rootIndexStyles,\n}));\n\nexport class LatexLabel extends React.Component {\n static propTypes = {\n latex: PropTypes.string.isRequired,\n };\n\n constructor(props) {\n super(props);\n this.state = { markup: latexToMarkup(props.latex) };\n this.labelRef = React.createRef();\n }\n\n async componentDidMount() {\n // MathLive may not have finished loading when the keypad first mounts.\n if (this.state.markup) {\n // The long-division key's label needs MathLive's drawing corrected.\n fixLongDivisionWhenReady(this.labelRef.current);\n return;\n }\n\n await loadMathLive();\n\n if (this.unmounted) {\n return;\n }\n\n const markup = latexToMarkup(this.props.latex);\n\n if (markup) {\n this.setState({ markup });\n return;\n }\n\n // Still nothing: the engine is genuinely unavailable (a missing chunk, a\n // blocked request). Keep the raw-latex fallback visible rather than an\n // empty button, and log once so this is diagnosable.\n if (!LatexLabel.warned) {\n LatexLabel.warned = true;\n log('MathLive unavailable - keypad labels are falling back to raw latex');\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n if (prevProps.latex !== this.props.latex) {\n this.setState({ markup: latexToMarkup(this.props.latex) });\n }\n\n if (this.state.markup !== (prevState && prevState.markup)) {\n fixLongDivisionWhenReady(this.labelRef.current);\n }\n }\n\n componentWillUnmount() {\n this.unmounted = true;\n }\n\n render() {\n const { markup } = this.state;\n\n // Fall back to the raw latex so a button is never blank.\n return markup ? (\n // eslint-disable-next-line react/no-danger\n <LabelHolder\n ref={this.labelRef}\n slanted={SLANTED_LABELS.includes(this.props.latex)}\n dangerouslySetInnerHTML={{ __html: markup }}\n />\n ) : (\n <LabelHolder slanted={SLANTED_LABELS.includes(this.props.latex)}>{this.props.latex}</LabelHolder>\n );\n }\n}\n\nconst createCustomLayout = (layoutObj) => {\n if (layoutObj) {\n return {\n gridTemplateColumns: `repeat(${layoutObj.columns}, minmax(min-content, 150px))`,\n gridTemplateRows: `repeat(${layoutObj.rows}, minmax(40px, 60px))`,\n gridAutoFlow: 'initial',\n };\n }\n\n return {};\n};\n\nconst KeyPadContainer = styled('div')(() => ({\n ...commonKeyboardStyles,\n width: '100%',\n display: 'grid',\n gridTemplateRows: 'repeat(5, minmax(40px, 60px))',\n gridRowGap: '0px',\n gridColumnGap: '0px',\n gridAutoFlow: 'column',\n '&.character': {\n textTransform: 'initial !important',\n gridTemplateRows: 'repeat(5, minmax(40px, 50px)) !important',\n },\n '&.language': {\n gridTemplateRows: 'repeat(4, minmax(40px, 50px)) !important',\n '& *': {\n fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',\n },\n },\n}));\n\nconst buttonBackground = (category) => ({\n backgroundColor: category === 'operators' ? color.keypadButtonOperator() : color.keypadButton(),\n '&:hover': {\n backgroundColor: category === 'operators' ? color.keypadButtonOperatorHover() : color.keypadButtonHover(),\n },\n});\n\nconst StyledButton = styled(Button)(({ category, isDelete, isComma, isDot }) => ({\n minWidth: 'auto',\n textTransform: 'none',\n fontSize: isComma || isDot ? '200% !important' : '140% !important',\n lineHeight: isComma || isDot ? '100%' : 'normal',\n color: color.text(),\n ...buttonBackground(category),\n borderRadius: 0,\n ...(isDelete && {\n fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',\n }),\n}));\n\nconst StyledLatexButtonWrapper = styled(Button)(({ category }) => ({\n textTransform: 'none',\n padding: 0,\n margin: 0,\n fontSize: '110% !important',\n minWidth: 'auto',\n borderRadius: 0,\n ...buttonBackground(category),\n}));\n\nconst StyledIconButton = styled(IconButton)(({ category }) => ({\n minWidth: 'auto',\n ...buttonBackground(category),\n borderRadius: 0,\n '& .icon': {\n height: '30px',\n },\n}));\n\nexport class KeyPad extends React.Component {\n static propTypes = {\n className: PropTypes.string,\n controlledKeypadMode: PropTypes.bool,\n baseSet: PropTypes.array,\n additionalKeys: PropTypes.array,\n layoutForKeyPad: PropTypes.object,\n onPress: PropTypes.func.isRequired,\n onFocus: PropTypes.func,\n noDecimal: PropTypes.bool,\n setKeypadInteraction: PropTypes.func,\n mode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n };\n\n static defaultProps = {\n baseSet: baseSet,\n noDecimal: false,\n };\n\n constructor(props) {\n super(props);\n this.keypadRef = React.createRef();\n }\n\n componentDidMount() {\n // Ensure MathLive is available for the LaTeX labels.\n loadMathLive();\n\n const keyPadElement = this.keypadRef?.current;\n const mainContainer = keyPadElement?.closest('.main-container');\n const currentToolbar = keyPadElement?.closest('.pie-toolbar');\n\n // need only for math keyboard so we need also controlledKeypadMode\n if (this.props.controlledKeypadMode && mainContainer && currentToolbar) {\n const mainContainerPosition = mainContainer.getBoundingClientRect();\n const currentToolbarPosition = currentToolbar.getBoundingClientRect();\n const difference =\n mainContainerPosition.top +\n mainContainerPosition.height -\n (currentToolbarPosition.top + currentToolbarPosition.height);\n\n if (difference < 0) {\n const totalHeight = mainContainerPosition.height + mainContainerPosition.top - difference;\n\n mainContainer.style.height = `${totalHeight}px`;\n }\n }\n\n if (keyPadElement) {\n keyPadElement.addEventListener('touchstart', this.handleKeypadInteraction, true);\n keyPadElement.addEventListener('mousedown', this.handleKeypadInteraction, true);\n }\n }\n\n componentWillUnmount() {\n const keyPadElement = this.keypadRef?.current;\n\n if (this.props.controlledKeypadMode && keyPadElement) {\n const mainContainer = keyPadElement.closest('.main-container');\n\n if (mainContainer) {\n mainContainer.style.height = 'unset';\n }\n }\n\n if (keyPadElement) {\n keyPadElement.removeEventListener('touchstart', this.handleKeypadInteraction, true);\n keyPadElement.removeEventListener('mousedown', this.handleKeypadInteraction, true);\n }\n }\n\n handleKeypadInteraction = () => {\n if (this.props.setKeypadInteraction) {\n this.props.setKeypadInteraction(true);\n }\n };\n\n buttonClick = (key) => {\n log('[buttonClick]', key);\n this.props.onPress(key);\n };\n\n flowKeys = (base, extras) => flatten([...sortKeys(base), ...sortKeys(extras)]);\n\n keyIsNotAllowed = (key) => {\n const { noDecimal } = this.props;\n\n return !!(((key.write === '.' && key.label === '.') || (key.write === ',' && key.label === ',')) && noDecimal);\n };\n\n render() {\n const { className, baseSet: base, additionalKeys, layoutForKeyPad, onFocus, mode } = this.props;\n\n const noBaseSet = ['non-negative-integers', 'integers', 'decimals', 'fractions', 'item-authoring', 'language'];\n const keysWithoutBaseSet = noBaseSet.includes(mode);\n const allKeys = keysWithoutBaseSet\n ? this.flowKeys([], additionalKeys || [])\n : this.flowKeys(base, additionalKeys || []);\n\n const shift = allKeys.length % 5 ? 1 : 0;\n const style = {\n gridTemplateColumns: `repeat(${Math.floor(allKeys.length / 5) + shift}, minmax(min-content, 150px))`,\n ...createCustomLayout(layoutForKeyPad),\n };\n\n return (\n <KeyPadContainer\n ref={this.keypadRef}\n className={[className, mode].filter(Boolean).join(' ')}\n style={style}\n onFocus={onFocus}\n >\n {allKeys.map((k, index) => {\n if (!k) {\n return <span key={`empty-${index}`} />;\n }\n\n const key = `${k.label || k.latex || k.command}-${index}`;\n const category = !keysWithoutBaseSet ? k.category : undefined;\n const extra = { ...(k.actions || {}), ...(k.extraProps || {}) };\n const onClick = this.buttonClick.bind(this, k);\n const disabled = this.keyIsNotAllowed(k);\n const ariaLabel = k.ariaLabel ? k.ariaLabel : k.name || k.label;\n\n if (k.latex) {\n return (\n <StyledLatexButtonWrapper\n key={key}\n onClick={onClick}\n disabled={disabled}\n category={category}\n aria-label={ariaLabel}\n {...extra}\n >\n <LatexLabel latex={k.latex} />\n </StyledLatexButtonWrapper>\n );\n }\n\n if (k.label) {\n return (\n <StyledButton\n key={key}\n onClick={onClick}\n disabled={disabled}\n category={category}\n isDelete={k.label === '⌫'}\n isComma={k.label === ','}\n isDot={k.label === '.'}\n aria-label={ariaLabel}\n {...extra}\n >\n {k.label}\n </StyledButton>\n );\n }\n\n const Icon = k.icon ? k.icon : 'div';\n\n return (\n <StyledIconButton\n key={key}\n tabIndex={'-1'}\n onClick={onClick}\n disabled={disabled}\n category={category}\n size=\"large\"\n {...extra}\n >\n <Icon className=\"icon\" />\n </StyledIconButton>\n );\n })}\n </KeyPadContainer>\n );\n }\n}\n\nexport default KeyPad;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"index.js","names":["_react","_interopRequireDefault","require","_propTypes","_Button","_IconButton","_styles","_debug","_lodashEs","_renderUi","_keys","_keysLayout","_commonStyles","_mathliveInstance","_longdiv","_callSuper","t","o","e","_getPrototypeOf2","_possibleConstructorReturn2","_isNativeReflectConstruct","Reflect","construct","constructor","apply","Boolean","prototype","valueOf","call","ownKeys","r","Object","keys","getOwnPropertySymbols","filter","getOwnPropertyDescriptor","enumerable","push","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","log","debug","SLANTED_LABELS","SLANT","SLANTED_STROKE","SLANTED_SCALE_Y","LabelHolder","styled","shouldForwardProp","prop","_ref","slanted","transform","concat","WebkitTextStroke","pointerEvents","textTransform","color","text","display","textAlign","lineHeight","maxWidth","overflow","backgroundColor","keypadEmptyPlaceholder","undefined","opacity","paddingTop","position","top","rootIndexStyles","LatexLabel","exports","_React$Component","props","_this","_classCallCheck2","state","markup","latexToMarkup","latex","labelRef","React","createRef","_inherits2","_createClass2","key","value","_componentDidMount","_asyncToGenerator2","_regenerator","mark","_callee","wrap","_context","prev","next","fixLongDivisionWhenReady","current","abrupt","loadMathLive","unmounted","setState","warned","stop","componentDidMount","componentDidUpdate","prevProps","prevState","componentWillUnmount","render","createElement","ref","includes","dangerouslySetInnerHTML","__html","Component","PropTypes","string","isRequired","createCustomLayout","layoutObj","gridTemplateColumns","columns","gridTemplateRows","rows","gridAutoFlow","KeyPadContainer","commonKeyboardStyles","width","gridRowGap","gridColumnGap","fontFamily","buttonBackground","category","keypadButtonOperator","keypadButton","keypadButtonOperatorHover","keypadButtonHover","StyledButton","Button","_ref2","isDelete","isComma","isDot","minWidth","fontSize","borderRadius","StyledLatexButtonWrapper","_ref3","padding","margin","StyledIconButton","IconButton","_ref4","height","KeyPad","_React$Component2","_this2","setKeypadInteraction","onPress","base","extras","flatten","_toConsumableArray2","sortKeys","noDecimal","write","label","keypadRef","_this$keypadRef","keyPadElement","mainContainer","closest","currentToolbar","controlledKeypadMode","mainContainerPosition","getBoundingClientRect","currentToolbarPosition","difference","totalHeight","style","addEventListener","handleKeypadInteraction","_this$keypadRef2","removeEventListener","_this3","_this$props","className","baseSet","additionalKeys","layoutForKeyPad","onFocus","mode","noBaseSet","keysWithoutBaseSet","allKeys","flowKeys","shift","Math","floor","join","map","k","index","command","extra","actions","extraProps","onClick","buttonClick","bind","disabled","keyIsNotAllowed","ariaLabel","name","_extends2","Icon","icon","tabIndex","size","bool","array","object","func","oneOfType","number","_default"],"sources":["../../src/keypad/index.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport Button from '@mui/material/Button';\nimport IconButton from '@mui/material/IconButton';\nimport { styled } from '@mui/material/styles';\nimport debug from 'debug';\nimport { flatten } from 'lodash-es';\nimport { color } from '@pie-lib/render-ui';\n\nimport { baseSet } from '../keys';\nimport { sortKeys } from './keys-layout';\nimport { commonKeyboardStyles, rootIndexStyles } from '../mf/common-styles';\nimport { loadMathLive, latexToMarkup } from '../mathlive-instance';\nimport { fixLongDivisionWhenReady } from '../longdiv';\n\nconst log = debug('pie-lib:math-input-mathlive:keypad');\n\n/**\n * A LaTeX keypad label.\n *\n * The MathQuill implementation rendered every LaTeX label as its own\n * `MQ.StaticMath` instance. Here each label is static HTML produced once by\n * `convertLatexToMarkup`, so a 40-key keypad no longer creates 40 live math\n * instances.\n */\n// Labels that the legacy keypad drew slanted. MathQuill styled `\\parallel` as\n// italic, which slants the two bars; MathLive draws it upright. A skew is used\n// rather than `font-style: italic` so the slant does not depend on the font\n// having an italic face for this glyph.\nconst SLANTED_LABELS = ['\\\\parallel'];\nconst SLANT = 'skewX(-15deg)';\n// MathLive's `∥` has hairline bars next to the radical sign and the other keys, so\n// they are thickened with a text stroke and stretched a little taller.\nconst SLANTED_STROKE = '0.03em currentColor';\nconst SLANTED_SCALE_Y = 1.25;\n\n// The `color.*()` helpers must be called lazily, inside the styled callback.\n// Evaluating them in a plain object literal runs them at module load, which\n// breaks any consumer that mocks a subset of @pie-lib/render-ui.\nconst LabelHolder = styled('span', { shouldForwardProp: (prop) => prop !== 'slanted' })(({ slanted }) => ({\n ...(slanted && {\n transform: `${SLANT} scaleY(${SLANTED_SCALE_Y})`,\n '& *': { WebkitTextStroke: SLANTED_STROKE },\n }),\n pointerEvents: 'none',\n textTransform: 'none',\n color: color.text(),\n // Deliberately inline-block, NOT inline-flex: MathLive's markup relies on\n // normal inline flow. Making its spans flex items collapses their width, and\n // stretchy accents render an <svg width=\"100%\" preserveAspectRatio=\"none\">\n // that then squeezes into a spike instead of spanning the content.\n display: 'inline-block',\n textAlign: 'center',\n lineHeight: 1,\n // Keep a label from sizing its grid column. `overflow: hidden` also collapses\n // the label's min-content contribution, so a wide accent cannot drag the\n // column across the screen. The svg's own positioning is left to\n // mathlive-static.css (injected by the package) - duplicating it here broke\n // the accent's containing block.\n maxWidth: '100%',\n overflow: 'hidden',\n // Answer-block / empty-slot boxes inside a label.\n '& .ML__placeholder': {\n backgroundColor: color.keypadEmptyPlaceholder ? color.keypadEmptyPlaceholder() : undefined,\n },\n // The stand-in glyph for an empty argument slot (see EMPTY_SLOT). Muted so it\n // reads as \"a slot goes here\" rather than as part of the symbol, matching how\n // MathQuill shaded `.mq-empty`.\n '& [data-pie-empty]': {\n opacity: 0.5,\n },\n // A fraction is taller than the label's 1em line box, so its numerator sat\n // flush against (and was clipped by) the top edge. Extra room above it grows\n // the box, which the keypad then centres, so the fraction moves down a little.\n '&:has(.ML__mfrac)': {\n paddingTop: '0.25em',\n },\n // Centre a fraction's bar between its empty slots (see `placeholderStyles`).\n '& .ML__mfrac:has([data-pie-empty]) .ML__frac-line': {\n position: 'relative',\n top: '0.16em',\n },\n // A real numerator (`x`) is lighter than an empty box and its ink ends at the\n // baseline, so the full drop overshoots: it needs a smaller drop. The numerator is\n // the second `.ML__center` (MathLive emits the denominator first).\n '& .ML__mfrac:has([data-pie-empty]):not(:has(.ML__center ~ .ML__center [data-pie-empty])) .ML__frac-line': {\n top: '0.13em',\n },\n // Same for a mixed number (`x` then the fraction): the leading `x` is a sibling\n // of the fraction, which a lone `\\frac{}{}` does not have.\n '& .ML__mfrac:has([data-pie-empty]):not(:only-child) .ML__frac-line': {\n top: '0.13em',\n },\n // A readable index on the nth-root key. Carried by the label itself, not only\n // by the keypad container, so it holds wherever a LatexLabel is mounted.\n ...rootIndexStyles,\n}));\n\nexport class LatexLabel extends React.Component {\n static propTypes = {\n latex: PropTypes.string.isRequired,\n };\n\n constructor(props) {\n super(props);\n this.state = { markup: latexToMarkup(props.latex) };\n this.labelRef = React.createRef();\n }\n\n async componentDidMount() {\n // MathLive may not have finished loading when the keypad first mounts.\n if (this.state.markup) {\n // The long-division key's label needs MathLive's drawing corrected.\n fixLongDivisionWhenReady(this.labelRef.current);\n return;\n }\n\n await loadMathLive();\n\n if (this.unmounted) {\n return;\n }\n\n const markup = latexToMarkup(this.props.latex);\n\n if (markup) {\n this.setState({ markup });\n return;\n }\n\n // Still nothing: the engine is genuinely unavailable (a missing chunk, a\n // blocked request). Keep the raw-latex fallback visible rather than an\n // empty button, and log once so this is diagnosable.\n if (!LatexLabel.warned) {\n LatexLabel.warned = true;\n log('MathLive unavailable - keypad labels are falling back to raw latex');\n }\n }\n\n componentDidUpdate(prevProps, prevState) {\n if (prevProps.latex !== this.props.latex) {\n this.setState({ markup: latexToMarkup(this.props.latex) });\n }\n\n if (this.state.markup !== (prevState && prevState.markup)) {\n fixLongDivisionWhenReady(this.labelRef.current);\n }\n }\n\n componentWillUnmount() {\n this.unmounted = true;\n }\n\n render() {\n const { markup } = this.state;\n\n // Fall back to the raw latex so a button is never blank.\n return markup ? (\n // eslint-disable-next-line react/no-danger\n <LabelHolder\n ref={this.labelRef}\n slanted={SLANTED_LABELS.includes(this.props.latex)}\n dangerouslySetInnerHTML={{ __html: markup }}\n />\n ) : (\n <LabelHolder slanted={SLANTED_LABELS.includes(this.props.latex)}>{this.props.latex}</LabelHolder>\n );\n }\n}\n\nconst createCustomLayout = (layoutObj) => {\n if (layoutObj) {\n return {\n gridTemplateColumns: `repeat(${layoutObj.columns}, minmax(min-content, 150px))`,\n gridTemplateRows: `repeat(${layoutObj.rows}, minmax(40px, 60px))`,\n gridAutoFlow: 'initial',\n };\n }\n\n return {};\n};\n\nconst KeyPadContainer = styled('div')(() => ({\n ...commonKeyboardStyles,\n width: '100%',\n display: 'grid',\n gridTemplateRows: 'repeat(5, minmax(40px, 60px))',\n gridRowGap: '0px',\n gridColumnGap: '0px',\n gridAutoFlow: 'column',\n '&.character': {\n textTransform: 'initial !important',\n gridTemplateRows: 'repeat(5, minmax(40px, 50px)) !important',\n },\n '&.language': {\n gridTemplateRows: 'repeat(4, minmax(40px, 50px)) !important',\n '& *': {\n fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',\n },\n },\n}));\n\nconst buttonBackground = (category) => ({\n backgroundColor: category === 'operators' ? color.keypadButtonOperator() : color.keypadButton(),\n '&:hover': {\n backgroundColor: category === 'operators' ? color.keypadButtonOperatorHover() : color.keypadButtonHover(),\n },\n});\n\nconst StyledButton = styled(Button)(({ category, isDelete, isComma, isDot }) => ({\n minWidth: 'auto',\n textTransform: 'none',\n fontSize: isComma || isDot ? '200% !important' : '140% !important',\n lineHeight: isComma || isDot ? '100%' : 'normal',\n color: color.text(),\n ...buttonBackground(category),\n borderRadius: 0,\n ...(isDelete && {\n fontFamily: 'Roboto, Helvetica, Arial, sans-serif !important',\n }),\n}));\n\nconst StyledLatexButtonWrapper = styled(Button)(({ category }) => ({\n textTransform: 'none',\n padding: 0,\n margin: 0,\n fontSize: '110% !important',\n minWidth: 'auto',\n borderRadius: 0,\n ...buttonBackground(category),\n}));\n\nconst StyledIconButton = styled(IconButton)(({ category }) => ({\n minWidth: 'auto',\n ...buttonBackground(category),\n borderRadius: 0,\n '& .icon': {\n height: '30px',\n },\n}));\n\nexport class KeyPad extends React.Component {\n static propTypes = {\n className: PropTypes.string,\n controlledKeypadMode: PropTypes.bool,\n baseSet: PropTypes.array,\n additionalKeys: PropTypes.array,\n layoutForKeyPad: PropTypes.object,\n onPress: PropTypes.func.isRequired,\n onFocus: PropTypes.func,\n noDecimal: PropTypes.bool,\n setKeypadInteraction: PropTypes.func,\n mode: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n };\n\n static defaultProps = {\n baseSet: baseSet,\n noDecimal: false,\n };\n\n constructor(props) {\n super(props);\n this.keypadRef = React.createRef();\n }\n\n componentDidMount() {\n // Ensure MathLive is available for the LaTeX labels.\n loadMathLive();\n\n const keyPadElement = this.keypadRef?.current;\n const mainContainer = keyPadElement?.closest('.main-container');\n const currentToolbar = keyPadElement?.closest('.pie-toolbar');\n\n // need only for math keyboard so we need also controlledKeypadMode\n if (this.props.controlledKeypadMode && mainContainer && currentToolbar) {\n const mainContainerPosition = mainContainer.getBoundingClientRect();\n const currentToolbarPosition = currentToolbar.getBoundingClientRect();\n const difference =\n mainContainerPosition.top +\n mainContainerPosition.height -\n (currentToolbarPosition.top + currentToolbarPosition.height);\n\n if (difference < 0) {\n const totalHeight = mainContainerPosition.height + mainContainerPosition.top - difference;\n\n mainContainer.style.height = `${totalHeight}px`;\n }\n }\n\n if (keyPadElement) {\n keyPadElement.addEventListener('touchstart', this.handleKeypadInteraction, true);\n keyPadElement.addEventListener('mousedown', this.handleKeypadInteraction, true);\n }\n }\n\n componentWillUnmount() {\n const keyPadElement = this.keypadRef?.current;\n\n if (this.props.controlledKeypadMode && keyPadElement) {\n const mainContainer = keyPadElement.closest('.main-container');\n\n if (mainContainer) {\n mainContainer.style.height = 'unset';\n }\n }\n\n if (keyPadElement) {\n keyPadElement.removeEventListener('touchstart', this.handleKeypadInteraction, true);\n keyPadElement.removeEventListener('mousedown', this.handleKeypadInteraction, true);\n }\n }\n\n handleKeypadInteraction = () => {\n if (this.props.setKeypadInteraction) {\n this.props.setKeypadInteraction(true);\n }\n };\n\n buttonClick = (key) => {\n log('[buttonClick]', key);\n this.props.onPress(key);\n };\n\n flowKeys = (base, extras) => flatten([...sortKeys(base), ...sortKeys(extras)]);\n\n keyIsNotAllowed = (key) => {\n const { noDecimal } = this.props;\n\n return !!(((key.write === '.' && key.label === '.') || (key.write === ',' && key.label === ',')) && noDecimal);\n };\n\n render() {\n const { className, baseSet: base, additionalKeys, layoutForKeyPad, onFocus, mode } = this.props;\n\n const noBaseSet = ['non-negative-integers', 'integers', 'decimals', 'fractions', 'item-authoring', 'language'];\n const keysWithoutBaseSet = noBaseSet.includes(mode);\n const allKeys = keysWithoutBaseSet\n ? this.flowKeys([], additionalKeys || [])\n : this.flowKeys(base, additionalKeys || []);\n\n const shift = allKeys.length % 5 ? 1 : 0;\n const style = {\n gridTemplateColumns: `repeat(${Math.floor(allKeys.length / 5) + shift}, minmax(min-content, 150px))`,\n ...createCustomLayout(layoutForKeyPad),\n };\n\n return (\n <KeyPadContainer\n ref={this.keypadRef}\n className={[className, mode].filter(Boolean).join(' ')}\n style={style}\n onFocus={onFocus}\n >\n {allKeys.map((k, index) => {\n if (!k) {\n return <span key={`empty-${index}`} />;\n }\n\n const key = `${k.label || k.latex || k.command}-${index}`;\n const category = !keysWithoutBaseSet ? k.category : undefined;\n const extra = { ...(k.actions || {}), ...(k.extraProps || {}) };\n const onClick = this.buttonClick.bind(this, k);\n const disabled = this.keyIsNotAllowed(k);\n const ariaLabel = k.ariaLabel ? k.ariaLabel : k.name || k.label;\n\n if (k.latex) {\n return (\n <StyledLatexButtonWrapper\n key={key}\n onClick={onClick}\n disabled={disabled}\n category={category}\n aria-label={ariaLabel}\n {...extra}\n >\n <LatexLabel latex={k.latex} />\n </StyledLatexButtonWrapper>\n );\n }\n\n if (k.label) {\n return (\n <StyledButton\n key={key}\n onClick={onClick}\n disabled={disabled}\n category={category}\n isDelete={k.label === '⌫'}\n isComma={k.label === ','}\n isDot={k.label === '.'}\n aria-label={ariaLabel}\n {...extra}\n >\n {k.label}\n </StyledButton>\n );\n }\n\n const Icon = k.icon ? k.icon : 'div';\n\n return (\n <StyledIconButton\n key={key}\n tabIndex={'-1'}\n onClick={onClick}\n disabled={disabled}\n category={category}\n size=\"large\"\n {...extra}\n >\n <Icon className=\"icon\" />\n </StyledIconButton>\n );\n })}\n </KeyPadContainer>\n );\n }\n}\n\nexport default KeyPad;\n"],"mappings":"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","ignoreList":[]}
@@ -75,6 +75,18 @@ var DEFAULT_FIELD_ID = exports.DEFAULT_FIELD_ID = 'r1';
75
75
  */
76
76
  var EMPTY_SLOT = '\\htmlData{pie-empty=1}{\\rule{0.55em}{0.55em}}';
77
77
  var EMPTY_GROUP_REGEX = /\{\s*\}/g;
78
+ // The smallest boxes are the ones in a subscript (`x_{}`, `\log_{}`) or exponent
79
+ // (`x^{}`): they sit at script size, so the 0.55em square reads cramped. They get
80
+ // 0.4em more height, and `\rule[-d]` decides which side it grows on:
81
+ // - subscript / log base: all of it goes below, the top edge stays put;
82
+ // - exponent: 0.3em goes above, plus 0.1em below.
83
+ var EMPTY_SUBSCRIPT_REGEX = /_\{\s*\}/g;
84
+ var EMPTY_SUPERSCRIPT_REGEX = /\^\{\s*\}/g;
85
+ var EMPTY_SUBSCRIPT_SLOT = '\\htmlData{pie-empty=1}{\\rule[-0.4em]{0.55em}{0.95em}}';
86
+ // The label clips what hangs below its line box (`overflow: hidden`), so the lowered
87
+ // box needs a zero-width strut after it to make room, or its bottom is cut off.
88
+ var EMPTY_SUBSCRIPT_STRUT = '\\rule[-0.5em]{0em}{0.5em}';
89
+ var EMPTY_SUPERSCRIPT_SLOT = '\\htmlData{pie-empty=1}{\\rule[-0.1em]{0.55em}{0.95em}}';
78
90
  // The segment key (`\overline{}`). The keypad centres every label in its cell, and
79
91
  // a thin bar is a much shorter label than the ray and line keys' stretchy arrows,
80
92
  // so by default both its bar and its box sit off from theirs: the bar is lower
@@ -115,7 +127,7 @@ var EMPTY_FENCE_SLOT = '\\rule{0em}{1em}\\htmlData{pie-empty=1}{\\rule[-0.25em]{
115
127
  * @returns {string}
116
128
  */
117
129
  var withVisibleEmptySlots = exports.withVisibleEmptySlots = function withVisibleEmptySlots(latex) {
118
- return (latex || '').replace(EMPTY_OVERLINE_REGEX, "".concat(EMPTY_OVERLINE_LABEL_STRUT, "\\overline{").concat(EMPTY_OVERLINE_BAR_STRUT).concat(EMPTY_SLOT, "}")).replace(EMPTY_GROUP_REGEX, "{".concat(EMPTY_SLOT, "}")).replace(EMPTY_FENCE_REGEX, function (_m, open, close) {
130
+ return (latex || '').replace(EMPTY_OVERLINE_REGEX, "".concat(EMPTY_OVERLINE_LABEL_STRUT, "\\overline{").concat(EMPTY_OVERLINE_BAR_STRUT).concat(EMPTY_SLOT, "}")).replace(EMPTY_SUBSCRIPT_REGEX, "_{".concat(EMPTY_SUBSCRIPT_SLOT, "}").concat(EMPTY_SUBSCRIPT_STRUT)).replace(EMPTY_SUPERSCRIPT_REGEX, "^{".concat(EMPTY_SUPERSCRIPT_SLOT, "}")).replace(EMPTY_GROUP_REGEX, "{".concat(EMPTY_SLOT, "}")).replace(EMPTY_FENCE_REGEX, function (_m, open, close) {
119
131
  return "\\left".concat(open).concat(EMPTY_FENCE_SLOT, "\\right").concat(close);
120
132
  });
121
133
  };
@@ -512,4 +524,7 @@ var keyToAction = exports.keyToAction = function keyToAction(key) {
512
524
  }
513
525
  return undefined;
514
526
  };
527
+ // TEMP: remove once confirmed that pie-elements picks up this build.
528
+ // eslint-disable-next-line no-console
529
+ console.log('[math-input-mathlive] latex-bridge loaded - taller sub/sup slots (PIE-1135 v2)');
515
530
  //# sourceMappingURL=latex-bridge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"latex-bridge.js","names":["NEWLINE_EMBED","exports","NEWLINE_EMBED_REGEX","DISPLAYLINES_REGEX","MQ_FIELD_REGEX","PLACEHOLDER_REGEX","BARE_PLACEHOLDER_REGEX","BARE_PLACEHOLDER_NO_ARG_REGEX","DEFAULT_FIELD_ID","EMPTY_SLOT","EMPTY_GROUP_REGEX","EMPTY_OVERLINE_REGEX","EMPTY_OVERLINE_BAR_STRUT","EMPTY_OVERLINE_LABEL_STRUT","EMPTY_FENCE_REGEX","EMPTY_FENCE_SLOT","withVisibleEmptySlots","latex","replace","concat","_m","open","close","toNativeCommands","out","replaceAbs","escapeBareComments","indexOf","backslashes","i","length","ch","idx","depth","inner","slice","fieldIds","match","lastIndex","exec","push","toMathLive","id","content","split","join","MATHQUILL_ALIASES","MATHQUILL_ALIAS_REGEX","PRIME_SUPERSCRIPT_REGEX","BARE_DOUBLEPRIME_REGEX","primesToApostrophes","primes","repeat","BARE_PRIME_COMMAND_REGEX","barePrimesToApostrophes","groups","isDouble","isScriptArgument","test","inScript","command","text","pop","toCanonicalCommands","m","fromMathLive","trim","map","s","COMMANDS_WITH_ARGS","_","KEYSTROKES","Left","Right","Backspace","Delete","Up","Down","keyToAction","key","undefined","type","value","write","parts","Array","isArray","c","keystroke","selector"],"sources":["../src/latex-bridge.js"],"sourcesContent":["/**\n * LaTeX translation layer between the MathQuill-era content model and MathLive.\n *\n * Two independent concerns live here:\n *\n * 1. Newlines. MathQuill had no line break, so pie-lib registered a custom\n * `newLine` embed that serialises to `\\embed{newLine}[]`. MathLive has no\n * embed system but supports real multiline environments, so we translate\n * `\\embed{newLine}[]` <-> `\\\\` inside `\\displaylines{}`.\n *\n * Authored content keeps its `\\embed{newLine}[]` on-disk form (that is what\n * @pie-lib/math-rendering already normalises for MathJax), so each renderer\n * normalises at its own boundary and stored items stay compatible.\n *\n * 2. Keypad key -> MathLive action. MathQuill keys carry `write`/`command`/\n * `keystroke` built for `mf.write()` / `mf.cmd()` / `mf.keystroke()`.\n * MathLive has `insert()` and `executeCommand()` instead.\n */\n\nexport const NEWLINE_EMBED = '\\\\embed{newLine}[]';\nconst NEWLINE_EMBED_REGEX = /\\\\embed\\{newLine\\}\\[\\]/g;\nconst DISPLAYLINES_REGEX = /^\\\\displaylines\\{([\\s\\S]*)\\}$/;\n\n/**\n * MathQuill's editable sub-field syntax, e.g. `\\MathQuillMathField[r1]{}`.\n * These are the answer blocks in templated math items; MathLive expresses the\n * same idea as `\\placeholder[id]{}` and reads them back via the prompts API.\n */\nconst MQ_FIELD_REGEX = /\\\\MathQuillMathField\\[([^\\]]*)\\]\\{([^{}]*)\\}/g;\nconst PLACEHOLDER_REGEX = /\\\\placeholder\\[([^\\]]*)\\]\\{([^{}]*)\\}/g;\n\n/**\n * Unnamed placeholders, which MathLive inserts on its own.\n *\n * Typing a command with empty arguments (`\\longdiv{}`, `\\frac{}{}`) makes\n * MathLive serialise the empty slots as `\\placeholder{}`. That token is\n * MathLive-specific: MathJax - which @pie-lib/math-rendering uses to render\n * prompts and previews - has no such command and renders it as red error text.\n * Stored latex must therefore keep plain empty groups.\n */\nconst BARE_PLACEHOLDER_REGEX = /\\\\placeholder\\{([^{}]*)\\}/g;\nconst BARE_PLACEHOLDER_NO_ARG_REGEX = /\\\\placeholder(?![[{a-zA-Z])/g;\n\n/** Default id used when stored latex has an unnamed field. */\nexport const DEFAULT_FIELD_ID = 'r1';\n\n/**\n * A visible stand-in for an empty argument slot, used for STATIC rendering only.\n *\n * Stored latex legitimately contains empty groups - `\\longdiv{}`, `\\frac{}{}`,\n * `x^{}` - to express a command's shape. MathQuill drew those as a shaded box\n * (`.mq-empty`); MathLive renders `{}` as nothing, so `convertLatexToMarkup`\n * output comes out completely blank (not even the surrounding bracket, in the\n * case of `\\enclose{longdiv}{}`).\n *\n * `\\placeholder{}` is not usable here: in static markup it renders as a\n * non-breaking space, because its editable box only exists inside a live\n * mathfield. So something with real width is required.\n *\n * It must be a `\\rule`, not a unicode glyph. A glyph's width comes from font\n * metrics, and U+25AB is not in the KaTeX fonts - the browser substitutes a\n * wider fallback while MathLive still sizes surrounding accents from its own\n * metrics. That left stretchy accents (`\\overarc`, `\\overleftrightarrow`)\n * visibly narrower than the box they were meant to span. A rule carries an\n * explicit em width, so accents size correctly - and a filled box is closer to\n * MathQuill's `.mq-empty` anyway.\n *\n * Live mathfields need none of this - MathLive manages empty slots itself.\n */\nconst EMPTY_SLOT = '\\\\htmlData{pie-empty=1}{\\\\rule{0.55em}{0.55em}}';\nconst EMPTY_GROUP_REGEX = /\\{\\s*\\}/g;\n// The segment key (`\\overline{}`). The keypad centres every label in its cell, and\n// a thin bar is a much shorter label than the ray and line keys' stretchy arrows,\n// so by default both its bar and its box sit off from theirs: the bar is lower\n// than the arrows' shafts, and the box higher than theirs. Two zero-width struts\n// fix that, found by rendering the three keys at 14-28px and measuring:\n// - inside the bar, above the box: pushes the bar up to the height of the\n// arrows' shafts (the bar-to-box distance then matches theirs);\n// - before the bar, from the baseline: raises the label's top, which moves the\n// whole label down so the box lands where theirs does.\nconst EMPTY_OVERLINE_REGEX = /\\\\overline\\{\\s*\\}/g;\nconst EMPTY_OVERLINE_BAR_STRUT = '\\\\rule{0em}{0.87em}';\nconst EMPTY_OVERLINE_LABEL_STRUT = '\\\\rule{0em}{1.3em}';\n// Empty delimiter pairs: `\\abs{}` is converted to `\\left|\\right|`, and the\n// parenthesis / bracket keys are `\\left(\\right)` / `\\left[\\right]`. None has a\n// `{}` group for the rule above to catch, so they would render as bare fences.\nconst EMPTY_FENCE_REGEX = /\\\\left([([|])\\s*\\\\right([)\\]|])/g;\n// The same muted fill as the other slots (`pie-empty`), but a tall rectangle\n// rather than a square. It also sets the fences' height: `\\left...\\right` stretch\n// to their content, so a taller slot gives taller parentheses.\n//\n// A `\\rule` stands on the baseline, but the fences are centred on the math axis\n// (0.25em above it), so an un-lifted box sat high between them. `[-0.25em]`\n// lowers it by (axis - height / 2) = 0.25 - 1 / 2, centring it on the axis.\n//\n// Lowering it alone also shrinks the fences, which size themselves to their\n// content (MathLive switches to short bars). The zero-width `\\rule{0em}{1em}`\n// strut keeps the content as tall as before, so the bars keep their height and\n// only the box moves.\nconst EMPTY_FENCE_SLOT = '\\\\rule{0em}{1em}\\\\htmlData{pie-empty=1}{\\\\rule[-0.25em]{0.55em}{1em}}';\n\n/**\n * Make empty argument slots visible, for static rendering.\n *\n * Display-only: never feed the result to a mathfield or to storage - the\n * original latex is what gets typed and saved.\n *\n * @param {string} latex\n * @returns {string}\n */\nexport const withVisibleEmptySlots = (latex) =>\n (latex || '')\n .replace(EMPTY_OVERLINE_REGEX, `${EMPTY_OVERLINE_LABEL_STRUT}\\\\overline{${EMPTY_OVERLINE_BAR_STRUT}${EMPTY_SLOT}}`)\n .replace(EMPTY_GROUP_REGEX, `{${EMPTY_SLOT}}`)\n .replace(EMPTY_FENCE_REGEX, (_m, open, close) => `\\\\left${open}${EMPTY_FENCE_SLOT}\\\\right${close}`);\n\n/**\n * Pie commands that take an argument, and their native MathLive equivalents.\n *\n * These MUST NOT be handled as MathLive macros. A macro is serialised from the\n * arguments it was created with, so text typed inside its expansion never makes\n * it back out: `getValue('latex')` keeps returning `\\longdiv{\\placeholder{}}`\n * while `getValue('ascii-math')` shows the typed content. Setting\n * `captureSelection: false` lets the cursor in but does not change\n * serialisation.\n *\n * Expanding to native constructs instead gives real, editable atoms that\n * round-trip. All three targets are understood by MathJax too, so stored latex\n * still renders in @pie-lib/math-rendering without a reverse mapping.\n */\n/**\n * Rewrite argument-taking pie commands into native MathLive latex.\n * Applied on the way *into* a mathfield.\n *\n * @param {string} latex\n * @returns {string}\n */\nexport const toNativeCommands = (latex) => {\n if (typeof latex !== 'string' || !latex) {\n return latex || '';\n }\n\n let out = latex;\n\n // \\abs{x} -> \\left|x\\right| needs brace-aware handling, the rest are prefix\n // swaps.\n out = replaceAbs(out);\n out = out.replace(/\\\\longdiv\\{/g, '\\\\enclose{longdiv}{');\n out = out.replace(/\\\\overarc\\{/g, '\\\\overparen{');\n out = escapeBareComments(out);\n\n return out;\n};\n\n/**\n * Escape an unescaped `%`.\n *\n * In real LaTeX `%` starts a comment, so MathLive discards it *and everything\n * after it*: `50%` renders as `50`, and `x%y` as just `x`. MathQuill had no\n * such notion - it treated `%` as a symbol - so latex from anywhere outside the\n * keypad may still carry a bare one.\n *\n * Only a `%` preceded by an even number of backslashes is bare: `\\%` is already\n * escaped, while the `%` in `\\\\%` (a line break, then a comment) is not.\n *\n * @param {string} latex\n * @returns {string}\n */\nconst escapeBareComments = (latex) => {\n if (latex.indexOf('%') === -1) {\n return latex;\n }\n\n let out = '';\n // Consecutive backslashes immediately before the current character.\n let backslashes = 0;\n\n for (let i = 0; i < latex.length; i++) {\n const ch = latex[i];\n\n out += ch === '%' && backslashes % 2 === 0 ? '\\\\%' : ch;\n backslashes = ch === '\\\\' ? backslashes + 1 : 0;\n }\n\n return out;\n};\n\n/** `\\abs{x}` -> `\\left|x\\right|`, matching balanced braces. */\nconst replaceAbs = (latex) => {\n let out = latex;\n let idx = out.indexOf('\\\\abs{');\n\n while (idx !== -1) {\n const open = idx + '\\\\abs{'.length - 1;\n let depth = 0;\n let close = -1;\n\n for (let i = open; i < out.length; i++) {\n if (out[i] === '{') depth++;\n else if (out[i] === '}') {\n depth--;\n if (depth === 0) {\n close = i;\n break;\n }\n }\n }\n\n if (close === -1) {\n break;\n }\n\n const inner = out.slice(open + 1, close);\n\n out = `${out.slice(0, idx)}\\\\left|${inner}\\\\right|${out.slice(close + 1)}`;\n idx = out.indexOf('\\\\abs{');\n }\n\n return out;\n};\n\n/**\n * Ids of the answer blocks in a piece of stored latex, in document order.\n *\n * @param {string} latex\n * @returns {string[]}\n */\nexport const fieldIds = (latex) => {\n if (typeof latex !== 'string') {\n return [];\n }\n\n const out = [];\n let match;\n\n MQ_FIELD_REGEX.lastIndex = 0;\n\n while ((match = MQ_FIELD_REGEX.exec(latex)) !== null) {\n out.push(match[1] || DEFAULT_FIELD_ID);\n }\n\n return out;\n};\n\n/**\n * Convert stored latex (which may contain `\\embed{newLine}[]`) into latex that\n * MathLive can parse and render as multiple lines.\n *\n * @param {string} latex\n * @returns {string}\n */\nexport const toMathLive = (latex) => {\n if (typeof latex !== 'string' || !latex) {\n return latex || '';\n }\n\n // Argument-taking pie commands -> native constructs, so their content stays\n // editable and serialises back correctly (see toNativeCommands).\n let out = toNativeCommands(latex);\n\n // Answer blocks: \\MathQuillMathField[id]{x} -> \\placeholder[id]{x}\n out = out.replace(MQ_FIELD_REGEX, (_m, id, content) => `\\\\placeholder[${id || DEFAULT_FIELD_ID}]{${content}}`);\n\n // Newlines: \\embed{newLine}[] -> a multiline environment\n if (out.indexOf(NEWLINE_EMBED) !== -1) {\n out = `\\\\displaylines{${out.split(NEWLINE_EMBED_REGEX).join(' \\\\\\\\ ')}}`;\n }\n\n return out;\n};\n\n/**\n * Keypad command names that MathQuill treated as ALIASES of a different command.\n *\n * MathQuill registered `\\\\divide` as another name for `\\\\div` (and\n * `\\\\perpendicular` for `\\\\perp`), so pressing the key stored the real command.\n * MathLive only knows these names through `PIE_MACROS`, and serialises a macro\n * under its own name - so `\\\\divide` reached storage verbatim, where MathJax\n * (@pie-lib/math-rendering) has no such command and renders it as red text.\n *\n * Every other keypad command already matches what MathQuill stored (`\\\\degree`,\n * `\\\\nsim`, `\\\\ncong`, `\\\\nparallel`, `\\\\square`, `\\\\napprox`,\n * `\\\\parallelogram`), and MathJax understands those.\n */\nconst MATHQUILL_ALIASES = {\n '\\\\divide': '\\\\div',\n '\\\\perpendicular': '\\\\perp',\n};\n\n// Whole command names only: `\\\\divideontimes` is a real AMS symbol.\nconst MATHQUILL_ALIAS_REGEX = /\\\\(divide|perpendicular)(?![a-zA-Z])/g;\n\n/**\n * Primes. MathLive turns a prime that follows a base into a superscript atom and\n * serialises it as `^{\\\\prime}`, or `^{\\\\doubleprime}` for the keypad's double\n * prime key (`5''` comes back out as `5^{\\\\doubleprime}`). MathJax has no\n * `\\\\doubleprime`, and two adjacent `^{\\\\prime}` groups - what typing `'` twice\n * produces - are a \"double exponent\" error. MathQuill stored plain apostrophes,\n * which both MathJax and MathLive read as primes, so store those.\n *\n * Only a superscript made of primes alone is rewritten: `x^{\\\\prime 2}` keeps\n * its group, since it holds more than primes.\n */\nconst PRIME_SUPERSCRIPT_REGEX = /\\^\\{((?:\\s*\\\\(?:prime|doubleprime)(?![a-zA-Z]))+)\\s*\\}/g;\nconst BARE_DOUBLEPRIME_REGEX = /\\\\doubleprime(?![a-zA-Z])/g;\n\nconst primesToApostrophes = (primes) =>\n // eslint-disable-next-line quotes\n \"'\".repeat(\n (primes.match(/\\\\prime(?![a-zA-Z])/g) || []).length + 2 * (primes.match(BARE_DOUBLEPRIME_REGEX) || []).length,\n );\n\nconst BARE_PRIME_COMMAND_REGEX = /^\\\\(doubleprime|prime)(?![a-zA-Z])/;\n\n/**\n * Primes that are *not* in a superscript.\n *\n * MathLive emits bare `\\prime` / `\\doubleprime` for a `′` or `″` typed or pasted\n * as a character (`5′6″` serialises as `5\\prime6\\doubleprime`). A bare `\\prime`\n * is a full-size glyph in MathJax, while `''` is a superscript, so storing\n * `5\\prime6''` drew the single prime visibly larger than each stroke of the\n * double prime. Both become apostrophes, the superscript primes MathQuill\n * stored, so they always match.\n *\n * Inside a script (`x^{\\prime 2}`, `x^\\prime`) a prime is already a\n * superscript, and an apostrophe there would mean something else, so\n * `\\prime` is kept and `\\doubleprime` (unknown to MathJax) becomes\n * `\\prime\\prime`.\n *\n * @param {string} latex\n * @returns {string}\n */\nconst barePrimesToApostrophes = (latex) => {\n if (latex.indexOf('prime') === -1) {\n return latex;\n }\n\n // One entry per open brace: is that group a super/subscript?\n const groups = [];\n let out = '';\n let i = 0;\n\n while (i < latex.length) {\n const ch = latex[i];\n\n if (ch === '\\\\') {\n const match = latex.slice(i).match(BARE_PRIME_COMMAND_REGEX);\n\n if (match) {\n const isDouble = match[1] === 'doubleprime';\n // `x^\\prime`: the command is itself the script.\n const isScriptArgument = /[\\^_]\\s*$/.test(out);\n const inScript = isScriptArgument || groups.indexOf(true) !== -1;\n\n if (inScript) {\n out += isDouble ? '\\\\prime\\\\prime' : '\\\\prime';\n } else {\n // eslint-disable-next-line quotes\n out += isDouble ? \"''\" : \"'\";\n }\n\n i += match[0].length;\n continue;\n }\n\n // Copy any other command, or an escaped character such as `\\{`, whole.\n const command = latex.slice(i).match(/^\\\\(?:[a-zA-Z]+|.)/);\n const text = command ? command[0] : ch;\n\n out += text;\n i += text.length;\n continue;\n }\n\n if (ch === '{') {\n groups.push(/[\\^_]\\s*$/.test(out));\n } else if (ch === '}') {\n groups.pop();\n }\n\n out += ch;\n i += 1;\n }\n\n return out;\n};\n\n/**\n * Rewrite what MathLive serialises into the form MathQuill stored: alias\n * command names, and primes.\n *\n * @param {string} latex\n * @returns {string}\n */\nexport const toCanonicalCommands = (latex) =>\n typeof latex === 'string'\n ? barePrimesToApostrophes(\n latex\n .replace(MATHQUILL_ALIAS_REGEX, (m) => MATHQUILL_ALIASES[m])\n .replace(PRIME_SUPERSCRIPT_REGEX, (_m, primes) => primesToApostrophes(primes)),\n )\n : latex;\n\n/**\n * Convert latex out of MathLive back into the stored form, so items authored\n * with the MathLive editor remain readable by @pie-lib/math-rendering and by\n * the existing MathQuill implementation.\n *\n * @param {string} latex\n * @returns {string}\n */\nexport const fromMathLive = (latex) => {\n if (typeof latex !== 'string' || !latex) {\n return latex || '';\n }\n\n const match = latex.trim().match(DISPLAYLINES_REGEX);\n let out = match ? match[1] : latex;\n\n // `\\\\` is the line separator inside a multiline environment.\n if (out.indexOf('\\\\\\\\') !== -1) {\n out = out\n .split(/\\s*\\\\\\\\\\s*/)\n .map((s) => s.trim())\n .join(NEWLINE_EMBED);\n }\n\n // Answer blocks: \\placeholder[id]{x} -> \\MathQuillMathField[id]{x}\n out = out.replace(\n PLACEHOLDER_REGEX,\n (_m, id, content) => `\\\\MathQuillMathField[${id || DEFAULT_FIELD_ID}]{${content}}`,\n );\n\n // Unnamed placeholders are MathLive's own representation of an empty slot and\n // must not reach storage or MathJax. Unwrap them: keep any content, drop the\n // command itself (the surrounding braces are already part of the host latex,\n // so re-adding them here would produce `\\longdiv{{}}`).\n out = out.replace(BARE_PLACEHOLDER_REGEX, (_m, content) => content);\n out = out.replace(BARE_PLACEHOLDER_NO_ARG_REGEX, '');\n\n // Store the command MathQuill stored, not the alias - also heals latex that was\n // saved with `\\\\divide` before the keypad resolved it.\n return toCanonicalCommands(out);\n};\n\n/**\n * MathQuill `cmd()` semantics: commands that take arguments should land the\n * cursor inside the first argument. MathLive expresses that with `#?`\n * placeholders in the inserted latex.\n */\nconst COMMANDS_WITH_ARGS = {\n // An explicit \"blank over blank\" key: both slots start empty.\n '\\\\frac': '\\\\frac{#?}{#?}',\n // Division, which must behave like MathQuill's `/`: whatever precedes the\n // cursor becomes the numerator and the caret lands in the denominator. `#@`\n // is MathLive's token for \"the selection, or the item before the cursor\" -\n // this is exactly the template MathLive binds to the `/` key itself. Using\n // `#?` here instead produced an empty fraction and left the typed number\n // stranded outside it.\n '/': '\\\\frac{#@}{#?}',\n '\\\\sqrt': '\\\\sqrt{#?}',\n '\\\\nthroot': '\\\\sqrt[#?]{#?}',\n '\\\\overline': '\\\\overline{#?}',\n '\\\\overrightarrow': '\\\\overrightarrow{#?}',\n '\\\\overleftrightarrow': '\\\\overleftrightarrow{#?}',\n // Native forms, not the pie macros: a macro would not serialise the user's\n // typed content back out (see toNativeCommands).\n '\\\\overarc': '\\\\overparen{#?}',\n '\\\\longdiv': '\\\\enclose{longdiv}{#?}',\n '^': '^{#?}',\n _: '_{#?}',\n '(': '\\\\left(#?\\\\right)',\n '[': '\\\\left[#?\\\\right]',\n '|': '\\\\left|#?\\\\right|',\n};\n\n/**\n * MathQuill keystroke names -> MathLive command selectors.\n */\nconst KEYSTROKES = {\n Left: 'moveToPreviousChar',\n Right: 'moveToNextChar',\n Backspace: 'deleteBackward',\n Delete: 'deleteForward',\n Up: 'moveUp',\n Down: 'moveDown',\n};\n\n/**\n * Translate a keypad key definition into a MathLive action.\n *\n * Mirrors the precedence in @pie-lib/math-input's MathInput.keypadPress:\n * latex (unless a command is present) -> write -> command -> keystroke.\n *\n * @param {object} key\n * @returns {{type: 'insert'|'command', value: string}|undefined}\n */\nexport const keyToAction = (key) => {\n if (!key) {\n return undefined;\n }\n\n if (key.latex && !key.command) {\n return { type: 'insert', value: key.latex };\n }\n\n if (key.write) {\n return { type: 'insert', value: key.write };\n }\n\n if (key.command) {\n // Some keys carry an array of commands (e.g. Measured Angle is\n // ['m', '\\\\angle'], log-base-n is ['\\\\log', '_']). MathQuill's `cmd()`\n // applied them in sequence; MathLive inserts one latex string, so expand\n // each part and concatenate.\n const parts = Array.isArray(key.command) ? key.command : [key.command];\n const value = parts.map((c) => COMMANDS_WITH_ARGS[c] || MATHQUILL_ALIASES[c] || c).join('');\n\n return { type: 'insert', value };\n }\n\n if (key.keystroke) {\n const selector = KEYSTROKES[key.keystroke];\n\n return selector ? { type: 'command', value: selector } : undefined;\n }\n\n return undefined;\n};\n\nexport { COMMANDS_WITH_ARGS, KEYSTROKES, MATHQUILL_ALIASES };\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"latex-bridge.js","names":["NEWLINE_EMBED","exports","NEWLINE_EMBED_REGEX","DISPLAYLINES_REGEX","MQ_FIELD_REGEX","PLACEHOLDER_REGEX","BARE_PLACEHOLDER_REGEX","BARE_PLACEHOLDER_NO_ARG_REGEX","DEFAULT_FIELD_ID","EMPTY_SLOT","EMPTY_GROUP_REGEX","EMPTY_SUBSCRIPT_REGEX","EMPTY_SUPERSCRIPT_REGEX","EMPTY_SUBSCRIPT_SLOT","EMPTY_SUBSCRIPT_STRUT","EMPTY_SUPERSCRIPT_SLOT","EMPTY_OVERLINE_REGEX","EMPTY_OVERLINE_BAR_STRUT","EMPTY_OVERLINE_LABEL_STRUT","EMPTY_FENCE_REGEX","EMPTY_FENCE_SLOT","withVisibleEmptySlots","latex","replace","concat","_m","open","close","toNativeCommands","out","replaceAbs","escapeBareComments","indexOf","backslashes","i","length","ch","idx","depth","inner","slice","fieldIds","match","lastIndex","exec","push","toMathLive","id","content","split","join","MATHQUILL_ALIASES","MATHQUILL_ALIAS_REGEX","PRIME_SUPERSCRIPT_REGEX","BARE_DOUBLEPRIME_REGEX","primesToApostrophes","primes","repeat","BARE_PRIME_COMMAND_REGEX","barePrimesToApostrophes","groups","isDouble","isScriptArgument","test","inScript","command","text","pop","toCanonicalCommands","m","fromMathLive","trim","map","s","COMMANDS_WITH_ARGS","_","KEYSTROKES","Left","Right","Backspace","Delete","Up","Down","keyToAction","key","undefined","type","value","write","parts","Array","isArray","c","keystroke","selector","console","log"],"sources":["../src/latex-bridge.js"],"sourcesContent":["/**\n * LaTeX translation layer between the MathQuill-era content model and MathLive.\n *\n * Two independent concerns live here:\n *\n * 1. Newlines. MathQuill had no line break, so pie-lib registered a custom\n * `newLine` embed that serialises to `\\embed{newLine}[]`. MathLive has no\n * embed system but supports real multiline environments, so we translate\n * `\\embed{newLine}[]` <-> `\\\\` inside `\\displaylines{}`.\n *\n * Authored content keeps its `\\embed{newLine}[]` on-disk form (that is what\n * @pie-lib/math-rendering already normalises for MathJax), so each renderer\n * normalises at its own boundary and stored items stay compatible.\n *\n * 2. Keypad key -> MathLive action. MathQuill keys carry `write`/`command`/\n * `keystroke` built for `mf.write()` / `mf.cmd()` / `mf.keystroke()`.\n * MathLive has `insert()` and `executeCommand()` instead.\n */\n\nexport const NEWLINE_EMBED = '\\\\embed{newLine}[]';\nconst NEWLINE_EMBED_REGEX = /\\\\embed\\{newLine\\}\\[\\]/g;\nconst DISPLAYLINES_REGEX = /^\\\\displaylines\\{([\\s\\S]*)\\}$/;\n\n/**\n * MathQuill's editable sub-field syntax, e.g. `\\MathQuillMathField[r1]{}`.\n * These are the answer blocks in templated math items; MathLive expresses the\n * same idea as `\\placeholder[id]{}` and reads them back via the prompts API.\n */\nconst MQ_FIELD_REGEX = /\\\\MathQuillMathField\\[([^\\]]*)\\]\\{([^{}]*)\\}/g;\nconst PLACEHOLDER_REGEX = /\\\\placeholder\\[([^\\]]*)\\]\\{([^{}]*)\\}/g;\n\n/**\n * Unnamed placeholders, which MathLive inserts on its own.\n *\n * Typing a command with empty arguments (`\\longdiv{}`, `\\frac{}{}`) makes\n * MathLive serialise the empty slots as `\\placeholder{}`. That token is\n * MathLive-specific: MathJax - which @pie-lib/math-rendering uses to render\n * prompts and previews - has no such command and renders it as red error text.\n * Stored latex must therefore keep plain empty groups.\n */\nconst BARE_PLACEHOLDER_REGEX = /\\\\placeholder\\{([^{}]*)\\}/g;\nconst BARE_PLACEHOLDER_NO_ARG_REGEX = /\\\\placeholder(?![[{a-zA-Z])/g;\n\n/** Default id used when stored latex has an unnamed field. */\nexport const DEFAULT_FIELD_ID = 'r1';\n\n/**\n * A visible stand-in for an empty argument slot, used for STATIC rendering only.\n *\n * Stored latex legitimately contains empty groups - `\\longdiv{}`, `\\frac{}{}`,\n * `x^{}` - to express a command's shape. MathQuill drew those as a shaded box\n * (`.mq-empty`); MathLive renders `{}` as nothing, so `convertLatexToMarkup`\n * output comes out completely blank (not even the surrounding bracket, in the\n * case of `\\enclose{longdiv}{}`).\n *\n * `\\placeholder{}` is not usable here: in static markup it renders as a\n * non-breaking space, because its editable box only exists inside a live\n * mathfield. So something with real width is required.\n *\n * It must be a `\\rule`, not a unicode glyph. A glyph's width comes from font\n * metrics, and U+25AB is not in the KaTeX fonts - the browser substitutes a\n * wider fallback while MathLive still sizes surrounding accents from its own\n * metrics. That left stretchy accents (`\\overarc`, `\\overleftrightarrow`)\n * visibly narrower than the box they were meant to span. A rule carries an\n * explicit em width, so accents size correctly - and a filled box is closer to\n * MathQuill's `.mq-empty` anyway.\n *\n * Live mathfields need none of this - MathLive manages empty slots itself.\n */\nconst EMPTY_SLOT = '\\\\htmlData{pie-empty=1}{\\\\rule{0.55em}{0.55em}}';\nconst EMPTY_GROUP_REGEX = /\\{\\s*\\}/g;\n// The smallest boxes are the ones in a subscript (`x_{}`, `\\log_{}`) or exponent\n// (`x^{}`): they sit at script size, so the 0.55em square reads cramped. They get\n// 0.4em more height, and `\\rule[-d]` decides which side it grows on:\n// - subscript / log base: all of it goes below, the top edge stays put;\n// - exponent: 0.3em goes above, plus 0.1em below.\nconst EMPTY_SUBSCRIPT_REGEX = /_\\{\\s*\\}/g;\nconst EMPTY_SUPERSCRIPT_REGEX = /\\^\\{\\s*\\}/g;\nconst EMPTY_SUBSCRIPT_SLOT = '\\\\htmlData{pie-empty=1}{\\\\rule[-0.4em]{0.55em}{0.95em}}';\n// The label clips what hangs below its line box (`overflow: hidden`), so the lowered\n// box needs a zero-width strut after it to make room, or its bottom is cut off.\nconst EMPTY_SUBSCRIPT_STRUT = '\\\\rule[-0.5em]{0em}{0.5em}';\nconst EMPTY_SUPERSCRIPT_SLOT = '\\\\htmlData{pie-empty=1}{\\\\rule[-0.1em]{0.55em}{0.95em}}';\n// The segment key (`\\overline{}`). The keypad centres every label in its cell, and\n// a thin bar is a much shorter label than the ray and line keys' stretchy arrows,\n// so by default both its bar and its box sit off from theirs: the bar is lower\n// than the arrows' shafts, and the box higher than theirs. Two zero-width struts\n// fix that, found by rendering the three keys at 14-28px and measuring:\n// - inside the bar, above the box: pushes the bar up to the height of the\n// arrows' shafts (the bar-to-box distance then matches theirs);\n// - before the bar, from the baseline: raises the label's top, which moves the\n// whole label down so the box lands where theirs does.\nconst EMPTY_OVERLINE_REGEX = /\\\\overline\\{\\s*\\}/g;\nconst EMPTY_OVERLINE_BAR_STRUT = '\\\\rule{0em}{0.87em}';\nconst EMPTY_OVERLINE_LABEL_STRUT = '\\\\rule{0em}{1.3em}';\n// Empty delimiter pairs: `\\abs{}` is converted to `\\left|\\right|`, and the\n// parenthesis / bracket keys are `\\left(\\right)` / `\\left[\\right]`. None has a\n// `{}` group for the rule above to catch, so they would render as bare fences.\nconst EMPTY_FENCE_REGEX = /\\\\left([([|])\\s*\\\\right([)\\]|])/g;\n// The same muted fill as the other slots (`pie-empty`), but a tall rectangle\n// rather than a square. It also sets the fences' height: `\\left...\\right` stretch\n// to their content, so a taller slot gives taller parentheses.\n//\n// A `\\rule` stands on the baseline, but the fences are centred on the math axis\n// (0.25em above it), so an un-lifted box sat high between them. `[-0.25em]`\n// lowers it by (axis - height / 2) = 0.25 - 1 / 2, centring it on the axis.\n//\n// Lowering it alone also shrinks the fences, which size themselves to their\n// content (MathLive switches to short bars). The zero-width `\\rule{0em}{1em}`\n// strut keeps the content as tall as before, so the bars keep their height and\n// only the box moves.\nconst EMPTY_FENCE_SLOT = '\\\\rule{0em}{1em}\\\\htmlData{pie-empty=1}{\\\\rule[-0.25em]{0.55em}{1em}}';\n\n/**\n * Make empty argument slots visible, for static rendering.\n *\n * Display-only: never feed the result to a mathfield or to storage - the\n * original latex is what gets typed and saved.\n *\n * @param {string} latex\n * @returns {string}\n */\nexport const withVisibleEmptySlots = (latex) =>\n (latex || '')\n .replace(EMPTY_OVERLINE_REGEX, `${EMPTY_OVERLINE_LABEL_STRUT}\\\\overline{${EMPTY_OVERLINE_BAR_STRUT}${EMPTY_SLOT}}`)\n .replace(EMPTY_SUBSCRIPT_REGEX, `_{${EMPTY_SUBSCRIPT_SLOT}}${EMPTY_SUBSCRIPT_STRUT}`)\n .replace(EMPTY_SUPERSCRIPT_REGEX, `^{${EMPTY_SUPERSCRIPT_SLOT}}`)\n .replace(EMPTY_GROUP_REGEX, `{${EMPTY_SLOT}}`)\n .replace(EMPTY_FENCE_REGEX, (_m, open, close) => `\\\\left${open}${EMPTY_FENCE_SLOT}\\\\right${close}`);\n\n/**\n * Pie commands that take an argument, and their native MathLive equivalents.\n *\n * These MUST NOT be handled as MathLive macros. A macro is serialised from the\n * arguments it was created with, so text typed inside its expansion never makes\n * it back out: `getValue('latex')` keeps returning `\\longdiv{\\placeholder{}}`\n * while `getValue('ascii-math')` shows the typed content. Setting\n * `captureSelection: false` lets the cursor in but does not change\n * serialisation.\n *\n * Expanding to native constructs instead gives real, editable atoms that\n * round-trip. All three targets are understood by MathJax too, so stored latex\n * still renders in @pie-lib/math-rendering without a reverse mapping.\n */\n/**\n * Rewrite argument-taking pie commands into native MathLive latex.\n * Applied on the way *into* a mathfield.\n *\n * @param {string} latex\n * @returns {string}\n */\nexport const toNativeCommands = (latex) => {\n if (typeof latex !== 'string' || !latex) {\n return latex || '';\n }\n\n let out = latex;\n\n // \\abs{x} -> \\left|x\\right| needs brace-aware handling, the rest are prefix\n // swaps.\n out = replaceAbs(out);\n out = out.replace(/\\\\longdiv\\{/g, '\\\\enclose{longdiv}{');\n out = out.replace(/\\\\overarc\\{/g, '\\\\overparen{');\n out = escapeBareComments(out);\n\n return out;\n};\n\n/**\n * Escape an unescaped `%`.\n *\n * In real LaTeX `%` starts a comment, so MathLive discards it *and everything\n * after it*: `50%` renders as `50`, and `x%y` as just `x`. MathQuill had no\n * such notion - it treated `%` as a symbol - so latex from anywhere outside the\n * keypad may still carry a bare one.\n *\n * Only a `%` preceded by an even number of backslashes is bare: `\\%` is already\n * escaped, while the `%` in `\\\\%` (a line break, then a comment) is not.\n *\n * @param {string} latex\n * @returns {string}\n */\nconst escapeBareComments = (latex) => {\n if (latex.indexOf('%') === -1) {\n return latex;\n }\n\n let out = '';\n // Consecutive backslashes immediately before the current character.\n let backslashes = 0;\n\n for (let i = 0; i < latex.length; i++) {\n const ch = latex[i];\n\n out += ch === '%' && backslashes % 2 === 0 ? '\\\\%' : ch;\n backslashes = ch === '\\\\' ? backslashes + 1 : 0;\n }\n\n return out;\n};\n\n/** `\\abs{x}` -> `\\left|x\\right|`, matching balanced braces. */\nconst replaceAbs = (latex) => {\n let out = latex;\n let idx = out.indexOf('\\\\abs{');\n\n while (idx !== -1) {\n const open = idx + '\\\\abs{'.length - 1;\n let depth = 0;\n let close = -1;\n\n for (let i = open; i < out.length; i++) {\n if (out[i] === '{') depth++;\n else if (out[i] === '}') {\n depth--;\n if (depth === 0) {\n close = i;\n break;\n }\n }\n }\n\n if (close === -1) {\n break;\n }\n\n const inner = out.slice(open + 1, close);\n\n out = `${out.slice(0, idx)}\\\\left|${inner}\\\\right|${out.slice(close + 1)}`;\n idx = out.indexOf('\\\\abs{');\n }\n\n return out;\n};\n\n/**\n * Ids of the answer blocks in a piece of stored latex, in document order.\n *\n * @param {string} latex\n * @returns {string[]}\n */\nexport const fieldIds = (latex) => {\n if (typeof latex !== 'string') {\n return [];\n }\n\n const out = [];\n let match;\n\n MQ_FIELD_REGEX.lastIndex = 0;\n\n while ((match = MQ_FIELD_REGEX.exec(latex)) !== null) {\n out.push(match[1] || DEFAULT_FIELD_ID);\n }\n\n return out;\n};\n\n/**\n * Convert stored latex (which may contain `\\embed{newLine}[]`) into latex that\n * MathLive can parse and render as multiple lines.\n *\n * @param {string} latex\n * @returns {string}\n */\nexport const toMathLive = (latex) => {\n if (typeof latex !== 'string' || !latex) {\n return latex || '';\n }\n\n // Argument-taking pie commands -> native constructs, so their content stays\n // editable and serialises back correctly (see toNativeCommands).\n let out = toNativeCommands(latex);\n\n // Answer blocks: \\MathQuillMathField[id]{x} -> \\placeholder[id]{x}\n out = out.replace(MQ_FIELD_REGEX, (_m, id, content) => `\\\\placeholder[${id || DEFAULT_FIELD_ID}]{${content}}`);\n\n // Newlines: \\embed{newLine}[] -> a multiline environment\n if (out.indexOf(NEWLINE_EMBED) !== -1) {\n out = `\\\\displaylines{${out.split(NEWLINE_EMBED_REGEX).join(' \\\\\\\\ ')}}`;\n }\n\n return out;\n};\n\n/**\n * Keypad command names that MathQuill treated as ALIASES of a different command.\n *\n * MathQuill registered `\\\\divide` as another name for `\\\\div` (and\n * `\\\\perpendicular` for `\\\\perp`), so pressing the key stored the real command.\n * MathLive only knows these names through `PIE_MACROS`, and serialises a macro\n * under its own name - so `\\\\divide` reached storage verbatim, where MathJax\n * (@pie-lib/math-rendering) has no such command and renders it as red text.\n *\n * Every other keypad command already matches what MathQuill stored (`\\\\degree`,\n * `\\\\nsim`, `\\\\ncong`, `\\\\nparallel`, `\\\\square`, `\\\\napprox`,\n * `\\\\parallelogram`), and MathJax understands those.\n */\nconst MATHQUILL_ALIASES = {\n '\\\\divide': '\\\\div',\n '\\\\perpendicular': '\\\\perp',\n};\n\n// Whole command names only: `\\\\divideontimes` is a real AMS symbol.\nconst MATHQUILL_ALIAS_REGEX = /\\\\(divide|perpendicular)(?![a-zA-Z])/g;\n\n/**\n * Primes. MathLive turns a prime that follows a base into a superscript atom and\n * serialises it as `^{\\\\prime}`, or `^{\\\\doubleprime}` for the keypad's double\n * prime key (`5''` comes back out as `5^{\\\\doubleprime}`). MathJax has no\n * `\\\\doubleprime`, and two adjacent `^{\\\\prime}` groups - what typing `'` twice\n * produces - are a \"double exponent\" error. MathQuill stored plain apostrophes,\n * which both MathJax and MathLive read as primes, so store those.\n *\n * Only a superscript made of primes alone is rewritten: `x^{\\\\prime 2}` keeps\n * its group, since it holds more than primes.\n */\nconst PRIME_SUPERSCRIPT_REGEX = /\\^\\{((?:\\s*\\\\(?:prime|doubleprime)(?![a-zA-Z]))+)\\s*\\}/g;\nconst BARE_DOUBLEPRIME_REGEX = /\\\\doubleprime(?![a-zA-Z])/g;\n\nconst primesToApostrophes = (primes) =>\n // eslint-disable-next-line quotes\n \"'\".repeat(\n (primes.match(/\\\\prime(?![a-zA-Z])/g) || []).length + 2 * (primes.match(BARE_DOUBLEPRIME_REGEX) || []).length,\n );\n\nconst BARE_PRIME_COMMAND_REGEX = /^\\\\(doubleprime|prime)(?![a-zA-Z])/;\n\n/**\n * Primes that are *not* in a superscript.\n *\n * MathLive emits bare `\\prime` / `\\doubleprime` for a `′` or `″` typed or pasted\n * as a character (`5′6″` serialises as `5\\prime6\\doubleprime`). A bare `\\prime`\n * is a full-size glyph in MathJax, while `''` is a superscript, so storing\n * `5\\prime6''` drew the single prime visibly larger than each stroke of the\n * double prime. Both become apostrophes, the superscript primes MathQuill\n * stored, so they always match.\n *\n * Inside a script (`x^{\\prime 2}`, `x^\\prime`) a prime is already a\n * superscript, and an apostrophe there would mean something else, so\n * `\\prime` is kept and `\\doubleprime` (unknown to MathJax) becomes\n * `\\prime\\prime`.\n *\n * @param {string} latex\n * @returns {string}\n */\nconst barePrimesToApostrophes = (latex) => {\n if (latex.indexOf('prime') === -1) {\n return latex;\n }\n\n // One entry per open brace: is that group a super/subscript?\n const groups = [];\n let out = '';\n let i = 0;\n\n while (i < latex.length) {\n const ch = latex[i];\n\n if (ch === '\\\\') {\n const match = latex.slice(i).match(BARE_PRIME_COMMAND_REGEX);\n\n if (match) {\n const isDouble = match[1] === 'doubleprime';\n // `x^\\prime`: the command is itself the script.\n const isScriptArgument = /[\\^_]\\s*$/.test(out);\n const inScript = isScriptArgument || groups.indexOf(true) !== -1;\n\n if (inScript) {\n out += isDouble ? '\\\\prime\\\\prime' : '\\\\prime';\n } else {\n // eslint-disable-next-line quotes\n out += isDouble ? \"''\" : \"'\";\n }\n\n i += match[0].length;\n continue;\n }\n\n // Copy any other command, or an escaped character such as `\\{`, whole.\n const command = latex.slice(i).match(/^\\\\(?:[a-zA-Z]+|.)/);\n const text = command ? command[0] : ch;\n\n out += text;\n i += text.length;\n continue;\n }\n\n if (ch === '{') {\n groups.push(/[\\^_]\\s*$/.test(out));\n } else if (ch === '}') {\n groups.pop();\n }\n\n out += ch;\n i += 1;\n }\n\n return out;\n};\n\n/**\n * Rewrite what MathLive serialises into the form MathQuill stored: alias\n * command names, and primes.\n *\n * @param {string} latex\n * @returns {string}\n */\nexport const toCanonicalCommands = (latex) =>\n typeof latex === 'string'\n ? barePrimesToApostrophes(\n latex\n .replace(MATHQUILL_ALIAS_REGEX, (m) => MATHQUILL_ALIASES[m])\n .replace(PRIME_SUPERSCRIPT_REGEX, (_m, primes) => primesToApostrophes(primes)),\n )\n : latex;\n\n/**\n * Convert latex out of MathLive back into the stored form, so items authored\n * with the MathLive editor remain readable by @pie-lib/math-rendering and by\n * the existing MathQuill implementation.\n *\n * @param {string} latex\n * @returns {string}\n */\nexport const fromMathLive = (latex) => {\n if (typeof latex !== 'string' || !latex) {\n return latex || '';\n }\n\n const match = latex.trim().match(DISPLAYLINES_REGEX);\n let out = match ? match[1] : latex;\n\n // `\\\\` is the line separator inside a multiline environment.\n if (out.indexOf('\\\\\\\\') !== -1) {\n out = out\n .split(/\\s*\\\\\\\\\\s*/)\n .map((s) => s.trim())\n .join(NEWLINE_EMBED);\n }\n\n // Answer blocks: \\placeholder[id]{x} -> \\MathQuillMathField[id]{x}\n out = out.replace(\n PLACEHOLDER_REGEX,\n (_m, id, content) => `\\\\MathQuillMathField[${id || DEFAULT_FIELD_ID}]{${content}}`,\n );\n\n // Unnamed placeholders are MathLive's own representation of an empty slot and\n // must not reach storage or MathJax. Unwrap them: keep any content, drop the\n // command itself (the surrounding braces are already part of the host latex,\n // so re-adding them here would produce `\\longdiv{{}}`).\n out = out.replace(BARE_PLACEHOLDER_REGEX, (_m, content) => content);\n out = out.replace(BARE_PLACEHOLDER_NO_ARG_REGEX, '');\n\n // Store the command MathQuill stored, not the alias - also heals latex that was\n // saved with `\\\\divide` before the keypad resolved it.\n return toCanonicalCommands(out);\n};\n\n/**\n * MathQuill `cmd()` semantics: commands that take arguments should land the\n * cursor inside the first argument. MathLive expresses that with `#?`\n * placeholders in the inserted latex.\n */\nconst COMMANDS_WITH_ARGS = {\n // An explicit \"blank over blank\" key: both slots start empty.\n '\\\\frac': '\\\\frac{#?}{#?}',\n // Division, which must behave like MathQuill's `/`: whatever precedes the\n // cursor becomes the numerator and the caret lands in the denominator. `#@`\n // is MathLive's token for \"the selection, or the item before the cursor\" -\n // this is exactly the template MathLive binds to the `/` key itself. Using\n // `#?` here instead produced an empty fraction and left the typed number\n // stranded outside it.\n '/': '\\\\frac{#@}{#?}',\n '\\\\sqrt': '\\\\sqrt{#?}',\n '\\\\nthroot': '\\\\sqrt[#?]{#?}',\n '\\\\overline': '\\\\overline{#?}',\n '\\\\overrightarrow': '\\\\overrightarrow{#?}',\n '\\\\overleftrightarrow': '\\\\overleftrightarrow{#?}',\n // Native forms, not the pie macros: a macro would not serialise the user's\n // typed content back out (see toNativeCommands).\n '\\\\overarc': '\\\\overparen{#?}',\n '\\\\longdiv': '\\\\enclose{longdiv}{#?}',\n '^': '^{#?}',\n _: '_{#?}',\n '(': '\\\\left(#?\\\\right)',\n '[': '\\\\left[#?\\\\right]',\n '|': '\\\\left|#?\\\\right|',\n};\n\n/**\n * MathQuill keystroke names -> MathLive command selectors.\n */\nconst KEYSTROKES = {\n Left: 'moveToPreviousChar',\n Right: 'moveToNextChar',\n Backspace: 'deleteBackward',\n Delete: 'deleteForward',\n Up: 'moveUp',\n Down: 'moveDown',\n};\n\n/**\n * Translate a keypad key definition into a MathLive action.\n *\n * Mirrors the precedence in @pie-lib/math-input's MathInput.keypadPress:\n * latex (unless a command is present) -> write -> command -> keystroke.\n *\n * @param {object} key\n * @returns {{type: 'insert'|'command', value: string}|undefined}\n */\nexport const keyToAction = (key) => {\n if (!key) {\n return undefined;\n }\n\n if (key.latex && !key.command) {\n return { type: 'insert', value: key.latex };\n }\n\n if (key.write) {\n return { type: 'insert', value: key.write };\n }\n\n if (key.command) {\n // Some keys carry an array of commands (e.g. Measured Angle is\n // ['m', '\\\\angle'], log-base-n is ['\\\\log', '_']). MathQuill's `cmd()`\n // applied them in sequence; MathLive inserts one latex string, so expand\n // each part and concatenate.\n const parts = Array.isArray(key.command) ? key.command : [key.command];\n const value = parts.map((c) => COMMANDS_WITH_ARGS[c] || MATHQUILL_ALIASES[c] || c).join('');\n\n return { type: 'insert', value };\n }\n\n if (key.keystroke) {\n const selector = KEYSTROKES[key.keystroke];\n\n return selector ? { type: 'command', value: selector } : undefined;\n }\n\n return undefined;\n};\n\nexport { COMMANDS_WITH_ARGS, KEYSTROKES, MATHQUILL_ALIASES };\n\n// TEMP: remove once confirmed that pie-elements picks up this build.\n// eslint-disable-next-line no-console\nconsole.log('[math-input-mathlive] latex-bridge loaded - taller sub/sup slots (PIE-1135 v2)');\n"],"mappings":"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","ignoreList":[]}
@@ -243,10 +243,24 @@ var PLACEHOLDER_LATEX = '\\placeholder{}';
243
243
  */
244
244
  var PLACEHOLDER_CARET_CSS = [":host(.".concat(PLACEHOLDER_CARET_CLASS, ") .ML__selected:not(:has(.ML__selected)){position:relative}"), ":host(.".concat(PLACEHOLDER_CARET_CLASS, ") .ML__selected:not(:has(.ML__selected))::after{"), 'content:"";position:absolute;left:50%;top:12%;height:76%;', 'border-right:2px solid var(--_caret-color, currentColor);', 'animation:ML__caret-blink 1.05s step-end forwards infinite}'].join('');
245
245
 
246
+ // MathLive sets the bar of `\overline{}` right on top of the content, so over an
247
+ // empty slot it touches the slot's box, while the ray and line arrows (stretchy
248
+ // accents) float clear of it. The bar is raised 0.33em, and the strut that sets
249
+ // the field's top edge is raised with it, or the bar would be clipped.
250
+ var OVERLINE_GAP_CSS = '.ML__latex .overline>.ML__vlist-t>.ML__vlist-r>.ML__vlist>span:has(>.overline-line){top:-4.15em !important}' + '.ML__latex:has(.overline)>.ML__strut{height:1.23em !important}';
251
+
252
+ // MathLive spaces a fraction's bar for text glyphs, whose ink sits tight against
253
+ // the baseline. An empty slot's box (`▢`) hangs lower than that, so the bar ends
254
+ // up much nearer the denominator's box than the numerator's (measured ~0.28em vs
255
+ // ~0.11em). Dropping the bar 0.08em evens the two gaps. Layout is untouched, so
256
+ // the numerator and denominator keep their positions; filled fractions (`1/2`)
257
+ // only see the bar move a hair.
258
+ var FRAC_BAR_CENTER_CSS = '.ML__latex .ML__frac-line{position:relative;top:0.08em}';
259
+
246
260
  // A live mathfield needs the readable radical index too: `rootIndexStyles` is
247
261
  // written for static markup in the host page, which cannot cross the shadow
248
262
  // boundary.
249
- var SHADOW_CSS = '.ML__latex .ML__center:has(.ML__stretchy){margin-left:0 !important}' + _commonStyles.ROOT_INDEX_CSS + _commonStyles.PARALLEL_CSS + PLACEHOLDER_CARET_CSS;
263
+ var SHADOW_CSS = '.ML__latex .ML__center:has(.ML__stretchy){margin-left:0 !important}' + _commonStyles.ROOT_INDEX_CSS + _commonStyles.PARALLEL_CSS + OVERLINE_GAP_CSS + FRAC_BAR_CENTER_CSS + PLACEHOLDER_CARET_CSS;
250
264
 
251
265
  /**
252
266
  * Keep {@link PLACEHOLDER_CARET_CLASS} in step with the selection.
@@ -1 +1 @@
1
- {"version":3,"file":"mathlive-instance.js","names":["_debug","_interopRequireDefault","require","_latexBridge","_commonStyles","_longdiv","ownKeys","e","r","t","Object","keys","getOwnPropertySymbols","o","filter","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","_interopRequireWildcard","WeakMap","n","__esModule","i","f","__proto__","_typeof","has","get","set","_t2","hasOwnProperty","call","log","debug","mathlive","fontsDirectory","absoluteFontsDirectory","dir","test","URL","document","baseURI","href","message","FALLBACK_MATHLIVE_VERSION","cdnFontsDirectory","version","concat","configureFonts","exports","MathfieldElement","undefined","MATH_MODE_SPACE","PIE_MACROS","parallelogram","parallel","napprox","nsim","ncong","nparallel","perpendicular","divide","degree","square","longdiv","overarc","abs","embeds","Map","KNOWN_EMBED_LATEX","newLine","answerBlock","loadWarned","configureLoaded","injectCoreStylesheet","PLACEHOLDER_CARET_CLASS","PLACEHOLDER_LATEX","PLACEHOLDER_CARET_CSS","join","SHADOW_CSS","ROOT_INDEX_CSS","PARALLEL_CSS","trackPlaceholderCaret","mathField","addEventListener","update","selected","selectionIsCollapsed","selection","getValue","classList","toggle","removeEventListener","applyShadowStyles","root","shadowRoot","CSSStyleSheet","__pieAccentSheet","sheet","replaceSync","adoptedStyleSheets","_toConsumableArray2","querySelector","style","createElement","setAttribute","textContent","appendChild","renderMathInElement","loadMathLiveSync","window","loadMathLive","_ref","_asyncToGenerator2","_regenerator","mark","_callee","_t","wrap","_context","prev","next","abrupt","Promise","resolve","then","sent","process","env","NODE_ENV","console","warn","stop","getMathLive","getMacros","out","_ref2","name","latex","registerEmbed","factory","definition","prototype","mathliveLatex","registeredEmbeds","Array","from","__resetEmbeds","clear","__setMathLiveForTest","stub","applyStaticMath","element","options","source","ml","loaded","isConnected","innerHTML","convertLatexToMarkup","withVisibleEmptySlots","toMathLive","macros","fixLongDivisionWhenReady","latexToMarkup"],"sources":["../src/mathlive-instance.js"],"sourcesContent":["import debug from 'debug';\nimport { NEWLINE_EMBED, toMathLive, withVisibleEmptySlots } from './latex-bridge';\nimport { ROOT_INDEX_CSS, PARALLEL_CSS } from './mf/common-styles';\nimport { fixLongDivisionWhenReady } from './longdiv';\n\nconst log = debug('pie-lib:math-input-mathlive:instance');\n\n/**\n * MathLive bootstrap + compatibility shims for @pie-lib/math-input's public API.\n *\n * MathLive is loaded lazily and only in the browser: the editor bundle is\n * ~227KB gzip and registers custom elements, so it must never run during SSR.\n */\n\nlet mathlive;\n\n/**\n * Where the KaTeX woff2 fonts are served from, as configured by the host app.\n * `undefined` means \"not configured\"; `null` means \"explicitly disabled\".\n */\nlet fontsDirectory;\n\n/**\n * Turn a fonts path into a fully-qualified URL.\n *\n * MathLive's default `fontsDirectory` is the relative `'./fonts/'`, which it\n * resolves against its own script URL. Under a bundler (webpack/Next) that\n * script URL is empty, so `new URL('./fonts/', '')` throws\n * \"Failed to construct 'URL': Invalid base URL\" from `loadFonts`.\n * Resolving against `document.baseURI` avoids that entirely and honours any\n * <base href> / asset prefix the host app uses.\n */\nconst absoluteFontsDirectory = (dir) => {\n if (!dir) {\n return dir;\n }\n\n // Already absolute (http://, https://, //cdn...) - MathLive handles these.\n if (/^(?:[a-z+]+:)?\\/\\//i.test(dir)) {\n return dir;\n }\n\n try {\n return new URL(dir, document.baseURI).href;\n } catch (e) {\n log('could not resolve fontsDirectory \"%s\": %s', dir, e && e.message);\n return null;\n }\n};\n\n/**\n * Version-pinned CDN fallback for the KaTeX fonts.\n *\n * Some symbols are composed from Private Use Area glyphs that exist only in\n * those fonts: `\\\\neq` is U+E020 (a negation slash) overlapped on `=`, and\n * `\\\\nsim` / `\\\\ncong` work the same way. With no fonts the browser substitutes\n * an arbitrary glyph for U+E020, so those keys render as garbage rather than\n * simply falling back to a plainer face.\n *\n * The version comes from MathLive itself, so the fonts always match the engine.\n * Hosts that would rather not depend on a third party should serve the fonts and\n * call `configureFonts('/their/path')`, or pass `null` to opt out.\n */\nconst FALLBACK_MATHLIVE_VERSION = '0.110.0';\n\nconst cdnFontsDirectory = () => {\n const version = (mathlive && mathlive.version && mathlive.version.mathlive) || FALLBACK_MATHLIVE_VERSION;\n\n // NOTE: `/fonts`, not `/dist/fonts` - the published package root holds them.\n return `https://unpkg.com/mathlive@${version}/fonts`;\n};\n\n/**\n * Tell the package where the MathLive fonts are served from.\n *\n * Call before `loadMathLive()`.\n *\n * - a path/URL: served by you, no third-party request\n * - `null`: skip font loading; note `\\\\neq`, `\\\\nsim` and `\\\\ncong` then\n * render incorrectly, being built from Private Use Area glyphs\n * - not called: falls back to a version-pinned CDN\n *\n * The fonts ship inside the `mathlive` package (`node_modules/mathlive/fonts`)\n * ready to copy into whatever the host app serves statically.\n *\n * @param {string|null} [dir]\n */\nexport const configureFonts = (dir) => {\n fontsDirectory = dir;\n\n if (mathlive) {\n mathlive.MathfieldElement.fontsDirectory = dir === undefined ? cdnFontsDirectory() : absoluteFontsDirectory(dir);\n }\n};\n\n/**\n * What the spacebar inserts in math mode.\n *\n * MathLive's `mathModeSpace` defaults to an empty string, which makes the\n * spacebar a no-op - users cannot type a space at all. `\\\\ ` (a LaTeX control\n * space) is what MathQuill serialised spaces as, so existing content and the\n * MathJax renderer in @pie-lib/math-rendering both already understand it.\n *\n * A literal \" \" is not usable: LaTeX skips raw whitespace.\n */\nexport const MATH_MODE_SPACE = '\\\\ ';\n\n/**\n * Custom macros for the pie-specific commands that the MathQuill fork\n * understood but stock LaTeX does not.\n *\n * Kept deliberately in sync with the MathJax macros in\n * @pie-lib/math-rendering (`render-math.js`) so the same latex renders the same\n * way in the editor and in the static renderer.\n */\nexport const PIE_MACROS = {\n // Argument-less symbols. Atomic is correct here: backspace should remove the\n // whole glyph, and there is nothing to type into.\n parallelogram: '\\\\htmlData{pie-macro=parallelogram}{\\\\unicode{\"25B1}}',\n // Same glyph as the built-in `\\\\parallel` (U+2225), tagged so it can be sized -\n // see `parallelStyles`.\n parallel: '\\\\htmlData{pie-macro=parallel}{\\\\unicode{\"2225}}',\n napprox: '\\\\not\\\\approx',\n nsim: '\\\\not\\\\sim',\n ncong: '\\\\not\\\\cong',\n nparallel: '\\\\not\\\\parallel',\n perpendicular: '\\\\perp',\n divide: '\\\\div',\n degree: '^{\\\\circ}',\n square: '\\\\unicode{\"25A1}',\n\n // Argument-taking commands, kept ONLY so previously authored latex still\n // parses and renders. They are never used for editing: MathLive serialises a\n // macro from the arguments it was created with, so text typed inside the\n // expansion never comes back out of `getValue('latex')`. Anything entering a\n // mathfield is rewritten to the native equivalent first - see\n // `toNativeCommands` in latex-bridge.\n longdiv: '\\\\enclose{longdiv}{#1}',\n overarc: '\\\\overparen{#1}',\n abs: '\\\\left|#1\\\\right|',\n};\n\n/**\n * Registry for `registerEmbed`.\n *\n * MathLive has no embed plugin system, so an embed is expressed as a macro that\n * expands to real LaTeX. `\\htmlData{embed=<name>}` tags the rendered output so\n * consumers can target it with CSS exactly as they targeted the old\n * `htmlString` markup.\n *\n * Known embeds map to native constructs:\n * - `newLine` -> structural, handled by latex-bridge (`\\displaylines` + `\\\\`)\n * - `answerBlock`-> `\\placeholder{}` (interactive, read via the prompts API)\n *\n * @type {Map<string, {factory: Function, latex: string}>}\n */\nconst embeds = new Map();\n\nconst KNOWN_EMBED_LATEX = {\n // newLine is structural: it is translated by latex-bridge before it ever\n // reaches MathLive, so the macro only needs to be harmless.\n newLine: '',\n answerBlock: '\\\\placeholder{}',\n};\n\nlet loadWarned = false;\n\n/** Apply post-load configuration exactly once. */\nconst configureLoaded = () => {\n // Always replace MathLive's relative `'./fonts/'` default: it throws\n // \"Invalid base URL\" when bundled. Use the host's copy if one was configured,\n // otherwise the version-pinned CDN.\n if (fontsDirectory === undefined) {\n log(\n 'no fontsDirectory configured - falling back to the CDN (%s). ' +\n 'Serve the fonts yourself and call configureFonts(\"/path/to/fonts\") to avoid the network request, ' +\n 'or configureFonts(null) to opt out.',\n cdnFontsDirectory(),\n );\n }\n\n mathlive.MathfieldElement.fontsDirectory =\n fontsDirectory === undefined ? cdnFontsDirectory() : absoluteFontsDirectory(fontsDirectory);\n\n injectCoreStylesheet();\n};\n\n/**\n * CSS that has to live *inside* a mathfield's shadow root.\n *\n * A live `<math-field>` renders in shadow DOM (`attachShadow({mode:'open'})`),\n * so nothing in the host page's stylesheets reaches it. The stretchy-accent\n * problem therefore needs fixing twice: once for static markup (see\n * `placeholderStyles`) and once here for the editor.\n *\n * MathLive centres an accent with `margin-left: <half the content width>` as an\n * inline style. For a stretchy accent that also shrinks its containing block\n * (`.ML__center` is position:relative), so the arc ends up half-width and offset\n * - visibly failing to span the text underneath.\n *\n * `:has(.ML__stretchy)` keeps the fix to stretchy accents; single-glyph accents\n * (`\\hat{x}`, `\\vec{x}`) still need their centring offset.\n */\n/**\n * Marker put on the host `<math-field>` while a `\\placeholder{}` is selected,\n * so the caret rules below apply to a placeholder and nothing else.\n */\nexport const PLACEHOLDER_CARET_CLASS = 'pie-caret-in-placeholder';\n\n/** What MathLive serialises a `#?` slot as. */\nconst PLACEHOLDER_LATEX = '\\\\placeholder{}';\n\n/**\n * A blinking caret inside a selected placeholder box.\n *\n * A keypad key such as `\\frac` inserts `\\frac{#?}{#?}`. MathLive turns each\n * `#?` into a `\\placeholder{}` atom and *selects* the first one. That atom is a\n * leaf - the offsets around it are \"before\" and \"after\", there is no position\n * inside it - so MathLive renders **no caret element at all** and shows only\n * the selection highlight. The box therefore looked focused (blue) but dead,\n * where MathQuill used to blink a cursor inside its empty box.\n *\n * So the caret is drawn here. `:not(:has(.ML__selected))` picks the innermost\n * selected element (MathLive puts the class on a wrapper *and* the glyph span,\n * which would otherwise give two carets), and the `ML__caret-blink` keyframes\n * plus `--_caret-color` are MathLive's own, already in this shadow root.\n *\n * Typing still replaces the whole placeholder, which for an empty box is\n * indistinguishable from inserting at the caret.\n */\nconst PLACEHOLDER_CARET_CSS = [\n `:host(.${PLACEHOLDER_CARET_CLASS}) .ML__selected:not(:has(.ML__selected)){position:relative}`,\n `:host(.${PLACEHOLDER_CARET_CLASS}) .ML__selected:not(:has(.ML__selected))::after{`,\n 'content:\"\";position:absolute;left:50%;top:12%;height:76%;',\n 'border-right:2px solid var(--_caret-color, currentColor);',\n 'animation:ML__caret-blink 1.05s step-end forwards infinite}',\n].join('');\n\n// A live mathfield needs the readable radical index too: `rootIndexStyles` is\n// written for static markup in the host page, which cannot cross the shadow\n// boundary.\nconst SHADOW_CSS =\n '.ML__latex .ML__center:has(.ML__stretchy){margin-left:0 !important}' +\n ROOT_INDEX_CSS +\n PARALLEL_CSS +\n PLACEHOLDER_CARET_CSS;\n\n/**\n * Keep {@link PLACEHOLDER_CARET_CLASS} in step with the selection.\n *\n * Gating on the class is what keeps the caret specific to placeholders: an\n * ordinary selection (`x+1`) must not sprout one. MathLive fires\n * `selection-change` for every caret move, including the one that lands on the\n * placeholder straight after an insert.\n *\n * @param {HTMLElement} mathField\n * @returns {function|undefined} teardown, to call on unmount\n */\nexport const trackPlaceholderCaret = (mathField) => {\n if (!mathField || typeof mathField.addEventListener !== 'function') {\n return undefined;\n }\n\n const update = () => {\n let selected = '';\n\n try {\n // A collapsed selection already has a real MathLive caret.\n if (!mathField.selectionIsCollapsed && mathField.selection) {\n selected = mathField.getValue(mathField.selection, 'latex');\n }\n } catch (e) {\n log('could not read the selection: %s', e && e.message);\n }\n\n if (mathField.classList) {\n mathField.classList.toggle(PLACEHOLDER_CARET_CLASS, selected === PLACEHOLDER_LATEX);\n }\n };\n\n mathField.addEventListener('selection-change', update);\n update();\n\n return () => mathField.removeEventListener('selection-change', update);\n};\n\n/**\n * Apply {@link SHADOW_CSS} inside a mathfield's shadow root.\n *\n * Uses `adoptedStyleSheets` when available (which is how MathLive loads its own\n * stylesheets) and falls back to appending a <style> node.\n *\n * @param {HTMLElement} mathField\n */\nexport const applyShadowStyles = (mathField) => {\n const root = mathField && mathField.shadowRoot;\n\n if (!root) {\n return;\n }\n\n try {\n if ('adoptedStyleSheets' in root && typeof CSSStyleSheet !== 'undefined') {\n // Do not re-add on a re-render.\n if (root.__pieAccentSheet) {\n return;\n }\n\n const sheet = new CSSStyleSheet();\n\n sheet.replaceSync(SHADOW_CSS);\n root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];\n root.__pieAccentSheet = sheet;\n\n return;\n }\n\n if (!root.querySelector('style[data-pie-accent]')) {\n const style = document.createElement('style');\n\n style.setAttribute('data-pie-accent', '');\n style.textContent = SHADOW_CSS;\n root.appendChild(style);\n }\n } catch (e) {\n log('could not apply shadow styles to the mathfield: %s', e && e.message);\n }\n};\n\n/**\n * Ensure MathLive's \"core\" stylesheet is in the document.\n *\n * `convertLatexToMarkup` - which renders keypad labels and static math - does\n * NOT inject it, while `renderMathInElement` and live mathfields do. Without it\n * the generated markup is unstyled: glyphs misalign and the <svg> used by\n * stretchy accents lays out statically at an unbounded width.\n *\n * Hosts that can import CSS should `import 'mathlive/static.css'`. For bundles\n * that cannot handle CSS imports (pie-elements ships JS-only web components),\n * this triggers MathLive's own injection against a detached element, so the\n * styles come from MathLive itself rather than being duplicated here.\n */\nconst injectCoreStylesheet = () => {\n if (typeof document === 'undefined' || !mathlive || !mathlive.renderMathInElement) {\n return;\n }\n\n try {\n mathlive.renderMathInElement(document.createElement('span'));\n } catch (e) {\n log('could not trigger MathLive core stylesheet injection: %s', e && e.message);\n }\n};\n\n/**\n * Load MathLive synchronously when the bundler allows it.\n *\n * `require` keeps MathLive inside the host's bundle. An `import()` would make\n * webpack emit a separate chunk, and a deployment that does not serve that\n * chunk fails with a 404 at runtime - leaving every mathfield and keypad label\n * blank with no obvious cause. Being in the main bundle also makes the engine\n * available on first render, so callers that run synchronously (applyStaticMath,\n * keypad labels) work without a second pass.\n *\n * Returns undefined during SSR or if the module is genuinely unavailable.\n *\n * @returns {object|undefined}\n */\nexport const loadMathLiveSync = () => {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n if (!mathlive) {\n try {\n // eslint-disable-next-line global-require\n mathlive = require('mathlive');\n configureLoaded();\n } catch (e) {\n log('synchronous MathLive load unavailable: %s', e && e.message);\n return undefined;\n }\n }\n\n return mathlive;\n};\n\n/**\n * Load MathLive. Prefers the synchronous path; falls back to a dynamic import.\n * Resolves to undefined during SSR.\n *\n * @returns {Promise<object|undefined>}\n */\nexport const loadMathLive = async () => {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n if (mathlive) {\n return mathlive;\n }\n\n if (loadMathLiveSync()) {\n return mathlive;\n }\n\n try {\n mathlive = await import('mathlive');\n configureLoaded();\n } catch (e) {\n // Surface this once: a silent failure here renders every field and keypad\n // label blank, which is very hard to trace back to a module load.\n // Skipped under test, where jsdom cannot load the browser build.\n if (!loadWarned && process.env.NODE_ENV !== 'test') {\n loadWarned = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[@pie-lib/math-input-mathlive] MathLive could not be loaded; math input will not render. ' +\n 'If this is a bundling issue, ensure \"mathlive\" is resolvable from the host bundle. Cause: ' +\n (e && e.message),\n );\n }\n\n return undefined;\n }\n\n return mathlive;\n};\n\n/**\n * Synchronous accessor for an already-loaded MathLive.\n * @returns {object|undefined}\n */\nexport const getMathLive = () => mathlive;\n\n/**\n * The macro dictionary to hand to a mathfield: pie macros plus anything\n * registered through `registerEmbed`.\n *\n * @returns {object}\n */\nexport const getMacros = () => {\n const out = { ...PIE_MACROS };\n\n embeds.forEach(({ latex }, name) => {\n out[name] = `\\\\htmlData{embed=${name}}{${latex}}`;\n });\n\n return out;\n};\n\n/**\n * Register an embed. API-compatible with @pie-lib/math-input's `registerEmbed`\n * so existing callers do not change.\n *\n * MathQuill's factory returns `{ htmlString, text, latex }`. Only the\n * declarative parts survive: `latex` round-trips through a macro and the\n * styling hook becomes a `data-embed` attribute. Arbitrary DOM injection via\n * `htmlString` has no MathLive equivalent and is ignored.\n *\n * @param {string} name\n * @param {Function} factory\n */\nexport function registerEmbed(name, factory) {\n if (!name || typeof factory !== 'function') {\n return;\n }\n\n let definition = {};\n\n try {\n definition = factory() || {};\n } catch (e) {\n log('embed factory threw for \"%s\": %s', name, e.message);\n }\n\n const latex = Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name)\n ? KNOWN_EMBED_LATEX[name]\n : definition.mathliveLatex || '\\\\placeholder{}';\n\n if (!Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name) && !definition.mathliveLatex) {\n // Unknown third-party embed: degrade instead of throwing. `htmlString`\n // cannot be reproduced, so it renders as an editable slot.\n log(\n 'embed \"%s\" is not natively supported by MathLive; rendering as a placeholder. ' +\n 'Provide `mathliveLatex` in the factory result to control this.',\n name,\n );\n }\n\n embeds.set(name, { factory, latex });\n}\n\n/**\n * Embeds registered so far. Exposed for tests/diagnostics.\n * @returns {string[]}\n */\nexport const registeredEmbeds = () => Array.from(embeds.keys());\n\n/** Reset the embed registry. Test helper. */\nexport const __resetEmbeds = () => embeds.clear();\n\n/** Inject a stub MathLive instance. Test helper. */\nexport const __setMathLiveForTest = (stub) => {\n mathlive = stub;\n};\n\n/**\n * Render static math into an element. API-compatible with\n * @pie-lib/math-input's `applyStaticMath`.\n *\n * Callers written against MathQuill invoke this synchronously from lifecycle\n * methods, where MathLive (a dynamic import) may not have loaded yet. Rather\n * than silently rendering nothing, this kicks off the load and re-applies once\n * the engine is ready, so the element fills in on the next tick.\n *\n * @param {HTMLElement} element\n * @param {string} [latex] assigned to the element before rendering\n * @param {object} [options] `{ macros }` overrides\n * @returns {HTMLElement|undefined} the element, or undefined if deferred\n */\nexport function applyStaticMath(element, latex, options = {}) {\n if (!element || typeof window === 'undefined') {\n return undefined;\n }\n\n // Capture the source now: if we defer, the element's textContent may have\n // been overwritten by the time MathLive is ready.\n const source = latex === undefined || latex === null ? element.textContent : latex;\n const ml = getMathLive() || loadMathLiveSync();\n\n if (!ml) {\n log('applyStaticMath called before MathLive loaded - deferring until it is ready');\n\n loadMathLive().then((loaded) => {\n // The element may have been unmounted while loading.\n if (loaded && element.isConnected !== false) {\n applyStaticMath(element, source, options);\n }\n });\n\n return undefined;\n }\n\n element.innerHTML = ml.convertLatexToMarkup(withVisibleEmptySlots(toMathLive(source)), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n });\n\n // MathLive misdraws long division (see longdiv.js).\n fixLongDivisionWhenReady(element);\n\n return element;\n}\n\n/**\n * Convert latex to markup using the pie macro set. Used for keypad labels and\n * any read-only rendering that does not need a live mathfield.\n *\n * @param {string} latex\n * @param {object} [options]\n * @returns {string} HTML markup, or '' if MathLive is not loaded\n */\nexport function latexToMarkup(latex, options = {}) {\n // Try the synchronous load so the very first render can produce markup\n // instead of falling back to raw latex.\n const ml = getMathLive() || loadMathLiveSync();\n\n if (!ml || !latex) {\n return '';\n }\n\n try {\n // Empty groups render as nothing in static markup, so give them a visible\n // box. This covers every static path: keypad labels, mf.Static in display\n // mode, and applyStaticMath.\n return ml.convertLatexToMarkup(withVisibleEmptySlots(toMathLive(latex)), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n ...options,\n });\n } catch (e) {\n log('convertLatexToMarkup failed for \"%s\": %s', latex, e.message);\n return '';\n }\n}\n\nexport { NEWLINE_EMBED };\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"mathlive-instance.js","names":["_debug","_interopRequireDefault","require","_latexBridge","_commonStyles","_longdiv","ownKeys","e","r","t","Object","keys","getOwnPropertySymbols","o","filter","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","_interopRequireWildcard","WeakMap","n","__esModule","i","f","__proto__","_typeof","has","get","set","_t2","hasOwnProperty","call","log","debug","mathlive","fontsDirectory","absoluteFontsDirectory","dir","test","URL","document","baseURI","href","message","FALLBACK_MATHLIVE_VERSION","cdnFontsDirectory","version","concat","configureFonts","exports","MathfieldElement","undefined","MATH_MODE_SPACE","PIE_MACROS","parallelogram","parallel","napprox","nsim","ncong","nparallel","perpendicular","divide","degree","square","longdiv","overarc","abs","embeds","Map","KNOWN_EMBED_LATEX","newLine","answerBlock","loadWarned","configureLoaded","injectCoreStylesheet","PLACEHOLDER_CARET_CLASS","PLACEHOLDER_LATEX","PLACEHOLDER_CARET_CSS","join","OVERLINE_GAP_CSS","FRAC_BAR_CENTER_CSS","SHADOW_CSS","ROOT_INDEX_CSS","PARALLEL_CSS","trackPlaceholderCaret","mathField","addEventListener","update","selected","selectionIsCollapsed","selection","getValue","classList","toggle","removeEventListener","applyShadowStyles","root","shadowRoot","CSSStyleSheet","__pieAccentSheet","sheet","replaceSync","adoptedStyleSheets","_toConsumableArray2","querySelector","style","createElement","setAttribute","textContent","appendChild","renderMathInElement","loadMathLiveSync","window","loadMathLive","_ref","_asyncToGenerator2","_regenerator","mark","_callee","_t","wrap","_context","prev","next","abrupt","Promise","resolve","then","sent","process","env","NODE_ENV","console","warn","stop","getMathLive","getMacros","out","_ref2","name","latex","registerEmbed","factory","definition","prototype","mathliveLatex","registeredEmbeds","Array","from","__resetEmbeds","clear","__setMathLiveForTest","stub","applyStaticMath","element","options","source","ml","loaded","isConnected","innerHTML","convertLatexToMarkup","withVisibleEmptySlots","toMathLive","macros","fixLongDivisionWhenReady","latexToMarkup"],"sources":["../src/mathlive-instance.js"],"sourcesContent":["import debug from 'debug';\nimport { NEWLINE_EMBED, toMathLive, withVisibleEmptySlots } from './latex-bridge';\nimport { ROOT_INDEX_CSS, PARALLEL_CSS } from './mf/common-styles';\nimport { fixLongDivisionWhenReady } from './longdiv';\n\nconst log = debug('pie-lib:math-input-mathlive:instance');\n\n/**\n * MathLive bootstrap + compatibility shims for @pie-lib/math-input's public API.\n *\n * MathLive is loaded lazily and only in the browser: the editor bundle is\n * ~227KB gzip and registers custom elements, so it must never run during SSR.\n */\n\nlet mathlive;\n\n/**\n * Where the KaTeX woff2 fonts are served from, as configured by the host app.\n * `undefined` means \"not configured\"; `null` means \"explicitly disabled\".\n */\nlet fontsDirectory;\n\n/**\n * Turn a fonts path into a fully-qualified URL.\n *\n * MathLive's default `fontsDirectory` is the relative `'./fonts/'`, which it\n * resolves against its own script URL. Under a bundler (webpack/Next) that\n * script URL is empty, so `new URL('./fonts/', '')` throws\n * \"Failed to construct 'URL': Invalid base URL\" from `loadFonts`.\n * Resolving against `document.baseURI` avoids that entirely and honours any\n * <base href> / asset prefix the host app uses.\n */\nconst absoluteFontsDirectory = (dir) => {\n if (!dir) {\n return dir;\n }\n\n // Already absolute (http://, https://, //cdn...) - MathLive handles these.\n if (/^(?:[a-z+]+:)?\\/\\//i.test(dir)) {\n return dir;\n }\n\n try {\n return new URL(dir, document.baseURI).href;\n } catch (e) {\n log('could not resolve fontsDirectory \"%s\": %s', dir, e && e.message);\n return null;\n }\n};\n\n/**\n * Version-pinned CDN fallback for the KaTeX fonts.\n *\n * Some symbols are composed from Private Use Area glyphs that exist only in\n * those fonts: `\\\\neq` is U+E020 (a negation slash) overlapped on `=`, and\n * `\\\\nsim` / `\\\\ncong` work the same way. With no fonts the browser substitutes\n * an arbitrary glyph for U+E020, so those keys render as garbage rather than\n * simply falling back to a plainer face.\n *\n * The version comes from MathLive itself, so the fonts always match the engine.\n * Hosts that would rather not depend on a third party should serve the fonts and\n * call `configureFonts('/their/path')`, or pass `null` to opt out.\n */\nconst FALLBACK_MATHLIVE_VERSION = '0.110.0';\n\nconst cdnFontsDirectory = () => {\n const version = (mathlive && mathlive.version && mathlive.version.mathlive) || FALLBACK_MATHLIVE_VERSION;\n\n // NOTE: `/fonts`, not `/dist/fonts` - the published package root holds them.\n return `https://unpkg.com/mathlive@${version}/fonts`;\n};\n\n/**\n * Tell the package where the MathLive fonts are served from.\n *\n * Call before `loadMathLive()`.\n *\n * - a path/URL: served by you, no third-party request\n * - `null`: skip font loading; note `\\\\neq`, `\\\\nsim` and `\\\\ncong` then\n * render incorrectly, being built from Private Use Area glyphs\n * - not called: falls back to a version-pinned CDN\n *\n * The fonts ship inside the `mathlive` package (`node_modules/mathlive/fonts`)\n * ready to copy into whatever the host app serves statically.\n *\n * @param {string|null} [dir]\n */\nexport const configureFonts = (dir) => {\n fontsDirectory = dir;\n\n if (mathlive) {\n mathlive.MathfieldElement.fontsDirectory = dir === undefined ? cdnFontsDirectory() : absoluteFontsDirectory(dir);\n }\n};\n\n/**\n * What the spacebar inserts in math mode.\n *\n * MathLive's `mathModeSpace` defaults to an empty string, which makes the\n * spacebar a no-op - users cannot type a space at all. `\\\\ ` (a LaTeX control\n * space) is what MathQuill serialised spaces as, so existing content and the\n * MathJax renderer in @pie-lib/math-rendering both already understand it.\n *\n * A literal \" \" is not usable: LaTeX skips raw whitespace.\n */\nexport const MATH_MODE_SPACE = '\\\\ ';\n\n/**\n * Custom macros for the pie-specific commands that the MathQuill fork\n * understood but stock LaTeX does not.\n *\n * Kept deliberately in sync with the MathJax macros in\n * @pie-lib/math-rendering (`render-math.js`) so the same latex renders the same\n * way in the editor and in the static renderer.\n */\nexport const PIE_MACROS = {\n // Argument-less symbols. Atomic is correct here: backspace should remove the\n // whole glyph, and there is nothing to type into.\n parallelogram: '\\\\htmlData{pie-macro=parallelogram}{\\\\unicode{\"25B1}}',\n // Same glyph as the built-in `\\\\parallel` (U+2225), tagged so it can be sized -\n // see `parallelStyles`.\n parallel: '\\\\htmlData{pie-macro=parallel}{\\\\unicode{\"2225}}',\n napprox: '\\\\not\\\\approx',\n nsim: '\\\\not\\\\sim',\n ncong: '\\\\not\\\\cong',\n nparallel: '\\\\not\\\\parallel',\n perpendicular: '\\\\perp',\n divide: '\\\\div',\n degree: '^{\\\\circ}',\n square: '\\\\unicode{\"25A1}',\n\n // Argument-taking commands, kept ONLY so previously authored latex still\n // parses and renders. They are never used for editing: MathLive serialises a\n // macro from the arguments it was created with, so text typed inside the\n // expansion never comes back out of `getValue('latex')`. Anything entering a\n // mathfield is rewritten to the native equivalent first - see\n // `toNativeCommands` in latex-bridge.\n longdiv: '\\\\enclose{longdiv}{#1}',\n overarc: '\\\\overparen{#1}',\n abs: '\\\\left|#1\\\\right|',\n};\n\n/**\n * Registry for `registerEmbed`.\n *\n * MathLive has no embed plugin system, so an embed is expressed as a macro that\n * expands to real LaTeX. `\\htmlData{embed=<name>}` tags the rendered output so\n * consumers can target it with CSS exactly as they targeted the old\n * `htmlString` markup.\n *\n * Known embeds map to native constructs:\n * - `newLine` -> structural, handled by latex-bridge (`\\displaylines` + `\\\\`)\n * - `answerBlock`-> `\\placeholder{}` (interactive, read via the prompts API)\n *\n * @type {Map<string, {factory: Function, latex: string}>}\n */\nconst embeds = new Map();\n\nconst KNOWN_EMBED_LATEX = {\n // newLine is structural: it is translated by latex-bridge before it ever\n // reaches MathLive, so the macro only needs to be harmless.\n newLine: '',\n answerBlock: '\\\\placeholder{}',\n};\n\nlet loadWarned = false;\n\n/** Apply post-load configuration exactly once. */\nconst configureLoaded = () => {\n // Always replace MathLive's relative `'./fonts/'` default: it throws\n // \"Invalid base URL\" when bundled. Use the host's copy if one was configured,\n // otherwise the version-pinned CDN.\n if (fontsDirectory === undefined) {\n log(\n 'no fontsDirectory configured - falling back to the CDN (%s). ' +\n 'Serve the fonts yourself and call configureFonts(\"/path/to/fonts\") to avoid the network request, ' +\n 'or configureFonts(null) to opt out.',\n cdnFontsDirectory(),\n );\n }\n\n mathlive.MathfieldElement.fontsDirectory =\n fontsDirectory === undefined ? cdnFontsDirectory() : absoluteFontsDirectory(fontsDirectory);\n\n injectCoreStylesheet();\n};\n\n/**\n * CSS that has to live *inside* a mathfield's shadow root.\n *\n * A live `<math-field>` renders in shadow DOM (`attachShadow({mode:'open'})`),\n * so nothing in the host page's stylesheets reaches it. The stretchy-accent\n * problem therefore needs fixing twice: once for static markup (see\n * `placeholderStyles`) and once here for the editor.\n *\n * MathLive centres an accent with `margin-left: <half the content width>` as an\n * inline style. For a stretchy accent that also shrinks its containing block\n * (`.ML__center` is position:relative), so the arc ends up half-width and offset\n * - visibly failing to span the text underneath.\n *\n * `:has(.ML__stretchy)` keeps the fix to stretchy accents; single-glyph accents\n * (`\\hat{x}`, `\\vec{x}`) still need their centring offset.\n */\n/**\n * Marker put on the host `<math-field>` while a `\\placeholder{}` is selected,\n * so the caret rules below apply to a placeholder and nothing else.\n */\nexport const PLACEHOLDER_CARET_CLASS = 'pie-caret-in-placeholder';\n\n/** What MathLive serialises a `#?` slot as. */\nconst PLACEHOLDER_LATEX = '\\\\placeholder{}';\n\n/**\n * A blinking caret inside a selected placeholder box.\n *\n * A keypad key such as `\\frac` inserts `\\frac{#?}{#?}`. MathLive turns each\n * `#?` into a `\\placeholder{}` atom and *selects* the first one. That atom is a\n * leaf - the offsets around it are \"before\" and \"after\", there is no position\n * inside it - so MathLive renders **no caret element at all** and shows only\n * the selection highlight. The box therefore looked focused (blue) but dead,\n * where MathQuill used to blink a cursor inside its empty box.\n *\n * So the caret is drawn here. `:not(:has(.ML__selected))` picks the innermost\n * selected element (MathLive puts the class on a wrapper *and* the glyph span,\n * which would otherwise give two carets), and the `ML__caret-blink` keyframes\n * plus `--_caret-color` are MathLive's own, already in this shadow root.\n *\n * Typing still replaces the whole placeholder, which for an empty box is\n * indistinguishable from inserting at the caret.\n */\nconst PLACEHOLDER_CARET_CSS = [\n `:host(.${PLACEHOLDER_CARET_CLASS}) .ML__selected:not(:has(.ML__selected)){position:relative}`,\n `:host(.${PLACEHOLDER_CARET_CLASS}) .ML__selected:not(:has(.ML__selected))::after{`,\n 'content:\"\";position:absolute;left:50%;top:12%;height:76%;',\n 'border-right:2px solid var(--_caret-color, currentColor);',\n 'animation:ML__caret-blink 1.05s step-end forwards infinite}',\n].join('');\n\n// MathLive sets the bar of `\\overline{}` right on top of the content, so over an\n// empty slot it touches the slot's box, while the ray and line arrows (stretchy\n// accents) float clear of it. The bar is raised 0.33em, and the strut that sets\n// the field's top edge is raised with it, or the bar would be clipped.\nconst OVERLINE_GAP_CSS =\n '.ML__latex .overline>.ML__vlist-t>.ML__vlist-r>.ML__vlist>span:has(>.overline-line){top:-4.15em !important}' +\n '.ML__latex:has(.overline)>.ML__strut{height:1.23em !important}';\n\n// MathLive spaces a fraction's bar for text glyphs, whose ink sits tight against\n// the baseline. An empty slot's box (`▢`) hangs lower than that, so the bar ends\n// up much nearer the denominator's box than the numerator's (measured ~0.28em vs\n// ~0.11em). Dropping the bar 0.08em evens the two gaps. Layout is untouched, so\n// the numerator and denominator keep their positions; filled fractions (`1/2`)\n// only see the bar move a hair.\nconst FRAC_BAR_CENTER_CSS = '.ML__latex .ML__frac-line{position:relative;top:0.08em}';\n\n// A live mathfield needs the readable radical index too: `rootIndexStyles` is\n// written for static markup in the host page, which cannot cross the shadow\n// boundary.\nconst SHADOW_CSS =\n '.ML__latex .ML__center:has(.ML__stretchy){margin-left:0 !important}' +\n ROOT_INDEX_CSS +\n PARALLEL_CSS +\n OVERLINE_GAP_CSS +\n FRAC_BAR_CENTER_CSS +\n PLACEHOLDER_CARET_CSS;\n\n/**\n * Keep {@link PLACEHOLDER_CARET_CLASS} in step with the selection.\n *\n * Gating on the class is what keeps the caret specific to placeholders: an\n * ordinary selection (`x+1`) must not sprout one. MathLive fires\n * `selection-change` for every caret move, including the one that lands on the\n * placeholder straight after an insert.\n *\n * @param {HTMLElement} mathField\n * @returns {function|undefined} teardown, to call on unmount\n */\nexport const trackPlaceholderCaret = (mathField) => {\n if (!mathField || typeof mathField.addEventListener !== 'function') {\n return undefined;\n }\n\n const update = () => {\n let selected = '';\n\n try {\n // A collapsed selection already has a real MathLive caret.\n if (!mathField.selectionIsCollapsed && mathField.selection) {\n selected = mathField.getValue(mathField.selection, 'latex');\n }\n } catch (e) {\n log('could not read the selection: %s', e && e.message);\n }\n\n if (mathField.classList) {\n mathField.classList.toggle(PLACEHOLDER_CARET_CLASS, selected === PLACEHOLDER_LATEX);\n }\n };\n\n mathField.addEventListener('selection-change', update);\n update();\n\n return () => mathField.removeEventListener('selection-change', update);\n};\n\n/**\n * Apply {@link SHADOW_CSS} inside a mathfield's shadow root.\n *\n * Uses `adoptedStyleSheets` when available (which is how MathLive loads its own\n * stylesheets) and falls back to appending a <style> node.\n *\n * @param {HTMLElement} mathField\n */\nexport const applyShadowStyles = (mathField) => {\n const root = mathField && mathField.shadowRoot;\n\n if (!root) {\n return;\n }\n\n try {\n if ('adoptedStyleSheets' in root && typeof CSSStyleSheet !== 'undefined') {\n // Do not re-add on a re-render.\n if (root.__pieAccentSheet) {\n return;\n }\n\n const sheet = new CSSStyleSheet();\n\n sheet.replaceSync(SHADOW_CSS);\n root.adoptedStyleSheets = [...root.adoptedStyleSheets, sheet];\n root.__pieAccentSheet = sheet;\n\n return;\n }\n\n if (!root.querySelector('style[data-pie-accent]')) {\n const style = document.createElement('style');\n\n style.setAttribute('data-pie-accent', '');\n style.textContent = SHADOW_CSS;\n root.appendChild(style);\n }\n } catch (e) {\n log('could not apply shadow styles to the mathfield: %s', e && e.message);\n }\n};\n\n/**\n * Ensure MathLive's \"core\" stylesheet is in the document.\n *\n * `convertLatexToMarkup` - which renders keypad labels and static math - does\n * NOT inject it, while `renderMathInElement` and live mathfields do. Without it\n * the generated markup is unstyled: glyphs misalign and the <svg> used by\n * stretchy accents lays out statically at an unbounded width.\n *\n * Hosts that can import CSS should `import 'mathlive/static.css'`. For bundles\n * that cannot handle CSS imports (pie-elements ships JS-only web components),\n * this triggers MathLive's own injection against a detached element, so the\n * styles come from MathLive itself rather than being duplicated here.\n */\nconst injectCoreStylesheet = () => {\n if (typeof document === 'undefined' || !mathlive || !mathlive.renderMathInElement) {\n return;\n }\n\n try {\n mathlive.renderMathInElement(document.createElement('span'));\n } catch (e) {\n log('could not trigger MathLive core stylesheet injection: %s', e && e.message);\n }\n};\n\n/**\n * Load MathLive synchronously when the bundler allows it.\n *\n * `require` keeps MathLive inside the host's bundle. An `import()` would make\n * webpack emit a separate chunk, and a deployment that does not serve that\n * chunk fails with a 404 at runtime - leaving every mathfield and keypad label\n * blank with no obvious cause. Being in the main bundle also makes the engine\n * available on first render, so callers that run synchronously (applyStaticMath,\n * keypad labels) work without a second pass.\n *\n * Returns undefined during SSR or if the module is genuinely unavailable.\n *\n * @returns {object|undefined}\n */\nexport const loadMathLiveSync = () => {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n if (!mathlive) {\n try {\n // eslint-disable-next-line global-require\n mathlive = require('mathlive');\n configureLoaded();\n } catch (e) {\n log('synchronous MathLive load unavailable: %s', e && e.message);\n return undefined;\n }\n }\n\n return mathlive;\n};\n\n/**\n * Load MathLive. Prefers the synchronous path; falls back to a dynamic import.\n * Resolves to undefined during SSR.\n *\n * @returns {Promise<object|undefined>}\n */\nexport const loadMathLive = async () => {\n if (typeof window === 'undefined') {\n return undefined;\n }\n\n if (mathlive) {\n return mathlive;\n }\n\n if (loadMathLiveSync()) {\n return mathlive;\n }\n\n try {\n mathlive = await import('mathlive');\n configureLoaded();\n } catch (e) {\n // Surface this once: a silent failure here renders every field and keypad\n // label blank, which is very hard to trace back to a module load.\n // Skipped under test, where jsdom cannot load the browser build.\n if (!loadWarned && process.env.NODE_ENV !== 'test') {\n loadWarned = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[@pie-lib/math-input-mathlive] MathLive could not be loaded; math input will not render. ' +\n 'If this is a bundling issue, ensure \"mathlive\" is resolvable from the host bundle. Cause: ' +\n (e && e.message),\n );\n }\n\n return undefined;\n }\n\n return mathlive;\n};\n\n/**\n * Synchronous accessor for an already-loaded MathLive.\n * @returns {object|undefined}\n */\nexport const getMathLive = () => mathlive;\n\n/**\n * The macro dictionary to hand to a mathfield: pie macros plus anything\n * registered through `registerEmbed`.\n *\n * @returns {object}\n */\nexport const getMacros = () => {\n const out = { ...PIE_MACROS };\n\n embeds.forEach(({ latex }, name) => {\n out[name] = `\\\\htmlData{embed=${name}}{${latex}}`;\n });\n\n return out;\n};\n\n/**\n * Register an embed. API-compatible with @pie-lib/math-input's `registerEmbed`\n * so existing callers do not change.\n *\n * MathQuill's factory returns `{ htmlString, text, latex }`. Only the\n * declarative parts survive: `latex` round-trips through a macro and the\n * styling hook becomes a `data-embed` attribute. Arbitrary DOM injection via\n * `htmlString` has no MathLive equivalent and is ignored.\n *\n * @param {string} name\n * @param {Function} factory\n */\nexport function registerEmbed(name, factory) {\n if (!name || typeof factory !== 'function') {\n return;\n }\n\n let definition = {};\n\n try {\n definition = factory() || {};\n } catch (e) {\n log('embed factory threw for \"%s\": %s', name, e.message);\n }\n\n const latex = Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name)\n ? KNOWN_EMBED_LATEX[name]\n : definition.mathliveLatex || '\\\\placeholder{}';\n\n if (!Object.prototype.hasOwnProperty.call(KNOWN_EMBED_LATEX, name) && !definition.mathliveLatex) {\n // Unknown third-party embed: degrade instead of throwing. `htmlString`\n // cannot be reproduced, so it renders as an editable slot.\n log(\n 'embed \"%s\" is not natively supported by MathLive; rendering as a placeholder. ' +\n 'Provide `mathliveLatex` in the factory result to control this.',\n name,\n );\n }\n\n embeds.set(name, { factory, latex });\n}\n\n/**\n * Embeds registered so far. Exposed for tests/diagnostics.\n * @returns {string[]}\n */\nexport const registeredEmbeds = () => Array.from(embeds.keys());\n\n/** Reset the embed registry. Test helper. */\nexport const __resetEmbeds = () => embeds.clear();\n\n/** Inject a stub MathLive instance. Test helper. */\nexport const __setMathLiveForTest = (stub) => {\n mathlive = stub;\n};\n\n/**\n * Render static math into an element. API-compatible with\n * @pie-lib/math-input's `applyStaticMath`.\n *\n * Callers written against MathQuill invoke this synchronously from lifecycle\n * methods, where MathLive (a dynamic import) may not have loaded yet. Rather\n * than silently rendering nothing, this kicks off the load and re-applies once\n * the engine is ready, so the element fills in on the next tick.\n *\n * @param {HTMLElement} element\n * @param {string} [latex] assigned to the element before rendering\n * @param {object} [options] `{ macros }` overrides\n * @returns {HTMLElement|undefined} the element, or undefined if deferred\n */\nexport function applyStaticMath(element, latex, options = {}) {\n if (!element || typeof window === 'undefined') {\n return undefined;\n }\n\n // Capture the source now: if we defer, the element's textContent may have\n // been overwritten by the time MathLive is ready.\n const source = latex === undefined || latex === null ? element.textContent : latex;\n const ml = getMathLive() || loadMathLiveSync();\n\n if (!ml) {\n log('applyStaticMath called before MathLive loaded - deferring until it is ready');\n\n loadMathLive().then((loaded) => {\n // The element may have been unmounted while loading.\n if (loaded && element.isConnected !== false) {\n applyStaticMath(element, source, options);\n }\n });\n\n return undefined;\n }\n\n element.innerHTML = ml.convertLatexToMarkup(withVisibleEmptySlots(toMathLive(source)), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n });\n\n // MathLive misdraws long division (see longdiv.js).\n fixLongDivisionWhenReady(element);\n\n return element;\n}\n\n/**\n * Convert latex to markup using the pie macro set. Used for keypad labels and\n * any read-only rendering that does not need a live mathfield.\n *\n * @param {string} latex\n * @param {object} [options]\n * @returns {string} HTML markup, or '' if MathLive is not loaded\n */\nexport function latexToMarkup(latex, options = {}) {\n // Try the synchronous load so the very first render can produce markup\n // instead of falling back to raw latex.\n const ml = getMathLive() || loadMathLiveSync();\n\n if (!ml || !latex) {\n return '';\n }\n\n try {\n // Empty groups render as nothing in static markup, so give them a visible\n // box. This covers every static path: keypad labels, mf.Static in display\n // mode, and applyStaticMath.\n return ml.convertLatexToMarkup(withVisibleEmptySlots(toMathLive(latex)), {\n macros: { ...getMacros(), ...(options.macros || {}) },\n ...options,\n });\n } catch (e) {\n log('convertLatexToMarkup failed for \"%s\": %s', latex, e.message);\n return '';\n }\n}\n\nexport { NEWLINE_EMBED };\n"],"mappings":"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","ignoreList":[]}
@@ -116,6 +116,25 @@ var placeholderStyles = exports.placeholderStyles = {
116
116
  '& [data-pie-empty]': {
117
117
  opacity: 0.5
118
118
  },
119
+ // A fraction with an empty slot: MathLive spaces the bar for text, but the
120
+ // slot's box is a taller `\rule`, so the bar hugs the numerator's box (~0.2em
121
+ // above vs ~0.4em below). Dropping the bar 0.16em (0.13em when the numerator is not an empty slot or follows an `x`) centres it between the two
122
+ // boxes. Only the bar moves, not the slots.
123
+ '& .ML__mfrac:has([data-pie-empty]) .ML__frac-line': {
124
+ position: 'relative',
125
+ top: '0.16em'
126
+ },
127
+ // A real numerator (`x`) is lighter than an empty box and its ink ends at the
128
+ // baseline, so the full drop overshoots: it needs a smaller drop. The numerator is
129
+ // the second `.ML__center` (MathLive emits the denominator first).
130
+ '& .ML__mfrac:has([data-pie-empty]):not(:has(.ML__center ~ .ML__center [data-pie-empty])) .ML__frac-line': {
131
+ top: '0.13em'
132
+ },
133
+ // Same for a mixed number (`x` then the fraction): the leading `x` is a sibling
134
+ // of the fraction, which a lone `\frac{}{}` does not have.
135
+ '& .ML__mfrac:has([data-pie-empty]):not(:only-child) .ML__frac-line': {
136
+ top: '0.13em'
137
+ },
119
138
  // Stretchy accents (\overarc, \overleftrightarrow, \overrightarrow) render an
120
139
  // <svg width="100%" preserveAspectRatio="none"> inside a `.ML__stretchy`. That
121
140
  // span is absolutely positioned, so its immediate wrapper computes to 0px and
@@ -1 +1 @@
1
- {"version":3,"file":"common-styles.js","names":["commonMqFontStyles","exports","fontFamily","longdivStyles","display","ROOT_INDEX_SELECTOR","ROOT_INDEX_FONT_SIZE","rootIndexStyles","_defineProperty2","concat","fontSize","ROOT_INDEX_CSS","PARALLEL_SELECTOR","PARALLEL_FONT_SIZE","parallelStyles","PARALLEL_CSS","supsubStyles","_objectSpread","placeholderStyles","borderBottom","minWidth","opacity","position","left","width","marginLeft","commonMqKeyboardStyles","touchAction","outline","commonMathLiveStyles","commonKeyboardStyles","_default"],"sources":["../../src/mf/common-styles.js"],"sourcesContent":["/**\n * Shared MathLive styling.\n *\n * Replaces @pie-lib/math-input's `common-mq-styles.js`. That file was built\n * around MathQuill's `.mq-*` class names, none of which exist in MathLive\n * output, so the selectors here target MathLive's own structure instead.\n *\n * The four named groups are kept because consumers destructure them:\n *\n * const { commonMqFontStyles, commonMqKeyboardStyles, longdivStyles, supsubStyles }\n * = mq.CommonMqStyles; // math-toolbar/src/editor-and-pad.jsx, math-preview.jsx\n *\n * Most are intentionally near-empty: MathLive sizes scripts, radicals and\n * fences correctly on its own, so the MathQuill-era corrections are not needed.\n * They stay as documented extension points rather than being deleted, so the\n * destructuring above keeps working. The exception is the radical index, which\n * MathLive sizes to TeX metrics that read too small here - see\n * `rootIndexStyles`.\n */\n\n/**\n * Font styling. MathQuill needed explicit MathJax font families to match the\n * static renderer; MathLive ships the KaTeX fonts it renders with, so this only\n * smooths rendering and lets the host override the family.\n */\nexport const commonMqFontStyles = {\n '-webkit-font-smoothing': 'antialiased',\n '& math-field': {\n fontFamily: 'inherit',\n },\n};\n\n/**\n * Long division. The MathQuill fork drew this with nested `.mq-longdiv-*`\n * elements that needed manual offsets; here it comes from the `\\longdiv` macro\n * (see `PIE_MACROS`), tagged with `data-pie-macro=\"longdiv\"`.\n */\nexport const longdivStyles = {\n '& [data-pie-macro=\"longdiv\"]': {\n display: 'inline-flex',\n },\n};\n\n/**\n * How the index of a radical is sized.\n *\n * MathLive follows TeX and sets the index of `\\sqrt[n]{x}` in scriptscriptstyle,\n * which it emits as an inline `font-size: 50%` on the span wrapping the index's\n * glyphs. At authoring sizes that leaves the index - on the nth-root key, and in\n * any radical the author types - too small to read next to the radicand, so it is\n * scaled up to 80% - 1.6x what MathLive asks for.\n *\n * Only that innermost span is resized. `.ML__sqrt-index` itself keeps its font\n * size on purpose: the vlist inside it tucks the index into the radical's crook\n * with em-based `top`/`height` offsets, and scaling those lifts the index clear\n * of the radical instead of just enlarging it.\n *\n * The child chain is spelled out so that nothing nested deeper inside the index\n * (a fraction's numerator, another radical) is caught by the same rule, and\n * `!important` is required because the 50% is an INLINE style.\n */\nconst ROOT_INDEX_SELECTOR = '.ML__sqrt-index > .ML__vlist-t > .ML__vlist-r > .ML__vlist > span > [style*=\"font-size\"]';\nconst ROOT_INDEX_FONT_SIZE = '80%';\n\nexport const rootIndexStyles = {\n [`& ${ROOT_INDEX_SELECTOR}`]: {\n fontSize: `${ROOT_INDEX_FONT_SIZE} !important`,\n },\n};\n\n/**\n * The same rule as a CSS string, for a live mathfield's shadow root - see\n * `SHADOW_CSS` in mathlive-instance.js. Static markup is styled by\n * {@link rootIndexStyles}.\n */\nexport const ROOT_INDEX_CSS = `${ROOT_INDEX_SELECTOR}{font-size:${ROOT_INDEX_FONT_SIZE} !important}`;\n\n/**\n * Size of the parallel sign (`\\parallel`, tagged `data-pie-macro=\"parallel\"` by\n * `PIE_MACROS`). The legacy editor enlarged it (`updateSpans` set 32px) because\n * the bars read too small next to the letters of `AB ∥ CD`; MathLive draws it at\n * the surrounding size, so it is scaled up here. Not applied to keypad labels.\n */\nconst PARALLEL_SELECTOR = '[data-pie-macro=\"parallel\"]';\nconst PARALLEL_FONT_SIZE = '1.4em';\n\nexport const parallelStyles = {\n [`& ${PARALLEL_SELECTOR}`]: {\n fontSize: PARALLEL_FONT_SIZE,\n },\n};\n\n/** The same rule as a CSS string, for a live mathfield's shadow root. */\nexport const PARALLEL_CSS = `${PARALLEL_SELECTOR}{font-size:${PARALLEL_FONT_SIZE}}`;\n\n/**\n * Superscript/subscript sizing. MathLive follows TeX metrics for scripts, so the\n * MathQuill-era corrections are gone; the radical index is the one place where a\n * TeX-correct size reads too small in the authoring UI.\n */\nexport const supsubStyles = {\n ...rootIndexStyles,\n ...parallelStyles,\n};\n\n/** Empty placeholder boxes (answer blocks / open slots). */\nexport const placeholderStyles = {\n '& .ML__placeholder': {\n borderBottom: '1px solid currentColor',\n minWidth: '1em',\n },\n // Stand-in glyph for an empty argument slot in STATIC math (see\n // `withVisibleEmptySlots`). Muted so it reads as \"a slot goes here\" rather\n // than as part of the symbol, matching how MathQuill shaded `.mq-empty`.\n '& [data-pie-empty]': {\n opacity: 0.5,\n },\n // Stretchy accents (\\overarc, \\overleftrightarrow, \\overrightarrow) render an\n // <svg width=\"100%\" preserveAspectRatio=\"none\"> inside a `.ML__stretchy`. That\n // span is absolutely positioned, so its immediate wrapper computes to 0px and\n // the width has to resolve against a *positioned* ancestor. Pin that to\n // `.ML__base`, whose width already equals the accent's content (measured:\n // 9.85px for a 0.56em slot), so the arc spans exactly its content.\n //\n // Do NOT write a bare `& svg` rule instead: MathLive's own rule is\n // descendant-scoped (`.ML__latex .ML__stretchy svg`), and a global one\n // re-parents every svg in the subtree.\n '& .ML__base': {\n position: 'relative',\n },\n '& .ML__stretchy': {\n position: 'absolute',\n left: 0,\n width: '100%',\n },\n // MathLive centres an accent by shifting it right half the content width -\n // `margin-left: 0.28em` for a 0.56em slot - which assumes a glyph with its own\n // side bearings. Over a synthetic empty slot it just pushes the arc right.\n //\n // `!important` is required: MathLive writes this as an INLINE style\n // (`style=\"top:-3.4em;margin-left:0.28em\"`), which a class cannot override.\n //\n // It also fixes the width. `.ML__center` is the stretchy's containing block\n // (MathLive gives `.ML__vlist > span` position:relative), and its width is the\n // base minus that margin - measured 9.85px - 4.93px = 4.93px, exactly half,\n // which is why the arc came out half-width AND offset right.\n //\n // Scoped with `:has(.ML__stretchy)`: only stretchy accents are affected.\n // A single-glyph accent (`\\hat{x}`, `\\vec{x}`) genuinely needs its centring\n // offset, and must keep it.\n '& .ML__center:has(.ML__stretchy)': {\n marginLeft: '0 !important',\n },\n};\n\n/**\n * Styling for the on-screen keyboard and any container rendering math labels.\n * Also hides MathLive's own affordances, since pie supplies its own keypad.\n */\nexport const commonMqKeyboardStyles = {\n ...commonMqFontStyles,\n ...longdivStyles,\n ...rootIndexStyles,\n ...placeholderStyles,\n touchAction: 'manipulation',\n '& math-field': {\n fontSize: 'inherit',\n outline: 'none',\n },\n '& math-field::part(virtual-keyboard-toggle)': {\n display: 'none',\n },\n '& math-field::part(menu-toggle)': {\n display: 'none',\n },\n};\n\n/** Everything combined - the common case for a container of math. */\nexport const commonMathLiveStyles = {\n ...commonMqFontStyles,\n ...longdivStyles,\n ...supsubStyles,\n ...placeholderStyles,\n '& math-field': {\n fontSize: 'inherit',\n outline: 'none',\n },\n '& math-field::part(virtual-keyboard-toggle)': {\n display: 'none',\n },\n '& math-field::part(menu-toggle)': {\n display: 'none',\n },\n};\n\nexport const commonKeyboardStyles = commonMqKeyboardStyles;\n\n/**\n * Default export mirrors @pie-lib/math-input's `CommonMqStyles` object so\n * existing destructuring keeps working.\n */\nexport default {\n commonMqFontStyles,\n longdivStyles,\n rootIndexStyles,\n supsubStyles,\n commonMqKeyboardStyles,\n placeholderStyles,\n commonMathLiveStyles,\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"common-styles.js","names":["commonMqFontStyles","exports","fontFamily","longdivStyles","display","ROOT_INDEX_SELECTOR","ROOT_INDEX_FONT_SIZE","rootIndexStyles","_defineProperty2","concat","fontSize","ROOT_INDEX_CSS","PARALLEL_SELECTOR","PARALLEL_FONT_SIZE","parallelStyles","PARALLEL_CSS","supsubStyles","_objectSpread","placeholderStyles","borderBottom","minWidth","opacity","position","top","left","width","marginLeft","commonMqKeyboardStyles","touchAction","outline","commonMathLiveStyles","commonKeyboardStyles","_default"],"sources":["../../src/mf/common-styles.js"],"sourcesContent":["/**\n * Shared MathLive styling.\n *\n * Replaces @pie-lib/math-input's `common-mq-styles.js`. That file was built\n * around MathQuill's `.mq-*` class names, none of which exist in MathLive\n * output, so the selectors here target MathLive's own structure instead.\n *\n * The four named groups are kept because consumers destructure them:\n *\n * const { commonMqFontStyles, commonMqKeyboardStyles, longdivStyles, supsubStyles }\n * = mq.CommonMqStyles; // math-toolbar/src/editor-and-pad.jsx, math-preview.jsx\n *\n * Most are intentionally near-empty: MathLive sizes scripts, radicals and\n * fences correctly on its own, so the MathQuill-era corrections are not needed.\n * They stay as documented extension points rather than being deleted, so the\n * destructuring above keeps working. The exception is the radical index, which\n * MathLive sizes to TeX metrics that read too small here - see\n * `rootIndexStyles`.\n */\n\n/**\n * Font styling. MathQuill needed explicit MathJax font families to match the\n * static renderer; MathLive ships the KaTeX fonts it renders with, so this only\n * smooths rendering and lets the host override the family.\n */\nexport const commonMqFontStyles = {\n '-webkit-font-smoothing': 'antialiased',\n '& math-field': {\n fontFamily: 'inherit',\n },\n};\n\n/**\n * Long division. The MathQuill fork drew this with nested `.mq-longdiv-*`\n * elements that needed manual offsets; here it comes from the `\\longdiv` macro\n * (see `PIE_MACROS`), tagged with `data-pie-macro=\"longdiv\"`.\n */\nexport const longdivStyles = {\n '& [data-pie-macro=\"longdiv\"]': {\n display: 'inline-flex',\n },\n};\n\n/**\n * How the index of a radical is sized.\n *\n * MathLive follows TeX and sets the index of `\\sqrt[n]{x}` in scriptscriptstyle,\n * which it emits as an inline `font-size: 50%` on the span wrapping the index's\n * glyphs. At authoring sizes that leaves the index - on the nth-root key, and in\n * any radical the author types - too small to read next to the radicand, so it is\n * scaled up to 80% - 1.6x what MathLive asks for.\n *\n * Only that innermost span is resized. `.ML__sqrt-index` itself keeps its font\n * size on purpose: the vlist inside it tucks the index into the radical's crook\n * with em-based `top`/`height` offsets, and scaling those lifts the index clear\n * of the radical instead of just enlarging it.\n *\n * The child chain is spelled out so that nothing nested deeper inside the index\n * (a fraction's numerator, another radical) is caught by the same rule, and\n * `!important` is required because the 50% is an INLINE style.\n */\nconst ROOT_INDEX_SELECTOR = '.ML__sqrt-index > .ML__vlist-t > .ML__vlist-r > .ML__vlist > span > [style*=\"font-size\"]';\nconst ROOT_INDEX_FONT_SIZE = '80%';\n\nexport const rootIndexStyles = {\n [`& ${ROOT_INDEX_SELECTOR}`]: {\n fontSize: `${ROOT_INDEX_FONT_SIZE} !important`,\n },\n};\n\n/**\n * The same rule as a CSS string, for a live mathfield's shadow root - see\n * `SHADOW_CSS` in mathlive-instance.js. Static markup is styled by\n * {@link rootIndexStyles}.\n */\nexport const ROOT_INDEX_CSS = `${ROOT_INDEX_SELECTOR}{font-size:${ROOT_INDEX_FONT_SIZE} !important}`;\n\n/**\n * Size of the parallel sign (`\\parallel`, tagged `data-pie-macro=\"parallel\"` by\n * `PIE_MACROS`). The legacy editor enlarged it (`updateSpans` set 32px) because\n * the bars read too small next to the letters of `AB ∥ CD`; MathLive draws it at\n * the surrounding size, so it is scaled up here. Not applied to keypad labels.\n */\nconst PARALLEL_SELECTOR = '[data-pie-macro=\"parallel\"]';\nconst PARALLEL_FONT_SIZE = '1.4em';\n\nexport const parallelStyles = {\n [`& ${PARALLEL_SELECTOR}`]: {\n fontSize: PARALLEL_FONT_SIZE,\n },\n};\n\n/** The same rule as a CSS string, for a live mathfield's shadow root. */\nexport const PARALLEL_CSS = `${PARALLEL_SELECTOR}{font-size:${PARALLEL_FONT_SIZE}}`;\n\n/**\n * Superscript/subscript sizing. MathLive follows TeX metrics for scripts, so the\n * MathQuill-era corrections are gone; the radical index is the one place where a\n * TeX-correct size reads too small in the authoring UI.\n */\nexport const supsubStyles = {\n ...rootIndexStyles,\n ...parallelStyles,\n};\n\n/** Empty placeholder boxes (answer blocks / open slots). */\nexport const placeholderStyles = {\n '& .ML__placeholder': {\n borderBottom: '1px solid currentColor',\n minWidth: '1em',\n },\n // Stand-in glyph for an empty argument slot in STATIC math (see\n // `withVisibleEmptySlots`). Muted so it reads as \"a slot goes here\" rather\n // than as part of the symbol, matching how MathQuill shaded `.mq-empty`.\n '& [data-pie-empty]': {\n opacity: 0.5,\n },\n // A fraction with an empty slot: MathLive spaces the bar for text, but the\n // slot's box is a taller `\\rule`, so the bar hugs the numerator's box (~0.2em\n // above vs ~0.4em below). Dropping the bar 0.16em (0.13em when the numerator is not an empty slot or follows an `x`) centres it between the two\n // boxes. Only the bar moves, not the slots.\n '& .ML__mfrac:has([data-pie-empty]) .ML__frac-line': {\n position: 'relative',\n top: '0.16em',\n },\n // A real numerator (`x`) is lighter than an empty box and its ink ends at the\n // baseline, so the full drop overshoots: it needs a smaller drop. The numerator is\n // the second `.ML__center` (MathLive emits the denominator first).\n '& .ML__mfrac:has([data-pie-empty]):not(:has(.ML__center ~ .ML__center [data-pie-empty])) .ML__frac-line': {\n top: '0.13em',\n },\n // Same for a mixed number (`x` then the fraction): the leading `x` is a sibling\n // of the fraction, which a lone `\\frac{}{}` does not have.\n '& .ML__mfrac:has([data-pie-empty]):not(:only-child) .ML__frac-line': {\n top: '0.13em',\n },\n // Stretchy accents (\\overarc, \\overleftrightarrow, \\overrightarrow) render an\n // <svg width=\"100%\" preserveAspectRatio=\"none\"> inside a `.ML__stretchy`. That\n // span is absolutely positioned, so its immediate wrapper computes to 0px and\n // the width has to resolve against a *positioned* ancestor. Pin that to\n // `.ML__base`, whose width already equals the accent's content (measured:\n // 9.85px for a 0.56em slot), so the arc spans exactly its content.\n //\n // Do NOT write a bare `& svg` rule instead: MathLive's own rule is\n // descendant-scoped (`.ML__latex .ML__stretchy svg`), and a global one\n // re-parents every svg in the subtree.\n '& .ML__base': {\n position: 'relative',\n },\n '& .ML__stretchy': {\n position: 'absolute',\n left: 0,\n width: '100%',\n },\n // MathLive centres an accent by shifting it right half the content width -\n // `margin-left: 0.28em` for a 0.56em slot - which assumes a glyph with its own\n // side bearings. Over a synthetic empty slot it just pushes the arc right.\n //\n // `!important` is required: MathLive writes this as an INLINE style\n // (`style=\"top:-3.4em;margin-left:0.28em\"`), which a class cannot override.\n //\n // It also fixes the width. `.ML__center` is the stretchy's containing block\n // (MathLive gives `.ML__vlist > span` position:relative), and its width is the\n // base minus that margin - measured 9.85px - 4.93px = 4.93px, exactly half,\n // which is why the arc came out half-width AND offset right.\n //\n // Scoped with `:has(.ML__stretchy)`: only stretchy accents are affected.\n // A single-glyph accent (`\\hat{x}`, `\\vec{x}`) genuinely needs its centring\n // offset, and must keep it.\n '& .ML__center:has(.ML__stretchy)': {\n marginLeft: '0 !important',\n },\n};\n\n/**\n * Styling for the on-screen keyboard and any container rendering math labels.\n * Also hides MathLive's own affordances, since pie supplies its own keypad.\n */\nexport const commonMqKeyboardStyles = {\n ...commonMqFontStyles,\n ...longdivStyles,\n ...rootIndexStyles,\n ...placeholderStyles,\n touchAction: 'manipulation',\n '& math-field': {\n fontSize: 'inherit',\n outline: 'none',\n },\n '& math-field::part(virtual-keyboard-toggle)': {\n display: 'none',\n },\n '& math-field::part(menu-toggle)': {\n display: 'none',\n },\n};\n\n/** Everything combined - the common case for a container of math. */\nexport const commonMathLiveStyles = {\n ...commonMqFontStyles,\n ...longdivStyles,\n ...supsubStyles,\n ...placeholderStyles,\n '& math-field': {\n fontSize: 'inherit',\n outline: 'none',\n },\n '& math-field::part(virtual-keyboard-toggle)': {\n display: 'none',\n },\n '& math-field::part(menu-toggle)': {\n display: 'none',\n },\n};\n\nexport const commonKeyboardStyles = commonMqKeyboardStyles;\n\n/**\n * Default export mirrors @pie-lib/math-input's `CommonMqStyles` object so\n * existing destructuring keeps working.\n */\nexport default {\n commonMqFontStyles,\n longdivStyles,\n rootIndexStyles,\n supsubStyles,\n commonMqKeyboardStyles,\n placeholderStyles,\n commonMathLiveStyles,\n};\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.1.5-beta.12",
6
+ "version": "1.1.5-beta.13",
7
7
  "description": "MathLive-based math input (drop-in alternative to @pie-lib/math-input)",
8
8
  "main": "lib/index.js",
9
9
  "module": "src/index.jsx",
@@ -69,6 +69,28 @@ const LabelHolder = styled('span', { shouldForwardProp: (prop) => prop !== 'slan
69
69
  '& [data-pie-empty]': {
70
70
  opacity: 0.5,
71
71
  },
72
+ // A fraction is taller than the label's 1em line box, so its numerator sat
73
+ // flush against (and was clipped by) the top edge. Extra room above it grows
74
+ // the box, which the keypad then centres, so the fraction moves down a little.
75
+ '&:has(.ML__mfrac)': {
76
+ paddingTop: '0.25em',
77
+ },
78
+ // Centre a fraction's bar between its empty slots (see `placeholderStyles`).
79
+ '& .ML__mfrac:has([data-pie-empty]) .ML__frac-line': {
80
+ position: 'relative',
81
+ top: '0.16em',
82
+ },
83
+ // A real numerator (`x`) is lighter than an empty box and its ink ends at the
84
+ // baseline, so the full drop overshoots: it needs a smaller drop. The numerator is
85
+ // the second `.ML__center` (MathLive emits the denominator first).
86
+ '& .ML__mfrac:has([data-pie-empty]):not(:has(.ML__center ~ .ML__center [data-pie-empty])) .ML__frac-line': {
87
+ top: '0.13em',
88
+ },
89
+ // Same for a mixed number (`x` then the fraction): the leading `x` is a sibling
90
+ // of the fraction, which a lone `\frac{}{}` does not have.
91
+ '& .ML__mfrac:has([data-pie-empty]):not(:only-child) .ML__frac-line': {
92
+ top: '0.13em',
93
+ },
72
94
  // A readable index on the nth-root key. Carried by the label itself, not only
73
95
  // by the keypad container, so it holds wherever a LatexLabel is mounted.
74
96
  ...rootIndexStyles,
@@ -69,6 +69,18 @@ export const DEFAULT_FIELD_ID = 'r1';
69
69
  */
70
70
  const EMPTY_SLOT = '\\htmlData{pie-empty=1}{\\rule{0.55em}{0.55em}}';
71
71
  const EMPTY_GROUP_REGEX = /\{\s*\}/g;
72
+ // The smallest boxes are the ones in a subscript (`x_{}`, `\log_{}`) or exponent
73
+ // (`x^{}`): they sit at script size, so the 0.55em square reads cramped. They get
74
+ // 0.4em more height, and `\rule[-d]` decides which side it grows on:
75
+ // - subscript / log base: all of it goes below, the top edge stays put;
76
+ // - exponent: 0.3em goes above, plus 0.1em below.
77
+ const EMPTY_SUBSCRIPT_REGEX = /_\{\s*\}/g;
78
+ const EMPTY_SUPERSCRIPT_REGEX = /\^\{\s*\}/g;
79
+ const EMPTY_SUBSCRIPT_SLOT = '\\htmlData{pie-empty=1}{\\rule[-0.4em]{0.55em}{0.95em}}';
80
+ // The label clips what hangs below its line box (`overflow: hidden`), so the lowered
81
+ // box needs a zero-width strut after it to make room, or its bottom is cut off.
82
+ const EMPTY_SUBSCRIPT_STRUT = '\\rule[-0.5em]{0em}{0.5em}';
83
+ const EMPTY_SUPERSCRIPT_SLOT = '\\htmlData{pie-empty=1}{\\rule[-0.1em]{0.55em}{0.95em}}';
72
84
  // The segment key (`\overline{}`). The keypad centres every label in its cell, and
73
85
  // a thin bar is a much shorter label than the ray and line keys' stretchy arrows,
74
86
  // so by default both its bar and its box sit off from theirs: the bar is lower
@@ -111,6 +123,8 @@ const EMPTY_FENCE_SLOT = '\\rule{0em}{1em}\\htmlData{pie-empty=1}{\\rule[-0.25em
111
123
  export const withVisibleEmptySlots = (latex) =>
112
124
  (latex || '')
113
125
  .replace(EMPTY_OVERLINE_REGEX, `${EMPTY_OVERLINE_LABEL_STRUT}\\overline{${EMPTY_OVERLINE_BAR_STRUT}${EMPTY_SLOT}}`)
126
+ .replace(EMPTY_SUBSCRIPT_REGEX, `_{${EMPTY_SUBSCRIPT_SLOT}}${EMPTY_SUBSCRIPT_STRUT}`)
127
+ .replace(EMPTY_SUPERSCRIPT_REGEX, `^{${EMPTY_SUPERSCRIPT_SLOT}}`)
114
128
  .replace(EMPTY_GROUP_REGEX, `{${EMPTY_SLOT}}`)
115
129
  .replace(EMPTY_FENCE_REGEX, (_m, open, close) => `\\left${open}${EMPTY_FENCE_SLOT}\\right${close}`);
116
130
 
@@ -529,3 +543,7 @@ export const keyToAction = (key) => {
529
543
  };
530
544
 
531
545
  export { COMMANDS_WITH_ARGS, KEYSTROKES, MATHQUILL_ALIASES };
546
+
547
+ // TEMP: remove once confirmed that pie-elements picks up this build.
548
+ // eslint-disable-next-line no-console
549
+ console.log('[math-input-mathlive] latex-bridge loaded - taller sub/sup slots (PIE-1135 v2)');
@@ -236,6 +236,22 @@ const PLACEHOLDER_CARET_CSS = [
236
236
  'animation:ML__caret-blink 1.05s step-end forwards infinite}',
237
237
  ].join('');
238
238
 
239
+ // MathLive sets the bar of `\overline{}` right on top of the content, so over an
240
+ // empty slot it touches the slot's box, while the ray and line arrows (stretchy
241
+ // accents) float clear of it. The bar is raised 0.33em, and the strut that sets
242
+ // the field's top edge is raised with it, or the bar would be clipped.
243
+ const OVERLINE_GAP_CSS =
244
+ '.ML__latex .overline>.ML__vlist-t>.ML__vlist-r>.ML__vlist>span:has(>.overline-line){top:-4.15em !important}' +
245
+ '.ML__latex:has(.overline)>.ML__strut{height:1.23em !important}';
246
+
247
+ // MathLive spaces a fraction's bar for text glyphs, whose ink sits tight against
248
+ // the baseline. An empty slot's box (`▢`) hangs lower than that, so the bar ends
249
+ // up much nearer the denominator's box than the numerator's (measured ~0.28em vs
250
+ // ~0.11em). Dropping the bar 0.08em evens the two gaps. Layout is untouched, so
251
+ // the numerator and denominator keep their positions; filled fractions (`1/2`)
252
+ // only see the bar move a hair.
253
+ const FRAC_BAR_CENTER_CSS = '.ML__latex .ML__frac-line{position:relative;top:0.08em}';
254
+
239
255
  // A live mathfield needs the readable radical index too: `rootIndexStyles` is
240
256
  // written for static markup in the host page, which cannot cross the shadow
241
257
  // boundary.
@@ -243,6 +259,8 @@ const SHADOW_CSS =
243
259
  '.ML__latex .ML__center:has(.ML__stretchy){margin-left:0 !important}' +
244
260
  ROOT_INDEX_CSS +
245
261
  PARALLEL_CSS +
262
+ OVERLINE_GAP_CSS +
263
+ FRAC_BAR_CENTER_CSS +
246
264
  PLACEHOLDER_CARET_CSS;
247
265
 
248
266
  /**
@@ -115,6 +115,25 @@ export const placeholderStyles = {
115
115
  '& [data-pie-empty]': {
116
116
  opacity: 0.5,
117
117
  },
118
+ // A fraction with an empty slot: MathLive spaces the bar for text, but the
119
+ // slot's box is a taller `\rule`, so the bar hugs the numerator's box (~0.2em
120
+ // above vs ~0.4em below). Dropping the bar 0.16em (0.13em when the numerator is not an empty slot or follows an `x`) centres it between the two
121
+ // boxes. Only the bar moves, not the slots.
122
+ '& .ML__mfrac:has([data-pie-empty]) .ML__frac-line': {
123
+ position: 'relative',
124
+ top: '0.16em',
125
+ },
126
+ // A real numerator (`x`) is lighter than an empty box and its ink ends at the
127
+ // baseline, so the full drop overshoots: it needs a smaller drop. The numerator is
128
+ // the second `.ML__center` (MathLive emits the denominator first).
129
+ '& .ML__mfrac:has([data-pie-empty]):not(:has(.ML__center ~ .ML__center [data-pie-empty])) .ML__frac-line': {
130
+ top: '0.13em',
131
+ },
132
+ // Same for a mixed number (`x` then the fraction): the leading `x` is a sibling
133
+ // of the fraction, which a lone `\frac{}{}` does not have.
134
+ '& .ML__mfrac:has([data-pie-empty]):not(:only-child) .ML__frac-line': {
135
+ top: '0.13em',
136
+ },
118
137
  // Stretchy accents (\overarc, \overleftrightarrow, \overrightarrow) render an
119
138
  // <svg width="100%" preserveAspectRatio="none"> inside a `.ML__stretchy`. That
120
139
  // span is absolutely positioned, so its immediate wrapper computes to 0px and