def replace(self, match): """ Substitution function for the re.sub function. """ filename, _ = self.getFilename(match.group(1)) if not filename: msg = "Failed to located filename in following command in file {}.\n {}" el = self.createErrorElement(msg.format(self.markdown.current.filename, match.group(0)), title="Unknown Markdown File") return etree.tostring(el) settings = self.getSettings(match.group(2)) if settings['start'] or settings['end']: content = ListingPattern.extractLineRange(filename, settings['start'], settings['end'], settings['include-end']) else: with open(filename, 'r') as fid: content = fid.read() if settings['re']: match = re.search(settings['re'], content, flags=re.MULTILINE|re.DOTALL) if not match: msg = "Failed to located regex in following command.\n{}" el = self.createErrorElement(msg.format(settings['re']), title="Failed Regex") return etree.tostring(el) if 'markdown' in match.groupdict(): content = match.group('markdown') else: content = match.group(0) self._found = True return content
def replace(self, match): """ Substitution function for the re.sub function. """ filename, _ = self.getFilename(match.group(1)) if not filename: msg = "Failed to located filename in following command in file {}.\n {}" el = self.createErrorElement(msg.format( self.markdown.current.filename, match.group(0)), title="Unknown Markdown File") return etree.tostring(el) settings = self.getSettings(match.group(2)) if settings['start'] or settings['end']: content = ListingPattern.extractLineRange(filename, settings['start'], settings['end'], settings['include-end']) else: with open(filename, 'r') as fid: content = fid.read() if settings['re']: match = re.search(settings['re'], content, flags=re.MULTILINE | re.DOTALL) if not match: msg = "Failed to located regex in following command.\n{}" el = self.createErrorElement(msg.format(settings['re']), title="Failed Regex") return etree.tostring(el) content = match.group(0) self._found = True return content
def sub(self, text, match): """ Substitution function that captures !listings command above a fenced code block. """ idx = text.rfind('\n', 0, match.start(0)-1) if idx: listing = re.search(self.RE, text[idx+1:match.start(0)-1]) if listing: # Stash the !listing line to be removed self._remove.append(text[idx+1:match.start(0)-1]) # The html stash that will contain the fenced code block placeholder = markdown.util.HTML_PLACEHOLDER % self.markdown.htmlStash.html_counter # Build the containing <div> settings = self.getSettings(listing.group('settings')) div = self.createFloatElement(settings) # Parse the fenced code block lines = match.group(0).split('\n') lines = super(ListingFencedBlockPreprocessor, self).run(lines) # String of html tags to wrap fenced content with start = self.markdown.htmlStash.store(etree.tostring(div)[:-6], safe=True) end = self.markdown.htmlStash.store('</div>', safe=True) # Add the wrapped html around the fenced block idx = lines.index(placeholder) lines.insert(idx+1, end) lines.insert(idx, start) return '\n'.join(lines) return match.group(0)
def run(self, root): rss = etree.Element('rss') rss.set('version', '2.0') channel = etree.SubElement(rss, 'channel') for tag, text in (('title', self.ext.getConfig('TITLE')), ('link', self.ext.getConfig('URL')), ('description', None)): element = etree.SubElement(channel, tag) element.text = text for child in root: if child.tag in ('h1', 'h2', 'h3', 'h4', 'h5'): heading = child.text.strip() item = etree.SubElement(channel, 'item') link = etree.SubElement(item, 'link') link.text = self.ext.getConfig('URL') title = etree.SubElement(item, 'title') title.text = heading guid = ''.join([ x for x in heading if x.isalnum() ]) guidElem = etree.SubElement(item, 'guid') guidElem.text = guid guidElem.set('isPermaLink', 'false') elif child.tag in ('p',): try: description = etree.SubElement(item, 'description') except UnboundLocalError: pass else: if len(child): content = '\n'.join([ etree.tostring(node) for node in child ]) else: content = child.text pholder = self.markdown.htmlStash.store('<![CDATA[ %s]]>' % content) description.text = pholder return rss
def svg_rewrite(svg): svg = re.sub('(xmlns(\:[a-z]*)?="[^"]+")', '', svg) svg = re.sub('xlink:href', 'href', svg) tree = etree.fromstring(svg) for use in tree.iter('use'): ref_id = use.get('href')[1:] ref = tree.find('.//path[@id=\'%s\']' % ref_id) use.attrib.pop('href') use.tag = ref.tag transform = use.attrib.pop('transform', '') x = use.attrib.pop('x', 0) y = use.attrib.pop('y', 0) transform += 'translate(%s, %s)' % (x, y) if len(use.attrib) > 0: raise RaphidocException( 'Unexpected attribute(s) on "use" element found: %s' % [k for k in ref.attrib.keys()]) for key, value in ref.attrib.items(): # TODO: BUG HERE?! if key == 'translate': translate += value elif key != 'id': use.attrib[key] = value use.attrib['transform'] = transform tree.remove(tree.find('defs')) return etree.tostring(tree).decode()
def translate(self, catalog, translations, root): children = root.getchildren() for idx, child in enumerate(children): if re.match(TRANSLATE_TAGS_RE, child.tag): translatable = child.text or '' translatable += '\n'.join([ etree.tostring(c) for c in child.getchildren() ]) if translatable: translatable = self.parser.unescape(translatable) catalog.add(translatable) attrs = ' '.join(( '{}="{}"'.format(k, v) for k, v in child.attrib.items() )) translated = translations.gettext(translatable) if isinstance(translated, binary_type): translated = translated.decode('utf-8') content = '<{0} {2}>{1}</{0}>'.format( child.tag, translated, attrs ) try: new_node = etree.fromstring(content.encode('utf-8')) root.remove(child) root.insert(idx, new_node) except etree.ParseError: pass else: self.translate(catalog, translations, child)
def render_wiki_file(wiki_file_id, wiki_file_name, wiki_file_type, w=0, h=0, tostring=False): link = '/{0}/file/{1}?filename={2}'.format(g.wiki_group, wiki_file_id, wiki_file_name) if wiki_file_type == 'image': el = etree.Element('img', attrib={'src': link}) if w: el.attrib['width'] = str(w) if h: el.attrib['height'] = str(h) elif wiki_file_type == 'file': sub_el = etree.Element('img', attrib={ 'alt': 'file icon', 'src': '/static/images/file-icon.png', 'width': '20', 'height': '20' }) sub_el.tail = wiki_file_name el = etree.Element('a', attrib={'href': link}) el.append(sub_el) if tostring: return etree.tostring(el, encoding='unicode') else: return el
def convert_admonition(self, block): lines = block.split('\n') if self.RE.search(block): m = self.RE.search(lines.pop(0)) klass, title = self.get_class_and_title(m) lines = list(map(lambda x: self.detab(x)[0], lines)) lines = '\n'.join(lines[:-1]) div = etree.Element('div') div.set('class', '%s %s' % (self.CLASSNAME, klass)) if title: p = etree.SubElement(div, 'p') p.set('class', self.CLASSNAME_TITLE) p.text = title content = etree.SubElement(div, 'p') content.text = lines string = etree.tostring(div).decode(self.encoding) lines = [string] lines.append('') return lines
def _expected(self, Cls, ctx): from markdown.util import etree s = '<p>%s</p>' % Cls.render_template(ctx) # "tree-ify" it which causes some stuff like re-arranging properties # etc el = etree.fromstring(s) s = etree.tostring(el) return s.decode('utf-8')
def sub(self, text, match): """ Substitution function that captures !listings command above a fenced code block. """ idx = text.rfind('\n', 0, match.start(0) - 1) if idx: listing = re.search(self.RE, text[idx + 1:match.start(0) - 1]) if listing: # Stash the !listing line to be removed self._remove.append(text[idx + 1:match.start(0) - 1]) # The html stash that will contain the fenced code block placeholder = markdown.util.HTML_PLACEHOLDER % self.markdown.htmlStash.html_counter # Build the containing <div> settings = self.getSettings(listing.group('settings')) div = self.createFloatElement(settings) # Add a copy button if settings['copy-button']: code_id = 'moose-code-block-{}'.format( MooseMarkdown.CODE_BLOCK_COUNT) btn = self.createCopyButton(code_id) string = '<pre>{}<code%s id={}>%s</code></pre>'.format( etree.tostring(btn), code_id) self.CODE_WRAP = string #pylint: disable=invalid-name # Parse the fenced code block lines = match.group(0).split('\n') lines = super(ListingFencedBlockPreprocessor, self).run(lines) # String of html tags to wrap fenced content with start = self.markdown.htmlStash.store(etree.tostring(div)[:-6], safe=True) end = self.markdown.htmlStash.store('</div>', safe=True) # Add the wrapped html around the fenced block idx = lines.index(placeholder) lines.insert(idx + 1, end) lines.insert(idx, start) return '\n'.join(lines) return match.group(0)
def render_wiki_page(wiki_page_id, wiki_page_title, tostring=False): el = etree.Element( 'a', attrib={'href': '/{0}/page/{1}'.format(g.wiki_group, wiki_page_id)}) el.text = wiki_page_title if tostring: return etree.tostring(el, encoding='unicode') else: return el
def sub(self, text, match): """ Substitution function that captures !listings command above a fenced code block. """ idx = text.rfind('\n', 0, match.start(0)-1) if idx: listing = re.search(self.RE, text[idx+1:match.start(0)-1]) if listing: # Stash the !listing line to be removed self._remove.append(text[idx+1:match.start(0)-1]) # The html stash that will contain the fenced code block placeholder = markdown.util.HTML_PLACEHOLDER % self.markdown.htmlStash.html_counter # Build the containing <div> settings = self.getSettings(listing.group('settings')) div = self.createFloatElement(settings) # Add a copy button if settings['copy-button']: code_id = 'moose-code-block-{}'.format(MooseMarkdown.CODE_BLOCK_COUNT) btn = self.createCopyButton(code_id) string = '<pre>{}<code%s id={}>%s</code></pre>'.format(etree.tostring(btn), code_id) self.CODE_WRAP = string #pylint: disable=invalid-name # Parse the fenced code block lines = match.group(0).split('\n') lines = super(ListingFencedBlockPreprocessor, self).run(lines) # String of html tags to wrap fenced content with start = self.markdown.htmlStash.store(etree.tostring(div)[:-6], safe=True) end = self.markdown.htmlStash.store('</div>', safe=True) # Add the wrapped html around the fenced block idx = lines.index(placeholder) lines.insert(idx+1, end) lines.insert(idx, start) return '\n'.join(lines) return match.group(0)
def render_wiki_link(group, page_id, page_title, tostring=True): """Render html """ el = etree.Element('a', attrib={ 'class': 'wiki-page', 'href': '/{0}/{1!s}/page'.format(group, page_id) }) el.text = page_title if tostring: return etree.tostring(el, encoding='unicode') else: return el
def is_text_node(el): """ """ s = str(etree.tostring(el)) # strip our tag: html = s.split('<%s' % el.tag, 1)[1].split('>', 1)[1].rsplit('>', 1)[0] # do we start with another tagged child which is NOT in inlines:? if not html.startswith('<'): return 1, html for inline in ('<a', '<em>', '<code>', '<strong>'): if html.startswith(inline): return 1, html return 0, 0
def is_text_node(el): """ """ # strip our tag: html = etree.tostring(el).split('<%s' % el.tag, 1)[1].split('>', 1)[1].rsplit('>', 1)[0] # do we start with another tagged child which is NOT in inlines:? if not html.startswith('<'): return 1, html for inline in inlines: if html.startswith(inline): return 1, html return 0, 0
def render_wiki_image(group, file_id, filename, tostring=True): el = etree.Element('img', attrib={ 'src': '/{}/file/{}?filename={}'.format( group, file_id, filename), 'class': 'wiki-file' }) if tostring: return etree.tostring(el, encoding='unicode') else: return el
def run(self, root): rss = etree.Element("rss") rss.set("version", "2.0") channel = etree.SubElement(rss, "channel") for tag, text in ( ("title", self.ext.getConfig("TITLE")), ("link", self.ext.getConfig("URL")), ("description", None), ): element = etree.SubElement(channel, tag) element.text = text for child in root: if child.tag in ["h1", "h2", "h3", "h4", "h5"]: heading = child.text.strip() item = etree.SubElement(channel, "item") link = etree.SubElement(item, "link") link.text = self.ext.getConfig("URL") title = etree.SubElement(item, "title") title.text = heading guid = "".join([x for x in heading if x.isalnum()]) guidElem = etree.SubElement(item, "guid") guidElem.text = guid guidElem.set("isPermaLink", "false") elif child.tag in ["p"]: try: description = etree.SubElement(item, "description") except UnboundLocalError: # Item not defined - moving on pass else: if len(child): content = "\n".join( [etree.tostring(node) for node in child]) else: content = child.text pholder = self.markdown.htmlStash.store("<![CDATA[ %s]]>" % content) description.text = pholder return rss
def run(self, lines: List[str]) -> List[str]: new_lines = [] i = 0 while i < len(lines): new_lines.append(lines[i]) m = self._pattern.match(lines[i]) i += 1 if m: new_lines.append( etree.tostring(etree.Element('a', {'name': m.group(1)}), encoding='unicode')) while len(lines[i].strip()) == 0 and i < len(lines): i += 1 return new_lines
def __sub(self, match): """ Substitution method for regex replacement. """ name = match.group('name') markdown = match.group('markdown') settings = self.getSettings(match.group('settings')) # Use the content in database if name in self.__database: div = etree.Element('div') div.set('markdown', '1') item = self.__database[name] div.text = item.markdown # Use the default elif settings['default']: div = etree.Element('div') div.set('markdown', '1') div.text = markdown # Produce error else: help_div = etree.Element('div') heading = etree.SubElement(help_div, 'h3') heading.text = "Adding Markdown for '{}' Item.".format(name) p = etree.SubElement(help_div, 'p') p.text = "To add content for the '{}' item, simply add a block similar to what is ' \ 'shown below in the markdown file '{}'.".format( name, self.markdown.current.filename) pre = etree.SubElement(help_div, 'pre') code = etree.SubElement(pre, 'code') code.set('class', 'language-text') code.text = '!SQA-template-item {}\nThe content placed here should be valid markdown ' \ 'that will replace the template description.\n!END-template-item' \ .format(name) title = 'Missing Template Item: {}'.format(name) div = self.createErrorElement(title=title, message=markdown, markdown=True, help_button=help_div) return etree.tostring(div)
def _create_video(self, m, vtype, width, height, url): vid = m.group('%s_vid' % vtype) url = url % vid url = url.replace('&', '&') div = etree.Element('div') div.set('class', 'video %s' % vtype) iframe = etree.SubElement(div, 'iframe') iframe.set('allowfullscreen', 'true') iframe.set('frameborder', '0') iframe.set('width', str(width)) iframe.set('height', str(height)) iframe.set('scrolling', 'no') iframe.set('src', url) return etree.tostring(div)
def run (self, root): rss = etree.Element("rss") rss.set("version", "2.0") channel = etree.SubElement(rss, "channel") for tag, text in (("title", self.ext.getConfig("TITLE")), ("link", self.ext.getConfig("URL")), ("description", None)): element = etree.SubElement(channel, tag) element.text = text for child in root: if child.tag in ["h1", "h2", "h3", "h4", "h5"]: heading = child.text.strip() item = etree.SubElement(channel, "item") link = etree.SubElement(item, "link") link.text = self.ext.getConfig("URL") title = etree.SubElement(item, "title") title.text = heading guid = ''.join([x for x in heading if x.isalnum()]) guidElem = etree.SubElement(item, "guid") guidElem.text = guid guidElem.set("isPermaLink", "false") elif child.tag in ["p"]: try: description = etree.SubElement(item, "description") except UnboundLocalError: # Item not defined - moving on pass else: if len(child): content = "\n".join([etree.tostring(node) for node in child]) else: content = child.text pholder = self.markdown.htmlStash.store( "<![CDATA[ %s]]>" % content) description.text = pholder return rss
def _replace_block(self, text): # Parse configuration params m = self.FENCED_BLOCK_RE.search(text) if not m: m = self.BLOCK_RE.search(text) if not m: return text, False # Parse configuration params img_format = m.group('format') if m.group( 'format') else self.config['format'] classes = m.group('classes') if m.group( 'classes') else self.config['classes'] alt = m.group('alt') if m.group('alt') else self.config['alt'] title = m.group('title') if m.group('title') else self.config['title'] # Extract diagram source end convert it code = m.group('code') diagram = self.generate_uml_image(code, img_format) if img_format == 'png': data = 'data:image/png;base64,{0}'.format( base64.b64encode(diagram).decode('ascii')) img = etree.Element('img') img.attrib['src'] = data img.attrib['classes'] = classes img.attrib['alt'] = alt img.attrib['title'] = title elif img_format == 'svg': # Firefox handles only base64 encoded SVGs data = 'data:image/svg+xml;base64,{0}'.format( base64.b64encode(diagram).decode('ascii')) img = etree.Element('img') img.attrib['src'] = data img.attrib['classes'] = classes img.attrib['alt'] = alt img.attrib['title'] = title elif img_format == 'txt': # logger.debug(diagram) img = etree.Element('pre') code = etree.SubElement(img, 'code') code.attrib['class'] = 'text' code.text = AtomicString(diagram.decode('UTF-8')) return text[:m.start()] + etree.tostring( img).decode() + text[m.end():], True
def run(self, parent, blocks): """ Create the collapsible region with the listed requirements. """ block = blocks.pop(0) match = self.RE.search(block) settings = self.getSettings(match.group('settings')) key = match.group('key') # Set the default directory require_md = settings['require-markdown'] status = settings['status'] if require_md: folder = settings['markdown-folder'] if not folder: folder = os.path.join( os.path.dirname(self.markdown.current.filename), key) else: folder = os.path.join(MooseDocs.ROOT_DIR, folder) ul = MooseDocs.common.MooseCollapsible() if settings['title']: ul.addHeader(settings['title']) for item in match.group('items').split('\n'): tag_id, text = re.split(r'\s+', item.strip(), maxsplit=1) desc = text if require_md: slug, _ = MooseDocs.common.slugify(tag_id, ('.', '-')) slug += '.md' full_name = os.path.join(folder, slug) if not os.path.exists(full_name): LOG.error( "The required markdown file (%s) does not exist.", full_name) tag_id = '<a href="{}">{}</a>'.format(full_name, tag_id) if status: _, found = self.getFilename(slug) if found: status_el = SQAPageStatus.createStatusElement( found, self.markdown.current) desc += etree.tostring(status_el) ul.addItem(tag_id, desc, text, id_='{}-{}'.format(key, tag_id)) parent.append(ul.element())
def __sub(self, match): """ Substitution method for regex replacement. """ name = match.group('name') markdown = match.group('markdown') settings = self.getSettings(match.group('settings')) # Use the content in database if name in self.__database: div = etree.Element('div') div.set('markdown', '1') item = self.__database[name] div.text = item.markdown # Use the default elif settings['default']: div = etree.Element('div') div.set('markdown', '1') div.text = markdown # Produce error else: help_div = etree.Element('div') heading = etree.SubElement(help_div, 'h3') heading.text = "Adding Markdown for '{}' Item.".format(name) p = etree.SubElement(help_div, 'p') p.text = "To add content for the '{}' item, simply add a block similar to what is ' \ 'shown below in the markdown file '{}'.".format(name, self.markdown.current.filename) pre = etree.SubElement(help_div, 'pre') code = etree.SubElement(pre, 'code') code.set('class', 'language-text') code.text = '!SQA-template-item {}\nThe content placed here should be valid markdown ' \ 'that will replace the template description.\n!END-template-item' \ .format(name) title = 'Missing Template Item: {}'.format(name) div = self.createErrorElement(title=title, message=markdown, markdown=True, help_button=help_div) return etree.tostring(div)
def tostring(root): '''Converts an etree into a string. Args: root: An Element from the ElementTree library. Returns: A string of the serialized HTML tree. ''' string = etree.tostring(root, encoding='unicode', method='html') def unescape_comment(matchobj): return r'<!--{}>{}<!{}-->'.format( matchobj.group('start_condition'), matchobj.group('content'), matchobj.group('end_condition')) string = re.sub(HtmlSerializer.COMMENT_PATTERN, unescape_comment, string, flags=re.DOTALL) return string
def _run(self, text): # Parse configuration params m = self.FENCED_BLOCK_RE.search(text) if not m: return text, False imgformat = m.group('format') if m.group('format') else self.config['format'] classes = m.group('classes') if m.group('classes') else self.config['classes'] alt = m.group('alt') if m.group('alt') else self.config['alt'] title = m.group('title') if m.group('title') else self.config['title'] # Remove block header and footer code = m.group('code') diagram = self.generate_uml_image(code, imgformat) p = etree.Element('p') if imgformat == 'png': data = 'data:image/png;base64,{0}'.format( base64.b64encode(diagram).decode('ascii') ) img = etree.SubElement(p, 'img') img.attrib['src' ] = data img.attrib['classes'] = classes img.attrib['alt' ] = alt img.attrib['title' ] = title elif imgformat == 'svg': # Firefox handles only base64 encoded SVGs data = 'data:image/svg+xml;base64,{0}'.format( base64.b64encode(diagram).decode('ascii') ) img = etree.SubElement(p, 'img') img.attrib['src' ] = data img.attrib['classes'] = classes img.attrib['alt' ] = alt img.attrib['title' ] = title elif imgformat == 'txt': #logger.debug(diagram) pre = etree.SubElement(parent, 'pre') code = etree.SubElement(pre, 'code') code.attrib['class'] = 'text' code.text = AtomicString(diagram) return text[:m.start()] + '\n' + etree.tostring(p).decode() + '\n' + text[m.end():], True
def run(self, parent, blocks): """ Create the collapsible region with the listed requirements. """ block = blocks.pop(0) match = self.RE.search(block) settings = self.getSettings(match.group('settings')) key = match.group('key') # Set the default directory require_md = settings['require-markdown'] status = settings['status'] if require_md: folder = settings['markdown-folder'] if not folder: folder = os.path.join(os.path.dirname(self.markdown.current.filename), key) else: folder = os.path.join(MooseDocs.ROOT_DIR, folder) ul = MooseDocs.common.MooseCollapsible() if settings['title']: ul.addHeader(settings['title']) for item in match.group('items').split('\n'): tag_id, text = re.split(r'\s+', item.strip(), maxsplit=1) desc = text if require_md: slug, _ = MooseDocs.common.slugify(tag_id, ('.', '-')) slug += '.md' full_name = os.path.join(folder, slug) if not os.path.exists(full_name): LOG.error("The required markdown file (%s) does not exist.", full_name) tag_id = '<a href="{}">{}</a>'.format(full_name, tag_id) if status: _, found = self.getFilename(slug) if found: status_el = SQAPageStatus.createStatusElement(found, self.markdown.current) desc += etree.tostring(status_el) ul.addItem(tag_id, desc, text, id_='{}-{}'.format(key, tag_id)) parent.append(ul.element())
def render_wiki_file(group, file_id, filename, tostring=True): sub_el = etree.Element('img', attrib={ 'alt': 'file icon', 'src': '/static/icons/file-icon.png', 'width': '20', 'height': '20' }) sub_el.tail = filename el = etree.Element('a', attrib={ 'href': '/{}/file/{}?filename={}'.format( group, file_id, filename), 'class': 'wiki-file' }) el.append(sub_el) if tostring: return etree.tostring(el, encoding='unicode') else: return el
def run(self, root): found = False # instead of creating a new tree from scratch, # simply use the original one and remove elements clone = deepcopy(root) # lazy iteration wouldn't work, since we manipulate as we iterate for parents, element in list(self.itertree(clone, (clone, ))): # if len(parents) is 1, only the root is left if found and len(parents) > 1: parents[-2].remove(element) elif element.text and self.config['marker'] in element.text: self.cleanup_marker(self.config['marker'], parents, element) found = True for parents, element in self.itertree(root, (root, )): if element.text and self.config['marker'] in element.text: self.cleanup_marker(self.config['marker'], parents, element) output = etree.tostring(clone, encoding='utf-8', method='html') for pp in self.markdown.postprocessors.values(): output = pp.run(output) self.markdown.summary = output self.markdown.is_summarized = found
def run(self, lines): new_lines = [] for line in lines: m = self.RE.match(line) if m: filename = m.group(1) extensions = m.group(2).split(',') video = etree.Element('video') video.set("autoplay", "true") video.set("controls", "false") video.set("loop", "true") video.set("class", self.gifv.getConfig('css_class')) for extension in extensions: source = etree.SubElement(video, "source") source.set( 'src', '{}{}.{}'.format(self.gifv.getConfig('video_url_base'), filename, extension)) new_lines.append(etree.tostring(video, encoding="unicode")) else: new_lines.append(line) return new_lines
# shift to the far left, no matter the indent (screenspace matters): firstl = s.split('\n')[0] del_spaces = ' ' * (len(firstl) - len(firstl.lstrip())) s = ('\n' + s).replace('\n%s' % del_spaces, '\n')[1:] # we want an indent of one and low vis prefix. this does it: code_lines = ('\n' + s).splitlines() prefix = '\n%s%s %s' % (ind, low(code_pref), col('', C, no_reset=1)) code_lines.pop() if code_lines[-1] == '\x1b[0m' else None code = prefix.join(code_lines) code = code.replace('\x01--', ':-') return code + '\n' + reset_col if PY3: elstr = lambda el: etree.tostring(el).decode('utf-8') else: elstr = lambda el: etree.tostring(el) def is_text_node(el): """ """ s = elstr(el) # strip our tag: html = s.split('<%s' % el.tag, 1)[1].split('>', 1)[1].rsplit('>', 1)[0] # do we start with another tagged child which is NOT in inlines:? if not html.startswith('<'): return 1, html for inline in ('<a', '<em>', '<code>', '<strong>'): if html.startswith(inline): return 1, html
def assert_xml_equal(self, a, b): self.assertEqual( xmltodict.parse(etree.tostring(a)), xmltodict.parse(etree.tostring(b)))
def render_wikilink(linktext): m = re.match(RE_WIKILINK, u'[[%s]]' % linktext) return etree.tostring(_render_match(m))
def _replace_block(self, text): # Parse configuration params m = self.FENCED_BLOCK_RE.search(text) if not m: m = self.BLOCK_RE.search(text) if not m: return text, False # Parse configuration params img_format = m.group('format') if m.group( 'format') else self.config['format'] classes = m.group('classes') if m.group( 'classes') else self.config['classes'] alt = m.group('alt') if m.group('alt') else self.config['alt'] title = m.group('title') if m.group('title') else self.config['title'] width = m.group('width') if m.group('width') else None height = m.group('height') if m.group('height') else None # Extract diagram source end convert it code = m.group('code') diagram = self.generate_uml_image(code, img_format) if img_format == 'txt': # logger.debug(diagram) img = etree.Element('pre') code = etree.SubElement(img, 'code') code.attrib['class'] = 'text' code.text = AtomicString(diagram.decode('UTF-8')) else: # These are images if img_format == 'svg_inline': data = self.ADAPT_SVG_REGEX.sub('<svg \\1\\2>', diagram.decode('UTF-8')) img = etree.fromstring(data) # remove width and height in style attribute img.attrib['style'] = re.sub(r'\b(?:width|height):\d+px;', '', img.attrib['style']) elif img_format == 'svg': # Firefox handles only base64 encoded SVGs data = 'data:image/svg+xml;base64,{0}'.format( base64.b64encode(diagram).decode('ascii')) img = etree.Element('img') img.attrib['src'] = data elif img_format == 'svg_object': # Firefox handles only base64 encoded SVGs data = 'data:image/svg+xml;base64,{0}'.format( base64.b64encode(diagram).decode('ascii')) img = etree.Element('object') img.attrib['data'] = data else: # png format, explicitly set or as a default when format is not recognized data = 'data:image/png;base64,{0}'.format( base64.b64encode(diagram).decode('ascii')) img = etree.Element('img') img.attrib['src'] = data styles = [] if width: styles.append("max-width:" + width) if height: styles.append("max-height:" + height) if styles: style = img.attrib[ 'style'] + ';' if 'style' in img.attrib and img.attrib[ 'style'] != '' else '' img.attrib['style'] = style + ";".join(styles) img.attrib['width'] = '100%' if 'height' in img.attrib: img.attrib.pop('height') img.attrib['class'] = classes img.attrib['alt'] = alt img.attrib['title'] = title return text[:m.start()] + etree.tostring( img).decode() + text[m.end():], True
# shift to the far left, no matter the indent (screenspace matters): firstl = s.split("\n")[0] del_spaces = " " * (len(firstl) - len(firstl.lstrip())) s = ("\n" + s).replace("\n%s" % del_spaces, "\n")[1:] # we want an indent of one and low vis prefix. this does it: code_lines = ("\n" + s).splitlines() prefix = "\n%s%s %s" % (ind, low(code_pref), col("", C, no_reset=1)) code_lines.pop() if code_lines[-1] == "\x1b[0m" else None code = prefix.join(code_lines) code = code.replace("\x01--", ":-") return code + "\n" + reset_col if PY3: elstr = lambda el: etree.tostring(el).decode("utf-8") else: elstr = lambda el: etree.tostring(el) def is_text_node(el): """ """ s = elstr(el) # strip our tag: html = s.split("<%s" % el.tag, 1)[1].split(">", 1)[1].rsplit(">", 1)[0] # do we start with another tagged child which is NOT in inlines:? if not html.startswith("<"): return 1, html for inline in ("<a", "<em>", "<code>", "<strong>"): if html.startswith(inline): return 1, html
def run(self, root): print(etree.tostring(root))
def main(): parser = argparse.ArgumentParser(description='A markdown processor') parser.add_argument('-t', '--template', help='document template') parser.add_argument('-ao', '--autooutput', help='automatically create the output file with appropriate extension', action='store_true') parser.add_argument('-o', '--output', type=argparse.FileType('w'),help='output file') parser.add_argument('-f', '--format',help='output format', choices=['html','latex'],default='html') parser.add_argument('-s', '--subs',help='template substitutions',default='') parser.add_argument('--filter',help='process only elements matching a given css selector',default=None) parser.add_argument('-q', '--query',help='print out elements matching a given css selector') parser.add_argument('--attrs', help='a comma separated list of attribute names to print (in conjunction with -q)', default='text_content') parser.add_argument('--norefs',help='do not include referenced elements when filtering',action='store_true') parser.add_argument('--numberreferencedonly',help='only number blocks which are actually referenced',action='store_true') parser.add_argument('--verbose', '-v', action='count',help='be verbose',default=0) parser.add_argument('--renderoptions', help='a comma separated list of key=value pairs which will be passed as options to the renderer',default=None) parser.add_argument('document',type=argparse.FileType('r'),help='filename of the document to transform') args = parser.parse_args() root_logger.setLevel(logging.FATAL-args.verbose*10) template = load_template(args.template, args.format) doc_source = unicode(args.document.read(),encoding='utf-8',errors='ignore'); comments_re = re.compile('^\/\/.*$', re.MULTILINE) doc_source = comments_re.sub('',doc_source) md, lxml_tree = render_md(doc_source,tree='lxml',ext_config={'references':{'number_referenced_only':args.numberreferencedonly}}) lxml_tree = build_sections(lxml_tree) if args.query: attrs = args.attrs.split(',') for e in query(args.query, lxml_tree): print(','.join([ attr+'='+e[attr] for attr in attrs if attr in e ])) return if args.filter: html = '\n'.join([lxml.etree.tostring(e,method='html') for e in filter(args.filter, lxml_tree, include_references=not args.norefs)]) else: html = lxml.etree.tostring(lxml_tree,method='html') html_tree = parse_html(html,tree='lxml') dct = {} render_options = {} if args.renderoptions: try: for opt in args.renderoptions.split(','): key,value = opt.split('=') render_options[key]=eval(value) except Exception as e: logger.warn('Bad render options: '+args.renderoptions+' ('+str(e)+')') if args.format == 'html': output = html dct['headings_css'] = build_headings(html_tree,position='after',format='css') elif args.format == 'latex': dct['headings'] = build_headings(html_tree,position='after',format='latex') latex = laTeXRenderer(render_options) output = latex.render_from_dom(html_tree) dct['content']=output if hasattr(md, 'Meta'): for (k,v) in md.Meta.items(): dct[k] = ' '.join(v) dct['toc']=etree.tostring(md.TOC.to_element()) try: for l in open('.md-substitutions','r').readlines(): if l.strip().startswith('#'): continue try: k,v = l.strip().split('=') dct[k.strip()] = v.strip() except: pass except: pass if args.subs: for ts in args.subs.split(','): k,v = ts.split('=') dct[k] = v if 'image_path' in dct: exp = re.compile(r'(<img\s*[^>]*)\s*src=[\'"]([^\'"]*)[\'"]([^>]*>)') dct['content']=exp.sub(r'\1src="'+dct['image_path']+r'\2"\3',dct['content']) if args.document.name.endswith('.md'): dct['basename'] = args.document.name[:-3] else: dct['basename'] = args.document.name output = render_template(template, dct) if args.output: args.output.write(output.encode('utf-8')) elif args.autooutput: extensions = { 'html':'.html', 'latex':'.tex' } base = args.document.name; if base.endswith('.md'): base = base[:-3] out_fname=base+extensions[args.format] open(out_fname,'w').write(output.encode('utf-8')) else: print(output.encode('utf-8'))
def htmlToString(self, html): inputHtml = '<div>' + html + '</div>' inputRoot = etree.fromstring(inputHtml) outputRoot = self.proc.run(inputRoot) outputText = b''.join(etree.tostring(child, encoding="utf-8") for child in outputRoot).decode("utf-8") return outputText