Initial commit: 25 scripts Python sauvegardés
Date: 2026-08-28 11:43:34 EDT
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
"""
|
||||
Auto-tag index.html with data-i18n attributes.
|
||||
|
||||
Reads the frontend/locales/fr.json file to build a reverse map
|
||||
(French text → locale key), then scans index.html for elements
|
||||
with French text content and inserts data-i18n="key" attributes.
|
||||
|
||||
Usage: python3 i18n-auto-tag.py
|
||||
Run from the ObsiGate project root.
|
||||
"""
|
||||
import re, json
|
||||
|
||||
with open('frontend/locales/fr.json', 'r', encoding='utf-8') as f:
|
||||
fr = json.load(f)
|
||||
|
||||
# Build reverse map: French text → key (prefer shorter keys for duplicates)
|
||||
text_to_key = {}
|
||||
for key, val in fr.items():
|
||||
if key.startswith('_'): continue
|
||||
if val not in text_to_key or len(key) < len(text_to_key[val]):
|
||||
text_to_key[val] = key
|
||||
|
||||
with open('frontend/index.html', 'r', encoding='utf-8') as f:
|
||||
html = f.read()
|
||||
|
||||
before = len(re.findall(r'data-i18n(?:-[a-z]+)?=\"', html))
|
||||
|
||||
# Tags to scan for text content
|
||||
TAGS = 'span|p|h[1-6]|label|button|a|li|td|th|strong|summary|legend|caption|dd|dt|small|em|b|u|div|option|figcaption|blockquote'
|
||||
|
||||
def replace_match(m):
|
||||
tag = m.group(1)
|
||||
attrs = m.group(2)
|
||||
text = m.group(3).strip()
|
||||
full_inner = m.group(3)
|
||||
|
||||
if 'data-i18n=' in attrs:
|
||||
return m.group(0)
|
||||
|
||||
key = text_to_key.get(text)
|
||||
if not key:
|
||||
return m.group(0)
|
||||
|
||||
if attrs.strip():
|
||||
new_open = f'<{tag} {attrs.strip()} data-i18n="{key}">'
|
||||
else:
|
||||
new_open = f'<{tag} data-i18n="{key}">'
|
||||
|
||||
return f'{new_open}{full_inner}</{tag}>'
|
||||
|
||||
pattern = rf'<({TAGS})([^>]*)>([^<{{]{{3,300}})</\1>'
|
||||
html = re.sub(pattern, replace_match, html)
|
||||
|
||||
# Also add data-i18n-placeholder for inputs
|
||||
def replace_placeholder(m):
|
||||
attrs = m.group(1)
|
||||
text = m.group(2)
|
||||
if 'data-i18n-placeholder=' in attrs or 'data-i18n=' in attrs:
|
||||
return m.group(0)
|
||||
key = text_to_key.get(text)
|
||||
if not key:
|
||||
return m.group(0)
|
||||
return f'<input{attrs} data-i18n-placeholder="{key}" placeholder="{text}"'
|
||||
|
||||
placeholder_pattern = r'<input([^>]*?)placeholder="([^"]{3,120})"'
|
||||
html = re.sub(placeholder_pattern, replace_placeholder, html)
|
||||
|
||||
after = len(re.findall(r'data-i18n(?:-[a-z]+)?=\"', html))
|
||||
|
||||
# Verify no concatenated attributes
|
||||
bad = re.findall(r'<[a-z]+data-i18n=', html)
|
||||
if bad:
|
||||
print(f'WARNING: {len(bad)} concatenated attributes found!')
|
||||
for b in bad[:5]:
|
||||
print(f' {b}')
|
||||
|
||||
with open('frontend/index.html', 'w', encoding='utf-8') as f:
|
||||
f.write(html)
|
||||
|
||||
print(f'data-i18n attributes: {before} → {after} (+{after - before})')
|
||||
print(f'Concatenated: {len(bad)}')
|
||||
Reference in New Issue
Block a user