ntangle icon indicating copy to clipboard operation
ntangle copied to clipboard

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

#+title: NTangle

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

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

  • What is Tangling From [[https://orgmode.org/manual/Extracting-source-code.html][Org Manual -- Extracting source code]]:

#+begin_quote 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 [[https://orgmode.org/manual/Noweb-reference-syntax.html][Noweb reference syntax]]). #+end_quote

/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

[[https://github.com/nim-lang/nimble][~nimble~]] can be used to install ~ntangle~. This utility ships with Nim installations. Think of it as the equivalent of the Python ~pip~.

/See [[https://github.com/dom96/choosenim#installation][choosenim installation]] to install nim and nimble./

To install ~ntangle~: #+begin_example nimble install ntangle #+end_example

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 [[https://github.com/kaushalmodi/eless][~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][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. #+begin_example ntangle <FILE.org> #+end_example

or a list of files:

#+begin_example ntangle <FILE1.org> <FILE2.org> .. #+end_example

or a list of directories:

#+begin_example ntangle <DIR1> <DIR2> .. #+end_example

or a mix of lists of files and directories:

#+begin_example ntangle <FILE1.org> <DIR1> <FILE2.org> <DIR2> .. #+end_example

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 [[https://github.com/OrgTangle/ntangle/tree/master/tests][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 ([[https://code.orgmode.org/bzg/org-mode/src/a85ba9fb9bc7518bc0b654c79812f5606be84c58/etc/ORG-NEWS#L1042][see ORG-NEWS]]).

So if you used the below in Org 8.x and older: #+begin_src org

Deprecated syntax

,#+property: tangle yes #+end_src

Refactor that to: #+begin_src org

Org 9.0 syntax

,#+property: header-args :tangle yes #+end_src

Similarly, refactor a property drawer from: #+begin_src org

Deprecated syntax

,* Some heading :PROPERTIES: :tangle: yes :END: #+end_src

To: #+begin_src org

Org 9.0 syntax

,* Some heading :PROPERTIES: :header-args: :tangle yes :END: #+end_src

  • Development Below assumes that you have ~nim~ and ~nimble~ installed. ** Building #+begin_example 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

#+end_example ** Testing #+begin_src shell :results output verbatim

cd to the git repo dir

./tests/test.sh #+end_src

  • History I was [[https://www.reddit.com/r/emacs/comments/8m5wuf/a_python_version_of_orgbabeltangle_for_literate/dzl3ooo/][motivated]] to start this project after reading about the [[https://github.com/OrgTangle/org-babel-tangle.py][~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]].