From 4ea6886a06cef46193f4101d84ebb3dcc7928d84 Mon Sep 17 00:00:00 2001 From: kj_sh604 Date: Fri, 20 Feb 2026 11:56:35 -0500 Subject: feat: extra options --- src/app.nim | 14 ++++++++--- src/latex/template.tex | 6 +++++ src/static/main.js | 62 ++++++++++++++++++++++++++++++++++++++---------- src/templates/index.html | 54 ++++++++++++++++++++++++++--------------- 4 files changed, 101 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/app.nim b/src/app.nim index 80c0502..b321a23 100644 --- a/src/app.nim +++ b/src/app.nim @@ -6,6 +6,7 @@ const AllowedImageExtensions = ["png", "jpg", "jpeg", "gif", "webp", "svg"] ValidPaperSizes = ["a4paper", "letterpaper", "legalpaper"] ValidMargins = ["0.75in", "1in", "1.25in", "1.5in"] + ValidLineSpacings = ["1", "1.5", "2"] const AppName = "likha-pdf" @@ -229,7 +230,7 @@ proc respondFile(req: Request; filePath: string; asAttachment: bool = false; att await req.respond(Http200, readFile(filePath), headers) # pandoc does the heavy lifting -proc runPandoc(sourceMarkdown: string; outputPath: string; paperSize: string; margin: string; mainFont: string): tuple[ok: bool, output: string, missingPandoc: bool] = +proc runPandoc(sourceMarkdown: string; outputPath: string; paperSize: string; margin: string; mainFont: string; lineSpacing: string; showPageNumbers: bool): tuple[ok: bool, output: string, missingPandoc: bool] = let tempDir = getTempDir() / (AppName & "-" & randomHex(10)) createDir(tempDir) let tempMarkdownPath = tempDir / "source.md" @@ -247,7 +248,7 @@ proc runPandoc(sourceMarkdown: string; outputPath: string; paperSize: string; ma # if preprocessing fails, fall back to original content writeFile(tempMarkdownPath, sourceMarkdown) - let args = @[ + var args = @[ tempMarkdownPath, "--from", "markdown+emoji+hard_line_breaks", "--pdf-engine=lualatex", @@ -255,10 +256,15 @@ proc runPandoc(sourceMarkdown: string; outputPath: string; paperSize: string; ma "-V", "papersize=" & paperSize, "-V", "margin=" & margin, "-V", "mainfont=" & mainFont, + "-V", "linespacing=" & lineSpacing, "--resource-path", baseDir() & ":" & uploadsDir() & ":" & tempDir, "-o", outputPath ] + if not showPageNumbers: + args.add("-V") + args.add("hidepages=true") + var process: Process try: process = startProcess("pandoc", args = args, options = {poUsePath, poStdErrToStdOut}) @@ -301,11 +307,13 @@ proc handleConvert(req: Request) {.async.} = mainFontFamily = "serif" let mainFont = if mainFontFamily == "sans": "TeX Gyre Heros" else: "TeX Gyre Pagella" + let lineSpacing = pickOption(formData.getOrDefault("line_spacing", ""), "1", ValidLineSpacings) + let showPageNumbers = formData.getOrDefault("page_numbers", "") == "on" let epoch = int(getTime().toUnix()) let outputName = AppName & "_" & $epoch & "_" & randomHex(32) & ".pdf" let outputPath = generatedDir() / outputName - let conversion = runPandoc(markdown, outputPath, paperSize, margin, mainFont) + let conversion = runPandoc(markdown, outputPath, paperSize, margin, mainFont, lineSpacing, showPageNumbers) if not conversion.ok: let message = if conversion.missingPandoc: diff --git a/src/latex/template.tex b/src/latex/template.tex index 9a0410b..ae44742 100644 --- a/src/latex/template.tex +++ b/src/latex/template.tex @@ -13,6 +13,8 @@ \usepackage[paper=$papersize$,margin=$margin$]{geometry} \usepackage{microtype} \usepackage{parskip} +\usepackage{setspace} +\setstretch{$linespacing$} \usepackage{xcolor} \usepackage{graphicx} \usepackage{float} @@ -66,6 +68,10 @@ $if(highlighting-macros)$ $highlighting-macros$ $endif$ +$if(hidepages)$ +\pagestyle{empty} +$endif$ + \begin{document} $if(title)$ diff --git a/src/static/main.js b/src/static/main.js index f3f4f71..68d36ad 100644 --- a/src/static/main.js +++ b/src/static/main.js @@ -1,41 +1,77 @@ const convertButton = document.getElementById("convert-button"); const uploadButton = document.getElementById("upload-button"); const markdownInput = document.getElementById("markdown"); +const imageInput = document.getElementById("image"); +const mdFileInput = document.getElementById("md-file"); -function sourceForm(event) { - const sourceElement = event.detail?.elt; - if (!sourceElement) { - return null; +document.body.addEventListener("htmx:beforeRequest", (event) => { + const elt = event.detail?.elt; + if (!elt) { + return; } - return sourceElement.closest("form"); -} -document.body.addEventListener("htmx:beforeRequest", (event) => { - const form = sourceForm(event); - if (form?.id === "convert-form" && convertButton) { + if (elt.id === "convert-form" && convertButton) { convertButton.disabled = true; convertButton.textContent = "generating..."; } - if (form?.id === "upload-form" && uploadButton) { + if (elt.id === "upload-button" && uploadButton) { uploadButton.disabled = true; uploadButton.textContent = "uploading..."; } }); document.body.addEventListener("htmx:afterRequest", (event) => { - const form = sourceForm(event); - if (form?.id === "convert-form" && convertButton) { + const elt = event.detail?.elt; + if (!elt) { + return; + } + + if (elt.id === "convert-form" && convertButton) { convertButton.disabled = false; convertButton.textContent = "generate pdf"; } - if (form?.id === "upload-form" && uploadButton) { + if (elt.id === "upload-button" && uploadButton) { uploadButton.disabled = false; uploadButton.textContent = "upload image"; } }); +if (mdFileInput) { + mdFileInput.addEventListener("change", () => { + const file = mdFileInput.files?.[0]; + + if (file) { + const reader = new FileReader(); + reader.onload = (e) => { + if (markdownInput) { + markdownInput.value = /** @type {string} */ (e.target.result); + markdownInput.readOnly = true; + } + if (imageInput) { + imageInput.disabled = true; + } + if (uploadButton) { + uploadButton.disabled = true; + } + }; + reader.readAsText(file); + } else { + if (markdownInput) { + markdownInput.value = ""; + markdownInput.readOnly = false; + } + if (imageInput) { + imageInput.disabled = false; + } + if (uploadButton) { + uploadButton.disabled = false; + } + } + }); +} + document.body.addEventListener("click", (event) => { const target = event.target; if (!(target instanceof HTMLElement)) { diff --git a/src/templates/index.html b/src/templates/index.html index e67f582..6cb610c 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -22,24 +22,6 @@
simple markdown export with pandoc + lualatex.
-