将非拉丁字符和特殊符号 (Ø) 写入 RTF 文件 (javascript)

问题描述 投票:0回答:1

您可以帮助我如何编码与特殊符号混合的非拉丁(俄语)字母,例如:

Abc Ø абв
(这里是英文文本,特殊符号“拉丁o”和俄语文本)。

我现有的 RTF 模板内含“占位符”文本,我需要的是将这个“占位符”替换为“Abc Ø абв”:

我使用页面底部此处的函数将UTF-8解码为Win-1251 - 它成功写入俄语字母,但最终我得到“Ш”而不是“Ø”:

这是我的示例代码以及输入和输出文件:

输入rtf:https://mega.nz/file/CtNB2CiY#yid1nLq9P6Jo8zSRAsXeGai-mZLV6xP1OvN1jDpFyG4

由以下代码生成的输出rtf:https://mega.nz/file/asMExKJI#q8oRn1J9oWMlUck6tJ6MdpVGiIjt81kNFRo7T3eSBTU

const http = require('http');
const port = 3100;

function utf8_decode_to_win1251(srcStr) {
  var tgtStr = "",
    c = 0;
  for (var i = 0; i < srcStr.length; i++) {
    c = srcStr.charCodeAt(i);
    if (c > 127) {
      if (c > 1024) {
        if (c === 1025) {
          c = 1016;
        } else if (c === 1105) {
          c = 1032;
        }
        c -= 848;
      }
      // c = c % 256; // ???
    }
    tgtStr += String.fromCharCode(c);
  }
  return tgtStr;
}


const server = http.createServer(function (req, res) {

  const fs = require('fs');

  // read existing file
  fs.readFile("C:\input.rtf", "utf8", (err, inputText) => {
    if (err) {
      console.error(err);
      return;
    }

    // I want to replace 'placeholder' text in file with this test text:
    let text = `Abc Ø абв`; // 'Abc Ø абв'

    text = utf8_decode_to_win1251(text); // text with encoded russian letters 'Abc Ø àáâ'

    // replace placeholder from input RTF with text with non-latin characters 'Abc Ø àáâ':
    inputText = inputText.replace("placeholder", text);

    // RTF uses 8-bit so need to convert from unicode
    let buf = Buffer.from(inputText, "ascii"); // "binary" also gives wrong output text https://stackoverflow.com/a/34476862/348736


    // write output file to disk
    fs.writeFile("C:\output.rtf", buf, function (error, resultFile) { // result file contains 'Abc Ш абв', which is wrong..
      if (!error) {
        console.info('Created file', resultFile);
      }
      else {
        console.error(error);
      }
    });
  });
});


server.listen(port, function (error) {

  if (error) {
    console.log(`${error}`);
  } else {
    console.log(`listening on port ${port}`);
  }
})
javascript unicode encoding rtf windows-1251
1个回答
0
投票

我认为你不能用 8 位编码来表示“Abc Ø абв”。至少据我所知。

我试图理解你的代码中发生了什么。问题是,在 Windows-1251 中没有字符 Ø,您可以在此表中查看https://www.ascii-code.com/CP1251。在 Windows-1251 中,字符 aбв 确实存在。因此,该函数实际生成 Windows-1251 是没有意义的。但是如果你尝试将“Abc Ø абв”转换为Windows-1252,你会发现Windows-1252确实有字符Ø,但没有абв(这里的a是西里尔字母a,与拉丁字母不同) A)。我认为发生的情况是,您解码为 Windows-1252,但数据最终到达了应该是 Windows-1251 的某个位置。

通过以下方式播放: “Abc Ø абв”翻译为十六进制 (utf-8)

41 62 63  C3 98  D0 B0 D0 B1 D0 B2
。尝试将其解码为 Windows-1252 会得到
41 62 63  D8  E0 E1 E2
。 打印出“Abc Ø àáâ”,这正是您所得到的。 如果随后将同一十六进制的编码从 Windows-1252 更改为 Windows-1251,则会打印“Abc Ш абв”。这又是你的例子中发生的事情。 (您可以在这里尝试一下https://www.rapidtables.com/convert/number/hex-to-ascii.html)。

© www.soinside.com 2019 - 2024. All rights reserved.