broadfield-dev commited on
Commit
1fb5157
·
verified ·
1 Parent(s): 9a1bdee

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -30
app.py CHANGED
@@ -108,45 +108,60 @@ def parse_endpoint():
108
  def build_full_html(markdown_text, styles, include_fontawesome):
109
  wrapper_id = "#output-wrapper"
110
  font_family = styles.get('font_family', "'Arial', sans-serif")
111
- google_font_name = font_family.split(',')[0].strip("'\"")
112
- google_font_link = ""
113
- if " " in google_font_name and google_font_name not in ["Times New Roman", "Courier New"]:
114
- google_font_link = f'<link href="https://fonts.googleapis.com/css2?family={google_font_name.replace(" ", "+")}:wght@400;700&display=swap" rel="stylesheet">'
115
 
 
 
 
 
116
  highlight_theme = styles.get('highlight_theme', 'default')
117
  pygments_css = ""
118
  if highlight_theme != 'none':
119
  formatter = HtmlFormatter(style=highlight_theme, cssclass="codehilite")
120
  pygments_css = formatter.get_style_defs(f' {wrapper_id}')
121
-
122
  scoped_css = f"""
 
123
  {wrapper_id} {{
124
- font-family: {font_family}; font-size: {styles.get('font_size', '16')}px;
125
- color: {styles.get('text_color', '#333')}; background-color: {styles.get('background_color', '#fff')};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  }}
127
- {wrapper_id} table {{ border-collapse: collapse; width: 100%; }}
128
- {wrapper_id} th, {wrapper_id} td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
129
- {wrapper_id} th {{ background-color: #f2f2f2; }}
130
- {wrapper_id} img {{ max-width: 100%; height: auto; }}
131
- {wrapper_id} pre {{ padding: {styles.get('code_padding', '15')}px; border-radius: 5px; white-space: pre-wrap; word-wrap: break-word; }}
132
- {wrapper_id} h1, {wrapper_id} h2, {wrapper_id} h3 {{ border-bottom: 1px solid #eee; padding-bottom: 5px; margin-top: 1.5em; }}
133
- {wrapper_id} :not(pre) > code {{ font-family: 'Courier New', monospace; background-color: #eef; padding: .2em .4em; border-radius: 3px; }}
134
- {pygments_css} {styles.get('custom_css', '')}
135
  """
 
 
 
136
 
137
- md_extensions = ['fenced_code', 'tables', 'codehilite']
138
- html_content = markdown.markdown(markdown_text, extensions=md_extensions, extension_configs={'codehilite': {'css_class': 'codehilite'}})
139
- final_html_body = f'<div id="output-wrapper">{html_content}</div>'
140
-
141
- fontawesome_link = '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">' if include_fontawesome else ""
142
-
143
- full_html = f"""<!DOCTYPE html>
144
- <html><head><meta charset="UTF-8">{google_font_link}{fontawesome_link}<style>
145
- #ouput-wrapper {{ background-color: {styles.get('background_color', '#fff')}; padding: 25px; display: inline-block;}}
146
- {scoped_css}
147
- </style></head><body>{final_html_body}</body></html>"""
148
 
149
- return full_html
 
 
 
 
 
 
 
 
 
 
 
150
 
151
  @app.route('/convert', methods=['POST'])
152
  def convert_endpoint():
@@ -157,7 +172,7 @@ def convert_endpoint():
157
  styles=data.get('styles', {}),
158
  include_fontawesome=data.get('include_fontawesome', False)
159
  )
160
- options = {"quiet": "", 'encoding': "UTF-8"}
161
 
162
  if data.get('download', False):
163
  download_type = data.get('download_type', 'png')
@@ -214,8 +229,62 @@ def index():
214
  <form id="main-form" onsubmit="return false;">
215
  <fieldset><legend>1. Load Content</legend><div id="info-box" class="info"></div><textarea id="markdown-text-input" name="markdown_text" rows="8"></textarea><div style="margin-top: 10px; display: flex; align-items: center; gap: 10px;"><label for="markdown-file-input">Or upload a file:</label><input type="file" id="markdown-file-input" name="markdown_file" accept=".md,.txt,text/markdown"></div><div style="margin-top: 15px;"><button type="button" id="load-btn" class="action-btn">Load & Analyze</button></div></fieldset>
216
  <fieldset id="components-fieldset" style="display:none;"><legend>2. Select Components</legend><div class="selection-controls"><button type="button" onclick="toggleAllComponents(true)">Select All</button><button type="button" onclick="toggleAllComponents(false)">Deselect All</button></div><div id="components-container" class="component-grid"></div></fieldset>
217
- <fieldset><legend>3. Configure Styles</legend><div class="style-grid"><div><label>Font Family:</label><select id="font_family"><optgroup label="Sans-Serif"><option value="'Arial', sans-serif">Arial</option><option value="'Roboto', sans-serif">Roboto</option></optgroup><optgroup label="Serif"><option value="'Times New Roman', serif">Times New Roman</option><option value="'Georgia', serif">Georgia</option></optgroup></select></div><div><label>Font Size (px):</label><input type="number" id="font_size" value="16"></div><div><label>Highlight Theme:</label><select id="highlight_theme"><option value="none">None</option>{% for style in highlight_styles %}<option value="{{ style }}" {% if style == 'default' %}selected{% endif %}>{{ style }}</option>{% endfor %}</select></div><div><label>Text Color:</label><input type="color" id="text_color" value="#333333"></div><div><label>Background Color:</label><input type="color" id="background_color" value="#ffffff"></div><div><label>Code Padding (px):</label><input type="number" id="code_padding" value="15"></div></div><div><input type="checkbox" id="include_fontawesome"><label for="include_fontawesome">Include Font Awesome</label></div><div><label for="custom_css">Custom CSS:</label><textarea id="custom_css" rows="3"></textarea></div></fieldset>
218
- <div class="main-actions"><button type="button" id="generate-btn" class="generate-btn">Generate Preview</button></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  </form>
220
  <div id="error-box" class="error"></div>
221
  <div id="preview-section" style="display:none;">
 
108
  def build_full_html(markdown_text, styles, include_fontawesome):
109
  wrapper_id = "#output-wrapper"
110
  font_family = styles.get('font_family', "'Arial', sans-serif")
 
 
 
 
111
 
112
+ # Extract clean font name for Google Fonts API
113
+ google_font_name = font_family.split(',')[0].strip("'\"")
114
+ google_font_link = f'<link href="https://fonts.googleapis.com/css2?family={google_font_name.replace(" ", "+")}:wght@400;700&display=swap" rel="stylesheet">'
115
+
116
  highlight_theme = styles.get('highlight_theme', 'default')
117
  pygments_css = ""
118
  if highlight_theme != 'none':
119
  formatter = HtmlFormatter(style=highlight_theme, cssclass="codehilite")
120
  pygments_css = formatter.get_style_defs(f' {wrapper_id}')
121
+
122
  scoped_css = f"""
123
+ body {{ background-color: {styles.get('background_color', '#ffffff')}; margin: 0; padding: 0; }}
124
  {wrapper_id} {{
125
+ font-family: {font_family};
126
+ font-size: {styles.get('font_size', '16')}px;
127
+ line-height: {styles.get('line_height', '1.6')};
128
+ color: {styles.get('text_color', '#333')};
129
+ background-color: {styles.get('background_color', '#fff')};
130
+ padding: {styles.get('page_padding', '40')}px;
131
+ max-width: 100%;
132
+ }}
133
+ {wrapper_id} h1, {wrapper_id} h2, {wrapper_id} h3 {{
134
+ margin-top: 1.2em;
135
+ margin-bottom: 0.6em;
136
+ font-weight: 700;
137
+ }}
138
+ {wrapper_id} pre {{
139
+ padding: {styles.get('code_padding', '15')}px;
140
+ border-radius: 8px;
141
+ overflow-x: auto;
142
  }}
143
+ {pygments_css}
144
+ /* User Custom CSS Injection */
145
+ {styles.get('custom_css', '')}
 
 
 
 
 
146
  """
147
+
148
+ md_extensions = ['fenced_code', 'tables', 'codehilite', 'nl2br']
149
+ html_body = markdown.markdown(markdown_text, extensions=md_extensions)
150
 
151
+ fontawesome = '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">' if include_fontawesome else ""
 
 
 
 
 
 
 
 
 
 
152
 
153
+ return f"""<!DOCTYPE html>
154
+ <html>
155
+ <head>
156
+ <meta charset="UTF-8">
157
+ {google_font_link}
158
+ {fontawesome}
159
+ <style>{scoped_css}</style>
160
+ </head>
161
+ <body>
162
+ <div id="output-wrapper">{html_body}</div>
163
+ </body>
164
+ </html>"""
165
 
166
  @app.route('/convert', methods=['POST'])
167
  def convert_endpoint():
 
172
  styles=data.get('styles', {}),
173
  include_fontawesome=data.get('include_fontawesome', False)
174
  )
175
+ options = {"quiet": "", 'encoding': "UTF-8", "width": 1200, "disable-smart-width":""}
176
 
177
  if data.get('download', False):
178
  download_type = data.get('download_type', 'png')
 
229
  <form id="main-form" onsubmit="return false;">
230
  <fieldset><legend>1. Load Content</legend><div id="info-box" class="info"></div><textarea id="markdown-text-input" name="markdown_text" rows="8"></textarea><div style="margin-top: 10px; display: flex; align-items: center; gap: 10px;"><label for="markdown-file-input">Or upload a file:</label><input type="file" id="markdown-file-input" name="markdown_file" accept=".md,.txt,text/markdown"></div><div style="margin-top: 15px;"><button type="button" id="load-btn" class="action-btn">Load & Analyze</button></div></fieldset>
231
  <fieldset id="components-fieldset" style="display:none;"><legend>2. Select Components</legend><div class="selection-controls"><button type="button" onclick="toggleAllComponents(true)">Select All</button><button type="button" onclick="toggleAllComponents(false)">Deselect All</button></div><div id="components-container" class="component-grid"></div></fieldset>
232
+ <fieldset>
233
+ <legend>3. Visual & Layout Controls</legend>
234
+ <div class="style-grid">
235
+ <div>
236
+ <label>Font Family</label>
237
+ <select id="font_family">
238
+ <option value="'Inter', sans-serif">Inter (Modern)</option>
239
+ <option value="'Playfair Display', serif">Playfair (Elegant)</option>
240
+ <option value="'Fira Code', monospace">Fira Code (Dev)</option>
241
+ <option value="'Roboto', sans-serif">Roboto (Clean)</option>
242
+ <option value="'Lora', serif">Lora (Classic)</option>
243
+ </select>
244
+ </div>
245
+ <div>
246
+ <label>Font Size (px)</label>
247
+ <input type="number" id="font_size" value="16">
248
+ </div>
249
+ <div>
250
+ <label>Line Height</label>
251
+ <input type="number" id="line_height" value="1.6" step="0.1">
252
+ </div>
253
+
254
+ <div>
255
+ <label>Text Color</label>
256
+ <input type="color" id="text_color" value="#333333">
257
+ </div>
258
+ <div>
259
+ <label>Background</label>
260
+ <input type="color" id="background_color" value="#ffffff">
261
+ </div>
262
+ <div>
263
+ <label>Highlight Theme</label>
264
+ <select id="highlight_theme">
265
+ <option value="monokai">Monokai</option>
266
+ <option value="github-light">GitHub Light</option>
267
+ <option value="dracula">Dracula</option>
268
+ </select>
269
+ </div>
270
+
271
+ <div>
272
+ <label>Page Padding (px)</label>
273
+ <input type="number" id="page_padding" value="40">
274
+ </div>
275
+ <div>
276
+ <label>Code Padding (px)</label>
277
+ <input type="number" id="code_padding" value="15">
278
+ </div>
279
+ </div>
280
+
281
+ <div style="margin-top:15px;">
282
+ <label><b>Custom CSS Overrides:</b></label>
283
+ <textarea id="custom_css" rows="4" placeholder="#output-wrapper h1 { color: red; }"></textarea>
284
+ </div>
285
+ </fieldset>
286
+
287
+ <div class="main-actions"><button type="button" id="generate-btn" class="generate-btn">Generate Preview</button></div>
288
  </form>
289
  <div id="error-box" class="error"></div>
290
  <div id="preview-section" style="display:none;">