def visit_moinpage_table(self, elem): attrib = Attributes(elem).convert() ret = html.table(attrib=attrib) caption = 1 if elem[0].tag.name == 'caption' else 0 for idx, item in enumerate(elem): tag = None if item.tag.uri == moin_page: if len(elem) > 1 + caption and html( 'class') in attrib and u'moin-wiki-table' in attrib[ html('class')]: # moinwiki tables require special handling because # moinwiki_in converts "||header||\n===\n||body||\n===\n||footer||" into multiple table-body's if idx == 0 + caption: # make first table-body after caption into header tag = html.thead elif len(elem) > 2 + caption and idx == len(elem) - 1: # make last table-body into footer tag = html.tfoot else: tag = html.caption if (caption and idx == 0) else html.tbody elif item.tag.name == 'table-body': tag = html.tbody elif item.tag.name == 'table-header': tag = html.thead elif item.tag.name == 'table-footer': tag = html.tfoot elif item.tag.name == 'caption': tag = html.caption elif item.tag.uri == html and \ item.tag.name in ('tbody', 'thead', 'tfoot'): tag = item.tag if tag is not None: ret.append(self.new_copy(tag, item)) return ret
def visit_moinpage_span(self, elem): # TODO : Fix bug if a span has multiple attributes # Check for the attributes of span attrib = Attributes(elem) # Check for the baseline-shift (subscript or superscript) generate = attrib.get('baseline-shift') if generate: if generate == 'sub': return self.new_copy(html.sub, elem) elif generate == 'super': return self.new_copy(html.sup, elem) generate = attrib.get('font-size') if generate: if generate == '85%': attribute = {} key = html('class') attribute[key] = 'moin-small' return self.new_copy(html.span, elem, attribute) elif generate == '120%': attribute = {} key = html('class') attribute[key] = 'moin-big' return self.new_copy(html.span, elem, attribute) generate = attrib.get('element') if generate: if generate in self.direct_inline_tags: return self.new_copy(html(generate), elem) else: attribute = {} key = html('class') attribute[key] = "element-{0}".format(generate) return self.new_copy(html.span, elem, attribute) # If no attributes are handled by our converter, just return span return self.new_copy(html.span, elem)
def visit_xhtml_hr(self, element, min_class=u'moin-hr1', max_class=u'moin-hr6', default_class=u'moin-hr3'): """ <hr /> --> <separator /> """ hr_class = element.attrib.get(html('class')) if not (min_class <= hr_class <= max_class): element.attrib[html('class')] = default_class return self.new_copy(moin_page.separator, element, {})
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 visit_docbook_formalpara(self, element, depth): """ <formalpara> <title>Heading</title> <para>Text</para> </formalpara> --> <p html:title="Heading">Text</p> """ for child in element: if isinstance(child, ET.Element): if child.tag.name == 'title': title_element = child if child.tag.name == 'para': para_element = child if not title_element: # XXX: Improve error raise SyntaxError("title child missing for formalpara element") if not para_element: # XXX: Improve error raise SyntaxError("para child missing for formalpara element") children = self.do_children(para_element, depth + 1)[0] attrib = {} attrib[html('title')] = title_element[0] return self.new(moin_page.p, attrib=attrib, children=children)
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 convert_attributes(self, element): result = {} for key, value in element.attrib.iteritems(): if key in self.standard_attributes: result[html(key)] = value if key == 'id': result[xml('id')] = value return result
def visit_xhtml_inline(self, element): """ For some specific inline tags (defined in inline_tags) We just return <span element="tag.name"> """ key = html('class') attrib = {} attrib[key] = ''.join(['html-', element.tag.name]) return self.new_copy(moin_page.span, element, attrib)
def visit_moinpage_table(self, element): # TODO: Attributes conversion title = element.get(html('title')) if not title: # TODO: Translation title = "Table {0}".format(self.table_counter) self.table_counter += 1 caption = ET.Element(docbook('caption'), attrib={}, children=[title]) children = [caption] children.extend(self.do_children(element)) return self.new(docbook.table, attrib={}, children=children)
def visit_moinpage_h(self, elem): level = elem.get(moin_page.outline_level, 1) try: level = int(level) except ValueError: raise ElementException('page:outline-level needs to be an integer') if level < 1: level = 1 elif level > 6: level = 6 ret = self.new_copy(html('h{0}'.format(level)), elem) ret.level = level return ret
def visit_moinpage_list(self, elem): attrib = Attributes(elem) attrib_new = attrib.convert() generate = attrib.get('item-label-generate') if generate: if generate == 'ordered': style = attrib.get('list-style-type') if style: if style == 'upper-alpha': attrib_new[html('class')] = 'moin-upperalpha-list' elif style == 'upper-roman': attrib_new[html('class')] = 'moin-upperroman-list' elif style == 'lower-roman': attrib_new[html('class')] = 'moin-lowerroman-list' elif style == 'lower-alpha': attrib_new[html('class')] = 'moin-loweralpha-list' start_number = attrib.get('list-start') if start_number: attrib_new[html('start')] = start_number ret = html.ol(attrib_new) elif generate == 'unordered': style = attrib.get('list-style-type') if style and style == 'no-bullet': attrib_new[html('class')] = 'moin-nobullet-list' ret = html.ul(attrib=attrib_new) else: raise ElementException( 'page:item-label-generate does not support "{0}"'.format( generate)) else: ret = html.dl(attrib=attrib_new) for item in elem: if isinstance(item, ET.Element): if item.tag.uri == moin_page and item.tag.name == 'list-item': if not generate: for label in item: if isinstance(label, ET.Element): if label.tag.uri == moin_page and label.tag.name == 'list-item-label': ret_label = self.new_copy(html.dt, label) ret.append(ret_label) for body in item: if isinstance(body, ET.Element): if body.tag.uri == moin_page and body.tag.name == 'list-item-body': if generate: ret_body = self.new_copy(html.li, body) else: ret_body = self.new_copy(html.dd, body) ret.append(ret_body) break return ret
def visit_moinpage_p(self, element): """ If we have a title attribute for p, we return a para, with a <title> child. Otherwise we return a <simpara>. """ title_attr = element.get(html('title')) if title_attr: print title_attr children = [] title_elem = self.new(docbook('title'), attrib={}, children=[title_attr]) children.append(title_elem) children.extend(self.do_children(element)) return self.new(docbook.para, attrib={}, children=children) else: return self.new_copy(docbook.simpara, element, attrib={})
def __init__(self, key): self.key = html(key)
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) attribs = {} query = [] if link_args: link_args = parse_arguments(link_args) # XXX needs different parsing for key in link_args.keys(): if key in ('target', 'title', 'download', 'class', 'accesskey'): attribs[html(key)] = link_args[key] if key[0] == '&': query.append('{0}={1}'.format(key[1:], link_args[key])) 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: if link_item.startswith('#') and '/+convert/' in request.url: # avoid traceback in link.py when converting moinwiki item to ReST | HTML | Docbook link_item = request.url.split('+convert/')[-1] + link_item link_item, fragment = link_item.rsplit('#', 1) else: link_item, fragment = link_item, None if '?' in link_item: path, link_query = link_item.rsplit('?', 1) query.insert(0, link_query) else: path, link_query = link_item, None if query: query = '&' + '&'.join(query) else: query = None target = Iri(scheme='wiki.local', path=path, query=query, fragment=fragment) text = link_item else: target = Iri(link_url) text = link_url attribs[xlink.href] = target element = moin_page.a(attrib=attribs) stack.push(element) if link_text: self.parse_inline(link_text, stack, self.inlinedesc_re) else: stack.top_append(text) stack.pop()