背景:调试"在次实现"的代码时,费了1天半的时间;一方面,是代码缩进有问题;另一方面,是书中给的代码有问题。下面,把调试后的代码,粘贴出来,供参考。
思考:学习项目,一方面是成功运行代码;一方面是根据项目用到的技术,回顾知识点,加强记忆。
注意:为了调试代码之间的调用关系,我在代码中加了很多print函数,方便查看调用信息。
书中原始内容,请自行去看电子书、纸质书,或者留言,我给你大家。
说明:test_input.txt、util.py在初次实现中,已提供,这里就不在添加。
(初次实现:https://blog.csdn.net/weixin_42163563/article/details/103235891)
class Handler:
def callback(self, prefix, name, *args):
method = getattr(self, prefix + name, None)
if callable(method):
# print("调用callable为True")
return method(*args)
def start(self, name):
self.callback('start_', name)
def end(self, name):
self.callback('end_', name)
def sub(self, name):
def substitution(match):
result = self.callback('sub_', name, match)
if result is None:
match.group(0)
return result
return substitution
class HTMLRenderer(Handler):
def start_document(self):
print('<html><head><title>...</title></head><body>')
def end_document(self):
print('</body></html>')
def end_paragraph(self):
print('</p>')
def start_heading(self):
print('<h2>')
def end_heading(self):
print('</h2>')
def start_list(self):
print('<ul>')
def end_list(self):
print('</ul>')
def start_listitem(self):
print('<li>')
def end_listitem(self):
print('</li>')
def start_title(self):
print('<h1>')
def end_title(self):
print('</h1>')
def sub_emphasis(self, match):
return '<em>{}</em>'.format(match.group(1))
def sub_url(self, match):
return '<a href="{}">{}</a>'.format(match.group(1), match.group(1))
def sub_mail(self, match):
return '<a href="mailto:{}">{}</a>'.format(match.group(1), match.group(1))
def feed(self, data):
print(data)
class Rule:
def action(self, block, handler):
handler.start(self.type)
handler.feed(block)
handler.end(self.type)
return True
class HeadingRule(Rule):
type = 'heading'
def condition(self, block):
return not '\n' in block and len(block) <= 70 and not block[-1] == ':'
class TitleRule(HeadingRule):
type = 'title'
first = True
def condition(self, block):
if not self.first:
return False
self.first = False
# print("调用HeadingRule.condition方法,返回值:")
# print(HeadingRule.condition(self, block))
return HeadingRule.condition(self, block)
class ListItemRule(Rule):
type = 'listitem'
def condition(self, block):
# print("调用ListItemRule condition方法")
return block[0] == '-'
def action(self, block, handler):
handler.start(self.type)
handler.feed(block[1:].strip())
handler.end(self.type)
return True
class ListRule(ListItemRule):
type = 'list'
inside = False
def condition(self, block):
# print("调用ListRule condition")
return True
def action(self, block, handler):
# print("打印ListItemRule.condition:")
# print(ListItemRule.condition(self, block))
if not self.inside and ListItemRule.condition(self, block):
# print("调用ListRule action方法")
handler.start(self.type)
self.inside = True
elif self.inside and not ListItemRule.condition(self, block):
handler.end(self.type)
self.inside = False
return False
class ParagraphRule(Rule):
type = 'paragraph'
def condition(self, block):
return True
import re
import sys
from handlers import *
from rules import *
from util import *
class Parser:
def __init__(self, handler):
# print("调用Parser方法")
self.handler = handler
self.rules = []
self.filters = []
def addRule(self, rule):
# print("调用addRule方法")
self.rules.append(rule)
# print(self.rules)
def addFilter(self, pattern, name):
# print("调用addFilter方法1")
def filter(block, handler):
# print("调用addFilter方法")
return re.sub(pattern, handler.sub(name), block)
self.filters.append(filter)
# print(self.filters)
def parse(self, file):
# print("调用parse函数")
self.handler.start('document')
# print("调用handler start方法")
for block in blocks(file):
# print("调用blocks方法")
for filter in self.filters:
# print("调用filter方法")
block = filter(block, self.handler)
for rule in self.rules:
if rule.condition(block):
# print("调用rule方法")
last = rule.action(block, self.handler)
# print("last begin:")
# print(last)
# print("last end:")
if last:
break
if last:
break
self.handler.end('document')
class BasicTextParser(Parser):
def __init__(self, handler):
# print("调用BasicTextParser构造方法")
Parser.__init__(self, handler)
self.addRule(ListRule())
self.addRule(ListItemRule())
self.addRule(TitleRule())
# self.addRule(HeadingRule())
self.addRule(ParagraphRule())
self.addFilter(r'\*(.+?)\*', 'emphasis')
self.addFilter(r'(http://[\.a-zA-Z/]+)', 'url')
self.addFilter(r'([\.a-zA-Z]+@[\.a-zA-Z]+[a-zA-Z]+)', 'mail')
handler = HTMLRenderer()
parser = BasicTextParser(handler)
parser.parse(open("test_input.txt", "r+"))
# parser.parse(sys.stdin)
PyCharm控制台输出:
上述结果,保存为html文件,浏览器打开如下:
代码改进的地方:
重复显示的结果如下:
至此,再次实现项目完成,代码供参考。