Neatbo.

PO 结构化词条转换

在 UTF-8 gettext PO 和结构化 JSON 间转换,保留上下文、复数索引、头信息、注释、旧值及废弃词条。

浏览器本地处理输入PO / 结构化 JSON输出结构化 JSON / PO / CSV单个文件最多 1 MiB · 最多 1 个
  1. 1添加输入
  2. 2调整设置
  3. 3获取结果

工具输入和文件在当前浏览器处理,不会上传。

输入内容

切换工具时在当前标签页临时保留输入。刷新或关闭后清除,较大的结果可能需要重新生成。

⌘ / Ctrl + Enter 运行

或将文件拖到这里

文件留在当前设备,原始文件不会被覆盖。

.po · .json

单个文件最多 1 MiB · 最多 1 个

    0 个字符 · 0 字节
    处理选项

    先填写标记为必填的选项,其余可保留默认值。

    正在准备处理工具…

    开始之前

    通过明确的记录结构迁移翻译目录,避免扁平化损失语义。查看活跃与废弃词条,编辑带索引的译文,再生成可读 PO。

    如何使用

    1. 选择 PO → JSON 或结构化 JSON → PO,并打开一个本地 UTF-8 目录。
    2. 在 JSON 中检查上下文、复数、注释及废弃状态,编辑时保留每项全部六个字段。
    3. 下载 catalog.json 和 catalog.po,在接收端 gettext 流程中验证。

    支持范围与限制

    一个 UTF-8 PO/JSON 文件或粘贴源,不超过 1 MiB。最多 10,000 个词条、100,000 个 PO 物理行,每项最多 100 个连续译文索引。生成 PO 不超过 4 MiB。所选文件优先,去除 BOM;输出使用 LF 和规范化引号、分行字符串。 JSON 解析另有 200,000 节点、128 层预算。

    JSON 必须使用 schema=neatbo-po-v1、encoding=UTF-8、entries 和 trailingComments。每项必须包含 context、msgid、plural、translations、comments、obsolete。null 上下文区别于空上下文;单数译文使用键 0,复数从 0 连续编号。拒绝同状态词条身份重复及未知结构字段。

    保留头词条及译文文本、译者/提取/引用/标志/旧值注释行、废弃记录和结尾注释。不扁平化为 msgid 字典,不保留原折行空白,不编译 MO、不翻译、不计算复数表达式;只对明确 nplurals 检查活跃复数译文数量。

    仅接受严格 UTF-8 输入与明确 UTF-8 charset,其他编码会拒绝。支持无缩进声明及 C 字符串的引号、反斜杠、常见控制转义和 UTF-8 字节八/十六进制转义。拒绝未知转义、NUL、不合法引号、缺失 msgstr 和未完成词条内部注释。JSON/PO 保留全部记录,表格/CSV 只摘要词条。

    操作示例

    示例输入

    # catalog comment
    msgid ""
    msgstr ""
    "Content-Type: text/plain; charset=UTF-8\n"
    "Plural-Forms: nplurals=2; plural=(n != 1);\n"
    
    #. extracted comment
    #: app.ts:1 other.ts:2
    #, fuzzy, c-format
    #| msgctxt "old-menu"
    #| msgid "old file"
    msgctxt "menu"
    msgid "%d file"
    msgid_plural "%d files"
    msgstr[0] "%d 个文件"
    msgstr[1] "%d 个文件"
    
    # obsolete comment
    #~| msgid "older"
    #~ msgctxt "old"
    #~ msgid "gone"
    #~ msgstr "旧"
    
    # trailing catalog comment
    
    示例参数
    {"params": {"direction": "po-to-json"}}

    示例输出

    {
      "schema": "neatbo-po-v1",
      "encoding": "UTF-8",
      "entries": [
        {
          "context": null,
          "plural": null,
          "translations": {
            "0": "Content-Type: text/plain; charset=UTF-8\nPlural-Forms: nplurals=2; plural=(n != 1);\n"
          },
          "comments": [
            "# catalog comment"
          ],
          "obsolete": false,
          "msgid": ""
        },
        {
          "context": "menu",
          "plural": "%d files",
          "translations": {
            "0": "%d 个文件",
            "1": "%d 个文件"
          },
          "comments": [
            "#. extracted comment",
            "#: app.ts:1 other.ts:2",
            "#, fuzzy, c-format",
            "#| msgctxt \"old-menu\"",
            "#| msgid \"old file\""
          ],
          "obsolete": false,
          "msgid": "%d file"
        },
        {
          "context": "old",
          "plural": null,
          "translations": {
            "0": "旧"
          },
          "comments": [
            "# obsolete comment",
            "#~| msgid \"older\""
          ],
          "obsolete": true,
          "msgid": "gone"
        }
      ],
      "trailingComments": [
        "# trailing catalog comment"
      ]
    }

    出现问题时

    使用完整导出结构,修正缺失、重复字段和索引。非 UTF-8 目录请先明确转码,修复引号或不支持的转义,避免将注释放入未完成词条。预算超限时缩小目录。

    常见问题

    可以输入扁平翻译 JSON 吗?

    不可以。扁平对象无法忠实表达上下文、复数索引和废弃状态,请使用工具导出的结构。

    会计算 Plural-Forms 吗?

    不会。表达式保持在头信息中,只检查明确声明的 nplurals 与活跃复数译文数量是否一致。

    转换后能逐字节还原源文件吗?

    不能。词条值和注释行保留,但 PO 引号、分行、空白间隔和换行格式会规范化。

    文档与延伸阅读

    相关工具