如何创建支持 ANSI 转义码序列的可滚动控制台应用程序 [英] How to create scrollable console application that support ANSI escape code sequences

查看:32
本文介绍了如何创建支持 ANSI 转义码序列的可滚动控制台应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里根据我所知道的技术对技术做出一些假设,但欢迎其他技术建议.

I am making some assumptions here on technology based on what I know, but other technology recommendations are welcome.

我的目标:编写一个 ANSI Art 查看器,尽可能类似于在 DOS 上查看机器尽可能,最好没有运行 dosbox 的开销.这将在 Raspberry Pi 上运行.

My goal: Write an ANSI Art viewer that as closely as possible resembles viewing on a DOS machine as possible, preferably without the overhead of running dosbox. This will run on a Raspberry Pi.

我已经让我的控制台正确地使用正确的字符、颜色等对 ANSI 进行分类.查看器"的问题是我希望能够使用箭头键在文档中上下滚动,很像,比如说,less"命令所做的.

I have gotten my console to properly cat an ANSI with proper characters, colors, etc. The catch with the "viewer" is that I would like to be able to use the arrow keys to scroll up and down through the document, much like, say, the "less" command does.

根据我的研究,curses 是一个完美的候选者.问题是curses 不支持ANSI 转义码序列.有一个用 C++ 编写的 ANSI 编辑器,它使用了curses,但它构建了自己的解析转义码序列的支持.现在这是我最后的手段.

From what I have been able to research, curses is a perfect candidate for this. The problem is that curses does not support ANSI escape code sequences. There is an ANSI editor written in C++ that uses curses, but it builds its own support for parsing the escape code sequences. Right now this is my last resort.

所以我的问题是:是否有更好的方法来创建可滚动的控制台模式应用程序以在 linux 上的 python 中查看 ANSI 艺术(代码页 437 + ANSI 转义码序列)?

So my question is: Is there a better route to creating a scrollable console-mode application for viewing ANSI Art (Code Page 437 + ANSI escape code sequences) in python on linux?

推荐答案

实际上只有两种可能性:将 ANSI 序列解析为 curses 可以接受的内容,或者按原样使用 ANSI 序列.

There are really only two possibilities: Parse the ANSI sequences into something curses can accept, or use the ANSI sequences as-is.

起初,后者可能看起来更有吸引力.大多数限制要么与您无关,要么易于处理:

At first, the latter may seem more attractive. Most of the limitations are either irrelevant to you, or easy to deal with:

  • 它仅适用于静态 ANSI 艺术,不适用于动画文件.这是非常合理的,因为在动画文件中向上滚动"没有多大意义.(当然,您可以将其即时渲染到画布上,然后在其中上下滚动窗口,但是一旦您开始考虑渲染和窗口化的含义……您正在解析 ANSI 艺术.)但这听起来像您只需要静态的 ANSI 艺术.
  • 它仅在您的终端(足够接近)与 ANSI 兼容时才有效……但它是(或可以如此),否则您的 cat 命令将不起作用.(您可能仍然对颜色设置有疑问,但我想您也知道如何解决这个问题.)
  • 它仅在您的终端是 cp437 时才有效,这可能是一个更大的问题……但这很容易解决;只需 decode('cp437') 然后在您的代码中进行适当的编码;转义序列将保持不变.
  • 您可能需要原始键盘输入.但这就像 tty.setraw(sys.stdin.fileno()) 一样简单,只需将 stdin 作为无缓冲文件读取即可.(好吧,您可能希望将原始 tcgetattr 藏起来,以便以后可以恢复它,但这并不难.)
  • 您必须自己解析键盘输入转义序列.这通常有很多工作要做……但只需处理 ANSI-art 兼容终端的向上和向下箭头就很容易了.
  • 您必须知道如何将 ANS 文件映射到实际行.
  • It only works for static ANSI art, not animated files. Which is pretty reasonable, because it wouldn't make much sense to "scroll up" in an animated file. (You could of course render it on the fly to a canvas and then scroll a window up and down within that, but once you start thinking about what that rendering and windowing means… you're parsing ANSI art.) But it sounds like you only need static ANSI art.
  • It only works if your terminal is (close enough to) ANSI compatible… but it is (or can be made so) or your cat command wouldn't work. (You may still have a problem with the color settings, but I assume you know how to work around that too.)
  • It only works if your terminal is cp437, which may be more of a problem… but that's trivial to work around; just decode('cp437') then encode as appropriately in your code; the escape sequences are going to pass through unchanged.
  • You probably want raw keyboard input. But this is as easy as tty.setraw(sys.stdin.fileno()) and just reading stdin as an unbuffered file. (Well, you may want to stash the original tcgetattr so you can restore it later, but that's not much harder.)
  • You'll have to parse keyboard input escape sequences yourself. This is a lot of work to do generally… but just handling the up and down arrows for ANSI-art-compatible terminals is easy.
  • You'll have to know how to map the ANS file to actual lines.

最后一个听起来很容易,但事实并非如此.例如,我抓取了一个随机文件,GR-BANT;它只有 33 行,但它有 154 个换行符.这将是非常普遍的.在很多情况下,它只是以esc-[-A开头的覆盖线",你必须将其视为上一行的一部分,这并不难,但是会有很多情况需要不止于此.

That last one sounds like the easy part, but it's not. For example, I grabbed a random file, GR-BANT; it's only 33 lines long, but it's got 154 newlines in it. And that's going to be pretty common. In many cases, it's just going to be "overlay lines" that start with esc-[-A, that you have to treat as part of the previous line, which is not hard to do, but there will be plenty of cases that require something more than that.

因此,无论如何,您都必须至少进行一些 ANSI 解析.

So, you're going to have to do at least some ANSI parsing, no matter what.

一旦你开始这样做,我想你会发现你的最后手段"更容易进行完整解析并手动绘制到诅咒垫.(当然,这有副作用,可以处理动画文件、在非 ANSI 终端上工作、在所有终端上更轻松地处理键盘"键,……)

And once you start on that, I think you'll find an easier time with your "last resort" of doing a full parse and drawing manually to a curses pad. (And of course this has the side effects of making it possible to handle animated files, working on non-ANSI terminals, handling "keypad" keys more easily and on all terminals, …)

但如果您想走第二种方式,这里是一个快速入门的方法.

But if you want to go the second way, here is a quick hack that should get you started.

这篇关于如何创建支持 ANSI 转义码序列的可滚动控制台应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆