Exemplo n.º 1
0
def bullet_list(node: "RenderTreeNode", context: "RenderContext") -> str:
    marker_type = get_list_marker_type(node)
    first_line_indent = " "
    indent = " " * len(marker_type + first_line_indent)
    block_separator = "\n" if is_tight_list(node) else "\n\n"

    context.env["indent_width"] += len(indent)

    text = ""
    for child_idx, child in enumerate(node.children):
        list_item = child.render(context)
        formatted_lines = []
        line_iterator = iter(list_item.split("\n"))
        first_line = next(line_iterator)
        formatted_lines.append(
            f"{marker_type}{first_line_indent}{first_line}"
            if first_line
            else marker_type
        )
        for line in line_iterator:
            formatted_lines.append(f"{indent}{line}" if line else "")

        text += "\n".join(formatted_lines)
        if child_idx != len(node.children) - 1:
            text += block_separator

    context.env["indent_width"] -= len(indent)
    return text
Exemplo n.º 2
0
def bullet_list(
    node: "RenderTreeNode",
    renderer_funcs: Mapping[str, RendererFunc],
    options: Mapping[str, Any],
    env: MutableMapping,
) -> str:
    marker_type = get_list_marker_type(node)
    first_line_indent = " "
    indent = " " * len(marker_type + first_line_indent)
    block_separator = "\n" if is_tight_list(node) else "\n\n"
    text = ""
    for child_idx, child in enumerate(node.children):
        list_item = child.render(renderer_funcs, options, env)
        lines = list_item.split("\n")
        formatted_lines = []
        for i, line in enumerate(lines):
            if i == 0:
                formatted_lines.append(
                    f"{marker_type}{first_line_indent}{line}"
                    if line else marker_type)
            else:
                formatted_lines.append(f"{indent}{line}" if line else "")

        text += "\n".join(formatted_lines)
        if child_idx != len(node.children) - 1:
            text += block_separator
    return text
Exemplo n.º 3
0
def ordered_list_close(text: str, tokens: Sequence[Token], idx: int,
                       options: Mapping[str, Any], env: dict) -> str:
    marker_type = get_list_marker_type(tokens, idx)
    first_line_indent = " "

    text = removesuffix(text, MARKERS.BLOCK_SEPARATOR)
    if is_tight_list(tokens, idx):
        text = text.replace(MARKERS.BLOCK_SEPARATOR, "\n")
    else:
        text = text.replace(MARKERS.BLOCK_SEPARATOR, "\n\n")

    opening_token = find_opening_token(tokens, idx)
    starting_number = opening_token.attrGet("start")
    if starting_number is None:
        starting_number = 1

    if options.get("mdformat", {}).get(CONSECUTIVE_KEY):
        # Replace MARKERS.LIST_ITEM with consecutive numbering,
        # padded with zeros to make all markers of even length.
        # E.g.
        #   002. This is the first list item
        #   003. Second item
        #   ...
        #   112. Last item
        pad = len(str(text.count(MARKERS.LIST_ITEM) + starting_number - 1))
        indentation = " " * (pad + len(f"{marker_type}{first_line_indent}"))
        while MARKERS.LIST_ITEM in text:
            number = str(starting_number).rjust(pad, "0")
            text = text.replace(MARKERS.LIST_ITEM, f"{number}{marker_type}", 1)
            starting_number += 1
    else:
        # Replace first MARKERS.LIST_ITEM with the starting number of the list.
        # Replace following MARKERS.LIST_ITEMs with number one prefixed by zeros
        # to make the marker of even length with the first one.
        # E.g.
        #   5321. This is the first list item
        #   0001. Second item
        #   0001. Third item
        first_item_marker = f"{starting_number}{marker_type}"
        other_item_marker = "0" * (len(str(starting_number)) -
                                   1) + "1" + marker_type
        indentation = " " * len(first_item_marker + first_line_indent)
        text = text.replace(MARKERS.LIST_ITEM, first_item_marker, 1)
        text = text.replace(MARKERS.LIST_ITEM, other_item_marker)

    text = text.replace(MARKERS.LIST_INDENT_FIRST_LINE, first_line_indent)
    text = text.replace(MARKERS.LIST_INDENT, indentation)

    return text + MARKERS.BLOCK_SEPARATOR
Exemplo n.º 4
0
def bullet_list_close(text: str, tokens: Sequence[Token], idx: int,
                      options: Mapping[str, Any], env: dict) -> str:
    text = removesuffix(text, MARKERS.BLOCK_SEPARATOR)
    if is_tight_list(tokens, idx):
        text = text.replace(MARKERS.BLOCK_SEPARATOR, "\n")
    else:
        text = text.replace(MARKERS.BLOCK_SEPARATOR, "\n\n")

    marker_type = get_list_marker_type(tokens, idx)
    first_line_indent = " "
    indent = " " * len(marker_type + first_line_indent)
    text = text.replace(MARKERS.LIST_ITEM, marker_type)
    text = text.replace(MARKERS.LIST_INDENT_FIRST_LINE, first_line_indent)
    text = text.replace(MARKERS.LIST_INDENT, indent)
    return text + MARKERS.BLOCK_SEPARATOR
Exemplo n.º 5
0
def ordered_list(node: "RenderTreeNode", context: "RenderContext") -> str:
    consecutive_numbering = context.options.get("mdformat", {}).get(CONSECUTIVE_KEY)
    marker_type = get_list_marker_type(node)
    first_line_indent = " "
    block_separator = "\n" if is_tight_list(node) else "\n\n"
    list_len = len(node.children)

    starting_number = node.attrs.get("start")
    if starting_number is None:
        starting_number = 1
    assert isinstance(starting_number, int)

    if consecutive_numbering:
        indent_width = len(
            f"{list_len + starting_number - 1}{marker_type}{first_line_indent}"
        )
    else:
        indent_width = len(f"{starting_number}{marker_type}{first_line_indent}")
    context.env["indent_width"] += indent_width

    text = ""
    for list_item_index, list_item in enumerate(node.children):
        list_item_text = list_item.render(context)
        formatted_lines = []
        line_iterator = iter(list_item_text.split("\n"))
        first_line = next(line_iterator)
        if consecutive_numbering:
            # Prefix first line of the list item with consecutive numbering,
            # padded with zeros to make all markers of even length.
            # E.g.
            #   002. This is the first list item
            #   003. Second item
            #   ...
            #   112. Last item
            number = starting_number + list_item_index
            pad = len(str(list_len + starting_number - 1))
            number_str = str(number).rjust(pad, "0")
            formatted_lines.append(
                f"{number_str}{marker_type}{first_line_indent}{first_line}"
                if first_line
                else f"{number_str}{marker_type}"
            )
        else:
            # Prefix first line of first item with the starting number of the
            # list. Prefix following list items with the number one
            # prefixed by zeros to make the list item marker of even length
            # with the first one.
            # E.g.
            #   5321. This is the first list item
            #   0001. Second item
            #   0001. Third item
            first_item_marker = f"{starting_number}{marker_type}"
            other_item_marker = (
                "0" * (len(str(starting_number)) - 1) + "1" + marker_type
            )
            if list_item_index == 0:
                formatted_lines.append(
                    f"{first_item_marker}{first_line_indent}{first_line}"
                    if first_line
                    else first_item_marker
                )
            else:
                formatted_lines.append(
                    f"{other_item_marker}{first_line_indent}{first_line}"
                    if first_line
                    else other_item_marker
                )
        for line in line_iterator:
            formatted_lines.append(" " * indent_width + line if line else "")

        text += "\n".join(formatted_lines)
        if list_item_index != len(node.children) - 1:
            text += block_separator

    context.env["indent_width"] -= indent_width
    return text
Exemplo n.º 6
0
def ordered_list(
    node: "RenderTreeNode",
    renderer_funcs: Mapping[str, RendererFunc],
    options: Mapping[str, Any],
    env: MutableMapping,
) -> str:
    marker_type = get_list_marker_type(node)
    first_line_indent = " "
    block_separator = "\n" if is_tight_list(node) else "\n\n"
    list_len = len(node.children)

    starting_number: Optional[int] = node.attrs.get("start")
    if starting_number is None:
        starting_number = 1

    text = ""
    for list_item_index, list_item in enumerate(node.children):
        list_item_text = list_item.render(renderer_funcs, options, env)
        lines = list_item_text.split("\n")
        formatted_lines = []
        conseucutive_numbering = options.get("mdformat",
                                             {}).get(CONSECUTIVE_KEY)
        for line_index, line in enumerate(lines):
            if line_index == 0:
                if conseucutive_numbering:
                    # Prefix first line of the list item with consecutive numbering,
                    # padded with zeros to make all markers of even length.
                    # E.g.
                    #   002. This is the first list item
                    #   003. Second item
                    #   ...
                    #   112. Last item
                    number = starting_number + list_item_index
                    pad = len(str(list_len + starting_number - 1))
                    indentation = " " * (
                        pad + len(f"{marker_type}{first_line_indent}"))
                    number_str = str(number).rjust(pad, "0")
                    formatted_lines.append(
                        f"{number_str}{marker_type}{first_line_indent}{line}"
                        if line else f"{number_str}{marker_type}")
                else:
                    # Prefix first line of first item with the starting number of the
                    # list. Prefix following list items with the number one
                    # prefixed by zeros to make the list item marker of even length
                    # with the first one.
                    # E.g.
                    #   5321. This is the first list item
                    #   0001. Second item
                    #   0001. Third item
                    first_item_marker = f"{starting_number}{marker_type}"
                    other_item_marker = ("0" *
                                         (len(str(starting_number)) - 1) +
                                         "1" + marker_type)
                    indentation = " " * len(first_item_marker +
                                            first_line_indent)
                    if list_item_index == 0:
                        formatted_lines.append(
                            f"{first_item_marker}{first_line_indent}{line}"
                            if line else first_item_marker)
                    else:
                        formatted_lines.append(
                            f"{other_item_marker}{first_line_indent}{line}"
                            if line else other_item_marker)
            else:
                formatted_lines.append(f"{indentation}{line}" if line else "")

        text += "\n".join(formatted_lines)
        if list_item_index != len(node.children) - 1:
            text += block_separator
    return text