LOWDOWN-DIFF(1)

๐Ÿ’… lowdown-diff โ€” the manual page (part 1)

okay so bestie, welcome to LOWDOWN-DIFF(1) โ€” General Commands Manual energy, tiny tool, huge personality. sit down, grab a strawberry ๐Ÿ“, and let's get into it.


โœจ NAME โœจ

lowdown-diff โ€” view differences in markdown files. that's it, that's the vibe. ๐Ÿฆ‹


โœจ SYNOPSIS โœจ

lowdown-diff [input_options] [output_options] [-s] [-M metadata]
             [-m metadata] [-o file] [-t mode] oldfile [newfile]

โœจ DESCRIPTION โœจ

So what does this icon actually do? It shows differences between lowdown(5) documents as formatted output. Like, you feed it two markdown files and it tells you what changed โ€” but pretty. Results are written to standard output. slay. ๐Ÿ’–

The short arguments are as follows:

  • -s โ€” produce a standalone document (e.g., a valid HTML document including document type, head, etc.) around the formatted content. See โ€œStandalone documentsโ€ for the deets. ๐ŸŽ€
  • -M metadata โ€” provide a single metadata key-value pair. This may be in the normal syntax or as pairs separated by an equal sign, depending upon which character (a colon or equal sign) comes first. Exits with an error if given neither. This overrides -m and what's parsed from the document. See โ€œMetadataโ€. no cap, -M always wins ๐Ÿ’…
  • -m metadata โ€” like -M, but overridden by what's parsed the document, then -M. so the priority chain is literally document โ†’ -m โ†’ -M, -M sitting at the top like the main character it is.
  • -o file โ€” send output to file unless it's โ€œ-โ€, in which case fall back to the default of standard output. ๐Ÿซถ
  • -t mode, -T mode โ€” the output mode. This may be:
    • html for HTML5 output
    • latex for LaTeX
    • gemini for the Gemini โ€œgemtextโ€ format
    • ms for roff output using the -mspdf package and needing table support
    • term for ANSI-compatible UTF-8 terminal output
    • man for roff output using the -man package
    • mdoc for roff output using the -mdoc package
    • tree, to show the parse tree of the input document
    • null to parse the document but do no rendering

See โ€œOutput mediaโ€. oh and btw, the -T mode form is retained for backward compatibility โ€” it's giving legacy, but we respect it. ๐Ÿ™ˆ

  • oldfile, newfile โ€” markdown documents used for comparison. If newfile is not given or โ€œ-โ€, it is read from standard input. ๐Ÿ’€ classic stdin behaviour.

The following are long options for input parsing. These affect the parse tree passed to all outputs. (so like, they change the tree before any renderer gets its hands on it โ€” big deal energy ๐Ÿ”ฅ)

  • --parse-hilite โ€” enable highlight span support. This are disabled by default because it may be erroneously interpreted as section headers. yes, that's a real risk, don't come for me. ๐ŸŒธ
  • --parse-math โ€” recognise mathematics equations. math girlies rise ๐Ÿงš
  • --parse-maxdepth=depth โ€” the maximum depth of nested elements. This defaults to 128, which is probably more than enough for any real-world document. If the maximum is hit, the system exits as if memory were exhausted. Set to zero for no maximum. so basically: chaos mode is available, but it is chaos. ๐Ÿ˜ญ
  • --parse-no-autolink โ€” do not parse http, https, ftp, mailto, and relative links or link fragments. links stay plain, no glow-up. โœจ
  • --parse-no-cmark โ€” do not parse with CommonMark constraints. This also disables using the first ordered list value instead of starting all lists at one. ๐ŸŽ€
  • --parse-no-codeindent โ€” do not parse indented content as code blocks. four spaces? just vibes now.
  • --parse-no-callouts โ€” do not parse GFM/MDN callouts (โ€œadmonitionsโ€). no shouty boxes for you. ๐Ÿ“ฃ
  • --parse-no-deflists โ€” do not parse PHP extra definition lists.
  • --parse-no-ext-attrs โ€” do not parse PHP extra extended attributes.
  • --parse-no-fenced โ€” do not parse GFM fenced (language-specific) code blocks. bye bye ``` fences ๐Ÿ’…
  • --parse-no-footnotes โ€” do not parse MMD footnotes. no little endnotes hiding at the bottom.
  • --parse-no-img-ext โ€” deprecated. See --parse-no-ext-attrs. it's giving old news, move on bestie ๐Ÿ™ˆ
  • --parse-no-intraemph โ€” do not parse emphasis within words and links. like in*side*word? no ma'am.
  • --parse-no-mantitle โ€” do not parse manpage title, section, source, and volume from Pandoc title metadata. Manpages titles are indicated by a title then an open parenthesis, digit followed by optional characters, then a closed parenthesis. (that's the whole name(1) situation, iykyk ๐Ÿ‘‘)
  • --parse-no-metadata โ€” do not parse metadata. This does not affect metadata given on -m or -M. so the flags still work, only the in-document stuff gets skipped. ๐Ÿซถ
  • --parse-no-strike โ€” do not parse strikethroughs. ~~nothing gets crossed out~~, sorry, nvm, nothing gets crossed out.
  • --parse-no-super โ€” do not parse super-scripts or sub-scripts at all. no ^ no ~, none of it. โญ
  • --parse-no-tables โ€” do not parse GFM tables. no grid, no glamour. ๐Ÿ’€
  • --parse-no-tasklists โ€” do not parse GFM task lists. no checkboxes, no ticking things off.
  • --parse-super-short โ€” if super-script parsing is enabled, use the traditional non-GFM โ€œshortโ€ syntax. throwback edition ๐Ÿฆ‹

๐ŸŒˆ output long options โ€” the shared ones

There are many output long options. The following are shared by all output media:

  • --out-standalone โ€” alias for -s. same energy, longer name.
  • --out-no-smarty โ€” do not use the smart typography filter. By default, certain character sequences are translated into output-specific glyphs. (yes, the curly quotes are watching you ๐Ÿ‘€)
  • --template template โ€” when producing standalone -s output, use a template file. See โ€œTemplatesโ€. Currently only for -tgemini, -thtml, -tlatex, -tman, -tms, and -ttree. so check your mode first, bestie. ๐ŸŽ€

๐ŸŒธ HTML options โ€” for -thtml

What follows are per-output long options. For HTML with -thtml, these are as follows:

  • --html-callout-mdn, --html-callout-gfm โ€” output either or both MDN or GFM callout syntaxes. pick your fighter, or don't, both is valid ๐Ÿ’…
  • --html-hardwrap โ€” hard-wrap paragraph content by outputting line breaks where applicable. aggressive line breaks, on purpose.
  • --html-no-escapehtml โ€” if --html-no-skiphtml has been specified, this causes embedded HTML not to be escaped, and is instead output verbatim. This has no effect if --html-no-skiphtml has not been specified. read that one twice, it's a two-flag situation ๐Ÿ”ฅ
  • --html-no-head-ids โ€” do not output id attributes for headers. no anchors, no jump-links.
  • --html-no-num-ent โ€” don't normalise HTML entities (when possible) as numeric ones and instead use the entities as given on input. honour the original, periodt โœจ
  • --html-no-owasp โ€” don't follow the OWASP recommendations for escaping text, and do only the minimal escaping to make sure that regular content isn't interpreted as HTML. > โš ๏ธ okay so like, this is the minimal safety setting โ€” the original says OWASP escaping is the thing being skipped, so know that you're trading safety for vibes here.
  • --html-no-skiphtml โ€” output embedded HTML. By default, embedded HTML is not output at all. See --html-no-escapehtml. ๐Ÿซถ
  • --html-titleblock โ€” if any were parsed, format the title information (title, author, date) into a header element appearing first in the document. cute lil title card, main character energy ๐Ÿ‘‘

๐Ÿ”ฅ roff options โ€” for -tman, -tmdoc, and -tms

For roff formats -tman, -tmdoc, and -tms (unless as noted), the following apply:

  • --roff-code-font=fonts โ€” override the default constant-width fonts with a tuple of regular, bold, italic, and bold-italic variants in that order. For example, B,B,BI,BI uses bold (โ€œBโ€) instead of a constant-width. Not specifying a font will use the default, as will specifying a zero-length font name. Aliases none, bold, and code set no special fonts, bold, and the default constant-width. tuple order matters, don't come for me ๐ŸŽ€
  • --roff-endnotes โ€” delay printing of footnotes until the end of the document. Only applies to -tms, as -tman and -tmdoc only support endnotes. so like, those two are already endnote-only, no choice given ๐Ÿ˜ญ
  • --roff-manpage โ€” format output as a manpage. This re-formats paragraphs under the NAME, SYNOPSIS, and SEE ALSO sections in the canonical form used by manpages. The way the document is formatted depends upon the section metadata: 1, 6, and 8 for program-style; 2, 3, and 9 for function-style. Program style re-formats flags and arguments, while function style re-formats function names, variables, arguments. Any content in font spans (e.g., emphasis or double emphasis) in other sections is stripped of the font and re-formatted in the same way. Only applies to -tman and -tmdoc. this is the whole โ€œlooking like a real manpageโ€ button ๐Ÿ’…
  • --roff-no-numbered โ€” don't output numbered headings (.NH NN). Only applies to -tms.
  • --roff-no-skiphtml โ€” output embedded HTML. This usually doesn't make sense because the HTML won't be interpreted by the output reader. By default, HTML is omitted. so like, it works but nobody's reading it ๐Ÿ™ˆ
  • --roff-no-links โ€” when possible, don't show URLs for images and links. Link content is always shown. Overrides --roff-short-links and --roff-no-rellinks. the content stays, only the URL gets shy ๐Ÿซถ
  • --roff-no-rellinks โ€” when possible, don't show URLs for relative links. Link content is always shown. Overrides --roff-short-links.
  • --roff-short-links โ€” when possible, shorten URLs for images, links, and autolinks to only the domain name and final path. cute lil trimmed URL โœจ
  • --roff-traditional โ€” output traditional -ms (not -mspdf) and -man without extensions. Specifically, don't use hyperlink macros (.pdfhref, .UR, .MT), multi-page tables (.TS H, .TH), Unicode sequence syntax (\[uNNNN]), example block macros (.EX), modern section headings (.NH NN, .SH NN, .pdfhref O NN), or intra-document links (.pdfhref L). The output is compatible with troff(1). old-school, no extensions, extremely vintage of it โญ

The argument prefix --nroff, such as in --nroff-traditional, is deprecated in favour of --roff. it's giving legacy naming, we've moved on ๐Ÿฆ‹


๐Ÿ–ฅ๏ธ term options โ€” for -tterm

The -tterm output has the following:

  • --term-all-metadata โ€” if -s is specified, output all metadata instead of just the title, author, and date. so -s plus this = the whole metadata dump ๐Ÿ’–
  • --term-columns=columns โ€” the number of columns in the terminal. Useful for when running in a pipe. Defaults to what the terminal reports or 72 if not in a terminal. pipe girlies, set this one ๐Ÿ˜ญ
  • --term-hmargin=margin โ€” the number of left margin characters. Defaults to zero. Can also be auto to set the left margin to half the remaining --term-columns after subtracting --term-width. math, but make it layout โœจ
  • --term-hpadding=padding โ€” the number of left padding characters. Defaults to four. Padding eats into --term-width. yes, it eats it, that's the actual wording, respect it ๐Ÿ“
  • --term-no-ansi โ€” don't show ANSI styles at all. Use backspace encoding instead for bold/underline. This implies --term-no-colour. retro encoding, iconic ๐Ÿ’…
  • --term-no-colour โ€” don't show ANSI colours. This will still decorate text with underlines, bolds, and italics, but not emit any colour codes. style stays, colour dips ๐ŸŒˆ
  • --term-no-links โ€” when possible, don't show URLs for images and links. Link content is always shown. Overrides --term-short-links and --term-no-rellinks.
  • --term-no-rellinks โ€” when possible, don't show URLs for relative links. Link content is always shown. Overrides --term-short-links. so this one outranks --term-short-links, noted ๐Ÿซถ
  • --term-no-style โ€” don't use any escape styles at all. This implies --term-no-ansi. full plain-text mode, no cap ๐ŸŽ€
  • --term-no-tablewrap โ€” don't wrap table columns to fit the width of the output. horizontal scroll girlies, this is your moment ๐Ÿ’€
  • --term-short-links โ€” when possible, shorten URLs for images, links, and autolinks to only the domain name and final path.
  • --term-vmargin=margin โ€” the number of top and bottom margin newlines. Defaults to zero. breathing room, if you want it ๐ŸŒธ
  • *--term-width=width*** โ€” a soft limit on how many characters can fit on a line, including</pink> --term-hpadding. Soft means soft, bestie โ€” literal text can absolutely blow right past it. If it's zero or just not set, it falls back to --term-columns, or 80 at most. And it truncates to --term-columns. ๐Ÿ’…

Okay so the -tgemini output has a whole little crew of flags that control where links go. Default behaviour, no cap: links (images, autolinks, and links) get queued when they're specified in-line, then emitted in a block sequence right after the nearest block element. ๐ŸŽ€

  • --gemini-link-end โ€” dumps the whole queue of links at the end of the document instead of after the nearest block element. Big fan of the dramatic finale energy. โœจ
  • --gemini-link-inline โ€” renders all links right there in the flow of text. Careful though โ€” this will cause breakage when you've got nested links, like images inside links, links in blockquotes, etc. Don't use it unless your document is carefully crafted, iykyk. ๐Ÿ’€
  • --gemini-link-noref โ€” don't format link labels at all. Takes precedence over --gemini-link-roman. ๐Ÿ‘‘
  • --gemini-link-roman โ€” when formatting link labels, use lower-case Roman numerals instead of the default lower-case hexavigesimal (i.e., โ€œaโ€, โ€œbโ€, ..., โ€œaaโ€, โ€œabโ€, ...). Rome-core. ๐Ÿ›๏ธ
  • --gemini-metadata โ€” prints metadata as the canonicalised key, then a colon, then the value, each one on its own line (newlines get replaced by spaces). The metadata block is terminated by a double newline. If there's no metadata? Does literally nothing. ๐Ÿ™ˆ

The -tlatex output has these options:

  • --latex-no-numbered โ€” don't number sections (and subsections, etc.). Unnumbered and unbothered. ๐ŸŒธ
  • --latex-no-skiphtml โ€” output embedded HTML. Tbh this usually doesn't make sense, because the HTML won't be interpreted by the output reader. By default, HTML is omitted. ๐Ÿซถ

The -tfodt output has these options:

  • --odt-no-skiphtml โ€” output embedded HTML. Same deal, this usually doesn't make sense because the HTML won't be interpreted by the output reader. By default, HTML is omitted. โœจ
  • --odt-style=file** โ€” specify an OpenDocument style file. It must consist of at least <office:font-face-decls>, <office:scripts>, and <office:styles>` XML elements in the root of the document. And ngl, this is **not syntax-checked in any way. So, like, be responsible. ๐Ÿ˜ญ

๐ŸŽจ Output media

The output media is specified by -t, which defaults to -thtml.

  • -tfodt โ€” โ€œFlatโ€ OpenDocument output. Automatic styles (those conditional upon document state) are generated with output. Classes specified by PHP extended attributes are not checked for existence. ๐Ÿฆ‹
  • -tgemini โ€” Gemini โ€œgemtextโ€ format. โœจ
  • -thtml โ€” HTML5 output with UTF-8 encoding. The main character of output formats, honestly. ๐Ÿ‘‘
  • -tlatex โ€” simple LaTeX output. The following packages are required: amsmath and amssymb for maths, graphicx for images, inputenc (utf8) for UTF-8 input, frontend (T1) and textcomp for output glyphs, lmodern for Latin modern font, xcolor for the difference engine output, and hyperref for links. It's giving โœจacademiaโœจ.
  • -tman โ€” the man macro package, suitable for reading by groff(1), mandoc(1), Heirloom troff(1), or traditional troff(1). Does not support equations and images. Table support is provided by tbl(1). And heads up โ€” since UTF-8 may be passed as input values, preconv(1) may need to be used. ๐Ÿ’œ
  • -tmdoc โ€” the mdoc macro package, suitable for reading by groff(1), mandoc(1), Heirloom troff(1), or (possibly?) traditional troff(1). Does not support equations and images. Table support is provided by tbl(1). Since UTF-8 may be passed as input values, preconv(1) may need to be used. ๐ŸŽ€
  • -tms โ€” the ms macro package, suitable for reading by groff(1) or traditional troff(1). Does not support equations, and has limited image support for encapsulated postscript (PS and EPS suffix) images. Images are always block-formatted. Image dimensions and extended attributes are ignored, though images are downsized if larger than the current text width. Table support is provided by tbl(1). Since UTF-8 may be passed as input values, preconv(1) may need to be used. ๐Ÿ˜ฎโ€๐Ÿ’จ
  • -tterm โ€” ANSI-escaped UTF-8 output, suitable for reading on the terminal. Images and equations not supported. ๐Ÿ–ฅ๏ธ
  • -ttree โ€” debugging output. Not for programmatic use, because the format may change between versions. ๐Ÿ™ˆ

๐Ÿฆ‹ Differences

The differences between old and new document are illustrated in the following ways:

  • -tfodt โ€” โ€œFlatโ€ Differences are rendered using document tracking. ๐Ÿ“
  • -tgemini โ€” Differences are not rendered. We simply do not perceive them. ๐Ÿ’€
  • -tlatex โ€” Differences are rendered by colouring in blue (insert) and red (delete) (this format is not fixed). ๐Ÿ’™โค๏ธ
  • -tman, -tmdoc, -tms โ€” Differences are rendered by colouring in blue (insert) and red (delete) (this format is not fixed). ๐Ÿ’™โค๏ธ
  • -tterm โ€” Differences are rendered by background-colouring in blue (insert) and red (delete) (this format is not fixed). ๐Ÿ’™โค๏ธ
  • -ttree โ€” Differences are manually in the tree output. ๐Ÿงš

Differences in content metadata use the following rule: deleted metadata key-value pairs are not processed in the output, so only inserted or retained metadata are processed. Periodt. โœจ

๐ŸŒˆ Standalone documents

When -s is specified, the formatted content is serialised into a self-contained document template as defined by the output type.

If not explicitly set with --template, a default template is produced as follows:

  • -tfodt โ€” envelope <office:document> and prologue <office:automatic-styles>, <office:master-styles>, and <office:body>. ๐ŸŽ€
  • -thtml โ€” HTML5 doctype declaration followed by envelope <html> with optional language, then <head>. In order, the <head> consists of charset and viewport <meta> elements; optional <meta> elements from metadata affiliation (creator), author, copyright, and date; optional CSS sources from metadata; optional JavaScript sources from metadata; the possibly-empty <title>; then optional arbitrary content from metadata HTML header. That's a lot of head, bestie. ๐Ÿ’…
  • -tlatex โ€” prologue documentclass and usepackage statements, optional arbitrary content from metadata LaTeX header, then surrounding begin{document} statements. ๐Ÿ“œ
  • -tman, -tmdoc, -tms โ€” prologue macros. ๐Ÿซถ
  • -tterm โ€” prologue lines. โญ
  • -ttree โ€” metadata and parsed template. ๐ŸŒธ

See โ€œMetadataโ€ for metadata values used by the default template.

๐Ÿ’– Metadata

Metadata keys are canonicalised and de-deduplicated in the following order: -m (overridden by document content and -M), the prologue of the document itself, then -M (overriding document content and -m). Yes, the last one wins. It's giving survival of the fittest. ๐Ÿ”ฅ

After de-duplication, metadata is serialised into document variables and/or standalone -s output.

When not using --template, the following metadata keys are used in the default -s template:

  • affiliation โ€” author affiliation (organisation or institution). Multiple affiliations may be separated by two or more spaces (including newlines). Used in -thtml, -tlatex, and -tms. ๐Ÿซ
  • author โ€” document author. Multiple authors may be separated by two or more spaces (including newlines). Overridden by rcsauthor. Used in -tfodt, -thtml, -tlatex, -tms, and -tterm. ๐Ÿ‘‘
  • baseheaderlevel โ€” added to each header level. Deprecated in favour of shiftheadinglevelby. Don't be that girl, use the new one. ๐Ÿ™ˆ
  • copyright โ€” a document copyright (without the word โ€œCopyrightโ€), for example, โ€œ2017, Kristaps Dzonsonsโ€. Used in -tms and -thtml. ยฉ๏ธ
  • css โ€” a CSS file output in the HTML document head as a <link rel="stylesheet" href="..." /> statement. Multiple CSS files (in order) may be separated by two or more spaces (including newlines) and are output in the given order. Only used in -thtml. ๐ŸŽจ
  • date โ€” document date in ISO-8601 YYYY-MM-DD format. Overridden by rcsdate. Used in -tfodt, -thtml, -tlatex, -tman, -tmdoc, -tms, and -tterm. ๐Ÿ“…
  • htmlheader โ€” arbitrary HTML content output in the HTML document head immediately prior to closing the head element. Only used in -thtml and with -s. This metadata is not processed: it's passed unchanged into the output. ๐Ÿซถ
  • javascript โ€” a JavaScript file output in the HTML document head as a <script src="..."></script> statement. Multiple script files (in order) may be separated by two or more spaces (including newlines) and are output in the given order. Only used in -thtml. โšก
  • lang โ€” document language in RFC 5646 format. Only used in -thtml. ๐ŸŒ
  • latexheader โ€” arbitrary LaTeX content output in the document prologue immediately prior to the begin{document}. Only used in -tlatex and with -s. This metadata is not processed: it's passed unchanged into the output. ๐Ÿ“œ
  • manheader โ€” arbitrary roff content output immediately prior to the .TH macro. Only used in -tman and with -s. This metadata is not processed: it's passed unchanged into the output. ๐Ÿ’œ
  • msheader โ€” arbitrary roff content output immediately prior to the .TL macro. Only used in -tms and with -s. This metadata is not processed: it's passed unchanged into the output. ๐Ÿ’œ
  • rcsauthor โ€” like author, but in RCS author format. Overrides author. ๐Ÿ†
  • rcsdate โ€” like date, but in RCS date format. Overrides date. ๐Ÿ†
  • section โ€” man page section, defaulting to โ€œ7โ€. Only used in -tman and -tmdoc. ๐Ÿ“–
  • shiftheadinglevelby โ€” shift all headers by the given number. For example, a value of 1 causes headers originally at level 1 (โ€œ<h1>โ€) to be level 2 (โ€œ<h2>โ€), while a value of -1 moves level 2 to 1. Levels will not move to less than 1. Takes precedence over baseheaderlevel. If unset or not a valid number, defaults to zero. Used in -tfodt, -thtml, -tlatex, -tman, -tmdoc, and -tms. ๐Ÿชœ
  • source โ€” man page source (organisation providing the manual). Only used in -tman and -tmdoc. ๐Ÿข
  • volume โ€” man page volume (describes the manual page section). Only used in -tman and -tmdoc. ๐Ÿ“š
  • title โ€” document title. Used in -tfodt, -thtml, -tlatex, -tman, -tmdoc, -tms, and -tterm. โœจ

Default values, such โ€œ7โ€ for the section, are not set as metadata values, and will not appear if the metadata key is used as a variable. Sneaky little defaults. ๐Ÿ™ˆ


๐Ÿงš Templates

Some output media accept a template (--template) to customise standalone (-s) output. Parsed input content is filled into templates through control statements that support conditionals, loops, and variable transformation sequences. Honestly? Iconic. ๐Ÿ’…

ok so control statements are delimited as $statement$ or ${statement} โ€” that's the whole vibe ๐Ÿ’…. Arbitrary white-space may surround the case-insensitive statement between the matching delimiters, so you can space it out however you like. And if a statement is missing its closing delimiter? It's just considered opaque text, like, it's not even invited to the party ๐Ÿ™ˆ.

The following statements are available, bestie:

  • $$, ${} โ€” outputs a literal $. Yep, this one may contain arbitrary white-space. Iconic.
  • $ifdef(expression)$ โ€” the conditional statement. Heads up: there may not be any white-space between the ifdef and the opening parenthesis, so keep 'em glued together ๐Ÿซถ. It begins a block that gets ended by a else, endif, or the end of file. Its contents are output only if expression evaluates to a non-empty string.
  • $else$ โ€” begins a block that's ended by a endif or the end of file. Its contents are output only if the condition of a preceding ifdef evaluates to an empty string. An else with no preceding ifdef? Yeah it's just not output, sorry babe ๐Ÿ’€.
  • $endif$ โ€” closes a block begun with ifdef or else. If it's not preceded by one of those statements, it's silently ignored. no drama, no error, it just minds its business.
  • $for(expression)$ โ€” the looping statement. Again, no white-space between the for and the opening parenthesis โœจ. Begins a block ended by an endfor or the end of file. The block contents are repeatedly output for each list item evaluated from expression. And the anaphoric keyword this may be used to access the current loop expression within the block โ€” main character energy for real.
  • $expression$ โ€” replaced by the result of evaluating a template expression. simple as that.

Here's a lil trick that's lowkey iconic: if a control statement ends with two consecutive hyphens before the closing delimiter, input is consumed up to and including the next newline or until end of file ๐ŸŒˆ. This lets line-sensitive output media use control statements without leaving superfluous blank lines everywhere. chef's kiss.


Expressions consist of

initial[([arg]*)]?[.transform[([arg]*)]?]*,

or an initial value accepting optional arguments followed by an optional series of transforms accepting optional arguments. If an argument list is empty or not provided, it evaluates to an empty list. noted ๐Ÿ“.

The initial value is one of the following:

  • and(expression[,expression]*) โ€” a non-empty list containing the value true if all expressions evaluate to non-empty lists, otherwise an empty list. An empty expression evaluates to an empty list.
  • "literal string" โ€” evaluates to a singleton list containing the string. An empty string evaluates to an empty list. The double quote character may be escaped, such as "foo\"bar" ๐ŸŽ€.
  • body โ€” the parsed input document body.
  • canonicalised metadata key โ€” the value for the given metadata key, if found, otherwise an empty list.
  • body โ€” the parsed input document body. (yes bestie it's listed twice in the source, we don't make the rules, we just keep the receipts ๐Ÿ’€)
  • meta(key) โ€” produces the metadata value for the canonicalised metadata key. This one's for the keys that are also keywords like body or endif โ€” iykyk.
  • not(expression) โ€” a non-empty list containing the value true if the expression evaluates as an empty list, otherwise an empty list.
  • or(expression[,expression]*) โ€” a non-empty list containing the value true if one expression evaluates to non-empty lists, otherwise an empty list. An empty expression evaluates to an empty list.
  • this โ€” the value of a current loop context, or an empty list.

If a metadata key isn't specified in the input, or if the anaphoric this hasn't been initialised by a looping context, the initial value evaluates to an empty list. Otherwise, the value is a singleton list โœจ. And if transforms are invalid, they'll transform into an empty list โ€” no cap.

The following transformations are available:

  • escapegemini, escapegeminiline โ€” escape list items for gemini (-tgemini), either for multiple lines or compressed to a single line.
  • escapehtml, escapehtmlattr, escapehtmlurl โ€” escape list items for HTML (-thtml) body content, attributes, and URL attributes, respectively.
  • escapelatex โ€” escape list items for LaTeX (-tlatex) body content.
  • escaperoff, escaperoffline โ€” escape list items for roff (-tms, -tman, -tmdoc), either for multiple lines or compressed to a single line. fun fact: escaperoff also escapes initial roff delimiters and those after newlines ๐Ÿ”ฅ.
  • join โ€” joins a list into a singleton list using two spaces as a join delimiter.
  • lowercase โ€” lowercases all list items.
  • split โ€” splits list items on sequences of two or more white-space tokens (space, newline, tab). This is usually invoked on a singleton, but it may be repeatedly invoked on a pre-split list. Invokes trim prior to the first split. The resulting list has no items that are only white-space.
  • trim โ€” trims white-space from the beginning and end of all list items. If an item has no non-white-space, it's discarded. bye felicia ๐Ÿ‘‹.
  • uppercase โ€” uppercases all list items.

๐ŸŒฟ ENVIRONMENT ๐ŸŒฟ

  • NO_COLOR โ€” do not emit colours when in -tterm mode. It's a synonym for NO_COLOUR, and same as --term-nocolour ๐ŸŽจ.

๐Ÿ“ FILES ๐Ÿ“

  • share/html/default.html โ€” the default template used if --template is not provided to -thtml.
  • share/latex/default.latex โ€” the default template used if --template is not provided to -tlatex.
  • share/man/default.man โ€” the default template used if --template is not provided to -tman.
  • share/man/default.ms โ€” the default template used if --template is not provided to -tms.
  • share/odt/styles.xml โ€” the default styles used when generating standalone -tfodt documents. It's also the template for --odt-style styles ๐Ÿฆ‹.

๐Ÿšช EXIT STATUS ๐Ÿšช

The lowdown-diff utility exits 0 on success, and >0 if an error occurs. slay when it works, ๐Ÿ˜ญ when it doesn't.


โœจ EXAMPLES โœจ

Wanna view Markdown differences on an ANSI-compatible, UTF-8 terminal? say less:

lowdown-diff -tterm old.md new.md | less -R

To emit a standalone HTML5 document ๐Ÿ‘‘:

lowdown-diff -s old.md new.md > foo.html

To use groff(1) to format as a PS file:

lowdown-diff -stms old.md new.md | \
  groff -itk -mspdf > foo.ps

Or with LaTeX ๐Ÿ’œ:

lowdown-diff -stlatex old.md new.md > foo.latex
pslatex foo.latex

PDF generation follows similar logic:

lowdown-diff -stms old.md new.md | \
  pdfroff -itk -mspdf > foo.pdf
lowdown-diff -stlatex old.md new.md > foo.latex
pdflatex foo.latex
Heads up bestie: UTF-8 support for groff(1) PDF or PS output requires appropriate fonts, such as the Unicode Times font. This and other Unicode fonts are not always installed by default ๐Ÿ˜ญ. They may be found, for PDF output, in the devpdf set of the groff(1) font directory and are prefixed with โ€˜Uโ€™.
lowdown-diff -stms old.md new.md | \
  pdfroff -itk -mspdf -FU-T > foo.pdf

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

lowdown(1), lowdown(3), lowdown(5) โ€” go read those too, bestie, they're literally right there ๐Ÿ’–.


๐Ÿ’– AUTHORS ๐Ÿ’–

lowdown-diff was written by Kristaps Dzonsons, kristaps@bsd.lv. absolute legend behavior.


โš ๏ธ CAVEATS โš ๏ธ

When viewing -tman or -tmdoc differences with mandoc(1), the marker colours are not rendered ๐Ÿ™ˆ. And the -tgemini output also currently has no way of encoding differences. it's giving "we're working on it" energy, fr fr.


ok that's the whole page, bestie ๐ŸŽ€ this one's straight from the Debian fam, dated $Mdocdate$, and it's LOWDOWN-DIFF(1) โ€” now go diff some markdown and live your truth ๐Ÿ’…โœจ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from