Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions .claude/skills/sync-ko-to-en-ja.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# 한국어 MDX 변경사항을 영어/일본어에 동기화

## 개요

이 skill은 한국어 MDX 문서의 구조적 변경(이미지 태그, 테이블 속성 등)을 영어/일본어 문서에 동기화하는 워크플로우를 설명합니다.

## 배경

- **한국어 MDX**: Confluence XHTML에서 자동 변환됨 (원본)
- **영어/일본어 MDX**: 한국어를 번역한 것
- **문제**: 한국어에 기술적 변경이 발생하면 영어/일본어도 동기화 필요

## 도구

### 1. sync_ko_commit.py

한국어 커밋의 변경사항을 영어/일본어 파일에 덮어쓰는 도구입니다.

```bash
cd confluence-mdx

# 기본 사용법 - 한국어 커밋 변경을 en/ja에 덮어쓰기
python3 bin/sync_ko_commit.py <commit-hash>

# dry-run (미리보기)
python3 bin/sync_ko_commit.py <commit-hash> --dry-run

# 특정 언어만 적용
python3 bin/sync_ko_commit.py <commit-hash> --lang en
python3 bin/sync_ko_commit.py <commit-hash> --lang ja
```

### 2. restore_alt_from_diff.py

sync_ko_commit.py 실행 후, git diff에서 기존 영어/일본어 alt 텍스트를 추출하여 복원합니다.

```bash
cd confluence-mdx

# 미리보기 - 어떤 alt가 복원되는지 확인
python3 bin/restore_alt_from_diff.py --dry-run

# 실제 적용
python3 bin/restore_alt_from_diff.py --apply

# 특정 언어만
python3 bin/restore_alt_from_diff.py --apply --lang en
```

## 전체 워크플로우

### Step 1: 한국어 커밋 확인

```bash
# 동기화할 한국어 커밋 확인
git log --oneline src/content/ko/ | head -10
```

### Step 2: 한국어 변경을 영어/일본어에 덮어쓰기

```bash
cd confluence-mdx
python3 bin/sync_ko_commit.py <commit-hash>
```

이 단계에서 한국어 라인이 영어/일본어 파일의 같은 위치에 복사됩니다.

### Step 3: 기존 번역 텍스트 복원 (이미지 alt 등)

```bash
# git diff에서 기존 alt 텍스트 복원
python3 bin/restore_alt_from_diff.py --dry-run # 미리보기
python3 bin/restore_alt_from_diff.py --apply # 적용
```

### Step 4: 나머지 한국어 텍스트 번역

git diff를 확인하여 아직 한국어로 남아있는 부분을 번역합니다:

```bash
git diff src/content/en/
git diff src/content/ja/
```

번역 시 [translation.md](/docs/translation.md) 가이드를 따릅니다.

### Step 5: 검증

```bash
# Skeleton 구조 일치 확인
cd confluence-mdx
python3 bin/mdx_to_skeleton.py --recursive --max-diff=10

# 빌드 확인
cd ..
npm run build
```

## 예시: 이미지 태그 width 동기화

한국어 커밋 `ae93da7e`가 이미지 태그에 width 속성을 추가한 경우:

```bash
# 1. 한국어 변경 덮어쓰기
cd confluence-mdx
python3 bin/sync_ko_commit.py ae93da7e

# 2. 기존 영어/일본어 alt 텍스트 복원
python3 bin/restore_alt_from_diff.py --apply

# 3. 검증
python3 bin/mdx_to_skeleton.py --recursive --max-diff=10
```

## 주의사항

1. **라인 번호 일치 가정**: ko/en/ja 파일의 구조가 동일해야 함
2. **skeleton 일치 필요**: 동기화 전 skeleton이 일치해야 함 (번역 완료 상태)
3. **커밋 전 검증**: 반드시 skeleton 비교와 빌드 확인 수행

## 관련 문서

- **번역 가이드**: [docs/translation.md](/docs/translation.md)
- **Skeleton 비교**: [.claude/skills/mdx-skeleton-comparison.md](/.claude/skills/mdx-skeleton-comparison.md)
- **Confluence MDX 변환**: [.claude/skills/confluence-mdx.md](/.claude/skills/confluence-mdx.md)
152 changes: 152 additions & 0 deletions confluence-mdx/bin/restore_alt_from_diff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#!/usr/bin/env python3
"""
git diff에서 기존 alt 텍스트를 추출하여 덮어쓴 파일에 복원

사용법:
python bin/restore_alt_from_diff.py --dry-run
python bin/restore_alt_from_diff.py --apply
"""

import re
import subprocess
import sys
from pathlib import Path
from typing import Dict, List, Tuple


def get_diff_for_lang(lang: str) -> str:
"""특정 언어의 git diff 가져오기"""
result = subprocess.run(
['git', 'diff', f'src/content/{lang}/'],
capture_output=True, text=True
)
return result.stdout


def parse_diff_for_alt_mapping(diff_content: str) -> Dict[str, Dict[str, str]]:
"""
diff에서 파일별 이미지 경로 → 기존 alt 텍스트 매핑 추출

Returns:
{file_path: {image_path: original_alt_text}}
"""
file_mappings = {}
current_file = None

lines = diff_content.split('\n')
i = 0

while i < len(lines):
line = lines[i]

# 파일 경로 추출
if line.startswith('--- a/'):
current_file = line[6:]
if current_file not in file_mappings:
file_mappings[current_file] = {}

# 삭제된 라인 (기존 Markdown 이미지)
elif line.startswith('-') and not line.startswith('---'):
# ![alt](path) 패턴 찾기
match = re.search(r'!\[([^\]]*)\]\(([^)]+)\)', line)
if match and current_file:
alt_text = match.group(1)
img_path = match.group(2)
file_mappings[current_file][img_path] = alt_text

i += 1

return file_mappings


def restore_alt_in_file(file_path: Path, alt_mapping: Dict[str, str], dry_run: bool = True) -> List[Tuple[int, str, str]]:
"""
파일에서 한국어 alt를 기존 번역으로 복원

Returns:
List of (line_number, before, after) tuples
"""
content = file_path.read_text(encoding='utf-8')
lines = content.split('\n')
changes = []

for i, line in enumerate(lines):
# <img src="path" alt="..." .../> 패턴 찾기
match = re.search(r'<img\s+src="([^"]+)"\s+alt="([^"]+)"', line)
if match:
img_path = match.group(1)
current_alt = match.group(2)

if img_path in alt_mapping:
original_alt = alt_mapping[img_path]
if current_alt != original_alt:
new_line = line.replace(f'alt="{current_alt}"', f'alt="{original_alt}"')
changes.append((i + 1, line, new_line))
if not dry_run:
lines[i] = new_line

if not dry_run and changes:
file_path.write_text('\n'.join(lines), encoding='utf-8')

return changes


def main():
import argparse

parser = argparse.ArgumentParser(description='git diff에서 기존 alt 텍스트 복원')
parser.add_argument('--dry-run', action='store_true', help='실제 변경 없이 미리보기')
parser.add_argument('--apply', action='store_true', help='실제 변경 적용')
parser.add_argument('--lang', choices=['en', 'ja', 'all'], default='all', help='대상 언어')

args = parser.parse_args()

if not args.dry_run and not args.apply:
print("--dry-run 또는 --apply 옵션을 지정하세요.")
sys.exit(1)

dry_run = args.dry_run
target_langs = ['en', 'ja'] if args.lang == 'all' else [args.lang]

for lang in target_langs:
print(f"\n=== Processing {lang} ===")

# diff에서 매핑 추출
diff_content = get_diff_for_lang(lang)
file_mappings = parse_diff_for_alt_mapping(diff_content)

print(f"Found {len(file_mappings)} files with alt text to restore")

total_changes = 0

for file_path_str, alt_mapping in file_mappings.items():
file_path = Path(file_path_str)

if not file_path.exists():
continue

changes = restore_alt_in_file(file_path, alt_mapping, dry_run=dry_run)

if changes:
total_changes += len(changes)
print(f"\n{file_path}: {len(changes)} changes")
for line_num, before, after in changes[:3]:
# alt 부분만 추출해서 표시
before_alt = re.search(r'alt="([^"]*)"', before)
after_alt = re.search(r'alt="([^"]*)"', after)
if before_alt and after_alt:
print(f" Line {line_num}:")
print(f" - alt=\"{before_alt.group(1)[:50]}{'...' if len(before_alt.group(1)) > 50 else ''}\"")
print(f" + alt=\"{after_alt.group(1)[:50]}{'...' if len(after_alt.group(1)) > 50 else ''}\"")
if len(changes) > 3:
print(f" ... and {len(changes) - 3} more")

print(f"\nTotal: {total_changes} alt texts {'would be' if dry_run else ''} restored for {lang}")

if dry_run:
print("\n[Dry run] No files were modified.")
print("Run with --apply to apply changes.")


if __name__ == '__main__':
main()
Loading