Update app.py
Browse files
app.py
CHANGED
@@ -1,5 +1,3 @@
|
|
1 |
-
|
2 |
-
|
3 |
import io
|
4 |
import re
|
5 |
import streamlit as st
|
@@ -32,9 +30,9 @@ def create_pdf_tab(default_markdown):
|
|
32 |
auto_size = st.checkbox("Auto-size text", value=True)
|
33 |
base_font_size = st.slider("Base Font Size (points)", min_value=6, max_value=16, value=10, step=1)
|
34 |
if auto_size:
|
35 |
-
st.info("Font size will adjust between 6-16 points
|
36 |
plain_text_mode = st.checkbox("Render as Plain Text (Preserve Bold Only)", value=False)
|
37 |
-
num_columns = st.selectbox("Number of Columns", options=[1, 2, 3, 4, 5, 6], index=
|
38 |
|
39 |
# Register font
|
40 |
pdfmetrics.registerFont(TTFont(selected_font_name, selected_font_path))
|
@@ -62,7 +60,7 @@ def create_pdf_tab(default_markdown):
|
|
62 |
return emoji_pattern.sub(replace_emoji, text)
|
63 |
|
64 |
# Markdown to PDF content
|
65 |
-
def markdown_to_pdf_content(markdown_text, plain_text_mode
|
66 |
lines = markdown_text.strip().split('\n')
|
67 |
pdf_content = []
|
68 |
|
@@ -86,31 +84,30 @@ def create_pdf_tab(default_markdown):
|
|
86 |
pdf_content.append(line.strip())
|
87 |
|
88 |
total_lines = len(pdf_content)
|
89 |
-
|
90 |
-
lines_per_column = total_lines / num_columns if num_columns > 0 else total_lines
|
91 |
-
current_line_count = 0
|
92 |
-
current_column = 0
|
93 |
-
|
94 |
-
for item in pdf_content:
|
95 |
-
if current_line_count >= lines_per_column and current_column < num_columns - 1:
|
96 |
-
current_column += 1
|
97 |
-
current_line_count = 0
|
98 |
-
columns[current_column].append(item)
|
99 |
-
current_line_count += 1
|
100 |
-
|
101 |
-
return columns, total_lines
|
102 |
|
103 |
# Create PDF
|
104 |
def create_pdf(markdown_text, base_font_size, auto_size, plain_text_mode, num_columns):
|
105 |
buffer = io.BytesIO()
|
106 |
-
|
|
|
|
|
|
|
107 |
styles = getSampleStyleSheet()
|
108 |
story = []
|
109 |
spacer_height = 10
|
110 |
-
|
111 |
|
|
|
112 |
if auto_size and total_lines > 0:
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
|
115 |
item_font_size = base_font_size
|
116 |
section_font_size = base_font_size * 1.1
|
@@ -125,6 +122,18 @@ def create_pdf_tab(default_markdown):
|
|
125 |
)
|
126 |
|
127 |
story.append(Spacer(1, spacer_height))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
column_cells = [[] for _ in range(num_columns)]
|
129 |
for col_idx, column in enumerate(columns):
|
130 |
for item in column:
|
@@ -138,7 +147,7 @@ def create_pdf_tab(default_markdown):
|
|
138 |
for cells in column_cells:
|
139 |
cells.extend([Paragraph("", item_style)] * (max_cells - len(cells)))
|
140 |
|
141 |
-
col_width = (
|
142 |
table_data = list(zip(*column_cells)) if column_cells else [[]]
|
143 |
table = Table(table_data, colWidths=[col_width] * num_columns, hAlign='CENTER')
|
144 |
table.setStyle(TableStyle([
|
@@ -194,9 +203,6 @@ def create_pdf_tab(default_markdown):
|
|
194 |
st.download_button(label="Save Markdown", data=st.session_state.markdown_content, file_name="deities_guide.md", mime="text/markdown")
|
195 |
|
196 |
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
default_markdown = """# π Deities Guide: Mythology and Moral Lessons π
|
201 |
|
202 |
## 1. π Introduction
|
|
|
|
|
|
|
1 |
import io
|
2 |
import re
|
3 |
import streamlit as st
|
|
|
30 |
auto_size = st.checkbox("Auto-size text", value=True)
|
31 |
base_font_size = st.slider("Base Font Size (points)", min_value=6, max_value=16, value=10, step=1)
|
32 |
if auto_size:
|
33 |
+
st.info("Font size will adjust between 6-16 points to fit content on one page, starting from your base size.")
|
34 |
plain_text_mode = st.checkbox("Render as Plain Text (Preserve Bold Only)", value=False)
|
35 |
+
num_columns = st.selectbox("Number of Columns", options=[1, 2, 3, 4, 5, 6], index=1) # Default to 2 columns
|
36 |
|
37 |
# Register font
|
38 |
pdfmetrics.registerFont(TTFont(selected_font_name, selected_font_path))
|
|
|
60 |
return emoji_pattern.sub(replace_emoji, text)
|
61 |
|
62 |
# Markdown to PDF content
|
63 |
+
def markdown_to_pdf_content(markdown_text, plain_text_mode):
|
64 |
lines = markdown_text.strip().split('\n')
|
65 |
pdf_content = []
|
66 |
|
|
|
84 |
pdf_content.append(line.strip())
|
85 |
|
86 |
total_lines = len(pdf_content)
|
87 |
+
return pdf_content, total_lines
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
# Create PDF
|
90 |
def create_pdf(markdown_text, base_font_size, auto_size, plain_text_mode, num_columns):
|
91 |
buffer = io.BytesIO()
|
92 |
+
# Double A4 page: A4 width * 2 (landscape)
|
93 |
+
page_width = A4[0] * 2
|
94 |
+
page_height = A4[1]
|
95 |
+
doc = SimpleDocTemplate(buffer, pagesize=(page_width, page_height), leftMargin=36, rightMargin=36, topMargin=36, bottomMargin=36)
|
96 |
styles = getSampleStyleSheet()
|
97 |
story = []
|
98 |
spacer_height = 10
|
99 |
+
pdf_content, total_lines = markdown_to_pdf_content(markdown_text, plain_text_mode)
|
100 |
|
101 |
+
# Auto-size logic: reduce font size as content grows to fit one page
|
102 |
if auto_size and total_lines > 0:
|
103 |
+
# Target fitting content within page height (accounting for margins and spacing)
|
104 |
+
target_lines_per_column = (page_height - 72 - spacer_height) / (base_font_size * 1.15) # Approx lines per column
|
105 |
+
total_target_lines = target_lines_per_column * num_columns
|
106 |
+
if total_lines > total_target_lines:
|
107 |
+
scale_factor = total_target_lines / total_lines
|
108 |
+
base_font_size = max(6, min(16, base_font_size * scale_factor))
|
109 |
+
else:
|
110 |
+
base_font_size = min(16, base_font_size * (total_lines / total_target_lines))
|
111 |
|
112 |
item_font_size = base_font_size
|
113 |
section_font_size = base_font_size * 1.1
|
|
|
122 |
)
|
123 |
|
124 |
story.append(Spacer(1, spacer_height))
|
125 |
+
columns = [[] for _ in range(num_columns)]
|
126 |
+
lines_per_column = total_lines / num_columns if num_columns > 0 else total_lines
|
127 |
+
current_line_count = 0
|
128 |
+
current_column = 0
|
129 |
+
|
130 |
+
for item in pdf_content:
|
131 |
+
if current_line_count >= lines_per_column and current_column < num_columns - 1:
|
132 |
+
current_column += 1
|
133 |
+
current_line_count = 0
|
134 |
+
columns[current_column].append(item)
|
135 |
+
current_line_count += 1
|
136 |
+
|
137 |
column_cells = [[] for _ in range(num_columns)]
|
138 |
for col_idx, column in enumerate(columns):
|
139 |
for item in column:
|
|
|
147 |
for cells in column_cells:
|
148 |
cells.extend([Paragraph("", item_style)] * (max_cells - len(cells)))
|
149 |
|
150 |
+
col_width = (page_width - 72) / num_columns if num_columns > 0 else page_width - 72
|
151 |
table_data = list(zip(*column_cells)) if column_cells else [[]]
|
152 |
table = Table(table_data, colWidths=[col_width] * num_columns, hAlign='CENTER')
|
153 |
table.setStyle(TableStyle([
|
|
|
203 |
st.download_button(label="Save Markdown", data=st.session_state.markdown_content, file_name="deities_guide.md", mime="text/markdown")
|
204 |
|
205 |
|
|
|
|
|
|
|
206 |
default_markdown = """# π Deities Guide: Mythology and Moral Lessons π
|
207 |
|
208 |
## 1. π Introduction
|