Python基础教程项目1:即使标记源码

  • util.py

# coding=utf-8
__author__ = ‘twocold‘
# 文本块生成器

def lines(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 = []
  • handlers.py

# coding=utf-8
__author__ = ‘twocold‘

class Handler:
    """
    处理从Parser调用的方法的对象

    这个解析器会在每个块的开始部分调用start()和end()方法,使用合适的
    块名作为参数。sub()方法会用于正则表达式替换中。当使用了‘emphasis‘
    这样的名字调用时,它会返回合适的替换函数。
    """
    def callback(self, perfix, name, *args):
        method = getattr(self, perfix+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: result = match.group(1)
            return result
        return substitution

class HTMLRenderer(Handler):
    """
    用于生产HTML的具体处理程序

    HTMLRenderer内的方法都可以通过超类处理程序的start()、
    end()和sub()方法来访问。它们实现了用于HTML文档的基本标签。
    """

    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 ‘<h1>‘

    def end_title(self):
        print ‘</h1>‘

    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

# coding=utf-8
__author__ = ‘twocold‘

class Rule:
    """
    所有规则的基类
    """

    def action(self, block, handler):
        handler.start(self.type)
        handler.feed(block)
        handler.end(self.type)
        return type

class HeadingRule(Rule):
    """
    标题占一行,最多70多个字符,并且不易冒号结尾。
    """
    type = ‘heading‘

    def condition(self, block):
        return not ‘\n‘ not 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 type

class ListRule(ListItemRule):
    """
    列表从不是列表项的块和随后的列表项之间。在最后一个连续列表项之后结束。
    """
    type = ‘list‘
    inside = False

    def condition(self,block):
        return type

    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

# coding=utf-8
__author__ = ‘twocold‘

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(block, handler):
            return re.sub(pattern, handler.sub(name), block)
        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][email protected][\.a-zA-Z]+[a-zA-Z]+)‘, ‘mail‘)

handler = HTMLRenderer()
parser = BasicTextParser(handler)

parser.parse(sys.stdin)
时间: 2024-11-08 20:45:42

Python基础教程项目1:即使标记源码的相关文章

Mz学院ES6视频教程 ES6基础教程 共27课包含源码课件

1.ES6简介.mp42.let基本用法.mp43.let不存在变量提升.mp44.let暂时性死区.mp45.let不允许重复声明.mp46.为什么需要块级作用域.mp47.块级作用域.mp48.const命令.mp49.const对象.mp410.const对象冻结.mp411.跨模块常量.mp412.全局对象属性.mp413.Destructuring.mp414.不完全解构.mp415.制定默认值.mp416.let和const命令.mp417.对象的解构赋值.mp418.对象解构赋值的

python基础教程——即时标记(详解)

最近一直在学习python,语法部分差不多看完了,想写一写python基础教程后面的第一个项目.因为我在网上看到的别人的博客讲解都并不是特别详细,仅仅是贴一下代码,书上内容照搬一下,对于当时刚学习python的我帮助有限. 下面是自己学习过程整理的一些内容. 基础版: 基础教程上面的项目例子,都会先出一个基础的代码版本,然后根据第一个版本,进行相应的补充完善.我们先来看一下util.py这个文件. 1 #encoding:utf-8 2 #生成器,for循环时会依次返回每一行,它只在文件的最后追

Python基础教程__项目(公告板)

由于最近学习Python,从最基础的Python基础教程学起,其中最后的十个项目还是很不错的.个人认为.本人新手,如有错误,还请指教. 书上用的是PostgreSQL,这里用的是MySQL.由于这是一个CGI项目.所以事先需要准备一个可以运行CGI脚本的试验环境. 本次用的是Apache运行cgi.配置网上很多. 其次需要创建一个数据表: CREATE TABLE `messages` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `subject` v

Python基础教程(第十章 自带电池)

本文内容全部出自<Python基础教程>第二版,在此分享自己的学习之路. ______欢迎转载:http://www.cnblogs.com/Marlowes/p/5459376.html______ Created on Marlowes 现在已经介绍了Python语言的大部分基础知识.Python语言的核心非常强大,同时还提供了更多值得一试的工具.Python的标准安装中还包括一组模块,称为标准库(standard library).之前已经介绍了一些模块(例如math和cmath,其中包

python基础教程_学习笔记5:字符串

字符串 基本字符串操作 字符串也是序列,因此序列的基本操作(索引.分片.连接.乘法.长度.求最大值和最小值.成员资格)对字符串同样适用: 索引 >>> 'a_string'[0] 'a' 长度 >>> len('a_string') 8 求最大值 >>> max('a_string') 't' 求最小值 >>> min('a_string') '_' 乘法 >>> 'a_string'*2 'a_stringa_st

Python基础教程(第九章 魔法方法、属性和迭代器)

本文内容全部出自<Python基础教程>第二版,在此分享自己的学习之路. ______欢迎转载:http://www.cnblogs.com/Marlowes/p/5437223.html______ Created on Marlowes 在Python中,有的名称会在前面和后面都加上两个下划线,这种写法很特别.前面几章中已经出现过一些这样的名称(如__future__),这种拼写表示名字有特殊含义,所以绝不要在自己的程序中使用这样的名字.在Python中,由这些名字组成的集合所包含的方法称

《Python基础教程(第二版)》学习笔记 -&gt; 第九章 魔法方法、属性和迭代器

准备工作 >>> class NewStyle(object): more_code_here >>> class OldStyle: more_code_here 在这两个类中,NewStyle是新式的类,OldStyle是旧式的类,如果文件以__metaclass__ = type 开始,那么两个类都是新式类. 构造方法 构造方法,当一个对象被创建后,会立即调用构造方法.Python中创建一个构造方法,只要把init方法的名字从简单的init修改成__init__

Python基础教程(第五章 条件、循环和其他语句)

本文内容全部出自<Python基础教程>第二版,在此分享自己的学习之路. ______欢迎转载:http://www.cnblogs.com/Marlowes/p/5329066.html______ Created on Xu Hoo 读者学到这里估计都有点不耐烦了.好吧,这些数据结构什么的看起来都挺好,但还是没法用它们做什么事,对吧? 下面开始,进度会慢慢加快.前面已经介绍过了几种基本语句(print语句.import语句.赋值语句).在深入介绍条件语句和循环语句之前,我们先来看看这几种基

python基础教程_学习笔记26:好玩的编程

好玩的编程 程序设计的柔术 当大家坐下来并计划应该如何组织程序的时候,对于这个具体的程序,还没有任何的经验.在实现功能的时候,会逐渐地学到对原始设计有用的新知识.不应该无视一路走来所吸取的教训,而应该将它们用于软件的重新设计(或重构)中. 灵活性的实现包括许多方面,下面是其中两个: 原型设计:python最棒的功能之一就是可以快速地编写程序.编写原型程序是更充分地了解问题的一种很好的方法. 配置:灵活性有很多种存在形式.配置的目的就是让程序某部分的改变更简单,对于你和用户来说都是这样. 第三点是