This document describes and comments Org syntax as it is currently read by its parser (Org Elements) and, therefore, by the export framework. It also includes a few comments on that syntax.

A core concept in this syntax is that only headlines, sections, planning lines and property drawers are context-free12. Every other syntactical part only exists within specific environments.

Three categories are used to classify these environments: "Greater elements", "elements", and "objects", from the broadest scope to the narrowest. The word "element" is used for both Greater and non-Greater elements, the context should make that clear.

The paragraph is the unit of measurement. An element defines syntactical parts that are at the same level as a paragraph, i.e. which cannot contain or be included in a paragraph. An object is a part that could be included in an element. Greater elements are all parts that can contain an element.

Empty lines belong to the largest element ending before them. For example, in a list, empty lines between items belong are part of the item before them, but empty lines at the end of a list belong to the plain list element.

Unless specified otherwise, case is not significant.

#+BEGIN_EXAMPLE STARS KEYWORD PRIORITY TITLE TAGS #+END_EXAMPLE

STARS is a string starting at column 0, containing at least one asterisk (and up to org-inlinetask-min-level if =org-inlinetask= library is loaded) and ended by a space character. The number of asterisks is used to define the level of the headline. It's the sole compulsory part of a headline.

KEYWORD is a TODO keyword, which has to belong to the list defined in org-todo-keywords-1. Case is significant.

PRIORITY is a priority cookie, i.e. a single letter preceded by a hash sign # and enclosed within square brackets.

TITLE can be made of any character but a new line. Though, it will match after every other part have been matched.

TAGS is made of words containing any alpha-numeric character, underscore, at sign, hash sign or percent sign, and separated with colons.

#+BEGIN_EXAMPLE ,*

,** DONE

,*** Some e-mail

,**** TODO [#A] COMMENT Title :tag:a2%: #+END_EXAMPLE

If the first word appearing in the title is "COMMENT", the headline will be considered as "commented". Case is significant.

If its title is org-footnote-section, it will be considered as a "footnote section". Case is significant.

If "ARCHIVE" is one of its tags, it will be considered as "archived". Case is significant.

A headline contains directly one section (optionally), followed by any number of deeper level headlines.

A section contains directly any greater element or element. Only a headline can contain a section. As an exception, text before the first headline in the document also belongs to a section.

As an example, consider the following document:

#+BEGIN_SRC org An introduction.

Some text.

,** Sub-Topic 1

,** Sub-Topic 2

Its internal structure could be summarized as:

Affiliated Keywords

:PROPERTIES: :CUSTOM_ID: Affiliated_keywords :END:

With the exception of inlinetasks, items, planning, clocks, node properties and table rows, every other element type can be assigned attributes.

This is done by adding specific keywords, named "affiliated keywords", just above the element considered, no blank line allowed.

Affiliated keywords are built upon one of the following patterns: "#+KEY: VALUE", "#+KEY[OPTIONAL]: VALUE" or "#+ATTR_BACKEND: VALUE".

KEY is either "CAPTION", "HEADER", "NAME", "PLOT" or "RESULTS" string.

BACKEND is a string constituted of alpha-numeric characters, hyphens or underscores.

OPTIONAL and VALUE can contain any character but a new line. Only "CAPTION" and "RESULTS" keywords can have an optional value.

An affiliated keyword can appear more than once if KEY is either "CAPTION" or "HEADER" or if its pattern is "#+ATTR_BACKEND: VALUE".

"CAPTION", "AUTHOR", "DATE" and "TITLE" keywords can contain objects in their value and their optional value, if applicable.

Greater Elements

:PROPERTIES: :CUSTOM_ID: Greater_Elements :END:

Unless specified otherwise, greater elements can contain directly any other element or greater element excepted:

Greater Blocks

:PROPERTIES: :CUSTOM_ID: Greater_Blocks :END:

Greater blocks consist in the following pattern:

#+BEGIN_EXAMPLE ,#+BEGIN_NAME PARAMETERS CONTENTS ,#+END_NAME #+END_EXAMPLE

NAME can contain any non-whitespace character.

PARAMETERS can contain any character other than new line, and can be omitted.

If NAME is "CENTER", it will be a "center block". If it is "QUOTE", it will be a "quote block".

If the block is neither a center block, a quote block or a block element, it will be a "special block".

CONTENTS can contain any element, except : a line #+END_NAME on its own. Also lines beginning with STARS must be quoted by a comma.

Drawers and Property Drawers

:PROPERTIES: :CUSTOM_ID: Drawers :END:

Pattern for drawers is:

#+BEGIN_EXAMPLE :NAME: CONTENTS :END: #+END_EXAMPLE

NAME can contain word-constituent characters, hyphens and underscores.

CONTENTS can contain any element but another drawer.

Dynamic Blocks

:PROPERTIES: :CUSTOM_ID: Dynamic_Blocks :END:

Pattern for dynamic blocks is:

#+BEGIN_EXAMPLE ,#+BEGIN: NAME PARAMETERS CONTENTS ,#+END: #+END_EXAMPLE

NAME cannot contain any whitespace character.

PARAMETERS can contain any character and can be omitted.

Footnote Definitions

:PROPERTIES: :CUSTOM_ID: Footnote_Definitions :END:

Pattern for footnote definitions is:

#+BEGIN_EXAMPLE 3 CONTENTS #+END_EXAMPLE

It must start at column 0.

LABEL is either a number or follows the pattern "fn:WORD", where word can contain any word-constituent character, hyphens and underscore characters.

CONTENTS can contain any element excepted another footnote definition. It ends at the next footnote definition, the next headline, two consecutive empty lines or the end of buffer.

Inlinetasks are defined by org-inlinetask-min-level contiguous asterisk characters starting at column 0, followed by a whitespace character.

Optionally, inlinetasks can be ended with a string constituted of org-inlinetask-min-level contiguous asterisk characters starting at column 0, followed by a space and the "END" string.

Inlinetasks are recognized only after org-inlinetask library is loaded.

Plain Lists and Items

:PROPERTIES: :CUSTOM_ID: Plain_Lists_and_Items :END:

Items are defined by a line starting with the following pattern: "BULLET COUNTER-SET CHECK-BOX TAG", in which only BULLET is mandatory.

BULLET is either an asterisk, a hyphen, a plus sign character or follows either the pattern "COUNTER." or "COUNTER)". In any case, BULLET is follwed by a whitespace character or line ending.

COUNTER can be a number or a single letter.

COUNTER-SET follows the pattern [@COUNTER].

CHECK-BOX is either a single whitespace character, a "X" character or a hyphen, enclosed within square brackets.

TAG follows "TAG-TEXT ::" pattern, where TAG-TEXT can contain any character but a new line.

An item ends before the next item, the first line less or equally indented than its starting line, or two consecutive empty lines. Indentation of lines within other greater elements do not count, neither do inlinetasks boundaries.

A plain list is a set of consecutive items of the same indentation. It can only directly contain items.

If first item in a plain list has a counter in its bullet, the plain list will be an "ordered plain-list". If it contains a tag, it will be a "descriptive list". Otherwise, it will be an "unordered list". List types are mutually exclusive.

For example, consider the following excerpt of an Org document:

#+BEGIN_EXAMPLE
1. item 1
2. X] item 2
3. some tag
item 2.1
#+END_EXAMPLE

Its internal structure is as follows:

#+BEGIN_EXAMPLE (ordered-plain-list (item) (item (descriptive-plain-list (item)))) #+END_EXAMPLE

Property Drawers

:PROPERTIES: :CUSTOM_ID: Property_Drawers :END:

Property drawers are a special type of drawer containing properties attached to a headline. They are located right after a headline and its planning information.

PROPERTYDRAWER follows the pattern

#+BEGIN_EXAMPLE :PROPERTIES: CONTENTS :END: #+END_EXAMPLE

where CONTENTS consists of zero or more node properties.

Tables

:PROPERTIES: :CUSTOM_ID: Tables :END:

Tables start at lines beginning with either a vertical bar or the "+-" string followed by plus or minus signs only, assuming they are not preceded with lines of the same type. These lines can be indented.

A table starting with a vertical bar has "org" type. Otherwise it has "table.el" type.

Org tables end at the first line not starting with a vertical bar. Table.el tables end at the first line not starting with either a vertical line or a plus sign. Such lines can be indented.

An org table can only contain table rows. A table.el table does not contain anything.

One or more "#+TBLFM: FORMULAS" lines, where "FORMULAS" can contain any character, can follow an org table.

Elements

:PROPERTIES: :CUSTOM_ID: Elements :END:

Elements cannot contain any other element.

Only keywords whose name belongs to org-element-document-properties, verse blocks , paragraphs and table rows can contain objects.

Babel Call

:PROPERTIES: :CUSTOM_ID: Babel_Call :END:

Pattern for babel calls is:

#+BEGIN_EXAMPLE ,#+CALL: VALUE #+END_EXAMPLE

VALUE is optional. It can contain any character but a new line.

Blocks

:PROPERTIES: :CUSTOM_ID: Blocks :END:

Like greater blocks, pattern for blocks is:

#+BEGIN_EXAMPLE ,#+BEGIN_NAME DATA CONTENTS ,#+END_NAME #+END_EXAMPLE

NAME cannot contain any whitespace character.

If NAME is "COMMENT", it will be a "comment block". If it is "EXAMPLE", it will be an "example block". If it is "EXPORT", it will be an "export block". If it is "SRC", it will be a "source block". If it is "VERSE", it will be a "verse block".

DATA can contain any character but a new line. It can be ommitted, unless the block is either a "source block" or an "export block".

In the latter case, it should be constituted of a single word.

In the former case, it must follow the pattern "LANGUAGE SWITCHES ARGUMENTS", where SWITCHES and ARGUMENTS are optional.

LANGUAGE cannot contain any whitespace character.

SWITCHES is made of any number of "SWITCH" patterns, separated by blank lines.

A SWITCH pattern is either "-l "FORMAT"", where FORMAT can contain any character but a double quote and a new line, "-S" or "+S", where S stands for a single letter.

ARGUMENTS can contain any character but a new line.

CONTENTS can contain any character, including new lines. Though it will only contain Org objects if the block is a verse block. Otherwise, CONTENTS will not be parsed.

Clock, Diary Sexp and Planning

:PROPERTIES: :CUSTOM_ID: Clock,_Diary_Sexp_and_Planning :END:

A clock follows either of the patterns below:

#+BEGIN_EXAMPLE CLOCK: INACTIVE-TIMESTAMP CLOCK: INACTIVE-TIMESTAMP-RANGE DURATION #+END_EXAMPLE

INACTIVE-TIMESTAMP, resp. INACTIVE-TIMESTAMP-RANGE, is an inactive, resp. inactive range, timestamp object.

DURATION follows the pattern:

#+BEGIN_EXAMPLE => HH:MM #+END_EXAMPLE

HH is a number containing any number of digits. MM is a two digit numbers.

A diary sexp is a line starting at column 0 with "%%(" string. It can then contain any character besides a new line.

A planning is an element with the following pattern:

where HEADLINE is a headline element and PLANNING is a line filled with INFO parts, where each of them follows the pattern:

#+BEGIN_EXAMPLE KEYWORD: TIMESTAMP #+END_EXAMPLE

KEYWORD is either "DEADLINE", "SCHEDULED" or "CLOSED". TIMESTAMP is a timestamp object.

In particular, no blank line is allowed between PLANNING and HEADLINE.

A "comment line" starts with a hash signe and a whitespace character or an end of line.

Comments can contain any number of consecutive comment lines.

Fixed Width Areas

:PROPERTIES: :CUSTOM_ID: Fixed_Width_Areas :END:

A "fixed-width line" start with a colon character and a whitespace or an end of line.

Fixed width areas can contain any number of consecutive fixed-width lines.

Horizontal Rules

:PROPERTIES: :CUSTOM_ID: Horizontal_Rules :END:

A horizontal rule is a line made of at least 5 consecutive hyphens. It can be indented.

Keywords

:PROPERTIES: :CUSTOM_ID: Keywords :END:

#+BEGIN_EXAMPLE ,#+KEY: VALUE #+END_EXAMPLE

KEY can contain any non-whitespace character, but it cannot be equal to "CALL" or any affiliated keyword.

VALUE can contain any character excepted a new line.

If KEY belongs to org-element-document-properties, VALUE can contain objects.

LaTeX Environments

:PROPERTIES: :CUSTOM_ID: LaTeX_Environments :END:

Pattern for LaTeX environments is:

#+BEGIN_EXAMPLE \begin{NAME} CONTENTS \end{NAME} #+END_EXAMPLE

NAME is constituted of alpha-numeric or asterisk characters.

CONTENTS can contain anything but the "\end{NAME}" string.

Node Properties

:PROPERTIES: :CUSTOM_ID: Node_Properties :END:

Node properties can only exist in property drawers. Their pattern is any of the following

#+BEGIN_EXAMPLE :NAME: VALUE

:NAME+: VALUE

:NAME:

:NAME+: #+END_EXAMPLE

NAME can contain any non-whitespace character but cannot end with a plus sign. It cannot be the empty string.

VALUE can contain anything but a newline character.

Paragraphs

:PROPERTIES: :CUSTOM_ID: Paragraphs :END:

Paragraphs are the default element, which means that any unrecognized context is a paragraph.

Empty lines and other elements end paragraphs.

Paragraphs can contain every type of object.

Table Rows

:PROPERTIES: :CUSTOM_ID: Table_Rows :END:

A table rows is either constituted of a vertical bar and any number of table cells or a vertical bar followed by a hyphen.

In the first case the table row has the "standard" type. In the second case, it has the "rule" type.

Table rows can only exist in tables.

Objects

:PROPERTIES: :CUSTOM_ID: Objects :END:

Objects can only be found in the following locations:

Most objects cannot contain objects. Those which can will be specified.

Entities and LaTeX Fragments

:PROPERTIES: :CUSTOM_ID: Entities_and_LaTeX_Fragments :END:

An entity follows the pattern:

#+BEGIN_EXAMPLE \NAME POST #+END_EXAMPLE

where NAME has a valid association in either org-entities or org-entities-user.

POST is the end of line, "{}" string, or a non-alphabetical character. It isn't separated from NAME by a whitespace character.

A LaTeX fragment can follow multiple patterns:

#+BEGIN_EXAMPLE \NAME BRACKETS $$CONTENTS$$ $CONTENTS$ $$CONTENTS$$ PRE$CHAR$POST PRE$BORDER1 BODY BORDER2$POST #+END_EXAMPLE

NAME contains alphabetical characters only and must not have an association in either org-entities or org-entities-user.

BRACKETS is optional, and is not separated from NAME with white spaces. It may contain any number of the following patterns:

#+BEGIN_EXAMPLE [CONTENTS1] {CONTENTS2} #+END_EXAMPLE

where CONTENTS1 can contain any characters excepted "{" "}", "[" "]" and newline and CONTENTS2 can contain any character excepted "{", "}" and newline.

CONTENTS can contain any character but cannot contain "\)" in the second template or "\]" in the third one.

PRE is either the beginning of line or a character different from $. CHAR is a non-whitespace character different from ~.~, ~,~, ~?~, ;, ' or a double quote. POST is any punctuation (including parentheses and quotes) or space character, or the end of line. BORDER1 is a non-whitespace character different from ~.~, ~,~, ;~ and ~$.

BODY can contain any character excepted $, and may not span over more than 3 lines. BORDER2 is any non-whitespace character different from ~,~, ~.~ and $.

#+ATTR_ASCII: :width 5

#+BEGIN_QUOTE It would introduce incompatibilities with previous Org versions, but support for $...$ (and for symmetry, $$...$$) constructs ought to be removed.

They are slow to parse, fragile, redundant and imply false positives. --- ngz #+END_QUOTE

Export Snippets

:PROPERTIES: :CUSTOM_ID: Export_Snippets :END:

Patter for export snippets is:

#+BEGIN_EXAMPLE @@NAME:VALUE@@ #+END_EXAMPLE

NAME can contain any alpha-numeric character and hyphens.

VALUE can contain anything but "@@" string.

Footnote References

:PROPERTIES: :CUSTOM_ID: Footnote_References :END:

There are four patterns for footnote references:

#+BEGIN_EXAMPLE 4 5 6 #+END_EXAMPLE

LABEL can contain any word constituent character, hyphens and underscores.

DEFINITION can contain any character. Though opening and closing square brackets must be balanced in it. It can contain any object encountered in a paragraph, even other footnote references.

If the reference follows the second pattern, it is called an "inline footnote". If it follows the third one, i.e. if LABEL is omitted, it is an "anonymous footnote".

Inline Babel Calls and Source Blocks

:PROPERTIES: :CUSTOM_ID: Inline_Babel_Calls_and_Source_Blocks :END:

Inline Babel calls follow any of the following patterns:

NAME can contain any character besides (, ~)~ and "\n".

HEADER can contain any character besides ~]~ and "\n".

ARGUMENTS can contain any character besides ~)~ and "\n".

Inline source blocks follow any of the following patterns:

#+BEGIN_EXAMPLE src_LANG{BODY} src_LANG[OPTIONS]{BODY} #+END_EXAMPLE

LANG can contain any non-whitespace character.

OPTIONS and BODY can contain any character but "\n".

Line Breaks

:PROPERTIES: :CUSTOM_ID: Line_Breaks :END:

A line break consists in "\\SPACE" pattern at the end of an otherwise non-empty line.

SPACE can contain any number of tabs and spaces, including 0.

There are 4 major types of links:

PRE1 and POST1, when they exist, are non alphanumeric characters.

RADIO is a string matched by some radio target. It may contain entities, latex fragments, subscript and superscript.

PROTOCOL is a string among org-link-types.

PATH can contain any character but ~]~, <, > and \n.

PRE2 and POST2, when they exist, are non word constituent characters.

PATH2 can contain any non-whitespace character excepted (, ~)~, < and >. It must end with a word-constituent character, or any non-whitespace non-punctuation character followed by /.

DESCRIPTION must be enclosed within square brackets. It can contain any character but square brackets. It can contain any object found in a paragraph excepted a footnote reference, a radio target and a line break. It cannot contain another link either, unless it is a plain or angular link.

DESCRIPTION is optional.

PATH3 is built according to the following patterns:

#+BEGIN_EXAMPLE FILENAME ("file" type) PROTOCOL:PATH4 ("PROTOCOL" type) PROTOCOL://PATH4 ("PROTOCOL" type) id:ID ("id" type) #CUSTOM-ID ("custom-id" type) (CODEREF) ("coderef" type) FUZZY ("fuzzy" type) #+END_EXAMPLE

FILENAME is a file name, either absolute or relative.

PATH4 can contain any character besides square brackets.

ID is constituted of hexadecimal numbers separated with hyphens.

PATH4, CUSTOM-ID, CODEREF and FUZZY can contain any character besides square brackets.

Macros

:PROPERTIES: :CUSTOM_ID: Macros :END:

#+BEGIN_EXAMPLE {{{NAME(ARGUMENTS)}}} #+END_EXAMPLE

NAME must start with a letter and can be followed by any number of alpha-numeric characters, hyphens and underscores.

ARGUMENTS can contain anything but "}}}" string. Values within ARGUMENTS are separated by commas. Non-separating commas have to be escaped with a backslash character.

#+BEGIN_EXAMPLE <<>> #+END_EXAMPLE

CONTENTS can be any character besides <, > and "\n". It cannot start or end with a whitespace character. As far as objects go, it can contain text markup, entities, latex fragments, subscript and superscript only.

#+BEGIN_EXAMPLE <> #+END_EXAMPLE

TARGET can contain any character besides <, > and "\n". It cannot start or end with a whitespace character. It cannot contain any object.

#+BEGIN_EXAMPLE [PERCENT%] [NUM1/NUM2] #+END_EXAMPLE

PERCENT, NUM1 and NUM2 are numbers or the empty string.

Subscript and Superscript

:PROPERTIES: :CUSTOM_ID: Subscript_and_Superscript :END:

Pattern for subscript is:

#+BEGIN_EXAMPLE CHAR_SCRIPT #+END_EXAMPLE

Pattern for superscript is:

#+BEGIN_EXAMPLE CHAR^SCRIPT #+END_EXAMPLE

CHAR is any non-whitespace character.

SCRIPT can be * or an expression enclosed in parenthesis (respectively curly brackets), possibly containing balanced parenthesis (respectively curly brackets).

SCRIPT can also follow the pattern:

#+BEGIN_EXAMPLE SIGN CHARS FINAL #+END_EXAMPLE

SIGN is either a plus sign, a minus sign, or an empty string.

CHARS is any number of alpha-numeric characters, commas, backslashes and dots, or an empty string.

FINAL is an alpha-numeric character.

There is no white space between SIGN, CHARS and FINAL.

Table Cells

:PROPERTIES: :CUSTOM_ID: Table_Cells :END:

#+BEGIN_EXAMPLE CONTENTS SPACES| #+END_EXAMPLE

CONTENTS can contain any character excepted a vertical bar.

SPACES contains any number of space characters, including zero. It can be used to align properly the table.

The final bar may be replaced with a newline character for the last cell in row.

Timestamps

:PROPERTIES: :CUSTOM_ID: Timestamp :END:

There are seven possible patterns for timestamps:

#+BEGIN_EXAMPLE <%%(SEXP)> (diary) (active) [DATE TIME REPEATER-OR-DELAY] (inactive) -- (active range) (active range) [DATE TIME REPEATER-OR-DELAY]--[DATE TIME REPEATER-OR-DELAY] (inactive range) [DATE TIME-TIME REPEATER-OR-DELAY] (inactive range) #+END_EXAMPLE

SEXP can contain any character excepted > and \n.

DATE follows the pattern:

#+BEGIN_EXAMPLE YYYY-MM-DD DAYNAME #+END_EXAMPLE

Y, M and D are digits. DAYNAME can contain any non whitespace-character besides +, -, ~]~, >, a digit or \n.

TIME follows the pattern H:MM. H can be one or two digit long and can start with 0.

REPEATER-OR-DELAY follows the pattern:

#+BEGIN_EXAMPLE MARK VALUE UNIT #+END_EXAMPLE

MARK is + (cumulate type), ++ (catch-up type) or ~.+~ (restart type) for a repeater, and - (all type) or -- (first type) for warning delays.

VALUE is a number.

UNIT is a character among h (hour), d (day), w (week), m~ (month), ~y (year).

MARK, VALUE and UNIT are not separated by whitespace characters.

There can be two REPEATER-OR-DELAY in the timestamp: one as a repeater and one as a warning delay.

Text Markup

:PROPERTIES: :CUSTOM_ID: Emphasis_Markers :END:

Text markup follows the pattern:

#+BEGIN_EXAMPLE PRE MARKER CONTENTS MARKER POST #+END_EXAMPLE

PRE is a whitespace character, (, { ' or a double quote. It can also be a beginning of line.

MARKER is a character among * (bold), = (verbatim), /~ (italic), ~+ (strike-through), _ (underline), ~ (code).

CONTENTS is a string following the pattern:

#+BEGIN_EXAMPLE BORDER BODY BORDER #+END_EXAMPLE

BORDER can be any non-whitespace character excepted ~,~, ' or a double quote.

BODY can contain contain any character but may not span over more than 3 lines.

BORDER and BODY are not separated by whitespaces.

CONTENTS can contain any object encountered in a paragraph when markup is "bold", "italic", "strike-through" or "underline".

POST is a whitespace character, -, ~.~, ~,~, :, ~!~, ~?~, ', ~)~, ~}~ or a double quote. It can also be an end of line.

PRE, MARKER, CONTENTS, MARKER and POST are not separated by whitespace characters.

#+ATTR_ASCII: :width 5

#+BEGIN_QUOTE All of this is wrong if org-emphasis-regexp-components or org-emphasis-alist are modified.

This should really be simplified.

Also, CONTENTS should be anything within code and verbatim emphasis, by definition. --- ngz #+END_QUOTE

Footnotes

quoted by a comma when they do not define a headline.

recognized just by looking at the beginning of the line. Planning lines and property drawers can be recognized by looking at one or two lines above.

As a consequence, using org-element-at-point or ~org-element-context~ will move up to the parent headline, and parse top-down from there until context around original location is found.

1. In particular, the parser requires stars at column 0 to be
2. It also means that only headlines and sections can be