
    rj'                     6   d Z ddlZddlZddlZddlZddlZddlZdZdZdZ	d Z
d Z ej                  d      Z ej                  d	      Zd
 Z ej                  d      Z ej                  d	      Zd Zd Zd Zd Zd Zd Zd Zd Zd Zedk(  r e        yy)u  
Apply <mark> highlights to edited files using editor notes + extracted originals.

Strategy:
1. Parse notes to get (page, old_text, new_text, type)
2. Find old_text in extracted (original) file at the correct page
3. Calculate its relative position (% offset within the page)
4. Find new_text in the edited file at approximately the same position
5. Mark only that specific occurrence — avoids marking common words everywhere

Fallback: smart diff between extracted and edited, filtering out formatting changes.
    NzZ/home/tuan-nguyen/.openclaw/workspace/003-tang-chi-bo-giang-giai/edited-notes/gemini-flashzT/home/tuan-nguyen/.openclaw/workspace/003-tang-chi-bo-giang-giai/edited/gemini-flashzJ/home/tuan-nguyen/.openclaw/workspace/003-tang-chi-bo-giang-giai/extractedc                 z   t        j                  dt         j                        }i }|j                  |       D ]-  }|j	                         |t        |j                  d            <   / t        |      }i }t        |      D ]8  \  }}||   }|dz   t        |      k  r|||dz         n
t        |       }	||	f||<   : |S )Nz^## PAGE (\d+)$   )
recompile	MULTILINEfinditerstartintgroupsorted	enumeratelen)
textpatbmspripnses
             apply-marks.pyget_page_offsetsr      s    
**'
6C
A\\$ 'WWY#aggaj/'	B
A2 2bEA#B-Ab1gJSYA" H    c                 t    | j                         } | j                  d      r| j                  d      r| dd } | S )N`r   )strip
startswithendswithr   s    r   clean_backtickr#   $   s3    		A||CQZZ_aGHr   z5^\|[- ]+\|[- ]+\|[- ]+\|[- ]+\|[- ]+\|[- ]+\|[- ]+\|$z^\|\s*\d+\s*\|c                 Z   g }| j                  d      }d}|D ]
  }|j                         }t        j                  |      rd},|s/|j	                  d      rt
        j                  |      sV|j                  d      D cg c]  }|j                          }}t        |      dk\  s|j                  |d   t        |      dkD  r|d   ndt        |      d	kD  r|d	   ndt        |      d
kD  r|d
   ndt        |      dkD  r|d   ndt        |      dkD  r|d   ndd        |S c c}w )N
FT|                   pageposoldnewtypenote)splitr   RE_A_SEPmatchr    	RE_A_DATAr   append)r   rowslinesin_tableliner   ccellss           r   parse_format_ar@   /   s   DJJtEH JJL>>!HX||C 	(:H$%GGCL1q11u:?KKaSZ\qr#&u:a<uQxR#&u:a<uQxR$'JqLab$'JqLab  K 2s   D(z'^\|[- ]+\|[- ]+\|[- ]+\|[- ]+\|[- ]+\|$c           
      @   g }| j                  d      }d}|D ]}  }|j                         }t        j                  |      rd},|s/|j	                  d      rt
        j                  |      sV|j                  d      D cg c]  }|j                          }}t        |      dk  r|d   t        |      dkD  r|d   nd}	}|d   |d	   }}
t        j                  d
|
      }|st        j                  d
|      }|r8|j                  |d|j                  d      |j                  d      |	|d       t        j                  d|
      }t        j                  d|      }|r|d   nd}|r|d   nd}|s_||k7  sf|j                  |d|||	|d        |S c c}w )Nr%   FTr&   r,   r(   r*   r)   r+   u   `([^`]+)`\s*→\s*`([^`]+)`r   r.   z	`([^`]+)`r   )r5   r   RE_B_SEPr7   r    	RE_B_DATAr   r   searchr9   r   findall)r   r:   r;   r<   r=   r   r>   r?   pgtcraweddr   brbeons                    r   parse_format_brN   I   s   DJJtEH ^JJL>>!HX||C 	(:H$%GGCL1q11u:>8qs5z!|58B8U1XSII4c:bii >D!KKBqwwqz!''RS*^`jmnoZZc*ZZc*BqERBqERaKKBqBX[\])^* K 2s   Fc                 `    | d   j                         }d|v s	d|v s|dk(  rydD ]  }||v s y y)Nr3   u   Dấu phụu   Định dạngz
OCR+FORMATF)Paliu
   Nghi ngờu   Số đếmu
   Trợ từSPELLOCRTRUNCT)r   )rowtcts      r   is_content_correctionrW   f   sI    FA-2a<6GZ  74 r   c                    t        j                  dd|       } t        j                  dd|       } t        j                  dd|       } t        j                  dd|       } t        j                  dd| t         j                        } | S )Nz\*\*r*   __z\*_z^#+\s*)flags)r   subr   r"   s    r   	_strip_mdr]   p   sg    
wAA
ub!A
ub!A
tRA
y"ar||4AHr   c                     t        |       } t        j                  dd|       j                         } dD ]  }| j	                  |d      }  t        j                  d|       S )Nz\s+ )u   ​u   ‌u   ‍u   ‎u   ‏r*   NFKD)r]   r   r\   r   replaceunicodedata	normalize)r   zs     r   
_normalizere   x   sX    !A
vsA$$&A? IIa  ++r   c                    | |k(  r|S | j                  dd      j                  dd      }|j                  dd      j                  dd      }|j                  d      }|j                  d      }t        j                  d||d      }g }d}|j	                         D ]2  \  }	}
}}}|	d	k(  r|j                  |||        $|	d
k(  r||
| }||| }t        t        |      t        |            }t        |      D ]  }|t        |      k  r||   nd}|t        |      k  r||   nd}t        |      t        |      k7  r/t        t        |            dk\  r|j                  d|z   dz          s|j                  |        |	dk(  s||| D ]B  }t        t        |            dk\  r|j                  d|z   dz          2|j                  |       D 5 dj                  |      S )z:Line-by-line comparison. Mark lines where content differs.<mark>r*   </mark>r%   NF)autojunkr   equalra      insert)ra   r5   difflibSequenceMatcherget_opcodesextendmaxr   rangere   r9   join)ext_pageedt_pagececdeldlsmresulteitagi1i2j1j2ex_sliceed_slicerM   kexeds                       r   diff_mark_pager      s   8			(B	'	/	/	2	>B			(B	'	/	/	2	>B	$B	$B		 	 r2	>BF	
B!~~/ &RR'>MM"R)$I"RyH"RyHCM3x=1A1X &$%H$5Xa[2$%H$5Xa[2b>Z^3JrN8Kq8PMM(R-)";<MM"%& H_Bi &z"~&!+MM(R-)";<MM"%	&#&. 99Vr   c                    t        | d      5 }|j                         }ddd       t        |d      5 }|j                         }ddd       t              }t              }|s|dfS g dd}	}}t        |      D ]}  }
||
   \  }}|	|k  r|j	                  ||	|        |
|v r@||
   \  }}t        ||| |||       }||j                  d      z  }|j	                  |       n|j	                  |||        |}	 |	t        |      k  r|j	                  ||	d        dj                  |      |fS # 1 sw Y   xY w# 1 sw Y   xY w)z!Page-by-page smart diff fallback.utf-8encodingNr   rg   r*   )	openreadr   r   r9   r   countr   rs   )edited_pathextracted_pathfedited	extractedepdpsectmlpr   dsdexsxemps                   r   smart_diff_fallbackr      sD   	kG	,DAFFH6D	nw	/J1!&&(iJ	)	$B	&	!BfaiaRCRj 
BB7CJJvb}-8VFB	"R 0&B-@B"((8$$BJJrNJJvb}%
 
CKF23K0773<% EDJJs   D/D</D9<Ec           	         t        | d      5 }|j                         }d d d        t        |d      5 }|j                         }d d d        t              }t              }i }|D ]s  }	t        |	      st	        |	d         }
t        |	d         t        |	d         }}|r|r||k(  rC|
|vs|
|vrL|j                  |
g       j                  |||	d   d       u g }t        |      D ]  }
||
   \  }}||
   \  }}||| ||| }}||
   D ]  }|j                  |d         }|dk(  r|t        t        |      d	      z  }t	        |t        |      z        g }d
}	 |j                  |d   |      }|dk(  rn|j                  |       |d	z   }2|st        |fd      }||z   }|j                  |t        |d         |d   f         |j                  d d       d
}|D ]A  \  }}}||||z    |k7  rd|t        d
|dz
        | v r(|d | d| dz   |||z   d  z   }|d	z  }C ||fS # 1 sw Y   xY w# 1 sw Y   xY w# t
        $ r Y w xY w)Nr   r   r/   r1   r2   r3   )r1   r2   r3   r   r   r   Tc                      t        | z
        S )N)abs)xests    r   <lambda>z'apply_marks_to_edited.<locals>.<lambda>   s    3qu: r   )keyc                     | d   S )Nr    )r   s    r   r   z'apply_marks_to_edited.<locals>.<lambda>   s
    !A$ r   )r   reverserg   r-   rh   )r   r   r   rW   r
   
ValueErrorr#   
setdefaultr9   r   findrq   r   minsort)r   r   correctionsr   r   r   r   r   pcr   r   otntamr   r   r   r   dsectxsectr>   xprpcandssidxbestgpr   tlr   s                                 @r   apply_marks_to_editedr      s   	kG	,DAFFH6D	nw	/J1!&&(iJ	&	!B	)	$B	B P$Q'ai.R%)>!E(+CBrRxR<2R<
b"$$RAfI%NOP 
BRj 5BB"R&Rb}i2&6uB 	5AAeH%BRxc#e*a((Bb3u:o&CDArjj52."9eC sQw"  t!56DdBIIr3qx=!E(34	55" GGG-	
B 
B"RUr!8vc!BqDk"--xt733fRUVnD
a	
 2:M EDJJ #8#s(   H/H<7I	/H9<I		IIc                 ^   t         j                  j                  |       }d|v r|j                  dd      n|}t         j                  j	                  t
        |      }t         j                  j	                  t        |      }t         j                  j                  |      sd d| fS t         j                  j                  |      sd d| fS t        | d      5 }|j                         }d d d        t              xs t        |      }|rm|D cg c]  }t        |      s| }	}|	rPt        |||      \  }
}|dkD  r;t        |dd      5 }|j                  |
       d d d        || d	t        |	       d
fS t!        ||      \  }
}|dkD  rDt        |dd      5 }|j                  |
       d d d        |rt        |       dnd}|| d| dfS |r,|D cg c]  }t        |      s| }	}ddt        |	       dfS y# 1 sw Y   xY wc c}w # 1 sw Y   xY w# 1 sw Y   rxY wc c}w )Nz	-notes.mdz.mdzedited not found: zextracted not found: r   r   r   wz marks (z notes content)z noteszno notesz diff marks ()z	0 marks (z content, diff=0))r   z0 marks (no notes, diff=0))ospathbasenamera   rs   
EDITED_DIREXTRACTED_DIRexistsr   r   r@   rN   rW   r   writer   r   )
notes_pathbntargetr   r   r   r   corrr>   ccr   mcnms                r   process_pairr      s   			*	%B/:b/@RZZU+bF	j&	)B	mV	,B77>>"d.@,I&II77>>"d.CF8,L&LL	j7	+Aq$A$7>$#7D:A!6q!9a::*2r48FBAv"cG4F1772;FbT#b'/BBB R(FB	Av"cG,>1772;>%)D	{&!zbTrd!,,,:A!6q!9a::Ic"gY&7888*% BA ; GF
 	?> ;s<   H H!HHHH*(H* H
HH'c            	         t        t        j                  t        j                  j	                  t
        d                  } t        dt        |        d       dx}x}}| D ]  }t        j                  j                  |      }t        |      \  }}|t        d| d|        |dz  }I|dk(  rt        d| d|        |dz  }et        d| d	|        |dz  }||z  } t                t        d
       t        d| d| d| d       y )Nz*.mdzFound z notes files
r   u     📄 u
   
     ⚠ r   u   
     ⏭  u
   
     ✅ z2==================================================zDone: z	 marked (z	 marks), z skipped)
r   globr   r   rs   	NOTES_DIRprintr   r   r   )nfsprocskipr   nfr   r>   msgs           r   mainr     s   
277<<	6:;
<C	F3s8*N
+,D4" FWWb!b!39GB4{3%014194!VGB4|C512DAIDGB4{3%014194bAgbF 
G	(O	F4&	"YtfH
=>r   __main__)__doc__r   sysr   r   rm   rb   r   r   r   r   r#   r   r6   r8   r@   rB   rC   rN   rW   r]   re   r   r   r   r   r   __name__r   r   r   <module>r      s    / . .h	c
\ 2::NOBJJ()	. 2::@ABJJ()	:,#J0'V+6?" zF r   