【问题标题】:How do I convert DOS ANSI (CP 437) files to Unix ANSI with Unicode?如何将 DOS ANSI (CP 437) 文件转换为带有 Unicode 的 Unix ANSI?
【发布时间】:2013-12-17 15:41:43
【问题描述】:

http://blocktronics.org/ 的 ANSI 文件似乎使用了另一种 ANSI 编码,而不是我的 VT100 终端仿真器支持的编码。

如果我使用tetraview 查看这些文件,它们看起来不错。但是,如果我使用less -r 查看它们,则块字符不起作用。如果我使用iconv -f 437 -t utf-8 | less -r,块字符可以工作,但字符的对齐仍然是混乱的。它在tetraview 中工作,所以一定有某种转换正在进行。

我写了一个脚本来抓取在tmux 中运行的tetraview 的屏幕内容,但这是一个hack,我想做tetraview 自己做的转换。

【问题讨论】:

  • 您能否澄清对齐仍然混乱的意思?另外,您在什么系统上运行 iconv?
  • @zatch_rulz:iconv 正在 Ubuntu Saucy 上运行。当我说对齐搞砸时,我的意思是:i.imgur.com/Lf0RF1u.png 右边是 tetraview,左边是 iconv 输出。两个终端都是 80x24。截图中的文件是来自 ACiD Trip 的dman-warrior.ANS
  • 只是为了给未来的读者节省一些时间:tetraview 是Tetradraw 的一部分。

标签: utf-8 character-encoding codepages ansi-escape terminal-color


【解决方案1】:

涉及两个问题

  • 编码 需要从CP 437 转换为您的终端编码。正如您已经发现的那样,这是使用 iconv -f 437 input_file.ANS 完成的。
  • ANSI escape sequences 需要修复。

dman-warrior.ANS 中使用了两个types of escape sequences。第一个只使用一次,是文件中的第一件事。它是ESC[0m,它会重置所有图形模式属性。第二种类型是ESC[<value>C(例如ESC[24C),它将光标<value>字符向前(向右)移动。如果光标不能继续前进,它就会停止。您可以使用以下 shell 命令在终端中对其进行测试:

printf '\x1b[10000CXYZ\n'

应该是这样的:

|$ printf '\x1b[10000CXYZ\n'              |
|                                        X|
|YZ                                       |
|$                                        |

图像文件只有几行(由 CRLF 分隔)。每个都被包裹到终端宽度(80 列),从而产生几条屏幕线。

图像在文件行中间以ESC[<value>C 转义序列开头的第一行之前都可以。

  • 终端写入上一个屏幕行,在最后一列结束。
  • 满足ESC[<value>C 转义序列。由于位于最后一列,光标不能再向右移动,因此序列被忽略。
  • 接下来是一个字符,它强制换行并打印在下一个屏幕行上。

新的屏幕行缺少应该被转义序列跳过的空白区域。

可能的解决方案

  • 以某种方式改变终端仿真器的行为。 (我不知道怎么做,除了编译一个经过调整的自定义版本。)
  • 明确换行。如果ESC[<value>C 是唯一使用的转义序列,那么编写一个修复图像的程序应该很容易。

【讨论】:

    【解决方案2】:

    这些文件都是“动画”类型,它依赖于特定的屏幕宽度和高度来显示它。您的终端可能没有正确的宽度。

    【讨论】:

    • 我的终端的标准尺寸为 80x24。由于这也是 DOS 的标准宽度,并且 tetraview 成功地在这样的终端中显示图像,我认为这不是问题。
    【解决方案3】:

    Littleimp 的回答有些正确。

    许多 ANSI 艺术作品专为比当前标准 80 列更宽的终端尺寸设计。 Janus 认为这种艺术仅适用于 80 列是不正确的。仔细的目视检查会发现,有些用户每行使用的字符要多得多。

    与大多数标准文本文件不同,许多 ANSI 艺术文件 /not/ 包含 CR 或 CR/LF 来终止每一行的结尾,而是允许终端为它们换行到下一行。这使他们可以使用终端的完整列,例如80 或 132,无需在行尾前进行 CRLF,使最大宽度为 79 或 131。

    所以例如blocktronicks goo-b7.ans 将无法在 160 个字符宽之外的任何终端中正确显示。

    我在此处的 ANSI 图片示例中对此进行了说明: https://i.imgur.com/WBJ8xfs.png

    在每个 X 字符后插入回车的标准 sed/awk 技巧将不起作用,因为不会跳过以 CR/LF 结尾的短行,而是在插入 CR 之前从下一行的长度中减去在不合适的地方。

    要将这些文件转换为更合理的文件,需要一个程序/脚本来逐行执行,仅在找到具有最大行长的行时插入 CR。

    【讨论】:

      【解决方案4】:

      我在网上找了一个你不需要安装的自动转换器。 http://www.gofunnow.com/convertutf8/convertutf8.php?destencoding=-2#.UqdmkifMrAk

      【讨论】:

      • 那个站点使用了“ANSI”的另一种定义,他们可能只是指CP-1251。无论如何,这比 iconv 没有任何优势。
      猜你喜欢
      • 1970-01-01
      • 2012-05-06
      • 2015-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-29
      • 2011-06-03
      • 2022-09-24
      相关资源
      最近更新 更多