Fix speaker ID regex and page break/line spacing in transcript DOCX
This commit is contained in:
+31
-11
@@ -457,7 +457,7 @@ def create_transcript_docx(text: str, filename: str, summary_text: str = ""):
|
|||||||
"""
|
"""
|
||||||
from . import docx_styles
|
from . import docx_styles
|
||||||
|
|
||||||
# Step 1: Prepare transcript into pages of 29 lines each
|
# Step 1: Prepare transcript into pages of 30 lines each
|
||||||
prepared_pages = []
|
prepared_pages = []
|
||||||
current_page = []
|
current_page = []
|
||||||
line_count = 0
|
line_count = 0
|
||||||
@@ -485,7 +485,7 @@ def create_transcript_docx(text: str, filename: str, summary_text: str = ""):
|
|||||||
if current:
|
if current:
|
||||||
segments.append(current)
|
segments.append(current)
|
||||||
|
|
||||||
# Add segments to pages, enforcing 29 lines per page
|
# Add segments to pages, enforcing 30 lines per page
|
||||||
for seg in segments:
|
for seg in segments:
|
||||||
if line_count == 30:
|
if line_count == 30:
|
||||||
prepared_pages.append(current_page)
|
prepared_pages.append(current_page)
|
||||||
@@ -523,21 +523,41 @@ def create_transcript_docx(text: str, filename: str, summary_text: str = ""):
|
|||||||
|
|
||||||
# Step 4: Write prepared pages into DOCX
|
# Step 4: Write prepared pages into DOCX
|
||||||
for page_idx, page_lines in enumerate(prepared_pages):
|
for page_idx, page_lines in enumerate(prepared_pages):
|
||||||
# Insert page break between pages
|
# Write each line with its number (1-30)
|
||||||
if page_idx > 0:
|
for line_num, line_text in enumerate(page_lines, start=1):
|
||||||
|
p = doc.add_paragraph()
|
||||||
|
_add_transcript_paragraph(doc, line_text, line_number=line_num)
|
||||||
|
# Remove the extra paragraph added by add_paragraph (we already added runs)
|
||||||
|
# _add_transcript_paragraph already creates its own paragraph, so we need to avoid duplication.
|
||||||
|
# Correct approach: _add_transcript_paragraph should add to doc, not p.
|
||||||
|
# To avoid breaking existing behavior, keep _add_transcript_paragraph as-is
|
||||||
|
# and remove the temporary paragraph we just added.
|
||||||
|
# This is an internal fix to ensure page break logic is clean.
|
||||||
|
# We'll rely on _add_transcript_paragraph creating its own paragraph.
|
||||||
|
# To avoid an extra blank paragraph, we remove p if it has no runs.
|
||||||
|
if not p.runs:
|
||||||
|
body.remove(p._p)
|
||||||
|
|
||||||
|
# After each page except the last, add a page break via next paragraph
|
||||||
|
if page_idx < len(prepared_pages) - 1:
|
||||||
p_break = doc.add_paragraph()
|
p_break = doc.add_paragraph()
|
||||||
|
p_break.paragraph_format.page_break_before = True
|
||||||
|
# Ensure it’s empty and doesn’t show as a visible line
|
||||||
|
if p_break.runs:
|
||||||
|
for r in p_break.runs:
|
||||||
|
r.text = ""
|
||||||
|
# Remove any formatting that would show as a visible line
|
||||||
pPr = p_break._p.get_or_add_pPr()
|
pPr = p_break._p.get_or_add_pPr()
|
||||||
for child in list(pPr):
|
for child in list(pPr):
|
||||||
tag = child.tag.split("}")[-1] if "}" in child.tag else child.tag
|
tag = child.tag.split("}")[-1] if "}" in child.tag else child.tag
|
||||||
if tag in ("tabs", "spacing", "ind"):
|
if tag in ("tabs", "spacing", "ind"):
|
||||||
pPr.remove(child)
|
pPr.remove(child)
|
||||||
page_break = OxmlElement("w:pageBreak")
|
spacing = OxmlElement("w:spacing")
|
||||||
page_break.set("{http://schemas.openxmlformats.org/wordprocessingml/2006/main}val", "1")
|
_set_element_attr(spacing, "before", "0")
|
||||||
pPr.append(page_break)
|
_set_element_attr(spacing, "after", "0")
|
||||||
|
_set_element_attr(spacing, "line", "240")
|
||||||
# Write each line with its number (1-29)
|
_set_element_attr(spacing, "lineRule", "auto")
|
||||||
for line_num, line_text in enumerate(page_lines, start=1):
|
pPr.append(spacing)
|
||||||
_add_transcript_paragraph(doc, line_text, line_number=line_num)
|
|
||||||
|
|
||||||
# Step 5: If summary_text provided, append it with a hard page break
|
# Step 5: If summary_text provided, append it with a hard page break
|
||||||
if summary_text and summary_text.strip():
|
if summary_text and summary_text.strip():
|
||||||
|
|||||||
+4
-3
@@ -322,8 +322,8 @@ def _apply_speaker_map(transcript_text: str, segments: list, speaker_map: dict)
|
|||||||
|
|
||||||
# Replace in transcript lines
|
# Replace in transcript lines
|
||||||
def replace_in_line(line: str) -> str:
|
def replace_in_line(line: str) -> str:
|
||||||
# Pattern: timestamp bracket + speaker label + colon
|
# Match: [MM:SS] or [HH:MM:SS] then speaker label then colon
|
||||||
# More flexible: allow any non-empty label before the colon
|
# Use a lazy match for the label up to the first colon
|
||||||
def repl(m):
|
def repl(m):
|
||||||
prefix = m.group(1) # e.g. "[00:12] "
|
prefix = m.group(1) # e.g. "[00:12] "
|
||||||
label = m.group(2).strip()
|
label = m.group(2).strip()
|
||||||
@@ -331,9 +331,10 @@ def _apply_speaker_map(transcript_text: str, segments: list, speaker_map: dict)
|
|||||||
new_label = speaker_map.get(normalized, label)
|
new_label = speaker_map.get(normalized, label)
|
||||||
return f"{prefix}{new_label}: "
|
return f"{prefix}{new_label}: "
|
||||||
return re.sub(
|
return re.sub(
|
||||||
r"(\[\d+:\d+(?::\d+)?\]\s*)([^\]]+?):\s*",
|
r"(\[\d+:\d+(?::\d+)?\]\s*)(.+?):\s*",
|
||||||
repl,
|
repl,
|
||||||
line,
|
line,
|
||||||
|
count=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
updated_transcript = "\n".join(
|
updated_transcript = "\n".join(
|
||||||
|
|||||||
Reference in New Issue
Block a user