如何使用粗体等的转义码生成联机帮助页?

mur*_*uru 8 less man roff groff

在检查的源代码时less,我注意到包含的联机帮助页 ( less.man) 使用终端转义码来显示粗体文本:

^[[1mNAME^[[0m
       less - opposite of more

^[[1mSYNOPSIS^[[0m
       ^[[1mless -?^[[0m
       ^[[1mless --help^[[0m
       ^[[1mless -V^[[0m
       ^[[1mless --version^[[0m
       ^[[1mless [-[+]aABcCdeEfFgGiIJKLmMnNqQrRsSuUVwWX~]^[[0m
Run Code Online (Sandbox Code Playgroud)

用于生成的命令显然是nroff -man:

$ head Makefile.aut 
# Makefile for authoring less.

EMAIL = bug-less@gnu.org
HOMEPAGE = http://www.greenwoodsoftware.com/less
SHELL = /bin/sh
RCS = rcs
NROFF = nroff -man
Run Code Online (Sandbox Code Playgroud)

然而,如果我运行nroff -man less.nro,我会使用退格键获得(通常的)联机帮助页输出:

N^HNA^HAM^HME^HE
       less - opposite of more

S^HSY^HYN^HNO^HOP^HPS^HSI^HIS^HS
       l^Hle^Hes^Hss^Hs -^H-?^H?
       l^Hle^Hes^Hss^Hs -^H--^H-h^Hhe^Hel^Hlp^Hp
       l^Hle^Hes^Hss^Hs -^H-V^HV
       l^Hle^Hes^Hss^Hs -^H--^H-v^Hve^Her^Hrs^Hsi^Hio^Hon^Hn
Run Code Online (Sandbox Code Playgroud)

如何生成第一个表格?

Tho*_*key 10

“第一种形式”是groff. 如果您的“nroff”不是 的包装器groff,您将只会看到第二种形式。

该功能在grotty(用于打字机类设备的 groff 驱动程序)的手册页中被引用:

默认情况下, grotty 发出 SGR 转义序列(来自 ISO 6429,也称为 ANSI 颜色转义)来更改文本属性(粗体、斜体、颜色)。这使得有可能有​​八种不同的背景背景底色和前景色;另外,粗体和斜体属性可用于在同一时间 (通过使用BI字体)。

在实践中,它不能很好地工作,例如,在此处查看相同的评论(对这些序列进行后处理)是如何被错误渲染的:

默认情况下,grotty发出 SGR 转义序列(来自 ISO 6429,也称为 ANSI 颜色转义)来更改文本属性(粗体、斜体、颜色)。这使得有可能有​​八种不同的M[green]backgroundM[]和m[red]foregroundm[]颜色;此外,粗体和斜体属性可以同时使用BI](通过使用 BI 字体)。

出于这个原因,一些开发人员选择不使用它(例如,来自 Emacs 邮件列表的讨论)。

但是,正如手册页所说的“默认”。所以,如果你有 groff,那么它应该产生那些转义序列。

打包者可以应用补丁来修改程序。@muru 的评论提到了 Debian 中的版本(请参阅错误报告和软件包页面)。包更改日志是这样说的:

 -- Colin Watson <cjwatson@debian.org>  Sat, 27 Jul 2002 18:41:46 +0100
groff (1.18-1) unstable; urgency=low 

  * Disable the new ANSI colour/bold/underline escapes in nroff mode,
    because most pagers either fail to cope with it or need special options
    to do so. It can be re-enabled by editing /etc/groff/man.local and
    /etc/groff/mdoc.local, or by setting the environment variable GROFF_SGR
    to something non-empty.
Run Code Online (Sandbox Code Playgroud)

但是, groff 来源没有提到GROFF_SGR; 它只引用了GROFF_NO_SGR:

./NEWS:1108:  for the GROFF_NO_SGR environment variable also.
./NEWS:1450:o If the environment variable GROFF_NO_SGR is set, SGR output is disa...
./PROBLEMS:33:  1. Set the GROFF_NO_SGR environment variable.
./doc/webpage.ms:1920:.  URL #GROFF_NO_SGR GROFF_NO_SGR
./doc/webpagewebpage.ms:1922:. nop GROFF_NO_SGR
./doc/webpagewebpage.ms:2437:.TAG GROFF_NO_SGR        
./doc/webpagewebpage.ms:2439:If the environment variable GROFF_NO_SGR is set, SGR output is 
./src/devices/grotty/grotty.man:126:.B GROFF_NO_SGR
./src/devices/grotty/grotty.man:394:.B GROFF_NO_SGR
./src/devices/grotty/tty.cpp:864:  if (getenv("GROFF_NO_SGR"))
Run Code Online (Sandbox Code Playgroud)

并且变更日志(ChangeLog.118)没有给出任何线索:

2002-02-12  Werner LEMBERG  <wl@gnu.org>

        * src/libs/libgroff/Makefile.sub (snprintf.o): Don't use
        $(COMPILE.c) to not include groff's assert.h.        
        * src/drivers/grotty/tty.cc (main): Add GROFF_NO_SGR environment
        variable.                           
        * NEWS, src/drivers/grotty/grotty.man: Document it. 
Run Code Online (Sandbox Code Playgroud)

设置GROFF_NO_SGR不会给出 SGR 序列(联机帮助页是正确的)。Debian 更改日志注释引用了来自 的这个块/etc/groff/man.local,其中 Debian 添加了对GROFF_SGR变量的检查:

.  \" Debian: Disable the use of SGR (ANSI colour) escape sequences by
.  \" grotty. 
.  if '\V[GROFF_SGR]'' \
.    output x X tty: sgr 0
Run Code Online (Sandbox Code Playgroud)

并设置环境变量确实会使其生成粗体等的 SGR 序列。