Python食谱-1.25.在Unix终端上格式化显示HTML文本
| 原文作者: | Brent Burley, Mark Moraes |
|---|---|
| 中文翻译: | Tony (digitalsatori) |
问题
如何才能在Unix终端上显示HTML文本,使其可以表现粗体和下划线。
解决方案
最简单的方法是编制一个过滤脚本,从标准输入获取HTML然后在标准输出文本和终端控制符。因为本配方针对得唯一对象是Unix, 我们可以通过Unix命令 tput 来获取需要的终端控制符。具体方法是使用Python标准库中os模块中得popen函数来启动tput。
#!/usr/bin/env python
import sys, os, htmllib, formatter
# use Unix tput to get the escape sequences for bold, underline, reset
set_bold = os.popen('tput bold').read( )
set_underline = os.popen('tput smul').read( )
perform_reset = os.popen('tput sgr0').read( )
class TtyFormatter(formatter.AbstractFormatter):
''' a formatter that keeps track of bold and italic font states, and
emits terminal control sequences accordingly.
'''
def _ _init_ _(self, writer):
# first, as usual, initialize the superclass
formatter.AbstractFormatter._ _init_ _(self, writer)
# start with neither bold nor italic, and no saved font state
self.fontState = False, False
self.fontStack = [ ]
def push_font(self, font):
# the `font' tuple has four items, we only track the two flags
# about whether italic and bold are active or not
size, is_italic, is_bold, is_tt = font
self.fontStack.append((is_italic, is_bold))
self._updateFontState( )
def pop_font(self, *args):
# go back to previous font state
try:
self.fontStack.pop( )
except IndexError:
pass
self._updateFontState( )
def updateFontState(self):
# emit appropriate terminal control sequences if the state of
# bold and/or italic(==underline) has just changed
try:
newState = self.fontStack[-1]
except IndexError:
newState = False, False
if self.fontState != newState:
# relevant state change: reset terminal
print perform_reset,
# set underine and/or bold if needed
if newState[0]:
print set_underline,
if newState[1]:
print set_bold,
# remember the two flags as our current font-state
self.fontState = newState
# make writer, formatter and parser objects, connecting them as needed
myWriter = formatter.DumbWriter( )
if sys.stdout.isatty( ):
myFormatter = TtyFormatter(myWriter)
else:
myFormatter = formatter.AbstractFormatter(myWriter)
myParser = htmllib.HTMLParser(myFormatter)
# feed all of standard input to the parser, then terminate operations
myParser.feed(sys.stdin.read( ))
myParser.close( )
讨论
Python标准库中的 formatter.AbstractFormatter 基本类可以工作在任何地方。而本配方中的 TtyFormatter 子类則依赖于类Unix的终端。确切的说是依赖于Unix命令 tput , 利用其获取控制符以输出粗体或下划线,并可以重置终端状态。
本配方中的方法要求只要系统中有 tput 命令即可工作,所以本配方可以工作于包括Linux,Mac OS X 在内的大多数类Unix系统。
如果你的终端模拟器支持其他控制输出样式的控制符,你可以对 TtyFormatter 做响应的调整。比如,在Windows系统上,cmd.exe 命令窗口支持标准ANSI控制符。你可以将这些控制符编入要运行的脚本中。
多数情况下,你可能倾向于使用诸如 lynx -dump - 这样的Unix命令,以获得比本配方更加丰富的输出格式。但是如果你正好面对一个没有 lynx 命令的系统,而该系统又恰好安装有Python,那么本配方的方法就很有用了。
参见
Python标准库参考手册和Python in a Nutshell 中关于 formatter 和 htmllib 模块的介绍;使用 man tput 来了解更多关于 tput 的信息。













