Source code for docx_parser_converter.docx_to_txt.converters.numbering_converter

from docx_parser_converter.docx_parsers.models.paragraph_models import Paragraph
from docx_parser_converter.docx_parsers.models.numbering_models import NumberingLevel


[docs] class NumberingConverter: """ Class to convert numbering to plain text. """ numbering_counters = {}
[docs] @staticmethod def convert_numbering(paragraph: Paragraph, numbering_schema) -> str: """ Convert numbering to plain text. Args: paragraph (Paragraph): The paragraph object. numbering_schema: The numbering schema. Returns: str: Plain text representation of the numbering. Example: .. code-block:: python paragraph = Paragraph( properties=properties, runs=runs, numbering=numbering ) numbering_text = NumberingConverter.convert_numbering(paragraph, numbering_schema) print(numbering_text) """ numbering = paragraph.numbering level_key = (numbering.numId, numbering.ilvl) try: numbering_level = NumberingConverter.get_numbering_level(numbering_schema, numbering.numId, numbering.ilvl) except ValueError as e: print(f"Warning: {e}") return "•" if numbering.numId not in NumberingConverter.numbering_counters: NumberingConverter.numbering_counters[numbering.numId] = [0] * 9 # Supports up to 9 levels NumberingConverter.numbering_counters[numbering.numId][numbering.ilvl] += 1 # Reset counters for deeper levels if a higher level is incremented for i in range(numbering.ilvl + 1, 9): NumberingConverter.numbering_counters[numbering.numId][i] = 0 counters = NumberingConverter.numbering_counters[numbering.numId][:numbering.ilvl + 1] formatted_counters = [NumberingConverter.format_number(counters[i], numbering_level.numFmt) for i in range(numbering.ilvl + 1)] # Replace all placeholders in lvlText lvlText = numbering_level.lvlText for i in range(1, numbering.ilvl + 2): lvlText = lvlText.replace(f"%{i}", formatted_counters[i-1]) return lvlText + " "
[docs] @staticmethod def get_numbering_level(numbering_schema, numId: int, ilvl: int) -> NumberingLevel: """ Get the numbering level from the numbering schema. Args: numbering_schema: The numbering schema. numId (int): The numbering ID. ilvl (int): The indent level. Returns: NumberingLevel: The corresponding numbering level. Raises: ValueError: If the numbering level is not found. Example: .. code-block:: python numbering_level = NumberingConverter.get_numbering_level(numbering_schema, numId, ilvl) """ instance = next((inst for inst in numbering_schema.instances if inst.numId == numId), None) if instance: level = next((lvl for lvl in instance.levels if lvl.ilvl == ilvl), None) if level: return level raise ValueError(f"Numbering level not found for numId: {numId}, ilvl: {ilvl}")
[docs] @staticmethod def format_number(counter: int, numFmt: str) -> str: """ Format the counter according to the specified numbering format. Args: counter (int): The counter value. numFmt (str): The numbering format. Returns: str: The formatted number. Example: .. code-block:: python formatted_number = NumberingConverter.format_number(1, 'decimal') print(formatted_number) # Output: '1' """ if numFmt == "decimal": return str(counter) elif numFmt == "lowerRoman": return NumberingConverter.to_roman(counter).lower() elif numFmt == "upperRoman": return NumberingConverter.to_roman(counter).upper() elif numFmt == "lowerLetter": return NumberingConverter.to_lower_letter(counter) elif numFmt == "upperLetter": return NumberingConverter.to_upper_letter(counter) elif numFmt == "bullet": return "•" return ""
[docs] @staticmethod def to_roman(num: int) -> str: """ Convert an integer to a Roman numeral. Args: num (int): The integer to convert. Returns: str: The Roman numeral representation. Example: .. code-block:: python roman_number = NumberingConverter.to_roman(5) print(roman_number) # Output: 'V' """ val = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] syb = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] roman_num = '' i = 0 while num > 0: for _ in range(num // val[i]): roman_num += syb[i] num -= val[i] i += 1 return roman_num
[docs] @staticmethod def to_upper_letter(num: int) -> str: """ Convert an integer to an uppercase letter (A-Z). Args: num (int): The integer to convert. Returns: str: The uppercase letter representation. Example: .. code-block:: python letter = NumberingConverter.to_upper_letter(1) print(letter) # Output: 'A' """ return chr(64 + num)
[docs] @staticmethod def to_lower_letter(num: int) -> str: """ Convert an integer to a lowercase letter (a-z). Args: num (int): The integer to convert. Returns: str: The lowercase letter representation. Example: .. code-block:: python letter = NumberingConverter.to_lower_letter(1) print(letter) # Output: 'a' """ return chr(96 + num)