def __handle_start_list_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the start unordered list token. """ list_token = cast(ListStartMarkdownToken, next_token) transform_state.is_in_loose_list = ( TransformToGfmListLooseness.calculate_list_looseness( transform_state.actual_tokens, transform_state.actual_token_index, list_token, )) if list_token.is_ordered_list_start: token_parts = ["<ol"] if list_token.list_start_content != "1": token_parts.extend( [' start="', str(int(list_token.list_start_content)), '"']) token_parts.extend([">", ParserHelper.newline_character, "<li>"]) transform_state.add_leading_text = "".join(token_parts) else: transform_state.add_leading_text = "".join( ["<ul>", ParserHelper.newline_character, "<li>"]) return output_html
def __apply_transformation( self, transform_state: TransformState, actual_tokens: List[MarkdownToken], actual_tokens_size: int, next_token: MarkdownToken, output_html: str, ) -> str: transform_state.add_trailing_text = None transform_state.add_leading_text = None transform_state.next_token = None if (transform_state.actual_token_index + 1) < actual_tokens_size: transform_state.next_token = actual_tokens[ transform_state.actual_token_index + 1] if next_token.token_name in self.start_token_handlers: start_handler_fn = self.start_token_handlers[next_token.token_name] output_html = start_handler_fn(output_html, next_token, transform_state) elif next_token.is_end_token: end_token = cast(EndMarkdownToken, next_token) if end_token.type_name in self.end_token_handlers: end_handler_fn = self.end_token_handlers[end_token.type_name] output_html = end_handler_fn(output_html, end_token, transform_state) else: raise AssertionError( f"Markdown token end type {end_token.type_name} not supported." ) else: raise AssertionError( f"Markdown token type {type(next_token)} not supported.") return output_html
def __handle_start_html_block_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the start html block token. """ _ = next_token transform_state.is_in_html_block = True token_parts = [] if (not output_html and transform_state.transform_stack and transform_state.transform_stack[-1].endswith("<li>")): token_parts.append(ParserHelper.newline_character) else: previous_token = transform_state.actual_tokens[ transform_state.actual_token_index - 1] POGGER.debug(">previous_token>$>", previous_token) token_parts.append(output_html) if (not previous_token.is_list_end and previous_token.is_paragraph_end and not transform_state.is_in_loose_list or previous_token.is_list_end): token_parts.append(ParserHelper.newline_character) return "".join(token_parts)
def __handle_start_fenced_code_block_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the start fenced code block token. """ start_fence_token = cast(FencedCodeBlockMarkdownToken, next_token) token_parts = [output_html] if (output_html.endswith("</ol>") or output_html.endswith("</ul>") ) or (output_html and output_html[-1] != ParserHelper.newline_character): token_parts.append(ParserHelper.newline_character) transform_state.is_in_code_block, transform_state.is_in_fenced_code_block = ( True, True, ) token_parts.append("<pre><code") if start_fence_token.extracted_text: token_parts.extend( [' class="language-', start_fence_token.extracted_text, '"']) token_parts.append(">") return "".join(token_parts)
def __handle_start_indented_code_block_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the start indented code block token. """ _ = next_token token_parts = [] if (not output_html and transform_state.transform_stack and transform_state.transform_stack[-1].endswith("<li>")): token_parts.append(ParserHelper.newline_character) elif output_html and output_html[-1] != ParserHelper.newline_character: token_parts.extend([output_html, ParserHelper.newline_character]) else: token_parts.append(output_html) transform_state.is_in_code_block, transform_state.is_in_fenced_code_block = ( True, False, ) token_parts.append("<pre><code>") return "".join(token_parts)
def __handle_end_list_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the end list token for either an ordered or unordered list. """ transform_state.is_in_loose_list = ( TransformToGfmListLooseness.reset_list_looseness( transform_state.actual_tokens, transform_state.actual_token_index, )) transform_state.add_trailing_text = "".join([ "</li>", ParserHelper.newline_character, "</ul>" if next_token.is_unordered_list_end else "</ol>", ]) return output_html
def __handle_end_fenced_code_block_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the end fenced code block token. """ end_token = cast(EndMarkdownToken, next_token) fenced_token_index = transform_state.actual_token_index - 1 while not transform_state.actual_tokens[ fenced_token_index].is_fenced_code_block: fenced_token_index -= 1 fenced_token = cast( FencedCodeBlockMarkdownToken, transform_state.actual_tokens[fenced_token_index], ) inner_tag_parts = ["<code"] if fenced_token.extracted_text: inner_tag_parts.extend([ ' class="language-', fenced_token.extracted_text, '"', ]) inner_tag_parts.append(">") inner_tag = "".join(inner_tag_parts) POGGER.debug(f"inner_tag>>:{inner_tag}:<<") POGGER.debug(f"output_html>>:{output_html}:<<") POGGER.debug( f"last_token>>:{transform_state.actual_tokens[transform_state.actual_token_index - 1]}:<<" ) token_parts = [output_html] if (not output_html.endswith(inner_tag) and output_html[-1] != ParserHelper.newline_character): token_parts.append(ParserHelper.newline_character) POGGER.debug("#1") elif (output_html[-1] == ParserHelper.newline_character and transform_state.last_token and transform_state.last_token.is_text): POGGER.debug("#2:$", transform_state.last_token) text_token = cast(TextMarkdownToken, transform_state.last_token) if not (end_token.was_forced and text_token.token_text.endswith("\n\x03")): token_parts.append(ParserHelper.newline_character) transform_state.is_in_code_block, transform_state.is_in_fenced_code_block = ( False, False, ) token_parts.extend(["</code></pre>", ParserHelper.newline_character]) return "".join(token_parts)
def transform(self, actual_tokens: List[MarkdownToken]) -> str: """ Transform the tokens into html. """ POGGER.debug("\n\n---\n") transform_state, output_html, actual_tokens_size = ( TransformState(actual_tokens), "", len(actual_tokens), ) # This is the easiest way to finish covering the missing items. assert transform_state.next_token is None assert not transform_state.is_in_fenced_code_block for next_token in transform_state.actual_tokens: output_html = self.__apply_transformation( transform_state, actual_tokens, actual_tokens_size, next_token, output_html, ) POGGER.debug("======") POGGER.debug( "add_trailing_text-->$<--", transform_state.add_trailing_text, ) POGGER.debug("add_leading_text -->$<--", transform_state.add_leading_text) POGGER.debug("output_html -->$<--", output_html) if transform_state.add_trailing_text: output_html = self.__apply_trailing_text( output_html, transform_state) if transform_state.add_leading_text: output_html = self.__apply_leading_text( output_html, transform_state) POGGER.debug("------") POGGER.debug("next_token -->$<--", next_token) POGGER.debug("output_html -->$<--", output_html) POGGER.debug("transform_stack-->$<--", transform_state.transform_stack) transform_state.last_token = next_token transform_state.actual_token_index += 1 if output_html and output_html[-1] == ParserHelper.newline_character: output_html = output_html[:-1] POGGER.debug("output_html -->$<--", output_html) return output_html
def __handle_end_html_block_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the end html block token. """ _ = next_token transform_state.is_in_html_block = False return output_html
def __handle_start_block_quote_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the start block quote token. """ _ = next_token token_parts = [output_html] if output_html and output_html[-1] != ParserHelper.newline_character: token_parts.append(ParserHelper.newline_character) transform_state.is_in_loose_list = True token_parts.extend(["<blockquote>", ParserHelper.newline_character]) return "".join(token_parts)
def __handle_end_indented_code_block_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the end indented code block token. """ _ = next_token transform_state.is_in_code_block = False return "".join([ output_html, ParserHelper.newline_character, "</code></pre>", ParserHelper.newline_character, ])
def __handle_new_list_item_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the new list item token. """ _ = next_token transform_state.add_trailing_text, transform_state.add_leading_text = ( "</li>", "<li>", ) token_parts = [output_html] if output_html and output_html[-1] == ">": token_parts.append(ParserHelper.newline_character) return "".join(token_parts)
def __handle_end_block_quote_token( cls, output_html: str, next_token: MarkdownToken, transform_state: TransformState, ) -> str: """ Handle the end block quote token. """ _ = next_token token_parts = [output_html] if output_html[-1] != ParserHelper.newline_character: token_parts.append(ParserHelper.newline_character) transform_state.is_in_loose_list = ( TransformToGfmListLooseness.reset_list_looseness( transform_state.actual_tokens, transform_state.actual_token_index, )) token_parts.extend(["</blockquote>", ParserHelper.newline_character]) return "".join(token_parts)