| import { getNary, getNaryTarget } from '../ooml/index.js' |
| import { walker } from '../walker.js' |
|
|
| import { getTextContent } from '../helpers.js' |
|
|
| const UPPER_COMBINATION = { |
| '\u2190': '\u20D6', |
| '\u27F5': '\u20D6', |
| '\u2192': '\u20D7', |
| '\u27F6': '\u20D7', |
| '\u00B4': '\u0301', |
| '\u02DD': '\u030B', |
| '\u02D8': '\u0306', |
| ˇ: '\u030C', |
| '\u00B8': '\u0312', |
| '\u005E': '\u0302', |
| '\u00A8': '\u0308', |
| '\u02D9': '\u0307', |
| '\u0060': '\u0300', |
| '\u002D': '\u0305', |
| '\u00AF': '\u0305', |
| '\u2212': '\u0305', |
| '\u002E': '\u0307', |
| '\u007E': '\u0303', |
| '\u02DC': '\u0303' |
| } |
|
|
| function underOrOver(element, targetParent, previousSibling, nextSibling, ancestors, direction) { |
| |
|
|
| if (element.children.length !== 2) { |
| |
| return targetParent |
| } |
|
|
| ancestors = [...ancestors] |
| ancestors.unshift(element) |
|
|
| const base = element.children[0] |
| const script = element.children[1] |
|
|
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| const naryChar = getNary(base) |
|
|
| if ( |
| naryChar && |
| element.attribs?.accent?.toLowerCase() !== 'true' && |
| element.attribs?.accentunder?.toLowerCase() !== 'true' |
| ) { |
| const topTarget = getNaryTarget( |
| naryChar, |
| element, |
| 'undOvr', |
| direction === 'over', |
| direction === 'under' |
| ) |
| element.isNary = true |
|
|
| const subscriptTarget = { |
| name: 'm:sub', |
| type: 'tag', |
| attribs: {}, |
| children: [] |
| } |
| const superscriptTarget = { |
| name: 'm:sup', |
| type: 'tag', |
| attribs: {}, |
| children: [] |
| } |
| walker( |
| script, |
| direction === 'under' ? subscriptTarget : superscriptTarget, |
| false, |
| false, |
| ancestors |
| ) |
| topTarget.children.push(subscriptTarget) |
| topTarget.children.push(superscriptTarget) |
| topTarget.children.push({ type: 'tag', name: 'm:e', attribs: {}, children: [] }) |
| targetParent.children.push(topTarget) |
| return |
| } |
|
|
| const scriptText = getTextContent(script) |
|
|
| const baseTarget = { |
| name: 'm:e', |
| type: 'tag', |
| attribs: {}, |
| children: [] |
| } |
| walker(base, baseTarget, false, false, ancestors) |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| if ( |
| (direction === 'under' && script.name === 'mo' && ['\u0332', '\u005F'].includes(scriptText)) || |
| (direction === 'over' && script.name === 'mo' && ['\u0305', '\u00AF'].includes(scriptText)) |
| ) { |
| |
| targetParent.children.push({ |
| type: 'tag', |
| name: 'm:bar', |
| attribs: {}, |
| children: [ |
| { |
| type: 'tag', |
| name: 'm:barPr', |
| attribs: {}, |
| children: [ |
| { |
| type: 'tag', |
| name: 'm:pos', |
| attribs: { |
| 'm:val': direction === 'under' ? 'bot' : 'top' |
| }, |
| children: [] |
| } |
| ] |
| }, |
| { |
| type: 'tag', |
| name: 'm:e', |
| attribs: {}, |
| children: [ |
| { |
| type: 'tag', |
| name: direction === 'under' ? 'm:sSub' : 'm:sSup', |
| attribs: {}, |
| children: [ |
| { |
| type: 'tag', |
| name: direction === 'under' ? 'm:sSubPr' : 'm:sSupPr', |
| attribs: {}, |
| children: [{ type: 'tag', name: 'm:ctrlPr', attribs: {}, children: [] }] |
| }, |
| baseTarget, |
| { type: 'tag', name: 'm:sub', attribs: {}, children: [] } |
| ] |
| } |
| ] |
| } |
| ] |
| }) |
| return |
| } |
|
|
| |
| |
| |
| |
| |
| |
| if ( |
| (direction === 'under' && |
| element.attribs?.accentunder?.toLowerCase() === 'true' && |
| script.name === 'mo' && |
| scriptText.length < 2) || |
| (direction === 'over' && |
| element.attribs?.accent?.toLowerCase() === 'true' && |
| script.name === 'mo' && |
| scriptText.length < 2) |
| ) { |
| |
| targetParent.children.push({ |
| type: 'tag', |
| name: 'm:acc', |
| attribs: {}, |
| children: [ |
| { |
| type: 'tag', |
| name: 'm:accPr', |
| attribs: {}, |
| children: [ |
| { |
| type: 'tag', |
| name: 'm:chr', |
| attribs: { |
| 'm:val': UPPER_COMBINATION[scriptText] || scriptText |
| }, |
| children: [] |
| } |
| ] |
| }, |
| baseTarget |
| ] |
| }) |
| return |
| } |
| |
| |
| |
| |
| |
| |
| if ( |
| element.attribs?.accent?.toLowerCase() !== 'true' && |
| element.attribs?.accentunder?.toLowerCase() !== 'true' && |
| script.name === 'mo' && |
| base.name === 'mrow' && |
| scriptText.length === 1 |
| ) { |
| targetParent.children.push({ |
| type: 'tag', |
| name: 'm:groupChr', |
| attribs: {}, |
| children: [ |
| { |
| type: 'tag', |
| name: 'm:groupChrPr', |
| attribs: {}, |
| children: [ |
| { |
| type: 'tag', |
| name: 'm:chr', |
| attribs: { |
| 'm:val': scriptText, |
| 'm:pos': direction === 'under' ? 'bot' : 'top' |
| }, |
| children: [] |
| } |
| ] |
| }, |
| baseTarget |
| ] |
| }) |
| return |
| } |
| |
|
|
| const scriptTarget = { |
| name: 'm:lim', |
| type: 'tag', |
| attribs: {}, |
| children: [] |
| } |
|
|
| walker(script, scriptTarget, false, false, ancestors) |
| targetParent.children.push({ |
| type: 'tag', |
| name: direction === 'under' ? 'm:limLow' : 'm:limUpp', |
| attribs: {}, |
| children: [baseTarget, scriptTarget] |
| }) |
| |
| } |
|
|
| export function munder(element, targetParent, previousSibling, nextSibling, ancestors) { |
| return underOrOver(element, targetParent, previousSibling, nextSibling, ancestors, 'under') |
| } |
|
|
| export function mover(element, targetParent, previousSibling, nextSibling, ancestors) { |
| return underOrOver(element, targetParent, previousSibling, nextSibling, ancestors, 'over') |
| } |
|
|