commit e22334952d642c3a3ecc42011f54063630f488e3 Author: kirbylife Date: Sat May 11 01:19:08 2024 -0600 First commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..09df62f --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +A simple MD to HTML converter + +## Compilation + +1. `git clone https://git.kirbylife.dev/kirbylife/nim-md-to-html` +1. `cd nim-md-to-html` +1. `nimble build -d:release` + +## Usage + +1. `nim-md-to-html > index.html` + +The theme must be a classless CSS file. +I personally recommend [water.css](https://watercss.kognise.dev/), but on the internet there is a good variety, choose the one you like the most. + + +## License + +This project is licensed under the LGPL 3.0 license. \ No newline at end of file diff --git a/md_to_html_embed.nimble b/md_to_html_embed.nimble new file mode 100644 index 0000000..7688132 --- /dev/null +++ b/md_to_html_embed.nimble @@ -0,0 +1,16 @@ +# Package + +version = "0.1.0" +author = "kirbylife" +description = "A simple MD to HTML converter" +license = "LGPL-3.0-or-later" +srcDir = "src" +bin = @["md_to_html_embed"] + + +# Dependencies + +requires "nim >= 2.0" +requires "markdown == 0.8.7" +requires "glob == 0.11.3" +requires "regex == 0.25.0" diff --git a/src/md_to_html_embed.nim b/src/md_to_html_embed.nim new file mode 100644 index 0000000..2771892 --- /dev/null +++ b/src/md_to_html_embed.nim @@ -0,0 +1,85 @@ +import markdown +import glob +import regex +import std/htmlparser +import std/xmltree +import std/strtabs +import std/strutils +import std/os +import std/paths +import std/sequtils +import std/streams +import std/base64 + +const MAXOUTERLIMIT = 2 + +proc applyTheme(html: XmlNode, theme: string) = + let charset_att = {"charset": "utf-8"}.toXmlAttributes() + let charset = newXmlTree("meta", [], charset_att) + + let theme_att = {"style": "text/css"}.toXmlAttributes() + let theme_content = newText(theme) + let style = newXmlTree("style", [theme_content], theme_att) + + let head = newXmlTree("head", [charset, style]) + + html.insert(head, 0) + +proc bytesToBase64(bytes: seq[byte]): string = + return " data:image/jpeg;charset=utf8;base64," & bytes.encode() + +proc pathToBytes(path: string): seq[byte] = + const block_size = 4096 + + var + buffer: array[block_size, byte] + bytes: seq[byte] + total_bytes_readed = 0 + + let strm = openFileStream(path, fmRead) + + while true: + let bytes_readed = strm.readData(addr(buffer), block_size) + if bytes_readed == 0: + break + bytes.add(buffer[0.. 0: + let img_path = possible_attempts[0] + src = img_path.pathToBytes().bytesToBase64() + node.attrs["src"] = src + + # let img_bytes = pathToBytes(src) + +when isMainModule and declared(commandLineParams): + let + params = commandLineParams() + md_src = absolutePath(params[0]) + md_root = splitFile(md_src).dir + theme_src = params[1] + + let raw_md = readFile(md_src).replace(re2"!\[\[(.+)\]\]", "") + let raw_html = markdown(raw_md, config=initGfmConfig()) + let parsed_html = parseHtml(raw_html) + + let raw_theme = readFile(theme_src) + + embedImages(parsed_html, md_root) + applyTheme(parsed_html, raw_theme) + + echo parsed_html +