Skip to content

Commit 7022f99

Browse files
github#2: Translate for instructions
1 parent a6cc462 commit 7022f99

File tree

122 files changed

+14509
-1593
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+14509
-1593
lines changed

change_file_name.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env python3
2+
"""Đổi tên tất cả các file trong dự án có mẫu "<base> copy.<ext>" thành "<base>.vi.<ext>".
3+
4+
Yêu cầu cụ thể:
5+
- Tìm các file chứa chuỗi " copy" ngay trước phần mở rộng cuối cùng.
6+
Ví dụ: a11y.instructions copy.md -> a11y.instructions.vi.md
7+
- Hỗ trợ nhiều phần mở rộng kép (vd: .tar.gz) => chỉ chèn ".vi" trước phần mở rộng đầu tiên trong chuỗi mở rộng.
8+
Quy ước: Dùng phần sau dấu chấm đầu tiên sau " copy" làm phần mở rộng nguyên vẹn.
9+
- Bỏ qua thư mục ẩn (.git, .venv, node_modules, v.v.) theo một danh sách exclude.
10+
- Có chế độ dry-run (mặc định) để in ra các cặp rename mà không áp dụng.
11+
- Tránh ghi đè: nếu tên đích đã tồn tại, bỏ qua và cảnh báo.
12+
13+
Cách dùng:
14+
python change_file_name.py # Dry-run (không đổi tên thật)
15+
python change_file_name.py --apply # Thực hiện đổi tên thật
16+
python change_file_name.py --root . # Chỉ định thư mục gốc
17+
18+
"""
19+
from __future__ import annotations
20+
import argparse
21+
from pathlib import Path
22+
import sys
23+
from typing import Iterable
24+
25+
EXCLUDE_DIRS = {'.git', '.hg', '.svn', '.venv', 'venv', 'node_modules', '.idea', '.vscode', '__pycache__'}
26+
TARGET_TOKEN = ' copy'
27+
INSERT_TOKEN = '.vi'
28+
29+
def iter_files(root: Path) -> Iterable[Path]:
30+
for p in root.rglob('*'):
31+
if p.is_dir():
32+
# Skip excluded dirs early by not descending into them
33+
if p.name in EXCLUDE_DIRS:
34+
# Prevent recursion into excluded
35+
dirs_to_skip = [d for d in p.iterdir() if d.is_dir()]
36+
continue
37+
elif p.is_file():
38+
yield p
39+
40+
def build_new_name(file_path: Path) -> Path | None:
41+
name = file_path.name
42+
# Tìm vị trí " copy" trước phần mở rộng đầu tiên (tức dấu chấm đầu tiên từ trái sang phải sau token)
43+
if TARGET_TOKEN not in name:
44+
return None
45+
# Tách phần trước và sau token
46+
prefix, suffix = name.split(TARGET_TOKEN, 1)
47+
if not suffix:
48+
return None # Không có phần mở rộng tiếp theo
49+
# Nếu suffix bắt đầu bằng '.' thì đó là phần mở rộng (có thể phức tạp: .md, .tar.gz ...). Giữ nguyên toàn bộ suffix.
50+
if not suffix.startswith('.'):
51+
# Không đúng dạng mong muốn: yêu cầu phải có .ext
52+
return None
53+
new_name = f"{prefix}{INSERT_TOKEN}{suffix}"
54+
if new_name == name:
55+
return None
56+
return file_path.with_name(new_name)
57+
58+
def should_skip(path: Path) -> bool:
59+
# Bỏ qua nếu bất kỳ phần nào trong parts thuộc EXCLUDE_DIRS
60+
return any(part in EXCLUDE_DIRS for part in path.parts)
61+
62+
def process(root: Path, apply: bool) -> int:
63+
count = 0
64+
for fp in iter_files(root):
65+
if should_skip(fp):
66+
continue
67+
new_path = build_new_name(fp)
68+
if not new_path:
69+
continue
70+
if new_path.exists():
71+
print(f"[WARN] Bỏ qua vì đã tồn tại: {new_path}")
72+
continue
73+
print(f"{'RENAME' if apply else 'DRY-RUN'}: {fp} -> {new_path}")
74+
if apply:
75+
try:
76+
fp.rename(new_path)
77+
count += 1
78+
except OSError as e:
79+
print(f"[ERROR] Không thể đổi tên {fp}: {e}", file=sys.stderr)
80+
else:
81+
count += 1
82+
return count
83+
84+
def parse_args():
85+
parser = argparse.ArgumentParser(description='Đổi tên các file chứa " copy" thành thêm hậu tố .vi trước phần mở rộng.')
86+
parser.add_argument('--root', type=Path, default=Path('.'), help='Thư mục gốc để quét (mặc định: .)')
87+
parser.add_argument('--apply', action='store_true', help='Thực hiện đổi tên thật (mặc định chỉ dry-run).')
88+
return parser.parse_args()
89+
90+
def main():
91+
args = parse_args()
92+
root = args.root.resolve()
93+
if not root.exists() or not root.is_dir():
94+
print(f"Thư mục không hợp lệ: {root}", file=sys.stderr)
95+
sys.exit(1)
96+
apply = args.apply
97+
total = process(root, apply)
98+
print(f"Tổng số file {'đã đổi tên' if apply else 'sẽ đổi tên'}: {total}")
99+
100+
if __name__ == '__main__':
101+
main()

instructions/a11y.instructions.md

Lines changed: 191 additions & 191 deletions
Large diffs are not rendered by default.

instructions/a11y.instructions.vi.md

Lines changed: 347 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)