From f4d4b423ccb8939a851a9b4f19cb966ed214dab6 Mon Sep 17 00:00:00 2001 From: Ignacio Rivero Date: Sun, 22 Jun 2025 01:40:52 -0300 Subject: [PATCH] Markdown line support, better CSS, refactoring --- app.py | 151 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 115 insertions(+), 36 deletions(-) diff --git a/app.py b/app.py index c96f113..6b910da 100644 --- a/app.py +++ b/app.py @@ -40,7 +40,7 @@ HTML_FORM = ''' } .form-card { background: #22282c; - padding: 2em 2.4em 1em 2em; + padding: 2em 2em 1em 2em; border-radius: 1.5em; box-shadow: 0 0 12px 0 #000a; min-width: 410px; @@ -54,12 +54,14 @@ HTML_FORM = ''' .markdown-ref { background: #22282c; border-radius: 1.2em; - box-shadow: 0 0 8px #0008; - padding: 1.3em 1.2em 1.1em 1.6em; + box-shadow: 0 0 12px 0 #000a; + padding: 2em 2em 1.5em 2em; color: #b6c8e0; font-size: 1.08em; - max-width: 410px; font-family: inherit; + box-sizing: border-box; + width: 100%; + max-width: 410px; } .markdown-ref h4 { margin: 0 0 0.4em 0; @@ -102,10 +104,10 @@ HTML_FORM = ''' .buttons { display: flex; gap: 1em; - align-items: center; + justify-content: center; } button[type=submit] { - background: linear-gradient(90deg, #8ee3c1, #35a7ff 85%); + background: linear-gradient(90deg, #8ee3c1, #35a7ff); color: #222; font-weight: bold; font-size: 1.12em; @@ -122,6 +124,12 @@ HTML_FORM = ''' filter: brightness(1.12); box-shadow: 0 4px 18px #2229; } + + button[type=submit][name=print] { + background: linear-gradient(90deg, #ffeb3b, #ff9100); + color:#181c1f; + } + .preview-card { background: #23282d; padding: 2em 1.4em 1em 1.4em; @@ -137,7 +145,6 @@ HTML_FORM = ''' margin-top: 1em; max-width: 100%; background: #fff; - border-radius: 0.6em; box-shadow: 0 0 8px 1px #111a; } .status-msg { @@ -158,8 +165,92 @@ HTML_FORM = ''' border-left: 4px solid #ff6384; box-shadow: 0 0 8px #22000690; } + + @media (max-width: 1000px) { + .centered-flex { + flex-direction: column; + align-items: center; + height: auto; + gap: 1.6em; + } + + .form-card, + .preview-card, + .markdown-ref { + min-width: auto; + max-width: 90vw; + width: 100%; + margin: 0.8em 0; + } + } + + .print-frame { + position: relative; + background: #fff; + padding: 10px 15px; + margin-top: 1em; + overflow: hidden; + } + + .print-frame::before, + .print-frame::after { + content: ""; + position: absolute; + left: 0; + width: 101%; + height: 10px; + background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDQuMjMzMyA0LjIzMzMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS1vcGFjaXR5PSIuOTc2NDciPgo8cmVjdCB4PSItNS41NTExZS0xNyIgd2lkdGg9IjQuMjMzMyIgaGVpZ2h0PSI0LjIzMzMiIGZpbGw9IiMyMjI4MmMiIHN0cm9rZS13aWR0aD0iLjE5MjI2Ii8+CjxwYXRoIHRyYW5zZm9ybT0ibWF0cml4KC4wMzYxMzUgMCAwIC4wNDE3MjUgMS4xNTY4IDEuMTI4OSkiIGQ9Im04NS4xNDEgNzQuNDAzLTExNy4xNS0xZS02IDU4LjU3Ny0xMDEuNDZ6IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9Ii4yNjQ1OCIvPgo8L2c+Cjwvc3ZnPgo=') repeat-x left; + background-size: 10px 384px; + z-index: 1; + } + + .print-frame::before { + top: 0; + } + + .print-frame::after { + bottom: 0; + transform: rotate(180deg); + } + + .print-frame img { + display: block; + margin: 0 auto; + border-radius: 0; + box-shadow: none; + position: relative; + z-index: 2; + }
+
+
+

😺 CatNote 🖨️

+
+
+
+
+ + +
+
+ {% if printed %} +
✅ Enviado a impresora
+ {% endif %} + {% if error %} +
⚠️ {{ error }}
+ {% endif %} +
+
+ {% if img %} +

Vista previa

+ + {% else %} +

Su vista previa aparecerá aquí

+ {% endif %} +

Referencia rápida de Markdown

    @@ -174,35 +265,12 @@ HTML_FORM = '''
  • Salto de línea: Deje una línea vacía
-
-

CatNotepad

-
-
-
- - -
-
- {% if printed %} -
✅ Enviado a impresora
- {% endif %} - {% if error %} -
⚠️ {{ error }}
- {% endif %} -
-
- {% if img %} -

Vista previa

- - {% else %} -

Su vista previa aparecerá aquí

- {% endif %} -
''' def parse_line(line): - header_level = 0 + if re.match(r'^\s*---\s*$', line): + return ('hr', []) header_match = re.match(r"^(#{1,3}) +(.*)", line) if header_match: header_level = len(header_match.group(1)) @@ -307,7 +375,9 @@ def render(md): lines_out.append(('blank', [])) continue tag = parse_line(src_line) - if tag[0] == 'header': + if tag[0] == 'hr': + lines_out.append(('hr',)) + elif tag[0] == 'header': header_level = tag[1] segments = tag[2] if header_level == 1: @@ -346,13 +416,23 @@ def render(md): segments = tag[1] for wrapped in wrap_segments(segments, font, font_bold, font_italic, font_bolditalic, IMAGE_WIDTH): lines_out.append(('text', wrapped, font, FONT_SIZE)) - height = sum(item[3] if item[0] in ('header','text','bullet','ordered') else FONT_SIZE for item in lines_out) + 10 + + height = sum( + item[3] if item[0] in ('header', 'text', 'bullet', 'ordered') else + 10 if item[0] == 'hr' else + FONT_SIZE + for item in lines_out + ) + 10 + image = Image.new("L", (IMAGE_WIDTH, height), 255) draw = ImageDraw.Draw(image) y = 0 for item in lines_out: if item[0] == 'blank': y += FONT_SIZE + elif item[0] == 'hr': + draw.line((0, y + 5, IMAGE_WIDTH, y + 5), fill=0, width=2) + y += 10 elif item[0] == 'header': segments, fnt, sz = item[1], item[2], item[3] x = 0 @@ -396,7 +476,6 @@ def render(md): y += sz return image - @app.route("/", methods=["GET", "POST"]) def index(): img_data = None @@ -436,4 +515,4 @@ def index(): printed=printed, error=error) if __name__ == "__main__": - app.run(host="0.0.0.0") + app.run(host="0.0.0.0", debug=True)