1
import markdown
2
from markdown.util import etree
3
4
DEFAULT_URL = "http://www.freewisdom.org/projects/python-markdown/"
5
DEFAULT_CREATOR = "Yuri Takhteyev"
6
DEFAULT_TITLE = "Markdown in Python"
7
GENERATOR = "http://www.freewisdom.org/projects/python-markdown/markdown2rss"
8
9
month_map = { "Jan" : "01",
10
              "Feb" : "02",
11
              "March" : "03",
12
              "April" : "04",
13
              "May" : "05",
14
              "June" : "06",
15
              "July" : "07",
16
              "August" : "08",
17
              "September" : "09",
18
              "October" : "10",
19
              "November" : "11",
20
              "December" : "12" }
21
22
def get_time(heading):
23
24
    heading = heading.split("-")[0]
25
    heading = heading.strip().replace(",", " ").replace(".", " ")
26
27
    month, date, year = heading.split()
28
    month = month_map[month]
29
30
    return rdftime(" ".join((month, date, year, "12:00:00 AM")))
31
32
def rdftime(time):
33
34
    time = time.replace(":", " ")
35
    time = time.replace("/", " ")
36
    time = time.split()
37
    return "%s-%s-%sT%s:%s:%s-08:00" % (time[0], time[1], time[2],
38
                                        time[3], time[4], time[5])
39
40
41
def get_date(text):
42
    return "date"
43
44
class RssExtension (markdown.Extension):
45
46
    def extendMarkdown(self, md, md_globals):
47
48
        self.config = { 'URL' : [DEFAULT_URL, "Main URL"],
49
                        'CREATOR' : [DEFAULT_CREATOR, "Feed creator's name"],
50
                        'TITLE' : [DEFAULT_TITLE, "Feed title"] }
51
52
        md.xml_mode = True
53
        
54
        # Insert a tree-processor that would actually add the title tag
55
        treeprocessor = RssTreeProcessor(md)
56
        treeprocessor.ext = self
57
        md.treeprocessors['rss'] = treeprocessor
58
        md.stripTopLevelTags = 0
59
        md.docType = '<?xml version="1.0" encoding="utf-8"?>\n'
60
61
class RssTreeProcessor(markdown.treeprocessors.Treeprocessor):
62
63
    def run (self, root):
64
65
        rss = etree.Element("rss")
66
        rss.set("version", "2.0")
67
68
        channel = etree.SubElement(rss, "channel")
69
70
        for tag, text in (("title", self.ext.getConfig("TITLE")),
71
                          ("link", self.ext.getConfig("URL")),
72
                          ("description", None)):
73
            
74
            element = etree.SubElement(channel, tag)
75
            element.text = text
76
77
        for child in root:
78
79
            if child.tag in ["h1", "h2", "h3", "h4", "h5"]:
80
      
81
                heading = child.text.strip()
82
                item = etree.SubElement(channel, "item")
83
                link = etree.SubElement(item, "link")
84
                link.text = self.ext.getConfig("URL")
85
                title = etree.SubElement(item, "title")
86
                title.text = heading
87
88
                guid = ''.join([x for x in heading if x.isalnum()])
89
                guidElem = etree.SubElement(item, "guid")
90
                guidElem.text = guid
91
                guidElem.set("isPermaLink", "false")
92
93
            elif child.tag in ["p"]:
94
                try:
95
                    description = etree.SubElement(item, "description")
96
                except UnboundLocalError:
97
                    # Item not defined - moving on
98
                    pass
99
                else:
100
                    if len(child):
101
                        content = "\n".join([etree.tostring(node)
102
                                             for node in child])
103
                    else:
104
                        content = child.text
105
                    pholder = self.markdown.htmlStash.store(
106
                                                "<![CDATA[ %s]]>" % content)
107
                    description.text = pholder
108
    
109
        return rss
110
111
112
def makeExtension(configs):
113
114
    return RssExtension(configs)