1

我有一个动态创建的网页。大多数文本是使用翻译机制插入的。但当然现在必须先翻译文本。因此,除了在单独的工具中进行批量翻译之外,我还希望允许在页面中显示翻译的地方发生这种情况。

所以(我认为)我需要做的是,以某种方式标记应该翻译的文本并使用 javascript 创建一个显示翻译小部件并填写元信息的按钮。到现在为止还挺好。问题是,文本可能不仅出现在 html 节点内的 textnodes 中,而且还出现在属性中。这就是为什么我的想法(使用一些 html 标签<translate metadata=.../>,甚至使用 html 注释)不起作用的原因。此外,说“将这些数据放在当前的 html 标记之外”也是不可行的,因为整个代码都使用了翻译例程。

是否有另一种方法可以透明地将元信息放入 html 代码中?也许是不可见的 unicode 字符?(我使用的是 utf-8)

4

3 回答 3

1

在 HTML5 中,有一个全局translate属性

translate属性是一个枚举属性,用于指定在页面本地化时是否要翻译元素的属性值及其 Text 节点子节点的值,或者是否保持它们不变。

您必须添加translate="no"不应翻译的每个元素(请注意,子元素继承该值)。

对于应该翻译属性值而不是元素内容的极端情况,您可以span在内容周围添加一个元素,例如:

<b title="translate this, please" translate="yes"><span translate="no">Don't translate this</span></b> 

对于更复杂的情况,您可以查看W3C Recommendation Internationalization Tag Set (ITS)

于 2013-03-03T12:31:25.043 回答
0

我认为您正在尝试重新发明轮子。谷歌有一个很棒的翻译 API,我认为你应该使用它。

https://developers.google.com/translate/

于 2013-03-02T19:16:41.273 回答
0

我设法自己解决了这个问题,使用零长度的 unicode 字符。

三个字符\u200B(零宽度空格,ZWSP),\u200C(零宽度非连接符,ZWNJ)和\u200D(零宽度连接符,ZWJ)是不可见的控制字符。我选择 ZWSP 作为消歧的边界指标, ZWNJ 作为 binary0和 ZWJ 作为 binary 1。在 PHP 中,这意味着对注释 id 进行编码$nr是这样完成的:

$binnr = decbin($nr);
$annotation = "&#x200B;";
for($i=0; $i<strlen($binnr); $i++)
    $annotation .= '&#x200'.($binnr{$i}=="0"?"c":"d").';';
$annotation .= '&#x200b;';

使用实际字符而不是 html 实体可能会更好。所以我们需要

return html_entity_decode($annotation, ENT_NOQUOTES, 'UTF-8');

我正在将属于这些 id 的元数据收集到一个单独的数组中,并将其放入页眉中。然后在故事的 javascript 方面,搜索 DOM 树以查找编码注释:

function parse_numbers(text)
{
    read = false;
    nrs = []; nr = 0;
    for(var i=0; i<text.length; i++)
    {
        if(text[i] == "\u200B") {
            read = !read;
            if(!read) {
                nrs.push(nr);
                nr = 0;
            }
        } else if(text[i] == "\u200C") {
            nr <<= 1;
        } else if(text[i] == "\u200D") {
            nr <<= 1; nr++;
        }
    }
    return nrs;
}

function buttons_recursive(node, insert)
{
    nrs = [];
    switch(node.nodeType)
    {
        case 1: //ELEMENT_NODE:
            for(var i=0; i<node.attributes.length; i++) {
                nrs.concat(buttons_recursive(node.attributes[i], false));
            }
            var new_insert = insert;
            if(node.nodeName == "BUTTON" || node.nodeName == "A") {
                new_insert = false;
            }
            for(var i=0; i<node.childNodes.length; i++) {
                nrs.concat(buttons_recursive(node.childNodes[i], new_insert));
            }
            break;
        case 2: //ATTRIBUTE_NODE:
            nrs = parse_numbers(node.value);
            break;
        case 3: //TEXT_NODE:
            nrs = parse_numbers(node.nodeValue);
            break;
        default:
            return [];
    }
    if(insert) {
        for(var i=nrs.length-1; i>=0; i--) {
            node.parentNode.insertBefore(create_inline_button(nrs[i]), node.nextSibling);
        }
        return [];
    } else {
        return nrs;
    }
}

通过执行

buttons_recursive(document.body, true);

该函数create_inline_button应创建控制元素以启动具有给定标识符的文本的翻译。

于 2013-03-03T14:09:40.137 回答