feat: 동물약 안내서 항목별 줄바꿈 처리

- 가. 나. 다. 라. 등 항목 앞에 줄바꿈 추가
- 1) 2) 3) 등 번호 앞에 들여쓰기 + 줄바꿈
- 미리보기/인쇄 모두 적용
- white-space: pre-line으로 줄바꿈 표시
- 80mm 프린터 출력에 최적화
This commit is contained in:
thug0bin 2026-03-04 19:33:00 +09:00
parent f374ca4fd1
commit abb8ad1325
2 changed files with 40 additions and 12 deletions

View File

@ -6480,6 +6480,18 @@ def api_animal_drug_info_print():
text = re.sub(r'\s+', ' ', text).strip()
return text
# 항목별 줄바꿈 처리 (가. 나. 다. 라. / 1) 2) 3) 등)
def format_for_print(text):
if not text:
return ''
# 가. 나. 다. 라. 마. 바. 사. 아. 자. 앞에 줄바꿈
text = re.sub(r'\s*(가|나|다|라|마|바|사|아|자)\.\s*', r'\n\1. ', text)
# 1) 2) 3) 등 앞에 줄바꿈 (단, 문장 시작이 아닌 경우)
text = re.sub(r'\s+(\d+)\)\s*', r'\n \1) ', text)
# 첫 줄바꿈 제거
text = text.strip()
return text
# 텍스트를 줄 단위로 분리 (80mm ≈ 42자)
def wrap_text(text, width=40):
lines = []
@ -6532,24 +6544,30 @@ def api_animal_drug_info_print():
{THIN}
효능효과
"""
for line in wrap_text(efficacy[:400], 46):
message += f" {line}\n"
formatted_efficacy = format_for_print(efficacy[:400])
for para in formatted_efficacy.split('\n'):
for line in wrap_text(para.strip(), 44):
message += f" {line}\n"
if dosage:
message += f"""
{THIN}
용법용량
"""
for line in wrap_text(dosage[:500], 46):
message += f" {line}\n"
formatted_dosage = format_for_print(dosage[:500])
for para in formatted_dosage.split('\n'):
for line in wrap_text(para.strip(), 44):
message += f" {line}\n"
if precautions:
message += f"""
{THIN}
주의사항
"""
for line in wrap_text(precautions[:400], 46):
message += f" {line}\n"
formatted_precautions = format_for_print(precautions[:600])
for para in formatted_precautions.split('\n'):
for line in wrap_text(para.strip(), 44):
message += f" {line}\n"
message += f"""
{LINE}
@ -6623,15 +6641,25 @@ def api_animal_drug_info_preview():
text = re.sub(r'\s+', ' ', text).strip()
return text
# 항목별 줄바꿈 처리 (가. 나. 다. 라. / 1) 2) 3) 등)
def format_items(text):
if not text:
return ''
# 가. 나. 다. 라. 마. 바. 사. 아. 자. 앞에 줄바꿈
text = re.sub(r'\s*(가|나|다|라|마|바|사|아|자)\.\s*', r'\n\1. ', text)
# 1) 2) 3) 등 앞에 줄바꿈
text = re.sub(r'\s+(\d+)\)\s*', r'\n \1) ', text)
return text.strip()
return jsonify({
'success': True,
'data': {
'product_name': row.product_name,
'company_name': row.company_name,
'main_ingredient': row.main_ingredient if row.main_ingredient != 'NaN' else None,
'efficacy_effect': strip_html(row.efficacy_effect),
'dosage_instructions': strip_html(row.dosage_instructions),
'precautions': strip_html(row.precautions)
'efficacy_effect': format_items(strip_html(row.efficacy_effect)),
'dosage_instructions': format_items(strip_html(row.dosage_instructions)),
'precautions': format_items(strip_html(row.precautions))
}
})

View File

@ -1150,19 +1150,19 @@
${info.efficacy_effect ? `
<div style="margin-bottom:12px;background:#f0fdf4;padding:12px;border-radius:8px;">
<h5 style="margin:0 0 6px;color:#059669;">▶ 효능효과</h5>
<p style="margin:0;font-size:13px;line-height:1.5;color:#334155;">${escapeHtml(info.efficacy_effect)}</p>
<p style="margin:0;font-size:13px;line-height:1.7;color:#334155;white-space:pre-line;">${escapeHtml(info.efficacy_effect)}</p>
</div>` : ''}
${info.dosage_instructions ? `
<div style="margin-bottom:12px;background:#eff6ff;padding:12px;border-radius:8px;">
<h5 style="margin:0 0 6px;color:#0284c7;">▶ 용법용량</h5>
<p style="margin:0;font-size:13px;line-height:1.5;color:#334155;">${escapeHtml(info.dosage_instructions)}</p>
<p style="margin:0;font-size:13px;line-height:1.7;color:#334155;white-space:pre-line;">${escapeHtml(info.dosage_instructions)}</p>
</div>` : ''}
${info.precautions ? `
<div style="margin-bottom:12px;background:#fef2f2;padding:12px;border-radius:8px;">
<h5 style="margin:0 0 6px;color:#dc2626;">▶ 주의사항</h5>
<p style="margin:0;font-size:13px;line-height:1.5;color:#334155;">${escapeHtml(info.precautions.substring(0, 500))}${info.precautions.length > 500 ? '...' : ''}</p>
<p style="margin:0;font-size:13px;line-height:1.7;color:#334155;white-space:pre-line;">${escapeHtml(info.precautions.substring(0, 800))}${info.precautions.length > 800 ? '...' : ''}</p>
</div>` : ''}
<div style="display:flex;gap:10px;margin-top:20px;">