为 man 手册页编写解析器的备忘录

作者: Linux技术 | 来源:发表于2019-06-12 22:10 被阅读6次

我一般都很喜欢无所事事,但有时候太无聊了也不行 —— 2015 年的一个星期天下午就是这样,我决定开始写一个开源项目来让我不那么无聊。

在我寻求创意时,我偶然发现了一个请求,要求构建一个由 Mathias Bynens 提出的“按 Web 标准构建的 Man 手册页查看器”。没有考虑太多,我开始使用 JavaScript 编写一个手册页解析器,经过大量的反复思考,最终做出了一个 Jroff

那时候,我非常熟悉手册页这个概念,而且使用过很多次,但我知道的仅止于此,我不知道它们是如何生成的,或者是否有一个标准。在经过两年后,我有了一些关于此事的想法。

man 手册页是如何写的

当时令我感到惊讶的第一件事是,手册页的核心只是存储在系统某处的纯文本文件(你可以使用 manpath 命令检查这些目录)。

此文件中不仅包含文档,还包含使用了 20 世纪 70 年代名为 troff 的排版系统的格式化信息。

troff 及其 GNU 实现 groff 是处理文档的文本描述以生成适合打印的排版版本的程序。它更像是“你所描述的即你得到的”,而不是你所见即所得的。

摘自 troff.org

如果你对排版格式毫不熟悉,可以将它们视为 steroids 期刊用的 Markdown,但其灵活性带来的就是更复杂的语法:

groff-compressor

groff 文件可以手工编写,也可以使用许多不同的工具从其他格式生成,如 Markdown、Latex、HTML 等。

为什么 groff 和 man 手册页绑在一起是有历史原因的,其格式随时间有变化,它的血统由一系列类似命名的程序组成:RUNOFF > roff > nroff > troff > groff。

但这并不一定意味着 groff 与手册页有多紧密的关系,它是一种通用格式,已被用于书籍,甚至用于照相排版

此外,值得注意的是 groff 也可以调用后处理器将其中间输出结果转换为最终格式,这对于终端显示来说不一定是 ascii !一些支持的格式是:TeX DVI、HTML、Canon、HP LaserJet4 兼容格式、PostScript、utf8 等等。

该格式的其他很酷的功能是它的可扩展性,你可以编写宏来增强其基本功能。

鉴于 *nix 系统的悠久历史,有几个可以根据你想要生成的输出而将特定功能组合在一起的宏包,例如 man、mdoc、mom、ms、mm 等等。

手册页通常使用 man 和 mdoc 宏包编写。

区分原生的 groff 命令和宏的方式是通过标准 groff 包大写其宏名称。对于 man 宏包,每个宏的名称都是大写的,如 .PP、.TH、.SH 等。对于 mdoc 宏包,只有第一个字母是大写的: .Pp、.Dt、.Sh。

groff-example

挑战

无论你是考虑编写自己的 groff 解析器,还是只是好奇,这些都是我发现的一些更具挑战性的问题。

上下文敏感的语法

表面上,groff 的语法是上下文无关的,遗憾的是,因为宏描述的是主体不透明的令牌,所以包中的宏集合本身可能不会实现上下文无关的语法。

这导致我在那时做不出来一个解析器生成器(不管好坏)。

嵌套的宏

mdoc 宏包中的大多数宏都是可调用的,这差不多意味着宏可以用作其他宏的参数,例如,你看看这个:

宏 Fl(Flag)会在其参数中添加破折号,因此 Fl s 会生成 -s

宏 Ar(Argument)提供了定义参数的工具

宏 Op(Optional)会将其参数括在括号中,因为这是将某些东西定义为可选的标准习惯用法

以下组合 .Op Fl s Ar file 将生成 [-s file],因为 Op 宏可以嵌套。

缺乏适合初学者的资源

让我感到困惑的是缺乏一个规范的、定义明确的、清晰的来源,网上有很多信息,这些信息对读者来说很重要,需要时间来掌握。

有趣的宏

总结一下,我会向你提供一个非常简短的宏列表,我在开发 jroff 时发现它很有趣:

man 宏包:

.TH:用 man 宏包编写手册页时,你的第一个不是注释的行必须是这个宏,它接受五个参数:title、section、date、source、manual。

.BI:粗体加斜体(特别适用于函数格式)

.BR:粗体加正体(特别适用于参考其他手册页)

mdoc 宏包:

.Dd、.Dt、.Os:类似于 man 宏包需要 .TH,mdoc 宏也需要这三个宏,需要按特定顺序使用。它们的缩写分别代表:文档日期、文档标题和操作系统。

.Bl、.It、.El:这三个宏用于创建列表,它们的名称不言自明:开始列表、项目和结束列表。

via: https://monades.roperzh.com/memories-writing-parser-man-pages/

作者:Roberto Dip 译者:wxy 校对:wxy 选题:lujun9972

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关文章

  • 为 man 手册页编写解析器的备忘录

    我一般都很喜欢无所事事,但有时候太无聊了也不行 —— 2015 年的一个星期天下午就是这样,我决定开始写一个开源项...

  • spring boot 自定义参数解析器不生效问题排查

    首先添加自定义的参数解析器 编写注解及添加解析器 注意以下是 Kotlin 代码编写 在接口参数上添加注解 启...

  • RH124|第四章 在红帽企业 Linux 中获取帮助

    阅读man page 目标 完成本节内容后,你可以在本地Linux系统手册页面中找到相关帮助信息。 介绍man命令...

  • linux用户和文件管理

    帮助命令 whatis 命令 #显示命令的简短功能 man 命令 #查看手册页和命令描述 命令--help ...

  • 第七章 AOP

    整体流程:1、解析XML配置:编写一个自定义标签解析器Spring容器,加载这个解析器,并parse配置解析器自动...

  • mac常用命令

    $ man 作用:查阅某个命令的手册页,q 退出英文:Manual pages $ sudo作用:通过安全的方式使...

  • bash手册

    man命令用来访问存储在Linux系统上的手册页面。在想要查找的工具的名称前面输入man命令,就可以找到那个工具相...

  • 学习 Linux/*BSD/Unix 的 30 个最佳在线文档

    手册页(man)是由系统管理员和 IT 技术开发人员写的,更多的是为了作为参考而不是教你如何使用。手册页对于已经熟...

  • Zsh oh-my-zsh

    Reference Mac、Linux 安装zsh & ohmyzsh shell 俗称壳,c语言编写的命令解析器...

  • swift项目使用libxml

    1、安装 Libxml2 是一个 用c语言编写的XML 解析器和工具包,最初是为Gnome项目开发的, 后来被其他...

网友评论

    本文标题:为 man 手册页编写解析器的备忘录

    本文链接:https://www.haomeiwen.com/subject/wvtdfctx.html