Home | History | Annotate | Download | only in extensions
      1 import markdown
      2 from markdown 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)
    115