import { Context } from '../core/context' ; import { Atom } from '../core/atom-class' ; import { makeSVGBox , Box } from '../core/box' ; import { VBox } from '../core/v-box' ; import { Style } from '../public/core' ; import { X_HEIGHT } from '../core/font-metrics' ; export class AccentAtom extends Atom { private readonly accent ? : number ; private readonly svgAccent ? : string ; constructor ( command , body , options ) { super ( 'accent' , { command , style : options . style } ) ; if ( options . accentChar ) { this . accent = options . accentChar ; } else { this . svgAccent = options ?. svgAccent ; } this . body = body ; this . skipBoundary = true ; } render ( parentContext ) { const context = new Context ( parentContext , this . style , 'cramp' ) ; const base = Atom . createBox ( context , this . body ) ?? new Box ( null ) ; let skew = 0 ; if ( ! this . hasEmptyBranch ( 'body' ) && this . body ! . length === 2 && this . body ! [ 1 ] . isCharacterBox ( ) ) { skew = base . skew ; } let clearance = Math . min ( base . height , X_HEIGHT ) ; let accentBox ; if ( this . svgAccent ) { accentBox = makeSVGBox ( this . svgAccent ) ; clearance = context . metrics . bigOpSpacing1 - clearance ; } else if ( this . accent ) { const accent = new Box ( this . accent , { fontFamily : 'Main-Regular' } ) ; accent . italic = 0 ; const vecClass = this . accent === 0x20d7 ? ' ML__accent-vec' : '' ; accentBox = new Box ( new Box ( accent ) , { classes : 'ML__accent-body' + vecClass , } ) ; } accentBox = new VBox ( { shift : 0 , children : [ { box : new Box ( base ) } , - clearance , { box : accentBox ! , marginLeft : base . left + 2 * skew , classes : [ 'ML__center' ] , } , ] , } ) ; const result = new Box ( accentBox , { newList : true , type : 'mord' } ) ; if ( this . caret ) result . caret = this . caret ; this . bind ( context , result . wrap ( context ) ) ; return this . attachSupsub ( context , { base : result } ) ; } }