我设法自己解决了这个问题,使用零长度的 unicode 字符。
三个字符\u200B
(零宽度空格,ZWSP),\u200C
(零宽度非连接符,ZWNJ)和\u200D
(零宽度连接符,ZWJ)是不可见的控制字符。我选择 ZWSP 作为消歧的边界指标, ZWNJ 作为 binary0
和 ZWJ 作为 binary 1
。在 PHP 中,这意味着对注释 id 进行编码$nr
是这样完成的:
$binnr = decbin($nr);
$annotation = "​";
for($i=0; $i<strlen($binnr); $i++)
$annotation .= 'Ȁ'.($binnr{$i}=="0"?"c":"d").';';
$annotation .= '​';
使用实际字符而不是 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
应创建控制元素以启动具有给定标识符的文本的翻译。