diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-08-24 18:10:33 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-08-24 18:10:33 +0200 |
commit | d0690bc311ee4969fc35604fed0fe819d4938704 (patch) | |
tree | 647187fb8f275f9a4db5d9edd99c742cda147da7 /src/nix/markdown.cc | |
parent | 0f314f3c2594e80322c675b70a61dcfda11bf423 (diff) |
nix repl ':doc': Render using lowdown
Diffstat (limited to 'src/nix/markdown.cc')
-rw-r--r-- | src/nix/markdown.cc | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/nix/markdown.cc b/src/nix/markdown.cc new file mode 100644 index 000000000..40788a42f --- /dev/null +++ b/src/nix/markdown.cc @@ -0,0 +1,50 @@ +#include "markdown.hh" +#include "util.hh" +#include "finally.hh" + +#include <sys/queue.h> +extern "C" { +#include <lowdown.h> +} + +namespace nix { + +std::string renderMarkdownToTerminal(std::string_view markdown) +{ + struct lowdown_opts opts { + .type = LOWDOWN_TERM, + .maxdepth = 20, + .cols = std::min(getWindowSize().second, (unsigned short) 80), + .hmargin = 0, + .vmargin = 0, + .feat = LOWDOWN_COMMONMARK | LOWDOWN_FENCED | LOWDOWN_DEFLIST | LOWDOWN_TABLES, + .oflags = 0, + }; + + auto doc = lowdown_doc_new(&opts); + if (!doc) + throw Error("cannot allocate Markdown document"); + Finally freeDoc([&]() { lowdown_doc_free(doc); }); + + size_t maxn = 0; + auto node = lowdown_doc_parse(doc, &maxn, markdown.data(), markdown.size()); + if (!node) + throw Error("cannot parse Markdown document"); + Finally freeNode([&]() { lowdown_node_free(node); }); + + auto renderer = lowdown_term_new(&opts); + if (!renderer) + throw Error("cannot allocate Markdown renderer"); + Finally freeRenderer([&]() { lowdown_term_free(renderer); }); + + auto buf = lowdown_buf_new(16384); + if (!buf) + throw Error("cannot allocate Markdown output buffer"); + Finally freeBuffer([&]() { lowdown_buf_free(buf); }); + + lowdown_term_rndr(buf, nullptr, renderer, node); + + return std::string(buf->data, buf->size); +} + +} |