def consolidate_texts(cls, iterator): pending = None contents = None for span in iterator: if not isinstance(span, MarkdownItem): raise AssertionError("Item in text consolidation isn't" " MarkdownItem: {}".format(type(span))) if span.spanType is SpanType.TEXT: if contents is None and pending is None: pending = span else: if contents is None: contents = [] if pending is not None: contents.append(pending.contents) pending = None contents.append(span.contents) else: if pending is not None: yield pending pending = None if contents is not None: yield MarkdownItem(None, SpanType.TEXT, ''.join(contents)) contents = None yield span if pending is not None: yield pending pending = None if contents is not None: yield MarkdownItem(None, SpanType.TEXT, ''.join(contents)) contents = None
def resolve_all_doc_uri(cls, blockType, text, custom=None): output = [] outputTail = None for child in text: if child.blockType is BlockType.DOC_URI: for grandchild in child.contents: if cls.can_contain(blockType, grandchild): if outputTail is None: outputTail = [] outputTail.append(grandchild) else: if outputTail is not None: output.append(MarkdownItem( blockType, None, outputTail, custom)) outputTail = None output.append(grandchild) else: if outputTail is None: outputTail = [] outputTail.append(child) if outputTail is not None: output.append(MarkdownItem(blockType, None, outputTail, custom)) return output
def test_doc_resolver(self): docResolver = DocResolver() # # Test that paragraph cannot contain paragraph. self.assertFalse( docResolver.can_contain( BlockType.PARAGRAPH, MarkdownItem(BlockType.PARAGRAPH, None, []))) # # Test that list item can contain paragraph. self.assertTrue( docResolver.can_contain( BlockType.LIST_ITEM, MarkdownItem(BlockType.PARAGRAPH, None, [])))
def outputs(self, maxWidth=None): yield " " * self.indentStart yield "/**" yield "\n" if self._swiftSource else " " # In the next statement, + 1 because the continuation leaders have one # more space than the initial leader. indentContinue = " " * (self.indentStart + 1) # Following code would preserve the original indentation, which might be # wanted as an option. # indentContinue = " " * ( # self.indentStart + 1 if self.indentContinue is None # else self.indentContinue) if self.markdownItems is not None: # import json # def json_dump(iterator, indent=4): # return json.dumps(tuple( # item.asTuple() for item in iterator), indent=4) self._process_at_paragraphs(maxWidth) # print("CommentBlock outputs{}".format(json_dump(self.markdownItems))) # In the next statement, 3 is the length of " * " which will be the # comment leader. outputs = MarkdownItem.output_all( self.markdownItems , None if maxWidth is None else maxWidth - (self.indentStart + (2 if self._swiftSource else 3))) for index, line in enumerate(''.join(outputs).splitlines(True)): if index > 0 or self._swiftSource: yield indentContinue if not self._swiftSource: yield "* " yield line yield "\n" yield indentContinue yield "*/"
def doc_uri(self, groups): name, uri = CommentLine.group_startswith(groups, 'doc') if self.verbose: print('DocRenderer doc_uri', groups, name) contentLines = self.docGetter.get_content(uri, self.docPath) content = ''.join(contentLines) if content == "": return [] markdownItems = MarkdownParser(self.docGetter).get_markdown_items( self.docPath, content) # If len(contentLines) is 1 then destructure the markdown() return # value, i.e. remove the paragraph layer. if len(contentLines) == 1: if markdownItems[0].type is BlockType.PARAGRAPH: markdownItems = markdownItems[0].contents else: raise NotImplementedError() return [MarkdownItem(BlockType.DOC_URI, None ,markdownItems)]
def inline_html(self, text): if self.verbose: print('DocRenderer inline_html(,\n{})'.format(text)) return [MarkdownItem(None, SpanType.INLINE_HTML, text)]
def text(self, text): if self.verbose: print('DocRenderer text(,{}\n{})'.format(len(text), text)) return [MarkdownItem(None, SpanType.TEXT, text)]
def emphasis(self, text): if self.verbose: print('DocRenderer emphasis(,\n{})'.format(text)) return [MarkdownItem(None, SpanType.EMPHASIS, text)]
def codespan(self, text): if self.verbose: print('DocRenderer codespan(,\n{})'.format(text)) return [MarkdownItem(None, SpanType.CODESPAN, text)]
def autolink(self, link, is_email=False): if self.verbose: print('DocRenderer autolink(,{},{})'.format(link, is_email)) return [MarkdownItem(None, SpanType.AUTOLINK, link)]
def block_code(self, code, language=None): if self.verbose: print('DocRenderer block_code(,{},{})'.format(code, language)) return [MarkdownItem(BlockType.BLOCK_CODE, None, code)]
def process_at_commands(cls, iterator): """\ Take an iterator of paragraphs and split each to ensure that any at-commands are at the start of a paragraph. Also: - Join adjacent texts, to prevent wrong handling of parameter names with embedded _ characters later. - Strip leading whitespace from every line after the first in each paragraph. """ # Splitting is necessary if there is an embedded newline-at in a text # item that is a direct child of the paragraph. for paragraph in iterator: # Don't attempt to resolve at commands in code blocks. if paragraph.blockType is BlockType.BLOCK_CODE: yield paragraph continue # Unresolved at this time is that non-paragraphs sometimes come # through here, like lists also come through here. It seems to be OK # though, because those could have at commands that need to be # resolved. # Start a list of Markdown items that will become child items in the # yielded paragraphs. contents = [] for span in cls.consolidate_texts(paragraph.contents): if span.spanType is not SpanType.TEXT: contents.append(span) continue if not isinstance(span.contents, str): raise AssertionError( "Text in paragraph contents aren't str.") # The following returns a list with an odd number of items, # because the pattern has a capture group. splits = re.split(cls.atPattern, "".join(tuple( # Strip any leading whitespace from lines after the first. (line if lineIndex <= 0 else line.lstrip()) for lineIndex, line in enumerate( span.contents.splitlines(True)) ))) # Following lines are handy to check what's coming out of the re # split. # for index, split in enumerate(splits): # print('{:>02d} "{}"'.format(index, split)) # Note that splits never has an even number of items. If splits # has one item, this loop runs zero times. for splitIndex in range(0, len(splits) - 2, 2): if not(splits[splitIndex] == "" and splitIndex == 0): contents.append(MarkdownItem( None, SpanType.TEXT , splits[splitIndex] if splitIndex <= 0 else ''.join(splits[splitIndex - 1: splitIndex + 1]) )) yield MarkdownItem( paragraph.blockType, None, contents, paragraph.custom) contents = [] # Sweep up the items that weren't processed by the loop, either # one or two items. contents.append(MarkdownItem( None, SpanType.TEXT, ''.join(splits[-2:]))) yield MarkdownItem( paragraph.blockType, None, contents, paragraph.custom)