Source code for pytexmd.filter.enumitem

__all__ = ["Itemize","ItemizeItem","Enumeration","EnumerationItem"]

from .core import *
from .splitting import * 



#enum_styles = {"\\roman":enum_style_roman,"\\Roman":enum_style_Roman,"\\arabic":enum_style_arabic,"\\alph":enum_style_alph,"\\Alph":enum_style_Alph}


[docs] class ItemizeItem(Element): """ Represents an item in a LaTeX itemize environment. Example: >>> item = ItemizeItem("First item", None) >>> print(item.to_string()) • First item """ def __init__(self, modifiable_content: str, parent: Element, enum_item: str = "*"): super().__init__("",parent) self.enum_item = enum_item self.children = [Undefined(self.enum_item,self),Undefined(modifiable_content,self)]
[docs] def label_name(self) -> str: """ Returns the label of the item. Returns: str: The label. Example: >>> item = ItemizeItem("abc", None) >>> item.label_name() '•' """ return self.enum_item#self.children[0].to_string()
[docs] def to_string(self) -> str: """ Converts the item to a formatted string. Returns: str: The formatted item string. Example: >>> item = ItemizeItem("abc", None) >>> isinstance(item.to_string(), str) True """ #string_len = len(self.children[0].to_string()) + 2 out = self.children[0].to_string()+" " tmp = self.children[1].to_string().lstrip().rstrip() for i, line in enumerate(tmp.split("\n")): if i==0: out += line.strip() + "\n" else: out += " " + line.strip() + "\n" out = out.rstrip() return out
[docs] @staticmethod def position(string: str) -> int: """ Finds the position of '\\item' in the string. Args: string (str): The input string. Returns: int: The position index. Example: >>> ItemizeItem.position("\\item abc") 0 """ return position_of(string,"\\item")
[docs] @staticmethod def split_and_create(string: str, parent: Element) -> tuple: """ Splits the string on '\\item' and creates an ItemizeItem. Args: string (str): The input string. parent (Element): The parent element. Returns: tuple: (pre, ItemizeItem, post) Example: >>> pre, item, post = ItemizeItem.split_and_create("\\item abc", None) >>> isinstance(item, ItemizeItem) True """ pre,content = split_on_next(string,"\\item") if "\\item" in content: content,post = split_on_next(content,"\\item") post = "\\item" + post else: post = "" enum_item = "" if first_char_brace(content,"["): enum_item,content = split_on_first_brace(content,"[","]") elem_out = ItemizeItem(content,parent,enum_item) return pre,elem_out,post
[docs] class Itemize(Element): """ Represents a LaTeX itemize environment. Example: >>> itemize = Itemize("content", None) >>> isinstance(itemize.to_string(), str) True """ current_index = 0 def __init__(self, modifiable_content: str, parent: Element): """ Args: modifiable_content (str): The content of the itemize. parent (Element): The parent element. Example: >>> itemize = Itemize("abc", None) >>> isinstance(itemize, Itemize) True """ super().__init__(modifiable_content,parent)
[docs] def to_string(self) -> str: """ Converts the itemize to a formatted string. Returns: str: The formatted itemize string. Example: >>> itemize = Itemize("abc", None) >>> isinstance(itemize.to_string(), str) True """ out = "\n" for child in self.children: out += child.to_string().rstrip().lstrip() + "\n" return out
[docs] @staticmethod def position(string: str) -> int: """ Finds the position of '\\begin{itemize}' in the string. Args: string (str): The input string. Returns: int: The position index. Example: >>> Itemize.position("\\begin{itemize}abc") 0 """ return position_of(string,"\\begin{itemize}")
[docs] @staticmethod def split_and_create(string: str, parent: Element) -> tuple: """ Splits the string on itemize environment and creates an Itemize. Args: string (str): The input string. parent (Element): The parent element. Returns: tuple: (pre, Itemize, post) Example: >>> pre, itemize, post = Itemize.split_and_create("\\begin{itemize}abc\\end{itemize}", None) >>> isinstance(itemize, Itemize) True """ pre,content,post = begin_end_split(string,"\\begin{itemize}","\\end{itemize}") elem_out = Itemize(content,parent) elem_out.expand([ItemizeItem]) return pre,elem_out,post
def parse_label_pattern(pattern: str, counter_value: int) -> str: """ Parses LaTeX label patterns and converts them to formatted strings. Args: pattern (str): LaTeX label pattern like '\textup{({\sffamily SF\arabic*})}' counter_value (int): Current counter value Returns: str: Formatted label string Example: >>> parse_label_pattern('\\textup{({\\sffamily SF\\arabic*})}', 1) 'SF1' """ result = pattern # Remove common LaTeX formatting commands formatting_commands = [ '\\sffamily', '\\bfseries', '\\itshape', '\\rmfamily', '\\small', '\\large', '\\Large', '\\LARGE', '\\huge', '\\Huge', '\\textup', '\\textbf', '\\textit', '\\textrm', '\\textsf', '\\texttt' ] for cmd in formatting_commands: result = result.replace(cmd, '') result = result.replace('{', '').replace('}', '') counter_patterns = { '\\arabic*': str(counter_value), '\\roman*': to_roman_lower(counter_value), '\\Roman*': to_roman_upper(counter_value), '\\alph*': to_alpha_lower(counter_value), '\\Alph*': to_alpha_upper(counter_value) } for pattern_key, replacement in counter_patterns.items(): result = result.replace(pattern_key, replacement) return result.strip() def to_roman_lower(num: int) -> str: """Convert integer to lowercase Roman numeral.""" values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] symbols = ['m', 'cm', 'd', 'cd', 'c', 'xc', 'l', 'xl', 'x', 'ix', 'v', 'iv', 'i'] result = '' for i in range(len(values)): count = num // values[i] result += symbols[i] * count num -= values[i] * count return result def to_roman_upper(num: int) -> str: """Convert integer to uppercase Roman numeral.""" return to_roman_lower(num).upper() def to_alpha_lower(num: int) -> str: """Convert integer to lowercase letter (1=a, 2=b, etc.).""" if num <= 0 or num > 26: return str(num) return chr(ord('a') + num - 1) def to_alpha_upper(num: int) -> str: """Convert integer to uppercase letter (1=A, 2=B, etc.).""" return to_alpha_lower(num).upper()
[docs] class EnumerationItem(Element): """ Represents an item in a LaTeX enumerate environment. Example: >>> enum_item = EnumerationItem("First", None) >>> isinstance(enum_item.to_string(), str) True """ def __init__(self, modifiable_content: str, parent: Element, enum_item: str = None): """ Args: modifiable_content (str): The content of the item. parent (Element): The parent element. enum_item (str, optional): The label for the item. Example: >>> enum_item = EnumerationItem("abc", None) >>> enum_item.label '' """ super().__init__("",parent) modifiable_content = modifiable_content.lstrip().rstrip() self.enum_item = "" if enum_item is None: enumeration: Enumeration = self.search_class(Enumeration) self.enum_item = enumeration.generate_enum_item() else: self.enum_item = enum_item self.label = None if modifiable_content.startswith("\\label"): label,modifiable_content = split_on_first_brace(modifiable_content[len("\\label"):],"{" ,"}") self.label = label_call(label,LabelType.ENUMERATION_ITEM) self.children = [Undefined(self.enum_item.strip(), self), Undefined(modifiable_content, self)]
[docs] def to_string(self) -> str: out = "\n\n" if self.label is not None: out += "(" + self.label + ")=\n" out += self.children[0].to_string().strip()+"\n: " tmp = self.children[1].to_string().strip() for i, line in enumerate(tmp.split("\n")): if i==0: out += line.strip() + "\n" else: out += " " + line.strip() + "\n" out = out.rstrip() return out
[docs] @staticmethod def position(string: str) -> int: """ Finds the position of '\\item' in the string. Args: string (str): The input string. Returns: int: The position index. Example: >>> EnumerationItem.position("\\item abc") 0 """ return position_of(string,"\\item")
[docs] @staticmethod def split_and_create(string: str, parent: Element) -> tuple: """ Splits the string on '\\item' and creates an EnumerationItem. Args: string (str): The input string. parent (Element): The parent element. Returns: tuple: (pre, EnumerationItem, post) Example: >>> pre, enum_item, post = EnumerationItem.split_and_create("\\item abc", None) >>> isinstance(enum_item, EnumerationItem) True """ pre,content = split_on_next(string,"\\item") if "\\item" in content: content,post = split_on_next(content,"\\item") post = "\\item" + post else: post = "" content = content.lstrip() enum_item = None if first_char_brace(content,"["): enum_item,content = split_on_first_brace(content,"[","]") elem_out = EnumerationItem(content,parent,enum_item) return pre,elem_out,post
[docs] class Enumeration(Element): """ Represents a LaTeX enumerate environment. Example: >>> enum = Enumeration("content", None, enum_style_arabic, "(", ")") >>> isinstance(enum.to_string(), str) True """ def __init__(self, modifiable_content: str, parent: Element,start,label_part): """ Example: >>> enum = Enumeration("abc", None, enum_style_arabic, "(", ")") >>> isinstance(enum, Enumeration) True """ super().__init__(modifiable_content,parent) self.current_index = start self.label_part = label_part
[docs] def generate_enum_item(self) -> str: if self.label_part is not None: out = parse_label_pattern(self.label_part,self.current_index) self.current_index += 1 return out out = str(self.current_index) + "." self.current_index += 1 return out
[docs] def to_string(self) -> str: """ Converts the enumerate to a formatted string. Returns: str: The formatted enumerate string. Example: >>> enum = Enumeration("abc", None, enum_style_arabic, "(", ")") >>> isinstance(enum.to_string(), str) True """ out = "\n" for child in self.children: out += child.to_string().rstrip().lstrip() + "\n" return out
[docs] @staticmethod def position(string: str) -> int: """ Finds the position of '\\begin{enumerate}' in the string. Args: string (str): The input string. Returns: int: The position index. Example: >>> Enumeration.position("\\begin{enumerate}abc") 0 """ return position_of(string,"\\begin{enumerate}")
[docs] @staticmethod def split_and_create(string: str, parent: Element) -> tuple: """ Splits the string on enumerate environment and creates an Enumeration. Args: string (str): The input string. parent (Element): The parent element. Returns: tuple: (pre, Enumeration, post) Example: >>> pre, enum, post = Enumeration.split_and_create("\\begin{enumerate}abc\\end{enumerate}", None) >>> isinstance(enum, Enumeration) True """ pre,content,post = begin_end_split(string,"\\begin{enumerate}","\\end{enumerate}") content = content.lstrip().rstrip() start = 1 label_part = None if content.startswith("["): _pre,_content,_post = begin_end_split(content,"[","]") content = _post.lstrip().rstrip() if "label" in _content: label_part = _content.split("label")[1].split("=")[1].strip().split(",")[0].strip() # Here you could implement parsing of label_str to set style_func, left, right if "start" in _content: start_str = _content.split("start")[1].split("=")[1].strip().split(",")[0].strip() try: start = int(start_str) except: start = 1 elem_out = Enumeration(content,parent,start,label_part) elem_out.expand([EnumerationItem]) return pre,elem_out,post
def get_all_filters(): """ Returns all filter classes for enum environments. Returns: list: List of filter classes. Example: >>> filters = get_all_filters() >>> isinstance(filters, list) True """ return [Itemize, Enumeration]