/ntangle

Command-line utility for Tangling of Org documents — programmed in Nim.

Primary LanguageEmacs LispMIT LicenseMIT

NTangle

Command-line utility for Tangling of Org documents — programmed in Nim.

https://github.com/OrgTangle/ntangle/actions/workflows/test.yml/badge.svg

What is Tangling

From Org Manual – Extracting source code:

Extracting source code from code blocks is a basic task in literate programming. Org has features to make this easy. In literate programming parlance, documents on creation are woven with code and documentation, and on export, the code is tangled for execution by a computer.

Org facilitates weaving and tangling for producing, maintaining, sharing, and exporting literate programming documents. Org provides extensive customization options for extracting source code.

When Org tangles src code blocks, it expands, merges, and transforms them. Then Org recomposes them into one or more separate files, as configured through the options. During this tangling process, Org expands variables in the source code, and resolves any Noweb style references (see Noweb reference syntax).

You can visit the same Org manual section from within Emacs by going to this Info manual node: ~(org) Extracting Source Code~.

Why ntangle?

While the tangling of Org documents works great from within Emacs, it can be quite a bit slow for large Org documents. This project aims to provide almost the same tangling functionality at a much higher speed.

You do not need Emacs or Org mode installed to use ntangle.

Installation

~nimble~ can be used to install ntangle. This utility ships with Nim installations. Think of it as the equivalent of the Python pip.

See *choosenim* installation to install *nim* and *nimble*.

To install ntangle:

nimble install ntangle

Above installs the binary in the ~/.nimble/bin/ directory.

Features

Tangling minus Noweb [7/8]

  • [X] Understands global tangle header-args in #+property keywords
  • [X] Understands tangle header-args directly above Org source blocks
  • [-] Understands tangle subtree property drawer header-args
    • [X] Rudimentary parsing of the property drawer header-args. ntangle does not check the validity of the property drawer (i.e. :PROPERTIES: appears immediately after the heading, and it ends with :END:, and that the properties are only between them, etc.). Also header-args is treated the same as header-args+ for simplicity for now.
    • [ ] Treat header-args vs header-args+ values correctly.
  • [X] Understands the precendence order of the tangle header-args when a mix of global and source block header-args are used
  • [X] Language-specific header-args (e.g. #+property: header-args:nim :tangle yes)
  • [X] Concatenating multiple source blocks to the same tangled file
  • [X] Respects comma-escaping in source blocks
  • [X] Removes common indentation, but also retains the indentation where needed

Supported header-args switches [5/7]

  • [X] :tangle
  • [X] :padline
  • [X] :shebang
  • [X] :mkdirp
  • [X] :tangle-mode
  • [ ] :comments
  • [ ] :no-expand

Noweb [0/1]

  • [ ] Noweb support. I sorely miss the lack of noweb support.. I use it heavily in ~eless~.

/There is no plan to support Org Babel functions with Noweb, like evaluating code blocks during tangling, etc. (just use Emacs for those :D)./

Supported header-args switches for Noweb [0/3]

  • [ ] :noweb
  • [ ] :noweb-ref
  • [ ] :noweb-sep

Screenshot

https://raw.githubusercontent.com/OrgTangle/ntangle/master/doc/img/Screenshot_ntangle_v0.4.2.png

Usage

Add one or more Org files (files with names ending in “.org”) or directory names after the ntangle command. If directory names are added, only the files in there with names ending with “.org” will be parsed.

ntangle <FILE.org>

or a list of files:

ntangle <FILE1.org> <FILE2.org> ..

or a list of directories:

ntangle <DIR1> <DIR2> ..

or a mix of lists of files and directories:

ntangle <FILE1.org> <DIR1> <FILE2.org> <DIR2> ..

The tangled files will be created in paths relative to the source Org file.

Org mode file samples for tangling

You can find samples of the supported Org mode tangling in the *test* directory of this project.

Org Tangle Syntax

ntangle expects the Org files to use the header-args property syntax used in Org mode 9.0 and newer. There was a minor syntax change with header-args property in Org 9.0 (see ORG-NEWS).

So if you used the below in Org 8.x and older:

# Deprecated syntax
#+property: tangle yes

Refactor that to:

# Org 9.0 syntax
#+property: header-args :tangle yes

Similarly, refactor a property drawer from:

# Deprecated syntax
* Some heading
:PROPERTIES:
:tangle: yes
:END:

To:

# Org 9.0 syntax
* Some heading
:PROPERTIES:
:header-args: :tangle yes
:END:

Development

Below assumes that you have nim and nimble installed.

Building

git clone https://github.com/OrgTangle/ntangle
cd ntangle
nimble build # creates the ntangle binary in the same directory
# nimble build -d:release # same as above but creates an optimized binary

Testing

# cd to the git repo dir
./tests/test.sh

History

I was motivated to start this project after reading about the ~org-babel-tangle.py~ Python project by @thblt.

I wanted to just see how easy it was to translate a Python script to Nim (it was very easy!), and from there, this project started snowballing, gathering features of its own :).

Other Org tangling implementations

See https://github.com/OrgTangle.