├── .editorconfig ├── .gitattributes ├── .gitignore ├── Cargo.toml ├── LICENSE ├── Makefile ├── Package.swift ├── README.md ├── binding.gyp ├── bindings ├── c │ ├── tree-sitter-djot.h │ └── tree-sitter-djot.pc.in ├── go │ ├── binding.go │ ├── binding_test.go │ └── go.mod ├── node │ ├── binding.cc │ ├── index.d.ts │ └── index.js ├── python │ └── tree_sitter_djot │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── binding.c │ │ └── py.typed ├── rust │ ├── build.rs │ └── lib.rs └── swift │ └── TreeSitterDjot │ └── djot.h ├── grammar.js ├── package-lock.json ├── package.json ├── pyproject.toml ├── queries ├── context.scm ├── folds.scm ├── highlights.scm ├── indents.scm ├── injections.scm ├── locals.scm └── textobjects.scm ├── setup.py ├── src ├── grammar.json ├── node-types.json ├── parser.c ├── scanner.c └── tree_sitter │ ├── alloc.h │ ├── array.h │ └── parser.h ├── test └── corpus │ ├── .editorconfig │ ├── syntax.txt │ └── syntax_crlf.txt └── tree-sitter.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | 9 | [*.{json,toml,yml,gyp}] 10 | indent_style = space 11 | indent_size = 2 12 | 13 | [*.js] 14 | indent_style = space 15 | indent_size = 2 16 | 17 | [*.rs] 18 | indent_style = space 19 | indent_size = 4 20 | 21 | [*.{c,cc,h}] 22 | indent_style = space 23 | indent_size = 4 24 | 25 | [*.{py,pyi}] 26 | indent_style = space 27 | indent_size = 4 28 | 29 | [*.swift] 30 | indent_style = space 31 | indent_size = 4 32 | 33 | [*.go] 34 | indent_style = tab 35 | indent_size = 8 36 | 37 | [Makefile] 38 | indent_style = tab 39 | indent_size = 8 40 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | test/corpus/syntax_crlf.txt text eol=crlf 3 | 4 | src/*.json linguist-generated 5 | src/parser.c linguist-generated 6 | src/tree_sitter/* linguist-generated 7 | 8 | bindings/** linguist-generated 9 | binding.gyp linguist-generated 10 | setup.py linguist-generated 11 | Makefile linguist-generated 12 | Package.swift linguist-generated 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | Cargo.lock 3 | node_modules 4 | .node-version 5 | build 6 | *.log 7 | /test.js 8 | /examples/npm 9 | /target/ 10 | log.html 11 | *.dj 12 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree-sitter-djot" 3 | description = "Djot grammar for the tree-sitter parsing library" 4 | version = "2.0.0" 5 | keywords = ["incremental", "parsing", "tree-sitter", "Djot"] 6 | categories = ["parsing", "text-editors"] 7 | repository = "https://github.com/treeman/tree-sitter-djot" 8 | edition = "2018" 9 | license = "MIT" 10 | 11 | build = "bindings/rust/build.rs" 12 | include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"] 13 | 14 | [lib] 15 | path = "bindings/rust/lib.rs" 16 | 17 | [dependencies] 18 | tree-sitter = ">=0.22.0" 19 | 20 | [build-dependencies] 21 | cc = "1.0" 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Jonas Hietala 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION := 2.0.0 2 | 3 | LANGUAGE_NAME := tree-sitter-djot 4 | 5 | # repository 6 | SRC_DIR := src 7 | 8 | PARSER_REPO_URL := $(shell git -C $(SRC_DIR) remote get-url origin 2>/dev/null) 9 | 10 | ifeq ($(PARSER_URL),) 11 | PARSER_URL := $(subst .git,,$(PARSER_REPO_URL)) 12 | ifeq ($(shell echo $(PARSER_URL) | grep '^[a-z][-+.0-9a-z]*://'),) 13 | PARSER_URL := $(subst :,/,$(PARSER_URL)) 14 | PARSER_URL := $(subst git@,https://,$(PARSER_URL)) 15 | endif 16 | endif 17 | 18 | TS ?= tree-sitter 19 | 20 | # ABI versioning 21 | SONAME_MAJOR := $(word 1,$(subst ., ,$(VERSION))) 22 | SONAME_MINOR := $(word 2,$(subst ., ,$(VERSION))) 23 | 24 | # install directory layout 25 | PREFIX ?= /usr/local 26 | INCLUDEDIR ?= $(PREFIX)/include 27 | LIBDIR ?= $(PREFIX)/lib 28 | PCLIBDIR ?= $(LIBDIR)/pkgconfig 29 | 30 | # object files 31 | OBJS := $(patsubst %.c,%.o,$(wildcard $(SRC_DIR)/*.c)) 32 | 33 | # flags 34 | ARFLAGS := rcs 35 | override CFLAGS += -I$(SRC_DIR) -std=c11 -fPIC 36 | 37 | # OS-specific bits 38 | ifeq ($(OS),Windows_NT) 39 | $(error "Windows is not supported") 40 | else ifeq ($(shell uname),Darwin) 41 | SOEXT = dylib 42 | SOEXTVER_MAJOR = $(SONAME_MAJOR).dylib 43 | SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).dylib 44 | LINKSHARED := $(LINKSHARED)-dynamiclib -Wl, 45 | ifneq ($(ADDITIONAL_LIBS),) 46 | LINKSHARED := $(LINKSHARED)$(ADDITIONAL_LIBS), 47 | endif 48 | LINKSHARED := $(LINKSHARED)-install_name,$(LIBDIR)/lib$(LANGUAGE_NAME).$(SONAME_MAJOR).dylib,-rpath,@executable_path/../Frameworks 49 | else 50 | SOEXT = so 51 | SOEXTVER_MAJOR = so.$(SONAME_MAJOR) 52 | SOEXTVER = so.$(SONAME_MAJOR).$(SONAME_MINOR) 53 | LINKSHARED := $(LINKSHARED)-shared -Wl, 54 | ifneq ($(ADDITIONAL_LIBS),) 55 | LINKSHARED := $(LINKSHARED)$(ADDITIONAL_LIBS) 56 | endif 57 | LINKSHARED := $(LINKSHARED)-soname,lib$(LANGUAGE_NAME).so.$(SONAME_MAJOR) 58 | endif 59 | ifneq ($(filter $(shell uname),FreeBSD NetBSD DragonFly),) 60 | PCLIBDIR := $(PREFIX)/libdata/pkgconfig 61 | endif 62 | 63 | all: lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) $(LANGUAGE_NAME).pc 64 | 65 | lib$(LANGUAGE_NAME).a: $(OBJS) 66 | $(AR) $(ARFLAGS) $@ $^ 67 | 68 | lib$(LANGUAGE_NAME).$(SOEXT): $(OBJS) 69 | $(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@ 70 | ifneq ($(STRIP),) 71 | $(STRIP) $@ 72 | endif 73 | 74 | $(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in 75 | sed -e 's|@URL@|$(PARSER_URL)|' \ 76 | -e 's|@VERSION@|$(VERSION)|' \ 77 | -e 's|@LIBDIR@|$(LIBDIR)|' \ 78 | -e 's|@INCLUDEDIR@|$(INCLUDEDIR)|' \ 79 | -e 's|@REQUIRES@|$(REQUIRES)|' \ 80 | -e 's|@ADDITIONAL_LIBS@|$(ADDITIONAL_LIBS)|' \ 81 | -e 's|=$(PREFIX)|=$${prefix}|' \ 82 | -e 's|@PREFIX@|$(PREFIX)|' $< > $@ 83 | 84 | $(SRC_DIR)/parser.c: grammar.js 85 | $(TS) generate --no-bindings 86 | 87 | install: all 88 | install -Dm644 bindings/c/$(LANGUAGE_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h 89 | install -Dm644 $(LANGUAGE_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 90 | install -Dm755 lib$(LANGUAGE_NAME).a '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a 91 | install -m755 lib$(LANGUAGE_NAME).$(SOEXT) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) 92 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) 93 | ln -sf lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) 94 | 95 | uninstall: 96 | $(RM) '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).a \ 97 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER) \ 98 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXTVER_MAJOR) \ 99 | '$(DESTDIR)$(LIBDIR)'/lib$(LANGUAGE_NAME).$(SOEXT) \ 100 | '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/$(LANGUAGE_NAME).h \ 101 | '$(DESTDIR)$(PCLIBDIR)'/$(LANGUAGE_NAME).pc 102 | 103 | clean: 104 | $(RM) $(OBJS) $(LANGUAGE_NAME).pc lib$(LANGUAGE_NAME).a lib$(LANGUAGE_NAME).$(SOEXT) 105 | 106 | test: 107 | $(TS) test 108 | 109 | .PHONY: all install uninstall clean test 110 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.3 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "TreeSitterDjot", 6 | platforms: [.macOS(.v10_13), .iOS(.v11)], 7 | products: [ 8 | .library(name: "TreeSitterDjot", targets: ["TreeSitterDjot"]), 9 | ], 10 | dependencies: [], 11 | targets: [ 12 | .target(name: "TreeSitterDjot", 13 | path: ".", 14 | exclude: [ 15 | "Cargo.toml", 16 | "Makefile", 17 | "binding.gyp", 18 | "bindings/c", 19 | "bindings/go", 20 | "bindings/node", 21 | "bindings/python", 22 | "bindings/rust", 23 | "prebuilds", 24 | "grammar.js", 25 | "package.json", 26 | "package-lock.json", 27 | "pyproject.toml", 28 | "setup.py", 29 | "test", 30 | "examples", 31 | ".editorconfig", 32 | ".github", 33 | ".gitignore", 34 | ".gitattributes", 35 | ".gitmodules", 36 | ], 37 | sources: [ 38 | "src/parser.c", 39 | // NOTE: if your language has an external scanner, add it here. 40 | ], 41 | resources: [ 42 | .copy("queries") 43 | ], 44 | publicHeadersPath: "bindings/swift", 45 | cSettings: [.headerSearchPath("src")]) 46 | ], 47 | cLanguageStandard: .c11 48 | ) 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter-djot 2 | 3 | This is an experimental [Tree-sitter][] grammar for [Djot][]. 4 | 5 | # Features 6 | 7 | Aims to be fully feature complete with the [Djot specification][] with a few extra features: 8 | 9 | 10 | - Parses an optional frontmatter at the very start of the file, e.g: 11 | 12 | ```` 13 | ---toml 14 | tag = "Some value" 15 | --- 16 | ```` 17 | 18 | - Parses tight sublists. 19 | 20 | Normally in Djot you need to surround a list inside a list with spaces: 21 | 22 | ``` 23 | - List 24 | 25 | - Another 26 | - list 27 | ``` 28 | 29 | This grammar doesn't require a space and recognizes this as a sublist: 30 | 31 | ``` 32 | - List 33 | - Another 34 | - list 35 | ``` 36 | 37 | - Parses standalone `TODO`, `NOTE` and `FIXME`. 38 | 39 | [Tree-sitter]: https://tree-sitter.github.io/tree-sitter/ 40 | [Djot]: https://djot.net/ 41 | [Djot specification]: https://htmlpreview.github.io/?https://github.com/jgm/djot/blob/master/doc/syntax.html 42 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "tree_sitter_djot_binding", 5 | "dependencies": [ 6 | " 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | extern "C" TSLanguage *tree_sitter_djot(); 6 | 7 | // "tree-sitter", "language" hashed with BLAKE2 8 | const napi_type_tag LANGUAGE_TYPE_TAG = { 9 | 0x8AF2E5212AD58ABF, 0xD5006CAD83ABBA16 10 | }; 11 | 12 | Napi::Object Init(Napi::Env env, Napi::Object exports) { 13 | exports["name"] = Napi::String::New(env, "djot"); 14 | auto language = Napi::External::New(env, tree_sitter_djot()); 15 | language.TypeTag(&LANGUAGE_TYPE_TAG); 16 | exports["language"] = language; 17 | return exports; 18 | } 19 | 20 | NODE_API_MODULE(tree_sitter_djot_binding, Init) 21 | -------------------------------------------------------------------------------- /bindings/node/index.d.ts: -------------------------------------------------------------------------------- 1 | type BaseNode = { 2 | type: string; 3 | named: boolean; 4 | }; 5 | 6 | type ChildNode = { 7 | multiple: boolean; 8 | required: boolean; 9 | types: BaseNode[]; 10 | }; 11 | 12 | type NodeInfo = 13 | | (BaseNode & { 14 | subtypes: BaseNode[]; 15 | }) 16 | | (BaseNode & { 17 | fields: { [name: string]: ChildNode }; 18 | children: ChildNode[]; 19 | }); 20 | 21 | type Language = { 22 | name: string; 23 | language: unknown; 24 | nodeTypeInfo: NodeInfo[]; 25 | }; 26 | 27 | declare const language: Language; 28 | export = language; 29 | -------------------------------------------------------------------------------- /bindings/node/index.js: -------------------------------------------------------------------------------- 1 | const root = require("path").join(__dirname, "..", ".."); 2 | 3 | module.exports = require("node-gyp-build")(root); 4 | 5 | try { 6 | module.exports.nodeTypeInfo = require("../../src/node-types.json"); 7 | } catch (_) {} 8 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_djot/__init__.py: -------------------------------------------------------------------------------- 1 | "Djot grammar for tree-sitter" 2 | 3 | from ._binding import language 4 | 5 | __all__ = ["language"] 6 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_djot/__init__.pyi: -------------------------------------------------------------------------------- 1 | def language() -> int: ... 2 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_djot/binding.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct TSLanguage TSLanguage; 4 | 5 | TSLanguage *tree_sitter_djot(void); 6 | 7 | static PyObject* _binding_language(PyObject *self, PyObject *args) { 8 | return PyLong_FromVoidPtr(tree_sitter_djot()); 9 | } 10 | 11 | static PyMethodDef methods[] = { 12 | {"language", _binding_language, METH_NOARGS, 13 | "Get the tree-sitter language for this grammar."}, 14 | {NULL, NULL, 0, NULL} 15 | }; 16 | 17 | static struct PyModuleDef module = { 18 | .m_base = PyModuleDef_HEAD_INIT, 19 | .m_name = "_binding", 20 | .m_doc = NULL, 21 | .m_size = -1, 22 | .m_methods = methods 23 | }; 24 | 25 | PyMODINIT_FUNC PyInit__binding(void) { 26 | return PyModule_Create(&module); 27 | } 28 | -------------------------------------------------------------------------------- /bindings/python/tree_sitter_djot/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/treeman/tree-sitter-djot/eb31845d59b9ee8c1b2098e78e9ca72004bd1579/bindings/python/tree_sitter_djot/py.typed -------------------------------------------------------------------------------- /bindings/rust/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let src_dir = std::path::Path::new("src"); 3 | 4 | let mut c_config = cc::Build::new(); 5 | c_config.include(&src_dir); 6 | c_config 7 | .flag_if_supported("-Wno-unused-parameter") 8 | .flag_if_supported("-Wno-unused-but-set-variable") 9 | .flag_if_supported("-Wno-trigraphs"); 10 | #[cfg(target_env = "msvc")] 11 | c_config.flag("-utf-8"); 12 | 13 | let parser_path = src_dir.join("parser.c"); 14 | c_config.file(&parser_path); 15 | 16 | let scanner_path = src_dir.join("scanner.c"); 17 | c_config.file(&scanner_path); 18 | println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); 19 | 20 | c_config.compile("parser"); 21 | println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap()); 22 | 23 | // If your language uses an external scanner written in C++, 24 | // then include this block of code: 25 | 26 | /* 27 | let mut cpp_config = cc::Build::new(); 28 | cpp_config.cpp(true); 29 | cpp_config.include(&src_dir); 30 | cpp_config 31 | .flag_if_supported("-Wno-unused-parameter") 32 | .flag_if_supported("-Wno-unused-but-set-variable"); 33 | let scanner_path = src_dir.join("scanner.cc"); 34 | cpp_config.file(&scanner_path); 35 | cpp_config.compile("scanner"); 36 | println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap()); 37 | */ 38 | } 39 | -------------------------------------------------------------------------------- /bindings/rust/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides Djot language support for the [tree-sitter][] parsing library. 2 | //! 3 | //! Typically, you will use the [language][language func] function to add this language to a 4 | //! tree-sitter [Parser][], and then use the parser to parse some code: 5 | //! 6 | //! ``` 7 | //! let code = ""; 8 | //! let mut parser = tree_sitter::Parser::new(); 9 | //! parser.set_language(tree_sitter_djot::language()).expect("Error loading Djot grammar"); 10 | //! let tree = parser.parse(code, None).unwrap(); 11 | //! ``` 12 | //! 13 | //! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html 14 | //! [language func]: fn.language.html 15 | //! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html 16 | //! [tree-sitter]: https://tree-sitter.github.io/ 17 | 18 | use tree_sitter::Language; 19 | 20 | extern "C" { 21 | fn tree_sitter_djot() -> Language; 22 | } 23 | 24 | /// Get the tree-sitter [Language][] for this grammar. 25 | /// 26 | /// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html 27 | pub fn language() -> Language { 28 | unsafe { tree_sitter_djot() } 29 | } 30 | 31 | /// The content of the [`node-types.json`][] file for this grammar. 32 | /// 33 | /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types 34 | pub const NODE_TYPES: &'static str = include_str!("../../src/node-types.json"); 35 | 36 | // Uncomment these to include any queries that this grammar contains 37 | 38 | pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm"); 39 | pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm"); 40 | // pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm"); 41 | // pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm"); 42 | 43 | #[cfg(test)] 44 | mod tests { 45 | #[test] 46 | fn test_can_load_grammar() { 47 | let mut parser = tree_sitter::Parser::new(); 48 | parser 49 | .set_language(super::language()) 50 | .expect("Error loading Djot language"); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /bindings/swift/TreeSitterDjot/djot.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_DJOT_H_ 2 | #define TREE_SITTER_DJOT_H_ 3 | 4 | typedef struct TSLanguage TSLanguage; 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | const TSLanguage *tree_sitter_djot(void); 11 | 12 | #ifdef __cplusplus 13 | } 14 | #endif 15 | 16 | #endif // TREE_SITTER_DJOT_H_ 17 | -------------------------------------------------------------------------------- /grammar.js: -------------------------------------------------------------------------------- 1 | const ELEMENT_PRECEDENCE = 100; 2 | 3 | module.exports = grammar({ 4 | name: "djot", 5 | 6 | extras: (_) => ["\r"], 7 | 8 | conflicts: ($) => [ 9 | [$.emphasis_begin, $._symbol_fallback], 10 | [$.strong_begin, $._symbol_fallback], 11 | [$.superscript_begin, $._symbol_fallback], 12 | [$.subscript_begin, $._symbol_fallback], 13 | [$.highlighted_begin, $._symbol_fallback], 14 | [$.insert_begin, $._symbol_fallback], 15 | [$.delete_begin, $._symbol_fallback], 16 | [$._bracketed_text_begin, $._symbol_fallback], 17 | [$._image_description_begin, $._symbol_fallback], 18 | [$.footnote_marker_begin, $._symbol_fallback], 19 | [$.math, $._symbol_fallback], 20 | [$.link_text, $._symbol_fallback], 21 | [$._curly_bracket_span_begin, $._curly_bracket_span_fallback], 22 | ], 23 | 24 | rules: { 25 | document: ($) => 26 | seq(optional($.frontmatter), repeat($._block_with_section)), 27 | 28 | frontmatter: ($) => 29 | seq( 30 | $.frontmatter_marker, 31 | $._whitespace, 32 | optional(field("language", $.language)), 33 | $._newline, 34 | field("content", $.frontmatter_content), 35 | $.frontmatter_marker, 36 | $._newline, 37 | ), 38 | frontmatter_content: ($) => repeat1($._line), 39 | 40 | // A section is only valid on the top level, or nested inside other sections. 41 | // Otherwise standalone headings are used (inside divs for example). 42 | _block_with_section: ($) => choice($.section, $._block_element, $._newline), 43 | _block_with_heading: ($) => 44 | seq( 45 | optional($._block_quote_continuation), 46 | choice($.heading, $._block_element, $._newline), 47 | ), 48 | _block_element: ($) => 49 | choice( 50 | $.list, 51 | $.table, 52 | $.footnote, 53 | $.div, 54 | $.raw_block, 55 | $.code_block, 56 | $.thematic_break, 57 | $.block_quote, 58 | $.link_reference_definition, 59 | $.block_attribute, 60 | $._paragraph, 61 | ), 62 | 63 | // Section should end by a new header with the same or fewer amount of '#'. 64 | section: ($) => 65 | seq( 66 | field("heading", $.heading), 67 | field( 68 | "content", 69 | alias(repeat($._block_with_section), $.section_content), 70 | ), 71 | $._block_close, 72 | ), 73 | 74 | // The external scanner allows for an arbitrary number of `#` 75 | // that can be continued on the next line. 76 | heading: ($) => 77 | seq( 78 | field("marker", alias($._heading_begin, $.marker)), 79 | field("content", alias($._heading_content, $.content)), 80 | $._block_close, 81 | optional($._eof_or_newline), 82 | ), 83 | _heading_content: ($) => 84 | seq( 85 | $._inline_line, 86 | repeat(seq(alias($._heading_continuation, $.marker), $._inline_line)), 87 | ), 88 | 89 | // Djot has a crazy number of different list types 90 | // that we need to keep separate from each other. 91 | list: ($) => 92 | prec.left( 93 | choice( 94 | $._list_dash, 95 | $._list_plus, 96 | $._list_star, 97 | $._list_task, 98 | $._list_definition, 99 | $._list_decimal_period, 100 | $._list_decimal_paren, 101 | $._list_decimal_parens, 102 | $._list_lower_alpha_period, 103 | $._list_lower_alpha_paren, 104 | $._list_lower_alpha_parens, 105 | $._list_upper_alpha_period, 106 | $._list_upper_alpha_paren, 107 | $._list_upper_alpha_parens, 108 | $._list_lower_roman_period, 109 | $._list_lower_roman_paren, 110 | $._list_lower_roman_parens, 111 | $._list_upper_roman_period, 112 | $._list_upper_roman_paren, 113 | $._list_upper_roman_parens, 114 | ), 115 | ), 116 | _list_dash: ($) => 117 | seq(repeat1(alias($._list_item_dash, $.list_item)), $._block_close), 118 | _list_item_dash: ($) => 119 | seq( 120 | optional($._block_quote_prefix), 121 | field("marker", $.list_marker_dash), 122 | field("content", $.list_item_content), 123 | ), 124 | 125 | _list_plus: ($) => 126 | seq(repeat1(alias($._list_item_plus, $.list_item)), $._block_close), 127 | _list_item_plus: ($) => 128 | seq( 129 | optional($._block_quote_prefix), 130 | field("marker", $.list_marker_plus), 131 | field("content", $.list_item_content), 132 | ), 133 | 134 | _list_star: ($) => 135 | seq(repeat1(alias($._list_item_star, $.list_item)), $._block_close), 136 | _list_item_star: ($) => 137 | seq( 138 | optional($._block_quote_prefix), 139 | field("marker", $.list_marker_star), 140 | field("content", $.list_item_content), 141 | ), 142 | 143 | _list_task: ($) => 144 | seq(repeat1(alias($._list_item_task, $.list_item)), $._block_close), 145 | _list_item_task: ($) => 146 | seq( 147 | optional($._block_quote_prefix), 148 | field("marker", $.list_marker_task), 149 | field("content", $.list_item_content), 150 | ), 151 | list_marker_task: ($) => 152 | seq( 153 | $._list_marker_task_begin, 154 | field("checkmark", choice($.checked, $.unchecked)), 155 | $._whitespace1, 156 | ), 157 | checked: (_) => seq("[", choice("x", "X"), "]"), 158 | unchecked: (_) => seq("[", " ", "]"), 159 | 160 | _list_definition: ($) => 161 | seq(repeat1(alias($._list_item_definition, $.list_item)), $._block_close), 162 | _list_item_definition: ($) => 163 | seq( 164 | field("marker", $.list_marker_definition), 165 | field("term", alias($._paragraph_content, $.term)), 166 | choice($._eof_or_newline, $._close_paragraph), 167 | field( 168 | "definition", 169 | alias( 170 | optional( 171 | repeat( 172 | seq( 173 | optional($._block_quote_prefix), 174 | $._list_item_continuation, 175 | $._block_with_heading, 176 | ), 177 | ), 178 | ), 179 | $.definition, 180 | ), 181 | ), 182 | $._list_item_end, 183 | ), 184 | 185 | _list_decimal_period: ($) => 186 | seq( 187 | repeat1(alias($._list_item_decimal_period, $.list_item)), 188 | $._block_close, 189 | ), 190 | _list_item_decimal_period: ($) => 191 | seq( 192 | optional($._block_quote_prefix), 193 | field("marker", $.list_marker_decimal_period), 194 | field("content", $.list_item_content), 195 | ), 196 | _list_decimal_paren: ($) => 197 | seq( 198 | repeat1(alias($._list_item_decimal_paren, $.list_item)), 199 | $._block_close, 200 | ), 201 | _list_item_decimal_paren: ($) => 202 | seq( 203 | optional($._block_quote_prefix), 204 | field("marker", $.list_marker_decimal_paren), 205 | field("content", $.list_item_content), 206 | ), 207 | _list_decimal_parens: ($) => 208 | seq( 209 | repeat1(alias($._list_item_decimal_parens, $.list_item)), 210 | $._block_close, 211 | ), 212 | _list_item_decimal_parens: ($) => 213 | seq( 214 | optional($._block_quote_prefix), 215 | field("marker", $.list_marker_decimal_parens), 216 | field("content", $.list_item_content), 217 | ), 218 | 219 | _list_lower_alpha_period: ($) => 220 | seq( 221 | repeat1(alias($._list_item_lower_alpha_period, $.list_item)), 222 | $._block_close, 223 | ), 224 | _list_item_lower_alpha_period: ($) => 225 | seq( 226 | optional($._block_quote_prefix), 227 | field("marker", $.list_marker_lower_alpha_period), 228 | field("content", $.list_item_content), 229 | ), 230 | _list_lower_alpha_paren: ($) => 231 | seq( 232 | repeat1(alias($._list_item_lower_alpha_paren, $.list_item)), 233 | $._block_close, 234 | ), 235 | _list_item_lower_alpha_paren: ($) => 236 | seq( 237 | optional($._block_quote_prefix), 238 | field("marker", $.list_marker_lower_alpha_paren), 239 | field("content", $.list_item_content), 240 | ), 241 | _list_lower_alpha_parens: ($) => 242 | seq( 243 | repeat1(alias($._list_item_lower_alpha_parens, $.list_item)), 244 | $._block_close, 245 | ), 246 | _list_item_lower_alpha_parens: ($) => 247 | seq( 248 | optional($._block_quote_prefix), 249 | field("marker", $.list_marker_lower_alpha_parens), 250 | field("content", $.list_item_content), 251 | ), 252 | 253 | _list_upper_alpha_period: ($) => 254 | seq( 255 | repeat1(alias($._list_item_upper_alpha_period, $.list_item)), 256 | $._block_close, 257 | ), 258 | _list_item_upper_alpha_period: ($) => 259 | seq( 260 | optional($._block_quote_prefix), 261 | field("marker", $.list_marker_upper_alpha_period), 262 | field("content", $.list_item_content), 263 | ), 264 | _list_upper_alpha_paren: ($) => 265 | seq( 266 | repeat1(alias($._list_item_upper_alpha_paren, $.list_item)), 267 | $._block_close, 268 | ), 269 | _list_item_upper_alpha_paren: ($) => 270 | seq( 271 | optional($._block_quote_prefix), 272 | field("marker", $.list_marker_upper_alpha_paren), 273 | field("content", $.list_item_content), 274 | ), 275 | _list_upper_alpha_parens: ($) => 276 | seq( 277 | repeat1(alias($._list_item_upper_alpha_parens, $.list_item)), 278 | $._block_close, 279 | ), 280 | _list_item_upper_alpha_parens: ($) => 281 | seq( 282 | optional($._block_quote_prefix), 283 | field("marker", $.list_marker_upper_alpha_parens), 284 | field("content", $.list_item_content), 285 | ), 286 | 287 | _list_lower_roman_period: ($) => 288 | seq( 289 | repeat1(alias($._list_item_lower_roman_period, $.list_item)), 290 | $._block_close, 291 | ), 292 | _list_item_lower_roman_period: ($) => 293 | seq( 294 | optional($._block_quote_prefix), 295 | field("marker", $.list_marker_lower_roman_period), 296 | field("content", $.list_item_content), 297 | ), 298 | _list_lower_roman_paren: ($) => 299 | seq( 300 | repeat1(alias($._list_item_lower_roman_paren, $.list_item)), 301 | $._block_close, 302 | ), 303 | _list_item_lower_roman_paren: ($) => 304 | seq( 305 | optional($._block_quote_prefix), 306 | field("marker", $.list_marker_lower_roman_paren), 307 | field("content", $.list_item_content), 308 | ), 309 | _list_lower_roman_parens: ($) => 310 | seq( 311 | repeat1(alias($._list_item_lower_roman_parens, $.list_item)), 312 | $._block_close, 313 | ), 314 | _list_item_lower_roman_parens: ($) => 315 | seq( 316 | optional($._block_quote_prefix), 317 | field("marker", $.list_marker_lower_roman_parens), 318 | field("content", $.list_item_content), 319 | ), 320 | 321 | _list_upper_roman_period: ($) => 322 | seq( 323 | repeat1(alias($._list_item_upper_roman_period, $.list_item)), 324 | $._block_close, 325 | ), 326 | _list_item_upper_roman_period: ($) => 327 | seq( 328 | optional($._block_quote_prefix), 329 | field("marker", $.list_marker_upper_roman_period), 330 | field("content", $.list_item_content), 331 | ), 332 | _list_upper_roman_paren: ($) => 333 | seq( 334 | repeat1(alias($._list_item_upper_roman_paren, $.list_item)), 335 | $._block_close, 336 | ), 337 | _list_item_upper_roman_paren: ($) => 338 | seq( 339 | optional($._block_quote_prefix), 340 | field("marker", $.list_marker_upper_roman_paren), 341 | field("content", $.list_item_content), 342 | ), 343 | _list_upper_roman_parens: ($) => 344 | seq( 345 | repeat1(alias($._list_item_upper_roman_parens, $.list_item)), 346 | $._block_close, 347 | ), 348 | _list_item_upper_roman_parens: ($) => 349 | seq( 350 | optional($._block_quote_prefix), 351 | field("marker", $.list_marker_upper_roman_parens), 352 | field("content", $.list_item_content), 353 | ), 354 | 355 | list_item_content: ($) => 356 | seq( 357 | $._block_with_heading, 358 | $._indented_content_spacer, 359 | optional( 360 | repeat( 361 | seq( 362 | optional($._block_quote_prefix), 363 | $._list_item_continuation, 364 | $._block_with_heading, 365 | $._indented_content_spacer, 366 | ), 367 | ), 368 | ), 369 | $._list_item_end, 370 | ), 371 | 372 | table: ($) => 373 | prec.right( 374 | seq( 375 | repeat1($._table_row), 376 | optional($._newline), 377 | optional($.table_caption), 378 | ), 379 | ), 380 | _table_row: ($) => 381 | seq( 382 | optional($._block_quote_prefix), 383 | choice($.table_header, $.table_separator, $.table_row), 384 | ), 385 | table_header: ($) => 386 | seq( 387 | alias($._table_header_begin, "|"), 388 | repeat($._table_cell), 389 | $._table_row_end_newline, 390 | ), 391 | table_separator: ($) => 392 | seq( 393 | alias($._table_separator_begin, "|"), 394 | repeat($._table_cell_alignment), 395 | $._table_row_end_newline, 396 | ), 397 | table_row: ($) => 398 | seq( 399 | alias($._table_row_begin, "|"), 400 | repeat($._table_cell), 401 | $._table_row_end_newline, 402 | ), 403 | _table_cell: ($) => 404 | seq(alias($._inline, $.table_cell), alias($._table_cell_end, "|")), 405 | _table_cell_alignment: ($) => 406 | seq( 407 | // Note that alignment appearance is already checked in the external 408 | // scanner when `_table_separator_begin` is output. 409 | // Therefore this regex can be simplified. 410 | alias(token.immediate(/[^|]+/), $.table_cell_alignment), 411 | alias($._table_cell_end, "|"), 412 | ), 413 | table_caption: ($) => 414 | seq( 415 | field("marker", alias($._table_caption_begin, $.marker)), 416 | field("content", alias(repeat1($._inline_line), $.content)), 417 | choice($._table_caption_end, "\0"), 418 | ), 419 | 420 | footnote: ($) => 421 | seq( 422 | $._footnote_mark_begin, 423 | $.footnote_marker_begin, 424 | field("label", $.reference_label), 425 | alias("]:", $.footnote_marker_end), 426 | $._whitespace1, 427 | field("content", $.footnote_content), 428 | ), 429 | footnote_content: ($) => 430 | seq( 431 | $._block_with_heading, 432 | $._indented_content_spacer, 433 | optional( 434 | repeat( 435 | seq( 436 | optional($._block_quote_prefix), 437 | $._footnote_continuation, 438 | $._block_with_heading, 439 | $._indented_content_spacer, 440 | ), 441 | ), 442 | ), 443 | $._footnote_end, 444 | ), 445 | 446 | div: ($) => 447 | seq( 448 | $._div_marker_begin, 449 | $._newline, 450 | field("content", alias(repeat($._block_with_heading), $.content)), 451 | optional($._block_quote_prefix), 452 | $._block_close, 453 | optional(seq(alias($._div_end, $.div_marker_end), $._newline)), 454 | ), 455 | _div_marker_begin: ($) => 456 | seq( 457 | alias($._div_begin, $.div_marker_begin), 458 | optional(seq($._whitespace1, field("class", $.class_name))), 459 | ), 460 | class_name: ($) => $._id, 461 | 462 | code_block: ($) => 463 | seq( 464 | alias($._code_block_begin, $.code_block_marker_begin), 465 | $._whitespace, 466 | optional(field("language", $.language)), 467 | $._newline, 468 | optional(field("code", $.code)), 469 | $._block_close, 470 | optional( 471 | seq(alias($._code_block_end, $.code_block_marker_end), $._newline), 472 | ), 473 | ), 474 | raw_block: ($) => 475 | seq( 476 | alias($._code_block_begin, $.raw_block_marker_begin), 477 | $._whitespace, 478 | field("info", $.raw_block_info), 479 | $._newline, 480 | field("content", optional(alias($.code, $.content))), 481 | $._block_close, 482 | optional( 483 | seq(alias($._code_block_end, $.raw_block_marker_end), $._newline), 484 | ), 485 | ), 486 | raw_block_info: ($) => 487 | seq( 488 | field("marker", alias("=", $.language_marker)), 489 | field("language", $.language), 490 | ), 491 | 492 | language: (_) => /[^\n\t \{\}=]+/, 493 | code: ($) => 494 | prec.left(repeat1(seq(optional($._block_quote_prefix), $._line))), 495 | _line: ($) => seq(/[^\n]*/, $._newline), 496 | 497 | thematic_break: ($) => 498 | seq(choice($._thematic_break_dash, $._thematic_break_star), $._newline), 499 | 500 | block_quote: ($) => 501 | seq( 502 | alias($._block_quote_begin, $.block_quote_marker), 503 | field("content", alias($._block_quote_content, $.content)), 504 | $._block_close, 505 | ), 506 | _block_quote_content: ($) => 507 | seq( 508 | choice($.heading, $._block_element), 509 | repeat(seq($._block_quote_prefix, optional($._block_element))), 510 | ), 511 | _block_quote_prefix: ($) => 512 | prec.left( 513 | repeat1( 514 | prec.left(alias($._block_quote_continuation, $.block_quote_marker)), 515 | ), 516 | ), 517 | 518 | link_reference_definition: ($) => 519 | seq( 520 | $._link_ref_def_mark_begin, 521 | "[", 522 | field("label", alias($._inline, $.link_label)), 523 | $._link_ref_def_label_end, 524 | "]", 525 | ":", 526 | optional(seq($._whitespace1, field("destination", $.link_destination))), 527 | $._newline, 528 | ), 529 | link_destination: (_) => /\S+/, 530 | 531 | block_attribute: ($) => 532 | seq( 533 | alias($._block_attribute_begin, "{"), 534 | field( 535 | "args", 536 | alias( 537 | repeat( 538 | choice( 539 | $.class, 540 | $.identifier, 541 | $.key_value, 542 | alias($._comment, $.comment), 543 | $._whitespace1, 544 | $._newline, 545 | ), 546 | ), 547 | $.args, 548 | ), 549 | ), 550 | "}", 551 | $._newline, 552 | ), 553 | class: ($) => seq(".", alias($.class_name, "class")), 554 | identifier: (_) => token(seq("#", token.immediate(/[^\s\}]+/))), 555 | key_value: ($) => seq(field("key", $.key), "=", field("value", $.value)), 556 | key: ($) => $._id, 557 | value: (_) => choice(seq('"', /[^"\n]+/, '"'), /\w+/), 558 | 559 | // Paragraphs are a bit special parsing wise as it's the "fallback" 560 | // block, where everything that doesn't fit will go. 561 | // There's no "start" token and they're not tracked by the external scanner. 562 | // 563 | // Instead they're ended by either a blankline or by an explicit 564 | // `_close_paragraph` token (by for instance div markers). 565 | // 566 | // Lines inside paragraphs are handled by the `_newline_inline` token 567 | // that's a newline character only valid inside an `_inline` context. 568 | // When the `newline_inline` token is no longer valid, the `_newline` 569 | // token can be emitted which closes the paragraph content. 570 | _paragraph: ($) => 571 | seq( 572 | alias($._paragraph_content, $.paragraph), 573 | // Blankline is split out from paragraph to enable textobject 574 | // to not select newline up to following text. 575 | choice($._eof_or_newline, $._close_paragraph), 576 | ), 577 | _paragraph_content: ($) => 578 | // Newlines inside inline blocks should be of the `_newline_inline` type. 579 | seq( 580 | optional($._block_quote_prefix), 581 | $._inline, 582 | repeat( 583 | seq($._newline_inline, optional($._block_quote_prefix), $._inline), 584 | ), 585 | // Last newline can be of the normal variant to signal the end of the paragraph. 586 | $._eof_or_newline, 587 | ), 588 | 589 | _whitespace: (_) => token.immediate(/[ \t]*/), 590 | _whitespace1: (_) => token.immediate(/[ \t]+/), 591 | 592 | _inline: ($) => 593 | prec.left( 594 | repeat1(choice($._inline_element, $._newline_inline, $._whitespace1)), 595 | ), 596 | 597 | _inline_without_trailing_space: ($) => 598 | seq( 599 | prec.left( 600 | repeat(choice($._inline_element, $._newline_inline, $._whitespace1)), 601 | ), 602 | $._inline_element, 603 | ), 604 | 605 | _inline_element: ($) => 606 | prec.left( 607 | choice( 608 | // Span is declared separately because it always parses an `inline_attribute`, 609 | // while the attribute is optional for everything else. 610 | $.span, 611 | seq( 612 | choice( 613 | $._smart_punctuation, 614 | $.backslash_escape, 615 | $.hard_line_break, 616 | // Elements containing other inline elements needs to have the same precedence level 617 | // so we can choose the element that's closed first. 618 | // 619 | // For example: 620 | // 621 | // *[x](y*) 622 | // 623 | // Should parse a strong element instead of a link because it's closed before the link. 624 | // 625 | // They also need a higher precedence than the fallback tokens so that: 626 | // 627 | // _a_ 628 | // 629 | // Is parsed as emphasis instead of just text with `_symbol_fallback` tokens. 630 | prec.dynamic(ELEMENT_PRECEDENCE, $.emphasis), 631 | prec.dynamic(ELEMENT_PRECEDENCE, $.strong), 632 | prec.dynamic(ELEMENT_PRECEDENCE, $.highlighted), 633 | prec.dynamic(ELEMENT_PRECEDENCE, $.superscript), 634 | prec.dynamic(ELEMENT_PRECEDENCE, $.subscript), 635 | prec.dynamic(ELEMENT_PRECEDENCE, $.insert), 636 | prec.dynamic(ELEMENT_PRECEDENCE, $.delete), 637 | prec.dynamic(ELEMENT_PRECEDENCE, $.footnote_reference), 638 | prec.dynamic(ELEMENT_PRECEDENCE, $._image), 639 | prec.dynamic(ELEMENT_PRECEDENCE, $._link), 640 | $.autolink, 641 | $.verbatim, 642 | $.math, 643 | $.raw_inline, 644 | $.symbol, 645 | $.inline_comment, 646 | $._todo_highlights, 647 | // Text and the symbol fallback matches everything not matched elsewhere. 648 | $._symbol_fallback, 649 | $._text, 650 | ), 651 | optional( 652 | // We need a separate fallback token for the opening `{` 653 | // for the parser to recognize the conflict. 654 | choice( 655 | // Use precedence for inline attribute as well to allow 656 | // closure before other elements. 657 | prec.dynamic( 658 | 2 * ELEMENT_PRECEDENCE, 659 | field("attribute", $.inline_attribute), 660 | ), 661 | $._curly_bracket_span_fallback, 662 | ), 663 | ), 664 | ), 665 | ), 666 | ), 667 | 668 | _inline_line: ($) => seq($._inline, $._eof_or_newline), 669 | 670 | _smart_punctuation: ($) => 671 | choice($.quotation_marks, $.ellipsis, $.em_dash, $.en_dash), 672 | // It would be nice to be able to mark bare " and ', but then we'd have to be smarter 673 | // so we don't mark the ' in `it's`. Not sure if we can do that in a correct way. 674 | quotation_marks: (_) => token(choice('{"', '"}', "{'", "'}", '\\"', "\\'")), 675 | ellipsis: (_) => "...", 676 | em_dash: (_) => "---", 677 | en_dash: (_) => "--", 678 | 679 | backslash_escape: (_) => /\\[^\r\n]/, 680 | 681 | autolink: (_) => seq("<", /[^>\s]+/, ">"), 682 | 683 | symbol: (_) => token(seq(":", /[\w\d_-]+/, ":")), 684 | 685 | // Emphasis and strong are a little special as they don't allow spaces next 686 | // to begin and end markers unless using the bracketed variant. 687 | // The strategy to solve this: 688 | // 689 | // Begin: Use the zero-width `$._non_whitespace_check` token to avoid the `_ ` case. 690 | // End: Use `$._inline_without_trailing_space` to match inline without a trailing space 691 | // and let the end token in the external scanner consume space for the `_}` case 692 | // and not for the `_` case. 693 | emphasis: ($) => 694 | seq( 695 | field("begin_marker", $.emphasis_begin), 696 | $._emphasis_mark_begin, 697 | field("content", alias($._inline_without_trailing_space, $.content)), 698 | field("end_marker", $.emphasis_end), 699 | ), 700 | emphasis_begin: ($) => choice("{_", seq("_", $._non_whitespace_check)), 701 | 702 | strong: ($) => 703 | seq( 704 | field("begin_marker", $.strong_begin), 705 | $._strong_mark_begin, 706 | field("content", alias($._inline_without_trailing_space, $.content)), 707 | field("end_marker", $.strong_end), 708 | ), 709 | strong_begin: ($) => choice("{*", seq("*", $._non_whitespace_check)), 710 | 711 | // The syntax description isn't clear about if non-bracket can contain surrounding spaces. 712 | // The live playground suggests that yes they can, although it's a bit inconsistent. 713 | superscript: ($) => 714 | seq( 715 | field("begin_marker", $.superscript_begin), 716 | $._superscript_mark_begin, 717 | field("content", alias($._inline, $.content)), 718 | field("end_marker", $.superscript_end), 719 | ), 720 | superscript_begin: (_) => choice("{^", "^"), 721 | 722 | subscript: ($) => 723 | seq( 724 | field("begin_marker", $.subscript_begin), 725 | $._subscript_mark_begin, 726 | field("content", alias($._inline, $.content)), 727 | field("end_marker", $.subscript_end), 728 | ), 729 | subscript_begin: (_) => choice("{~", "~"), 730 | 731 | highlighted: ($) => 732 | seq( 733 | field("begin_marker", $.highlighted_begin), 734 | $._highlighted_mark_begin, 735 | field("content", alias($._inline, $.content)), 736 | field("end_marker", $.highlighted_end), 737 | ), 738 | highlighted_begin: (_) => "{=", 739 | insert: ($) => 740 | seq( 741 | field("begin_marker", $.insert_begin), 742 | $._insert_mark_begin, 743 | field("content", alias($._inline, $.content)), 744 | field("end_marker", $.insert_end), 745 | ), 746 | insert_begin: (_) => "{+", 747 | delete: ($) => 748 | seq( 749 | field("begin_marker", $.delete_begin), 750 | $._delete_mark_begin, 751 | field("content", alias($._inline, $.content)), 752 | field("end_marker", $.delete_end), 753 | ), 754 | delete_begin: (_) => "{-", 755 | 756 | footnote_reference: ($) => 757 | seq( 758 | $.footnote_marker_begin, 759 | $._square_bracket_span_mark_begin, 760 | $.reference_label, 761 | alias($._square_bracket_span_end, $.footnote_marker_end), 762 | ), 763 | footnote_marker_begin: (_) => "[^", 764 | 765 | reference_label: ($) => $._id, 766 | _id: (_) => /[\w_-]+/, 767 | 768 | _image: ($) => 769 | choice( 770 | $.full_reference_image, 771 | $.collapsed_reference_image, 772 | $.inline_image, 773 | ), 774 | full_reference_image: ($) => 775 | seq(field("description", $.image_description), $._link_label), 776 | collapsed_reference_image: ($) => 777 | seq(field("description", $.image_description), token.immediate("[]")), 778 | inline_image: ($) => 779 | seq( 780 | field("description", $.image_description), 781 | field("destination", $.inline_link_destination), 782 | ), 783 | 784 | image_description: ($) => 785 | seq( 786 | $._image_description_begin, 787 | $._square_bracket_span_mark_begin, 788 | optional($._inline), 789 | alias($._square_bracket_span_end, "]"), 790 | ), 791 | _image_description_begin: (_) => "![", 792 | 793 | _link: ($) => 794 | choice($.full_reference_link, $.collapsed_reference_link, $.inline_link), 795 | full_reference_link: ($) => seq(field("text", $.link_text), $._link_label), 796 | collapsed_reference_link: ($) => 797 | seq(field("text", $.link_text), token.immediate("[]")), 798 | inline_link: ($) => 799 | seq( 800 | field("text", $.link_text), 801 | field("destination", $.inline_link_destination), 802 | ), 803 | 804 | link_text: ($) => 805 | choice( 806 | seq( 807 | $._bracketed_text_begin, 808 | $._square_bracket_span_mark_begin, 809 | $._inline, 810 | // Alias to "]" to allow us to highlight it in Neovim. 811 | // Maybe some bug, or some undocumented behavior? 812 | alias($._square_bracket_span_end, "]"), 813 | ), 814 | // Required as we track fallback characters between bracketed begin and end, 815 | // but when it's empty it skips blocks the inline link destination. 816 | // This is an easy workaround for that special case. 817 | "[]", 818 | ), 819 | 820 | span: ($) => 821 | seq( 822 | $._bracketed_text_begin, 823 | $._square_bracket_span_mark_begin, 824 | field("content", alias($._inline, $.content)), 825 | // Prefer span over regular text + inline attribute. 826 | prec.dynamic( 827 | ELEMENT_PRECEDENCE, 828 | alias($._square_bracket_span_end, "]"), 829 | ), 830 | field("attribute", $.inline_attribute), 831 | ), 832 | 833 | _bracketed_text_begin: (_) => "[", 834 | 835 | inline_attribute: ($) => 836 | seq( 837 | $._curly_bracket_span_begin, 838 | $._curly_bracket_span_mark_begin, 839 | alias( 840 | repeat( 841 | choice( 842 | $.class, 843 | $.identifier, 844 | $.key_value, 845 | alias($._comment, $.comment), 846 | $._whitespace1, 847 | $._newline_inline, 848 | ), 849 | ), 850 | $.args, 851 | ), 852 | alias($._curly_bracket_span_end, "}"), 853 | ), 854 | _curly_bracket_span_begin: (_) => "{", 855 | 856 | _bracketed_text: ($) => 857 | seq( 858 | $._bracketed_text_begin, 859 | $._square_bracket_span_mark_begin, 860 | $._inline, 861 | $._square_bracket_span_end, 862 | ), 863 | 864 | _link_label: ($) => 865 | seq( 866 | "[", 867 | field("label", alias($._inline, $.link_label)), 868 | token.immediate("]"), 869 | ), 870 | inline_link_destination: ($) => 871 | seq( 872 | $._parens_span_begin, 873 | $._parens_span_mark_begin, 874 | $._inline_link_url, 875 | alias($._parens_span_end, ")"), 876 | ), 877 | _inline_link_url: ($) => 878 | // Can escape `)`, but shouldn't capture it. 879 | repeat1(choice(/([^\)\n]|\\\))+/, $._newline_inline)), 880 | _parens_span_begin: (_) => "(", 881 | 882 | _comment: ($) => 883 | seq( 884 | "%", 885 | field( 886 | "content", 887 | alias(repeat(choice($.backslash_escape, /[^%}]/)), $.content), 888 | ), 889 | choice(alias($._comment_end_marker, "%"), $._comment_close), 890 | ), 891 | 892 | inline_comment: ($) => 893 | seq( 894 | $._whitespace1, 895 | $._inline_comment_begin, 896 | $._curly_bracket_span_mark_begin, 897 | $._comment, 898 | alias($._curly_bracket_span_end, "}"), 899 | ), 900 | 901 | raw_inline: ($) => 902 | seq( 903 | field( 904 | "begin_marker", 905 | alias($._verbatim_begin, $.raw_inline_marker_begin), 906 | ), 907 | field("content", alias($._verbatim_content, $.content)), 908 | field("end_marker", alias($._verbatim_end, $.raw_inline_marker_end)), 909 | field("attribute", $.raw_inline_attribute), 910 | ), 911 | raw_inline_attribute: ($) => 912 | seq(token.immediate("{="), field("language", $.language), "}"), 913 | math: ($) => 914 | seq( 915 | field("math_marker", alias("$", $.math_marker)), 916 | field("begin_marker", alias($._verbatim_begin, $.math_marker_begin)), 917 | field("content", alias($._verbatim_content, $.content)), 918 | field("end_marker", alias($._verbatim_end, $.math_marker_end)), 919 | ), 920 | verbatim: ($) => 921 | seq( 922 | field( 923 | "begin_marker", 924 | alias($._verbatim_begin, $.verbatim_marker_begin), 925 | ), 926 | field("content", alias($._verbatim_content, $.content)), 927 | field("end_marker", alias($._verbatim_end, $.verbatim_marker_end)), 928 | ), 929 | 930 | _todo_highlights: ($) => choice($.todo, $.note, $.fixme), 931 | todo: (_) => choice("TODO", "WIP"), 932 | note: (_) => choice("NOTE", "INFO", "XXX"), 933 | fixme: (_) => "FIXME", 934 | 935 | // These exists to explicit trigger an LR collision with existing 936 | // prefixes. A collision isn't detected with a string and the 937 | // catch-all `_text` regex. 938 | // 939 | // Don't use dynamic precedence on the fallback, instead use it 940 | // on span end tokens to prevent these branches from getting pruned 941 | // when the tree grows large. 942 | // 943 | // Block level collisions handled by the scanner scanning ahead. 944 | _symbol_fallback: ($) => 945 | choice( 946 | // Standalone emphasis and strong markers are required for backtracking 947 | "_", 948 | "*", 949 | // Whitespace sensitive 950 | seq( 951 | choice("{_", seq("_", $._non_whitespace_check)), 952 | choice($._emphasis_mark_begin, $._in_fallback), 953 | ), 954 | seq( 955 | choice("{*", seq("*", $._non_whitespace_check)), 956 | choice($._strong_mark_begin, $._in_fallback), 957 | ), 958 | // Not sensitive to whitespace 959 | seq( 960 | choice("{^", "^"), 961 | choice($._superscript_mark_begin, $._in_fallback), 962 | ), 963 | seq(choice("{~", "~"), choice($._subscript_mark_begin, $._in_fallback)), 964 | // Only bracketed versions 965 | seq("{=", choice($._highlighted_mark_begin, $._in_fallback)), 966 | seq("{+", choice($._insert_mark_begin, $._in_fallback)), 967 | seq("{-", choice($._delete_mark_begin, $._in_fallback)), 968 | 969 | // Bracketed spans 970 | seq("[^", choice($._square_bracket_span_mark_begin, $._in_fallback)), 971 | seq("![", choice($._square_bracket_span_mark_begin, $._in_fallback)), 972 | seq("[", choice($._square_bracket_span_mark_begin, $._in_fallback)), 973 | seq("(", choice($._parens_span_mark_begin, $._in_fallback)), 974 | 975 | // Autolink 976 | "<", 977 | seq("<", /[^>\s]+/), 978 | 979 | // Math 980 | "$", 981 | 982 | // Empty link text 983 | "[]", 984 | ), 985 | 986 | // Used to branch on inline attributes that may follow any element. 987 | _curly_bracket_span_fallback: ($) => 988 | seq("{", choice($._curly_bracket_span_mark_begin, $._in_fallback)), 989 | 990 | // It's a bit faster with repeat1 here. 991 | _text: (_) => repeat1(/\S/), 992 | }, 993 | 994 | externals: ($) => [ 995 | // Used as default value in scanner, should never be referenced. 996 | $._ignored, 997 | 998 | // Token to implicitly terminate open blocks, 999 | // for instance in this case: 1000 | // 1001 | // ::: 1002 | // :::: 1003 | // txt 1004 | // ::: <- closes both divs 1005 | // 1006 | // `_block_close` is used to close both open divs, 1007 | // and the outer most div consumes the optional ending div marker. 1008 | $._block_close, 1009 | 1010 | // Different kinds of newlines are handled by the external scanner so 1011 | // we can manually track indent (and reset it on newlines). 1012 | $._eof_or_newline, 1013 | // `_newline` is a regular newline, and is used to end paragraphs and other blocks. 1014 | $._newline, 1015 | // `_newline_inline` is a newline that's only valid inside an inline context. 1016 | // It contains logic on when to terminate a paragraph. 1017 | // When a paragraph should be closed, `_newline_inline` will not be valid, 1018 | // so `_newline` will have to be used, which is only valid at the end of a paragraph. 1019 | $._newline_inline, 1020 | // A zero-width whitespace check token. 1021 | $._non_whitespace_check, 1022 | // A hard line break that doesn't consume a newline. 1023 | $.hard_line_break, 1024 | 1025 | // Detects a frontmatter delimiters: `---` 1026 | // Handled externally to resolve conflicts with list markers and thematic breaks. 1027 | $.frontmatter_marker, 1028 | 1029 | // Blocks. 1030 | // The external scanner keeps a stack of blocks for context in order to 1031 | // match and close against open blocks. 1032 | 1033 | // Headings open and close sections, but they're not exposed to `grammar.js` 1034 | // but is used by the external scanner internally. 1035 | $._heading_begin, 1036 | // Heading continuation can continue a heading, but only if 1037 | // they match the number of `#` (or there's no `#`). 1038 | $._heading_continuation, 1039 | 1040 | // Matches div markers with varying number of `:`. 1041 | $._div_begin, 1042 | $._div_end, 1043 | // Matches code block markers with varying number of `. 1044 | $._code_block_begin, 1045 | $._code_block_end, 1046 | // There are lots of lists in Djot that shouldn't be mixed. 1047 | // Parsing a list marker opens or closes lists depending on the marker type. 1048 | $.list_marker_dash, 1049 | $.list_marker_star, 1050 | $.list_marker_plus, 1051 | // `list_marker_task_begin` only matches opening `- `, `+ `, or `* `, but 1052 | // only if followed by a valid task box. 1053 | // This is done to allow the task box markers like `x` to have their own token. 1054 | $._list_marker_task_begin, 1055 | $.list_marker_definition, 1056 | $.list_marker_decimal_period, 1057 | $.list_marker_lower_alpha_period, 1058 | $.list_marker_upper_alpha_period, 1059 | $.list_marker_lower_roman_period, 1060 | $.list_marker_upper_roman_period, 1061 | $.list_marker_decimal_paren, 1062 | $.list_marker_lower_alpha_paren, 1063 | $.list_marker_upper_alpha_paren, 1064 | $.list_marker_lower_roman_paren, 1065 | $.list_marker_upper_roman_paren, 1066 | $.list_marker_decimal_parens, 1067 | $.list_marker_lower_alpha_parens, 1068 | $.list_marker_upper_alpha_parens, 1069 | $.list_marker_lower_roman_parens, 1070 | $.list_marker_upper_roman_parens, 1071 | // List item continuation consumes whitespace indentation for lists. 1072 | $._list_item_continuation, 1073 | // `_list_item_end` is responsible for closing an open list, 1074 | // if indent or list markers are mismatched. 1075 | $._list_item_end, 1076 | // `_indented_content_spacer` is either a blankline separating 1077 | // indented content or a zero-width marker if content continues immediately. 1078 | // 1079 | // - a 1080 | // <- spacer 1081 | // ``` 1082 | // x 1083 | // ``` 1084 | // b <- zero-width spacer (followed by a list item continuation). 1085 | // 1086 | $._indented_content_spacer, 1087 | // Paragraphs are anonymous blocks and open blocks aren't tracked by the 1088 | // external scanner. `close_paragraph` is a marker that's responsible 1089 | // for closing the paragraph early, for example on a div marker. 1090 | $._close_paragraph, 1091 | $._block_quote_begin, 1092 | // `block_quote_continuation` continues an open block quote, and can be included 1093 | // in other elements. For example: 1094 | // 1095 | // > a <- `block_quote_begin` (before the paragraph) 1096 | // > b <- `block_quote_continuation` (inside the paragraph) 1097 | // 1098 | $._block_quote_continuation, 1099 | $._thematic_break_dash, 1100 | $._thematic_break_star, 1101 | // Footnotes have significant whitespace and can contain blocks, 1102 | // the same as lists. 1103 | $._footnote_mark_begin, 1104 | $._footnote_continuation, 1105 | $._footnote_end, 1106 | // Link reference definitions needs to make sure 1107 | // that inline content doesn't escape the label brackets 1108 | // or continue into other lines, like this: 1109 | // 1110 | // [one_]: /can_have_many_underscores_in_url 1111 | // [two_]: /should_not_be_emphasis 1112 | // 1113 | // The above should be two definitions, not a paragraph with emphasis. 1114 | $._link_ref_def_mark_begin, 1115 | $._link_ref_def_label_end, 1116 | // Table begin consumes a `|` if the row is a valid table row. 1117 | // In Djot the number of table cells don't have to match for in the table. 1118 | // The different types are here to let the scanner take care of the detection 1119 | // to avoid tree-sitter branching. 1120 | // `header`, `separator`, and `row` are just different types of table rows. 1121 | $._table_header_begin, 1122 | $._table_separator_begin, 1123 | $._table_row_begin, 1124 | // `_table_row_end_newline` consumes the ending newline. 1125 | $._table_row_end_newline, 1126 | // `_table_cell_end` consumes the ending `|`. 1127 | $._table_cell_end, 1128 | // Table captions have significant whitespace but contain only inline. 1129 | $._table_caption_begin, 1130 | $._table_caption_end, 1131 | // The `{` that begins a block attribute (scans the entire attribute to avoid 1132 | // excessive branching). 1133 | $._block_attribute_begin, 1134 | // A comment can be closed by a `%` or implicitly when the attribute closes at `}`. 1135 | $._comment_end_marker, 1136 | $._comment_close, 1137 | 1138 | // Inline elements. 1139 | 1140 | // Zero-width check if a standalone comment is valid. 1141 | $._inline_comment_begin, 1142 | 1143 | // Verbatim is handled externally to match a varying number of `, 1144 | // and to close open verbatim when a paragraph ends with a blankline. 1145 | $._verbatim_begin, 1146 | $._verbatim_end, 1147 | $._verbatim_content, 1148 | 1149 | // The different spans. 1150 | // Begin is marked by a zero-width token and the end is the actual 1151 | // ending token (such as `_}`). 1152 | $._emphasis_mark_begin, 1153 | $.emphasis_end, 1154 | $._strong_mark_begin, 1155 | $.strong_end, 1156 | $._superscript_mark_begin, 1157 | $.superscript_end, 1158 | $._subscript_mark_begin, 1159 | $.subscript_end, 1160 | $._highlighted_mark_begin, 1161 | $.highlighted_end, 1162 | $._insert_mark_begin, 1163 | $.insert_end, 1164 | $._delete_mark_begin, 1165 | $.delete_end, 1166 | // Spans where the external scanner uses a zero-width begin marker 1167 | // and parser the end token as ), } or ]. 1168 | $._parens_span_mark_begin, 1169 | $._parens_span_end, 1170 | $._curly_bracket_span_mark_begin, 1171 | $._curly_bracket_span_end, 1172 | $._square_bracket_span_mark_begin, 1173 | $._square_bracket_span_end, 1174 | 1175 | // A signaling token that's used to signal that a fallback token should be scanned, 1176 | // and should never be output. 1177 | // It's used to notify the external scanner if we're in the fallback branch or in 1178 | // if we're scanning a span. This so the scanner knows if the current element should 1179 | // be stored on the stack or not. 1180 | $._in_fallback, 1181 | 1182 | // Never valid and is only used to signal an internal scanner error. 1183 | $._error, 1184 | ], 1185 | }); 1186 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-djot", 3 | "version": "1.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "tree-sitter-djot", 9 | "version": "1.1.0", 10 | "hasInstallScript": true, 11 | "license": "ISC", 12 | "dependencies": { 13 | "node-addon-api": "^7.1.0", 14 | "node-gyp-build": "^4.8.0" 15 | }, 16 | "devDependencies": { 17 | "prebuildify": "^6.0.0", 18 | "tree-sitter-cli": "^0.22.1" 19 | }, 20 | "peerDependencies": { 21 | "tree-sitter": "^0.21.0" 22 | }, 23 | "peerDependenciesMeta": { 24 | "tree_sitter": { 25 | "optional": true 26 | } 27 | } 28 | }, 29 | "node_modules/base64-js": { 30 | "version": "1.5.1", 31 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 32 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 33 | "dev": true, 34 | "funding": [ 35 | { 36 | "type": "github", 37 | "url": "https://github.com/sponsors/feross" 38 | }, 39 | { 40 | "type": "patreon", 41 | "url": "https://www.patreon.com/feross" 42 | }, 43 | { 44 | "type": "consulting", 45 | "url": "https://feross.org/support" 46 | } 47 | ] 48 | }, 49 | "node_modules/bl": { 50 | "version": "4.1.0", 51 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", 52 | "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", 53 | "dev": true, 54 | "dependencies": { 55 | "buffer": "^5.5.0", 56 | "inherits": "^2.0.4", 57 | "readable-stream": "^3.4.0" 58 | } 59 | }, 60 | "node_modules/buffer": { 61 | "version": "5.7.1", 62 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 63 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 64 | "dev": true, 65 | "funding": [ 66 | { 67 | "type": "github", 68 | "url": "https://github.com/sponsors/feross" 69 | }, 70 | { 71 | "type": "patreon", 72 | "url": "https://www.patreon.com/feross" 73 | }, 74 | { 75 | "type": "consulting", 76 | "url": "https://feross.org/support" 77 | } 78 | ], 79 | "dependencies": { 80 | "base64-js": "^1.3.1", 81 | "ieee754": "^1.1.13" 82 | } 83 | }, 84 | "node_modules/chownr": { 85 | "version": "1.1.4", 86 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 87 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", 88 | "dev": true 89 | }, 90 | "node_modules/end-of-stream": { 91 | "version": "1.4.4", 92 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 93 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 94 | "dev": true, 95 | "dependencies": { 96 | "once": "^1.4.0" 97 | } 98 | }, 99 | "node_modules/fs-constants": { 100 | "version": "1.0.0", 101 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 102 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", 103 | "dev": true 104 | }, 105 | "node_modules/ieee754": { 106 | "version": "1.2.1", 107 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 108 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 109 | "dev": true, 110 | "funding": [ 111 | { 112 | "type": "github", 113 | "url": "https://github.com/sponsors/feross" 114 | }, 115 | { 116 | "type": "patreon", 117 | "url": "https://www.patreon.com/feross" 118 | }, 119 | { 120 | "type": "consulting", 121 | "url": "https://feross.org/support" 122 | } 123 | ] 124 | }, 125 | "node_modules/inherits": { 126 | "version": "2.0.4", 127 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 128 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 129 | "dev": true 130 | }, 131 | "node_modules/minimist": { 132 | "version": "1.2.8", 133 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 134 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 135 | "dev": true, 136 | "funding": { 137 | "url": "https://github.com/sponsors/ljharb" 138 | } 139 | }, 140 | "node_modules/mkdirp-classic": { 141 | "version": "0.5.3", 142 | "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", 143 | "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", 144 | "dev": true 145 | }, 146 | "node_modules/node-abi": { 147 | "version": "3.65.0", 148 | "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.65.0.tgz", 149 | "integrity": "sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==", 150 | "dev": true, 151 | "dependencies": { 152 | "semver": "^7.3.5" 153 | }, 154 | "engines": { 155 | "node": ">=10" 156 | } 157 | }, 158 | "node_modules/node-addon-api": { 159 | "version": "7.1.1", 160 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", 161 | "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==" 162 | }, 163 | "node_modules/node-gyp-build": { 164 | "version": "4.8.1", 165 | "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", 166 | "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", 167 | "bin": { 168 | "node-gyp-build": "bin.js", 169 | "node-gyp-build-optional": "optional.js", 170 | "node-gyp-build-test": "build-test.js" 171 | } 172 | }, 173 | "node_modules/npm-run-path": { 174 | "version": "3.1.0", 175 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", 176 | "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", 177 | "dev": true, 178 | "dependencies": { 179 | "path-key": "^3.0.0" 180 | }, 181 | "engines": { 182 | "node": ">=8" 183 | } 184 | }, 185 | "node_modules/once": { 186 | "version": "1.4.0", 187 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 188 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 189 | "dev": true, 190 | "dependencies": { 191 | "wrappy": "1" 192 | } 193 | }, 194 | "node_modules/path-key": { 195 | "version": "3.1.1", 196 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 197 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 198 | "dev": true, 199 | "engines": { 200 | "node": ">=8" 201 | } 202 | }, 203 | "node_modules/prebuildify": { 204 | "version": "6.0.1", 205 | "resolved": "https://registry.npmjs.org/prebuildify/-/prebuildify-6.0.1.tgz", 206 | "integrity": "sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==", 207 | "dev": true, 208 | "dependencies": { 209 | "minimist": "^1.2.5", 210 | "mkdirp-classic": "^0.5.3", 211 | "node-abi": "^3.3.0", 212 | "npm-run-path": "^3.1.0", 213 | "pump": "^3.0.0", 214 | "tar-fs": "^2.1.0" 215 | }, 216 | "bin": { 217 | "prebuildify": "bin.js" 218 | } 219 | }, 220 | "node_modules/pump": { 221 | "version": "3.0.0", 222 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 223 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 224 | "dev": true, 225 | "dependencies": { 226 | "end-of-stream": "^1.1.0", 227 | "once": "^1.3.1" 228 | } 229 | }, 230 | "node_modules/readable-stream": { 231 | "version": "3.6.2", 232 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 233 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 234 | "dev": true, 235 | "dependencies": { 236 | "inherits": "^2.0.3", 237 | "string_decoder": "^1.1.1", 238 | "util-deprecate": "^1.0.1" 239 | }, 240 | "engines": { 241 | "node": ">= 6" 242 | } 243 | }, 244 | "node_modules/safe-buffer": { 245 | "version": "5.2.1", 246 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 247 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 248 | "dev": true, 249 | "funding": [ 250 | { 251 | "type": "github", 252 | "url": "https://github.com/sponsors/feross" 253 | }, 254 | { 255 | "type": "patreon", 256 | "url": "https://www.patreon.com/feross" 257 | }, 258 | { 259 | "type": "consulting", 260 | "url": "https://feross.org/support" 261 | } 262 | ] 263 | }, 264 | "node_modules/semver": { 265 | "version": "7.6.2", 266 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", 267 | "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", 268 | "dev": true, 269 | "bin": { 270 | "semver": "bin/semver.js" 271 | }, 272 | "engines": { 273 | "node": ">=10" 274 | } 275 | }, 276 | "node_modules/string_decoder": { 277 | "version": "1.3.0", 278 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 279 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 280 | "dev": true, 281 | "dependencies": { 282 | "safe-buffer": "~5.2.0" 283 | } 284 | }, 285 | "node_modules/tar-fs": { 286 | "version": "2.1.1", 287 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", 288 | "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", 289 | "dev": true, 290 | "dependencies": { 291 | "chownr": "^1.1.1", 292 | "mkdirp-classic": "^0.5.2", 293 | "pump": "^3.0.0", 294 | "tar-stream": "^2.1.4" 295 | } 296 | }, 297 | "node_modules/tar-stream": { 298 | "version": "2.2.0", 299 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", 300 | "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", 301 | "dev": true, 302 | "dependencies": { 303 | "bl": "^4.0.3", 304 | "end-of-stream": "^1.4.1", 305 | "fs-constants": "^1.0.0", 306 | "inherits": "^2.0.3", 307 | "readable-stream": "^3.1.1" 308 | }, 309 | "engines": { 310 | "node": ">=6" 311 | } 312 | }, 313 | "node_modules/tree-sitter": { 314 | "version": "0.21.1", 315 | "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.21.1.tgz", 316 | "integrity": "sha512-7dxoA6kYvtgWw80265MyqJlkRl4yawIjO7S5MigytjELkX43fV2WsAXzsNfO7sBpPPCF5Gp0+XzHk0DwLCq3xQ==", 317 | "hasInstallScript": true, 318 | "peer": true, 319 | "dependencies": { 320 | "node-addon-api": "^8.0.0", 321 | "node-gyp-build": "^4.8.0" 322 | } 323 | }, 324 | "node_modules/tree-sitter-cli": { 325 | "version": "0.22.6", 326 | "resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.22.6.tgz", 327 | "integrity": "sha512-s7mYOJXi8sIFkt/nLJSqlYZP96VmKTc3BAwIX0rrrlRxWjWuCwixFqwzxWZBQz4R8Hx01iP7z3cT3ih58BUmZQ==", 328 | "dev": true, 329 | "hasInstallScript": true, 330 | "bin": { 331 | "tree-sitter": "cli.js" 332 | } 333 | }, 334 | "node_modules/tree-sitter/node_modules/node-addon-api": { 335 | "version": "8.1.0", 336 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.1.0.tgz", 337 | "integrity": "sha512-yBY+qqWSv3dWKGODD6OGE6GnTX7Q2r+4+DfpqxHSHh8x0B4EKP9+wVGLS6U/AM1vxSNNmUEuIV5EGhYwPpfOwQ==", 338 | "peer": true, 339 | "engines": { 340 | "node": "^18 || ^20 || >= 21" 341 | } 342 | }, 343 | "node_modules/util-deprecate": { 344 | "version": "1.0.2", 345 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 346 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 347 | "dev": true 348 | }, 349 | "node_modules/wrappy": { 350 | "version": "1.0.2", 351 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 352 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 353 | "dev": true 354 | } 355 | } 356 | } 357 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-djot", 3 | "version": "2.0.0", 4 | "description": "", 5 | "main": "bindings/node", 6 | "types": "bindings/node", 7 | "scripts": { 8 | "generate": "tree-sitter generate", 9 | "test": "tree-sitter test", 10 | "check-formatted": "prettier --check grammar.js", 11 | "build-wasm": "tree-sitter build-wasm", 12 | "install": "node-gyp-build", 13 | "prebuildify": "prebuildify --napi --strip" 14 | }, 15 | "author": "", 16 | "license": "MIT", 17 | "dependencies": { 18 | "node-addon-api": "^7.1.0", 19 | "node-gyp-build": "^4.8.0" 20 | }, 21 | "peerDependencies": { 22 | "tree-sitter": "^0.21.0" 23 | }, 24 | "peerDependenciesMeta": { 25 | "tree_sitter": { 26 | "optional": true 27 | } 28 | }, 29 | "devDependencies": { 30 | "tree-sitter-cli": "^0.22.1", 31 | "prebuildify": "^6.0.0" 32 | }, 33 | "files": [ 34 | "grammar.js", 35 | "binding.gyp", 36 | "prebuilds/**", 37 | "bindings/node/*", 38 | "queries/*", 39 | "src/**" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=42", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "tree-sitter-djot" 7 | description = "Djot grammar for tree-sitter" 8 | version = "2.0.0" 9 | keywords = ["incremental", "parsing", "tree-sitter", "djot"] 10 | classifiers = [ 11 | "Intended Audience :: Developers", 12 | "License :: OSI Approved :: MIT License", 13 | "Topic :: Software Development :: Compilers", 14 | "Topic :: Text Processing :: Linguistic", 15 | "Typing :: Typed", 16 | ] 17 | requires-python = ">=3.8" 18 | license.text = "MIT" 19 | readme = "README.md" 20 | 21 | [project.urls] 22 | Homepage = "https://github.com/tree-sitter/tree-sitter-djot" 23 | 24 | [project.optional-dependencies] 25 | core = ["tree-sitter~=0.21"] 26 | 27 | [tool.cibuildwheel] 28 | build = "cp38-*" 29 | build-frontend = "build" 30 | -------------------------------------------------------------------------------- /queries/context.scm: -------------------------------------------------------------------------------- 1 | ; Used by nvim-treesitter-context 2 | (section) @context 3 | -------------------------------------------------------------------------------- /queries/folds.scm: -------------------------------------------------------------------------------- 1 | [ 2 | (section) 3 | (code_block) 4 | (raw_block) 5 | (list) 6 | (div) 7 | ] @fold 8 | -------------------------------------------------------------------------------- /queries/highlights.scm: -------------------------------------------------------------------------------- 1 | (heading) @markup.heading 2 | 3 | ((heading 4 | (marker) @_heading.marker) @markup.heading.1 5 | (#eq? @_heading.marker "# ")) 6 | 7 | ((heading 8 | (marker) @_heading.marker) @markup.heading.2 9 | (#eq? @_heading.marker "## ")) 10 | 11 | ((heading 12 | (marker) @_heading.marker) @markup.heading.3 13 | (#eq? @_heading.marker "### ")) 14 | 15 | ((heading 16 | (marker) @_heading.marker) @markup.heading.4 17 | (#eq? @_heading.marker "##### ")) 18 | 19 | ((heading 20 | (marker) @_heading.marker) @markup.heading.5 21 | (#eq? @_heading.marker "###### ")) 22 | 23 | ((heading 24 | (marker) @_heading.marker) @markup.heading.6 25 | (#eq? @_heading.marker "####### ")) 26 | 27 | (thematic_break) @string.special 28 | 29 | [ 30 | (div_marker_begin) 31 | (div_marker_end) 32 | ] @punctuation.delimiter 33 | 34 | ([ 35 | (code_block) 36 | (raw_block) 37 | (frontmatter) 38 | ] @markup.raw.block 39 | (#set! priority 90)) 40 | 41 | ; Remove @markup.raw for code with a language spec 42 | (code_block 43 | . 44 | (code_block_marker_begin) 45 | (language) 46 | (code) @none 47 | (#set! priority 90)) 48 | 49 | [ 50 | (code_block_marker_begin) 51 | (code_block_marker_end) 52 | (raw_block_marker_begin) 53 | (raw_block_marker_end) 54 | ] @punctuation.delimiter 55 | 56 | (language) @attribute 57 | 58 | (inline_attribute 59 | _ @conceal 60 | (#set! conceal "")) 61 | 62 | ((language_marker) @punctuation.delimiter 63 | (#set! conceal "")) 64 | 65 | (block_quote) @markup.quote 66 | 67 | (block_quote_marker) @punctuation.special 68 | 69 | (table_header) @markup.heading 70 | 71 | (table_header 72 | "|" @punctuation.special) 73 | 74 | (table_row 75 | "|" @punctuation.special) 76 | 77 | (table_separator) @punctuation.special 78 | 79 | (table_caption 80 | (marker) @punctuation.special) 81 | 82 | (table_caption) @markup.italic 83 | 84 | [ 85 | (list_marker_dash) 86 | (list_marker_plus) 87 | (list_marker_star) 88 | (list_marker_definition) 89 | (list_marker_decimal_period) 90 | (list_marker_decimal_paren) 91 | (list_marker_decimal_parens) 92 | (list_marker_lower_alpha_period) 93 | (list_marker_lower_alpha_paren) 94 | (list_marker_lower_alpha_parens) 95 | (list_marker_upper_alpha_period) 96 | (list_marker_upper_alpha_paren) 97 | (list_marker_upper_alpha_parens) 98 | (list_marker_lower_roman_period) 99 | (list_marker_lower_roman_paren) 100 | (list_marker_lower_roman_parens) 101 | (list_marker_upper_roman_period) 102 | (list_marker_upper_roman_paren) 103 | (list_marker_upper_roman_parens) 104 | ] @markup.list 105 | 106 | (list_marker_task 107 | (unchecked)) @markup.list.unchecked 108 | 109 | (list_marker_task 110 | (checked)) @markup.list.checked 111 | 112 | ; Colorize `x` in `[x]` 113 | ((checked) @constant.builtin 114 | (#offset! @constant.builtin 0 1 0 -1)) 115 | 116 | [ 117 | (ellipsis) 118 | (en_dash) 119 | (em_dash) 120 | (quotation_marks) 121 | ] @string.special 122 | 123 | (list_item 124 | (term) @type.definition) 125 | 126 | ; Conceal { and } but leave " and ' 127 | ((quotation_marks) @string.special 128 | (#any-of? @string.special "\"}" "'}") 129 | (#offset! @string.special 0 1 0 0) 130 | (#set! conceal "")) 131 | 132 | ((quotation_marks) @string.special 133 | (#any-of? @string.special "\\\"" "\\'" "{'" "{\"") 134 | (#offset! @string.special 0 0 0 -1) 135 | (#set! conceal "")) 136 | 137 | [ 138 | (hard_line_break) 139 | (backslash_escape) 140 | ] @string.escape 141 | 142 | ; Only conceal \ but leave escaped character. 143 | ((backslash_escape) @string.escape 144 | (#offset! @string.escape 0 0 0 -1) 145 | (#set! conceal "")) 146 | 147 | (frontmatter_marker) @punctuation.delimiter 148 | 149 | (emphasis) @markup.italic 150 | 151 | (strong) @markup.strong 152 | 153 | (symbol) @string.special.symbol 154 | 155 | (insert) @markup.underline 156 | 157 | (delete) @markup.strikethrough 158 | 159 | [ 160 | (highlighted) 161 | (superscript) 162 | (subscript) 163 | ] @string.special 164 | 165 | ([ 166 | (emphasis_begin) 167 | (emphasis_end) 168 | (strong_begin) 169 | (strong_end) 170 | (superscript_begin) 171 | (superscript_end) 172 | (subscript_begin) 173 | (subscript_end) 174 | (highlighted_begin) 175 | (highlighted_end) 176 | (insert_begin) 177 | (insert_end) 178 | (delete_begin) 179 | (delete_end) 180 | (verbatim_marker_begin) 181 | (verbatim_marker_end) 182 | (math_marker) 183 | (math_marker_begin) 184 | (math_marker_end) 185 | (raw_inline_attribute) 186 | (raw_inline_marker_begin) 187 | (raw_inline_marker_end) 188 | ] @punctuation.delimiter 189 | (#set! conceal "")) 190 | 191 | ((math) @markup.math 192 | (#set! priority 90)) 193 | 194 | (verbatim) @markup.raw 195 | 196 | ((raw_inline) @markup.raw 197 | (#set! priority 90)) 198 | 199 | [ 200 | (comment) 201 | (inline_comment) 202 | ] @comment 203 | 204 | (span 205 | [ 206 | "[" 207 | "]" 208 | ] @punctuation.bracket) 209 | 210 | (inline_attribute 211 | [ 212 | "{" 213 | "}" 214 | ] @punctuation.bracket) 215 | 216 | (block_attribute 217 | [ 218 | "{" 219 | "}" 220 | ] @punctuation.bracket) 221 | 222 | [ 223 | (class) 224 | (class_name) 225 | ] @type 226 | 227 | (identifier) @tag 228 | 229 | (key_value 230 | "=" @operator) 231 | 232 | (key_value 233 | (key) @property) 234 | 235 | (key_value 236 | (value) @string) 237 | 238 | (link_text 239 | [ 240 | "[" 241 | "]" 242 | ] @punctuation.bracket 243 | (#set! conceal "")) 244 | 245 | (autolink 246 | [ 247 | "<" 248 | ">" 249 | ] @punctuation.bracket 250 | (#set! conceal "")) 251 | 252 | (inline_link 253 | (inline_link_destination) @markup.link.url 254 | (#set! conceal "")) 255 | 256 | (link_reference_definition 257 | ":" @punctuation.special) 258 | 259 | (full_reference_link 260 | (link_text) @markup.link) 261 | 262 | (full_reference_link 263 | (link_label) @markup.link.label 264 | (#set! conceal "")) 265 | 266 | (collapsed_reference_link 267 | "[]" @punctuation.bracket 268 | (#set! conceal "")) 269 | 270 | (full_reference_link 271 | [ 272 | "[" 273 | "]" 274 | ] @punctuation.bracket 275 | (#set! conceal "")) 276 | 277 | (collapsed_reference_link 278 | (link_text) @markup.link) 279 | 280 | (collapsed_reference_link 281 | (link_text) @markup.link.label) 282 | 283 | (inline_link 284 | (link_text) @markup.link) 285 | 286 | (full_reference_image 287 | (link_label) @markup.link.label) 288 | 289 | (full_reference_image 290 | [ 291 | "[" 292 | "]" 293 | ] @punctuation.bracket) 294 | 295 | (collapsed_reference_image 296 | "[]" @punctuation.bracket) 297 | 298 | (image_description 299 | [ 300 | "![" 301 | "]" 302 | ] @punctuation.bracket) 303 | 304 | (image_description) @markup.italic 305 | 306 | (link_reference_definition 307 | [ 308 | "[" 309 | "]" 310 | ] @punctuation.bracket) 311 | 312 | (link_reference_definition 313 | (link_label) @markup.link.label) 314 | 315 | (inline_link_destination 316 | [ 317 | "(" 318 | ")" 319 | ] @punctuation.bracket) 320 | 321 | [ 322 | (autolink) 323 | (inline_link_destination) 324 | (link_destination) 325 | (link_reference_definition) 326 | ] @markup.link.url 327 | 328 | (footnote 329 | (reference_label) @markup.link.label) 330 | 331 | (footnote_reference 332 | (reference_label) @markup.link.label) 333 | 334 | [ 335 | (footnote_marker_begin) 336 | (footnote_marker_end) 337 | ] @punctuation.bracket 338 | 339 | (todo) @comment.todo 340 | 341 | (note) @comment.note 342 | 343 | (fixme) @comment.error 344 | 345 | [ 346 | (paragraph) 347 | (comment) 348 | (table_cell) 349 | ] @spell 350 | 351 | [ 352 | (autolink) 353 | (inline_link_destination) 354 | (link_destination) 355 | (code_block) 356 | (raw_block) 357 | (math) 358 | (raw_inline) 359 | (verbatim) 360 | (reference_label) 361 | (class) 362 | (class_name) 363 | (identifier) 364 | (key_value) 365 | (frontmatter) 366 | ] @nospell 367 | 368 | (full_reference_link 369 | (link_label) @nospell) 370 | 371 | (full_reference_image 372 | (link_label) @nospell) 373 | -------------------------------------------------------------------------------- /queries/indents.scm: -------------------------------------------------------------------------------- 1 | ; The intention here is to rely on Neovims `autoindent` setting. 2 | ; This allows us to not indent after just a single list item 3 | ; so we can create narrow lists quickly, but indent blocks inside list items 4 | ; to the previous paragraph. 5 | (list_item_content) @indent.auto 6 | 7 | (footnote_content) @indent.align 8 | 9 | ((table_caption) @indent.begin 10 | (#set! indent.immediate 1)) 11 | -------------------------------------------------------------------------------- /queries/injections.scm: -------------------------------------------------------------------------------- 1 | ((comment) @injection.content 2 | (#set! injection.language "comment")) 3 | 4 | (math 5 | (content) @injection.content 6 | (#set! injection.language "latex")) 7 | 8 | (code_block 9 | (language) @injection.language 10 | (code) @injection.content) 11 | 12 | (raw_block 13 | (raw_block_info 14 | (language) @injection.language) 15 | (content) @injection.content) 16 | 17 | (raw_inline 18 | (content) @injection.content 19 | (raw_inline_attribute 20 | (language) @injection.language)) 21 | 22 | (frontmatter 23 | (language) @injection.language 24 | (frontmatter_content) @injection.content) 25 | -------------------------------------------------------------------------------- /queries/locals.scm: -------------------------------------------------------------------------------- 1 | (link_reference_definition 2 | (link_label) @local.definition) 3 | 4 | (footnote 5 | (reference_label) @local.definition) 6 | 7 | (collapsed_reference_link 8 | (link_text) @local.reference) 9 | 10 | (full_reference_link 11 | (link_label) @local.reference) 12 | 13 | (full_reference_image 14 | (link_label) @local.reference) 15 | 16 | (footnote_reference 17 | (reference_label) @local.reference) 18 | -------------------------------------------------------------------------------- /queries/textobjects.scm: -------------------------------------------------------------------------------- 1 | ; The markup doesn't contain elements like "classes" or "functions". 2 | ; These are used to provide a reasonable treesitter based jump and 3 | ; select experience. 4 | ; For instance "change inner function" allows us to replace an 5 | ; entire block quote, leaving the ">" prefix. 6 | ; The choices are a bit subjective though. 7 | ; Classes, the highest level 8 | (thematic_break) @class.outer 9 | 10 | (section 11 | (section_content) @class.inner 12 | (#offset! @class.inner 0 0 -1 0)) @class.outer 13 | 14 | ; Functions, the next level 15 | (heading 16 | (content) @function.inner) @function.outer 17 | 18 | (div 19 | (content) @function.inner) @function.outer 20 | 21 | (block_quote 22 | (content) @function.inner) @function.outer 23 | 24 | (code_block 25 | (code) @function.inner) @function.outer 26 | 27 | (raw_block 28 | (content) @function.inner) @function.outer 29 | 30 | ; Inner selects current list item, outer selects whole list 31 | (list 32 | (_) @function.inner) @function.outer 33 | 34 | ; Inner selects row, outer selects whole table 35 | (table 36 | (_) @function.inner) @function.outer 37 | 38 | (footnote 39 | (footnote_content) @function.inner) @function.outer 40 | 41 | ; Blocks, included inside functions 42 | (list_item 43 | (list_item_content) @block.inner) @block.outer 44 | 45 | (table_row) @block.outer 46 | 47 | (table_separator) @block.outer 48 | 49 | [ 50 | (table_cell_alignment) 51 | (table_cell) 52 | ] @block.inner 53 | 54 | ; Attributes, extra things attached to elements 55 | (block_attribute 56 | (args) @attribute.inner) @attribute.outer 57 | 58 | (inline_attribute 59 | (args) @attribute.inner) @attribute.outer 60 | 61 | (table_caption 62 | (content) @attribute.inner) @attribute.outer 63 | 64 | (emphasis 65 | (content) @attribute.inner) @attribute.outer 66 | 67 | (strong 68 | (content) @attribute.inner) @attribute.outer 69 | 70 | (highlighted 71 | (content) @attribute.inner) @attribute.outer 72 | 73 | (insert 74 | (content) @attribute.inner) @attribute.outer 75 | 76 | (delete 77 | (content) @attribute.inner) @attribute.outer 78 | 79 | (symbol) @attribute.outer 80 | 81 | (superscript 82 | (content) @attribute.inner) @attribute.outer 83 | 84 | (subscript 85 | (content) @attribute.inner) @attribute.outer 86 | 87 | (verbatim 88 | (content) @attribute.inner) @attribute.outer 89 | 90 | ; Parameters, inside a description of a thing 91 | [ 92 | (class_name) 93 | (class) 94 | (identifier) 95 | (key_value) 96 | (language) 97 | ] @parameter.outer 98 | 99 | [ 100 | (key) 101 | (value) 102 | ] @parameter.inner 103 | 104 | ; Statements, extra outer definitions 105 | (link_reference_definition 106 | (_) @statement.inner) @statement.outer 107 | 108 | ; Footnote is a function, can't reuse that here. 109 | ; Use @statement.outer as a jump-to point. 110 | (footnote 111 | (reference_label) @statement.inner) 112 | 113 | (footnote 114 | (footnote_marker_begin) @statement.outer) 115 | 116 | ; Comments 117 | (comment 118 | (content) @comment.inner) @comment.outer 119 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from os.path import isdir, join 2 | from platform import system 3 | 4 | from setuptools import Extension, find_packages, setup 5 | from setuptools.command.build import build 6 | from wheel.bdist_wheel import bdist_wheel 7 | 8 | 9 | class Build(build): 10 | def run(self): 11 | if isdir("queries"): 12 | dest = join(self.build_lib, "tree_sitter_djot", "queries") 13 | self.copy_tree("queries", dest) 14 | super().run() 15 | 16 | 17 | class BdistWheel(bdist_wheel): 18 | def get_tag(self): 19 | python, abi, platform = super().get_tag() 20 | if python.startswith("cp"): 21 | python, abi = "cp38", "abi3" 22 | return python, abi, platform 23 | 24 | 25 | setup( 26 | packages=find_packages("bindings/python"), 27 | package_dir={"": "bindings/python"}, 28 | package_data={ 29 | "tree_sitter_djot": ["*.pyi", "py.typed"], 30 | "tree_sitter_djot.queries": ["*.scm"], 31 | }, 32 | ext_package="tree_sitter_djot", 33 | ext_modules=[ 34 | Extension( 35 | name="_binding", 36 | sources=[ 37 | "bindings/python/tree_sitter_djot/binding.c", 38 | "src/parser.c", 39 | # NOTE: if your language uses an external scanner, add it here. 40 | ], 41 | extra_compile_args=( 42 | ["-std=c11"] if system() != 'Windows' else [] 43 | ), 44 | define_macros=[ 45 | ("Py_LIMITED_API", "0x03080000"), 46 | ("PY_SSIZE_T_CLEAN", None) 47 | ], 48 | include_dirs=["src"], 49 | py_limited_api=True, 50 | ) 51 | ], 52 | cmdclass={ 53 | "build": Build, 54 | "bdist_wheel": BdistWheel 55 | }, 56 | zip_safe=False 57 | ) 58 | -------------------------------------------------------------------------------- /src/node-types.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "args", 4 | "named": true, 5 | "fields": {}, 6 | "children": { 7 | "multiple": true, 8 | "required": false, 9 | "types": [ 10 | { 11 | "type": "class", 12 | "named": true 13 | }, 14 | { 15 | "type": "comment", 16 | "named": true 17 | }, 18 | { 19 | "type": "identifier", 20 | "named": true 21 | }, 22 | { 23 | "type": "key_value", 24 | "named": true 25 | } 26 | ] 27 | } 28 | }, 29 | { 30 | "type": "autolink", 31 | "named": true, 32 | "fields": {} 33 | }, 34 | { 35 | "type": "block_attribute", 36 | "named": true, 37 | "fields": { 38 | "args": { 39 | "multiple": false, 40 | "required": false, 41 | "types": [ 42 | { 43 | "type": "args", 44 | "named": true 45 | } 46 | ] 47 | } 48 | } 49 | }, 50 | { 51 | "type": "block_quote", 52 | "named": true, 53 | "fields": { 54 | "content": { 55 | "multiple": false, 56 | "required": true, 57 | "types": [ 58 | { 59 | "type": "content", 60 | "named": true 61 | } 62 | ] 63 | } 64 | }, 65 | "children": { 66 | "multiple": false, 67 | "required": true, 68 | "types": [ 69 | { 70 | "type": "block_quote_marker", 71 | "named": true 72 | } 73 | ] 74 | } 75 | }, 76 | { 77 | "type": "checked", 78 | "named": true, 79 | "fields": {} 80 | }, 81 | { 82 | "type": "class", 83 | "named": false, 84 | "fields": {} 85 | }, 86 | { 87 | "type": "class_name", 88 | "named": true, 89 | "fields": {} 90 | }, 91 | { 92 | "type": "code", 93 | "named": true, 94 | "fields": {}, 95 | "children": { 96 | "multiple": true, 97 | "required": false, 98 | "types": [ 99 | { 100 | "type": "block_quote_marker", 101 | "named": true 102 | } 103 | ] 104 | } 105 | }, 106 | { 107 | "type": "code_block", 108 | "named": true, 109 | "fields": { 110 | "code": { 111 | "multiple": false, 112 | "required": false, 113 | "types": [ 114 | { 115 | "type": "code", 116 | "named": true 117 | } 118 | ] 119 | }, 120 | "language": { 121 | "multiple": false, 122 | "required": false, 123 | "types": [ 124 | { 125 | "type": "language", 126 | "named": true 127 | } 128 | ] 129 | } 130 | }, 131 | "children": { 132 | "multiple": true, 133 | "required": true, 134 | "types": [ 135 | { 136 | "type": "code_block_marker_begin", 137 | "named": true 138 | }, 139 | { 140 | "type": "code_block_marker_end", 141 | "named": true 142 | } 143 | ] 144 | } 145 | }, 146 | { 147 | "type": "collapsed_reference_image", 148 | "named": true, 149 | "fields": { 150 | "description": { 151 | "multiple": false, 152 | "required": true, 153 | "types": [ 154 | { 155 | "type": "image_description", 156 | "named": true 157 | } 158 | ] 159 | } 160 | } 161 | }, 162 | { 163 | "type": "collapsed_reference_link", 164 | "named": true, 165 | "fields": { 166 | "text": { 167 | "multiple": false, 168 | "required": true, 169 | "types": [ 170 | { 171 | "type": "link_text", 172 | "named": true 173 | } 174 | ] 175 | } 176 | } 177 | }, 178 | { 179 | "type": "comment", 180 | "named": true, 181 | "fields": { 182 | "content": { 183 | "multiple": false, 184 | "required": false, 185 | "types": [ 186 | { 187 | "type": "content", 188 | "named": true 189 | } 190 | ] 191 | } 192 | } 193 | }, 194 | { 195 | "type": "content", 196 | "named": true, 197 | "fields": { 198 | "attribute": { 199 | "multiple": true, 200 | "required": false, 201 | "types": [ 202 | { 203 | "type": "inline_attribute", 204 | "named": true 205 | } 206 | ] 207 | } 208 | }, 209 | "children": { 210 | "multiple": true, 211 | "required": false, 212 | "types": [ 213 | { 214 | "type": "autolink", 215 | "named": true 216 | }, 217 | { 218 | "type": "backslash_escape", 219 | "named": true 220 | }, 221 | { 222 | "type": "block_attribute", 223 | "named": true 224 | }, 225 | { 226 | "type": "block_quote", 227 | "named": true 228 | }, 229 | { 230 | "type": "block_quote_marker", 231 | "named": true 232 | }, 233 | { 234 | "type": "code_block", 235 | "named": true 236 | }, 237 | { 238 | "type": "collapsed_reference_image", 239 | "named": true 240 | }, 241 | { 242 | "type": "collapsed_reference_link", 243 | "named": true 244 | }, 245 | { 246 | "type": "delete", 247 | "named": true 248 | }, 249 | { 250 | "type": "div", 251 | "named": true 252 | }, 253 | { 254 | "type": "ellipsis", 255 | "named": true 256 | }, 257 | { 258 | "type": "em_dash", 259 | "named": true 260 | }, 261 | { 262 | "type": "emphasis", 263 | "named": true 264 | }, 265 | { 266 | "type": "en_dash", 267 | "named": true 268 | }, 269 | { 270 | "type": "fixme", 271 | "named": true 272 | }, 273 | { 274 | "type": "footnote", 275 | "named": true 276 | }, 277 | { 278 | "type": "footnote_reference", 279 | "named": true 280 | }, 281 | { 282 | "type": "full_reference_image", 283 | "named": true 284 | }, 285 | { 286 | "type": "full_reference_link", 287 | "named": true 288 | }, 289 | { 290 | "type": "hard_line_break", 291 | "named": true 292 | }, 293 | { 294 | "type": "heading", 295 | "named": true 296 | }, 297 | { 298 | "type": "highlighted", 299 | "named": true 300 | }, 301 | { 302 | "type": "inline_comment", 303 | "named": true 304 | }, 305 | { 306 | "type": "inline_image", 307 | "named": true 308 | }, 309 | { 310 | "type": "inline_link", 311 | "named": true 312 | }, 313 | { 314 | "type": "insert", 315 | "named": true 316 | }, 317 | { 318 | "type": "link_reference_definition", 319 | "named": true 320 | }, 321 | { 322 | "type": "list", 323 | "named": true 324 | }, 325 | { 326 | "type": "marker", 327 | "named": true 328 | }, 329 | { 330 | "type": "math", 331 | "named": true 332 | }, 333 | { 334 | "type": "note", 335 | "named": true 336 | }, 337 | { 338 | "type": "paragraph", 339 | "named": true 340 | }, 341 | { 342 | "type": "quotation_marks", 343 | "named": true 344 | }, 345 | { 346 | "type": "raw_block", 347 | "named": true 348 | }, 349 | { 350 | "type": "raw_inline", 351 | "named": true 352 | }, 353 | { 354 | "type": "span", 355 | "named": true 356 | }, 357 | { 358 | "type": "strong", 359 | "named": true 360 | }, 361 | { 362 | "type": "subscript", 363 | "named": true 364 | }, 365 | { 366 | "type": "superscript", 367 | "named": true 368 | }, 369 | { 370 | "type": "symbol", 371 | "named": true 372 | }, 373 | { 374 | "type": "table", 375 | "named": true 376 | }, 377 | { 378 | "type": "thematic_break", 379 | "named": true 380 | }, 381 | { 382 | "type": "todo", 383 | "named": true 384 | }, 385 | { 386 | "type": "verbatim", 387 | "named": true 388 | } 389 | ] 390 | } 391 | }, 392 | { 393 | "type": "definition", 394 | "named": true, 395 | "fields": {}, 396 | "children": { 397 | "multiple": true, 398 | "required": false, 399 | "types": [ 400 | { 401 | "type": "block_attribute", 402 | "named": true 403 | }, 404 | { 405 | "type": "block_quote", 406 | "named": true 407 | }, 408 | { 409 | "type": "block_quote_marker", 410 | "named": true 411 | }, 412 | { 413 | "type": "code_block", 414 | "named": true 415 | }, 416 | { 417 | "type": "div", 418 | "named": true 419 | }, 420 | { 421 | "type": "footnote", 422 | "named": true 423 | }, 424 | { 425 | "type": "heading", 426 | "named": true 427 | }, 428 | { 429 | "type": "link_reference_definition", 430 | "named": true 431 | }, 432 | { 433 | "type": "list", 434 | "named": true 435 | }, 436 | { 437 | "type": "paragraph", 438 | "named": true 439 | }, 440 | { 441 | "type": "raw_block", 442 | "named": true 443 | }, 444 | { 445 | "type": "table", 446 | "named": true 447 | }, 448 | { 449 | "type": "thematic_break", 450 | "named": true 451 | } 452 | ] 453 | } 454 | }, 455 | { 456 | "type": "delete", 457 | "named": true, 458 | "fields": { 459 | "begin_marker": { 460 | "multiple": false, 461 | "required": true, 462 | "types": [ 463 | { 464 | "type": "delete_begin", 465 | "named": true 466 | } 467 | ] 468 | }, 469 | "content": { 470 | "multiple": false, 471 | "required": true, 472 | "types": [ 473 | { 474 | "type": "content", 475 | "named": true 476 | } 477 | ] 478 | }, 479 | "end_marker": { 480 | "multiple": false, 481 | "required": true, 482 | "types": [ 483 | { 484 | "type": "delete_end", 485 | "named": true 486 | } 487 | ] 488 | } 489 | } 490 | }, 491 | { 492 | "type": "delete_begin", 493 | "named": true, 494 | "fields": {} 495 | }, 496 | { 497 | "type": "div", 498 | "named": true, 499 | "fields": { 500 | "class": { 501 | "multiple": false, 502 | "required": false, 503 | "types": [ 504 | { 505 | "type": "class_name", 506 | "named": true 507 | } 508 | ] 509 | }, 510 | "content": { 511 | "multiple": false, 512 | "required": false, 513 | "types": [ 514 | { 515 | "type": "content", 516 | "named": true 517 | } 518 | ] 519 | } 520 | }, 521 | "children": { 522 | "multiple": true, 523 | "required": true, 524 | "types": [ 525 | { 526 | "type": "block_quote_marker", 527 | "named": true 528 | }, 529 | { 530 | "type": "div_marker_begin", 531 | "named": true 532 | }, 533 | { 534 | "type": "div_marker_end", 535 | "named": true 536 | } 537 | ] 538 | } 539 | }, 540 | { 541 | "type": "document", 542 | "named": true, 543 | "root": true, 544 | "fields": {}, 545 | "children": { 546 | "multiple": true, 547 | "required": false, 548 | "types": [ 549 | { 550 | "type": "block_attribute", 551 | "named": true 552 | }, 553 | { 554 | "type": "block_quote", 555 | "named": true 556 | }, 557 | { 558 | "type": "code_block", 559 | "named": true 560 | }, 561 | { 562 | "type": "div", 563 | "named": true 564 | }, 565 | { 566 | "type": "footnote", 567 | "named": true 568 | }, 569 | { 570 | "type": "frontmatter", 571 | "named": true 572 | }, 573 | { 574 | "type": "link_reference_definition", 575 | "named": true 576 | }, 577 | { 578 | "type": "list", 579 | "named": true 580 | }, 581 | { 582 | "type": "paragraph", 583 | "named": true 584 | }, 585 | { 586 | "type": "raw_block", 587 | "named": true 588 | }, 589 | { 590 | "type": "section", 591 | "named": true 592 | }, 593 | { 594 | "type": "table", 595 | "named": true 596 | }, 597 | { 598 | "type": "thematic_break", 599 | "named": true 600 | } 601 | ] 602 | } 603 | }, 604 | { 605 | "type": "emphasis", 606 | "named": true, 607 | "fields": { 608 | "begin_marker": { 609 | "multiple": false, 610 | "required": true, 611 | "types": [ 612 | { 613 | "type": "emphasis_begin", 614 | "named": true 615 | } 616 | ] 617 | }, 618 | "content": { 619 | "multiple": false, 620 | "required": true, 621 | "types": [ 622 | { 623 | "type": "content", 624 | "named": true 625 | } 626 | ] 627 | }, 628 | "end_marker": { 629 | "multiple": false, 630 | "required": true, 631 | "types": [ 632 | { 633 | "type": "emphasis_end", 634 | "named": true 635 | } 636 | ] 637 | } 638 | } 639 | }, 640 | { 641 | "type": "emphasis_begin", 642 | "named": true, 643 | "fields": {} 644 | }, 645 | { 646 | "type": "footnote", 647 | "named": true, 648 | "fields": { 649 | "content": { 650 | "multiple": false, 651 | "required": true, 652 | "types": [ 653 | { 654 | "type": "footnote_content", 655 | "named": true 656 | } 657 | ] 658 | }, 659 | "label": { 660 | "multiple": false, 661 | "required": true, 662 | "types": [ 663 | { 664 | "type": "reference_label", 665 | "named": true 666 | } 667 | ] 668 | } 669 | }, 670 | "children": { 671 | "multiple": true, 672 | "required": true, 673 | "types": [ 674 | { 675 | "type": "footnote_marker_begin", 676 | "named": true 677 | }, 678 | { 679 | "type": "footnote_marker_end", 680 | "named": true 681 | } 682 | ] 683 | } 684 | }, 685 | { 686 | "type": "footnote_content", 687 | "named": true, 688 | "fields": {}, 689 | "children": { 690 | "multiple": true, 691 | "required": false, 692 | "types": [ 693 | { 694 | "type": "block_attribute", 695 | "named": true 696 | }, 697 | { 698 | "type": "block_quote", 699 | "named": true 700 | }, 701 | { 702 | "type": "block_quote_marker", 703 | "named": true 704 | }, 705 | { 706 | "type": "code_block", 707 | "named": true 708 | }, 709 | { 710 | "type": "div", 711 | "named": true 712 | }, 713 | { 714 | "type": "footnote", 715 | "named": true 716 | }, 717 | { 718 | "type": "heading", 719 | "named": true 720 | }, 721 | { 722 | "type": "link_reference_definition", 723 | "named": true 724 | }, 725 | { 726 | "type": "list", 727 | "named": true 728 | }, 729 | { 730 | "type": "paragraph", 731 | "named": true 732 | }, 733 | { 734 | "type": "raw_block", 735 | "named": true 736 | }, 737 | { 738 | "type": "table", 739 | "named": true 740 | }, 741 | { 742 | "type": "thematic_break", 743 | "named": true 744 | } 745 | ] 746 | } 747 | }, 748 | { 749 | "type": "footnote_marker_begin", 750 | "named": true, 751 | "fields": {} 752 | }, 753 | { 754 | "type": "footnote_reference", 755 | "named": true, 756 | "fields": {}, 757 | "children": { 758 | "multiple": true, 759 | "required": true, 760 | "types": [ 761 | { 762 | "type": "footnote_marker_begin", 763 | "named": true 764 | }, 765 | { 766 | "type": "footnote_marker_end", 767 | "named": true 768 | }, 769 | { 770 | "type": "reference_label", 771 | "named": true 772 | } 773 | ] 774 | } 775 | }, 776 | { 777 | "type": "frontmatter", 778 | "named": true, 779 | "fields": { 780 | "content": { 781 | "multiple": false, 782 | "required": true, 783 | "types": [ 784 | { 785 | "type": "frontmatter_content", 786 | "named": true 787 | } 788 | ] 789 | }, 790 | "language": { 791 | "multiple": false, 792 | "required": false, 793 | "types": [ 794 | { 795 | "type": "language", 796 | "named": true 797 | } 798 | ] 799 | } 800 | }, 801 | "children": { 802 | "multiple": true, 803 | "required": true, 804 | "types": [ 805 | { 806 | "type": "frontmatter_marker", 807 | "named": true 808 | } 809 | ] 810 | } 811 | }, 812 | { 813 | "type": "frontmatter_content", 814 | "named": true, 815 | "fields": {} 816 | }, 817 | { 818 | "type": "full_reference_image", 819 | "named": true, 820 | "fields": { 821 | "description": { 822 | "multiple": false, 823 | "required": true, 824 | "types": [ 825 | { 826 | "type": "image_description", 827 | "named": true 828 | } 829 | ] 830 | }, 831 | "label": { 832 | "multiple": false, 833 | "required": true, 834 | "types": [ 835 | { 836 | "type": "link_label", 837 | "named": true 838 | } 839 | ] 840 | } 841 | } 842 | }, 843 | { 844 | "type": "full_reference_link", 845 | "named": true, 846 | "fields": { 847 | "label": { 848 | "multiple": false, 849 | "required": true, 850 | "types": [ 851 | { 852 | "type": "link_label", 853 | "named": true 854 | } 855 | ] 856 | }, 857 | "text": { 858 | "multiple": false, 859 | "required": true, 860 | "types": [ 861 | { 862 | "type": "link_text", 863 | "named": true 864 | } 865 | ] 866 | } 867 | } 868 | }, 869 | { 870 | "type": "heading", 871 | "named": true, 872 | "fields": { 873 | "content": { 874 | "multiple": false, 875 | "required": true, 876 | "types": [ 877 | { 878 | "type": "content", 879 | "named": true 880 | } 881 | ] 882 | }, 883 | "marker": { 884 | "multiple": false, 885 | "required": true, 886 | "types": [ 887 | { 888 | "type": "marker", 889 | "named": true 890 | } 891 | ] 892 | } 893 | } 894 | }, 895 | { 896 | "type": "highlighted", 897 | "named": true, 898 | "fields": { 899 | "begin_marker": { 900 | "multiple": false, 901 | "required": true, 902 | "types": [ 903 | { 904 | "type": "highlighted_begin", 905 | "named": true 906 | } 907 | ] 908 | }, 909 | "content": { 910 | "multiple": false, 911 | "required": true, 912 | "types": [ 913 | { 914 | "type": "content", 915 | "named": true 916 | } 917 | ] 918 | }, 919 | "end_marker": { 920 | "multiple": false, 921 | "required": true, 922 | "types": [ 923 | { 924 | "type": "highlighted_end", 925 | "named": true 926 | } 927 | ] 928 | } 929 | } 930 | }, 931 | { 932 | "type": "highlighted_begin", 933 | "named": true, 934 | "fields": {} 935 | }, 936 | { 937 | "type": "image_description", 938 | "named": true, 939 | "fields": { 940 | "attribute": { 941 | "multiple": true, 942 | "required": false, 943 | "types": [ 944 | { 945 | "type": "inline_attribute", 946 | "named": true 947 | } 948 | ] 949 | } 950 | }, 951 | "children": { 952 | "multiple": true, 953 | "required": false, 954 | "types": [ 955 | { 956 | "type": "autolink", 957 | "named": true 958 | }, 959 | { 960 | "type": "backslash_escape", 961 | "named": true 962 | }, 963 | { 964 | "type": "collapsed_reference_image", 965 | "named": true 966 | }, 967 | { 968 | "type": "collapsed_reference_link", 969 | "named": true 970 | }, 971 | { 972 | "type": "delete", 973 | "named": true 974 | }, 975 | { 976 | "type": "ellipsis", 977 | "named": true 978 | }, 979 | { 980 | "type": "em_dash", 981 | "named": true 982 | }, 983 | { 984 | "type": "emphasis", 985 | "named": true 986 | }, 987 | { 988 | "type": "en_dash", 989 | "named": true 990 | }, 991 | { 992 | "type": "fixme", 993 | "named": true 994 | }, 995 | { 996 | "type": "footnote_reference", 997 | "named": true 998 | }, 999 | { 1000 | "type": "full_reference_image", 1001 | "named": true 1002 | }, 1003 | { 1004 | "type": "full_reference_link", 1005 | "named": true 1006 | }, 1007 | { 1008 | "type": "hard_line_break", 1009 | "named": true 1010 | }, 1011 | { 1012 | "type": "highlighted", 1013 | "named": true 1014 | }, 1015 | { 1016 | "type": "inline_comment", 1017 | "named": true 1018 | }, 1019 | { 1020 | "type": "inline_image", 1021 | "named": true 1022 | }, 1023 | { 1024 | "type": "inline_link", 1025 | "named": true 1026 | }, 1027 | { 1028 | "type": "insert", 1029 | "named": true 1030 | }, 1031 | { 1032 | "type": "math", 1033 | "named": true 1034 | }, 1035 | { 1036 | "type": "note", 1037 | "named": true 1038 | }, 1039 | { 1040 | "type": "quotation_marks", 1041 | "named": true 1042 | }, 1043 | { 1044 | "type": "raw_inline", 1045 | "named": true 1046 | }, 1047 | { 1048 | "type": "span", 1049 | "named": true 1050 | }, 1051 | { 1052 | "type": "strong", 1053 | "named": true 1054 | }, 1055 | { 1056 | "type": "subscript", 1057 | "named": true 1058 | }, 1059 | { 1060 | "type": "superscript", 1061 | "named": true 1062 | }, 1063 | { 1064 | "type": "symbol", 1065 | "named": true 1066 | }, 1067 | { 1068 | "type": "todo", 1069 | "named": true 1070 | }, 1071 | { 1072 | "type": "verbatim", 1073 | "named": true 1074 | } 1075 | ] 1076 | } 1077 | }, 1078 | { 1079 | "type": "inline_attribute", 1080 | "named": true, 1081 | "fields": {}, 1082 | "children": { 1083 | "multiple": false, 1084 | "required": false, 1085 | "types": [ 1086 | { 1087 | "type": "args", 1088 | "named": true 1089 | } 1090 | ] 1091 | } 1092 | }, 1093 | { 1094 | "type": "inline_comment", 1095 | "named": true, 1096 | "fields": { 1097 | "content": { 1098 | "multiple": false, 1099 | "required": false, 1100 | "types": [ 1101 | { 1102 | "type": "content", 1103 | "named": true 1104 | } 1105 | ] 1106 | } 1107 | } 1108 | }, 1109 | { 1110 | "type": "inline_image", 1111 | "named": true, 1112 | "fields": { 1113 | "description": { 1114 | "multiple": false, 1115 | "required": true, 1116 | "types": [ 1117 | { 1118 | "type": "image_description", 1119 | "named": true 1120 | } 1121 | ] 1122 | }, 1123 | "destination": { 1124 | "multiple": false, 1125 | "required": true, 1126 | "types": [ 1127 | { 1128 | "type": "inline_link_destination", 1129 | "named": true 1130 | } 1131 | ] 1132 | } 1133 | } 1134 | }, 1135 | { 1136 | "type": "inline_link", 1137 | "named": true, 1138 | "fields": { 1139 | "destination": { 1140 | "multiple": false, 1141 | "required": true, 1142 | "types": [ 1143 | { 1144 | "type": "inline_link_destination", 1145 | "named": true 1146 | } 1147 | ] 1148 | }, 1149 | "text": { 1150 | "multiple": false, 1151 | "required": true, 1152 | "types": [ 1153 | { 1154 | "type": "link_text", 1155 | "named": true 1156 | } 1157 | ] 1158 | } 1159 | } 1160 | }, 1161 | { 1162 | "type": "inline_link_destination", 1163 | "named": true, 1164 | "fields": {} 1165 | }, 1166 | { 1167 | "type": "insert", 1168 | "named": true, 1169 | "fields": { 1170 | "begin_marker": { 1171 | "multiple": false, 1172 | "required": true, 1173 | "types": [ 1174 | { 1175 | "type": "insert_begin", 1176 | "named": true 1177 | } 1178 | ] 1179 | }, 1180 | "content": { 1181 | "multiple": false, 1182 | "required": true, 1183 | "types": [ 1184 | { 1185 | "type": "content", 1186 | "named": true 1187 | } 1188 | ] 1189 | }, 1190 | "end_marker": { 1191 | "multiple": false, 1192 | "required": true, 1193 | "types": [ 1194 | { 1195 | "type": "insert_end", 1196 | "named": true 1197 | } 1198 | ] 1199 | } 1200 | } 1201 | }, 1202 | { 1203 | "type": "insert_begin", 1204 | "named": true, 1205 | "fields": {} 1206 | }, 1207 | { 1208 | "type": "key", 1209 | "named": true, 1210 | "fields": {} 1211 | }, 1212 | { 1213 | "type": "key_value", 1214 | "named": true, 1215 | "fields": { 1216 | "key": { 1217 | "multiple": false, 1218 | "required": true, 1219 | "types": [ 1220 | { 1221 | "type": "key", 1222 | "named": true 1223 | } 1224 | ] 1225 | }, 1226 | "value": { 1227 | "multiple": false, 1228 | "required": true, 1229 | "types": [ 1230 | { 1231 | "type": "value", 1232 | "named": true 1233 | } 1234 | ] 1235 | } 1236 | } 1237 | }, 1238 | { 1239 | "type": "link_label", 1240 | "named": true, 1241 | "fields": { 1242 | "attribute": { 1243 | "multiple": true, 1244 | "required": false, 1245 | "types": [ 1246 | { 1247 | "type": "inline_attribute", 1248 | "named": true 1249 | } 1250 | ] 1251 | } 1252 | }, 1253 | "children": { 1254 | "multiple": true, 1255 | "required": false, 1256 | "types": [ 1257 | { 1258 | "type": "autolink", 1259 | "named": true 1260 | }, 1261 | { 1262 | "type": "backslash_escape", 1263 | "named": true 1264 | }, 1265 | { 1266 | "type": "collapsed_reference_image", 1267 | "named": true 1268 | }, 1269 | { 1270 | "type": "collapsed_reference_link", 1271 | "named": true 1272 | }, 1273 | { 1274 | "type": "delete", 1275 | "named": true 1276 | }, 1277 | { 1278 | "type": "ellipsis", 1279 | "named": true 1280 | }, 1281 | { 1282 | "type": "em_dash", 1283 | "named": true 1284 | }, 1285 | { 1286 | "type": "emphasis", 1287 | "named": true 1288 | }, 1289 | { 1290 | "type": "en_dash", 1291 | "named": true 1292 | }, 1293 | { 1294 | "type": "fixme", 1295 | "named": true 1296 | }, 1297 | { 1298 | "type": "footnote_reference", 1299 | "named": true 1300 | }, 1301 | { 1302 | "type": "full_reference_image", 1303 | "named": true 1304 | }, 1305 | { 1306 | "type": "full_reference_link", 1307 | "named": true 1308 | }, 1309 | { 1310 | "type": "hard_line_break", 1311 | "named": true 1312 | }, 1313 | { 1314 | "type": "highlighted", 1315 | "named": true 1316 | }, 1317 | { 1318 | "type": "inline_comment", 1319 | "named": true 1320 | }, 1321 | { 1322 | "type": "inline_image", 1323 | "named": true 1324 | }, 1325 | { 1326 | "type": "inline_link", 1327 | "named": true 1328 | }, 1329 | { 1330 | "type": "insert", 1331 | "named": true 1332 | }, 1333 | { 1334 | "type": "math", 1335 | "named": true 1336 | }, 1337 | { 1338 | "type": "note", 1339 | "named": true 1340 | }, 1341 | { 1342 | "type": "quotation_marks", 1343 | "named": true 1344 | }, 1345 | { 1346 | "type": "raw_inline", 1347 | "named": true 1348 | }, 1349 | { 1350 | "type": "span", 1351 | "named": true 1352 | }, 1353 | { 1354 | "type": "strong", 1355 | "named": true 1356 | }, 1357 | { 1358 | "type": "subscript", 1359 | "named": true 1360 | }, 1361 | { 1362 | "type": "superscript", 1363 | "named": true 1364 | }, 1365 | { 1366 | "type": "symbol", 1367 | "named": true 1368 | }, 1369 | { 1370 | "type": "todo", 1371 | "named": true 1372 | }, 1373 | { 1374 | "type": "verbatim", 1375 | "named": true 1376 | } 1377 | ] 1378 | } 1379 | }, 1380 | { 1381 | "type": "link_reference_definition", 1382 | "named": true, 1383 | "fields": { 1384 | "destination": { 1385 | "multiple": false, 1386 | "required": false, 1387 | "types": [ 1388 | { 1389 | "type": "link_destination", 1390 | "named": true 1391 | } 1392 | ] 1393 | }, 1394 | "label": { 1395 | "multiple": false, 1396 | "required": true, 1397 | "types": [ 1398 | { 1399 | "type": "link_label", 1400 | "named": true 1401 | } 1402 | ] 1403 | } 1404 | } 1405 | }, 1406 | { 1407 | "type": "link_text", 1408 | "named": true, 1409 | "fields": { 1410 | "attribute": { 1411 | "multiple": true, 1412 | "required": false, 1413 | "types": [ 1414 | { 1415 | "type": "inline_attribute", 1416 | "named": true 1417 | } 1418 | ] 1419 | } 1420 | }, 1421 | "children": { 1422 | "multiple": true, 1423 | "required": false, 1424 | "types": [ 1425 | { 1426 | "type": "autolink", 1427 | "named": true 1428 | }, 1429 | { 1430 | "type": "backslash_escape", 1431 | "named": true 1432 | }, 1433 | { 1434 | "type": "collapsed_reference_image", 1435 | "named": true 1436 | }, 1437 | { 1438 | "type": "collapsed_reference_link", 1439 | "named": true 1440 | }, 1441 | { 1442 | "type": "delete", 1443 | "named": true 1444 | }, 1445 | { 1446 | "type": "ellipsis", 1447 | "named": true 1448 | }, 1449 | { 1450 | "type": "em_dash", 1451 | "named": true 1452 | }, 1453 | { 1454 | "type": "emphasis", 1455 | "named": true 1456 | }, 1457 | { 1458 | "type": "en_dash", 1459 | "named": true 1460 | }, 1461 | { 1462 | "type": "fixme", 1463 | "named": true 1464 | }, 1465 | { 1466 | "type": "footnote_reference", 1467 | "named": true 1468 | }, 1469 | { 1470 | "type": "full_reference_image", 1471 | "named": true 1472 | }, 1473 | { 1474 | "type": "full_reference_link", 1475 | "named": true 1476 | }, 1477 | { 1478 | "type": "hard_line_break", 1479 | "named": true 1480 | }, 1481 | { 1482 | "type": "highlighted", 1483 | "named": true 1484 | }, 1485 | { 1486 | "type": "inline_comment", 1487 | "named": true 1488 | }, 1489 | { 1490 | "type": "inline_image", 1491 | "named": true 1492 | }, 1493 | { 1494 | "type": "inline_link", 1495 | "named": true 1496 | }, 1497 | { 1498 | "type": "insert", 1499 | "named": true 1500 | }, 1501 | { 1502 | "type": "math", 1503 | "named": true 1504 | }, 1505 | { 1506 | "type": "note", 1507 | "named": true 1508 | }, 1509 | { 1510 | "type": "quotation_marks", 1511 | "named": true 1512 | }, 1513 | { 1514 | "type": "raw_inline", 1515 | "named": true 1516 | }, 1517 | { 1518 | "type": "span", 1519 | "named": true 1520 | }, 1521 | { 1522 | "type": "strong", 1523 | "named": true 1524 | }, 1525 | { 1526 | "type": "subscript", 1527 | "named": true 1528 | }, 1529 | { 1530 | "type": "superscript", 1531 | "named": true 1532 | }, 1533 | { 1534 | "type": "symbol", 1535 | "named": true 1536 | }, 1537 | { 1538 | "type": "todo", 1539 | "named": true 1540 | }, 1541 | { 1542 | "type": "verbatim", 1543 | "named": true 1544 | } 1545 | ] 1546 | } 1547 | }, 1548 | { 1549 | "type": "list", 1550 | "named": true, 1551 | "fields": {}, 1552 | "children": { 1553 | "multiple": true, 1554 | "required": false, 1555 | "types": [ 1556 | { 1557 | "type": "list_item", 1558 | "named": true 1559 | } 1560 | ] 1561 | } 1562 | }, 1563 | { 1564 | "type": "list_item", 1565 | "named": true, 1566 | "fields": { 1567 | "content": { 1568 | "multiple": false, 1569 | "required": false, 1570 | "types": [ 1571 | { 1572 | "type": "list_item_content", 1573 | "named": true 1574 | } 1575 | ] 1576 | }, 1577 | "definition": { 1578 | "multiple": false, 1579 | "required": false, 1580 | "types": [ 1581 | { 1582 | "type": "definition", 1583 | "named": true 1584 | } 1585 | ] 1586 | }, 1587 | "marker": { 1588 | "multiple": false, 1589 | "required": true, 1590 | "types": [ 1591 | { 1592 | "type": "list_marker_dash", 1593 | "named": true 1594 | }, 1595 | { 1596 | "type": "list_marker_decimal_paren", 1597 | "named": true 1598 | }, 1599 | { 1600 | "type": "list_marker_decimal_parens", 1601 | "named": true 1602 | }, 1603 | { 1604 | "type": "list_marker_decimal_period", 1605 | "named": true 1606 | }, 1607 | { 1608 | "type": "list_marker_definition", 1609 | "named": true 1610 | }, 1611 | { 1612 | "type": "list_marker_lower_alpha_paren", 1613 | "named": true 1614 | }, 1615 | { 1616 | "type": "list_marker_lower_alpha_parens", 1617 | "named": true 1618 | }, 1619 | { 1620 | "type": "list_marker_lower_alpha_period", 1621 | "named": true 1622 | }, 1623 | { 1624 | "type": "list_marker_lower_roman_paren", 1625 | "named": true 1626 | }, 1627 | { 1628 | "type": "list_marker_lower_roman_parens", 1629 | "named": true 1630 | }, 1631 | { 1632 | "type": "list_marker_lower_roman_period", 1633 | "named": true 1634 | }, 1635 | { 1636 | "type": "list_marker_plus", 1637 | "named": true 1638 | }, 1639 | { 1640 | "type": "list_marker_star", 1641 | "named": true 1642 | }, 1643 | { 1644 | "type": "list_marker_task", 1645 | "named": true 1646 | }, 1647 | { 1648 | "type": "list_marker_upper_alpha_paren", 1649 | "named": true 1650 | }, 1651 | { 1652 | "type": "list_marker_upper_alpha_parens", 1653 | "named": true 1654 | }, 1655 | { 1656 | "type": "list_marker_upper_alpha_period", 1657 | "named": true 1658 | }, 1659 | { 1660 | "type": "list_marker_upper_roman_paren", 1661 | "named": true 1662 | }, 1663 | { 1664 | "type": "list_marker_upper_roman_parens", 1665 | "named": true 1666 | }, 1667 | { 1668 | "type": "list_marker_upper_roman_period", 1669 | "named": true 1670 | } 1671 | ] 1672 | }, 1673 | "term": { 1674 | "multiple": false, 1675 | "required": false, 1676 | "types": [ 1677 | { 1678 | "type": "term", 1679 | "named": true 1680 | } 1681 | ] 1682 | } 1683 | }, 1684 | "children": { 1685 | "multiple": true, 1686 | "required": false, 1687 | "types": [ 1688 | { 1689 | "type": "block_quote_marker", 1690 | "named": true 1691 | } 1692 | ] 1693 | } 1694 | }, 1695 | { 1696 | "type": "list_item_content", 1697 | "named": true, 1698 | "fields": {}, 1699 | "children": { 1700 | "multiple": true, 1701 | "required": false, 1702 | "types": [ 1703 | { 1704 | "type": "block_attribute", 1705 | "named": true 1706 | }, 1707 | { 1708 | "type": "block_quote", 1709 | "named": true 1710 | }, 1711 | { 1712 | "type": "block_quote_marker", 1713 | "named": true 1714 | }, 1715 | { 1716 | "type": "code_block", 1717 | "named": true 1718 | }, 1719 | { 1720 | "type": "div", 1721 | "named": true 1722 | }, 1723 | { 1724 | "type": "footnote", 1725 | "named": true 1726 | }, 1727 | { 1728 | "type": "heading", 1729 | "named": true 1730 | }, 1731 | { 1732 | "type": "link_reference_definition", 1733 | "named": true 1734 | }, 1735 | { 1736 | "type": "list", 1737 | "named": true 1738 | }, 1739 | { 1740 | "type": "paragraph", 1741 | "named": true 1742 | }, 1743 | { 1744 | "type": "raw_block", 1745 | "named": true 1746 | }, 1747 | { 1748 | "type": "table", 1749 | "named": true 1750 | }, 1751 | { 1752 | "type": "thematic_break", 1753 | "named": true 1754 | } 1755 | ] 1756 | } 1757 | }, 1758 | { 1759 | "type": "list_marker_task", 1760 | "named": true, 1761 | "fields": { 1762 | "checkmark": { 1763 | "multiple": false, 1764 | "required": true, 1765 | "types": [ 1766 | { 1767 | "type": "checked", 1768 | "named": true 1769 | }, 1770 | { 1771 | "type": "unchecked", 1772 | "named": true 1773 | } 1774 | ] 1775 | } 1776 | } 1777 | }, 1778 | { 1779 | "type": "math", 1780 | "named": true, 1781 | "fields": { 1782 | "begin_marker": { 1783 | "multiple": false, 1784 | "required": true, 1785 | "types": [ 1786 | { 1787 | "type": "math_marker_begin", 1788 | "named": true 1789 | } 1790 | ] 1791 | }, 1792 | "content": { 1793 | "multiple": false, 1794 | "required": true, 1795 | "types": [ 1796 | { 1797 | "type": "content", 1798 | "named": true 1799 | } 1800 | ] 1801 | }, 1802 | "end_marker": { 1803 | "multiple": false, 1804 | "required": true, 1805 | "types": [ 1806 | { 1807 | "type": "math_marker_end", 1808 | "named": true 1809 | } 1810 | ] 1811 | }, 1812 | "math_marker": { 1813 | "multiple": false, 1814 | "required": true, 1815 | "types": [ 1816 | { 1817 | "type": "math_marker", 1818 | "named": true 1819 | } 1820 | ] 1821 | } 1822 | } 1823 | }, 1824 | { 1825 | "type": "note", 1826 | "named": true, 1827 | "fields": {} 1828 | }, 1829 | { 1830 | "type": "paragraph", 1831 | "named": true, 1832 | "fields": { 1833 | "attribute": { 1834 | "multiple": true, 1835 | "required": false, 1836 | "types": [ 1837 | { 1838 | "type": "inline_attribute", 1839 | "named": true 1840 | } 1841 | ] 1842 | } 1843 | }, 1844 | "children": { 1845 | "multiple": true, 1846 | "required": false, 1847 | "types": [ 1848 | { 1849 | "type": "autolink", 1850 | "named": true 1851 | }, 1852 | { 1853 | "type": "backslash_escape", 1854 | "named": true 1855 | }, 1856 | { 1857 | "type": "block_quote_marker", 1858 | "named": true 1859 | }, 1860 | { 1861 | "type": "collapsed_reference_image", 1862 | "named": true 1863 | }, 1864 | { 1865 | "type": "collapsed_reference_link", 1866 | "named": true 1867 | }, 1868 | { 1869 | "type": "delete", 1870 | "named": true 1871 | }, 1872 | { 1873 | "type": "ellipsis", 1874 | "named": true 1875 | }, 1876 | { 1877 | "type": "em_dash", 1878 | "named": true 1879 | }, 1880 | { 1881 | "type": "emphasis", 1882 | "named": true 1883 | }, 1884 | { 1885 | "type": "en_dash", 1886 | "named": true 1887 | }, 1888 | { 1889 | "type": "fixme", 1890 | "named": true 1891 | }, 1892 | { 1893 | "type": "footnote_reference", 1894 | "named": true 1895 | }, 1896 | { 1897 | "type": "full_reference_image", 1898 | "named": true 1899 | }, 1900 | { 1901 | "type": "full_reference_link", 1902 | "named": true 1903 | }, 1904 | { 1905 | "type": "hard_line_break", 1906 | "named": true 1907 | }, 1908 | { 1909 | "type": "highlighted", 1910 | "named": true 1911 | }, 1912 | { 1913 | "type": "inline_comment", 1914 | "named": true 1915 | }, 1916 | { 1917 | "type": "inline_image", 1918 | "named": true 1919 | }, 1920 | { 1921 | "type": "inline_link", 1922 | "named": true 1923 | }, 1924 | { 1925 | "type": "insert", 1926 | "named": true 1927 | }, 1928 | { 1929 | "type": "math", 1930 | "named": true 1931 | }, 1932 | { 1933 | "type": "note", 1934 | "named": true 1935 | }, 1936 | { 1937 | "type": "quotation_marks", 1938 | "named": true 1939 | }, 1940 | { 1941 | "type": "raw_inline", 1942 | "named": true 1943 | }, 1944 | { 1945 | "type": "span", 1946 | "named": true 1947 | }, 1948 | { 1949 | "type": "strong", 1950 | "named": true 1951 | }, 1952 | { 1953 | "type": "subscript", 1954 | "named": true 1955 | }, 1956 | { 1957 | "type": "superscript", 1958 | "named": true 1959 | }, 1960 | { 1961 | "type": "symbol", 1962 | "named": true 1963 | }, 1964 | { 1965 | "type": "todo", 1966 | "named": true 1967 | }, 1968 | { 1969 | "type": "verbatim", 1970 | "named": true 1971 | } 1972 | ] 1973 | } 1974 | }, 1975 | { 1976 | "type": "raw_block", 1977 | "named": true, 1978 | "fields": { 1979 | "content": { 1980 | "multiple": false, 1981 | "required": false, 1982 | "types": [ 1983 | { 1984 | "type": "content", 1985 | "named": true 1986 | } 1987 | ] 1988 | }, 1989 | "info": { 1990 | "multiple": false, 1991 | "required": true, 1992 | "types": [ 1993 | { 1994 | "type": "raw_block_info", 1995 | "named": true 1996 | } 1997 | ] 1998 | } 1999 | }, 2000 | "children": { 2001 | "multiple": true, 2002 | "required": true, 2003 | "types": [ 2004 | { 2005 | "type": "raw_block_marker_begin", 2006 | "named": true 2007 | }, 2008 | { 2009 | "type": "raw_block_marker_end", 2010 | "named": true 2011 | } 2012 | ] 2013 | } 2014 | }, 2015 | { 2016 | "type": "raw_block_info", 2017 | "named": true, 2018 | "fields": { 2019 | "language": { 2020 | "multiple": false, 2021 | "required": true, 2022 | "types": [ 2023 | { 2024 | "type": "language", 2025 | "named": true 2026 | } 2027 | ] 2028 | }, 2029 | "marker": { 2030 | "multiple": false, 2031 | "required": true, 2032 | "types": [ 2033 | { 2034 | "type": "language_marker", 2035 | "named": true 2036 | } 2037 | ] 2038 | } 2039 | } 2040 | }, 2041 | { 2042 | "type": "raw_inline", 2043 | "named": true, 2044 | "fields": { 2045 | "attribute": { 2046 | "multiple": false, 2047 | "required": true, 2048 | "types": [ 2049 | { 2050 | "type": "raw_inline_attribute", 2051 | "named": true 2052 | } 2053 | ] 2054 | }, 2055 | "begin_marker": { 2056 | "multiple": false, 2057 | "required": true, 2058 | "types": [ 2059 | { 2060 | "type": "raw_inline_marker_begin", 2061 | "named": true 2062 | } 2063 | ] 2064 | }, 2065 | "content": { 2066 | "multiple": false, 2067 | "required": true, 2068 | "types": [ 2069 | { 2070 | "type": "content", 2071 | "named": true 2072 | } 2073 | ] 2074 | }, 2075 | "end_marker": { 2076 | "multiple": false, 2077 | "required": true, 2078 | "types": [ 2079 | { 2080 | "type": "raw_inline_marker_end", 2081 | "named": true 2082 | } 2083 | ] 2084 | } 2085 | } 2086 | }, 2087 | { 2088 | "type": "raw_inline_attribute", 2089 | "named": true, 2090 | "fields": { 2091 | "language": { 2092 | "multiple": false, 2093 | "required": true, 2094 | "types": [ 2095 | { 2096 | "type": "language", 2097 | "named": true 2098 | } 2099 | ] 2100 | } 2101 | } 2102 | }, 2103 | { 2104 | "type": "reference_label", 2105 | "named": true, 2106 | "fields": {} 2107 | }, 2108 | { 2109 | "type": "section", 2110 | "named": true, 2111 | "fields": { 2112 | "content": { 2113 | "multiple": false, 2114 | "required": false, 2115 | "types": [ 2116 | { 2117 | "type": "section_content", 2118 | "named": true 2119 | } 2120 | ] 2121 | }, 2122 | "heading": { 2123 | "multiple": false, 2124 | "required": true, 2125 | "types": [ 2126 | { 2127 | "type": "heading", 2128 | "named": true 2129 | } 2130 | ] 2131 | } 2132 | } 2133 | }, 2134 | { 2135 | "type": "section_content", 2136 | "named": true, 2137 | "fields": {}, 2138 | "children": { 2139 | "multiple": true, 2140 | "required": false, 2141 | "types": [ 2142 | { 2143 | "type": "block_attribute", 2144 | "named": true 2145 | }, 2146 | { 2147 | "type": "block_quote", 2148 | "named": true 2149 | }, 2150 | { 2151 | "type": "code_block", 2152 | "named": true 2153 | }, 2154 | { 2155 | "type": "div", 2156 | "named": true 2157 | }, 2158 | { 2159 | "type": "footnote", 2160 | "named": true 2161 | }, 2162 | { 2163 | "type": "link_reference_definition", 2164 | "named": true 2165 | }, 2166 | { 2167 | "type": "list", 2168 | "named": true 2169 | }, 2170 | { 2171 | "type": "paragraph", 2172 | "named": true 2173 | }, 2174 | { 2175 | "type": "raw_block", 2176 | "named": true 2177 | }, 2178 | { 2179 | "type": "section", 2180 | "named": true 2181 | }, 2182 | { 2183 | "type": "table", 2184 | "named": true 2185 | }, 2186 | { 2187 | "type": "thematic_break", 2188 | "named": true 2189 | } 2190 | ] 2191 | } 2192 | }, 2193 | { 2194 | "type": "span", 2195 | "named": true, 2196 | "fields": { 2197 | "attribute": { 2198 | "multiple": false, 2199 | "required": true, 2200 | "types": [ 2201 | { 2202 | "type": "inline_attribute", 2203 | "named": true 2204 | } 2205 | ] 2206 | }, 2207 | "content": { 2208 | "multiple": false, 2209 | "required": true, 2210 | "types": [ 2211 | { 2212 | "type": "content", 2213 | "named": true 2214 | } 2215 | ] 2216 | } 2217 | } 2218 | }, 2219 | { 2220 | "type": "strong", 2221 | "named": true, 2222 | "fields": { 2223 | "begin_marker": { 2224 | "multiple": false, 2225 | "required": true, 2226 | "types": [ 2227 | { 2228 | "type": "strong_begin", 2229 | "named": true 2230 | } 2231 | ] 2232 | }, 2233 | "content": { 2234 | "multiple": false, 2235 | "required": true, 2236 | "types": [ 2237 | { 2238 | "type": "content", 2239 | "named": true 2240 | } 2241 | ] 2242 | }, 2243 | "end_marker": { 2244 | "multiple": false, 2245 | "required": true, 2246 | "types": [ 2247 | { 2248 | "type": "strong_end", 2249 | "named": true 2250 | } 2251 | ] 2252 | } 2253 | } 2254 | }, 2255 | { 2256 | "type": "strong_begin", 2257 | "named": true, 2258 | "fields": {} 2259 | }, 2260 | { 2261 | "type": "subscript", 2262 | "named": true, 2263 | "fields": { 2264 | "begin_marker": { 2265 | "multiple": false, 2266 | "required": true, 2267 | "types": [ 2268 | { 2269 | "type": "subscript_begin", 2270 | "named": true 2271 | } 2272 | ] 2273 | }, 2274 | "content": { 2275 | "multiple": false, 2276 | "required": true, 2277 | "types": [ 2278 | { 2279 | "type": "content", 2280 | "named": true 2281 | } 2282 | ] 2283 | }, 2284 | "end_marker": { 2285 | "multiple": false, 2286 | "required": true, 2287 | "types": [ 2288 | { 2289 | "type": "subscript_end", 2290 | "named": true 2291 | } 2292 | ] 2293 | } 2294 | } 2295 | }, 2296 | { 2297 | "type": "subscript_begin", 2298 | "named": true, 2299 | "fields": {} 2300 | }, 2301 | { 2302 | "type": "superscript", 2303 | "named": true, 2304 | "fields": { 2305 | "begin_marker": { 2306 | "multiple": false, 2307 | "required": true, 2308 | "types": [ 2309 | { 2310 | "type": "superscript_begin", 2311 | "named": true 2312 | } 2313 | ] 2314 | }, 2315 | "content": { 2316 | "multiple": false, 2317 | "required": true, 2318 | "types": [ 2319 | { 2320 | "type": "content", 2321 | "named": true 2322 | } 2323 | ] 2324 | }, 2325 | "end_marker": { 2326 | "multiple": false, 2327 | "required": true, 2328 | "types": [ 2329 | { 2330 | "type": "superscript_end", 2331 | "named": true 2332 | } 2333 | ] 2334 | } 2335 | } 2336 | }, 2337 | { 2338 | "type": "superscript_begin", 2339 | "named": true, 2340 | "fields": {} 2341 | }, 2342 | { 2343 | "type": "table", 2344 | "named": true, 2345 | "fields": {}, 2346 | "children": { 2347 | "multiple": true, 2348 | "required": true, 2349 | "types": [ 2350 | { 2351 | "type": "block_quote_marker", 2352 | "named": true 2353 | }, 2354 | { 2355 | "type": "table_caption", 2356 | "named": true 2357 | }, 2358 | { 2359 | "type": "table_header", 2360 | "named": true 2361 | }, 2362 | { 2363 | "type": "table_row", 2364 | "named": true 2365 | }, 2366 | { 2367 | "type": "table_separator", 2368 | "named": true 2369 | } 2370 | ] 2371 | } 2372 | }, 2373 | { 2374 | "type": "table_caption", 2375 | "named": true, 2376 | "fields": { 2377 | "content": { 2378 | "multiple": false, 2379 | "required": true, 2380 | "types": [ 2381 | { 2382 | "type": "content", 2383 | "named": true 2384 | } 2385 | ] 2386 | }, 2387 | "marker": { 2388 | "multiple": false, 2389 | "required": true, 2390 | "types": [ 2391 | { 2392 | "type": "marker", 2393 | "named": true 2394 | } 2395 | ] 2396 | } 2397 | } 2398 | }, 2399 | { 2400 | "type": "table_cell", 2401 | "named": true, 2402 | "fields": { 2403 | "attribute": { 2404 | "multiple": true, 2405 | "required": false, 2406 | "types": [ 2407 | { 2408 | "type": "inline_attribute", 2409 | "named": true 2410 | } 2411 | ] 2412 | } 2413 | }, 2414 | "children": { 2415 | "multiple": true, 2416 | "required": false, 2417 | "types": [ 2418 | { 2419 | "type": "autolink", 2420 | "named": true 2421 | }, 2422 | { 2423 | "type": "backslash_escape", 2424 | "named": true 2425 | }, 2426 | { 2427 | "type": "collapsed_reference_image", 2428 | "named": true 2429 | }, 2430 | { 2431 | "type": "collapsed_reference_link", 2432 | "named": true 2433 | }, 2434 | { 2435 | "type": "delete", 2436 | "named": true 2437 | }, 2438 | { 2439 | "type": "ellipsis", 2440 | "named": true 2441 | }, 2442 | { 2443 | "type": "em_dash", 2444 | "named": true 2445 | }, 2446 | { 2447 | "type": "emphasis", 2448 | "named": true 2449 | }, 2450 | { 2451 | "type": "en_dash", 2452 | "named": true 2453 | }, 2454 | { 2455 | "type": "fixme", 2456 | "named": true 2457 | }, 2458 | { 2459 | "type": "footnote_reference", 2460 | "named": true 2461 | }, 2462 | { 2463 | "type": "full_reference_image", 2464 | "named": true 2465 | }, 2466 | { 2467 | "type": "full_reference_link", 2468 | "named": true 2469 | }, 2470 | { 2471 | "type": "hard_line_break", 2472 | "named": true 2473 | }, 2474 | { 2475 | "type": "highlighted", 2476 | "named": true 2477 | }, 2478 | { 2479 | "type": "inline_comment", 2480 | "named": true 2481 | }, 2482 | { 2483 | "type": "inline_image", 2484 | "named": true 2485 | }, 2486 | { 2487 | "type": "inline_link", 2488 | "named": true 2489 | }, 2490 | { 2491 | "type": "insert", 2492 | "named": true 2493 | }, 2494 | { 2495 | "type": "math", 2496 | "named": true 2497 | }, 2498 | { 2499 | "type": "note", 2500 | "named": true 2501 | }, 2502 | { 2503 | "type": "quotation_marks", 2504 | "named": true 2505 | }, 2506 | { 2507 | "type": "raw_inline", 2508 | "named": true 2509 | }, 2510 | { 2511 | "type": "span", 2512 | "named": true 2513 | }, 2514 | { 2515 | "type": "strong", 2516 | "named": true 2517 | }, 2518 | { 2519 | "type": "subscript", 2520 | "named": true 2521 | }, 2522 | { 2523 | "type": "superscript", 2524 | "named": true 2525 | }, 2526 | { 2527 | "type": "symbol", 2528 | "named": true 2529 | }, 2530 | { 2531 | "type": "todo", 2532 | "named": true 2533 | }, 2534 | { 2535 | "type": "verbatim", 2536 | "named": true 2537 | } 2538 | ] 2539 | } 2540 | }, 2541 | { 2542 | "type": "table_header", 2543 | "named": true, 2544 | "fields": {}, 2545 | "children": { 2546 | "multiple": true, 2547 | "required": false, 2548 | "types": [ 2549 | { 2550 | "type": "table_cell", 2551 | "named": true 2552 | } 2553 | ] 2554 | } 2555 | }, 2556 | { 2557 | "type": "table_row", 2558 | "named": true, 2559 | "fields": {}, 2560 | "children": { 2561 | "multiple": true, 2562 | "required": false, 2563 | "types": [ 2564 | { 2565 | "type": "table_cell", 2566 | "named": true 2567 | } 2568 | ] 2569 | } 2570 | }, 2571 | { 2572 | "type": "table_separator", 2573 | "named": true, 2574 | "fields": {}, 2575 | "children": { 2576 | "multiple": true, 2577 | "required": false, 2578 | "types": [ 2579 | { 2580 | "type": "table_cell_alignment", 2581 | "named": true 2582 | } 2583 | ] 2584 | } 2585 | }, 2586 | { 2587 | "type": "term", 2588 | "named": true, 2589 | "fields": { 2590 | "attribute": { 2591 | "multiple": true, 2592 | "required": false, 2593 | "types": [ 2594 | { 2595 | "type": "inline_attribute", 2596 | "named": true 2597 | } 2598 | ] 2599 | } 2600 | }, 2601 | "children": { 2602 | "multiple": true, 2603 | "required": false, 2604 | "types": [ 2605 | { 2606 | "type": "autolink", 2607 | "named": true 2608 | }, 2609 | { 2610 | "type": "backslash_escape", 2611 | "named": true 2612 | }, 2613 | { 2614 | "type": "block_quote_marker", 2615 | "named": true 2616 | }, 2617 | { 2618 | "type": "collapsed_reference_image", 2619 | "named": true 2620 | }, 2621 | { 2622 | "type": "collapsed_reference_link", 2623 | "named": true 2624 | }, 2625 | { 2626 | "type": "delete", 2627 | "named": true 2628 | }, 2629 | { 2630 | "type": "ellipsis", 2631 | "named": true 2632 | }, 2633 | { 2634 | "type": "em_dash", 2635 | "named": true 2636 | }, 2637 | { 2638 | "type": "emphasis", 2639 | "named": true 2640 | }, 2641 | { 2642 | "type": "en_dash", 2643 | "named": true 2644 | }, 2645 | { 2646 | "type": "fixme", 2647 | "named": true 2648 | }, 2649 | { 2650 | "type": "footnote_reference", 2651 | "named": true 2652 | }, 2653 | { 2654 | "type": "full_reference_image", 2655 | "named": true 2656 | }, 2657 | { 2658 | "type": "full_reference_link", 2659 | "named": true 2660 | }, 2661 | { 2662 | "type": "hard_line_break", 2663 | "named": true 2664 | }, 2665 | { 2666 | "type": "highlighted", 2667 | "named": true 2668 | }, 2669 | { 2670 | "type": "inline_comment", 2671 | "named": true 2672 | }, 2673 | { 2674 | "type": "inline_image", 2675 | "named": true 2676 | }, 2677 | { 2678 | "type": "inline_link", 2679 | "named": true 2680 | }, 2681 | { 2682 | "type": "insert", 2683 | "named": true 2684 | }, 2685 | { 2686 | "type": "math", 2687 | "named": true 2688 | }, 2689 | { 2690 | "type": "note", 2691 | "named": true 2692 | }, 2693 | { 2694 | "type": "quotation_marks", 2695 | "named": true 2696 | }, 2697 | { 2698 | "type": "raw_inline", 2699 | "named": true 2700 | }, 2701 | { 2702 | "type": "span", 2703 | "named": true 2704 | }, 2705 | { 2706 | "type": "strong", 2707 | "named": true 2708 | }, 2709 | { 2710 | "type": "subscript", 2711 | "named": true 2712 | }, 2713 | { 2714 | "type": "superscript", 2715 | "named": true 2716 | }, 2717 | { 2718 | "type": "symbol", 2719 | "named": true 2720 | }, 2721 | { 2722 | "type": "todo", 2723 | "named": true 2724 | }, 2725 | { 2726 | "type": "verbatim", 2727 | "named": true 2728 | } 2729 | ] 2730 | } 2731 | }, 2732 | { 2733 | "type": "thematic_break", 2734 | "named": true, 2735 | "fields": {} 2736 | }, 2737 | { 2738 | "type": "todo", 2739 | "named": true, 2740 | "fields": {} 2741 | }, 2742 | { 2743 | "type": "unchecked", 2744 | "named": true, 2745 | "fields": {} 2746 | }, 2747 | { 2748 | "type": "value", 2749 | "named": true, 2750 | "fields": {} 2751 | }, 2752 | { 2753 | "type": "verbatim", 2754 | "named": true, 2755 | "fields": { 2756 | "begin_marker": { 2757 | "multiple": false, 2758 | "required": true, 2759 | "types": [ 2760 | { 2761 | "type": "verbatim_marker_begin", 2762 | "named": true 2763 | } 2764 | ] 2765 | }, 2766 | "content": { 2767 | "multiple": false, 2768 | "required": true, 2769 | "types": [ 2770 | { 2771 | "type": "content", 2772 | "named": true 2773 | } 2774 | ] 2775 | }, 2776 | "end_marker": { 2777 | "multiple": false, 2778 | "required": true, 2779 | "types": [ 2780 | { 2781 | "type": "verbatim_marker_end", 2782 | "named": true 2783 | } 2784 | ] 2785 | } 2786 | } 2787 | }, 2788 | { 2789 | "type": "\u0000", 2790 | "named": false 2791 | }, 2792 | { 2793 | "type": " ", 2794 | "named": false 2795 | }, 2796 | { 2797 | "type": "![", 2798 | "named": false 2799 | }, 2800 | { 2801 | "type": "\"", 2802 | "named": false 2803 | }, 2804 | { 2805 | "type": "$", 2806 | "named": false 2807 | }, 2808 | { 2809 | "type": "%", 2810 | "named": false 2811 | }, 2812 | { 2813 | "type": "(", 2814 | "named": false 2815 | }, 2816 | { 2817 | "type": ")", 2818 | "named": false 2819 | }, 2820 | { 2821 | "type": "*", 2822 | "named": false 2823 | }, 2824 | { 2825 | "type": ".", 2826 | "named": false 2827 | }, 2828 | { 2829 | "type": ":", 2830 | "named": false 2831 | }, 2832 | { 2833 | "type": "<", 2834 | "named": false 2835 | }, 2836 | { 2837 | "type": "=", 2838 | "named": false 2839 | }, 2840 | { 2841 | "type": ">", 2842 | "named": false 2843 | }, 2844 | { 2845 | "type": "INFO", 2846 | "named": false 2847 | }, 2848 | { 2849 | "type": "NOTE", 2850 | "named": false 2851 | }, 2852 | { 2853 | "type": "TODO", 2854 | "named": false 2855 | }, 2856 | { 2857 | "type": "WIP", 2858 | "named": false 2859 | }, 2860 | { 2861 | "type": "X", 2862 | "named": false 2863 | }, 2864 | { 2865 | "type": "XXX", 2866 | "named": false 2867 | }, 2868 | { 2869 | "type": "[", 2870 | "named": false 2871 | }, 2872 | { 2873 | "type": "[]", 2874 | "named": false 2875 | }, 2876 | { 2877 | "type": "[^", 2878 | "named": false 2879 | }, 2880 | { 2881 | "type": "]", 2882 | "named": false 2883 | }, 2884 | { 2885 | "type": "^", 2886 | "named": false 2887 | }, 2888 | { 2889 | "type": "_", 2890 | "named": false 2891 | }, 2892 | { 2893 | "type": "backslash_escape", 2894 | "named": true 2895 | }, 2896 | { 2897 | "type": "block_quote_marker", 2898 | "named": true 2899 | }, 2900 | { 2901 | "type": "code_block_marker_begin", 2902 | "named": true 2903 | }, 2904 | { 2905 | "type": "code_block_marker_end", 2906 | "named": true 2907 | }, 2908 | { 2909 | "type": "delete_end", 2910 | "named": true 2911 | }, 2912 | { 2913 | "type": "div_marker_begin", 2914 | "named": true 2915 | }, 2916 | { 2917 | "type": "div_marker_end", 2918 | "named": true 2919 | }, 2920 | { 2921 | "type": "ellipsis", 2922 | "named": true 2923 | }, 2924 | { 2925 | "type": "em_dash", 2926 | "named": true 2927 | }, 2928 | { 2929 | "type": "emphasis_end", 2930 | "named": true 2931 | }, 2932 | { 2933 | "type": "en_dash", 2934 | "named": true 2935 | }, 2936 | { 2937 | "type": "fixme", 2938 | "named": true 2939 | }, 2940 | { 2941 | "type": "footnote_marker_end", 2942 | "named": true 2943 | }, 2944 | { 2945 | "type": "frontmatter_marker", 2946 | "named": true 2947 | }, 2948 | { 2949 | "type": "hard_line_break", 2950 | "named": true 2951 | }, 2952 | { 2953 | "type": "highlighted_end", 2954 | "named": true 2955 | }, 2956 | { 2957 | "type": "identifier", 2958 | "named": true 2959 | }, 2960 | { 2961 | "type": "insert_end", 2962 | "named": true 2963 | }, 2964 | { 2965 | "type": "language", 2966 | "named": true 2967 | }, 2968 | { 2969 | "type": "language_marker", 2970 | "named": true 2971 | }, 2972 | { 2973 | "type": "link_destination", 2974 | "named": true 2975 | }, 2976 | { 2977 | "type": "list_marker_dash", 2978 | "named": true 2979 | }, 2980 | { 2981 | "type": "list_marker_decimal_paren", 2982 | "named": true 2983 | }, 2984 | { 2985 | "type": "list_marker_decimal_parens", 2986 | "named": true 2987 | }, 2988 | { 2989 | "type": "list_marker_decimal_period", 2990 | "named": true 2991 | }, 2992 | { 2993 | "type": "list_marker_definition", 2994 | "named": true 2995 | }, 2996 | { 2997 | "type": "list_marker_lower_alpha_paren", 2998 | "named": true 2999 | }, 3000 | { 3001 | "type": "list_marker_lower_alpha_parens", 3002 | "named": true 3003 | }, 3004 | { 3005 | "type": "list_marker_lower_alpha_period", 3006 | "named": true 3007 | }, 3008 | { 3009 | "type": "list_marker_lower_roman_paren", 3010 | "named": true 3011 | }, 3012 | { 3013 | "type": "list_marker_lower_roman_parens", 3014 | "named": true 3015 | }, 3016 | { 3017 | "type": "list_marker_lower_roman_period", 3018 | "named": true 3019 | }, 3020 | { 3021 | "type": "list_marker_plus", 3022 | "named": true 3023 | }, 3024 | { 3025 | "type": "list_marker_star", 3026 | "named": true 3027 | }, 3028 | { 3029 | "type": "list_marker_upper_alpha_paren", 3030 | "named": true 3031 | }, 3032 | { 3033 | "type": "list_marker_upper_alpha_parens", 3034 | "named": true 3035 | }, 3036 | { 3037 | "type": "list_marker_upper_alpha_period", 3038 | "named": true 3039 | }, 3040 | { 3041 | "type": "list_marker_upper_roman_paren", 3042 | "named": true 3043 | }, 3044 | { 3045 | "type": "list_marker_upper_roman_parens", 3046 | "named": true 3047 | }, 3048 | { 3049 | "type": "list_marker_upper_roman_period", 3050 | "named": true 3051 | }, 3052 | { 3053 | "type": "marker", 3054 | "named": true 3055 | }, 3056 | { 3057 | "type": "math_marker", 3058 | "named": true 3059 | }, 3060 | { 3061 | "type": "math_marker_begin", 3062 | "named": true 3063 | }, 3064 | { 3065 | "type": "math_marker_end", 3066 | "named": true 3067 | }, 3068 | { 3069 | "type": "quotation_marks", 3070 | "named": true 3071 | }, 3072 | { 3073 | "type": "raw_block_marker_begin", 3074 | "named": true 3075 | }, 3076 | { 3077 | "type": "raw_block_marker_end", 3078 | "named": true 3079 | }, 3080 | { 3081 | "type": "raw_inline_marker_begin", 3082 | "named": true 3083 | }, 3084 | { 3085 | "type": "raw_inline_marker_end", 3086 | "named": true 3087 | }, 3088 | { 3089 | "type": "strong_end", 3090 | "named": true 3091 | }, 3092 | { 3093 | "type": "subscript_end", 3094 | "named": true 3095 | }, 3096 | { 3097 | "type": "superscript_end", 3098 | "named": true 3099 | }, 3100 | { 3101 | "type": "symbol", 3102 | "named": true 3103 | }, 3104 | { 3105 | "type": "table_cell_alignment", 3106 | "named": true 3107 | }, 3108 | { 3109 | "type": "verbatim_marker_begin", 3110 | "named": true 3111 | }, 3112 | { 3113 | "type": "verbatim_marker_end", 3114 | "named": true 3115 | }, 3116 | { 3117 | "type": "x", 3118 | "named": false 3119 | }, 3120 | { 3121 | "type": "{", 3122 | "named": false 3123 | }, 3124 | { 3125 | "type": "{*", 3126 | "named": false 3127 | }, 3128 | { 3129 | "type": "{+", 3130 | "named": false 3131 | }, 3132 | { 3133 | "type": "{-", 3134 | "named": false 3135 | }, 3136 | { 3137 | "type": "{=", 3138 | "named": false 3139 | }, 3140 | { 3141 | "type": "{^", 3142 | "named": false 3143 | }, 3144 | { 3145 | "type": "{_", 3146 | "named": false 3147 | }, 3148 | { 3149 | "type": "{~", 3150 | "named": false 3151 | }, 3152 | { 3153 | "type": "|", 3154 | "named": false 3155 | }, 3156 | { 3157 | "type": "}", 3158 | "named": false 3159 | }, 3160 | { 3161 | "type": "~", 3162 | "named": false 3163 | } 3164 | ] -------------------------------------------------------------------------------- /src/tree_sitter/alloc.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ALLOC_H_ 2 | #define TREE_SITTER_ALLOC_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // Allow clients to override allocation functions 13 | #ifdef TREE_SITTER_REUSE_ALLOCATOR 14 | 15 | extern void *(*ts_current_malloc)(size_t size); 16 | extern void *(*ts_current_calloc)(size_t count, size_t size); 17 | extern void *(*ts_current_realloc)(void *ptr, size_t size); 18 | extern void (*ts_current_free)(void *ptr); 19 | 20 | #ifndef ts_malloc 21 | #define ts_malloc ts_current_malloc 22 | #endif 23 | #ifndef ts_calloc 24 | #define ts_calloc ts_current_calloc 25 | #endif 26 | #ifndef ts_realloc 27 | #define ts_realloc ts_current_realloc 28 | #endif 29 | #ifndef ts_free 30 | #define ts_free ts_current_free 31 | #endif 32 | 33 | #else 34 | 35 | #ifndef ts_malloc 36 | #define ts_malloc malloc 37 | #endif 38 | #ifndef ts_calloc 39 | #define ts_calloc calloc 40 | #endif 41 | #ifndef ts_realloc 42 | #define ts_realloc realloc 43 | #endif 44 | #ifndef ts_free 45 | #define ts_free free 46 | #endif 47 | 48 | #endif 49 | 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | 54 | #endif // TREE_SITTER_ALLOC_H_ 55 | -------------------------------------------------------------------------------- /src/tree_sitter/array.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_ARRAY_H_ 2 | #define TREE_SITTER_ARRAY_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "./alloc.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _MSC_VER 17 | #pragma warning(push) 18 | #pragma warning(disable : 4101) 19 | #elif defined(__GNUC__) || defined(__clang__) 20 | #pragma GCC diagnostic push 21 | #pragma GCC diagnostic ignored "-Wunused-variable" 22 | #endif 23 | 24 | #define Array(T) \ 25 | struct { \ 26 | T *contents; \ 27 | uint32_t size; \ 28 | uint32_t capacity; \ 29 | } 30 | 31 | /// Initialize an array. 32 | #define array_init(self) \ 33 | ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL) 34 | 35 | /// Create an empty array. 36 | #define array_new() \ 37 | { NULL, 0, 0 } 38 | 39 | /// Get a pointer to the element at a given `index` in the array. 40 | #define array_get(self, _index) \ 41 | (assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index]) 42 | 43 | /// Get a pointer to the first element in the array. 44 | #define array_front(self) array_get(self, 0) 45 | 46 | /// Get a pointer to the last element in the array. 47 | #define array_back(self) array_get(self, (self)->size - 1) 48 | 49 | /// Clear the array, setting its size to zero. Note that this does not free any 50 | /// memory allocated for the array's contents. 51 | #define array_clear(self) ((self)->size = 0) 52 | 53 | /// Reserve `new_capacity` elements of space in the array. If `new_capacity` is 54 | /// less than the array's current capacity, this function has no effect. 55 | #define array_reserve(self, new_capacity) \ 56 | _array__reserve((Array *)(self), array_elem_size(self), new_capacity) 57 | 58 | /// Free any memory allocated for this array. Note that this does not free any 59 | /// memory allocated for the array's contents. 60 | #define array_delete(self) _array__delete((Array *)(self)) 61 | 62 | /// Push a new `element` onto the end of the array. 63 | #define array_push(self, element) \ 64 | (_array__grow((Array *)(self), 1, array_elem_size(self)), \ 65 | (self)->contents[(self)->size++] = (element)) 66 | 67 | /// Increase the array's size by `count` elements. 68 | /// New elements are zero-initialized. 69 | #define array_grow_by(self, count) \ 70 | do { \ 71 | if ((count) == 0) break; \ 72 | _array__grow((Array *)(self), count, array_elem_size(self)); \ 73 | memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \ 74 | (self)->size += (count); \ 75 | } while (0) 76 | 77 | /// Append all elements from one array to the end of another. 78 | #define array_push_all(self, other) \ 79 | array_extend((self), (other)->size, (other)->contents) 80 | 81 | /// Append `count` elements to the end of the array, reading their values from the 82 | /// `contents` pointer. 83 | #define array_extend(self, count, contents) \ 84 | _array__splice( \ 85 | (Array *)(self), array_elem_size(self), (self)->size, \ 86 | 0, count, contents \ 87 | ) 88 | 89 | /// Remove `old_count` elements from the array starting at the given `index`. At 90 | /// the same index, insert `new_count` new elements, reading their values from the 91 | /// `new_contents` pointer. 92 | #define array_splice(self, _index, old_count, new_count, new_contents) \ 93 | _array__splice( \ 94 | (Array *)(self), array_elem_size(self), _index, \ 95 | old_count, new_count, new_contents \ 96 | ) 97 | 98 | /// Insert one `element` into the array at the given `index`. 99 | #define array_insert(self, _index, element) \ 100 | _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element)) 101 | 102 | /// Remove one element from the array at the given `index`. 103 | #define array_erase(self, _index) \ 104 | _array__erase((Array *)(self), array_elem_size(self), _index) 105 | 106 | /// Pop the last element off the array, returning the element by value. 107 | #define array_pop(self) ((self)->contents[--(self)->size]) 108 | 109 | /// Assign the contents of one array to another, reallocating if necessary. 110 | #define array_assign(self, other) \ 111 | _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self)) 112 | 113 | /// Swap one array with another 114 | #define array_swap(self, other) \ 115 | _array__swap((Array *)(self), (Array *)(other)) 116 | 117 | /// Get the size of the array contents 118 | #define array_elem_size(self) (sizeof *(self)->contents) 119 | 120 | /// Search a sorted array for a given `needle` value, using the given `compare` 121 | /// callback to determine the order. 122 | /// 123 | /// If an existing element is found to be equal to `needle`, then the `index` 124 | /// out-parameter is set to the existing value's index, and the `exists` 125 | /// out-parameter is set to true. Otherwise, `index` is set to an index where 126 | /// `needle` should be inserted in order to preserve the sorting, and `exists` 127 | /// is set to false. 128 | #define array_search_sorted_with(self, compare, needle, _index, _exists) \ 129 | _array__search_sorted(self, 0, compare, , needle, _index, _exists) 130 | 131 | /// Search a sorted array for a given `needle` value, using integer comparisons 132 | /// of a given struct field (specified with a leading dot) to determine the order. 133 | /// 134 | /// See also `array_search_sorted_with`. 135 | #define array_search_sorted_by(self, field, needle, _index, _exists) \ 136 | _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists) 137 | 138 | /// Insert a given `value` into a sorted array, using the given `compare` 139 | /// callback to determine the order. 140 | #define array_insert_sorted_with(self, compare, value) \ 141 | do { \ 142 | unsigned _index, _exists; \ 143 | array_search_sorted_with(self, compare, &(value), &_index, &_exists); \ 144 | if (!_exists) array_insert(self, _index, value); \ 145 | } while (0) 146 | 147 | /// Insert a given `value` into a sorted array, using integer comparisons of 148 | /// a given struct field (specified with a leading dot) to determine the order. 149 | /// 150 | /// See also `array_search_sorted_by`. 151 | #define array_insert_sorted_by(self, field, value) \ 152 | do { \ 153 | unsigned _index, _exists; \ 154 | array_search_sorted_by(self, field, (value) field, &_index, &_exists); \ 155 | if (!_exists) array_insert(self, _index, value); \ 156 | } while (0) 157 | 158 | // Private 159 | 160 | typedef Array(void) Array; 161 | 162 | /// This is not what you're looking for, see `array_delete`. 163 | static inline void _array__delete(Array *self) { 164 | if (self->contents) { 165 | ts_free(self->contents); 166 | self->contents = NULL; 167 | self->size = 0; 168 | self->capacity = 0; 169 | } 170 | } 171 | 172 | /// This is not what you're looking for, see `array_erase`. 173 | static inline void _array__erase(Array *self, size_t element_size, 174 | uint32_t index) { 175 | assert(index < self->size); 176 | char *contents = (char *)self->contents; 177 | memmove(contents + index * element_size, contents + (index + 1) * element_size, 178 | (self->size - index - 1) * element_size); 179 | self->size--; 180 | } 181 | 182 | /// This is not what you're looking for, see `array_reserve`. 183 | static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) { 184 | if (new_capacity > self->capacity) { 185 | if (self->contents) { 186 | self->contents = ts_realloc(self->contents, new_capacity * element_size); 187 | } else { 188 | self->contents = ts_malloc(new_capacity * element_size); 189 | } 190 | self->capacity = new_capacity; 191 | } 192 | } 193 | 194 | /// This is not what you're looking for, see `array_assign`. 195 | static inline void _array__assign(Array *self, const Array *other, size_t element_size) { 196 | _array__reserve(self, element_size, other->size); 197 | self->size = other->size; 198 | memcpy(self->contents, other->contents, self->size * element_size); 199 | } 200 | 201 | /// This is not what you're looking for, see `array_swap`. 202 | static inline void _array__swap(Array *self, Array *other) { 203 | Array swap = *other; 204 | *other = *self; 205 | *self = swap; 206 | } 207 | 208 | /// This is not what you're looking for, see `array_push` or `array_grow_by`. 209 | static inline void _array__grow(Array *self, uint32_t count, size_t element_size) { 210 | uint32_t new_size = self->size + count; 211 | if (new_size > self->capacity) { 212 | uint32_t new_capacity = self->capacity * 2; 213 | if (new_capacity < 8) new_capacity = 8; 214 | if (new_capacity < new_size) new_capacity = new_size; 215 | _array__reserve(self, element_size, new_capacity); 216 | } 217 | } 218 | 219 | /// This is not what you're looking for, see `array_splice`. 220 | static inline void _array__splice(Array *self, size_t element_size, 221 | uint32_t index, uint32_t old_count, 222 | uint32_t new_count, const void *elements) { 223 | uint32_t new_size = self->size + new_count - old_count; 224 | uint32_t old_end = index + old_count; 225 | uint32_t new_end = index + new_count; 226 | assert(old_end <= self->size); 227 | 228 | _array__reserve(self, element_size, new_size); 229 | 230 | char *contents = (char *)self->contents; 231 | if (self->size > old_end) { 232 | memmove( 233 | contents + new_end * element_size, 234 | contents + old_end * element_size, 235 | (self->size - old_end) * element_size 236 | ); 237 | } 238 | if (new_count > 0) { 239 | if (elements) { 240 | memcpy( 241 | (contents + index * element_size), 242 | elements, 243 | new_count * element_size 244 | ); 245 | } else { 246 | memset( 247 | (contents + index * element_size), 248 | 0, 249 | new_count * element_size 250 | ); 251 | } 252 | } 253 | self->size += new_count - old_count; 254 | } 255 | 256 | /// A binary search routine, based on Rust's `std::slice::binary_search_by`. 257 | /// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`. 258 | #define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \ 259 | do { \ 260 | *(_index) = start; \ 261 | *(_exists) = false; \ 262 | uint32_t size = (self)->size - *(_index); \ 263 | if (size == 0) break; \ 264 | int comparison; \ 265 | while (size > 1) { \ 266 | uint32_t half_size = size / 2; \ 267 | uint32_t mid_index = *(_index) + half_size; \ 268 | comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \ 269 | if (comparison <= 0) *(_index) = mid_index; \ 270 | size -= half_size; \ 271 | } \ 272 | comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \ 273 | if (comparison == 0) *(_exists) = true; \ 274 | else if (comparison < 0) *(_index) += 1; \ 275 | } while (0) 276 | 277 | /// Helper macro for the `_sorted_by` routines below. This takes the left (existing) 278 | /// parameter by reference in order to work with the generic sorting function above. 279 | #define _compare_int(a, b) ((int)*(a) - (int)(b)) 280 | 281 | #ifdef _MSC_VER 282 | #pragma warning(pop) 283 | #elif defined(__GNUC__) || defined(__clang__) 284 | #pragma GCC diagnostic pop 285 | #endif 286 | 287 | #ifdef __cplusplus 288 | } 289 | #endif 290 | 291 | #endif // TREE_SITTER_ARRAY_H_ 292 | -------------------------------------------------------------------------------- /src/tree_sitter/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_PARSER_H_ 2 | #define TREE_SITTER_PARSER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ts_builtin_sym_error ((TSSymbol)-1) 13 | #define ts_builtin_sym_end 0 14 | #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 15 | 16 | #ifndef TREE_SITTER_API_H_ 17 | typedef uint16_t TSStateId; 18 | typedef uint16_t TSSymbol; 19 | typedef uint16_t TSFieldId; 20 | typedef struct TSLanguage TSLanguage; 21 | #endif 22 | 23 | typedef struct { 24 | TSFieldId field_id; 25 | uint8_t child_index; 26 | bool inherited; 27 | } TSFieldMapEntry; 28 | 29 | typedef struct { 30 | uint16_t index; 31 | uint16_t length; 32 | } TSFieldMapSlice; 33 | 34 | typedef struct { 35 | bool visible; 36 | bool named; 37 | bool supertype; 38 | } TSSymbolMetadata; 39 | 40 | typedef struct TSLexer TSLexer; 41 | 42 | struct TSLexer { 43 | int32_t lookahead; 44 | TSSymbol result_symbol; 45 | void (*advance)(TSLexer *, bool); 46 | void (*mark_end)(TSLexer *); 47 | uint32_t (*get_column)(TSLexer *); 48 | bool (*is_at_included_range_start)(const TSLexer *); 49 | bool (*eof)(const TSLexer *); 50 | void (*log)(const TSLexer *, const char *, ...); 51 | }; 52 | 53 | typedef enum { 54 | TSParseActionTypeShift, 55 | TSParseActionTypeReduce, 56 | TSParseActionTypeAccept, 57 | TSParseActionTypeRecover, 58 | } TSParseActionType; 59 | 60 | typedef union { 61 | struct { 62 | uint8_t type; 63 | TSStateId state; 64 | bool extra; 65 | bool repetition; 66 | } shift; 67 | struct { 68 | uint8_t type; 69 | uint8_t child_count; 70 | TSSymbol symbol; 71 | int16_t dynamic_precedence; 72 | uint16_t production_id; 73 | } reduce; 74 | uint8_t type; 75 | } TSParseAction; 76 | 77 | typedef struct { 78 | uint16_t lex_state; 79 | uint16_t external_lex_state; 80 | } TSLexMode; 81 | 82 | typedef union { 83 | TSParseAction action; 84 | struct { 85 | uint8_t count; 86 | bool reusable; 87 | } entry; 88 | } TSParseActionEntry; 89 | 90 | typedef struct { 91 | int32_t start; 92 | int32_t end; 93 | } TSCharacterRange; 94 | 95 | struct TSLanguage { 96 | uint32_t version; 97 | uint32_t symbol_count; 98 | uint32_t alias_count; 99 | uint32_t token_count; 100 | uint32_t external_token_count; 101 | uint32_t state_count; 102 | uint32_t large_state_count; 103 | uint32_t production_id_count; 104 | uint32_t field_count; 105 | uint16_t max_alias_sequence_length; 106 | const uint16_t *parse_table; 107 | const uint16_t *small_parse_table; 108 | const uint32_t *small_parse_table_map; 109 | const TSParseActionEntry *parse_actions; 110 | const char * const *symbol_names; 111 | const char * const *field_names; 112 | const TSFieldMapSlice *field_map_slices; 113 | const TSFieldMapEntry *field_map_entries; 114 | const TSSymbolMetadata *symbol_metadata; 115 | const TSSymbol *public_symbol_map; 116 | const uint16_t *alias_map; 117 | const TSSymbol *alias_sequences; 118 | const TSLexMode *lex_modes; 119 | bool (*lex_fn)(TSLexer *, TSStateId); 120 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 121 | TSSymbol keyword_capture_token; 122 | struct { 123 | const bool *states; 124 | const TSSymbol *symbol_map; 125 | void *(*create)(void); 126 | void (*destroy)(void *); 127 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 128 | unsigned (*serialize)(void *, char *); 129 | void (*deserialize)(void *, const char *, unsigned); 130 | } external_scanner; 131 | const TSStateId *primary_state_ids; 132 | }; 133 | 134 | static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { 135 | uint32_t index = 0; 136 | uint32_t size = len - index; 137 | while (size > 1) { 138 | uint32_t half_size = size / 2; 139 | uint32_t mid_index = index + half_size; 140 | TSCharacterRange *range = &ranges[mid_index]; 141 | if (lookahead >= range->start && lookahead <= range->end) { 142 | return true; 143 | } else if (lookahead > range->end) { 144 | index = mid_index; 145 | } 146 | size -= half_size; 147 | } 148 | TSCharacterRange *range = &ranges[index]; 149 | return (lookahead >= range->start && lookahead <= range->end); 150 | } 151 | 152 | /* 153 | * Lexer Macros 154 | */ 155 | 156 | #ifdef _MSC_VER 157 | #define UNUSED __pragma(warning(suppress : 4101)) 158 | #else 159 | #define UNUSED __attribute__((unused)) 160 | #endif 161 | 162 | #define START_LEXER() \ 163 | bool result = false; \ 164 | bool skip = false; \ 165 | UNUSED \ 166 | bool eof = false; \ 167 | int32_t lookahead; \ 168 | goto start; \ 169 | next_state: \ 170 | lexer->advance(lexer, skip); \ 171 | start: \ 172 | skip = false; \ 173 | lookahead = lexer->lookahead; 174 | 175 | #define ADVANCE(state_value) \ 176 | { \ 177 | state = state_value; \ 178 | goto next_state; \ 179 | } 180 | 181 | #define ADVANCE_MAP(...) \ 182 | { \ 183 | static const uint16_t map[] = { __VA_ARGS__ }; \ 184 | for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \ 185 | if (map[i] == lookahead) { \ 186 | state = map[i + 1]; \ 187 | goto next_state; \ 188 | } \ 189 | } \ 190 | } 191 | 192 | #define SKIP(state_value) \ 193 | { \ 194 | skip = true; \ 195 | state = state_value; \ 196 | goto next_state; \ 197 | } 198 | 199 | #define ACCEPT_TOKEN(symbol_value) \ 200 | result = true; \ 201 | lexer->result_symbol = symbol_value; \ 202 | lexer->mark_end(lexer); 203 | 204 | #define END_STATE() return result; 205 | 206 | /* 207 | * Parse Table Macros 208 | */ 209 | 210 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 211 | 212 | #define STATE(id) id 213 | 214 | #define ACTIONS(id) id 215 | 216 | #define SHIFT(state_value) \ 217 | {{ \ 218 | .shift = { \ 219 | .type = TSParseActionTypeShift, \ 220 | .state = (state_value) \ 221 | } \ 222 | }} 223 | 224 | #define SHIFT_REPEAT(state_value) \ 225 | {{ \ 226 | .shift = { \ 227 | .type = TSParseActionTypeShift, \ 228 | .state = (state_value), \ 229 | .repetition = true \ 230 | } \ 231 | }} 232 | 233 | #define SHIFT_EXTRA() \ 234 | {{ \ 235 | .shift = { \ 236 | .type = TSParseActionTypeShift, \ 237 | .extra = true \ 238 | } \ 239 | }} 240 | 241 | #define REDUCE(symbol_name, children, precedence, prod_id) \ 242 | {{ \ 243 | .reduce = { \ 244 | .type = TSParseActionTypeReduce, \ 245 | .symbol = symbol_name, \ 246 | .child_count = children, \ 247 | .dynamic_precedence = precedence, \ 248 | .production_id = prod_id \ 249 | }, \ 250 | }} 251 | 252 | #define RECOVER() \ 253 | {{ \ 254 | .type = TSParseActionTypeRecover \ 255 | }} 256 | 257 | #define ACCEPT_INPUT() \ 258 | {{ \ 259 | .type = TSParseActionTypeAccept \ 260 | }} 261 | 262 | #ifdef __cplusplus 263 | } 264 | #endif 265 | 266 | #endif // TREE_SITTER_PARSER_H_ 267 | -------------------------------------------------------------------------------- /test/corpus/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [syntax.txt] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = false 8 | 9 | [syntax_clrf.txt] 10 | charset = utf-8 11 | end_of_line = crlf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /test/corpus/syntax_crlf.txt: -------------------------------------------------------------------------------- 1 | =============================================================================== 2 | Paragraph: two 3 | =============================================================================== 4 | First 5 | 6 | Second 7 | 8 | ------------------------------------------------------------------------------- 9 | 10 | (document 11 | (paragraph) 12 | (paragraph)) 13 | 14 | =============================================================================== 15 | Paragraph: two multiline 16 | =============================================================================== 17 | In 18 | First 19 | 20 | In 21 | Second 22 | 23 | ------------------------------------------------------------------------------- 24 | 25 | (document 26 | (paragraph) 27 | (paragraph)) 28 | 29 | =============================================================================== 30 | Heading: multiple lines 31 | =============================================================================== 32 | # Heading 33 | # with 34 | # lines 35 | 36 | A paragraph 37 | 38 | ------------------------------------------------------------------------------- 39 | 40 | (document 41 | (section 42 | (heading 43 | (marker) 44 | (content 45 | (marker) 46 | (marker))) 47 | (section_content (paragraph)))) 48 | 49 | =============================================================================== 50 | Heading: multiple lines no # prefix 51 | =============================================================================== 52 | # Heading 53 | with 54 | lines 55 | 56 | A paragraph 57 | 58 | ------------------------------------------------------------------------------- 59 | 60 | (document 61 | (section 62 | (heading 63 | (marker) 64 | (content 65 | (marker) 66 | (marker))) 67 | (section_content (paragraph)))) 68 | 69 | =============================================================================== 70 | Heading: closed by higher heading on the next line 71 | =============================================================================== 72 | # One 73 | ## Two 74 | 75 | ------------------------------------------------------------------------------- 76 | 77 | (document 78 | (section 79 | (heading 80 | (marker) 81 | (content)) 82 | (section_content 83 | (section 84 | (heading 85 | (marker) 86 | (content)))))) 87 | 88 | =============================================================================== 89 | Heading: closed by lower heading on the next line 90 | =============================================================================== 91 | ## One 92 | # Two 93 | 94 | ------------------------------------------------------------------------------- 95 | 96 | (document 97 | (section 98 | (heading 99 | (marker) 100 | (content))) 101 | (section 102 | (heading 103 | (marker) 104 | (content)))) 105 | 106 | =============================================================================== 107 | Heading 4: div closes 108 | =============================================================================== 109 | ::: 110 | #### Heading 111 | ::: 112 | 113 | stop 114 | 115 | ------------------------------------------------------------------------------- 116 | 117 | (document 118 | (div 119 | (div_marker_begin) 120 | (content 121 | (heading (marker) (content))) 122 | (div_marker_end)) 123 | (paragraph)) 124 | 125 | =============================================================================== 126 | Heading 6: list closes 127 | =============================================================================== 128 | ###### Heading 129 | - a 130 | 131 | ------------------------------------------------------------------------------- 132 | 133 | (document 134 | (section 135 | (heading (marker) (content)) 136 | (section_content 137 | (list 138 | (list_item 139 | (list_marker_dash) 140 | (list_item_content (paragraph))))))) 141 | 142 | =============================================================================== 143 | Block quote: long 144 | =============================================================================== 145 | > This is a block quote. 146 | > 147 | > This is included 148 | 149 | ------------------------------------------------------------------------------- 150 | 151 | (document 152 | (block_quote 153 | (block_quote_marker) 154 | (content 155 | (paragraph) 156 | (block_quote_marker) 157 | (block_quote_marker) 158 | (paragraph)))) 159 | 160 | =============================================================================== 161 | Block quote: with hard line break 162 | =============================================================================== 163 | > a \ 164 | > b 165 | 166 | ------------------------------------------------------------------------------- 167 | 168 | (document 169 | (block_quote 170 | (block_quote_marker) 171 | (content 172 | (paragraph 173 | (hard_line_break) 174 | (block_quote_marker))))) 175 | 176 | =============================================================================== 177 | Code block: empty 178 | =============================================================================== 179 | ``` 180 | ``` 181 | 182 | ------------------------------------------------------------------------------- 183 | 184 | (document 185 | (code_block 186 | (code_block_marker_begin) 187 | (code_block_marker_end))) 188 | 189 | =============================================================================== 190 | Block attribute: key value spaces 191 | =============================================================================== 192 | {author="with spaces"} 193 | Paragraph 194 | 195 | ------------------------------------------------------------------------------- 196 | 197 | (document 198 | (block_attribute 199 | (args 200 | (key_value 201 | (key) 202 | (value)))) 203 | (paragraph)) 204 | 205 | =============================================================================== 206 | Inline attribute: with newlines 207 | =============================================================================== 208 | text{.one 209 | .two 210 | #three} 211 | 212 | ------------------------------------------------------------------------------- 213 | 214 | (document 215 | (paragraph 216 | (inline_attribute 217 | (args 218 | (class) 219 | (class) 220 | (identifier))))) 221 | 222 | =============================================================================== 223 | Hard line break 224 | =============================================================================== 225 | With \ 226 | break 227 | 228 | ------------------------------------------------------------------------------- 229 | 230 | (document 231 | (paragraph 232 | (hard_line_break))) 233 | 234 | =============================================================================== 235 | Div: end paragraph inside 236 | =============================================================================== 237 | ::: 238 | Inside 239 | ::: 240 | 241 | ------------------------------------------------------------------------------- 242 | 243 | (document 244 | (div 245 | (div_marker_begin) 246 | (content 247 | (paragraph)) 248 | (div_marker_end))) 249 | 250 | =============================================================================== 251 | Verbatim: newline closes 252 | =============================================================================== 253 | `verbatim 254 | 255 | ------------------------------------------------------------------------------- 256 | 257 | (document 258 | (paragraph 259 | (verbatim 260 | (verbatim_marker_begin) 261 | (content) 262 | (verbatim_marker_end)))) 263 | 264 | =============================================================================== 265 | List: tight dashes 266 | =============================================================================== 267 | - a 268 | - b 269 | - c 270 | 271 | ------------------------------------------------------------------------------- 272 | 273 | (document 274 | (list 275 | (list_item 276 | (list_marker_dash) 277 | (list_item_content (paragraph))) 278 | (list_item 279 | (list_marker_dash) 280 | (list_item_content (paragraph))) 281 | (list_item 282 | (list_marker_dash) 283 | (list_item_content (paragraph))))) 284 | 285 | =============================================================================== 286 | List: Close sublist 287 | =============================================================================== 288 | - a 289 | 290 | - b 291 | 292 | - c 293 | 294 | ------------------------------------------------------------------------------- 295 | 296 | (document 297 | (list 298 | (list_item 299 | (list_marker_dash) 300 | (list_item_content 301 | (paragraph) 302 | (list 303 | (list_item 304 | (list_marker_dash) 305 | (list_item_content 306 | (paragraph)))))) 307 | (list_item 308 | (list_marker_dash) 309 | (list_item_content (paragraph))))) 310 | 311 | =============================================================================== 312 | List: Continue paragraph with soft break 313 | =============================================================================== 314 | - First 315 | Second 316 | 317 | ------------------------------------------------------------------------------- 318 | 319 | (document 320 | (list 321 | (list_item 322 | (list_marker_dash) 323 | (list_item_content (paragraph))))) 324 | 325 | =============================================================================== 326 | List: Immediate blockquote 327 | =============================================================================== 328 | - > a 329 | > b 330 | 331 | ------------------------------------------------------------------------------- 332 | 333 | (document 334 | (list 335 | (list_item 336 | (list_marker_dash) 337 | (list_item_content 338 | (block_quote 339 | (block_quote_marker) 340 | (content 341 | (paragraph 342 | (block_quote_marker)))))))) 343 | 344 | =============================================================================== 345 | Table: inside blockquote 346 | =============================================================================== 347 | > | x|y| 348 | > |--|--:| 349 | > | a | b | 350 | 351 | ------------------------------------------------------------------------------- 352 | 353 | (document 354 | (block_quote 355 | (block_quote_marker) 356 | (content 357 | (table 358 | (table_header 359 | (table_cell) 360 | (table_cell)) 361 | (block_quote_marker) 362 | (table_separator 363 | (table_cell_alignment) 364 | (table_cell_alignment)) 365 | (block_quote_marker) 366 | (table_row 367 | (table_cell) 368 | (table_cell)))))) 369 | 370 | -------------------------------------------------------------------------------- /tree-sitter.json: -------------------------------------------------------------------------------- 1 | { 2 | "grammars": [ 3 | { 4 | "name": "djot", 5 | "camelcase": "Djot", 6 | "scope": "text.djot", 7 | "path": ".", 8 | "file-types": ["dj"], 9 | "highlights": ["queries/highlights.scm"], 10 | "injection-regex": "djot" 11 | } 12 | ], 13 | "metadata": { 14 | "version": "2.0.0", 15 | "license": "MIT", 16 | "description": "Djot grammar for tree-sitter", 17 | "links": { 18 | "repository": "https://github.com/treeman/tree-sitter-djot" 19 | } 20 | }, 21 | "bindings": { 22 | "c": true, 23 | "go": true, 24 | "node": true, 25 | "python": true, 26 | "rust": true, 27 | "swift": true 28 | } 29 | } 30 | --------------------------------------------------------------------------------