diff options
author | Richard Darst <rkd@zgib.net> | 2009-07-30 19:19:19 (GMT) |
---|---|---|
committer | Richard Darst <rkd@zgib.net> | 2009-07-30 19:19:19 (GMT) |
commit | 3873ed163f5bb2709e002b127437f77105784cd5 (patch) | |
tree | 464932da8c7c6789b49cb8b0e1568b3842d7f5c3 | |
parent | ae57372fe7e8e922532934b848de123e6026ffe4 (diff) |
add Text and HTML2 writers
- These combine the best features of the ReST and HTMLfromReST, without
the disadvantages of having to make one source fit two formats.
darcs-hash:20090730191919-82ea9-f7f88a57e8b59720f59c26bfe1961f93cda818bc.gz
-rw-r--r-- | items.py | 84 | ||||
-rw-r--r-- | writers.py | 263 |
2 files changed, 321 insertions, 26 deletions
@@ -62,11 +62,18 @@ class _BaseItem(object): endhtml = '' startrst = '' endrst = '' - def get_replacements(self): + starttext = '' + endtext = '' + def get_replacements(self, escapewith): replacements = { } for name in dir(self): if name[0] == "_": continue replacements[name] = getattr(self, name) + replacements['nick'] = escapewith(replacements['nick']) + if 'line' in replacements: + replacements['line'] = escapewith(replacements['line']) + if 'topic' in replacements: + replacements['topic'] = escapewith(replacements['topic']) return replacements def makeRSTref(self, M): if self.nick[-1] == '_': @@ -92,49 +99,67 @@ class Topic(_BaseItem): html_template = """<tr><td><a href='%(link)s#%(anchor)s'>%(time)s</a></td> <th colspan=3>%(starthtml)sTopic: %(topic)s%(endhtml)s</th> </tr>""" + #html2_template = ("""<b>%(starthtml)s%(topic)s%(endhtml)s</b> """ + # """(%(nick)s, <a href='%(link)s#%(anchor)s'>%(time)s</a>)""") + html2_template = ("""<b>%(starthtml)s%(topic)s%(endhtml)s</b> """ + """(<a href='%(link)s#%(anchor)s'>%(nick)s</a>, %(time)s)""") rst_template = """%(startrst)s%(topic)s%(endrst)s (%(rstref)s_)""" + text_template = """%(starttext)s%(topic)s%(endtext)s (%(nick)s, %(time)s)""" startrst = '**' endrst = '**' def __init__(self, nick, line, linenum, time_): self.nick = nick ; self.topic = line ; self.linenum = linenum self.time = time.strftime("%H:%M:%S", time_) - def html(self, M): - repl = self.get_replacements() - repl['nick'] = writers.html(self.nick) - repl['topic'] = writers.html(self.topic) + def _htmlrepl(self, M): + repl = self.get_replacements(escapewith=writers.html) repl['link'] = self.logURL(M) - return self.html_template%repl + return repl + def html(self, M): + return self.html_template%self._htmlrepl(M) + def html2(self, M): + return self.html2_template%self._htmlrepl(M) def rst(self, M): self.rstref = self.makeRSTref(M) - repl = self.get_replacements() + repl = self.get_replacements(escapewith=writers.rst) if repl['topic']=='': repl['topic']=' ' - else: repl['topic']=writers.rst(self.topic) - repl['nick'] = writers.rst(self.nick) repl['link'] = self.logURL(M) return self.rst_template%repl + def text(self, M): + repl = self.get_replacements(escapewith=writers.text) + repl['link'] = self.logURL(M) + return self.text_template%repl class GenericItem(_BaseItem): itemtype = '' html_template = """<tr><td><a href='%(link)s#%(anchor)s'>%(time)s</a></td> <td>%(itemtype)s</td><td>%(nick)s</td><td>%(starthtml)s%(line)s%(endhtml)s</td> </tr>""" + #html2_template = ("""<i>%(itemtype)s</i>: %(starthtml)s%(line)s%(endhtml)s """ + # """(%(nick)s, <a href='%(link)s#%(anchor)s'>%(time)s</a>)""") + html2_template = ("""<i>%(itemtype)s</i>: %(starthtml)s%(line)s%(endhtml)s """ + """(<a href='%(link)s#%(anchor)s'>%(nick)s</a>, %(time)s)""") rst_template = """*%(itemtype)s*: %(startrst)s%(line)s%(endrst)s (%(rstref)s_)""" + text_template = """%(itemtype)s: %(starttext)s%(line)s%(endtext)s (%(nick)s, %(time)s)""" def __init__(self, nick, line, linenum, time_): self.nick = nick ; self.line = line ; self.linenum = linenum self.time = time.strftime("%H:%M:%S", time_) - def html(self, M): - repl = self.get_replacements() - repl['nick'] = writers.html(self.nick) - repl['line'] = writers.html(self.line) + def _htmlrepl(self, M): + repl = self.get_replacements(escapewith=writers.html) repl['link'] = self.logURL(M) - return self.html_template%repl + return repl + def html(self, M): + return self.html_template%self._htmlrepl(M) + def html2(self, M): + return self.html2_template%self._htmlrepl(M) def rst(self, M): self.rstref = self.makeRSTref(M) - repl = self.get_replacements() - repl['nick'] = writers.rst(self.nick) - repl['line'] = writers.rst(self.line) + repl = self.get_replacements(escapewith=writers.rst) repl['link'] = self.logURL(M) return self.rst_template%repl + def text(self, M): + repl = self.get_replacements(escapewith=writers.text) + repl['link'] = self.logURL(M) + return self.text_template%repl class Info(GenericItem): @@ -160,7 +185,12 @@ class Link(_BaseItem): html_template = """<tr><td><a href='%(link)s#%(anchor)s'>%(time)s</a></td> <td>%(itemtype)s</td><td>%(nick)s</td><td>%(starthtml)s<a href="%(url)s">%(url_readable)s</a> %(line)s%(endhtml)s</td> </tr>""" + #html2_template = ("""<i>%(itemtype)s</i>: %(starthtml)s<a href="%(url)s">%(url_readable)s</a> %(line)s%(endhtml)s """ + # """(%(nick)s, <a href='%(link)s#%(anchor)s'>%(time)s</a>)""") + html2_template = ("""<i>%(itemtype)s</i>: %(starthtml)s<a href="%(url)s">%(url_readable)s</a> %(line)s%(endhtml)s """ + """(<a href='%(link)s#%(anchor)s'>%(nick)s</a>, %(time)s)""") rst_template = """*%(itemtype)s*: %(startrst)s%(url)s %(line)s%(endrst)s (%(rstref)s_)""" + text_template = """%(itemtype)s: %(starttext)s%(url)s %(line)s%(endtext)s (%(nick)s, %(time)s)""" def __init__(self, nick, line, linenum, time_): self.nick = nick ; self.linenum = linenum self.time = time.strftime("%H:%M:%S", time_) @@ -170,19 +200,23 @@ class Link(_BaseItem): self.url = self.url.replace('"', "%22") # readable line satitization: self.line = writers.html(self.line.strip()) - def html(self, M): - repl = self.get_replacements() - repl['nick'] = writers.html(self.nick) + def _htmlrepl(self, M): + repl = self.get_replacements(escapewith=writers.html) repl['url'] = writers.html(self.url) repl['url_readable'] = writers.html(self.url) - repl['line'] = writers.html(self.line) repl['link'] = self.logURL(M) - return self.html_template%repl + return repl + def html(self, M): + return self.html_template%self._htmlrepl(M) + def html2(self, M): + return self.html2_template%self._htmlrepl(M) def rst(self, M): self.rstref = self.makeRSTref(M) - repl = self.get_replacements() - repl['nick'] = writers.rst(self.nick) - repl['line'] = writers.rst(self.line) + repl = self.get_replacements(escapewith=writers.rst) repl['link'] = self.logURL(M) #repl['url'] = writers.rst(self.url) return self.rst_template%repl + def text(self, M): + repl = self.get_replacements(escapewith=writers.text) + repl['link'] = self.logURL(M) + return self.text_template%repl @@ -217,7 +217,139 @@ class HTML(_BaseWriter): for m in M.minutes: # The hack below is needed because of pickling problems if m.itemtype != "ACTION": continue - ActionItems.append(" <li>%s</li>"%m.line) #already escaped + ActionItems.append(" <li>%s</li>"%html(m.line)) + if len(ActionItems) == 0: + ActionItems.append(" <li>(none)</li>") + ActionItems = "\n".join(ActionItems) + + # Action Items, by person (This could be made lots more efficient) + ActionItemsPerson = [ ] + for nick, items in self.iterActionItemsNick(): + headerPrinted = False + for m in items: + if not headerPrinted: + ActionItemsPerson.append(" <li> %s <ol>"%html(nick)) + headerPrinted = True + ActionItemsPerson.append(" <li>%s</li>"%html(m.line)) + if headerPrinted: + ActionItemsPerson.append(" </ol></li>") + # unassigned items: + ActionItemsPerson.append(" <li><b>UNASSIGNED</b><ol>") + numberUnassigned = 0 + for m in self.iterActionItemsUnassigned(): + ActionItemsPerson.append(" <li>%s</li>"%html(m.line)) + numberUnassigned += 1 + if numberUnassigned == 0: + ActionItemsPerson.append(" <li>(none)</li>") + ActionItemsPerson.append(' </ol>\n</li>') + ActionItemsPerson = "\n".join(ActionItemsPerson) + + # People Attending + PeoplePresent = [ ] + # sort by number of lines spoken + for nick, count in self.iterNickCounts(): + PeoplePresent.append(' <li>%s (%s)</li>'%(html(nick), count)) + PeoplePresent = "\n".join(PeoplePresent) + + # Actual formatting and replacement + repl = self.replacements() + repl.update({'MeetingItems':MeetingItems, + 'ActionItems': ActionItems, + 'ActionItemsPerson': ActionItemsPerson, + 'PeoplePresent':PeoplePresent, + }) + body = self.body + body = body%repl + body = replaceWRAP(body) + return body +class HTML2(_BaseWriter): + + body = textwrap.dedent('''\ + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> + <html> + <head> + <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> + <title>%(pageTitle)s</title> + </head> + <body> + <h1>%(pageTitle)s</h1> + Meeting started by %(owner)s at %(starttime)s %(timeZone)s. + (<a href="%(fullLogs)s">full logs</a>)<br> + + %(MeetingItems)s + Meeting ended at %(endtime)s %(timeZone)s. + (<a href="%(fullLogs)s">full logs</a>) + + <br><br><br> + + <b>Action Items</b><ol> + %(ActionItems)s + </ol> + <br> + + <b>Action Items, by person</b> + <ol> + %(ActionItemsPerson)s + </ol><br> + + <b>People Present (lines said):</b><ol> + %(PeoplePresent)s + </ol> + + <br> + Generated by <a href="%(MeetBotInfoURL)s">MeetBot</a>. + </body></html> + ''') + + def format(self, extension=None): + """Write the minutes summary.""" + M = self.M + + # Add all minute items to the table + MeetingItems = [ ] + MeetingItems.append("<ol>") + + + + haveTopic = None + inSublist = False + for m in M.minutes: + item = '<li>'+m.html2(M) + if m.itemtype == "TOPIC": + if inSublist: + MeetingItems.append("</ol>") + inSublist = False + if haveTopic: + MeetingItems.append("</li>") + item = item + haveTopic = True + else: + if not inSublist: + MeetingItems.append('<ol type="a">') + inSublist = True + if haveTopic: item = wrapList(item, 2)+"</li>" + else: item = wrapList(item, 0)+"</li>" + MeetingItems.append(item) + #MeetingItems.append("</li>") + + if inSublist: + MeetingItems.append("</ol>") + if haveTopic: + MeetingItems.append("</li>") + + + + MeetingItems.append("</ol>") + MeetingItems = "\n".join(MeetingItems) + + # Action Items + ActionItems = [ ] + for m in M.minutes: + # The hack below is needed because of pickling problems + if m.itemtype != "ACTION": continue + ActionItems.append(" <li>%s</li>"%html(m.line)) + if len(ActionItems) == 0: + ActionItems.append(" <li>(none)</li>") ActionItems = "\n".join(ActionItems) # Action Items, by person (This could be made lots more efficient) @@ -399,3 +531,132 @@ class HTMLfromReST(_BaseWriter): 'raw_enabled': 0, 'output_encoding':self.M.config.output_codec}) return rstToHTML + + + +class Text(_BaseWriter): + + body = textwrap.dedent("""\ + %(titleBlock)s + %(pageTitle)s + %(titleBlock)s + + + WRAPMeeting started by %(owner)s at %(starttime)s %(timeZone)s. + The `full logs`_ are available.WRAP + + .. _`full logs`: %(fullLogs)s + + + + Meeting log + ----------- + %(MeetingItems)s + + Meeting ended at %(endtime)s %(timeZone)s. + + + + + Action Items + ------------ + %(ActionItems)s + + + + + Action Items, by person + ----------------------- + %(ActionItemsPerson)s + + + + + People Present (lines said) + --------------------------- + %(PeoplePresent)s + + + + + Generated by `MeetBot`_ + + .. _`MeetBot`: %(MeetBotInfoURL)s + """) + + def format(self, extension=None): + """Return a ReStructured Text minutes summary.""" + M = self.M + + # Agenda items + MeetingItems = [ ] + #M.rst_urls = [ ] + #M.rst_refs = { } + haveTopic = None + for m in M.minutes: + item = "* "+m.text(M) + if m.itemtype == "TOPIC": + item = wrapList(item, 0) + haveTopic = True + else: + if haveTopic: item = wrapList(item, 2) + else: item = wrapList(item, 0) + MeetingItems.append(item) + MeetingItems = '\n'.join(MeetingItems) + #MeetingURLs = "\n".join(M.rst_urls) + #del M.rst_urls, M.rst_refs + MeetingItems = MeetingItems# + '\n\n'+MeetingURLs + + # Action Items + ActionItems = [ ] + for m in M.minutes: + # The hack below is needed because of pickling problems + if m.itemtype != "ACTION": continue + #already escaped + ActionItems.append(wrapList("* %s"%text(m.line), indent=0)) + ActionItems = "\n".join(ActionItems) + + # Action Items, by person (This could be made lots more efficient) + ActionItemsPerson = [ ] + for nick in sorted(M.attendees.keys(), key=lambda x: x.lower()): + headerPrinted = False + for m in M.minutes: + # The hack below is needed because of pickling problems + if m.itemtype != "ACTION": continue + if m.line.find(nick) == -1: continue + if not headerPrinted: + ActionItemsPerson.append("* %s"%text(nick)) + headerPrinted = True + ActionItemsPerson.append(wrapList("* %s"%text(m.line), 2)) + m.assigned = True + # unassigned items: + ActionItemsPerson.append("* **UNASSIGNED**") + numberUnassigned = 0 + for m in M.minutes: + if m.itemtype != "ACTION": continue + if getattr(m, 'assigned', False): continue + ActionItemsPerson.append(wrapList("* %s"%text(m.line), 2)) + numberUnassigned += 1 + if numberUnassigned == 0: ActionItemsPerson.append(" * (none)") + ActionItemsPerson = "\n".join(ActionItemsPerson) + + # People Attending + PeoplePresent = [ ] + # sort by number of lines spoken + for nick, count in self.iterNickCounts(): + PeoplePresent.append('* %s (%s)'%(text(nick), count)) + PeoplePresent = "\n".join(PeoplePresent) + + # Actual formatting and replacement + repl = self.replacements() + repl.update({'titleBlock':('='*len(repl['pageTitle'])), + 'MeetingItems':MeetingItems, + 'ActionItems': ActionItems, + 'ActionItemsPerson': ActionItemsPerson, + 'PeoplePresent':PeoplePresent, + }) + body = self.body + body = replaceWRAP(body) + body = body%repl + return body + |