@@ -8,6 +8,7 @@ import { getCurrentColorScheme } from './lib/utilities';
88import pako from 'pako' ;
99import { createPositionMapper } from './sdt/create-position-mapper' ;
1010import { getTextNodeSpans } from './sdt/position-mapper' ;
11+ import { buildSDTReadAloudSegments , getSDTLang } from './read-aloud/sdt-segments' ;
1112import {
1213 openStructuredDocumentTextPack ,
1314 SDT_PACK_VERSION ,
@@ -435,6 +436,92 @@ class View {
435436 if ( ! sdt ) {
436437 return null ;
437438 }
439+ let built = this . _buildAnnotationFromSDT ( sdt , sdtAnchor , type ) ;
440+ if ( ! built ) {
441+ return null ;
442+ }
443+ return this . _annotationManager . addAnnotation ( {
444+ type,
445+ color,
446+ comment,
447+ tags,
448+ position : built . position ,
449+ text : built . text ,
450+ sortIndex : built . sortIndex ,
451+ pageLabel : built . pageLabel ,
452+ } ) ;
453+ }
454+
455+ /**
456+ * @param {ReadAloudGranularity } granularity
457+ * @returns {Promise<ReadAloudSegment[] | null> }
458+ */
459+ async getReadAloudSegments ( granularity ) {
460+ let sdt = await this . _loadSDT ( ) ;
461+ if ( ! sdt ) {
462+ return null ;
463+ }
464+ let lang = getSDTLang ( sdt . structure ) ;
465+ let { segments } = buildSDTReadAloudSegments ( sdt . structure , granularity , lang ) ;
466+ return segments ;
467+ }
468+
469+ /**
470+ * @param {string } [id] If set, resize an existing annotation
471+ * @param {SDTPosition } startPosition
472+ * @param {SDTPosition } [endPosition] Defaults to startPosition
473+ * @param {AnnotationType } type
474+ * @param {string } color
475+ * @param {string } [comment]
476+ * @param {string[] } [tags]
477+ * @returns {Promise<import('./types').Annotation | null> }
478+ */
479+ async setReadAloudAnnotation ( { id, startPosition, endPosition, type, color, comment, tags } ) {
480+ let sdt = await this . _loadSDT ( ) ;
481+ if ( ! sdt ) {
482+ return null ;
483+ }
484+ let sdtAnchor = {
485+ start : startPosition . start ,
486+ end : ( endPosition || startPosition ) . end ,
487+ } ;
488+ let built = this . _buildAnnotationFromSDT ( sdt , sdtAnchor , type ) ;
489+ if ( ! built ) {
490+ return null ;
491+ }
492+ if ( id && this . _annotationManager . _getAnnotationByID ( id ) ) {
493+ let update = {
494+ id,
495+ position : built . position ,
496+ sortIndex : built . sortIndex ,
497+ pageLabel : built . pageLabel ,
498+ text : built . text ,
499+ } ;
500+ // Only overwrite type/color when explicitly provided, so a resize
501+ // preserves them
502+ if ( type ) {
503+ update . type = type ;
504+ }
505+ if ( color ) {
506+ update . color = color ;
507+ }
508+ this . _annotationManager . updateAnnotations ( [ update ] ) ;
509+ return this . _annotationManager . _getAnnotationByID ( id ) ;
510+ }
511+ return this . _annotationManager . addAnnotation ( {
512+ type,
513+ color,
514+ comment,
515+ tags,
516+ position : built . position ,
517+ text : built . text ,
518+ sortIndex : built . sortIndex ,
519+ pageLabel : built . pageLabel ,
520+ } ) ;
521+ }
522+
523+ // Map an SDT range to a source position, sortIndex/pageLabel, and text.
524+ _buildAnnotationFromSDT ( sdt , sdtAnchor , type ) {
438525 let spans = getTextNodeSpans ( sdt . structure , sdtAnchor ) ;
439526 let position = sdt . mapper . textNodeSpansToSourcePosition ( spans ) ;
440527 if ( ! position ) {
@@ -448,16 +535,7 @@ class View {
448535 return null ;
449536 }
450537 let text = spans . map ( s => s . node . text . slice ( s . start , s . end ) ) . join ( '' ) ;
451- return this . _annotationManager . addAnnotation ( {
452- type,
453- color,
454- comment,
455- tags,
456- position,
457- text,
458- sortIndex : meta . sortIndex ,
459- pageLabel : meta . pageLabel ,
460- } ) ;
538+ return { position, text, sortIndex : meta . sortIndex , pageLabel : meta . pageLabel } ;
461539 }
462540}
463541
0 commit comments