python的即时标记项目练习笔记
这是《python基础教程》后面的实践,照着写写,一方面是来熟悉python的代码方式,另一方面是练习使用python中的基本的以及非基本的语法,做到熟能生巧。
这个项目一开始比较简单,不过重构之后就有些复杂了,但是更灵活了。
按照书上所说,重构之后的程序,分为四个模块:处理程序模块,过滤器模块,规则(其实应该是处理规则),语法分析器。
先来说处理程序模块,这个模块的作用有两个,一个是提供那些固定的html标记的输出(每一个标记都有start和end),另一个是对这个标记输出的开始和结束提供了一个友好的访问接口。来看下程序handlers.py:
代码如下:
class Handler:
'''
'''
def callback(self, prefix, name, *args):
method = getattr(self,prefix name,None)
if callable(method): 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 '
def end_document(self):
print ''
def start_paragraph(self):
print '
'
def end_paragraph(self):
print '
def start_heading(self):
print '
'
def end_heading(self):
print '
'def start_list(self):
print '
- '
def end_list(self):
print '
def start_listitem(self):
print '
def end_listitem(self):
print '
def start_title(self):
print '
'
def end_title(self):
print '
'def sub_emphasis(self, match):
return '%s' % match.group(1)
def sub_url(self, match):
return '%s' % (match.group(1),match.group(1))
def sub_mail(self, match):
return '%s' % (match.group(1),match.group(1))
def feed(self, data):
print data
这个程序堪称是整个“项目”的基石所在:提供了标签的输出,以及字符串的替换。理解起来也比较简单。
再来看第二个模块“过滤器”,这个模块更为简单,其实就是一个正则表达式的字符串。相关代码如下:
代码如下:
self.addFilter(r'*(. ?)*', 'emphasis')
self.addFilter(r'(http://[.a-z0-9A-Z/] )', 'url')
self.addFilter(r'([.a-zA-Z] @[.a-zA-Z] [a-zA-Z] )','mail')
这就是三个过滤器了,分别是:强调牌过滤器(用×号标出的),url牌过滤器,email牌过滤器。熟悉正则表达式的同学理解起来是没有压力的。
再来看第三个模块“规则”,这个模块,抛开那祖父类不说,其他类应该有的两个方法是condition和action,前者是用来判断读进来的字符串是不是符合自家规则,后者是用来执行操作的,所谓的执行操作就是指调用“处理程序模块”,输出前标签、内容、后标签。 来看下这个模块的代码,其实这个里面几个类的关系,画到类图里面看会比较清晰。 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):
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
return 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
补充utils.py:
代码如下:
def line(file):
for line in file:yield line
yield 'n'
def blocks(file):
block = []
for line in lines(file):
if line.strip():
block.append(line)
elif block:
yield ''.join(block).strip()
block = []
最后隆重的来看下“语法分析器模块”,这个模块的作用其实就是协调读入的文本和其他模块的关系。在往重点说就是,提供了两个存放“规则”和“过滤器”的列表,这么做的好处就是使得整个程序的灵活性得到了极大的提高,使得规则和过滤器变成的热插拔的方式,当然这个也归功于前面在写规则和过滤器时每一种类型的规则(过滤器)都单独的写成了一个类,而不是用if..else来区分。 看代码:
代码如下:
import sys, re
from handlers import *
from util import *
from rules import *
类解析器:
def __init__(self,handler):
self.handler = 处理程序
self.rules = []
self.filters = []
def addRule(self, 规则):
self.rules.append(规则)
def addFilter(self,pattern,name):
def 过滤器(块,处理程序):
return re.sub(pattern, handler.sub(name),block)
self.filters.append(过滤器)
def parse(self, file):
self.handler.start('文档')
对于块中的块(文件):
对于 self.filters 中的过滤器:
block = filter(block, self.handler)
对于 self.rules 中的规则:
if 规则.条件(块):
最后 = Rule.action(block, self.handler)
如果最后:打破
self.handler.end('文档')
类BasicTextParser(解析器):
def __init__(self,handler):
解析器.__init__(self,handler)
self.addRule(ListRule())
self.addRule(ListItemRule())
self.addRule(TitleRule())
self.addRule(HeadingRule())
self.addRule(ParagraphRule())
self.addFilter(r'*(. ?)*', '强调')
self.addFilter(r'(http://[.a-z0-9A-Z/] )', 'url')
self.addFilter(r'([.a-zA-Z] @[.a-zA-Z] [a-zA-Z] )','mail')
处理程序 = HTMLRenderer()
解析器 = BasicTextParser(handler)
parser.parse(sys.stdin)
这个模块里面的处理思路是,遍历客户端(顺序执行的入口)给插进去的所有的规则和过滤器,来处理读进来的文本。
有一个细节的地方要说一下,其实就是和前面写的呼应一下,就是在遍历规则的时候通过调用条件这个东西来判断是否符合当前规则。
我觉得这个程序很相当于命令行模式,有空可以复习一下该模式,以保持记忆网节点的提醒性。
最后说一下我认为这个程序的用途:
1、用来做代码高亮分析,如果改写成js版本的话,可以做一个在线代码编辑器。
2、可以用来学习,供我写博文用。
还有其他的思路,可以给你留下真知灼见。
补充一个类图,很简陋,但是应该能说明之间的关系。另外我还是建议如果看代码捋不清楚关系最好自己画图,自己画图才能熟悉整个结构。

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

不可能直接在手机上用单一应用完成 XML 到 PDF 的转换。需要使用云端服务,通过两步走的方式实现:1. 在云端转换 XML 为 PDF,2. 在手机端访问或下载转换后的 PDF 文件。

手机XML转PDF的速度取决于以下因素:XML结构的复杂性手机硬件配置转换方法(库、算法)代码质量优化手段(选择高效库、优化算法、缓存数据、利用多线程)总体而言,没有绝对的答案,需要根据具体情况进行优化。

C语言中没有内置求和函数,需自行编写。可通过遍历数组并累加元素实现求和:循环版本:使用for循环和数组长度计算求和。指针版本:使用指针指向数组元素,通过自增指针遍历高效求和。动态分配数组版本:动态分配数组并自行管理内存,确保释放已分配内存以防止内存泄漏。

无法找到一款将 XML 直接转换为 PDF 的应用程序,因为它们是两种根本不同的格式。XML 用于存储数据,而 PDF 用于显示文档。要完成转换,可以使用编程语言和库,例如 Python 和 ReportLab,来解析 XML 数据并生成 PDF 文档。

XML 转换图片需要先确定 XML 数据结构,再选择合适的图形化库(如 Python 的 matplotlib)和方法,根据数据结构选择可视化策略,考虑数据量和图片格式,进行分批处理或使用高效库,最终根据需求保存为 PNG、JPEG 或 SVG 等格式。

可以将 XML 转换为图像,方法是使用 XSLT 转换器或图像库。XSLT 转换器:使用 XSLT 处理器和样式表,将 XML 转换为图像。图像库:使用 PIL 或 ImageMagick 等库,从 XML 数据创建图像,例如绘制形状和文本。

没有APP可以将所有XML文件转成PDF,因为XML结构灵活多样。XML转PDF的核心是将数据结构转换为页面布局,需要解析XML并生成PDF。常用的方法包括使用Python库(如ElementTree)解析XML,并利用ReportLab库生成PDF。对于复杂XML,可能需要使用XSLT转换结构。性能优化时,考虑使用多线程或多进程,并选择合适的库。

想要通过XML生成图片,需要使用图形库(如Pillow、JFreeChart)作为桥梁,根据XML中的元数据(尺寸、颜色)生成图片。控制图片大小的关键在于调整XML中<width>和<height>标签的值。然而,在实际应用中,XML结构的复杂性、图形绘制的精细度、图片生成的速度和内存消耗,以及图片格式的选择,都对生成的图片大小产生影响,因此需要深入理解XML结构、熟练掌握图形库,以及考虑优化算法和图片格式选择等因素。
