173 lines
6.8 KiB
Python
173 lines
6.8 KiB
Python
import re
|
|
import ast
|
|
|
|
|
|
def clean_tables(text):
|
|
def replace_colon(text):
|
|
# Define a function to use in re.sub to check the context of the match
|
|
def replacer(match):
|
|
# Extract the character after ':' to check if it's '['
|
|
following_text = match.group(1)
|
|
if following_text.strip().startswith("["):
|
|
return match.group(
|
|
0
|
|
) # Return the original match (':' and whatever follows)
|
|
else:
|
|
return "" + match.group(1) # Replace ':' with ';' and return the rest
|
|
|
|
# Use a regular expression to find ':' and the text that follows
|
|
pattern = r":(\s*.)"
|
|
replaced_text = re.sub(pattern, replacer, text)
|
|
return replaced_text
|
|
|
|
def remove_unquoted_brackets(text):
|
|
# Define a function to check the content between brackets
|
|
def replacer(match):
|
|
content = match.group(1)
|
|
if "'" not in content and (len(content) > 0):
|
|
return content # Return just the content without brackets
|
|
else:
|
|
return match.group(
|
|
0
|
|
) # Return the original match if it contains a quote
|
|
|
|
# Use a regular expression to find brackets and the text within
|
|
pattern = r"\[([^\[\]]*?)\]"
|
|
cleaned_text = re.sub(pattern, replacer, text)
|
|
return cleaned_text
|
|
|
|
# Clean tables
|
|
text = text.strip("{}") # Remove brackets
|
|
text = replace_colon(text)
|
|
text = remove_unquoted_brackets(text)
|
|
return text
|
|
|
|
|
|
def convert_to_dict(table_text):
|
|
"""
|
|
Converts a formatted table text into a dictionary where each key maps to a list of values.
|
|
|
|
This function processes a string representation of a table, extracting key-value pairs and converting them into a dictionary.
|
|
Each key maps to a list of values parsed from the input string. The function also returns the number of elements in each list.
|
|
|
|
Parameters:
|
|
table_text (str): The input string representing the table, formatted with keys and values.
|
|
|
|
Returns:
|
|
tuple: A dictionary with keys mapping to lists of values, and an integer representing the number of elements in each list.
|
|
"""
|
|
table_text = clean_tables(table_text)
|
|
# print(table_text, '\n')
|
|
table_text_list = table_text.split("]")
|
|
table_text_list = [item for item in table_text_list if len(item) > 0]
|
|
|
|
final_dict = {}
|
|
num_elements = 0
|
|
for key_value_text in table_text_list:
|
|
key = key_value_text.split(":")[0].strip(", '")
|
|
try:
|
|
value = ":".join(key_value_text.split(":")[1:]).strip() + "]"
|
|
# print(value, '\n')
|
|
if len(value) > 1:
|
|
value_list = ast.literal_eval(value)
|
|
final_dict[key] = value_list
|
|
num_elements = len(value_list)
|
|
except:
|
|
value = ":".join(key_value_text.split(":")[1:]).strip() + "']"
|
|
# print(value, '\n')
|
|
if len(value) > 1:
|
|
value_list = ast.literal_eval(value)
|
|
final_dict[key] = value_list
|
|
num_elements = len(value_list)
|
|
|
|
return final_dict, num_elements
|
|
|
|
|
|
def format_table(table_json, table_size):
|
|
"""
|
|
Formats a dictionary of table data into a string representation of the table.
|
|
|
|
This function takes a dictionary where each key maps to a list of values and converts it into a formatted string.
|
|
The keys are used as headers, and each row is constructed by iterating through the lists up to the specified table size.
|
|
The resulting string separates headers and values with ' : ' and includes newline characters to delineate rows.
|
|
|
|
Parameters:
|
|
table_json (dict): The dictionary containing the table data, with keys as column headers and lists as column values.
|
|
table_size (int): The number of rows in the table.
|
|
|
|
Returns:
|
|
str: The formatted string representation of the table.
|
|
"""
|
|
table_text = ""
|
|
keys = [key for key in table_json.keys()]
|
|
table_text += " : ".join(keys) + "\n"
|
|
for i in range(table_size):
|
|
for key in keys:
|
|
if table_json[key][i]:
|
|
# table_text += key + ': ' + table_json[key][i] + ', '
|
|
table_text += table_json[key][i] + " : "
|
|
table_text += r"\n"
|
|
return table_text
|
|
|
|
|
|
def align_and_format_tables(text_dict):
|
|
"""
|
|
Aligns and formats tables within the text of each page in a dictionary.
|
|
|
|
This function searches for table text within the input text of each page, marked by 'Table Start' and 'Table End' tags.
|
|
It extracts, converts, and formats these tables, then replaces the original table text with the formatted version while
|
|
maintaining the alignment with surrounding text. The cleaned and formatted text for each page is then stored in a new dictionary.
|
|
|
|
Parameters:
|
|
text_dict (dict): A dictionary where keys are page numbers and values are the text content of those pages, potentially containing tables.
|
|
|
|
Returns:
|
|
dict: A new dictionary with aligned and formatted tables in the text for each page.
|
|
"""
|
|
aligned_text_dict = {}
|
|
for key, text in text_dict.items():
|
|
aligned_text = text
|
|
if "Table Start" in text:
|
|
table_texts = re.findall(
|
|
r"-------Table Start--------(.*?)-------Table End--------",
|
|
text,
|
|
re.DOTALL,
|
|
)
|
|
for table_text in table_texts:
|
|
# print(table_text, '\n')
|
|
|
|
try:
|
|
# Extract pretable text
|
|
pretable = table_text.split("{")[0].strip()
|
|
# Extract and format table text
|
|
# table_only = "{" + table_text.split('{', 1)[1].rsplit('}', 1)[0].replace("'", '"') + "}"
|
|
table_only = (
|
|
"{" + table_text.split("{", 1)[1].rsplit("}", 1)[0] + "}"
|
|
)
|
|
|
|
table, table_size = convert_to_dict(table_only)
|
|
table_formatted = format_table(table, table_size)
|
|
except:
|
|
table_formatted = table_text
|
|
|
|
# Align
|
|
if text.count(pretable) == 2: # One table
|
|
# Remove original table
|
|
aligned_text = text.replace(table_text, "")
|
|
# Align new table
|
|
aligned_text = aligned_text.replace(
|
|
pretable, pretable + table_formatted
|
|
)
|
|
|
|
else:
|
|
aligned_text = aligned_text.replace(
|
|
table_text, pretable + " " + table_formatted
|
|
)
|
|
aligned_text_dict[key] = aligned_text.replace(
|
|
"-------Table Start--------", ""
|
|
).replace("-------Table End--------", "")
|
|
else:
|
|
aligned_text_dict[key] = text
|
|
|
|
return aligned_text_dict
|