def parse(story): """ The main workhorse that does nothing but call MoinMoin to do its dirty laundry @param story: A text for conversion @type story: string @returns: formatted string @rtype: string """ s = StringIO() oldstdout = sys.stdout form = None page = Page(None) page.hilite_re = None request = Request() request.user = User() formatter = Formatter(request) formatter.setPage(page) sys.stdout = s Parser(story, request).format(formatter, form) sys.stdout = oldstdout result = s.getvalue() s.close() return result
def convert(self, text): del self.response[:] formatter = Formatter(self) formatter.setPage(Page()) Parser(text, self).format(formatter) html = "".join(self.response) return html
def parse15(story): """ The main workhorse that does nothing but call MoinMoin to do its dirty laundry. This version compatible with MoinMoin 1.5 @param story: A text for conversion @type story: string @returns: formatted string @rtype: string """ s = StringIO() oldstdout = sys.stdout form = None request = RequestCLI() #request.user = User() page = Page(request, '') page.hilite_re = None formatter = Formatter(request) formatter.setPage(page) sys.stdout = s Parser(story, request).format(formatter) sys.stdout = oldstdout result = s.getvalue() s.close() return result
def __init__(self, request, static=[], formatter=None, **kw): if formatter: self.formatter = formatter else: from MoinMoin.formatter.text_html import Formatter self.formatter = Formatter(request, store_pagelinks=1) self.static = static self.code_fragments = [] self.__formatter = "formatter" self.__parser = "parser" self.request = request self.__lang = request.current_lang self.__in_p = 0 self.__in_pre = 0 self.text_cmd_begin = '\nrequest.write(' self.text_cmd_end = ')\n'
def url(self, on, url='', css=None, **kw): if on == 0: self._in_mailto = False if url.startswith('mailto:'): self._in_mailto = True url = url.replace('@', ' at ') url = url.replace('.', ' dot ') css = 'link_email' return Formatter.url(self, on, url, css, **kw)
def make_macro(request, page): """ creates the macro """ from MoinMoin import macro p = Parser("##\n", request) p.formatter = Formatter(request) p.formatter.page = page request.page = page request.formatter = p.formatter p.form = request.form m = macro.Macro(p) return m
def execute(pagename, request): _ = request.getText request.http_headers() # This action generate data using the user language request.setContentLanguage(request.lang) wikiutil.send_title(request, _('Local Site Map for "%s"') % (pagename), pagename=pagename) # Start content - IMPORTANT - witout content div, there is no # direction support! formatter = Formatter(request) request.write(formatter.startContent("content")) request.write(LocalSiteMap(pagename).output(request)) # End content request.write(formatter.endContent()) # end content div # Footer wikiutil.send_footer(request, pagename)
def formatMarkup(request, text, currentStack = []): """ Formats the text passed according to wiki markup. This raises an exception if a text needs itself to be translated, this could possibly happen with macros. """ try: currentStack.index(text) raise Exception("Formatting a text that is being formatted?!") except ValueError: pass currentStack.append(text) from MoinMoin.Page import Page from MoinMoin.parser.wiki import Parser from MoinMoin.formatter.text_html import Formatter import StringIO origtext = text out = StringIO.StringIO() request.redirect(out) parser = Parser(text, request) formatter = Formatter(request, terse = True) reqformatter = None if hasattr(request, 'formatter'): reqformatter = request.formatter request.formatter = formatter p = Page(request, "$$$$i18n$$$$") formatter.setPage(p) parser.format(formatter) text = out.getvalue() if reqformatter == None: del request.formatter else: request.formatter = reqformatter request.redirect() del currentStack[-1] text = text.strip() return text
def rendered (content): formatter = HtmlFormatter(request) formatter.setPage(request.page) request.page.formatter = formatter request.formatter = formatter parser = WikiParser(content, request, line_anchors=False) formatter.startContent('') output = request.redirectedOutput(parser.format, formatter) formatter.endContent('') return output
def __init__(self, request, static = [], formatter = None, **kw): if formatter: self.formatter = formatter else: from MoinMoin.formatter.text_html import Formatter self.formatter = Formatter(request, store_pagelinks=1) self.static = static self.code_fragments = [] self.__formatter = "formatter" self.__parser = "parser" self.request = request self.__lang = request.current_lang self.__in_p = 0 self.__in_pre = 0 self.text_cmd_begin = '\nrequest.write(' self.text_cmd_end = ')\n'
def show_result(pagename, request): _ = request.getText request.theme.send_title(_("Subscribed for %s:") % pagename, pagename=pagename) from MoinMoin.formatter.text_html import Formatter formatter = Formatter(request) usernames = request.form['users'].split(",") subscribe, unsubscribe = parse_userlist(usernames) result = subscribe_users(request, subscribe, unsubscribe, pagename, formatter) request.write(result) request.theme.send_footer(pagename) request.theme.send_closing_html()
def execute(pagename, request): _ = request.getText from MoinMoin.formatter.text_html import Formatter request.formatter = Formatter(request) request.emit_http_headers() # This action generate data using the user language request.setContentLanguage(request.lang) request.theme.send_title(_('Actions for %s') % pagename, pagename=pagename) # Start content - IMPORTANT - without content div, there is no # direction support! request.write(request.formatter.startContent("content")) # Just list the actions request.write(availableactions(request)) # End content and send footer request.write(request.formatter.endContent()) request.theme.send_footer(pagename)
def parse(self, body): """Parse body and return html Create a page with body, then parse it and format using html formatter """ request = self.request assert body is not None request.reset() page = Page(request, PAGENAME) page.hilite_re = None page.set_raw_body(body) formatter = HtmlFormatter(request) formatter.setPage(page) page.formatter = formatter request.formatter = formatter parser = WikiParser(body, request, line_anchors=False) formatter.startContent("") # needed for _include_stack init output = request.redirectedOutput(parser.format, formatter) formatter.endContent("") return output
def parse(self, body): """Parse body and return html Create a page with body, then parse it and format using html formatter """ request = self.request assert body is not None request.reset() page = Page(request, PAGENAME) page.hilite_re = None page.set_raw_body(body) formatter = HtmlFormatter(request) formatter.setPage(page) page.formatter = formatter request.formatter = formatter parser = WikiParser(body, request, line_anchors=False) formatter.startContent('') # needed for _include_stack init output = request.redirectedOutput(parser.format, formatter) formatter.endContent('') return output
+re:username_re: subscribes users who match <username_re> regex. -re:username_re: unsubscribes users who match <username_re> regex. URL is just needed for a farmconfig scenario. Example: %(myname)s FrontPage TestUser,MatthewSimpson """ % {"myname": os.path.basename(args[0])} raise SystemExit pagename = args[1] usernames = args[2].split(",") if len(args) > 3: request_url = args[3] else: request_url = None # Setup MoinMoin environment from MoinMoin.web.contexts import ScriptContext request = ScriptContext(url=request_url) from MoinMoin.formatter.text_plain import Formatter formatter = Formatter(request) subscribe, unsubscribe = parse_userlist(usernames) print subscribe_users(request, subscribe, unsubscribe, pagename, formatter)
class Formatter: """ Inserts '<<<>>>' into the page and adds python code to self.code_fragments for dynamic parts of the page (as macros, wikinames...). Static parts are formatted with an external formatter. Page must be assembled after the parsing to get working python code. """ def __init__(self, request, static = [], formatter = None, **kw): if formatter: self.formatter = formatter else: from MoinMoin.formatter.text_html import Formatter self.formatter = Formatter(request, store_pagelinks=1) self.static = static self.code_fragments = [] self.__formatter = "formatter" self.__parser = "parser" self.request = request self.__lang = request.current_lang self.__in_p = 0 self.__in_pre = 0 self.text_cmd_begin = '\nrequest.write(' self.text_cmd_end = ')\n' def assemble_code(self, text): """inserts the code into the generated text """ #text = text.replace('\\', '\\\\') #text = text.replace('"', '\\"') text = text.split('<<<>>>', len(self.code_fragments)) source = self.text_cmd_begin + repr(text[0]) i = 0 for t in text[1:]: source = (source + self.text_cmd_end + self.code_fragments[i] + self.text_cmd_begin + repr(text[i+1])) i = i + 1 source = source + self.text_cmd_end self.code_fragments = [] # clear code fragments to make # this object reusable # Automatic invalidation due to moin code changes: # we are called from Page.py, so moincode_timestamp is # mtime of MoinMoin directory. If we detect, that the # saved rendering code is older than the MoinMoin directory # we invalidate it by raising an exception. This avoids # calling functions that have changed by a code update. # Hint: we don't check the mtime of the directories within # MoinMoin, so better do a touch if you only modified stuff # in a subdirectory. waspcode_timestamp = int(time.time()) source = """ moincode_timestamp = int(os.path.getmtime(os.path.dirname(__file__))) if moincode_timestamp > %d: raise "CacheNeedsUpdate" %s """ % (waspcode_timestamp, source) return source def __getattr__(self, name): """ For every thing we have no method/attribute use the formatter """ return getattr(self.formatter, name) def __insert_code(self, call): """ returns the python code """ self.code_fragments.append(call) return '<<<>>>' def __is_static(self, dependencies): for dep in dependencies: if dep not in self.static: return False return True def __adjust_languge_state(self): """ Add current language state changing code to the cache """ if self.__lang != self.request.current_lang: self.__lang = self.request.current_lang return 'request.current_lang = %r\n' % self.__lang return '' def __adjust_formatter_state(self): result = self.__adjust_languge_state() if self.__in_p != self.formatter.in_p: result = "%s%s.in_p = %r\n" % (result, self.__formatter, self.formatter.in_p) self.__in_p = self.formatter.in_p if self.__in_pre != self.formatter.in_pre: result = "%s%s.in_pre = %r\n" % (result, self.__formatter, self.formatter.in_pre) self.__in_pre = self.formatter.in_pre return result def dynamic_content(self, parser, callback, arg_list = [], arg_dict = {}, returns_content = 1): adjust = self.__adjust_formatter_state() if returns_content: return self.__insert_code('%srequest.write(%s.%s(*%r,**%r))' % (adjust, self.__parser, callback, arg_list, arg_dict)) else: return self.__insert_code('%s%s.%s(*%r,**%r)' % (adjust, self.__parser, callback, arg_list, arg_dict)) # Public methods --------------------------------------------------- def pagelink(self, on, pagename='', page=None, **kw): if on: return self.__insert_code('page=Page(request, %r, formatter=%s);' 'request.write(%s.pagelink(%r, page=page, **%r))' % (pagename, self.__formatter, self.__formatter, on, kw)) else: return self.__insert_code('request.write(%s.pagelink(%r, page=page, **%r))' % (self.__formatter, on, kw)) def attachment_link(self, on, url='', **kw): return self.__insert_code( 'request.write(%s.attachment_link(%r, %r, **%r))' % (self.__formatter, on, url, kw)) def attachment_image(self, url, **kw): return self.__insert_code( 'request.write(%s.attachment_image(%r, **%r))' % (self.__formatter, url, kw)) def attachment_drawing(self, url, **kw): return self.__insert_code( 'request.write(%s.attachment_drawing(%r, **%r))' % (self.__formatter, url, kw)) def attachment_inlined(self, url, **kw): return self.__insert_code( 'request.write(%s.attachment_inlined(%r, **%r))' % (self.__formatter, url, kw)) def heading(self, on, depth, **kw): if on: code = [ self.__adjust_languge_state(), 'request.write(%s.heading(%r, %r, **%r))' % (self.__formatter, on, depth, kw), ] return self.__insert_code(''.join(code)) else: return self.formatter.heading(on, depth, **kw) def icon(self, type): if self.__is_static(['user']): return self.formatter.icon(type) else: return self.__insert_code('request.write(%s.icon(%r))' % (self.__formatter, type)) def macro(self, macro_obj, name, args): if self.__is_static(macro_obj.get_dependencies(name)): return macro_obj.execute(name, args) else: return self.__insert_code( '%srequest.write(%s.macro(macro_obj, %r, %r))' % (self.__adjust_formatter_state(), self.__formatter, name, args)) def processor(self, processor_name, lines, is_parser = 0): """ processor_name MUST be valid! prints out the result insted of returning it! """ if not is_parser: Dependencies = wikiutil.importPlugin(self.request.cfg, "processor", processor_name, "Dependencies") else: Dependencies = wikiutil.importPlugin(self.request.cfg, "parser", processor_name, "Dependencies") if Dependencies == None: Dependencies = ["time"] if self.__is_static(Dependencies): return self.formatter.processor(processor_name, lines, is_parser) else: return self.__insert_code('%s%s.processor(%r, %r, %r)' % (self.__adjust_formatter_state(), self.__formatter, processor_name, lines, is_parser))
class Formatter: """ Inserts '<<<>>>' into the page and adds python code to self.code_fragments for dynamic parts of the page (as macros, wikinames...). Static parts are formatted with an external formatter. Page must be assembled after the parsing to get working python code. """ defaultDependencies = ["time"] def __init__(self, request, static=[], formatter=None, **kw): if formatter: self.formatter = formatter else: from MoinMoin.formatter.text_html import Formatter self.formatter = Formatter(request, store_pagelinks=1) self.static = static self.code_fragments = [] self.__formatter = "formatter" self.__parser = "parser" self.request = request self.__lang = request.current_lang self.__in_p = 0 self.__in_pre = 0 self.text_cmd_begin = '\nrequest.write(' self.text_cmd_end = ')\n' def assemble_code(self, text): """inserts the code into the generated text """ # Automatic invalidation due to moin code changes: # we are called from Page.py, so moincode_timestamp is # mtime of MoinMoin directory. If we detect, that the # saved rendering code is older than the MoinMoin directory # we invalidate it by raising an exception. This avoids # calling functions that have changed by a code update. # Hint: we don't check the mtime of the directories within # MoinMoin, so better do a touch if you only modified stuff # in a subdirectory. waspcode_timestamp = int(time.time()) source = [""" moincode_timestamp = int(os.path.getmtime(os.path.dirname(__file__))) cfg_mtime = getattr(request.cfg, "cfg_mtime", None) if moincode_timestamp > %d or cfg_mtime is None or cfg_mtime > %d: raise Exception("CacheNeedsUpdate") """ % (waspcode_timestamp, waspcode_timestamp)] text = text.split('<<<>>>', len(self.code_fragments)) source.extend([self.text_cmd_begin, repr(text[0])]) i = 0 for t in text[1:]: source.extend([self.text_cmd_end, self.code_fragments[i], self.text_cmd_begin, repr(text[i+1])]) i += 1 source.append(self.text_cmd_end) source.append(self.__adjust_formatter_state()) self.code_fragments = [] # clear code fragments to make # this object reusable return "".join(source) def __cache_if_no_id(self, name, *args, **kw): if not 'id' in kw: return getattr(self.formatter, name)(*args, **kw) else: return self.__insert_code('request.write(%s.%s(*%r, **%r))' % (self.__formatter, name, args, kw)) def __getattr__(self, name): """ For every thing we have no method/attribute use the formatter unless there's an ID in the keywords. """ attr = getattr(self.formatter, name) if callable(attr): return lambda *args, **kw: self.__cache_if_no_id(name, *args, **kw) else: return attr def __insert_code(self, call): """ returns the python code """ self.code_fragments.append(call) return '<<<>>>' def __insert_fmt_call(self, function, *args, **kw): return self.__insert_code('request.write(%s.%s(*%r, **%r))' % ( self.__formatter, function, args, kw)) def __is_static(self, dependencies): for dep in dependencies: if dep not in self.static: return False return True def __adjust_language_state(self): """ Add current language state changing code to the cache """ if self.__lang != self.request.current_lang: self.__lang = self.request.current_lang return 'request.current_lang = %r\n' % self.__lang return '' def __adjust_formatter_state(self): result = self.__adjust_language_state() if self.__in_p != self.formatter.in_p: result = "%s%s.in_p = %r\n" % (result, self.__formatter, self.formatter.in_p) self.__in_p = self.formatter.in_p if self.__in_pre != self.formatter.in_pre: result = "%s%s.in_pre = %r\n" % (result, self.__formatter, self.formatter.in_pre) self.__in_pre = self.formatter.in_pre return result # Public methods --------------------------------------------------- def pagelink(self, on, pagename='', page=None, **kw): if on: return self.__insert_code('page=Page(request, %r, formatter=%s);' 'request.write(%s.pagelink(%r, page=page, **%r))' % (pagename, self.__formatter, self.__formatter, on, kw)) else: return self.__insert_code('request.write(%s.pagelink(%r, page=page, **%r))' % (self.__formatter, on, kw)) def attachment_link(self, on, url=None, **kw): return self.__insert_fmt_call('attachment_link', on, url, **kw) def attachment_image(self, url, **kw): return self.__insert_fmt_call('attachment_image', url, **kw) def attachment_drawing(self, url, text, **kw): return self.__insert_fmt_call('attachment_drawing', url, text, **kw) def attachment_inlined(self, url, text, **kw): return self.__insert_fmt_call('attachment_inlined', url, text, **kw) def heading(self, on, depth, **kw): if on: code = [ self.__adjust_language_state(), 'request.write(%s.heading(%r, %r, **%r))' % (self.__formatter, on, depth, kw), ] return self.__insert_code(''.join(code)) else: return self.formatter.heading(on, depth, **kw) def icon(self, type): if self.__is_static(['user']): return self.formatter.icon(type) else: return self.__insert_fmt_call('icon', type) smiley = icon def span(self, on, **kw): if on and 'comment' in kw.get('css_class', '').split(): return self.__insert_fmt_call('span', on, **kw) else: return self.formatter.span(on, **kw) def div(self, on, **kw): if on and 'comment' in kw.get('css_class', '').split(): return self.__insert_fmt_call('div', on, **kw) else: return self.formatter.div(on, **kw) def macro(self, macro_obj, name, args, markup=None): if self.__is_static(macro_obj.get_dependencies(name)): # XXX: why is this necessary?? macro_obj.formatter = self return macro_obj.execute(name, args) else: return self.__insert_code( '%srequest.write(%s.macro(macro_obj, %r, %r, %r))' % (self.__adjust_formatter_state(), self.__formatter, name, args, markup)) def parser(self, parser_name, lines): """ parser_name MUST be valid! prints out the result instead of returning it! """ try: Dependencies = wikiutil.searchAndImportPlugin(self.request.cfg, "parser", parser_name, "Dependencies") except (wikiutil.PluginMissingError, wikiutil.PluginAttributeError): Dependencies = self.defaultDependencies if self.__is_static(Dependencies): return self.formatter.parser(parser_name, lines) else: return self.__insert_code('%s%s.parser(%r, %r)' % (self.__adjust_formatter_state(), self.__formatter, parser_name, lines)) def startContent(self, content_id='content', newline=True, **kw): # we need to tell the request about the start of the content return self.__insert_fmt_call('startContent', content_id, newline, **kw) def endContent(self, newline=True): # we need to tell the request about the end of the content return self.__insert_fmt_call('endContent', newline) def anchorlink(self, on, name='', **kw): # anchorlink depends on state now, namely the include ID in the request. if on: return self.__insert_fmt_call('anchorlink', on, name, **kw) else: return self.formatter.anchorlink(on, name=name, **kw) def line_anchorlink(self, on, lineno=0): # anchorlink depends on state now, namely the include ID in the request. if on: return self.__insert_fmt_call('line_anchorlink', on, lineno) else: return self.formatter.line_anchorlink(on, lineno) def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1): if on: # update state of the HTML formatter self.formatter._in_code_area = 1 self.formatter._in_code_line = 0 self.formatter._code_area_state = [None, show, start, step, start] return self.__insert_fmt_call('code_area', on, code_id, code_type, show, start, step) else: return self.formatter.code_area(False, code_id, code_type, show, start, step) def line_anchordef(self, lineno): return self.__insert_fmt_call('line_anchordef', lineno) def anchordef(self, id): return self.__insert_fmt_call('anchordef', id)
def execute(pagename, request, fieldname='value', titlesearch=0): _ = request.getText titlesearch = isTitleSearch(request) # context is relevant only for full search if titlesearch: context = 0 else: context = int(request.form.get('context', [0])[0]) # Get other form parameters needle = request.form.get(fieldname, [''])[0] case = int(request.form.get('case', [0])[0]) regex = int(request.form.get('regex', [0])[0]) # no interface currently max_context = 1 # only show first `max_context` contexts XXX still unused # check for sensible search term striped = needle.strip() if len(striped) == 0: err = _('Please use a more selective search term instead ' 'of {{{"%s"}}}') % needle # send http headers request.http_headers() Page(request, pagename).send_page(request, msg=err) return # search the pages from MoinMoin import search query = search.QueryParser(case=case, regex=regex, titlesearch=titlesearch).parse_query(needle) results = search.searchPages(request, query) # directly show a single hit # XXX won't work with attachment search # improve if we have one... if len(results.hits) == 1: page = Page(request, results.hits[0].page_name) # TODO: remove escape=0 in 1.4 url = page.url(request, querystr={'highlight': query.highlight_re()}, escape=0) request.http_redirect(url) raise MoinMoinNoFooter # send http headers request.http_headers() # This action generate data using the user language request.setContentLanguage(request.lang) # Setup for type of search if titlesearch: title = _('Title Search: "%s"') results.sortByPagename() else: title = _('Full Text Search: "%s"') results.sortByWeight() wikiutil.send_title(request, title % needle, form=request.form, pagename=pagename) # Start content (important for RTL support) formatter = Formatter(request) request.write(formatter.startContent("content")) # First search stats request.write(results.stats(request, formatter)) # Then search results info = not titlesearch if context: output = results.pageListWithContext(request, formatter, info=info, context=context) else: output = results.pageList(request, formatter, info=info) request.write(output) # End content and send footer request.write(formatter.endContent()) wikiutil.send_footer(request, pagename, editable=0, showactions=0, form=request.form)
def execute(pagename, request): _ = request.getText # Start content - IMPORTANT - without content div, there is no # direction support! if not hasattr(request, 'formatter'): formatter = HtmlFormatter(request) else: formatter = request.formatter request.page.formatter = formatter formatter.setPage(request.page) # This action generate data using the user language request.setContentLanguage(request.lang) request.theme.send_title(request.getText('Search by metadata'), pagename=pagename) request.write(formatter.startContent("content")) q = '' mtabq = '' if request.values.has_key('q'): if request.values.has_key('mtab'): mtabq = ''.join(request.values.getlist('q')) else: q = ''.join(request.values.getlist('q')) request.write(u'<form method="GET" action="%s">\n' % actionname(request, pagename)) request.write(u'<input type=hidden name=action value="%s">' % 'MetaSearch') request.write(u'<input type="text" name="q" size=50 value="%s"> ' % (form_escape(q))) request.write(u'<input type="submit" name="mtab" value="Search as MetaTable">') request.write(u'<input type="submit" value="' + _('Search') + '">' + u'\n</form>\n') if q: if regexp_re.match(q): try: page_re = re.compile(q[1:-1]) q = '' except re.error: request.write(render_error(_("Bad regexp!"))) graphdata = request.graphdata graphdata.reverse_meta() keys_on_pages = graphdata.keys_on_pages vals_on_pages = graphdata.vals_on_pages keyhits = set([]) keys = set([]) for key in keys_on_pages: if q: if key == q: keyhits.update(keys_on_pages[key]) keys.add(key) else: if page_re.match(key): keyhits.update(keys_on_pages[key]) keys.add(key) valhits = set([]) vals = set([]) for val in vals_on_pages: if q: if val == q: valhits.update(vals_on_pages[val]) vals.add(val) else: if page_re.match(val): valhits.update(vals_on_pages[val]) vals.add(val) if not q: elemlist(request, formatter, keys, _('keys')) elemlist(request, formatter, vals, _('values')) request.write(formatter.paragraph(1)) request.write(formatter.text(_("Found as key in following pages"))) request.write(formatter.paragraph(0)) request.write(formatter.bullet_list(1)) for page in sorted(keyhits): # Do not include revisions etc so far, enabling this as per request if not graphdata[page].has_key(u'saved'): continue request.write(formatter.listitem(1)) request.write(formatter.pagelink(1, page)) request.write(formatter.text(page)) request.write(formatter.pagelink(0)) request.write(formatter.listitem(0)) request.write(formatter.bullet_list(0)) request.write(formatter.paragraph(1)) request.write(formatter.text(_("Found as value in following pages"))) request.write(formatter.paragraph(0)) request.write(formatter.bullet_list(1)) for page in sorted(valhits): # Do not include revisions etc so far, enabling this as per request if not graphdata[page].has_key(u'saved'): continue request.write(formatter.listitem(1)) request.write(formatter.pagelink(1, page)) request.write(formatter.text(page)) request.write(formatter.pagelink(0)) request.write(formatter.listitem(0)) request.write(formatter.bullet_list(0)) if mtabq: metatab = wikiutil.importPlugin(request.cfg, 'macro', 'MetaTable') request.write("<br>") # Poor but sufficient emulation of macro object mtabHTML = metatab(request.page, mtabq) request.write(mtabHTML) # End content request.write(formatter.endContent()) # end content div # Footer request.theme.send_footer(pagename) request.theme.send_closing_html()
class Formatter: """ Inserts '<<<>>>' into the page and adds python code to self.code_fragments for dynamic parts of the page (as macros, wikinames...). Static parts are formatted with an external formatter. Page must be assembled after the parsing to get working python code. """ defaultDependencies = ["time"] def __init__(self, request, static=[], formatter=None, **kw): if formatter: self.formatter = formatter else: from MoinMoin.formatter.text_html import Formatter self.formatter = Formatter(request, store_pagelinks=1) self.static = static self.code_fragments = [] self.__formatter = "formatter" self.__parser = "parser" self.request = request self.__lang = request.current_lang self.__in_p = 0 self.__in_pre = 0 self.text_cmd_begin = '\nrequest.write(' self.text_cmd_end = ')\n' def assemble_code(self, text): """inserts the code into the generated text """ # Automatic invalidation due to moin code changes: # we are called from Page.py, so moincode_timestamp is # mtime of MoinMoin directory. If we detect, that the # saved rendering code is older than the MoinMoin directory # we invalidate it by raising an exception. This avoids # calling functions that have changed by a code update. # Hint: we don't check the mtime of the directories within # MoinMoin, so better do a touch if you only modified stuff # in a subdirectory. waspcode_timestamp = int(time.time()) source = [""" moincode_timestamp = int(os.path.getmtime(os.path.dirname(__file__))) cfg_mtime = getattr(request.cfg, "cfg_mtime", None) if moincode_timestamp > %d or cfg_mtime is None or cfg_mtime > %d: raise Exception("CacheNeedsUpdate") """ % (waspcode_timestamp, waspcode_timestamp)] text = text.split('<<<>>>', len(self.code_fragments)) source.extend([self.text_cmd_begin, repr(text[0])]) i = 0 for t in text[1:]: source.extend([self.text_cmd_end, self.code_fragments[i], self.text_cmd_begin, repr(text[i+1])]) i += 1 source.append(self.text_cmd_end) source.append(self.__adjust_formatter_state()) self.code_fragments = [] # clear code fragments to make # this object reusable return "".join(source) def __cache_if_no_id(self, name, *args, **kw): if not 'id' in kw: return getattr(self.formatter, name)(*args, **kw) else: return self.__insert_code('request.write(%s.%s(*%r, **%r))' % (self.__formatter, name, args, kw)) def __getattr__(self, name): """ For every thing we have no method/attribute use the formatter unless there's an ID in the keywords. """ attr = getattr(self.formatter, name) if callable(attr): return lambda *args, **kw: self.__cache_if_no_id(name, *args, **kw) else: return attr def __insert_code(self, call): """ returns the python code """ self.code_fragments.append(call) return '<<<>>>' def __insert_fmt_call(self, function, *args, **kw): return self.__insert_code('request.write(%s.%s(*%r, **%r))' % ( self.__formatter, function, args, kw)) def __is_static(self, dependencies): for dep in dependencies: if dep not in self.static: return False return True def __adjust_language_state(self): """ Add current language state changing code to the cache """ if self.__lang != self.request.current_lang: self.__lang = self.request.current_lang return 'request.current_lang = %r\n' % self.__lang return '' def __adjust_formatter_state(self): result = self.__adjust_language_state() if self.__in_p != self.formatter.in_p: result = "%s%s.in_p = %r\n" % (result, self.__formatter, self.formatter.in_p) self.__in_p = self.formatter.in_p if self.__in_pre != self.formatter.in_pre: result = "%s%s.in_pre = %r\n" % (result, self.__formatter, self.formatter.in_pre) self.__in_pre = self.formatter.in_pre return result # Public methods --------------------------------------------------- def pagelink(self, on, pagename='', page=None, **kw): if on: return self.__insert_code('page=Page(request, %r, formatter=%s);' 'request.write(%s.pagelink(%r, page=page, **%r))' % (pagename, self.__formatter, self.__formatter, on, kw)) else: return self.__insert_code('request.write(%s.pagelink(%r, page=page, **%r))' % (self.__formatter, on, kw)) def attachment_link(self, on, url=None, **kw): return self.__insert_fmt_call('attachment_link', on, url, **kw) def attachment_image(self, url, **kw): return self.__insert_fmt_call('attachment_image', url, **kw) def attachment_drawing(self, url, text, **kw): return self.__insert_fmt_call('attachment_drawing', url, text, **kw) def attachment_inlined(self, url, text, **kw): return self.__insert_fmt_call('attachment_inlined', url, text, **kw) def heading(self, on, depth, **kw): if on: code = [ self.__adjust_language_state(), 'request.write(%s.heading(%r, %r, **%r))' % (self.__formatter, on, depth, kw), ] return self.__insert_code(''.join(code)) else: return self.formatter.heading(on, depth, **kw) def icon(self, type): if self.__is_static(['user']): return self.formatter.icon(type) else: return self.__insert_fmt_call('icon', type) smiley = icon def span(self, on, **kw): if on and 'comment' in kw.get('css_class', '').split(): return self.__insert_fmt_call('span', on, **kw) else: return self.formatter.span(on, **kw) def div(self, on, **kw): if on and 'comment' in kw.get('css_class', '').split(): return self.__insert_fmt_call('div', on, **kw) else: return self.formatter.div(on, **kw) def macro(self, macro_obj, name, args, markup=None): if self.__is_static(macro_obj.get_dependencies(name)): # XXX: why is this necessary?? macro_obj.formatter = self return macro_obj.execute(name, args) else: return self.__insert_code( '%srequest.write(%s.macro(macro_obj, %r, %r, %r))' % (self.__adjust_formatter_state(), self.__formatter, name, args, markup)) def parser(self, parser_name, lines): """ parser_name MUST be valid! prints out the result instead of returning it! """ try: Dependencies = wikiutil.searchAndImportPlugin(self.request.cfg, "parser", parser_name, "Dependencies") except (wikiutil.PluginMissingError, wikiutil.PluginAttributeError): Dependencies = self.defaultDependencies if self.__is_static(Dependencies): return self.formatter.parser(parser_name, lines) else: return self.__insert_code('%s%s.parser(%r, %r)' % (self.__adjust_formatter_state(), self.__formatter, parser_name, lines)) def startContent(self, content_id='content', newline=True, **kw): # we need to tell the request about the start of the content return self.__insert_fmt_call('startContent', content_id, newline, **kw) def endContent(self, newline=True): # we need to tell the request about the end of the content return self.__insert_fmt_call('endContent', newline) def anchorlink(self, on, name='', **kw): # anchorlink depends on state now, namely the include ID in the request. if on: return self.__insert_fmt_call('anchorlink', on, name, **kw) else: return self.formatter.anchorlink(on, name=name, **kw) def line_anchorlink(self, on, lineno=0): # anchorlink depends on state now, namely the include ID in the request. if on: return self.__insert_fmt_call('line_anchorlink', on, lineno) else: return self.formatter.line_anchorlink(on, lineno) def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1, msg=None): if on: # update state of the HTML formatter self.formatter._in_code_area = 1 self.formatter._in_code_line = 0 self.formatter._code_area_state = [None, show, start, step, start] return self.__insert_fmt_call('code_area', on, code_id, code_type, show, start, step) else: return self.formatter.code_area(False, code_id, code_type, show, start, step) def line_anchordef(self, lineno): return self.__insert_fmt_call('line_anchordef', lineno) def anchordef(self, id): return self.__insert_fmt_call('anchordef', id)
def execute(pagename, request): from MoinMoin import wikiutil from MoinMoin.Page import Page _ = request.getText thispage = Page(request, pagename) if request.user.valid: username = request.user.name else: username = '' if not username: return thispage.send_page(request, msg = _('Please log in first.')) userhomewiki = request.cfg.user_homewiki if userhomewiki != 'Self' and userhomewiki != request.cfg.interwikiname: interwiki = wikiutil.getInterwikiHomePage(request, username=username) wikitag, wikiurl, wikitail, wikitag_bad = wikiutil.resolve_wiki(request, '%s:%s' % interwiki) wikiurl = wikiutil.mapURL(request, wikiurl) homepageurl = wikiutil.join_wiki(wikiurl, wikitail) request.http_redirect('%s?action=MyPages' % homepageurl) homepage = Page(request, username) if not homepage.exists(): return homepage.send_page(request, msg = _('Please first create a homepage before creating additional pages.')) pagecontent = _("""\ You can add some additional sub pages to your already existing homepage here. You can choose how open to other readers or writers those pages shall be, access is controlled by group membership of the corresponding group page. Just enter the sub page's name and click on the button to create a new page. Before creating access protected pages, make sure the corresponding group page exists and has the appropriate members in it. Use HomepageGroupsTemplate for creating the group pages. ||'''Add a new personal page:'''||'''Related access control list group:'''|| ||[[NewPage(HomepageReadWritePageTemplate,read-write page,%(username)s)]]||["%(username)s/ReadWriteGroup"]|| ||[[NewPage(HomepageReadPageTemplate,read-only page,%(username)s)]]||["%(username)s/ReadGroup"]|| ||[[NewPage(HomepagePrivatePageTemplate,private page,%(username)s)]]||%(username)s only|| """, formatted=False) pagecontent = pagecontent % locals() pagecontent = pagecontent.replace('\n', '\r\n') from MoinMoin.Page import Page from MoinMoin.parser.wiki import Parser from MoinMoin.formatter.text_html import Formatter pagename = username request.http_headers() # This action generate data using the user language request.setContentLanguage(request.lang) wikiutil.send_title(request, _('MyPages management', formatted=False), pagename=pagename) # Start content - IMPORTANT - without content div, there is no # direction support! request.write(request.formatter.startContent("content")) parser = Parser(pagecontent, request) formatter = Formatter(request) reqformatter = None if hasattr(request, 'formatter'): reqformatter = request.formatter request.formatter = formatter p = Page(request, "$$$") formatter.setPage(p) parser.format(formatter) if reqformatter == None: del request.formatter else: request.formatter = reqformatter # End content and send footer request.write(request.formatter.endContent()) wikiutil.send_footer(request, pagename)
def __init__(self, request, **kw): self._in_mailto = False Formatter.__init__(self, request, **kw)
def _open(self, tag, newline=False, attr=None, allowed_attrs=None, **kw): """ Escape % characters in tags, see also text_html.Formatter._open. """ tagstr = TextHtmlFormatter._open(self, tag, newline, attr, allowed_attrs, **kw) return tagstr.replace('%', '%%')
def text(self, text, **kw): if self._in_mailto: text = text.replace('@', ' at ') text = text.replace('.', ' dot ') return Formatter.text(self, text, css = 'email', **kw) return Formatter.text(self, text, **kw)
def _open(self, tag, newline=False, attr=None, allowed_attrs=None, **kw): """ Escape % characters in tags, see also text_html.Formatter._open. """ tagstr = TextHtmlFormatter._open(self, tag, newline, attr, allowed_attrs, **kw) return tagstr.replace("%", "%%")