orgstar

Code blocks

orgstar runs and tangles source blocks the way Org Babel does, and refuses anything it would run differently.

Source blocks

A source block holds code in a named language:

#+begin_src python
return 6 * 7
#+end_src

orgstar reads the same syntax Org does: the language after #+begin_src, then any switches such as -i or -r, then header arguments. A #+NAME: line above a block names it, so other blocks, #+CALL: lines and :var references can refer to it.

Lines inside a block that start with * or #+ are protected with a leading comma, as Org does (org-escape-code-in-region). The comma is removed when the block runs, tangles or exports, and when you edit the block apart.

Syntax highlighting

The code in a block is highlighted in the editor on the Mac and on iOS, in the iOS reader, and in the Mac's block editor, in the theme's syntax-* colours. Highlighting uses tree-sitter grammars for these language names:

Language namesGrammar
sh, bash, shell, zshBash
python, python3, pyPython
emacs-lisp, elispEmacs Lisp
cC
c++, cppC++
rR
js, javascript, nodeJavaScript
javaJava
schemeScheme
clojure, cljClojure
haskellHaskell
rustRust
goGo
rubyRuby
jsonJSON
yaml, ymlYAML
toml, conf-tomlTOML
luaLua

Names are matched without regard to case. Blocks in any other language show as plain monospaced text.

Editing a block apart

org-edit-special edits a block's contents in a separate editor. Put the caret in a src, example or export block (or on a #+TBLFM: line; see Tables) and run Edit Block.

PresetKey
EmacsC-c '
DoomC-c ', or SPC m ' in normal state
Mac⌃⌘'

On the Mac the block opens in a sheet titled with the block's kind and language, with the same highlighting as the main editor. The protecting commas are removed while you edit and added back when you save.

ActionKeys
SaveC-c ' or ⌘Return, or Save Block
LeaveC-c C-k or Escape, or Cancel

If the block changed in the main editor while you edited it, the edit is not saved and the message area says so.

On iOS the block opens in a plain text sheet with Cancel and Save buttons.

Running a block

C-c C-c in a source block runs it (org-babel-execute-src-block) and writes its result under it. The same command runs a #+CALL: line or an inline src_ block when the caret is on one.

PresetKey
EmacsC-c C-c
DoomC-c C-c in normal, insert and visual state
Mac⌃⌘X

The program runs in the folder of the file, or in :dir. It reads the code on standard input. While it runs, the message area shows "Running language block…"; when it ends, it shows "Code block evaluation complete." or the problem.

If the program writes to standard error or exits with a non-zero status, the message area shows the exit status and the first line of standard error. The result is still inserted, as Emacs does.

The block's text is remembered when the run starts. If you edit the block while it runs, so it can no longer be found, the result is not written.

Languages that run

On the Mac, orgstar starts each interpreter through /usr/bin/env. Because an app opened from the Dock does not see your shell's PATH, orgstar adds /opt/homebrew/bin, /usr/local/bin, /Library/TeX/texbin, /usr/bin and /bin to the end of it.

LanguageProgram run
sh, bash, zsh, fish, ksh, dash, ash, csh, mksh, poshThe shell of that name
shellThe shell in SHELL, or /bin/sh
pythonpython3, or the program in :python
emacs-lisp, elispemacs -Q --batch; see Emacs Lisp blocks below
rubyruby, or the program in :ruby
js, javascriptnode
RRscript -
awkawk -f, the program written to a file
dot, plantuml, mermaiddot, plantuml, mmdc; see Graphics below
C, C++, cpp, D, java, fortran, clojureA compiler, or bb or clojure; see Compiled languages below

For js, javascript and R, :cmd names a different program. awk takes :cmd-line arguments after its program, and :in-file as the file it reads.

Any other language is refused with "No way to run language blocks yet."

A run that takes longer than five minutes is stopped. Runs in a :session have no time limit.

Compiled languages

On the Mac, C, C++, cpp, D, java, fortran and clojure blocks run as Org's ob-C, ob-java, ob-fortran and ob-clojure run them. orgstar writes the body, expanded as tangling writes it (see Tangling below), to a source file in a temporary folder, compiles it and runs the program in the file's folder or :dir, with a newline on standard input. What the compiler prints is dropped.

LanguageCommands
Cgcc -o bin FLAGS src LIBS, then bin CMDLINE
C++, cppg++ -o bin FLAGS src LIBS, then bin CMDLINE
Drdmd FLAGS src CMDLINE, which compiles and runs
fortrangfortran -o bin FLAGS src, then bin CMDLINE
javajavac CMPFLAG Class.java, then java -cp dir CMDLINE Class CMDARGS
clojurebb src (babashka) when bb is installed, otherwise clojure -M src

FLAGS is :flags, LIBS is :libs or the inherited LIBS property, and CMDLINE is :cmdline. A Lisp list works for :flags and :libs; its items are joined with spaces.

ArgumentLanguagesEffect
:flagsC, C++, D, FortranCompiler options.
:libsC, C++Libraries, after the source file, such as -lm.
:cmdlineC, C++, D, FortranThe program's arguments.
:cmdlineJavaOptions for java, before the class name.
:cmdargsJavaThe program's arguments.
:cmpflagJavaOptions for javac.
:javac, :javaJavaThe compiler and runtime commands, with options; javac and java by default.
:classnameJavaThe class to run; a dotted name gives its package.
:backendClojurebabashka runs bb, clojure-cli runs clojure -M.
:includes, :defines, :namespaces, :imports, :main, :prologue, :epilogue, :ns, :varas for tanglingWhat the expansion writes; see Tangling below.

When :imports is absent, a D block reads the IMPORTS property where it is, and a Fortran block without :includes or :defines reads the INCLUDES and DEFINES properties, as Org does when it runs them. :session is ignored for these languages, as in Org.

Java's defaults are :results output and :dir . (org-babel-default-header-args:java). The .java and .class files are written in the folder the block runs in, under folders for the class's package (org/ex/Hello.java for :classname org.ex.Hello), and are left there. The class is :classname, the body's own class with its package, or Main.

Any other Clojure backend is refused: "The cider backend for clojure needs Emacs; orgstar runs babashka or clojure-cli."

Before a run, orgstar checks that each program it needs is on the PATH described above. If not, the block fails with "gcc isn't installed, so C blocks can't run." (g++ for C++, rdmd, gfortran, or the commands :javac and :java name). For Clojure without a :backend, the message is "Neither bb nor clojure is installed, so clojure blocks can't run."

The trust prompt

Before a block runs, orgstar asks "Run this language block? (yes, no, always)", as org-confirm-babel-evaluate does.

A remembered block is identified by the file's path and the exact text of the block. Any change to the block, or moving the file, makes orgstar ask again. The remembered hashes are kept in trusted.json in orgstar's Application Support folder (~/Library/Application Support/Orgstar on the Mac). The same file records table formulas you allowed to run Lisp. To forget every choice, delete the file while orgstar is not running.

When a block's :var or :stdin refers to other blocks that have to run first, you are asked once for all of them. The prompt covers the block you ran and every block its references reach. If any of those blocks changes while the chain runs, orgstar stops with "The blocks changed while running; nothing more was run."

:eval

ValueEffect
never, noThe block does not run: "Evaluation of this language code block is disabled."
queryAsks every time, with only yes and no. A block reached through :var with :eval query makes the whole chain ask every time.
anything else, or absentRuns after the trust prompt.

never-export and no-export only stop evaluation during export in Org. orgstar does not run blocks during export, so with these values the block runs from C-c C-c like any other.

Cancelling a run

On the Mac, Edit ▸ Cancel Running Task (⌘.) stops the running block. Its result is not inserted, and the message area shows "Code block canceled." The same command stops an export or table recalculation running in Emacs (see Export and Tables). With nothing running it shows "Nothing is running". The command is also in the command palette.

Only one block runs at a time. Starting another block cancels the one that is running.

Cancelling a block that runs in a :session stops the session's interpreter, so the session's state is lost. The next block in that session starts a new one.

The iOS app has no cancel command.

Results

The result is written after a #+RESULTS: line below the block (org-babel-insert-result). Running again replaces it. A named block's result goes under #+RESULTS: name, wherever that line is in the file. An unnamed block's result is the #+RESULTS: line right after it, past blank lines. The result keeps the block's indentation, so a block inside a list item keeps its result inside the item.

#+begin_src sh
echo hello
#+end_src

#+RESULTS:
: hello

By default a result is shaped like this:

Value or output

WordResult
valueThe value of the block. This is the default.
outputEverything the program printed on standard output.

What "value" means depends on the language:

LanguageValue
Shells, by defaultStandard output, read as a table: tab-separated columns, then comma-separated, then space-separated; a single field is a plain value.
Shells, :results value written outThe exit status of the last command.
PythonWhat the block returns. The body runs as a function, so it needs return. :return expr adds a final return expr.
Python in a :sessionThe value of the last expression.
ruby, js in a :sessionThe value of the last expression, read as without a session.
Emacs LispThe value of the last form.
rubyThe value of the body, run as a lambda; strings as they are, other values as inspect prints them, arrays read as tables with nil rows as rules. :results pp prints it with pp.
js, javascriptWhat the body returns, as util.inspect prints it, arrays read as tables; it runs as a function, so it needs return.
awkStandard output, read as a table as for shells.
RStandard output, always.
C, C++, DStandard output without its common indentation, read as a table as for shells.
FortranThe same, with blank space around the output trimmed.
JavaWith :results value, what the body returns; it runs as main, so it needs return. Lists and arrays become tables, with null rows as rules, and a returned string is written without its quotes. Java's default is :results output.
ClojureThe value of the last form as Clojure prints it. A number, or a string without its quotes, is written as that; vectors, lists and maps are written as printed, not as tables.

Python lists of lists become tables, with None rows as rules. A flat list becomes a one-row table. Emacs Lisp lists become tables the same way, with hline for rules. Numbers are written the way Emacs prints them.

Result types

WordEffect
table, vectorRead the result as a table. This is the default for values.
listWrite a plain list, one =- = item per line or per element.
scalar, verbatimWrite the result as text without reading it as a table.
fileWrite a link to a file (see Results in files below).

:results verbatim on an Emacs Lisp value writes it as prin1 would, with quotes around strings.

With :results output list, the list made from the output is written as an example, in lines such as : - a, as Org writes it:

#+begin_src sh :results output list
printf 'a\nb\n'
#+end_src

#+RESULTS:
: - a
: - b

Result formats

WordWritten as
rawThe text as it is, so Org markup in it takes effect.
drawerBetween :results: and :end:.
codeIn a #+begin_src block of the block's language.
orgIn a #+begin_src org block.
htmlIn a #+begin_export html block.
latexIn a #+begin_export latex block.
ppPython: formatted with pprint; written as text.

Lines that start with * or #+ inside code, org, html and latex results are comma-protected.

Inserting

WordEffect
replaceReplace the previous result. This is the default.
appendAdd after the previous result.
prependAdd before the previous result.
silentShow the output in the message area and write nothing.
none, discardWrite nothing.

Words from different groups combine: :results output list append. A later word replaces an earlier one from the same group.

:wrap

:wrap puts the result in a block, ahead of any format word.

ValueWrapped in
:wrap alone#+begin_results … #+end_results
:wrap example#+begin_example … #+end_example
:wrap src python#+begin_src python … #+end_src
:wrap export html#+begin_export html … #+end_export
:wrap no, :wrap nilNo wrapping

Inside example, src and export wrappers, lines starting with * or #+ are comma-protected.

Results in files

With :results file, the result is a link instead of text.

HeaderEffect
:file nameWrite the result into name and link to it. Without :results file, :file has no effect, except in graphics blocks.
:output-dir dirPut :file under dir. The folder must exist.
:file-desc textGive the link a description: [[file:name][text]]. An empty :file-desc uses the file name.

A relative :file is written in the folder the block ran in: the file's folder, or :dir. Without :file, :results file takes the result itself as the path to link to.

#+begin_src sh :results file :file out.txt :file-desc Output
echo hello
#+end_src

#+RESULTS:
[[file:out.txt][Output]]

Header arguments

Where they come from

orgstar merges header arguments in this order, each layer overriding the ones before it (org-babel-get-src-block-info):

  1. #+PROPERTY: header-args … in the file, then header-args properties of the block's headings, from the outermost heading inwards.
  2. header-args:LANG the same way, for blocks in language LANG.
  3. The arguments on the #+begin_src line.
  4. #+HEADER: lines above the block.
  5. For a call, the call's arguments (see Calls below).

A property written with a +, such as header-args+, adds to the value inherited from above instead of replacing it. In a property drawer, :header-args:sh: is one property name, so its value applies only to sh blocks.

#+PROPERTY: header-args :results output

* Scripts
:PROPERTIES:
:header-args:sh: :dir /tmp
:END:

#+HEADER: :results verbatim
#+begin_src sh :var name="world"
echo "hello $name"
#+end_src

Without any of these, a block has :results replace, :exports code, :session none, :cache no, :noweb no, :hlines no and :tangle no. An inline src_ block defaults to :exports results and :hlines yes.

Lisp in header values

A header value that starts with (, ', ` or [ and is not in quotes is Lisp, as in org-babel-read. orgstar evaluates it with its own Emacs Lisp interpreter, which also knows buffer-file-name, default-directory, system-type and the functions expand-file-name, file-name-directory, file-name-nondirectory, file-name-sans-extension and file-name-as-directory.

#+begin_src sh :dir (concat "/" "usr") :results output
pwd
#+end_src

A string or number takes the place of the form. Lisp that the interpreter cannot evaluate is refused where it matters: for :var ("is Lisp that only Emacs can evaluate"), :colnames and :rownames, and any header of a :cache yes block.

Header argument reference

ArgumentValuesEffect
:resultssee Results aboveHow the result is collected, shaped and inserted.
:wrapblock type and parametersWraps the result in a block.
:filefile nameWhere a file result goes; required for graphics.
:output-dirfolderFolder for :file.
:file-desctextDescription of a file result's link.
:varname=valuePasses a value in (see Variables below).
:colnamesyes, no, Lisp listHeader row of table variables (see Tables in variables below).
:rownamesyes, no, Lisp listFirst column of table variables.
:hlinesyes, noKeep rules in table variables.
:separatortextColumn separator for tables in shell variables; a tab by default.
:hline-stringtextWhat a rule becomes in a shell variable with :hlines yes; hline by default.
:dirfolderFolder to run in, relative to the file's folder. It must exist.
:sessionname, noneRuns in a long-lived interpreter (see Sessions below). Shells, Python, ruby, js and R; ignored for the compiled languages.
:stdinname of a table, list or blockFeeds the value to standard input. Shells only.
:cmdlineargumentsCommand-line arguments. Shells, dot, plantuml, mermaid and the compiled languages only.
:shebang#!… lineRuns the block as a script with this first line. Shells only; also used by tangling.
:padlinenoNo blank line after the shebang of a script, or between tangled blocks.
:pythonprogramPython interpreter to use.
:cmdprogramInterpreter for js, javascript and R; :ruby for ruby.
:cmd-line, :in-filearguments, fileawk: arguments after the program, and the file it reads.
:returnexpressionPython: the value to return.
:cacheyes, noSkip the run when the result is current (see Caching below).
:evalnever, no, query, …Whether and how to ask before running (see :eval above).
:nowebsee Noweb belowExpands <<name>> references.
:noweb-refnameMakes the block part of <<name>>.
:noweb-septextSeparator between blocks joined under one :noweb-ref; a newline by default.
:noweb-prefixnoDo not repeat the text before <<name>> on each expanded line.
:exportscode, results, both, noneWhat export shows (see Export).
:tanglesee Tangling belowWhere tangling writes the block.

Arguments that are refused

orgstar does not run a block whose arguments it would handle differently from Emacs. Instead it says why and runs nothing.

ArgumentRefused forMessage
:prologue, :epiloguegraphics (dot, plantuml, mermaid)":prologue isn't supported yet; nothing was run."
:postevery language":post isn't supported yet; nothing was run."
:stdin, :shebanglanguages other than shells":stdin isn't supported yet; nothing was run."
:cmdlinelanguages other than shells, graphics and the compiled languages":cmdline isn't supported for language yet; nothing was run."
:sessionawk, graphics and Emacs Lisp; the compiled languages ignore it":session isn't supported for language yet; nothing was run."

Variables

:var name=value passes a value into the block (org-babel-ref-resolve). One :var can hold several assignments separated by spaces, and you can repeat :var. A later assignment to the same name replaces an earlier one.

ValueMeaning
5, 2.5A number.
"two words"A string. \n and \t in it are a newline and a tab.
'(1 2), (+ 1 2), '((1 2) hline (3 4))Lisp: evaluated to a string, number, list or table.
tblThe table or plain list under #+NAME: tbl in the same file.
genThe result of the source block named gen, which runs first.
double(n=4)The result of the block named double, run with n set to 4.
#+NAME: nums
| 1 | 2 |
| 3 | 4 |

#+begin_src python :var t=nums :var scale=10
return [[c * scale for c in row] for row in t]
#+end_src

A referenced block runs before the block that refers to it, after the one trust prompt that covers them all. A block with :cache yes and a current result gives that result without running. A chain that leads back to itself is refused with "name refers to itself through :var".

These are not supported and are refused:

How a value reaches the code depends on the language:

LanguageScalarsListsTables
bashquoted stringindexed array (declare -a)two or more columns: associative array keyed by the first column (declare -A); one column: indexed array
other shellsquoted stringone item per linerows on lines, cells separated by a tab or :separator
fishset name 'value'as other shellsas other shells
Pythonliterallistlist of lists, None for rules
Emacs Lisplet-bound valuelistlist of lists, hline for rules
Rubyname=value literalarrayarray of arrays, nil for rules
JavaScriptvar name=value;arrayarray of arrays, hline for rules
Rname <- value, integers with Lone-column data framedata frame read from tab-separated text, a header when the table has one
awk-v name'value'=one item per linerows on lines, cells separated by a tab

For shell blocks, the bash forms are used when SHELL is bash. :prologue and :epilogue add a line before the variables and one after the body, in every language that runs; in Emacs Lisp only when the block has variables, as org-babel-expand-body:emacs-lisp does. C, C++, D, Java, Fortran and Clojure blocks get declarations as their expansion writes them; see Tangling below.

#+NAME: kv
| a | 1 |
| b | 2 |

#+begin_src bash :var t=kv :results output
echo ${t[a]} ${t[b]}
#+end_src

Tables in variables

A table passed as a variable loses some of its structure first (org-babel-disassemble-tables):

If the result is a table of the same width (for columns) or height (for rows), the names are put back on it (org-babel-reassemble-table). Clojure results don't get them back, as in Org. :colnames and :rownames can also be Lisp lists of names to put on the result, such as :colnames '("x" "y").

#+NAME: tbl
| a | b |
|---+---|
| 1 | x |
| 2 | y |

#+begin_src python :var t=tbl
return [r + ["!"] for r in t]
#+end_src

Standard input and arguments

For shell blocks, :stdin name sends a table, list or block result to standard input, a table as tab-separated lines. :cmdline gives the script arguments, and :shebang its first line. With any of the three, the block is written to an executable script and run by the shell (org-babel-sh-evaluate); without :shebang, the first line is #!/usr/bin/env and the shell's name. A block with :stdin or :cmdline runs as a script even with a :session, and leaves the session untouched; :shebang alone runs in the session.

#+begin_src sh :cmdline one "two words" :results output
for a in "$@"; do echo "[$a]"; done
#+end_src

Sessions

:session name runs the block in an interpreter that stays running, so variables, functions and the working folder carry over to the next block in the same session. Sessions work for shells, Python, Ruby, JavaScript (Node) and R on the Mac.

Emacs runs these with packages beyond Org: inf-ruby for Ruby, ESS for R, and js-comint or skewer for JavaScript; with plain node, ob-js refuses sessions. orgstar's sessions don't need them, and their results can differ in detail from those packages' echoed output.

#+begin_src python :session py :results output
a = 2
print("set")
#+end_src

#+begin_src python :session py
a * 3
#+end_src

Caching

With :cache yes, orgstar computes a SHA-1 hash of the block's header arguments and expanded body, as org-babel-sha1-hash does, and writes it on the results line: #+RESULTS[hash]:. When you run the block again and the hash matches, nothing runs and the message area shows the cached value ("Cached: …").

Change the block or its arguments and it runs again. Results inserted with append or prepend carry no hash. Inline blocks are not cached. A cached block that has Lisp in its header arguments the interpreter cannot evaluate is refused.

The hash of a C, C++, D, Java, Fortran or Clojure block is taken over the body as the language expands it (see Tangling below), with the IMPORTS, INCLUDES and DEFINES properties where the block is, and Java's default header arguments, as Emacs does. A result Emacs wrote for such a block with :cache yes is recognised as current, and C-c C-c shows it.

Noweb

A noweb reference <<name>> in a block's body stands for other code. Whether references expand depends on :noweb and on what is happening:

:nowebRunningTanglingExporting
no (default)nonono
yesexpandsexpandsno
tanglenoexpandsno
evalexpandsnono
no-exportexpandsexpandsno
strip-exportexpandsexpandsno
strip-tangleexpandsremoves the referencesno

Exported code always shows the references as written; see Export.

<<name>> expands to the first of these that exists:

  1. The contents of the heading whose ID property is name, or whose CUSTOM_ID is name without its leading #.
  2. The body of the source block named name.
  3. The bodies of all blocks with :noweb-ref name, joined by each block's :noweb-sep (a newline by default).

Blocks under a COMMENT heading are skipped. A referenced block expands its own references according to its own :noweb, up to 32 levels deep.

Text before the reference on its line is repeated before each line the reference brings in, so references inside comments or indented code keep their prefix. :noweb-prefix no turns this off.

#+NAME: greeting
#+begin_src sh
echo hello
#+end_src

#+begin_src sh :noweb yes
<<greeting>>
echo world
#+end_src

A reference that runs a block, <<name()>>, is refused: "Noweb references that run a block (…) aren't supported yet; nothing was run."

Calls

#+CALL: lines

#+CALL: runs a named block with other arguments, as Org's library of Babel calls do (org-babel-lob-get-info). Run it with C-c C-c on the line.

#+NAME: double
#+begin_src sh :var n=2
echo $((n*2))
#+end_src

#+CALL: double(n=5)

#+RESULTS:
: 10

The full form is #+CALL: name[inside](arguments) end:

The call also takes the header-args and header-args:LANG properties, and #+PROPERTY: lines, where the call is, with LANG the called block's language. They apply after the called block's own header arguments and before [inside], as in Org.

The result goes under the call. A #+NAME: line above the #+CALL: names the result.

Inline calls and blocks

An inline source block, src_sh{echo hi}, runs with C-c C-c on it. Header arguments go in brackets: src_sh[:var x=3]{echo $x}. The result is written right after the block as a results macro:

Text src_sh{echo hi} {{{results(=hi=)}}} end.

Running again replaces the macro. With :results raw the result goes in as it is, without the macro. An inline result must be one line, and a table result must be a single cell.

An inline call, call_double(n=6), has the same parts as a #+CALL: line: call_name[inside](arguments)[end]. C-c C-c on an inline call runs it, and its result is written after it as a results macro, as for inline blocks. It takes the properties where it is as a #+CALL: line does.

Emacs Lisp blocks

On the Mac, an emacs-lisp or elisp block runs in a new emacs -Q --batch for each run, with lexical binding on. -Q means your init file and packages are not loaded, and nothing carries over between runs. orgstar looks for Emacs at ORGSTAR_EMACS, then /opt/homebrew/bin/emacs, /usr/local/bin/emacs, /Applications/Emacs.app/Contents/MacOS/Emacs, /run/current-system/sw/bin/emacs and /usr/bin/emacs. Without Emacs, the block fails with "Emacs isn't installed, so Emacs Lisp blocks can't run."

On iOS, Emacs Lisp blocks run in orgstar's own Emacs Lisp interpreter. It covers ordinary list, string, number and control forms, princ and message. A block that uses something the interpreter does not have fails with "This block uses Emacs Lisp that runs only in Emacs, on the Mac." A Lisp error fails the run, as it does in Emacs.

Variables are bound with let around the body. :results output collects what the block prints with princ, prin1, print and terpri.

Graphics

dot (Graphviz), plantuml and mermaid blocks draw a picture into :file, and the result is a link to it. :file is required: "language code blocks need a :file header argument". The file's extension picks the output format; with none, png is used.

LanguageCommand
dotdot -T/ext/ -o file
plantumlplantuml -p -t/ext/, output to the file
mermaidmmdc -i input -o file

A plantuml body without an @start… line is wrapped in @startuml and @enduml. :cmdline adds options to the command. The program must be installed and on the PATH described under Languages that run.

#+begin_src dot :file graph.svg
digraph { a -> b }
#+end_src

#+RESULTS:
[[file:graph.svg]]

Tangling

Tangling writes source blocks to the files their :tangle argument names (org-babel-tangle).

CommandEmacs and DoomMacWhat it tangles
Tangle FileC-c C-v t, C-c C-v C-t⌃⌘VEvery block in the file
Tangle Blocknone⌃⇧⌘VThe block at the caret (Emacs: C-u C-c C-v t)
Tangle Block's Targetnone⌃⌥⌘VEvery block going to the same file as the one at the caret (Emacs: C-u C-u C-c C-v t)

All three are in the Org menu and the command palette. Tangling uses the text in the editor, saved or not, and the message area reports "Tangled N code blocks from file".

:tangle and file names

:tangleTarget
no (default)Not tangled.
yesThe Org file's name with the language's extension, as Org's language files define it (org-babel-tangle-lang-exts): py for python, rb for ruby, pl for perl, cpp for C++, d for D, awk, sed, lua, hs for haskell, java, tex for latex, ly for LilyPond, F90 for fortran, clj for clojure, cljs for clojurescript, cs for csharp, groovy, jl for julia, lisp, max for maxima, ml for ocaml, pde for processing, el for emacs-lisp and elisp, and bib for bibtex. Any other language is its own extension (notes.sh for sh).
a pathThat file, relative to the Org file's folder. ~ is expanded.
LispEvaluated as described under Lisp in header values, with buffer-file-name set to the Org file.

Blocks under a COMMENT heading, or a heading tagged ARCHIVE, are skipped. Blocks going to the same file are written in the order they appear.

#+PROPERTY: header-args:python :tangle script.py

* Tool
:PROPERTIES:
:header-args: :tangle bin/tool.sh :mkdirp yes :shebang "#!/bin/sh"
:END:

#+begin_src sh
echo tool
#+end_src

Tangling arguments

ArgumentValuesEffect
:mkdirpyesCreate the target's folder if it is missing.
:tangle-mode(identity #o755), #o755, o755, rwxr-xr-x, u+x,g-rSet the file's mode. A symbolic mode starts from 644. When several blocks give a mode, the first one counts.
:shebang#!… lineFirst line of the file, written once. Makes the file mode 755 unless :tangle-mode says otherwise.
:padlinenoNo blank line between this block and the one before it.
:commentsno, link, yes, org, both, nowebComments around each block (below).
:nowebsee Noweb aboveExpand or strip <<name>> references.
:prologue, :epiloguetextA line before and after the block's code.
:varas for runningShell scalars become assignments, Python values become assignments, Emacs Lisp values are let-bound. For the languages below, as their Org language files write them.
:no-expandanyWrite the body without :var, :prologue, :epilogue or the language's wrapping.

A table in :var loses its first row when its only rule is under that row, or with :colnames yes, and its rules unless :hlines yes, as when the block runs. This holds for every language.

C, C++, cpp, D, java, fortran and clojure blocks are written as Org's org-babel-expand-body:LANG writes them:

LanguageWritten
C, C++, cpp#include lines from :includes, #define lines from :defines, using namespace lines from :namespaces, the :var declarations with table sizes and column-name helpers, then the body between :prologue and :epilogue, wrapped in int main() unless it has a main or :main no is given.
Dmodule mmm;, import lines from :imports (or the IMPORTS property, except when tangling) plus std.stdio and std.conv, the :var declarations, and the body wrapped in int main() as for C.
javaThe body between :prologue and :epilogue, wrapped in a main method when it has no method and in a class when it has none. The class is named by :classname or the body's own class; a dotted :classname adds a package line. :imports adds import lines, and :var values become static fields.
fortran#include and #define lines from :includes and :defines (or the INCLUDES and DEFINES properties, except when tangling), then the :var declarations and the body in program main, unless the body has its own program statement (then :var is refused) or :main no is given.
clojure(ns …) from :ns, the body in a let of the :var values, and a printer around it unless :results output.

With :hlines yes, a table that keeps rules is refused for C, C++, D and Fortran; Java writes null for each rule.

Block switches also apply. -r removes coderef labels such as (ref:name), using the format from -l if given. -i keeps the block's indentation. Otherwise common indentation and surrounding blank lines are removed.

Comments

:commentsWritten
noThe code only.
link, yesA comment with a link back to the block before the code, and "name ends here" after it.
orgThe Org text between the heading (or the previous block) and this block, as a comment.
bothThe Org text and the link comments.
nowebLink comments, plus link comments around each expanded noweb reference.

The link is relative to the tangled file's folder. name is the block's #+NAME, or the heading's title and the block's number under that heading, such as Setup:2.

Comments need the language's comment syntax. orgstar knows it for: emacs-lisp, elisp, lisp, scheme, asm (;;); python, ruby, perl, conf, toml, makefile, awk, tcl, m4, icon, desktop and the shells except fish (#); js, javascript, java, cpp, C++, objc, csharp, idl, pike, antlr, verilog (//); c, C, css (/* */); lua, sql, sqlite, vhdl (--); latex, tex, prolog (%%); ps, metapost (%); f90, dcl (!); html, xml, nxml, mhtml, sgml (<!-- -->); octave (##); pascal ({ }); texinfo (@c); bibtex (@Comment); nroff (\"); bat (rem). For any other language, :comments other than no stops tangling with a message.

Writing the files

What tangling refuses

Tangling stops, writes nothing and says why when:

On iOS

See iOS for the rest of the iOS app.