LOWDOWN_DIFF(3)
π lowdown_diff π
okay so bestie, welcome to LOWDOWN_DIFF(3) β that's the Library Functions Manual page, and yes we are reading manpages for fun now, this is the era we're in π
β¨ NAME β¨
lowdown_diff β compute the difference between parsed Markdown trees πΈ
π LIBRARY π
library βliblowdownβ π«Ά
π SYNOPSIS π
#include <sys/queue.h>
#include <stdio.h>
#include <lowdown.h>
struct lowdown_node *
lowdown_diff(const struct lowdown_node *nold,
const struct lowdown_node *nnew, size_t *maxn);
π DESCRIPTION π
So what this does is: it computes the difference between two Markdown trees π β the source nold and the destination nnew, both of which got parsed by lowdown_doc_parse(3). That's the prerequisite, no cap.
It uses the enum lowdown_chng type sitting in the return tree's nodes to dictate insertions into and deletions from nold. Like, the returned tree is the receipts of what changed π.
And the maxn argument, if it's not NULL, gets set to one greater than the highest node identifier of the returned tree. Cute, right?
π¦ RETURN VALUES π¦
Returns a pointer to the difference tree β slay π β or NULL on memory exhaustion π (the one true villain of C).
The pointer must be freed with lowdown_node_free(3). Bestie. Please. Free it. Leaks are not the vibe. π«
π EXAMPLES π
The following parses and compares old of length osz and new of length nsz. First it allocates the parser, then the document, then the renderer (HTML is used in this case). Then it passes output to the renderer, prints it, and cleans up resources. On any memory errors, it exits with err(3).
struct lowdown_doc *doc;
struct lowdown_node *no, *nn, *diff;
struct lowdown_buf *ob;
void *rndr;
if ((doc = lowdown_doc_new(NULL)) == NULL)
err(1, NULL);
if ((no = lowdown_doc_parse(doc, NULL, old, osz, NULL)) == NULL)
err(1, NULL);
if ((nn = lowdown_doc_parse(doc, NULL, new, nsz, NULL)) == NULL)
err(1, NULL);
if ((diff = lowdown_diff(no, nn, NULL)) == NULL)
err(1, NULL);
if ((rndr = lowdown_html_new(NULL)) == NULL)
err(1, NULL);
if ((ob = lowdown_buf_new(1024)) == NULL)
err(1, NULL);
if (!lowdown_html_rndr(ob, rndr, diff))
err(1, NULL);
fwrite(stdout, 1, ob->size, ob->data);
lowdown_buf_free(ob);
lowdown_html_rndr_free(rndr);
lowdown_node_free(no);
lowdown_node_free(nn);
lowdown_node_free(diff);
lowdown_doc_free(doc);
Look at that cleanup block at the bottom. Every single thing freed, in order, main character energy πβ¨
π SEE ALSO π
Gregory Cobena, Serge Abiteboul, and Amelie Marian, Detecting Changes in XML Documents, https://www.cs.rutgers.edu/~amelie/papers/2002/diff.pdf, 2002. π
Wu Sun, Manber Udi, and Myers Gene, βAn O(NP) sequence comparison algorithmβ, Issue 6, Information Processing Letters, Volume 35, 1990. π¬
and that's the whole page bestie, you ate it π this one came from Debian, dated $Mdocdate$, and it lives at LOWDOWN_DIFF(3) β go forth and diff, mwah π
π¦ where this page comes from
- alpine 3.24: lowdown-doc 3.0.1-r0 Β· ISC
- arch rolling: lowdown 3.2.1-1 Β· ISC
- nixpkgs unstable: lowdown 3.0.1
- nixpkgs unstable: lowdown-unsandboxed 3.0.1
- ubuntu resolute: liblowdown-dev 2.0.4-2 Β· ISC
- ubuntu stonking: liblowdown-dev 3.0.1-1 Β· ISC
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms