如何使用Unicode将DOS ANSI(CP 437)文件转换为Unix ANSI?

时间:2013-12-02 02:00:26

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

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

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

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

4 个答案:

答案 0 :(得分:3)

涉及两个问题

  • 编码需要从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是唯一使用的转义序列,则应该很容易编写修复图像的程序。

答案 1 :(得分:2)

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

答案 2 :(得分:1)

我在线查找,我找到了一个您无需安装的自动转换器。 http://www.gofunnow.com/convertutf8/convertutf8.php?destencoding=-2#.UqdmkifMrAk

答案 3 :(得分:1)

Littleimp的回答是正确的。

许多ANSI艺术作品的设计目的是要使终端尺寸比当日的标准80列还要宽。贾努斯(Janus)认为这种艺术仅适用于80列是不正确的。仔细的目视检查会发现,某些使用者每行使用更多的字符。

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

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

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

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

要将这些文件转换为更精简的文件,可能需要一个程序/脚本来遍历每一行,仅在找到具有最大行长的行时才插入CR。