def inline_link_repl(self, stack, link, link_url=None, link_item=None, link_text=None, link_interwiki_site=None, link_interwiki_item=None): """Handle all kinds of links.""" if link_interwiki_site: if is_known_wiki(link_interwiki_site): link = Iri(scheme='wiki', authority=link_interwiki_site, path='/' + link_interwiki_item) element = moin_page.a(attrib={xlink.href: link}) stack.push(element) if link_text: self.parse_inline(link_text, stack, self.inlinedesc_re) else: stack.top_append(link_interwiki_item) stack.pop() return else: # assume local language uses ":" inside of words, set link_item and continue link_item = '{0}:{1}'.format(link_interwiki_site, link_interwiki_item) if link_item is not None: att = 'attachment:' # moin 1.9 needed this for an attached file if link_item.startswith(att): link_item = '/' + link_item[len(att):] # now we have a subitem target = unicode(Iri(scheme='wiki.local', path=link_item)) text = link_item else: target = link_url text = link_url element = moin_page.a(attrib={xlink.href: target}) stack.push(element) if link_text: self.parse_inline(link_text, stack, self.inlinedesc_re) else: stack.top_append(text) stack.pop()
def traverse_tree(self, elem, page=None, __tag_page_href=moin_page.page_href, __tag_link=_tag_xlink_href, __tag_include=_tag_xinclude_href): """ Traverses the tree and handles each element appropriately """ new_page_href = elem.get(__tag_page_href) if new_page_href: page = Iri(new_page_href) xlink_href = elem.get(__tag_link) xinclude_href = elem.get(__tag_include) if xlink_href: xlink_href = Iri(xlink_href) if xlink_href.scheme == 'wiki.local': self.handle_wikilocal_links(elem, xlink_href, page) elif xlink_href.scheme == 'wiki': self.handle_wiki_links(elem, xlink_href) elif xlink_href.scheme: self.handle_external_links(elem, xlink_href) elif xinclude_href: xinclude_href = Iri(xinclude_href) if xinclude_href.scheme == 'wiki.local': self.handle_wikilocal_transclusions(elem, xinclude_href, page) elif xinclude_href.scheme == 'wiki': self.handle_wiki_transclusions(elem, xinclude_href) for child in elem.iter_elements(): self.traverse_tree(child, page) return elem
def inline_object_repl(self, stack, object, object_url=None, object_item=None, object_text=None, object_args=None): """Handles objects transcluded within the page.""" if object_args: args = parse_arguments(object_args).keyword # XXX needs different parsing else: args = {} query_keys = {} attrib = {} whitelist = ['width', 'height', 'class'] for attr, value in args.iteritems(): if attr.startswith('&'): query_keys[attr[1:]] = value elif attr in whitelist: attrib[html(attr)] = value if object_text: attrib[html.alt] = object_text if object_item is not None: # img tag query = url_encode(query_keys, charset=CHARSET, encode_keys=True) # TODO: moin 1.9 needed this for an attached file; move functionality to script/migration/moin/import19.py att = 'attachment:' if object_item.startswith(att): object_item = '/' + object_item[len(att):] # now we have a subitem target = Iri(scheme='wiki.local', path=object_item, query=query, fragment=None) attrib[xinclude.href] = target element = xinclude.include(attrib=attrib) stack.top_append(element) else: # object tag target = Iri(object_url) attrib[xlink.href] = target element = moin_page.object(attrib) stack.top_append(element)
def visit_reference(self, node): refuri = node.get('refuri', u'') if refuri.startswith(u'<<') and refuri.endswith(u'>>'): # moin macro macro_name = refuri[2:-2].split(u'(')[0] if macro_name == u"TableOfContents": arguments = refuri[2:-2].split(u'(')[1][:-1].split(u',') node = moin_page.table_of_content() self.open_moin_page_node(node) if arguments and arguments[0]: node.set(moin_page.outline_level, arguments[0]) return if macro_name == u"Include": # include macros are expanded by include.py similar to transclusions # rst include handles only wiki pages and does not support additional arguments like moinwiki arguments = refuri[2:-2].split(u'(')[1][:-1].split(u',') link = Iri(scheme=u'wiki.local', path=arguments) node = xinclude.include( attrib={ xinclude.href: link, moin_page.alt: refuri, moin_page.content_type: 'x-moin/macro;name=' + macro_name, }) self.open_moin_page_node(node) return try: arguments = refuri[2:-2].split(u'(')[1][:-1] except IndexError: arguments = u'' # <<DateTime>> self.open_moin_page_node( moin_page.inline_part( attrib={ moin_page.content_type: "x-moin/macro;name={0}".format(macro_name) })) if arguments: self.open_moin_page_node(moin_page.arguments()) self.open_moin_page_node(arguments) self.close_moin_page_node() self.close_moin_page_node() return if not allowed_uri_scheme(refuri): self.visit_error(node) return if refuri == u'': # build a link to a heading or an explicitly defined anchor refuri = Iri(scheme='wiki.local', fragment=node.attributes['name'].replace(' ', '_')) self.open_moin_page_node(moin_page.a(attrib={xlink.href: refuri}))
def visit_image(self, node): """ Processes images and other transcluded objects. """ whitelist = [ 'width', 'height', 'alt', ] attrib = {} for key in whitelist: if node.get(key): attrib[html(key)] = node.get(key) # there is no 'scale' attribute, hence absent from whitelist, handled separately if node.get('scale'): scaling_factor = int(node.get('scale')) / 100.0 for key in ('width', 'height'): if html(key) in attrib: attrib[html(key)] = int( int(attrib[html(key)]) * scaling_factor) # "align" parameter is invalid in HTML5. Convert it to a class defined in userstyles.css. userstyles = { 'left': 'left', 'center': 'center', 'right': 'right', 'top': 'top', # rst parser creates error messages for top, bottom, and middle 'bottom': 'bottom', 'middle': 'middle', } alignment = userstyles.get(node.get('align')) if alignment: attrib[html.class_] = alignment url = Iri(node['uri']) if url.scheme is None: # img target = Iri(scheme='wiki.local', path=node['uri'], fragment=None) attrib[xinclude.href] = target new_node = xinclude.include(attrib=attrib) else: # obj new_node = moin_page.object(attrib) new_node.set(xlink.href, url) self.open_moin_page_node(new_node)
def inline_link_repl(self, stack, link, link_url=None, link_item=None, link_text=None, link_args=None, link_interwiki_site=None, link_interwiki_item=None): """Handle all kinds of links.""" if link_interwiki_site: if is_known_wiki(link_interwiki_site): link = Iri(scheme='wiki', authority=link_interwiki_site, path='/' + link_interwiki_item) element = moin_page.a(attrib={xlink.href: link}) stack.push(element) if link_text: self.parse_inline(link_text, stack, self.inlinedesc_re) else: stack.top_append(link_interwiki_item) stack.pop() return else: # assume local language uses ":" inside of words, set link_item and continue link_item = '{0}:{1}'.format(link_interwiki_site, link_interwiki_item) if link_args: link_args = parse_arguments(link_args) # XXX needs different parsing query = url_encode(link_args.keyword, charset=CHARSET, encode_keys=True) else: query = None if link_item is not None: att = 'attachment:' # moin 1.9 needed this for an attached file if link_item.startswith(att): link_item = '/' + link_item[len(att):] # now we have a subitem if '#' in link_item: path, fragment = link_item.rsplit('#', 1) if link_item.startswith('#') and '/+convert/' in request.url: # avoid traceback in link.py when converting moinwiki item to ReST | HTML | Docbook path = request.url.split('+convert/')[-1] else: path, fragment = link_item, None target = Iri(scheme='wiki.local', path=path, query=query, fragment=fragment) text = link_item else: target = Iri(link_url) text = link_url element = moin_page.a(attrib={xlink.href: target}) stack.push(element) if link_text: self.parse_inline(link_text, stack, self.inlinedesc_re) else: stack.top_append(text) stack.pop()
def __call__(self, rev, contenttype=None, arguments=None): item_name = rev.item.name query_keys = {'do': 'get', 'rev': rev.revid} attrib = {} if arguments: query = arguments.keyword.get(xinclude.href) if query and query.query: # query.query value is similar to "w=75" given a transclusion "{{jpeg||&w=75 class="top"}}" query_keys.update(url_decode(query.query)) attrib = arguments.keyword query = url_encode(query_keys, charset=CHARSET, encode_keys=True) attrib.update({ moin_page.type_: unicode(self.input_type), xlink.href: Iri(scheme='wiki', authority='', path='/' + item_name, query=query), }) obj = moin_page.object_(attrib=attrib, children=[ item_name, ]) body = moin_page.body(children=(obj, )) return moin_page.page(children=(body, ))
def inline_object_repl(self, stack, object, object_page=None, object_url=None, object_text=None): """Handles objects included in the page.""" if object_page is not None: att = 'attachment:' # moin 1.9 needed this for an attached file if object_page.startswith(att): object_page = '/' + object_page[len( att):] # now we have a subitem target = Iri(scheme='wiki.local', path=object_page) text = object_page attrib = {xinclude.href: target} element = xinclude.include(attrib=attrib) stack.top_append(element) else: target = object_url text = object_url element = moin_page.object({xlink.href: target}) stack.push(element) self.parse_inline(object_text or text, stack, self.link_desc_re) stack.pop()
def __call__(self, content): item_name = content # we just give the name of the item in the content attrib = { moin_page.type_: unicode(self.input_type), xlink.href: Iri(scheme='wiki', authority='', path='/'+item_name, query='do=get'), } return moin_page.object_(attrib=attrib, children=[item_name, ])
def inline_link_repl(self, stack, link, link_url=None, link_item=None, link_text=None, link_interwiki_site=None, link_interwiki_item=None): """Handle all kinds of links.""" if link_interwiki_site: if is_known_wiki(link_interwiki_site): link = Iri(scheme='wiki', authority=link_interwiki_site, path='/' + link_interwiki_item) element = moin_page.a(attrib={xlink.href: link}) stack.push(element) if link_text: self.parse_inline(link_text, stack, self.inlinedesc_re) else: stack.top_append(link_interwiki_item) stack.pop() return else: # assume local language uses ":" inside of words, set link_item and continue link_item = '{0}:{1}'.format(link_interwiki_site, link_interwiki_item) if link_item is not None: att = 'attachment:' # moin 1.9 needed this for an attached file if link_item.startswith(att): link_item = '/' + link_item[len(att):] # now we have a subitem # we have Anchor macro, so we support anchor links despite lack of docs in Creole spec if '#' in link_item: path, fragment = link_item.rsplit('#', 1) else: path, fragment = link_item, None target = Iri(scheme='wiki.local', path=path, fragment=fragment) text = link_item else: target = Iri(link_url) text = link_url element = moin_page.a(attrib={xlink.href: target}) stack.push(element) if link_text: self.parse_inline(link_text, stack, self.inlinedesc_re) else: stack.top_append(text) stack.pop()
def __call__(self, rev, contenttype=None, arguments=None): item_name = rev.item.fqname.value attrib = { xlink.href: Iri(scheme='wiki', authority='', path='/' + item_name, query='do=modify'), } a = moin_page.a(attrib=attrib, children=[_("%(item_name)s does not exist. Create it?", item_name=item_name)]) body = moin_page.body(children=(a, )) return moin_page.page(children=(body, ))
def visit_img(self, element): """ <img src="URI" /> --> <object xlink:href="URI /> """ attrib = {} url = Iri(element.attrib.get('src')) if element.attrib.get('alt'): attrib[html.alt] = element.attrib.get('alt') if url.scheme is None: # img tag target = Iri(scheme='wiki.local', path=element.attrib.get("src"), fragment=None) attrib[xinclude.href] = target new_node = xinclude.include(attrib=attrib) else: # object tag attrib[xlink.href] = url new_node = moin_page.object(attrib) return new_node
def inline_object_repl(self, stack, object, object_url=None, object_item=None, object_text=None, object_args=None): """Handles objects included in the page.""" if object_args: args = parse_arguments( object_args).keyword # XXX needs different parsing else: args = {} if object_item is not None: query = url_encode(args, charset=config.charset, encode_keys=True) att = 'attachment:' # moin 1.9 needed this for an attached file if object_item.startswith(att): object_item = '/' + object_item[len( att):] # now we have a subitem target = Iri(scheme='wiki.local', path=object_item, query=query, fragment=None) text = object_item attrib = {xinclude.href: target} element = xinclude.include(attrib=attrib) stack.top_append(element) else: target = Iri(object_url) text = object_url attrib = {xlink.href: target} if object_text is not None: attrib[moin_page.alt] = object_text element = moin_page.object(attrib) stack.push(element) if object_text: self.parse_inline(object_text, stack, self.inlinedesc_re) else: stack.top_append(text) stack.pop()
def inline_freelink_repl(self, stack, freelink, freelink_bang=None, freelink_interwiki_page=None, freelink_interwiki_ref=None, freelink_page=None, freelink_email=None): if freelink_bang: stack.top_append(freelink) return attrib = {} if freelink_page: page = freelink_page.encode('utf-8') if '#' in page: path, fragment = page.rsplit('#', 1) else: path, fragment = page, None link = Iri(scheme='wiki.local', path=path, fragment=fragment) text = freelink_page elif freelink_email: link = 'mailto:' + freelink_email text = freelink_email else: wikitag_bad = resolve_interwiki(freelink_interwiki_ref, freelink_interwiki_page)[3] if wikitag_bad: stack.top_append(freelink) return link = Iri(scheme='wiki', authority=freelink_interwiki_ref, path='/' + freelink_interwiki_page) text = freelink_interwiki_page attrib[xlink.href] = link element = moin_page.a(attrib, children=[text]) stack.top_append(element)
def process_name(self, member_name): attrib = { xlink.href: Iri(scheme='wiki', authority='', path='/' + self.item_name, query='do=get&member=%s' % member_name), } return moin_page.a(attrib=attrib, children=[ member_name, ])
def process_name(self, member_name): name = unicode(member_name, 'utf-8') attrib = { xlink.href: Iri(scheme='wiki', authority='', path='/' + self.item_name, query=u'do=get&member={0}'.format(name)), } return moin_page.a(attrib=attrib, children=[ name, ])
def inline_link_repl(self, stack, link, link_url=None, link_item=None, link_text=None, link_args=None): """Handle all kinds of links.""" if link_args: link_args = parse_arguments( link_args) # XXX needs different parsing query = url_encode(link_args.keyword, charset=config.charset, encode_keys=True) else: query = None if link_item is not None: att = 'attachment:' # moin 1.9 needed this for an attached file if link_item.startswith(att): link_item = '/' + link_item[len(att):] # now we have a subitem if '#' in link_item: path, fragment = link_item.rsplit('#', 1) else: path, fragment = link_item, None target = Iri(scheme='wiki.local', path=path, query=query, fragment=fragment) text = link_item else: target = Iri(link_url) text = link_url element = moin_page.a(attrib={xlink.href: target}) stack.push(element) if link_text: self.parse_inline(link_text, stack, self.inlinedesc_re) else: stack.top_append(text) stack.pop()
def __call__(self, rev, contenttype=None, arguments=None): item_name = rev.item.name attrib = { xlink.href: Iri(scheme='wiki', authority='', path='/' + item_name, query='do=get&rev={0}'.format(rev.revid)), } a = moin_page.a(attrib=attrib, children=[u"Download {0}.".format(item_name)]) body = moin_page.body(children=(a, )) return moin_page.page(children=(body, ))
def handle_wiki_links(self, elem, input): wiki_name = 'Self' if input.authority and input.authority.host: wn = unicode(input.authority.host) if is_known_wiki(wn): # interwiki link elem.set(moin_page.class_, 'moin-interwiki') wiki_name = wn item_name = unicode(input.path[1:]) endpoint, rev, query = self._get_do_rev(input.query) url = url_for_item(item_name, wiki_name=wiki_name, rev=rev, endpoint=endpoint) link = Iri(url, query=query, fragment=input.fragment) elem.set(self._tag_xlink_href, link)
def __call__(self, content): item_name = content # we just give the name of the item in the content attrib = { xlink.href: Iri(scheme='wiki', authority='', path='/' + item_name, query='do=modify'), } return moin_page.a(attrib=attrib, children=[ _("%(item_name)s does not exist. Create it?", item_name=item_name) ])
def handle_wikilocal_links(self, elem, input, page): if input.path: # this can be a relative path, make it absolute: path = input.path path = self.absolute_path(path, page.path) item_name = unicode(path) if not flaskg.storage.has_item(item_name): # XXX these index accesses slow down the link converter quite a bit elem.set(moin_page.class_, 'moin-nonexistent') else: item_name = unicode(page.path[1:]) endpoint, rev, query = self._get_do_rev(input.query) url = url_for_item(item_name, rev=rev, endpoint=endpoint) link = Iri(url, query=query, fragment=input.fragment) elem.set(self._tag_xlink_href, link)
def inline_object_repl(self, stack, object, object_page=None, object_url=None, object_text=None): """Handles objects included in the page.""" attrib = {} if object_text: attrib[html.alt] = object_text if object_page is not None: att = 'attachment:' # moin 1.9 needed this for an attached file if object_page.startswith(att): object_page = '/' + object_page[len(att):] # now we have a subitem target = Iri(scheme='wiki.local', path=object_page) attrib[xinclude.href] = target element = xinclude.include(attrib=attrib) else: attrib[xlink.href] = object_url element = moin_page.object(attrib) stack.top_append(element)
def __call__(self, content): item_name = content # we just give the name of the item in the content attrib = { moin_page.type_: unicode(self.input_type), xlink.href: Iri(scheme='wiki', authority='', path='/' + item_name, query='do=get'), } return moin_page.object_( attrib=attrib, children=[ u'Your Browser does not support HTML5 audio/video element.', ])
def internal_representation(self, attributes=None): """ Return the internal representation of a document using a DOM Tree """ hash_name = HASH_ALGORITHM hash_hexdigest = self.rev.meta.get(hash_name) if hash_hexdigest: cid = cache_key(usage="internal_representation", hash_name=hash_name, hash_hexdigest=hash_hexdigest) doc = app.cache.get(cid) else: # likely a non-existing item doc = cid = None if doc is None: # We will see if we can perform the conversion: # FROM_mimetype --> DOM # if so we perform the transformation, otherwise we don't from MoinMoin.converter import default_registry as reg input_conv = reg.get(Type(self.contenttype), type_moin_document) if not input_conv: raise TypeError( "We cannot handle the conversion from {0} to the DOM tree". format(self.contenttype)) smiley_conv = reg.get(type_moin_document, type_moin_document, icon='smiley') # We can process the conversion links = Iri(scheme='wiki', authority='', path='/' + self.name) doc = input_conv(self.rev, self.contenttype, arguments=attributes) # XXX is the following assuming that the top element of the doc tree # is a moin_page.page element? if yes, this is the wrong place to do that # as not every doc will have that element (e.g. for images, we just get # moin_page.object, for a tar item, we get a moin_page.table): doc.set(moin_page.page_href, unicode(links)) if self.contenttype.startswith(( u'text/x.moin.wiki', u'text/x-mediawiki', u'text/x.moin.creole', )): doc = smiley_conv(doc) if cid: app.cache.set(cid, doc) return doc
def __call__(self, rev, contenttype=None, arguments=None): item_name = rev.item.name attrib = { moin_page.type_: unicode(self.input_type), xlink.href: Iri(scheme='wiki', authority='', path='/' + item_name, query='do=get&rev={0}'.format(rev.revid)), } obj = moin_page.object_( attrib=attrib, children=[ u'Your Browser does not support HTML5 audio/video element.', ]) body = moin_page.body(children=(obj, )) return moin_page.page(children=(body, ))
def absolute_path(self, path, current_page_path): """ Converts a relative iri path into an absolute one :param path: the relative path to be converted :type path: Iri.path :param current_page_path: the path of the page where the link is :type current_page_path: Iri.path :returns: the absolute equivalent of the relative path :rtype: Iri.path """ quoted_path = path.quoted # starts from 1 because 0 is always / for the current page quoted_current_page_path = current_page_path[1:].quoted abs_path = AbsItemName(quoted_current_page_path, quoted_path) abs_path = Iri(abs_path).path return abs_path
def macro(self, content, arguments, page_url, alternative): request = self.request if arguments: item_count = int(arguments[0]) else: item_count = 1 rootitem = Item(request, u'') all_item_names = [i.name for i in rootitem.list_items()] # Now select random item from the full list, and if it exists and # we can read it, save. random_item_names = [] found = 0 while found < item_count and all_item_names: # Take one random item from the list item_name = random.choice(all_item_names) all_item_names.remove(item_name) # Filter out items the user may not read. try: item = Item.create(item_name) random_item_names.append(item_name) found += 1 except AccessDeniedError: pass if not random_item_names: return random_item_names.sort() result = moin_page.span() for name in random_item_names: link = unicode(Iri(scheme=u'wiki', authority=u'', path=u'/' + name)) result.append(moin_page.a(attrib={xlink.href: link}, children=[name])) result.append(", ") del result[-1] # kill last comma return result
def inline_link_repl(self, stack, link, link_url=None, link_page=None, link_text=None): """Handle all kinds of links.""" if link_page is not None: att = 'attachment:' # moin 1.9 needed this for an attached file if link_page.startswith(att): link_page = '/' + link_page[len(att):] # now we have a subitem target = unicode(Iri(scheme='wiki.local', path=link_page)) text = link_page else: target = link_url text = link_url element = moin_page.a(attrib={xlink.href: target}) stack.push(element) self.parse_inline(link_text or text, stack, self.link_desc_re) stack.pop()
def inline_url_repl(self, stack, url, url_target): url = Iri(url_target) attrib = {xlink.href: url} element = moin_page.a(attrib=attrib, children=[url_target]) stack.top_append(element)
def inline_link_repl(self, stack, link, link_url=None, link_item=None, link_args=u'', external_link_url=None, alt_text=u''): """Handle all kinds of links.""" link_text = '' link_args_list = [] # Remove the first pipe/space, example of link_args : |arg1|arg2 or " arg1 arg2" parsed_args = self.parse_args(link_args[1:]) query = None if parsed_args.keyword: query = url_encode(parsed_args.keyword, charset=CHARSET, encode_keys=True) # Take the last of positional parameters as link_text(caption) if parsed_args.positional: link_text = parsed_args.positional.pop() if link_item is not None: if '#' in link_item: path, fragment = link_item.rsplit('#', 1) else: path, fragment = link_item, None target = Iri(scheme='wiki.local', path=path, query=query, fragment=fragment) text = link_item else: if link_url and len(link_url.split(':')) > 0 and link_url.split(':')[0] == 'File': object_item = ':'.join(link_url.split(':')[1:]) args = parsed_args.keyword if object_item is not None: if 'do' not in args: # by default, we want the item's get url for transclusion of raw data: args['do'] = 'get' query = url_encode(args, charset=CHARSET, encode_keys=True) target = Iri(scheme='wiki.local', path=object_item, query=query, fragment=None) text = object_item else: target = Iri(scheme='wiki.local', path=object_url) text = object_url if not link_text: link_text = text attrib = {xlink.href: target} attrib[moin_page.alt] = link_text element = moin_page.object(attrib) stack.push(element) if link_text: self.preprocessor.push() self.parse_inline(link_text, stack, self.inlinedesc_re) self.preprocessor.pop() else: stack.top_append(text) stack.pop() return target = Iri(scheme='wiki.local', path=link_url) text = link_url if external_link_url: target = Iri(external_link_url) text = alt_text element = moin_page.a(attrib={xlink.href: target}) stack.push(element) if link_text: self.preprocessor.push() self.parse_inline(link_text, stack, self.inlinedesc_re) self.preprocessor.pop() else: stack.top_append(text) stack.pop()