@@ -194,17 +194,23 @@ class Controller_latex extends Controller_keystroke {
194
194
const currentSelectionInfo = this . exportLatexSelection ( ) ;
195
195
const currentLatex = currentSelectionInfo . selection . latex ;
196
196
const newLatex = data . latex ;
197
- const { cursorInsertPath, signedSelectionSize } = data . opaqueSnapshot ;
198
197
199
- // latex's must match for the indicies in the selection to match up
200
- if ( currentLatex !== newLatex ) return ;
198
+ // latexs must match for the startIndex and endIndex to match up
199
+ if ( newLatex !== currentLatex ) return ;
200
+
201
+ // the data.startIndex and data.endIndex are values that are relative to the
202
+ // cleaned latex. The problem is that when we traverse this tree looking for
203
+ // the nodes in those positions we will be working on raw uncleaned latex. We need
204
+ // to map our cleaned indices back to uncleaned indices. Then we can take another
205
+ // pass through the tree looking for the nodes at the startIndex and endIndex
206
+ const mappedIndices = mapFromCleanedToUncleanedIndices (
207
+ currentLatex ,
208
+ currentSelectionInfo . ctx . latex ,
209
+ data
210
+ ) ;
211
+ this . exportLatexSelection ( mappedIndices ) ;
201
212
202
- // TODO - track things better so that we can actually make this work
203
- if ( currentLatex !== currentSelectionInfo . ctx . latex ) {
204
- throw new Error (
205
- 'TODO - restoring selection requires uncleanedLatex to match latex'
206
- ) ;
207
- }
213
+ const { cursorInsertPath, signedSelectionSize } = data . opaqueSnapshot ;
208
214
209
215
if ( ! this . insertCursorAtPath ( cursorInsertPath ) ) return ;
210
216
@@ -243,7 +249,10 @@ class Controller_latex extends Controller_keystroke {
243
249
return count ;
244
250
}
245
251
246
- exportLatexSelection ( ) : {
252
+ exportLatexSelection ( restoreInfo ?: {
253
+ uncleanStartIndex : number ;
254
+ uncleanEndIndex : number ;
255
+ } ) : {
247
256
selection : ExportedLatexSelection ;
248
257
ctx : LatexContext ;
249
258
} {
@@ -253,6 +262,13 @@ class Controller_latex extends Controller_keystroke {
253
262
endIndex : - 1
254
263
} ;
255
264
265
+ if ( restoreInfo ) {
266
+ ctx . restoreInfo = {
267
+ startIndex : restoreInfo . uncleanStartIndex ,
268
+ endIndex : restoreInfo . uncleanEndIndex
269
+ } ;
270
+ }
271
+
256
272
let cursorInsertPath : string = '' ;
257
273
let signedSelectionSize : number = 0 ;
258
274
@@ -289,28 +305,11 @@ class Controller_latex extends Controller_keystroke {
289
305
// need to clean the latex
290
306
var uncleanedLatex = ctx . latex ;
291
307
var cleanLatex = this . cleanLatex ( uncleanedLatex ) ;
292
- var startIndex = ctx . startIndex ;
293
- var endIndex = ctx . endIndex ;
294
-
295
- // assumes that the cleaning process will only remove characters. We
296
- // run through the uncleanedLatex and cleanLatex to find differences.
297
- // when we find differences we see how many characters are dropped until
298
- // we sync back up. While detecting missing characters we decrement the
299
- // startIndex and endIndex if appropriate.
300
- var j = 0 ;
301
- for ( var i = 0 ; i < ctx . endIndex ; i ++ ) {
302
- if ( uncleanedLatex [ i ] !== cleanLatex [ j ] ) {
303
- if ( i < ctx . startIndex ) {
304
- startIndex -= 1 ;
305
- }
306
- endIndex -= 1 ;
307
-
308
- // do not increment j. We wan to keep looking at this same
309
- // cleanLatex character until we find it in the uncleanedLatex
310
- } else {
311
- j += 1 ; //move to next cleanLatex character
312
- }
313
- }
308
+ const { startIndex, endIndex } = mapFromUncleanedToCleanedIndices (
309
+ uncleanedLatex ,
310
+ cleanLatex ,
311
+ ctx
312
+ ) ;
314
313
315
314
return {
316
315
selection : {
@@ -596,3 +595,79 @@ class Controller_latex extends Controller_keystroke {
596
595
}
597
596
}
598
597
}
598
+
599
+ function mapFromUncleanedToCleanedIndices (
600
+ uncleanedLatex : string ,
601
+ cleanedLatex : string ,
602
+ indices : { startIndex : number ; endIndex : number }
603
+ ) {
604
+ var startIndex = indices . startIndex ;
605
+ var endIndex = indices . endIndex ;
606
+
607
+ // assumes that the cleaning process will only remove space characters. We
608
+ // run through the uncleanedLatex and cleanLatex to find differences.
609
+ // when we find differences we see how many characters are dropped until
610
+ // we sync back up. While detecting missing characters we decrement the
611
+ // startIndex and endIndex if appropriate.
612
+ for (
613
+ var uncleanIdx = 0 , cleanIdx = 0 ;
614
+ uncleanIdx < indices . endIndex ;
615
+ uncleanIdx ++
616
+ ) {
617
+ if ( uncleanedLatex [ uncleanIdx ] !== cleanedLatex [ cleanIdx ] ) {
618
+ if ( uncleanIdx < indices . startIndex ) {
619
+ startIndex -= 1 ;
620
+ }
621
+ endIndex -= 1 ;
622
+
623
+ // do not increment j. We wan to keep looking at this same
624
+ // cleanLatex character until we find it in the uncleanedLatex
625
+ } else {
626
+ cleanIdx += 1 ; //move to next cleanLatex character
627
+ }
628
+ }
629
+
630
+ return {
631
+ startIndex,
632
+ endIndex
633
+ } ;
634
+ }
635
+
636
+ function mapFromCleanedToUncleanedIndices (
637
+ cleanedLatex : string ,
638
+ uncleanedLatex : string ,
639
+ indices : { startIndex : number ; endIndex : number }
640
+ ) {
641
+ const cleanStartIdx = indices . startIndex ;
642
+ const cleanEndIdx = indices . endIndex ;
643
+ var uncleanStartIndex = cleanStartIdx ;
644
+ var uncleanEndIndex = cleanEndIdx ;
645
+
646
+ // assumes that the cleaning process will only remove space characters. We
647
+ // run through the uncleanedLatex moving one character every time. We compare
648
+ // against the cleanedLatex. If the cleanedLatex matches we consume a cleanedLatex
649
+ // character. Otherwise we continue pointing to the same cleanedLatex character until
650
+ // it matches the uncleanedLatex. When we find mismatches we know that we need to increase
651
+ // the startIndex and endIndex to correspond to the correct uncleaned positions.
652
+ for (
653
+ var uncleanIdx = 0 , cleanIdx = 0 ;
654
+ uncleanIdx < uncleanedLatex . length ;
655
+ uncleanIdx ++
656
+ ) {
657
+ if ( uncleanedLatex [ uncleanIdx ] !== cleanedLatex [ cleanIdx ] ) {
658
+ if ( cleanIdx <= cleanStartIdx ) {
659
+ uncleanStartIndex += 1 ;
660
+ }
661
+ if ( cleanIdx <= cleanEndIdx ) {
662
+ uncleanEndIndex += 1 ;
663
+ }
664
+ } else {
665
+ cleanIdx += 1 ;
666
+ }
667
+ }
668
+
669
+ return {
670
+ uncleanStartIndex,
671
+ uncleanEndIndex
672
+ } ;
673
+ }
0 commit comments