Spaces:
Runtime error
Runtime error
Commit ·
92b8dbd
1
Parent(s): 88a3921
Double Spacing
Browse files
app/DocumentGeneration/grouped.py
CHANGED
|
@@ -103,6 +103,9 @@ def clean_markdown_from_line(line: str) -> str:
|
|
| 103 |
# Remove any remaining HTML-like tags
|
| 104 |
cleaned = re.sub(r'<[^>]+>', '', cleaned)
|
| 105 |
|
|
|
|
|
|
|
|
|
|
| 106 |
return cleaned.strip()
|
| 107 |
|
| 108 |
def parse_content_into_groups(content: str) -> List[Dict[str, Any]]:
|
|
|
|
| 103 |
# Remove any remaining HTML-like tags
|
| 104 |
cleaned = re.sub(r'<[^>]+>', '', cleaned)
|
| 105 |
|
| 106 |
+
# CRITICAL FIX: Replace multiple spaces with single space to prevent double spaces
|
| 107 |
+
cleaned = re.sub(r' +', ' ', cleaned) # Replace multiple spaces with single space
|
| 108 |
+
|
| 109 |
return cleaned.strip()
|
| 110 |
|
| 111 |
def parse_content_into_groups(content: str) -> List[Dict[str, Any]]:
|
app/DocumentGeneration/markdown_renderer.py
CHANGED
|
@@ -104,6 +104,9 @@ def clean_text_for_pdf(text: str) -> str:
|
|
| 104 |
for unicode_char, replacement in unicode_replacements.items():
|
| 105 |
cleaned = cleaned.replace(unicode_char, replacement)
|
| 106 |
|
|
|
|
|
|
|
|
|
|
| 107 |
return cleaned
|
| 108 |
|
| 109 |
def process_content_with_inline_charts(doc, content: str, business_idea: str):
|
|
@@ -310,7 +313,7 @@ def render_markdown_to_pdf(pdf, content: str, primary_color, accent_color, text_
|
|
| 310 |
pdf.set_font("Arial", "", 12) # Regular font, size 12
|
| 311 |
pdf.set_text_color(*text_color) # Dark gray
|
| 312 |
pdf.set_xy(25, current_y)
|
| 313 |
-
pdf.multi_cell(160, 8, line)
|
| 314 |
current_y = pdf.get_y()
|
| 315 |
|
| 316 |
|
|
@@ -466,14 +469,14 @@ def render_markdown_to_pdf_grouped(pdf, content: str, primary_color, accent_colo
|
|
| 466 |
pdf.set_font("Arial", "", 12) # Regular
|
| 467 |
pdf.set_text_color(*text_color)
|
| 468 |
pdf.set_xy(25, current_y)
|
| 469 |
-
pdf.multi_cell(160, 8, content)
|
| 470 |
current_y = pdf.get_y()
|
| 471 |
else:
|
| 472 |
# No content after ":", just render the whole line
|
| 473 |
pdf.set_font("Arial", "B", 12) # Bold for labels ending with ":"
|
| 474 |
pdf.set_text_color(*text_color)
|
| 475 |
pdf.set_xy(25, current_y)
|
| 476 |
-
pdf.multi_cell(160, 8, line)
|
| 477 |
current_y = pdf.get_y()
|
| 478 |
elif ' - ' in line:
|
| 479 |
# Split the line by " - " to separate the label from the content
|
|
@@ -494,21 +497,21 @@ def render_markdown_to_pdf_grouped(pdf, content: str, primary_color, accent_colo
|
|
| 494 |
pdf.set_font("Arial", "", 12) # Regular
|
| 495 |
pdf.set_text_color(*text_color)
|
| 496 |
pdf.set_xy(25, current_y)
|
| 497 |
-
pdf.multi_cell(160, 8, content)
|
| 498 |
current_y = pdf.get_y()
|
| 499 |
else:
|
| 500 |
# No content after " - ", just render the whole line
|
| 501 |
pdf.set_font("Arial", "B", 12) # Bold for labels ending with " -"
|
| 502 |
pdf.set_text_color(*text_color)
|
| 503 |
pdf.set_xy(25, current_y)
|
| 504 |
-
pdf.multi_cell(160, 8, line)
|
| 505 |
current_y = pdf.get_y()
|
| 506 |
else:
|
| 507 |
# Regular paragraph rendering without mixed text processing
|
| 508 |
pdf.set_font("Arial", "", 12)
|
| 509 |
pdf.set_text_color(*text_color)
|
| 510 |
pdf.set_xy(25, current_y)
|
| 511 |
-
pdf.multi_cell(160, 8, line)
|
| 512 |
current_y = pdf.get_y() # Update current_y after each line
|
| 513 |
else:
|
| 514 |
# Empty line spacing
|
|
|
|
| 104 |
for unicode_char, replacement in unicode_replacements.items():
|
| 105 |
cleaned = cleaned.replace(unicode_char, replacement)
|
| 106 |
|
| 107 |
+
# Additional space normalization after Unicode replacements to prevent double spaces
|
| 108 |
+
cleaned = re.sub(r' +', ' ', cleaned) # Replace multiple spaces with single space
|
| 109 |
+
|
| 110 |
return cleaned
|
| 111 |
|
| 112 |
def process_content_with_inline_charts(doc, content: str, business_idea: str):
|
|
|
|
| 313 |
pdf.set_font("Arial", "", 12) # Regular font, size 12
|
| 314 |
pdf.set_text_color(*text_color) # Dark gray
|
| 315 |
pdf.set_xy(25, current_y)
|
| 316 |
+
pdf.multi_cell(160, 8, line, align='L') # Left align to prevent text justification
|
| 317 |
current_y = pdf.get_y()
|
| 318 |
|
| 319 |
|
|
|
|
| 469 |
pdf.set_font("Arial", "", 12) # Regular
|
| 470 |
pdf.set_text_color(*text_color)
|
| 471 |
pdf.set_xy(25, current_y)
|
| 472 |
+
pdf.multi_cell(160, 8, content, align='L') # Left align to prevent text justification
|
| 473 |
current_y = pdf.get_y()
|
| 474 |
else:
|
| 475 |
# No content after ":", just render the whole line
|
| 476 |
pdf.set_font("Arial", "B", 12) # Bold for labels ending with ":"
|
| 477 |
pdf.set_text_color(*text_color)
|
| 478 |
pdf.set_xy(25, current_y)
|
| 479 |
+
pdf.multi_cell(160, 8, line, align='L') # Left align to prevent text justification
|
| 480 |
current_y = pdf.get_y()
|
| 481 |
elif ' - ' in line:
|
| 482 |
# Split the line by " - " to separate the label from the content
|
|
|
|
| 497 |
pdf.set_font("Arial", "", 12) # Regular
|
| 498 |
pdf.set_text_color(*text_color)
|
| 499 |
pdf.set_xy(25, current_y)
|
| 500 |
+
pdf.multi_cell(160, 8, content, align='L') # Left align to prevent text justification
|
| 501 |
current_y = pdf.get_y()
|
| 502 |
else:
|
| 503 |
# No content after " - ", just render the whole line
|
| 504 |
pdf.set_font("Arial", "B", 12) # Bold for labels ending with " -"
|
| 505 |
pdf.set_text_color(*text_color)
|
| 506 |
pdf.set_xy(25, current_y)
|
| 507 |
+
pdf.multi_cell(160, 8, line, align='L') # Left align to prevent text justification
|
| 508 |
current_y = pdf.get_y()
|
| 509 |
else:
|
| 510 |
# Regular paragraph rendering without mixed text processing
|
| 511 |
pdf.set_font("Arial", "", 12)
|
| 512 |
pdf.set_text_color(*text_color)
|
| 513 |
pdf.set_xy(25, current_y)
|
| 514 |
+
pdf.multi_cell(160, 8, line, align='L') # Left align to prevent text justification
|
| 515 |
current_y = pdf.get_y() # Update current_y after each line
|
| 516 |
else:
|
| 517 |
# Empty line spacing
|
app/DocumentGeneration/pdf_generator.py
CHANGED
|
@@ -302,7 +302,7 @@ def create_pdf_document(request: ExportRequest):
|
|
| 302 |
pdf.set_font("Arial", "", 12)
|
| 303 |
pdf.set_text_color(*text_color)
|
| 304 |
pdf.set_xy(25, y_offset)
|
| 305 |
-
pdf.multi_cell(160, 8, text)
|
| 306 |
return pdf.get_y()
|
| 307 |
|
| 308 |
def check_page_break(pdf, required_height=120, bottom_margin=300):
|
|
@@ -538,7 +538,7 @@ def create_pdf_document(request: ExportRequest):
|
|
| 538 |
render_markdown_to_pdf_grouped(pdf, content_text, primary_color, accent_color, text_color)
|
| 539 |
else:
|
| 540 |
# Add placeholder text to prevent blank page
|
| 541 |
-
pdf.multi_cell(160, 8, f"Content for {section.title} section is being processed...")
|
| 542 |
|
| 543 |
# Add minimal spacer only if we have content
|
| 544 |
if content_text and content_text.strip():
|
|
@@ -696,7 +696,7 @@ def create_pdf_document(request: ExportRequest):
|
|
| 696 |
pdf.set_font("Arial", "", 12)
|
| 697 |
pdf.set_text_color(51, 51, 51)
|
| 698 |
pdf.set_xy(25, 50)
|
| 699 |
-
pdf.multi_cell(160, 8, "No sections available for table of contents.")
|
| 700 |
except Exception as e:
|
| 701 |
# logging.error(f"Table of contents failed: {str(e)}")
|
| 702 |
pass
|
|
@@ -709,7 +709,7 @@ def create_pdf_document(request: ExportRequest):
|
|
| 709 |
pdf.set_font("Arial", "", 12)
|
| 710 |
pdf.set_text_color(51, 51, 51)
|
| 711 |
pdf.set_xy(25, 50)
|
| 712 |
-
pdf.multi_cell(160, 8, "Table of contents could not be generated.")
|
| 713 |
|
| 714 |
# Executive summary is now handled as part of the sections
|
| 715 |
# No separate page needed - the first section contains the executive summary
|
|
|
|
| 302 |
pdf.set_font("Arial", "", 12)
|
| 303 |
pdf.set_text_color(*text_color)
|
| 304 |
pdf.set_xy(25, y_offset)
|
| 305 |
+
pdf.multi_cell(160, 8, text, align='L') # Left align to prevent text justification
|
| 306 |
return pdf.get_y()
|
| 307 |
|
| 308 |
def check_page_break(pdf, required_height=120, bottom_margin=300):
|
|
|
|
| 538 |
render_markdown_to_pdf_grouped(pdf, content_text, primary_color, accent_color, text_color)
|
| 539 |
else:
|
| 540 |
# Add placeholder text to prevent blank page
|
| 541 |
+
pdf.multi_cell(160, 8, f"Content for {section.title} section is being processed...", align='L')
|
| 542 |
|
| 543 |
# Add minimal spacer only if we have content
|
| 544 |
if content_text and content_text.strip():
|
|
|
|
| 696 |
pdf.set_font("Arial", "", 12)
|
| 697 |
pdf.set_text_color(51, 51, 51)
|
| 698 |
pdf.set_xy(25, 50)
|
| 699 |
+
pdf.multi_cell(160, 8, "No sections available for table of contents.", align='L')
|
| 700 |
except Exception as e:
|
| 701 |
# logging.error(f"Table of contents failed: {str(e)}")
|
| 702 |
pass
|
|
|
|
| 709 |
pdf.set_font("Arial", "", 12)
|
| 710 |
pdf.set_text_color(51, 51, 51)
|
| 711 |
pdf.set_xy(25, 50)
|
| 712 |
+
pdf.multi_cell(160, 8, "Table of contents could not be generated.", align='L')
|
| 713 |
|
| 714 |
# Executive summary is now handled as part of the sections
|
| 715 |
# No separate page needed - the first section contains the executive summary
|