#cargo-build #cargo-subcommand #localization #build #cargo #internationalization #gettext

bin+lib cargo-i18n

Cargo 子命令,用于提取和构建本地化资源,以便嵌入到您的应用程序/库中

25 个版本

0.2.13 2023年11月27日
0.2.10 2022年2月10日
0.2.9 2021年11月29日
0.2.5 2021年4月25日
0.1.10 2020年5月20日

#103 in Cargo 插件

Download history 5/week @ 2024-03-09 1/week @ 2024-03-16 47/week @ 2024-03-30 17/week @ 2024-04-06

111 次每月下载

MIT 许可证

170KB
2.5K SLoC

cargo-i18n crates.io 徽章 许可证徽章 github actions 徽章 依赖状态

这个crate是一个Cargo子命令 cargo i18n,可用于在编译时提取和构建、验证您的crate的本地化资源。已创建i18n-embed库,以便您方便地将这些本地化嵌入到应用程序或库中,并在运行时选择它们。可以同时使用不同的系统。

i18n-embed 支持以下两种本地化系统

您可以使用以下命令安装此工具:cargo install cargo-i18n

cargo i18n 命令读取您的crate根目录中的配置文件(默认名为 i18n.toml),然后从源文件中提取本地化资源,并构建它们。

i18n-build 库包含了该工具的大部分实现。它已单独发布,以便在需要时可以在项目构建脚本中直接使用。

变更日志

使用 cargo-i18ni18n-embed 的项目

与 Fluent 一起使用

现在 i18n-embed 中提供了 Fluent 支持。请参阅该存储库的示例,以及 i18n-embed 文档,了解如何使用它的示例。

有关使用 i18n-embed 时访问 fluent 消息的便捷编译时检查方式,请参阅 fl!() 宏

目前,当使用 fluent 本地化系统时,cargo-i18n 工具不会执行任何验证。然而,有一些计划中的验证(参见跟踪问题 #31)。如果您对此有任何其他想法,请随时为此问题讨论做出贡献。

与 Gettext 一起使用

这是一个如何使用 cargo-i18n 工具和 i18n-embedgettext 本地化工具系统的示例。请注意,在许多方面技术上,gettext 本地化系统不如 fluent 优越,然而总有遗留原因,围绕 gettext 的开发者/翻译生态系统更加成熟。

首先,请确保您已将所需的实用程序安装到您的系统上。请参阅Gettext 系统要求,并安装您将要使用的本地化系统所需的必要实用程序和命令。

定义本地化字符串

您需要确保源代码中要本地化的字符串使用来自 tr 库的 tr!() 宏。

您可以为字符串添加注释,翻译人员可以使用这些注释添加上下文,并确保他们理解字符串的用途。

例如

use tr::tr;

fn example(file: String) {
    let my_string = tr!(
        // {0} is a file path
        // Example message: Printing this file: "file.doc"
        "Printing this file: \"{0}\"",
        file
    );
}

最小配置

您需要在您的 crate 根目录中创建一个 i18n.toml 配置文件。一个使用 gettext 系统将二进制 crate 本地化为西班牙语和日语的最小配置如下

# (Required) The language identifier of the language used in the
# source code for gettext system, and the primary fallback language
# (for which all strings must be present) when using the fluent
# system.
fallback_language = "en"

[gettext]
# (Required) The languages that the software will be translated into.
target_languages = ["es", "ja"]

# (Required) Path to the output directory, relative to `i18n.toml` of the crate
# being localized.
output_dir = "i18n"

请参阅配置以了解所有可用的配置选项。

运行 cargo i18n

打开您的命令行/终端,导航到您的 crate 目录,并运行 cargo i18n。您可能需要输入一些电子邮件地址,用于每个语言的 po 文件的联系点。最后,您的 crate 中应该有一个名为 i18n 的新目录,其中包含 potpomo 目录。

《pot》目录包含使用《xtr》工具从您的源代码中提取的《pot》文件,其中还应包含一个以您的crate名称命名的单个《pot》文件,这是合并所有其他《pot》文件的结果。

《po》目录包含特定语言的消息文件。

《mo》目录包含编译后的消息,这些消息稍后将嵌入到您的应用程序中。

此时,将以下内容添加到您的crate的《.gitignore》(如果您正在使用git)可能是个好主意:

/i18n/pot
/i18n/mo

如果您希望您的crate能够构建而不需要在系统上安装此工具,则可以将《/i18n/mo》目录从《.gitignore》中排除,并提交其中的文件。

嵌入翻译

现在您已经编译了翻译,您可以将它们嵌入到您的应用程序中。为此创建了《i18n-embed》crate。

将以下内容添加到您的《Cargo.toml》依赖项中:

[dependencies]
i18n-embed = "VERSION"

将编译后的翻译嵌入到应用程序中的最小示例可以是:

use i18n_embed::{DesktopLanguageRequester,
    gettext::gettext_language_loader};
use rust_embed::RustEmbed;

#[derive(RustEmbed)]
#[folder = "i18n/mo"] // path to the compiled localization resources
struct Translations;

fn main() {
    let translations = Translations {};
    let language_loader = gettext_language_loader!();

    // Use the language requester for the desktop platform (linux, windows, mac).
    // There is also a requester available for the web-sys WASM platform called
    // WebLanguageRequester, or you can implement your own.
    let requested_languages = DesktopLanguageRequester::requested_languages();

    i18n_embed::select(&language_loader, &translations, &requested_languages);

    // continue with your application
}

您可以在i18n-embed 文档中找到更多关于如何使用此库的详细示例。

分发到翻译者

现在您需要将《po》文件发送给您的翻译者,或者提供他们编辑它们的权限。一些可用于翻译的桌面工具包括

或者您还可以考虑为您的项目设置一个翻译管理网站,以便翻译者可以编辑翻译,而无需与源代码管理交互或处理发送文件和安装应用程序。一些例子

自托管

  • poeditor - 开源项目免费,目前该项目正在使用。
  • crowdin - 受欢迎的开源项目免费。

更新翻译

一旦您从翻译者那里收到一些更新的《po》文件,或者您想用新的或编辑过的字符串更新《po》文件,您只需运行cargo i18n来更新《po》文件,然后重新编译更新的《mo》文件,然后用cargo build重新构建您的应用程序。

对于一些使用构建脚本、复杂管道和持续集成的项目,您可能希望考虑使用i18n-build进行自动化,作为cargo i18n命令行工具的替代方案。

配置

《i18n.toml》可用的配置选项

# (Required) The language identifier of the language used in the
# source code for gettext system, and the primary fallback language
# (for which all strings must be present) when using the fluent
# system.
fallback_language = "en-US"

# (Optional) Specify which subcrates to perform localization within. If the
# subcrate has its own `i18n.toml` then, it will have its localization
# performed independently (rather than being incorporated into the parent
# project's localization).
subcrates = ["subcrate1", "subcrate2"]

# (Optional) Use the gettext localization system.
[gettext]
# (Required) The languages that the software will be translated into.
target_languages = ["es", "ru", "cz"]

# (Required) Path to the output directory, relative to `i18n.toml` of the crate
# being localized.
output_dir = "i18n"

# (Optional) The reporting address for msgid bugs. This is the email address or
# URL to which the translators shall report bugs in the untranslated
# strings.
msg_bugs_address = "[email protected]"

# (Optional) Set the copyright holder for the generated files.
copyright_holder = "You?"

# (Optional) If this crate is being localized as a subcrate, store the final
# localization artifacts (the module pot and mo files) with the parent crate's
# output. Currently crates which contain subcrates with duplicate names are not
# supported. By default this is false.
extract_to_parent = false

# (Optional) If a subcrate has extract_to_parent set to true, then merge the
# output pot file of that subcrate into this crate's pot file. By default this
# is false.
collate_extracted_subcrates = false

# (Optional) How much message location information to include in the output.
# If the type is ‘full’ (the default), it generates the lines with both file
# name and line number: ‘#: filename:line’. If it is ‘file’, the line number
# part is omitted: ‘#: filename’. If it is ‘never’, nothing is generated.
# [possible values: full, file, never].
add_location = "full"

# (Optional) Whether or not to perform string extraction using the `xtr` tool.
xtr = true

# (Optional )Path to where the pot files will be written to by `xtr` command,
# and were they will be read from by the `msginit` and `msgmerge` commands. By
# default this is `output_dir/pot`.
pot_dir = "i18n/pot"

# (Optional) Path to where the po files will be stored/edited with the
# `msgmerge` and `msginit` commands, and where they will be read from with the
# `msgfmt` command. By default this is `output_dir/po`.
po_dir = "i18n/po"

# (Optional) Path to where the mo files will be written to by the `msgfmt`
# command. By default this is `output_dir/mo`.
mo_dir = "i18n/mo"

# (Optional) Enable the `--use-fuzzy` option for the `msgfmt` command. By
# default this is false. If your .po file are copied from another project, you
# may need to enable it.
use_fuzzy = false

# (Optional) Use the fluent localization system.
[fluent]
# (Required) The path to the assets directory.
# The paths inside the assets directory should be structured like so:
# `assets_dir/{language}/{domain}.ftl`
assets_dir = "i18n"

系统需求

Gettext需求

使用此工具的 gettext 本地化系统需要您在系统中安装 gettext

msginitmsgfmtmsgmergemsgcat 命令都必须安装,并且出现在您的路径中。

您还需要确保已安装 xtr 字符串提取命令,这可以通过使用 cargo install xtr 实现。

贡献

欢迎提交 pull request,但对于设计更改,您最好先在实现前创建一个 GitHub issue 进行讨论。您还可以通过以下方式为此工具的本地化做出贡献:

或者,您也可以直接使用您喜欢的 po 编辑器来帮助本地化位于 i18n/poi18n-build/i18n/po 的文件。

要添加新语言,您可以通过 GitHub issue 提出请求,或者提交一个 pull request,将新区域添加到 i18n.toml 中,并使用 cargo i18n 生成相关的新 po 文件。

也欢迎为此 README.md 文件提供翻译,可以通过 pull request 提交。只需将其命名为 README.md.lang,其中 lang 是区域代码(见 ISO 639-1 代码列表)。

作者

依赖项

~17–27MB
~248K SLoC