如何将 DOS ANSI (CP 437) 文件转换为带有 Unicode 的 Unix ANSI?
Posted
技术标签:
【中文标题】如何将 DOS ANSI (CP 437) 文件转换为带有 Unicode 的 Unix ANSI?【英文标题】:How do I convert DOS ANSI (CP 437) files to Unix ANSI with Unicode? 【发布时间】: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 的一部分。
【参考方案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 没有任何优势。以上是关于如何将 DOS ANSI (CP 437) 文件转换为带有 Unicode 的 Unix ANSI?的主要内容,如果未能解决你的问题,请参考以下文章
求C++代码,把ANSI编码的.txt(中文内容的)文件转成成utf-8编码格式的文件