youssefreda9 commited on
Commit
291a28f
·
1 Parent(s): 4ec8363

fix: Grammar shows word-level suggestions instead of sentence chunks - Break grammar diffs into individual word changes - Skip grammar suggestions overlapping with spelling - Add alternatives to grammar suggestions - Prevents duplication on Apply All

Browse files
Files changed (1) hide show
  1. src/app.py +41 -10
src/app.py CHANGED
@@ -858,16 +858,47 @@ def analyze_text():
858
  corrected_grammar = correct_grammar(current_text)
859
  logger.info(f"[ANALYZE] Step 2: Grammar done in {time.time()-t0:.2f}s")
860
  if corrected_grammar != current_text:
861
- diffs = get_word_diffs(current_text, corrected_grammar)
862
- for d in diffs:
863
- orig_start, orig_end = map_range_to_original(d['start'], d['end'])
864
- suggestions.append({
865
- 'start': orig_start,
866
- 'end': orig_end,
867
- 'original': text[orig_start:orig_end],
868
- 'correction': d['correction'],
869
- 'type': 'grammar'
870
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
871
  mappers.append(OffsetMapper(current_text, corrected_grammar))
872
  current_text = corrected_grammar
873
  except Exception as e:
 
858
  corrected_grammar = correct_grammar(current_text)
859
  logger.info(f"[ANALYZE] Step 2: Grammar done in {time.time()-t0:.2f}s")
860
  if corrected_grammar != current_text:
861
+ # Word-level grammar diffs (individual words, not chunks)
862
+ g_orig_words = get_word_positions(current_text)
863
+ g_corr_words = get_word_positions(corrected_grammar)
864
+ g_matcher = difflib.SequenceMatcher(
865
+ None,
866
+ [w[0] for w in g_orig_words],
867
+ [w[0] for w in g_corr_words]
868
+ )
869
+
870
+ for tag, i1, i2, j1, j2 in g_matcher.get_opcodes():
871
+ if tag == 'replace':
872
+ # Process each original word individually
873
+ for k in range(i1, i2):
874
+ ck = j1 + (k - i1)
875
+ if ck < j2:
876
+ o_word = g_orig_words[k][0]
877
+ c_word = g_corr_words[ck][0]
878
+ if o_word != c_word:
879
+ g_start = g_orig_words[k][1]
880
+ g_end = g_orig_words[k][2]
881
+ orig_start, orig_end = map_range_to_original(g_start, g_end)
882
+
883
+ # Skip if overlaps with existing spelling suggestion
884
+ overlaps = False
885
+ for existing in suggestions:
886
+ if existing['type'] == 'spelling':
887
+ if not (orig_end <= existing['start'] or orig_start >= existing['end']):
888
+ overlaps = True
889
+ break
890
+ if overlaps:
891
+ continue
892
+
893
+ suggestions.append({
894
+ 'start': orig_start,
895
+ 'end': orig_end,
896
+ 'original': text[orig_start:orig_end],
897
+ 'correction': c_word,
898
+ 'type': 'grammar',
899
+ 'alternatives': [c_word, text[orig_start:orig_end]],
900
+ })
901
+
902
  mappers.append(OffsetMapper(current_text, corrected_grammar))
903
  current_text = corrected_grammar
904
  except Exception as e: