1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - IncludeComments Macro 4 5 @copyright: 2013 by Paul Boddie <paul@boddie.org.uk> 6 @license: GNU GPL (v2 or later), see COPYING.txt for details. 7 8 Code from the Include macro: 9 10 @copyright: 2000-2004 Juergen Hermann <jh@web.de>, 11 2000-2001 Richard Jones <richard@bizarsoftware.com.au> 12 @license: GNU GPL (v2 or later), see COPYING.txt for details. 13 """ 14 15 from MoinMoin.Page import Page 16 from MoinMoin.macro import Include 17 from MoinMoin.user import User 18 from MoinMoin.wikiutil import escape 19 import re 20 import codecs 21 22 try: 23 from cStringIO import StringIO 24 except ImportError: 25 from StringIO import StringIO 26 27 Dependencies = ['pages'] 28 29 # Macro functions. 30 31 def execute(macro, text): 32 request = macro.request 33 fmt = request.formatter 34 page = request.page 35 pagename = page.page_name 36 _ = request.getText 37 38 output = [] 39 append = output.append 40 41 # Add a heading. 42 43 append(fmt.heading(on=1, depth=1)) 44 append(fmt.text(_("Comments"))) 45 append(fmt.heading(on=0, depth=1)) 46 47 # Provide a form for adding new comments. 48 49 if request.user.valid and request.user.may.write(pagename): 50 51 d = { 52 "show_form" : escape(_("Add a comment to this page.")), 53 "comment_label" : escape(_("Write a comment in the box.")), 54 "comment_default" : "", 55 "submit" : escape(_("Submit this comment")), 56 } 57 58 append("""\ 59 <div id="includecomments-anchor"> 60 <a href="#includecomments-anchor">%(show_form)s</a> 61 <form action="?action=PostComment" method="post" class="includecomments-form"> 62 <p>%(comment_label)s</p> 63 <textarea name="comment" cols="60" rows="10">%(comment_default)s</textarea> 64 <p><input name="submit" type="submit" value="%(submit)s" /></p> 65 </form> 66 </div> 67 """ % d) 68 69 # NOTE: Much of the code below originates from the Include macro, but it 70 # NOTE: excludes various options of that macro and adds comment-related 71 # NOTE: output. 72 73 # Add included comments. 74 75 filterfn = re.compile(ur"^%s/" % re.escape(pagename), re.U).match 76 pages = request.rootpage.getPageList(filter=filterfn) 77 pages.sort() 78 79 ownerfn = re.compile("^#pragma comment-owner (.*?)$", re.MULTILINE | re.UNICODE).search 80 81 # Track included pages. 82 83 if not hasattr(page, '_macroInclude_pagelist'): 84 page._macroInclude_pagelist = {} 85 86 # Visit each comment page. 87 88 for inc_name in pages: 89 90 # Skip unreadable or already included pages. 91 92 if not request.user.may.read(inc_name): 93 continue 94 if inc_name in page._macroInclude_pagelist: 95 continue 96 97 # Obtain a separate formatter for the included page. 98 99 inc_fmt = macro.formatter.__class__(request, is_included=True) 100 inc_fmt._base_depth = macro.formatter._base_depth 101 102 # Obtain the included page. 103 104 inc_page = Page(request, inc_name, formatter=inc_fmt) 105 if not inc_page.exists(): 106 continue 107 inc_page._macroInclude_pagelist = page._macroInclude_pagelist 108 109 if not hasattr(request, "_Include_backto"): 110 request._Include_backto = pagename 111 112 # Output a container for the included page. 113 114 append(fmt.div(1, id=inc_name, css_class="included-comment")) 115 116 # Add a label indicating a comment. 117 118 match = ownerfn(inc_page.get_raw_body()) 119 if match: 120 user = User(request, auth_username=match.group(1)) 121 if user.exists(): 122 append(fmt.div(1, css_class="included-comment-owner")) 123 append(fmt.text(user.aliasname or user.name)) 124 append(fmt.div(0)) 125 126 # Set or increment include marker. 127 128 page._macroInclude_pagelist[inc_name] = \ 129 page._macroInclude_pagelist.get(inc_name, 0) + 1 130 131 # Output the included page. 132 133 strfile = codecs.getwriter("utf-8")(StringIO()) 134 request.redirect(strfile) 135 try: 136 inc_page.send_page(content_only=True, 137 omit_footnotes=True, 138 count_hit=False) 139 append(unicode(strfile.getvalue(), "utf-8")) 140 finally: 141 request.redirect() 142 143 # Decrement or remove include marker. 144 145 if page._macroInclude_pagelist[inc_name] > 1: 146 page._macroInclude_pagelist[inc_name] = \ 147 page._macroInclude_pagelist[inc_name] - 1 148 else: 149 del page._macroInclude_pagelist[inc_name] 150 151 # Close the container for the included page. 152 153 append(fmt.div(0)) 154 155 return u"".join(output) 156 157 # vim: tabstop=4 expandtab shiftwidth=4