추출¶
추출은 소스 코드에 표시된 모든 메시지를 번역자를 위한 .pot 템플릿으로
모으는 단계로, 튜토리얼 루프의 3단계입니다. 이 페이지는 그
단계의 레퍼런스입니다. 설정, 사용자 정의 함수 이름, strict CI 모드,
그리고 그 후 카탈로그를 지키는 검사를 다룹니다.
추출에는 babel extra가 필요합니다.
작업 흐름¶
babel.cfg를 만듭니다.
일반 Babel 명령을 그대로 사용합니다.
pybabel extract -F babel.cfg -c "Translators:" -o locales/messages.pot .
pybabel init -i locales/messages.pot -d locales -l ja
pybabel compile -d locales
init은 언어마다 한 번만 실행합니다. 그 뒤로는 pybabel update가 새
템플릿을 기존 카탈로그에 접어 넣습니다. 그 반복되는 주기 — 그리고 그
fuzzy 항목이 릴리스에 무엇을 뜻하는지 — 는
프로덕션에서가
차례로 살펴봅니다.
추출기는 _(), gettext(), ngettext()도 처리합니다. 따라서 한 매핑으로
tr(), ntr(), lazy_gettext(), lazy_pgettext()가 섞인 코드를 모두
다룹니다.
-c로 번역자 주석을 켜기
일반 gettext처럼 번역자 주석을 모으려면 -c "Translators:"를
전달해야 합니다. 빼도 추출은 그대로 동작합니다 — 주석이 카탈로그에
도달하지 않을 뿐이고, 그곳에서 주석은 이 워크플로 전체에서
가장 값싼 품질 지렛대입니다.
사용자 정의 함수 이름¶
INI 값은 공백이나 쉼표로 나눈 문자열이고 TOML은 목록을 받습니다. 옵션은 여섯 gettext 함수 계열을 모두 지원합니다.
-k는 t-string에 도달하지 않음
mytr(t"…") 같은 helper는 위 옵션에 선언해야 합니다. Babel의
--keyword는 t-string 리터럴을 읽지 않으므로
pybabel extract -k mytr은 경고 없이 누락합니다.
표준 인수 순서만 지원합니다.
로컬에서는 관대하게, CI에서는 엄격하게¶
기본적으로 파일 하나가 잘못되어도 실행이 끝나지 않습니다.
- 거부된 t-string은 경고 후 건너뜁니다.
- 파싱할 수 없는 파일도 같은 방식으로 격리합니다.
tokenize만 거부하는 파일도 격리합니다.
편집하는 동안에는 편리하지만 그렇지 않을 때는 위험합니다. 건너뛴 메시지는
그저 POT에 없을 뿐이라, 번역되지 않으면서 아무것도 그 사실을 알려주지
않습니다. 사람이 추출을 지켜보지 않는 곳에서는 매핑 옵션에
strict = true를 설정하세요.
그러면 위의 모든 경고가 하드 실패가 됩니다. 이쪽을 프로덕션 설정으로, 기본값을 로컬 설정으로 여기세요.
기존 도구 체인으로 검증¶
Babel은 표준 플래그를 추가합니다.
こんにちは {nombre} 같은 번역은 추가 설정 없이 감지됩니다.
$ msgfmt --check-format -o /dev/null locales/ja/LC_MESSAGES/messages.po
locales/ja/LC_MESSAGES/messages.po:25: a format specification for argument
'name' doesn't exist in 'msgstr'
msgfmt: found 1 fatal error
Weblate는 이 검사를 Python brace format으로 설명합니다. 각 플랫폼의 동작은 그 플랫폼의 것입니다. 여기서 검증한 도구는 msgfmt와 패키지가 제공하는 Babel checker입니다.
pybabel compile은 표시된 메시지마다 checker를 실행합니다.
$ pybabel compile -d locales -l ja
error: locales/ja/LC_MESSAGES/messages.po:24: translation does not match the
source placeholders: {name} is missing; {nombre} is not in the source message
1 errors encountered.
복수형 오류에는 해당 형태가 표시됩니다.
error: locales/ru/LC_MESSAGES/messages.po:31: msgstr[1]: translation does not
match the source placeholders: {n} is missing
pybabel compile은 .mo를 계속 기록함
위 오류가 보고되고 종료 상태는 1이지만, 잘못된 카탈로그도 어쨌든
컴파일됩니다. 그 종료 상태만이 파이프라인이 이를 배포하는 것을 막을
수 있으며, 이를 가능하게 하는 빌드 단계는
CI가 막는 것에서 보여줍니다.
두 검사는 중복이 아닙니다. 패키지의 checker는 적어도 두 경우에 더
엄격합니다. 이 checker는 msgfmt가 통과시킬 수 있는
이스케이프된 중괄호와 각 복수형을 따로 검증합니다. ASCII 이름은 모든
도구가 검사하게 하며 라이브러리 자체는 모든 str.isidentifier() 이름을
허용합니다.
템플릿과 다른 도구¶
t-string은 Python 문법입니다. Jinja2({% trans %}), Django와 다른
템플릿은 자체 추출기를 유지하면서 같은 PO 카탈로그를 사용할 수 있습니다.
pygettext는 아직 t-string을 파싱하지 못합니다. 다른 추출기는
명세의 규약을 구현할 수 있습니다.