Name

org-cli-tangle — tangle source code blocks in Emacs org-mode files from the command line

Synopsis

org-cli-tangle -- --help

org-cli-tangle -- --version

org-cli-tangle -- FILE [...]

org-cli-tangle -- OPTIONS FILE [...]

Description

org-cli-tangle is an Emacs (emacs(1)) script that invokes org-babel-tangle-file to tangle ("extract") source code blocks from the org-mode files specified on the command line.

The first form above prints a usage message and exits, while the second form prints the current version of org-cli-tangle and exits.

The third form will normally be sufficient to tangle one or more org-mode files.

The fourth form allows for more options in tangling one or more org-mode files, should those be necessary or of use.

The main benefit of org-cli-tangle is probably to help set the org-mode variable org-babel-load-languages depending on options on the command line and/or the contents of the file to be tangled, and then tangle the file.

Additionally, in the fourth form above, org-cli-tangle checks that the languages in the source code blocks matches languages specified in the OPTIONS (though there are options to modify or eliminate this check).

Finally, again using options as in the fourth form, org-cli-tangle can also restrict (by language) which source code blocks are tangled.

Options

--
options before the ‘--` should be Emacs options. one could specify things like -Q, -q, (to restrict processing of one or more Emacs startup files) -L (to add load libraries to Emacs’ load path), etc., especially if needed to find Emacs libraries such as org (if, say, a newer, preferred version is installed on the local machine). if passing any options (beginning with one or more dashes -) do not forget to specify the --, since otherwise Emacs itself may interpret the option, rather than passing it on to org-cli-tangle.
--help | -h
show a help message and exit
--language-exclude LANG[,…]
exclude one or more languages from being added to org-babel-load-languages. Multiple languages can appear as the argument to this (and other options below), separated by commas. And, this option may appear multiple times (ditto). Conflicts with --language-exclude-all.
--language-exclude-all
exclude all languages specified in a source code block in the file to be tangled.
--language-include LANG[,…]
specifies one or more language to be supported for tangling. This can only be used if --language-exclude-all is specified.
--language-include-tangled
include all languages specified in a source code block which contains a :tangle header. This can only be used if --language-exclude-all is specified.
--tangle-exclude LANG[,…]
suppress one or more languages from being tangled. Conflicts with --tangle-exclude-all.
--tangle-exclude-all
suppress all tangling. This only really makes sense when combined with the --tangle-include option.
--tangle-include LANG[,…]
allow tangling of scbs using the language(s) specified as arguments to this option. Must be used in conjunction with --tangle-exclude-all.

Other miscellaneous options

--check-off
tangle each file without checking for the language in source code blocks. languages specified in one or more --language-include options will be correctly tangled.
--check-tangled
only check the list of enabled languages against the languages in source code blocks with a :tangle header argument. If --check-tangled is specified, source code blocks that do not have a :tangle attribute are not checked; this is not the default because i think that other blocks may be invoked during the tangling process, for example to provide a value for a :var attribute for a source code block that is tangled.
--duplicate-check-on
mark as an error if a language is specified more than once in the same or multiple =--language-include= or =--tangle-exclude= options, etc.
--report-only
do not tangle the input file(s). Rather, report on which languages are in the source code blocks and which languages are in source code blocks with a :tangle header argument.
--version | -V
Print out the current version of prog.
--debug
Print out debug messages.
--testing-no-usage
This is used during development.

Option compatibility

The same language may appear in multiple specifications of the same option (but, see --duplicate-check-on). However

  • the languages in --language-exclude must be disjoint from those in --language-include
  • the languages in --tangle-exclude must be disjoint from those in --tangle-include

So, the following would generate an error

org-cli-tangle --language-exclude-all --language-include R --language-exclude R

To simplify understanding and coding of org-cli-tangle, the following rules are emforced:

  • Only one of --language-exclude and --language-exclude-all can be specified on the command line.
  • If --language-include is specified, --language-exclude-all must be specified. (These two rules imply that at most one of --language-exclude and --language-include can be specified.)
  • Only one of --tangle-exclude and --tangle-exclude-all can be specified on the command line.
  • If --tangle-include is specified, then --tangle-exclude-all must also be specified. (These two rules imply that at most one of --tangle-exclude and --tangle-include can be specified.)

How it works

Emacs org-mode has the ability to "tangle" source code blocks into separate files (which may run stand alone or may be used as input for building or running other software). From a buffer visiting an org-mode file within Emacs one invokes this process by typing something like [M-x org-babel-tangle] (often bound to the key sequence [C-c C-v t]). org-cli-tangle allows an org-mode file to be tangled from the command line.

There are two main controls made available by org-mode which org-cli-tangle makes use of:

  • org-babel-load-languages :: a variable containing a list of languages that are to be enabled for evaluation by org-mode. This same process also allows org-mode to embed variables for an source code block of one of those languages (org-mode’s :var header attributes) when that source code block is either evaluated or, in the case relevant to org-cli-tangle, tangled).
  • LANG-RE :: this is an optional argument to org-babel-tangle-file, which org-cli-tangle invokes to actually tangle a file.

org-cli-tangle will process each file specified on the command line, setting org-babel-load-languages in a way compatible with the source code blocks in that file.

By default, org-babel-load-languages is set to enable all languages in source code blocks in an input file. Different options — --language-exclude, --language-exclude-all, etc. — allow more fine control over this process, if needed.

Once the list of languages to enable is computed, if any source code blocks in one or more of the files to be tangled are of any other language, and that language doesn’t appear in the list of languages in any --language-exclude on the command line, an error will be raised (but, see --no-checking below). This is true even for source code blocks that might not have an org-mode =:tangle= header argument, as those source code blocks might produce variables or code needed by the source code blocks to be tangled (and org-cli-tangle doesn’t try to determine this; but, see --only-tangled below).

  • Languages specified in --language-include will be entered into org-mode’s org-babel-load-languages table.

When the languages to enable for a file are (at least partially) specified on the command line (with --language-exclude, say) then, by default, org-cli-tangle also checks the languages specified in the source code blocks in the file to make sure the list of languages appears compatible with the contents of the file. (See also the --check-tangled option, which restricts which source code blocks are examined). If the checking is not disabled (via --check-off, for the languages found in the relevant source code blocks are compared against the languages specified in --language-exclude, etc.. If any language is found in the former but not in one of the latter, an error is generated.

If the file passes the above check, then (org-babel-tangle-file) is invoked in an environment where org-babel-load-languages contains those languages used in source code blocks in the file, possibly modified by --language-exclude, etc.

In addition, org-cli-tangle can be used to prevent source code blocks from one or more languages from being tangled from a source file (i.e., blocks that contained a :tangle header argument). LANG-RE, if non-nil, tells which languages are to be tangled; so, if --tangle-exclude, etc., are specified on the command line, those languages are removed from the set of all languages found in source code blocks in the .org file, and a LANG-RE restricting tangling to just those languages is passed to org-babel-tangle-file.

EXIT STATUS

If no error occurs, org-cli-tangle exits with a status of 0.

If an error occurs processing options, org-cli-tangle exits with a status of 1.

If an error occurs while validating languages, org-cli-tangle exits with a status of 2.

If (org-babel-tangle-file) reports an error, org-cli-tangle exits with a status of 3.

SOURCE CODE, BUGS, SUGGESTIONS

The org-cli-tangle home page is https://git.sr.ht/~minshall/org-cli-tangle.

Please see https://todo.sr.ht/~minshall/org-cli-tangle to file bug reports or make suggestions.

HISTORY

org-cli-tangle was written in 2024.