自动化把文档包装进命令行程序(一):编译文档本身

自动包装文档至命令行程序

需求

写一个项目,有一些文档,文档里有的有待高亮显示,但是md不能让用户直接看见渲染后的结果;html发出去显得太开放了;截图之类的不仅土且空间利用率很差。
提供思路:写自动化程序将其包装进一个可执行文件,可通过命令行参数控制文档的输出,如下面这样

document.exe -exception 124

即输出exception类型的帮助文档,编号为124

思路

我们模仿md提供一个简化版的Markdown,然后利用控制台的彩色字符输出控制码,把要高亮的词汇静态嵌入进去,把整个文档写进另一个语言的函数,函数内调用打印函数输出彩色文档。然后自动化编写解析参数的函数,就能实现如上效果了。分析图如下:

Created with Raphaël 2.3.0 Document源文件 解析内部的特殊标记(高亮) 输出到自动生成的rust文件中 生成解析命令行参数函数,自动映射序号至打印文档函数 用`rustc`编译成可执行文件 完成编译,得到可执行文件

正式实现

写好输出帮助的函数(很低级):

# 显示帮助文档
def show_help():
    print("Usage: docgen <type> <filename> <id> <output>")
    print("type:\n")
    print("    -b\tGenerate document from source file with 'build-time error' mode")
    print("    -r\tGenerate document from source file with 'run-time error' mode")
    print("    -w\tGenerate document from source file with 'warning' mode")
    print("Note: You must give all these arguments or program won't run at all.")
    print("Note: Especially, if you use '-v' or '-h' option, you needn't give filename or output name.")
    print("    -v\tDisplay version")
    print("    -h\tDisplay this help message.")
    print("Note: Use '`' to sign words which are wanted to show with highlight.")

包装一下报错函数(应对id无法转换成int,越界,用户输入不正确等情况):

# 输出错误
def raise_error(con):
    print("docgen: error:", con)
    exit(1)

根据工具的帮助,写出解析命令行参数的主函数

def main():
    args = sys.argv
    tp = None  # 保存文档类型
    for idx, v in enumerate(args):
        if idx == 0:
            continue
        elif idx == 1:
            # type字段,可能是-h
            if v == "-h":
                show_help()
                exit(0)
            else:
                if v not in ["-b", "-r", "-w"]:
                    raise_error("Unknown argument at position 1:%s" % v)
            tp = v
        elif idx == 2:
            # 输入文件字段
            try:
                input_file = open(v, "r", encoding="utf-8")
            except Exception as e:
                raise_error("Could not open file '%s':%s" % (v, str(e)))
        elif idx == 3:
            # id字段
            try:
                match_id = int(v)
            except:
                raise_error("Could not convert `id` to int")
        elif idx == 4:
            # 输出文件字段
            try:
                output_file = open(v, "w+", encoding="utf-8")
            except Exception as e:
                raise_error("Could not create file '%s':%s" % (v, str(e)))
        else:
            raise_error("Too many arguments")
    if idx != 4:
        raise_error("Too few arguments")
    generate(tp, input_file, output_file, match_id)

包括转换参数,检查意义,检查参数充分性,然后调用包装后的生成逻辑.
generate接受四个参数:

  • tp 控制文档类型(b/r/w)
  • input_file接受打开了的IO对象,可读
  • output_file接受打开了可写的IO对象。注意,编码要一致。
  • match_id 接受文档的标记,即后续要映射的数字id

程序处理主逻辑:生成:

def generate(tp, input_file, output_file, match_id):
    content = input_file.read()
    # 下面写入函数头部
    output_file.write("pub fn doc_%s_print_%d() {\n" %
                      ({"-b": "bte", "-r": "rte", "-w": "wrn"}[tp], match_id))
    output_file.write("\tprintln!(\"")
    # 正式解析并输出代码
    flag = False  # 控制未进入高亮模式
    for c in content:
        if c == "\n":
            output_file.write("\");\n\tprintln!(\"")
        elif c == "`":
            if flag:
                # 已经是高亮模式
                output_file.write("\\x1b[0m")
                flag = False
            else:
                # 进入高亮模式
                output_file.write("\\x1b[1;33m")
                flag = True
        elif c == "\"":
            output_file.write("\\\"")
        elif c == "\\":
            output_file.write("\\\\")
        elif c == "{":
            output_file.write("{{")
        elif c == "}":
            output_file.write("}}")
        else:
            output_file.write(c)
    output_file.write("\");\n}\n")
    if flag:
        # 还在高亮模式之内,会导致结束的ASCII控制码未输出
        raise_error("Still in highlight mode")
    output_file.close()
    input_file.close()

一开始根据预设的rust函数命名规则生成头部,然后反复调用println!宏,有高亮的就检查下插进去,然后特殊字符特殊转义一下免得rust内部语法出问题。最后写函数尾部,检查一下高亮块是否关闭,最后清理,关文件,逻辑算简单。
实现效果:
(测试数据)

xyz:normal_text
`abc`:`highlight`

muti-line:`xxxxxxx
fdsfdsfdsfsdf
oer;';;'erer;'`

special-chars:
" " " { } } { \ \

Chinese-tests:
这是中文
这是`高亮`的中文

高亮多行中文
`多行的
 、 中
 文\ 包含特
  " 殊 符{}}{号`

处理命令:

python docgen.py -b test.ddoc 124 test.rs

手动加上主函数:
.
编译运行,得到初步结果:
在这里插入图片描述
可见一切正常。下一节将实现整合文档到一个主文件,可实现自动输出需要的文档内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dtsroy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值