Last active
September 15, 2025 23:28
-
-
Save Explosion-Scratch/c396ebbdf6ba4d63b78b7d2024193eb2 to your computer and use it in GitHub Desktop.
Print preview md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>Markdown to Print</title> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.2/marked.min.js"></script> | |
| <script> | |
| // Fetch and inline the LaTeX styles | |
| async function fetchStyles() { | |
| try { | |
| const response = await fetch( | |
| "https://latex.vercel.app/style.css", | |
| ); | |
| const css = await response.text(); | |
| const styleElement = document.createElement("style"); | |
| styleElement.textContent = css; | |
| document.head.appendChild(styleElement); | |
| } catch (error) { | |
| console.error("Failed to fetch styles:", error); | |
| } | |
| } | |
| fetchStyles(); | |
| </script> | |
| <style> | |
| /* Input form styling */ | |
| .input-container { | |
| max-width: 800px; | |
| margin: 2rem auto; | |
| padding: 0 1rem; | |
| } | |
| textarea, | |
| input { | |
| width: 100%; | |
| margin-bottom: 1rem; | |
| padding: 0.5rem; | |
| font-family: inherit; | |
| } | |
| textarea { | |
| height: 300px; | |
| } | |
| button { | |
| background: #000; | |
| color: white; | |
| border: none; | |
| padding: 0.5rem 1rem; | |
| cursor: pointer; | |
| } | |
| button:hover { | |
| opacity: 0.8; | |
| } | |
| .checkbox-container { | |
| margin-bottom: 1rem; | |
| } | |
| .checkbox-container input { | |
| width: auto; | |
| margin-right: 0.5rem; | |
| } | |
| /* Print styles */ | |
| @media print { | |
| .input-container { | |
| display: none; | |
| } | |
| .output-container { | |
| display: block !important; | |
| } | |
| } | |
| /* Output styling */ | |
| .output-container { | |
| display: none; | |
| max-width: 650px; | |
| margin: 0 auto; | |
| padding: 2rem; | |
| } | |
| .title { | |
| font-size: 2.5rem; | |
| text-align: center; | |
| margin-bottom: 0.5rem; | |
| } | |
| .author { | |
| text-align: center; | |
| font-size: 1.2rem; | |
| margin-bottom: 3rem; | |
| color: #666; | |
| } | |
| .content p:first-of-type::first-letter { | |
| float: left; | |
| font-size: 5.5em; | |
| padding: 0.1em 0.1em 0 0; | |
| line-height: 0.65; | |
| font-family: serif; | |
| } | |
| .content { | |
| font-size: 1.1rem; | |
| line-height: 1.6; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="input-container"> | |
| <h1>Markdown to Print</h1> | |
| <input type="text" id="title" placeholder="Enter title" required /> | |
| <input | |
| type="text" | |
| id="author" | |
| placeholder="Enter author" | |
| required | |
| /> | |
| <textarea | |
| id="markdown" | |
| placeholder="Enter your markdown here..." | |
| ></textarea> | |
| <div class="checkbox-container"> | |
| <input type="checkbox" id="doubleSpaced" /> | |
| <label for="doubleSpaced">Double Spaced</label> | |
| </div> | |
| <button onclick="generatePage()">Generate Print Page</button> | |
| </div> | |
| <div class="output-container"> | |
| <h1 class="title"></h1> | |
| <div class="author"></div> | |
| <div class="content"></div> | |
| </div> | |
| <script> | |
| // Load saved content from localStorage | |
| window.onload = function () { | |
| const savedTitle = localStorage.getItem("mdTitle") || ""; | |
| const savedAuthor = localStorage.getItem("mdAuthor") || ""; | |
| const savedMarkdown = localStorage.getItem("mdContent") || ""; | |
| const savedSpacing = | |
| localStorage.getItem("mdDoubleSpaced") === "true"; | |
| document.getElementById("title").value = savedTitle; | |
| document.getElementById("author").value = savedAuthor; | |
| document.getElementById("markdown").value = savedMarkdown; | |
| document.getElementById("doubleSpaced").checked = savedSpacing; | |
| }; | |
| // Save content to localStorage | |
| function saveToStorage() { | |
| localStorage.setItem( | |
| "mdTitle", | |
| document.getElementById("title").value, | |
| ); | |
| localStorage.setItem( | |
| "mdAuthor", | |
| document.getElementById("author").value, | |
| ); | |
| localStorage.setItem( | |
| "mdContent", | |
| document.getElementById("markdown").value, | |
| ); | |
| localStorage.setItem( | |
| "mdDoubleSpaced", | |
| document.getElementById("doubleSpaced").checked, | |
| ); | |
| } | |
| // Auto-save on input | |
| document | |
| .getElementById("title") | |
| .addEventListener("input", saveToStorage); | |
| document | |
| .getElementById("author") | |
| .addEventListener("input", saveToStorage); | |
| document | |
| .getElementById("markdown") | |
| .addEventListener("input", saveToStorage); | |
| document | |
| .getElementById("doubleSpaced") | |
| .addEventListener("change", saveToStorage); | |
| async function generatePage() { | |
| const title = document.getElementById("title").value; | |
| const author = document.getElementById("author").value; | |
| const markdown = document.getElementById("markdown").value; | |
| const isDoubleSpaced = | |
| document.getElementById("doubleSpaced").checked; | |
| const date = new Date().toLocaleDateString(); | |
| if (!title || !author || !markdown) { | |
| alert("Please fill in all fields"); | |
| return; | |
| } | |
| // Fetch LaTeX styles | |
| const styleResponse = await fetch( | |
| "https://latex.vercel.app/style.css", | |
| ); | |
| const latexStyles = await styleResponse.text(); | |
| // Create new window content | |
| const printContent = | |
| ` | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>${title}</title> | |
| <style> | |
| ${latexStyles} | |
| body { | |
| max-width: 650px; | |
| margin: 0 auto; | |
| padding: 2rem; | |
| } | |
| .title { | |
| font-size: 2.5rem; | |
| text-align: center; | |
| margin-bottom: 0.5rem; | |
| } | |
| .author { | |
| text-align: center; | |
| font-size: 1.2rem; | |
| margin-bottom: 3rem; | |
| color: #666; | |
| } | |
| .content p:first-of-type::first-letter { | |
| float: left; | |
| font-size: 5.5em; | |
| padding: 0.1em 0.1em 0 0; | |
| line-height: 0.65; | |
| font-family: serif; | |
| } | |
| .content { | |
| font-size: 1.1rem; | |
| text-indent: 1rem; | |
| line-height: ${isDoubleSpaced ? "2.4" : "1.6"}; | |
| } | |
| @media print { | |
| body { | |
| padding: 0; | |
| max-width: 800px; | |
| } | |
| .content { | |
| font-size: 12pt; | |
| line-height: ${isDoubleSpaced ? "3" : "1.8"}; | |
| } | |
| } | |
| @page { | |
| margin: 1in; | |
| @top-left { | |
| content: "${author}"; | |
| color: #999; | |
| font-size: 9pt; | |
| } | |
| @top-right { | |
| content: "${date}"; | |
| color: #999; | |
| font-size: 9pt; | |
| } | |
| @bottom-center { | |
| content: counter(page); | |
| color: #999; | |
| font-size: 9pt; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <h1 class="title">${title}</h1> | |
| <div class="author">${author}</div> | |
| <div class="content">${marked.parse(markdown)}</div> | |
| <` + | |
| `script> | |
| // Press Esc to return to editor | |
| document.addEventListener('keydown', function(e) { | |
| if (e.key === 'Escape') { | |
| window.close(); | |
| } | |
| }); | |
| <` + | |
| `/script> | |
| </body> | |
| </html> | |
| `; | |
| // Open new window with content | |
| const printWindow = window.open("", "_blank"); | |
| printWindow.document.write(printContent); | |
| printWindow.document.close(); | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment