@@ -65,6 +65,27 @@ def _restore_code_blocks(body, store):
6565 return body
6666
6767
68+ def _protect_images (body ):
69+ """이미지 마크다운 전체()를 placeholder 태그로 보호.
70+ URL만 보호하면 DeepL(tag_handling=html)이 self-closing 태그 뒤 ) 를
71+ 다음 줄로 밀어내 이미지 구문을 깨뜨린다 — 구문 전체를 감춰 괄호를 못 보게 한다."""
72+ store = {}
73+
74+ def _sub (m ):
75+ key = f'<x id="IMG{ len (store )} "/>'
76+ store [key ] = m .group (0 )
77+ return key
78+
79+ protected = re .sub (r'!\[[^\]]*\]\((/[^)]+)\)' , _sub , body )
80+ return protected , store
81+
82+
83+ def _restore_images (body , store ):
84+ for key , val in store .items ():
85+ body = body .replace (key , val )
86+ return body
87+
88+
6889def _protect_inline_code (body ):
6990 store = {}
7091 result = []
@@ -384,15 +405,9 @@ def _protect_ol(m: re.Match) -> str:
384405 return f'{ m .group (1 )} { key } . ' # group 1 = leading spaces
385406
386407 body_protected = re .sub (r'(?m)^( *)(\d+)\. ' , _protect_ol , body_protected )
387- # Protect image URLs — DeepL translates Korean path segments (e.g. /img/milvus-설치-.../)
388- _img_store : dict [str , str ] = {}
389-
390- def _protect_img (m : re .Match ) -> str :
391- key = f'<x id="IMG{ len (_img_store )} "/>'
392- _img_store [key ] = m .group (2 )
393- return f''
394-
395- body_protected = re .sub (r'!\[([^\]]*)\]\((/[^)]+)\)' , _protect_img , body_protected )
408+ # Protect images — hide the whole  so DeepL can't translate Korean
409+ # path segments nor relocate the closing ) onto a new line (breaks the image)
410+ body_protected , _img_store = _protect_images (body_protected )
396411 translated = translate_with_deepl (body_protected ) if body_no_inline .strip () else body_protected
397412 for key , num in _ol_store .items ():
398413 translated = translated .replace (key , num )
@@ -431,8 +446,7 @@ def _protect_img(m: re.Match) -> str:
431446 en_body = _restore_code_blocks (en_body , code_store )
432447 for key , val in _bq_store .items ():
433448 en_body = en_body .replace (key , val )
434- for key , url in _img_store .items ():
435- en_body = en_body .replace (key , url )
449+ en_body = _restore_images (en_body , _img_store )
436450 # Safety net: DeepL relocates blockquote '> ' marker mid-sentence
437451 # e.g. "If an> `code` ..." → "> If an `code` ..."
438452 en_body = re .sub (r'^([A-Za-z][^>\n]*\S)(> +)(\S)' , r'> \1 \3' , en_body , flags = re .MULTILINE )
0 commit comments