概述

在本文中,我们将会演示如何一步步开发一个命令行交互式工具。

知识预览

在本文中,我们将会涉及到如下一系列内容:

  1. ansi 库
  2. markdown 库
  3. 实战示例

    ansi 库

    ansi 库专门用于提供各种 ANSI 转义码,用于在文本控制台中移动光标或呈现彩色文本,这对于我们开发一个较好体验的控制台程序而言是非常重要的。
    例如,我们可以发送一个消息,它是使用黄色字体,背景为红色:
    1. from ansi.colour import fg, bg
    2. from ansi.colour.fx import reset
    3. msg = (bg.red, fg.yellow, 'Hello world!', reset)
    4. print(''.join(map(str, msg)))
    其中:
  • bg.red 表示背景是红色
  • fg.yellow 表示字体的黄色
  • ‘Hello world!’ 是要打印的字符串
  • reset 表示针对该字符串打印完成要恢复原始颜色

    markdown 库

    Python-Markdown 也是一个 Python 第三方扩展库,主要用于处理 markdown 文本,并且支持将 markdown 文本与其他类型的文本进行格式转化。
    它的安装非常简单:
    1. pip3 install markdown
    它的使用也非常简单,例如它可以方便的将 markdown 转化为 html 格式:
    1. import markdown
    2. html = markdown.markdown(your_text_string)
    同时,针对不支持的格式转化而言,markdown 也提供了足够的扩展能力,支持通过 extensions 的模式进行扩展,示例如下:
    1. md = Markdown(output_format="ansi", extensions=[ExtraExtension(), AnsiExtension()])
    此时,我们得到的 md 的实例就可以用于文本格式转化了:
    1. converted_msg = md.convert(msg)

    实战示例

    了解了上述背景知识之后,我们就可以通过一个示例项目看一下如何编写一个命令行的交互式工具。 ```python import time from logzero import logger from ansi.colour import fg, fx from markdown import Markdown from markdown.extensions.extra import ExtraExtension from ansiext import AnsiExtension

一个示例 markdown 文本

INTRO = “””

You start as a bot admin in a one-on-one conversation with the bot.

Context of the chat

  • Use !inroom{:color=’blue’} to switch to a room conversation.
  • Use !inperson{:color=’blue’} to switch back to a one-on-one conversation.
  • Use !asuser{:color=’green’} to talk as a normal user.
  • Use !asadmin{:color=’red’} to switch back as a bot admin.

Preferences

  • Use !ml{:color=’yellow’} to flip on/off the multiline mode (Enter twice at the end to send).

“””

是否开启多行输入模式

MULTILINE = False

def ansi(): “””This makes a converter from markdown to ansi (console) format. It can be called like this: from errbot.rendering import ansi md_converter = ansi() # you need to cache the converter

  1. ansi_txt = md_converter.convert(md_txt)
  2. """
  3. md = Markdown(output_format="ansi", extensions=[ExtraExtension(), AnsiExtension()])
  4. md.stripTopLevelTags = False
  5. return md

def send_message(msg: str) -> None:

  1. # md to ascii
  2. print(ansi().convert(msg))

def callback_message(msg: str, trigger: str) -> None: print(“msg %s execute by %s” % ( msg, trigger ))

if name == “main“:

  1. # 发送引导消息
  2. send_message(INTRO)
  3. try:
  4. while True:
  5. print("\n")
  6. full_msg = ""
  7. while True:
  8. prompt = "[␍] " if full_msg else ">>> "
  9. frm = "atomis"
  10. to = "opentesting rebot"
  11. # 设置颜色
  12. color = fg.green
  13. prompt = f"{color}[{frm} ➡ {to}] {fg.cyan}{prompt}{fx.reset}"
  14. # 读取输入
  15. entry = input(prompt)
  16. if not MULTILINE:
  17. full_msg = entry
  18. break
  19. if not entry:
  20. break
  21. full_msg += entry + "\n"
  22. # todo: 调用函数相关逻辑
  23. callback_message(full_msg, frm)
  24. time.sleep(0.5)
  25. except EOFError:
  26. pass
  27. except KeyboardInterrupt:
  28. pass
  29. finally:
  30. # simulate some real presence
  31. logger.debug("Trigger disconnect callback")
  32. logger.debug("Trigger shutdown")

```