Openapoc: 用 fmt 替换 tinyfmt (https://github.com/fmtlib/fmt)

创建于 2019-09-16  ·  9评论  ·  资料来源: OpenApoc/OpenApoc

文件:

  • 允许位置参数以简化翻译(例如,字符串格式(“Do {0} 到 {1}”,thing1,thing2)可以“翻译”为“Do {1} 到 {0}”,以允许在刑罚
  • 目前在 c++20 标准草案中,所以很可能很快就会出现在标准库中(更少的依赖和更广泛的使用和程序员暴露是好的)
  • 更快的编译时间
  • 运行时间快

与tinyformat相比。

Enhancement Feature Request

所有9条评论

这是在处理吗?

我已经让初始端口在本地工作,但还没有时间完善它并正确测试(例如,所有翻译字符串都需要更新,因此我将其用作使字符串自动从代码中提取的好点使用 xgettext 作为构建目标等)

它还揭示了许多“糟糕”的翻译策略——例如将翻译过的文本片段拼接在一起而不是一次做错误的字符串(例如“format(tr("%s, %s"), format(tr(") %s 的东西是 %d 的 "), object, count), format(tr(out of "%d total"), number));

这将导致翻译人员完全无用的字符串:
“%s %s”
“%s 是 %d”
“共 %d 个”

当它真的应该被翻译为单个调用时,所以提取的字符串应该是:
“%s 事物占 %d 项总数中的 %d”(或 fmtlib 处事方式中的“{0} 项事物占 {2} 项总数中的 {1}”)

据我所知,必须有两个不同的格式化子系统:

  1. {fmt}的日志记录(因为 IMO 翻译潜在不断变化的日志消息几乎没有什么好处,并且通过boost::locale路由它们会影响性能。
  2. boost::locale::format用于可本地化的 UI 字符串(因为它支持复数形式)。

我建议以小步骤实现它们:首先切换到{fmt}然后处理可本地化的字符串。

我不确定 boost::locale 是否真的对我们的未来有用 - 它对于具有静态翻译数据库的静态应用程序非常有用,但我一直在努力寻找可以连接到它的消息数据库以添加来自的新消息模组。

我认为只能在新的翻译域中添加一个全新的数据库,然后我们会遇到一些问题,试图找出我们应该用哪个域来翻译字符串,而无需像尝试 /all/ mod 域那样按顺序尝试,直到我们找到匹配

所以我目前的计划是尝试将每个任务分开 - 类似于你提到的:

  • 对所有日志和内部字符串使用 {fmt}(它在某些地方用于构造 ID 等 - 我们明确不想翻译的东西)
    -- 这将涉及从 %printf 样式到 {fmt} 的重大字符串更改,但理想情况下不会影响翻译
  • 使用 xgettext 自动连接 .pot 生成
    -- 这可能会突出大部分“糟糕”的翻译工作——有些人似乎已经将 OG .exe 提取的字符串作为“黄金”翻译消息源,尽管 openapoc 的字符串在某些地方的构造非常不同
  • 检查“错误”翻译字符串构造的来源(如我上面提到的示例),或不应翻译的字符串(日志、内部 ID 字符串等)或应翻译但不翻译的字符串(即直接使用 ::format())
    -- 这应该通过上一步变得更容易,因为它在生成的 .pot 中应该很明显
  • 将所有 /translated/ 字符串从 %printf 样式转换为 {fmt}/boost::locale 样式(我认为它们在功能上是相同的,因为我们目前没有任何胸膜注释或类似的注释)
    -- 这将使几乎所有当前的翻译工作无效-因此可能不值得在阶段之间进行任何翻译更新

我几乎在各个州都有上述所有阶段 - 尝试让它们进入可用状态对我来说可能是有意义的,现在这个长周末我有一些时间,我想这将是我的下一个任务:)

一旦这一切都完成了,我们就可以开始担心添加新字符串的 mods 是如何工作的

将所有 /translated/ 字符串从 %printf 样式转换为 {fmt}/boost::locale 样式(我认为它们在功能上是相同的,因为我们目前没有任何胸膜注释或类似的注释)

实际上,它们看起来很相似—— boost::locale具有基于 1 的索引和截然不同的格式语法。 如果不是复数形式,我会使用{fmt}因为我发现它对命名参数的支持对翻译人员添加有价值的上下文很有帮助,例如:

Delay = {seconds}
Range = {meters:2.1}m.

虽然我发现对复数形式的支持更有价值。

是的,我记得索引让我开始:)

TBH 向前发展 我认为 boost::locale 格式很好,我相信我们可以解决未来的 mod 上下文问题。

或者至少当我们发现“下一个”问题时,所有已翻译的字符串将采用更加合理的格式,并且不会与未翻译的格式化文本混合。

此外,老实说,整个 UString 类应该是一组围绕 std::basic_string 的助手- 但看起来它在 c++20 之前不会可靠。

我很想用 std::string (IE std::basic_string),但是我们将失去“已知 utf8”与“字节数组”的类型安全性 - 但我不确定我们是否真的在使用它。 我们只需要在接口上小心,但我们今天不小心,只是调用 .cStr()/.str() 没有任何真正的转换作为“退出”

IT 目前“碰巧”工作,因为我倾向于在已经在其系统 API 中使用 utf8 的平台上进行测试 - 但我怀疑如果我们今天尝试做一些事情,比如在 Windows 上打开一个带有非 ascii 路径的文件名,它目前会中断

此页面是否有帮助?
0 / 5 - 0 等级