Python练习1-文档格式化成html
2024-09-05 17:57:30
文档格式化成HTML
把文档格式化成了THML,并没有处理所有thml规则,只是处理了一部分,功能不重要,重要的是复习熟悉下Python对文档的处理细节。毕竟Python大多数给我的印象都是处理文档。代码里有很多逻辑可能不严谨,这里再次强调只是为了复习字符串以及文档操作。
同时提醒一下,如果运行失败,请删除注释,我是用vs2015编写的,返现当时中文注释导致编码错误运行失败。一共四个文档:
入口文档是markup.py。
参数 python markup.py < xxx.txt > xxx.html
执行效果和代码如下:
Util.py
def lines(file):
for line in file:yield line
yield '\n'
def blocks(file):
block = []
for line in lines(file):
if line.strip(): #'\n','\r','\t',' '
block.append(line);
elif block:
yield ''.join(block).strip()
block = []
Handlers.py
class Handler:
"""
处理从Parser调用的方法的对象。
这个解析器会在每个块的开始部分调用start()和end()方法,使用合适的
块名作为参数,sub()方法会用于正则表达式替换中。当使用了'emphasis'
这样的名字调用时,它会返回合适的替换函数。
"""
def callback(self ,prefix ,name ,*args):
method = getattr(self ,prefix + name ,None)
if callable(method) : return method(*agrs)
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):
"""
用于生成HTML的具体处理程序
THMLRenderer内容的方法都是可以通过超类处理程序的start()、
end()和sub()方法来访问。他们实现了用于HTRML文档的基本标签。
"""
def start_document(self):
print('<html><head><title>...</title></head><body>')
def end_document(self):
print('</body></html>')
def start_paragraph(self):
print('<p>')
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('<title>')
def end_title(self):
print('</title>')
def sub_emphasis(self ,match):
return ('<em>%s</em>' % match.group(1))
def sub_url(self ,match):
return ('<a href = "%s">%s</a>' % (match.group(1),match.group(1)))
def sub_mail(self ,match):
return ('<a href="mailto:%s">%s</a>' % (match.group(1),match.group(1)))
def feed(self ,data):
print(data)
Rules.py
class Rule:
"""
所有规则的基类。
"""
def action(self ,block ,handler):
handler.start(self.type)
handler.feed(block)
handler.end(self.type)
return True
class HeadingRule(Rule):
"""
标题占一行,最多70个字符,并且不以冒号结尾。
"""
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 = HeadingRule.condition(self ,block)
class ListItemRule(Rule):
"""
列表项是以连字符开始的段落。作为格式化的一部分,要移除连字符。
"""
type = 'listitem'
def condition(self ,block):
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):
return True
def action(self, block, handler):
if not self.inside and ListItemRule.condition(self ,block):
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
Markup.py
import sys,re
from handlers import *
from util import *
from rules import *
class Parser:
#"""
#语法分析器读取文本文件、应用规则并且控制处理程序
# """
def __init__(self ,handler):
self.handler = handler
self.rules = []
self.filters = []
def addRule(self ,rule):
self.rules.append(rule)
def addFilter(self ,pattern ,name):
def filter(bolck ,handler):
return re.sub(pattern ,handler.sub(name),bolck)
self.filters.append(filter)
def parse(self ,file):
self.handler.start('document')
for block in blocks(file):
for filter in self.filters:
block = filter(block ,self.handler)
for rule in self.rules:
if rule.condition(block):
last = rule.action(block ,self.handler)
if last : break
self.handler.end('document')
class BasicTextParser(Parser):
"""
在构造函数中添加规则和过滤器的具体语法分析器
"""
def __init__(self, handler):
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(sys.stdin)
最新文章
- unity对话代码
- spring jdbc分离数据库代码和java代码
- webform repeater控件
- 二模08day1解题报告
- 必须会的SQL语句(八)数据库的完整性约束
- j2SE基回顾(一)
- sqlserver取得本月一号
- ITEXT学习手册
- Mysql:常用代码
- Linux学习笔记12——Unix中的进程
- 有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位。
- shapeless官方指南翻译写在前面
- nodejs中异步
- LinkedHashMap 源码详细分析(JDK1.8)
- 剑指Offer——网易笔试之解救小易——曼哈顿距离的典型应用
- AI - TensorFlow - 示例02:影评文本分类
- MySQL添加用户并授权
- ubuntu sublime text 3 安装
- Python数据分析与挖掘常用模块
- install sz rz linux
热门文章
- 手把手教你Spring Boot2.x整合Elasticsearch(ES)
- CodeMonkey少儿编程第7章 函数
- Flutter学习简记
- 从零学脚手架(七)---webpack-dev-server使用
- 对用pyinstaller打包的exe程序进行反编译,获得源码
- Azure Front Door(三)启用 Web Application Firewall (WAF) 保护Web 应用程序,拒绝恶意攻击
- 浅谈意图识别各种实现&;数学原理
- Web 前端 - 浅谈外部手动控制 Promise 状态
- 热更新语言--lua学习笔记
- PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) 凌宸1642