Add 'vendored_parsers/tree-sitter-latex/' from commit 'cd3cc493a92b6bac7be4b3bd6d006d35d3c36d4c'

git-subtree-dir: vendored_parsers/tree-sitter-latex
git-subtree-mainline: 2934c08d07
git-subtree-split: cd3cc493a9
pull/511/head
Mike Grunweg 2023-05-05 13:40:46 +07:00
commit 8bdfb1d1dc
39 changed files with 670138 additions and 0 deletions

@ -0,0 +1,5 @@
---
BasedOnStyle: LLVM
IndentWidth: 2
---

@ -0,0 +1,2 @@
/src/** linguist-vendored
/examples/* linguist-vendored

@ -0,0 +1,17 @@
version: 2
updates:
- package-ecosystem: cargo
directory: '/'
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: npm
directory: '/'
schedule:
interval: daily
open-pull-requests-limit: 10
- package-ecosystem: github-actions
directory: '/'
schedule:
interval: daily
open-pull-requests-limit: 10

@ -0,0 +1,55 @@
name: CI
on:
push:
branches: [master]
pull_request:
env:
CARGO_INCREMENTAL: 0
CI: 1
RUST_BACKTRACE: short
RUSTFLAGS: '-D warnings'
RUSTUP_MAX_RETRIES: 10
jobs:
binding_node:
name: Node
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v3
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- run: npm install
- run: npm test
binding_rust:
name: Rust
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- name: Cache Dependencies
uses: Swatinem/rust-cache@v2
- name: Compile
run: cargo test --no-run
- name: Test
run: cargo test -- --nocapture --quiet
binding_c:
name: C
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v3
- run: make
- run: sudo make install

@ -0,0 +1,248 @@
# Created by https://www.toptal.com/developers/gitignore/api/c,c++,node,visualstudiocode,rust
# Edit at https://www.toptal.com/developers/gitignore?templates=c,c++,node,visualstudiocode,rust
### C ###
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
### C++ ###
# Prerequisites
# Compiled Object files
*.slo
# Precompiled Headers
# Compiled Dynamic libraries
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
# Executables
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
.env.production
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
### Node Patch ###
# Serverless Webpack directories
.webpack/
# Optional stylelint cache
.stylelintcache
# SvelteKit build / generate output
.svelte-kit
### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
# Support for Project snippet scope
!.vscode/*.code-snippets
# End of https://www.toptal.com/developers/gitignore/api/c,c++,node,visualstudiocode,rust
build/
/bindings/c/*.h
/bindings/c/tree-sitter-*.pc
# Swift Package Manager
.build/

@ -0,0 +1,4 @@
{
"singleQuote": true,
"arrowParens": "avoid"
}

@ -0,0 +1,43 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Add support for definition commands found in `xparse` package ([#82](https://github.com/latex-lsp/tree-sitter-latex/issues/82))
- Add rules for parsing subscript and superscript expressions ([#63](https://github.com/latex-lsp/tree-sitter-latex/pull/63))
- Add Swift package description ([#76](https://github.com/latex-lsp/tree-sitter-latex/pull/76))
### Fixed
- Parse `pycode` environments correctly ([#67](https://github.com/latex-lsp/tree-sitter-latex/pull/67), [#66](https://github.com/latex-lsp/tree-sitter-latex/issues/66))
## [0.3.0] - 2022-10-26
### Added
- Extend list of supported `\big` style commands
### Changed
- Do not associate bracket groups with commands by default ([#51](https://github.com/latex-lsp/tree-sitter-latex/pull/51), [#48](https://github.com/latex-lsp/tree-sitter-latex/issues/48))
## [0.2.1] - 2022-10-25
### Added
- Add `Makefile` for easier usage of `C` bindings ([#54](https://github.com/latex-lsp/tree-sitter-latex/pull/54))
### Changed
- Update to ABI version 14
### Fixed
- Allow `\big`, `\bigl` and `\bigr` commands in addition to `\left` and `\right` ([#58](https://github.com/latex-lsp/tree-sitter-latex/issues/58))
- Allow options when using `minted` environment ([#55](https://github.com/latex-lsp/tree-sitter-latex/issues/55))

@ -0,0 +1,31 @@
[package]
name = "tree-sitter-latex"
description = "latex grammar for the tree-sitter parsing library"
version = "0.3.0"
keywords = ["incremental", "parsing", "latex"]
categories = ["parsing", "text-editors"]
repository = "https://github.com/latex-lsp/tree-sitter-latex"
edition = "2018"
license = "MIT"
authors = ["Patrick Förster <patrick.foerster@outlook.de>"]
readme = "README.md"
build = "bindings/rust/build.rs"
include = ["bindings/rust/*", "grammar.js", "queries/*", "src/*"]
[lib]
path = "bindings/rust/lib.rs"
[dependencies]
tree-sitter = "~0.20.9"
[build-dependencies]
cc = "1.0"
[dev-dependencies]
criterion = "0.4.0"
[[bench]]
name = "bench_main"
path = "benches/bench_main.rs"
harness = false

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Patrick Förster
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,114 @@
VERSION := 0.3.0
# Repository
SRC_DIR := src
PARSER_REPO_URL := $(shell git -C $(SRC_DIR) remote get-url origin )
ifeq (, $(PARSER_NAME))
PARSER_NAME := $(shell basename $(PARSER_REPO_URL))
PARSER_NAME := $(subst tree-sitter-,,$(PARSER_NAME))
PARSER_NAME := $(subst .git,,$(PARSER_NAME))
endif
ifeq (, $(PARSER_URL))
PARSER_URL := $(subst :,/,$(PARSER_REPO_URL))
PARSER_URL := $(subst git@,https://,$(PARSER_URL))
PARSER_URL := $(subst .git,,$(PARSER_URL))
endif
UPPER_PARSER_NAME := $(shell echo $(PARSER_NAME) | tr a-z A-Z )
# install directory layout
PREFIX ?= /usr/local
INCLUDEDIR ?= $(PREFIX)/include
LIBDIR ?= $(PREFIX)/lib
PCLIBDIR ?= $(LIBDIR)/pkgconfig
# collect C++ sources, and link if necessary
CPPSRC := $(wildcard $(SRC_DIR)/*.cc)
ifeq (, $(CPPSRC))
ADDITIONALLIBS :=
else
ADDITIONALLIBS := -lc++
endif
# collect sources
SRC := $(wildcard $(SRC_DIR)/*.c)
SRC += $(CPPSRC)
OBJ := $(addsuffix .o,$(basename $(SRC)))
# ABI versioning
SONAME_MAJOR := 0
SONAME_MINOR := 0
CFLAGS ?= -O3 -Wall -Wextra -I$(SRC_DIR)
CXXFLAGS ?= -O3 -Wall -Wextra -I$(SRC_DIR)
override CFLAGS += -std=gnu99 -fPIC
override CXXFLAGS += -fPIC
# OS-specific bits
ifeq ($(shell uname),Darwin)
SOEXT = dylib
SOEXTVER_MAJOR = $(SONAME_MAJOR).dylib
SOEXTVER = $(SONAME_MAJOR).$(SONAME_MINOR).dylib
LINKSHARED := $(LINKSHARED)-dynamiclib -Wl,
ifneq ($(ADDITIONALLIBS),)
LINKSHARED := $(LINKSHARED)$(ADDITIONALLIBS),
endif
LINKSHARED := $(LINKSHARED)-install_name,$(LIBDIR)/libtree-sitter-$(PARSER_NAME).$(SONAME_MAJOR).dylib,-rpath,@executable_path/../Frameworks
else
SOEXT = so
SOEXTVER_MAJOR = so.$(SONAME_MAJOR)
SOEXTVER = so.$(SONAME_MAJOR).$(SONAME_MINOR)
LINKSHARED := $(LINKSHARED)-shared -Wl,
ifneq ($(ADDITIONALLIBS),)
LINKSHARED := $(LINKSHARED)$(ADDITIONALLIBS),
endif
LINKSHARED := $(LINKSHARED)-soname,libtree-sitter-$(PARSER_NAME).so.$(SONAME_MAJOR)
endif
ifneq (,$(filter $(shell uname),FreeBSD NetBSD DragonFly))
PCLIBDIR := $(PREFIX)/libdata/pkgconfig
endif
all: libtree-sitter-$(PARSER_NAME).a libtree-sitter-$(PARSER_NAME).$(SOEXTVER) bindings/c/$(PARSER_NAME).h bindings/c/tree-sitter-$(PARSER_NAME).pc
libtree-sitter-$(PARSER_NAME).a: $(OBJ)
$(AR) rcs $@ $^
libtree-sitter-$(PARSER_NAME).$(SOEXTVER): $(OBJ)
$(CC) $(LDFLAGS) $(LINKSHARED) $^ $(LDLIBS) -o $@
ln -sf $@ libtree-sitter-$(PARSER_NAME).$(SOEXT)
ln -sf $@ libtree-sitter-$(PARSER_NAME).$(SOEXTVER_MAJOR)
bindings/c/$(PARSER_NAME).h:
sed -e 's|@UPPER_PARSERNAME@|$(UPPER_PARSER_NAME)|' \
-e 's|@PARSERNAME@|$(PARSER_NAME)|' \
bindings/c/tree-sitter.h.in > $@
bindings/c/tree-sitter-$(PARSER_NAME).pc:
sed -e 's|@LIBDIR@|$(LIBDIR)|;s|@INCLUDEDIR@|$(INCLUDEDIR)|;s|@VERSION@|$(VERSION)|' \
-e 's|=$(PREFIX)|=$${prefix}|' \
-e 's|@PREFIX@|$(PREFIX)|' \
-e 's|@ADDITIONALLIBS@|$(ADDITIONALLIBS)|' \
-e 's|@PARSERNAME@|$(PARSER_NAME)|' \
-e 's|@PARSERURL@|$(PARSER_URL)|' \
bindings/c/tree-sitter.pc.in > $@
install: all
install -d '$(DESTDIR)$(LIBDIR)'
install -m755 libtree-sitter-$(PARSER_NAME).a '$(DESTDIR)$(LIBDIR)'/libtree-sitter-$(PARSER_NAME).a
install -m755 libtree-sitter-$(PARSER_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/libtree-sitter-$(PARSER_NAME).$(SOEXTVER)
ln -sf libtree-sitter-$(PARSER_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/libtree-sitter-$(PARSER_NAME).$(SOEXTVER_MAJOR)
ln -sf libtree-sitter-$(PARSER_NAME).$(SOEXTVER) '$(DESTDIR)$(LIBDIR)'/libtree-sitter-$(PARSER_NAME).$(SOEXT)
install -d '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter
install -m644 bindings/c/$(PARSER_NAME).h '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter/
install -d '$(DESTDIR)$(PCLIBDIR)'
install -m644 bindings/c/tree-sitter-$(PARSER_NAME).pc '$(DESTDIR)$(PCLIBDIR)'/
clean:
rm -f $(OBJ) libtree-sitter-$(PARSER_NAME).a libtree-sitter-$(PARSER_NAME).$(SOEXT) libtree-sitter-$(PARSER_NAME).$(SOEXTVER_MAJOR) libtree-sitter-$(PARSER_NAME).$(SOEXTVER)
rm -f bindings/c/$(PARSER_NAME).h bindings/c/tree-sitter-$(PARSER_NAME).pc
.PHONY: all install clean

@ -0,0 +1,36 @@
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "TreeSitterLatex",
products: [
.library(name: "TreeSitterLatex", targets: ["TreeSitterLatex"]),
],
dependencies: [],
targets: [
.target(name: "TreeSitterLatex",
path: ".",
exclude: [
"binding.gyp",
"bindings",
"benches",
".github",
"examples",
"Cargo.toml",
"test",
"grammar.js",
"LICENSE",
"Makefile",
"package.json",
"README.md",
"src/grammar.json",
"src/node-types.json",
],
sources: [
"src/parser.c",
"src/scanner.c",
],
publicHeadersPath: "bindings/swift",
cSettings: [.headerSearchPath("src")])
]
)

@ -0,0 +1,14 @@
# tree-sitter-latex
[![CI](https://github.com/latex-lsp/tree-sitter-latex/workflows/CI/badge.svg)](https://github.com/latex-lsp/tree-sitter-latex/actions)
[![npm](https://img.shields.io/npm/v/@pfoerster/tree-sitter-latex)](https://www.npmjs.com/package/@pfoerster/tree-sitter-latex)
This repo provides a [LaTeX](https://www.latex-project.org/) grammar for the [tree-sitter](https://github.com/tree-sitter/tree-sitter) parser generator.
Originally, this grammar is based off the parser of the [`texlab`](https://github.com/latex-lsp/texlab) language server and primarily focuses on the constructs that are relevant for the language server.
This repository does not provide the accompanying highlighting definitions, instead they live in the [`nvim-treesitter`](https://github.com/nvim-treesitter/nvim-treesitter/tree/master/queries/latex) repository.
## Limitations
As widely known, parsing LaTeX is Turing complete so there is no way to handle every construct in a `tree-sitter` grammar. Instead, the grammar relies on a best effort approach while focusing on the LaTeX specific constructs like environments or sections instead of dealing with TeX internals like catcode.

@ -0,0 +1,34 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
static CODE: &str = include_str!(r#"../examples/texlab.tex"#);
fn criterion_benchmark(c: &mut Criterion) {
let mut parser = tree_sitter::Parser::new();
parser.set_language(tree_sitter_latex::language()).unwrap();
c.bench_function("Full", |b| {
b.iter_with_large_drop(|| parser.parse(black_box(CODE), None).unwrap());
});
let tree = parser.parse(black_box(CODE), None).unwrap();
c.bench_function("Incremental", |b| {
b.iter_with_large_drop(|| {
let mut old_tree = tree.clone();
old_tree.edit(&tree_sitter::InputEdit {
start_byte: 0,
old_end_byte: 1,
new_end_byte: 0,
start_position: tree_sitter::Point { row: 0, column: 0 },
old_end_position: tree_sitter::Point { row: 0, column: 1 },
new_end_position: tree_sitter::Point { row: 0, column: 0 },
});
parser
.parse(black_box(&CODE[1..]), Some(&old_tree))
.unwrap()
});
});
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

@ -0,0 +1,19 @@
{
"targets": [
{
"target_name": "tree_sitter_latex_binding",
"include_dirs": [
"<!(node -e \"require('nan')\")",
"src"
],
"sources": [
"bindings/node/binding.cc",
"src/parser.c",
"src/scanner.c"
],
"cflags_c": [
"-std=c99",
]
}
]
}

@ -0,0 +1,16 @@
#ifndef TREE_SITTER_@UPPER_PARSERNAME@_H_
#define TREE_SITTER_@UPPER_PARSERNAME@_H_
#include <tree_sitter/parser.h>
#ifdef __cplusplus
extern "C" {
#endif
extern TSLanguage *tree_sitter_@PARSERNAME@();
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_@UPPER_PARSERNAME@_H_

@ -0,0 +1,11 @@
prefix=@PREFIX@
libdir=@LIBDIR@
includedir=@INCLUDEDIR@
additionallibs=@ADDITIONALLIBS@
Name: tree-sitter-@PARSERNAME@
Description: A tree-sitter grammar for the @PARSERNAME@ programming language.
URL: @PARSERURL@
Version: @VERSION@
Libs: -L${libdir} ${additionallibs} -ltree-sitter-@PARSERNAME@
Cflags: -I${includedir}

@ -0,0 +1,28 @@
#include "tree_sitter/parser.h"
#include <node.h>
#include "nan.h"
using namespace v8;
extern "C" TSLanguage * tree_sitter_latex();
namespace {
NAN_METHOD(New) {}
void Init(Local<Object> exports, Local<Object> module) {
Local<FunctionTemplate> tpl = Nan::New<FunctionTemplate>(New);
tpl->SetClassName(Nan::New("Language").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1);
Local<Function> constructor = Nan::GetFunction(tpl).ToLocalChecked();
Local<Object> instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked();
Nan::SetInternalFieldPointer(instance, 0, tree_sitter_latex());
Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("latex").ToLocalChecked());
Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance);
}
NODE_MODULE(tree_sitter_latex_binding, Init)
} // namespace

@ -0,0 +1,19 @@
try {
module.exports = require("../../build/Release/tree_sitter_latex_binding");
} catch (error1) {
if (error1.code !== 'MODULE_NOT_FOUND') {
throw error1;
}
try {
module.exports = require("../../build/Debug/tree_sitter_latex_binding");
} catch (error2) {
if (error2.code !== 'MODULE_NOT_FOUND') {
throw error2;
}
throw error1
}
}
try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
} catch (_) {}

@ -0,0 +1,38 @@
fn main() {
let src_dir = std::path::Path::new("src");
let mut c_config = cc::Build::new();
c_config.include(&src_dir);
c_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable")
.flag_if_supported("-Wno-trigraphs");
let parser_path = src_dir.join("parser.c");
c_config.file(&parser_path);
// If your language uses an external scanner written in C,
// then include this block of code:
let scanner_path = src_dir.join("scanner.c");
c_config.file(&scanner_path);
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
c_config.compile("tree-sitter-latex");
println!("cargo:rerun-if-changed={}", parser_path.to_str().unwrap());
// If your language uses an external scanner written in C++,
// then include this block of code:
/*
let mut cpp_config = cc::Build::new();
cpp_config.cpp(true);
cpp_config.include(&src_dir);
cpp_config
.flag_if_supported("-Wno-unused-parameter")
.flag_if_supported("-Wno-unused-but-set-variable");
let scanner_path = src_dir.join("scanner.cc");
cpp_config.file(&scanner_path);
cpp_config.compile("scanner");
println!("cargo:rerun-if-changed={}", scanner_path.to_str().unwrap());
*/
}

@ -0,0 +1,52 @@
//! This crate provides latex language support for the [tree-sitter][] parsing library.
//!
//! Typically, you will use the [language][language func] function to add this language to a
//! tree-sitter [Parser][], and then use the parser to parse some code:
//!
//! ```
//! let code = "";
//! let mut parser = tree_sitter::Parser::new();
//! parser.set_language(tree_sitter_latex::language()).expect("Error loading latex grammar");
//! let tree = parser.parse(code, None).unwrap();
//! ```
//!
//! [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
//! [language func]: fn.language.html
//! [Parser]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Parser.html
//! [tree-sitter]: https://tree-sitter.github.io/
use tree_sitter::Language;
extern "C" {
fn tree_sitter_latex() -> Language;
}
/// Get the tree-sitter [Language][] for this grammar.
///
/// [Language]: https://docs.rs/tree-sitter/*/tree_sitter/struct.Language.html
pub fn language() -> Language {
unsafe { tree_sitter_latex() }
}
/// The content of the [`node-types.json`][] file for this grammar.
///
/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
pub const NODE_TYPES: &str = include_str!("../../src/node-types.json");
// Uncomment these to include any queries that this grammar contains
// pub const HIGHLIGHTS_QUERY: &'static str = include_str!("../../queries/highlights.scm");
// pub const INJECTIONS_QUERY: &'static str = include_str!("../../queries/injections.scm");
// pub const LOCALS_QUERY: &'static str = include_str!("../../queries/locals.scm");
// pub const TAGS_QUERY: &'static str = include_str!("../../queries/tags.scm");
#[cfg(test)]
mod tests {
#[test]
fn test_can_load_grammar() {
let mut parser = tree_sitter::Parser::new();
parser
.set_language(super::language())
.expect("Error loading latex language");
}
}

@ -0,0 +1,16 @@
#ifndef TREE_SITTER_LATEX_H_
#define TREE_SITTER_LATEX_H_
typedef struct TSLanguage TSLanguage;
#ifdef __cplusplus
extern "C" {
#endif
extern TSLanguage *tree_sitter_latex();
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_LATEX_H_

@ -0,0 +1,78 @@
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{hyperref}
\date{\today}
\author{Eric Förster \and Patrick Förster}
\title{\TeX{}Lab}
\begin{document}
\maketitle{}
\section{Introduction}
TexLab is a cross-platform implementation of the
\href{https://microsoft.github.io/language-server-protocol/specifications/specification-current/}{Language Server Protocol}
for the \LaTeX{} typesetting system.
It aims to produce high quality code completion results.
The server may be used with any editor that implements the Language Server Protocol.
It is written in Rust, a blazingly fast systems programming language.
\section{Features}
The language server implements most of the Language Server Protocol specification.
In addition to that, it implements additional functionality like
building and forward search.
\section{Availability}
TexLab is available on \href{https://github.com/latex-lsp/texlab}{GitHub},
various package managers and CTAN\@.
Pre-compiled binaries are available on the
\href{https://github.com/latex-lsp/texlab/releases}{GitHub Releases} page.
Some editor extensions are able to automatically download TexLab.
\section{Installation}
There are various ways to install TexLab:
\begin{itemize}
\item
TexLab is included in some package managers like \texttt{brew},
\texttt{pacman} and \texttt{scoop}.
Please refer to the badges in the README to see if your package manager
includes TexLab.
\item
You can download a pre-compiled binary from our
\href{https://github.com/latex-lsp/texlab/releases}{GitHub Releases} page.
\item
Some extensions like the Visual Studio Code extension or
\texttt{coc-texlab} can automatically download the server for you.
\item
You can download the sources from either GitHub or CTAN
and compile the server with \texttt{cargo build --release}.
The \texttt{texlab} binary can be found inside \texttt{target/release}.
\end{itemize}
\section{Usage}
\subsection{Synopsis}
\texttt{texlab [FLAGS] [OPTIONS]}
\subsection{Flags}
\begin{itemize}
\item \texttt{-h}, \texttt{--help} Prints help information
\item \texttt{-q}, \texttt{--quiet} No output printed to stderr
\item \texttt{-V}, \texttt{--version} Prints version information
\item \texttt{-v}, \texttt{--verbosity} Increase message verbosity (\texttt{-vvvv} for max verbosity)
\end{itemize}
\subsection{Options}
\begin{itemize}
\item \texttt{--log-file <FILE>} WRite the logging output to \texttt{FILE}
\end{itemize}
\end{document}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,69 @@
{
"name": "@pfoerster/tree-sitter-latex",
"version": "0.3.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@pfoerster/tree-sitter-latex",
"version": "0.3.0",
"license": "MIT",
"dependencies": {
"nan": "^2.16.0"
},
"devDependencies": {
"prettier": "^2.6.2",
"tree-sitter-cli": "^0.20.8"
}
},
"node_modules/nan": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
},
"node_modules/prettier": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz",
"integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/tree-sitter-cli": {
"version": "0.20.8",
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz",
"integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==",
"dev": true,
"hasInstallScript": true,
"bin": {
"tree-sitter": "cli.js"
}
}
},
"dependencies": {
"nan": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
},
"prettier": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz",
"integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==",
"dev": true
},
"tree-sitter-cli": {
"version": "0.20.8",
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.20.8.tgz",
"integrity": "sha512-XjTcS3wdTy/2cc/ptMLc/WRyOLECRYcMTrSWyhZnj1oGSOWbHLTklgsgRICU3cPfb0vy+oZCC33M43u6R1HSCA==",
"dev": true
}
}
}

@ -0,0 +1,44 @@
{
"name": "@pfoerster/tree-sitter-latex",
"version": "0.3.0",
"description": "LaTeX grammar for the tree-sitter parsing library",
"main": "bindings/node",
"scripts": {
"generate": "tree-sitter generate",
"test": "tree-sitter test",
"test:update": "tree-sitter test --update"
},
"repository": {
"type": "git",
"url": "git+https://github.com/latex-lsp/tree-sitter-latex.git"
},
"keywords": [
"tree-sitter",
"latex",
"parser"
],
"author": "Patrick Förster <patrick.foerster@outlook.de>",
"license": "MIT",
"bugs": {
"url": "https://github.com/latex-lsp/tree-sitter-latex/issues"
},
"homepage": "https://github.com/latex-lsp/tree-sitter-latex#readme",
"dependencies": {
"nan": "^2.16.0"
},
"devDependencies": {
"prettier": "^2.6.2",
"tree-sitter-cli": "^0.20.8"
},
"tree-sitter": [
{
"scope": "source.tex",
"file-types": [
"tex",
"sty",
"cls",
"aux"
]
}
]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,123 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tree_sitter/parser.h>
enum TokenType {
TRIVIA_RAW_FI,
TRIVIA_RAW_ENV_COMMENT,
TRIVIA_RAW_ENV_VERBATIM,
TRIVIA_RAW_ENV_LISTING,
TRIVIA_RAW_ENV_MINTED,
TRIVIA_RAW_ENV_PYCODE,
};
static bool find_verbatim(TSLexer *lexer, const char *keyword,
bool is_command_name) {
bool has_marked = false;
while (true) {
if (lexer->eof(lexer)) {
break;
}
bool advanced = false;
bool failed = false;
for (size_t i = 0; keyword[i]; i++) {
if (lexer->eof(lexer)) {
return has_marked;
}
if (lexer->lookahead != keyword[i]) {
failed = true;
break;
}
lexer->advance(lexer, false);
advanced = true;
}
if (failed && !advanced) {
lexer->advance(lexer, false);
lexer->mark_end(lexer);
has_marked = true;
continue;
}
if (!failed) {
if (is_command_name) {
if (lexer->eof(lexer)) {
return has_marked;
}
char c = lexer->lookahead;
switch (c) {
case ':':
case '_':
case '@':
failed = true;
break;
default:
failed = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
break;
}
if (failed) {
lexer->mark_end(lexer);
has_marked = true;
continue;
}
}
return has_marked;
}
}
return has_marked;
}
void *tree_sitter_latex_external_scanner_create() { return NULL; }
void tree_sitter_latex_external_scanner_destroy(void *payload) {}
unsigned tree_sitter_latex_external_scanner_serialize(void *payload,
char *buffer) {
return 0;
}
void tree_sitter_latex_external_scanner_deserialize(void *payload,
const char *buffer,
unsigned length) {}
bool tree_sitter_latex_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
bool found = false;
TSSymbol type = 0xFFFF;
for (int i = 0; i <= TRIVIA_RAW_ENV_PYCODE; i++) {
if (valid_symbols[i]) {
if (found) {
return false;
} else {
found = true;
type = i;
}
}
}
lexer->result_symbol = type;
switch (type) {
case TRIVIA_RAW_FI:
return find_verbatim(lexer, "\\fi", true);
case TRIVIA_RAW_ENV_COMMENT:
return find_verbatim(lexer, "\\end{comment}", false);
case TRIVIA_RAW_ENV_VERBATIM:
return find_verbatim(lexer, "\\end{verbatim}", false);
case TRIVIA_RAW_ENV_LISTING:
return find_verbatim(lexer, "\\end{lstlisting}", false);
case TRIVIA_RAW_ENV_MINTED:
return find_verbatim(lexer, "\\end{minted}", false);
case TRIVIA_RAW_ENV_PYCODE:
return find_verbatim(lexer, "\\end{pycode}", false);
}
return false;
}

@ -0,0 +1,224 @@
#ifndef TREE_SITTER_PARSER_H_
#define TREE_SITTER_PARSER_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#define ts_builtin_sym_error ((TSSymbol)-1)
#define ts_builtin_sym_end 0
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
typedef uint16_t TSStateId;
#ifndef TREE_SITTER_API_H_
typedef uint16_t TSSymbol;
typedef uint16_t TSFieldId;
typedef struct TSLanguage TSLanguage;
#endif
typedef struct {
TSFieldId field_id;
uint8_t child_index;
bool inherited;
} TSFieldMapEntry;
typedef struct {
uint16_t index;
uint16_t length;
} TSFieldMapSlice;
typedef struct {
bool visible;
bool named;
bool supertype;
} TSSymbolMetadata;
typedef struct TSLexer TSLexer;
struct TSLexer {
int32_t lookahead;
TSSymbol result_symbol;
void (*advance)(TSLexer *, bool);
void (*mark_end)(TSLexer *);
uint32_t (*get_column)(TSLexer *);
bool (*is_at_included_range_start)(const TSLexer *);
bool (*eof)(const TSLexer *);
};
typedef enum {
TSParseActionTypeShift,
TSParseActionTypeReduce,
TSParseActionTypeAccept,
TSParseActionTypeRecover,
} TSParseActionType;
typedef union {
struct {
uint8_t type;
TSStateId state;
bool extra;
bool repetition;
} shift;
struct {
uint8_t type;
uint8_t child_count;
TSSymbol symbol;
int16_t dynamic_precedence;
uint16_t production_id;
} reduce;
uint8_t type;
} TSParseAction;
typedef struct {
uint16_t lex_state;
uint16_t external_lex_state;
} TSLexMode;
typedef union {
TSParseAction action;
struct {
uint8_t count;
bool reusable;
} entry;
} TSParseActionEntry;
struct TSLanguage {
uint32_t version;
uint32_t symbol_count;
uint32_t alias_count;
uint32_t token_count;
uint32_t external_token_count;
uint32_t state_count;
uint32_t large_state_count;
uint32_t production_id_count;
uint32_t field_count;
uint16_t max_alias_sequence_length;
const uint16_t *parse_table;
const uint16_t *small_parse_table;
const uint32_t *small_parse_table_map;
const TSParseActionEntry *parse_actions;
const char * const *symbol_names;
const char * const *field_names;
const TSFieldMapSlice *field_map_slices;
const TSFieldMapEntry *field_map_entries;
const TSSymbolMetadata *symbol_metadata;
const TSSymbol *public_symbol_map;
const uint16_t *alias_map;
const TSSymbol *alias_sequences;
const TSLexMode *lex_modes;
bool (*lex_fn)(TSLexer *, TSStateId);
bool (*keyword_lex_fn)(TSLexer *, TSStateId);
TSSymbol keyword_capture_token;
struct {
const bool *states;
const TSSymbol *symbol_map;
void *(*create)(void);
void (*destroy)(void *);
bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
unsigned (*serialize)(void *, char *);
void (*deserialize)(void *, const char *, unsigned);
} external_scanner;
const TSStateId *primary_state_ids;
};
/*
* Lexer Macros
*/
#define START_LEXER() \
bool result = false; \
bool skip = false; \
bool eof = false; \
int32_t lookahead; \
goto start; \
next_state: \
lexer->advance(lexer, skip); \
start: \
skip = false; \
lookahead = lexer->lookahead;
#define ADVANCE(state_value) \
{ \
state = state_value; \
goto next_state; \
}
#define SKIP(state_value) \
{ \
skip = true; \
state = state_value; \
goto next_state; \
}
#define ACCEPT_TOKEN(symbol_value) \
result = true; \
lexer->result_symbol = symbol_value; \
lexer->mark_end(lexer);
#define END_STATE() return result;
/*
* Parse Table Macros
*/
#define SMALL_STATE(id) id - LARGE_STATE_COUNT
#define STATE(id) id
#define ACTIONS(id) id
#define SHIFT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = state_value \
} \
}}
#define SHIFT_REPEAT(state_value) \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.state = state_value, \
.repetition = true \
} \
}}
#define SHIFT_EXTRA() \
{{ \
.shift = { \
.type = TSParseActionTypeShift, \
.extra = true \
} \
}}
#define REDUCE(symbol_val, child_count_val, ...) \
{{ \
.reduce = { \
.type = TSParseActionTypeReduce, \
.symbol = symbol_val, \
.child_count = child_count_val, \
__VA_ARGS__ \
}, \
}}
#define RECOVER() \
{{ \
.type = TSParseActionTypeRecover \
}}
#define ACCEPT_INPUT() \
{{ \
.type = TSParseActionTypeAccept \
}}
#ifdef __cplusplus
}
#endif
#endif // TREE_SITTER_PARSER_H_

@ -0,0 +1,156 @@
================================================================================
Command without arguments
================================================================================
\foo bar
--------------------------------------------------------------------------------
(source_file
(generic_command
(command_name))
(text
(word)))
================================================================================
Command with one curly argument
================================================================================
\foo{bar}
--------------------------------------------------------------------------------
(source_file
(generic_command
(command_name)
(curly_group
(text
(word)))))
================================================================================
Command with one curly argument and brackets
================================================================================
\foo{bar}[baz]
--------------------------------------------------------------------------------
(source_file
(generic_command
(command_name)
(curly_group
(text
(word))))
(text
(word)))
================================================================================
Command with incomplete argument
================================================================================
\foo{ \begin{document} \end{document}
--------------------------------------------------------------------------------
(source_file
(ERROR
(command_name)
(generic_environment
(begin
(curly_group_text
(text
(word))))
(end
(curly_group_text
(text
(word)))))))
================================================================================
Acroynm definition
================================================================================
\newacronym[foo={bar}]{gcd}{GCD}{Greatest Common Divisor}
--------------------------------------------------------------------------------
(source_file
(acronym_definition
(brack_group_key_value
(key_value_pair
(text
(word))
(value
(curly_group
(text
(word))))))
(curly_group_text
(text
(word)))
(curly_group
(text
(word)))
(curly_group
(text
(word)
(word)
(word)))))
================================================================================
Command definition without default arg
================================================================================
\newcommand{\foo}[1]{#1}
--------------------------------------------------------------------------------
(source_file
(new_command_definition
(curly_group_command_name
(command_name))
(brack_group_argc
(argc))
(curly_group
(text
(placeholder)))))
================================================================================
Command definition with default arg
================================================================================
\newcommand{\foo}[1][bar]{#1}
--------------------------------------------------------------------------------
(source_file
(new_command_definition
(curly_group_command_name
(command_name))
(brack_group_argc
(argc))
(brack_group
(text
(word)))
(curly_group
(text
(placeholder)))))
================================================================================
Author command
================================================================================
\author{John Doe \and Foo Bar}
--------------------------------------------------------------------------------
(source_file
(author_declaration
(curly_group_author_list
(author
(text
(word)
(word)))
(command_name)
(author
(text
(word)
(word))))))

@ -0,0 +1,270 @@
================================================================================
Simple environment
================================================================================
\begin{document}
Hello World!
\end{document}
--------------------------------------------------------------------------------
(source_file
(generic_environment
(begin
(curly_group_text
(text
(word))))
(text
(word)
(word))
(end
(curly_group_text
(text
(word))))))
================================================================================
Environment with options
================================================================================
\begin{document}[foo bar]
Hello World!
\end{document}
--------------------------------------------------------------------------------
(source_file
(generic_environment
(begin
(curly_group_text
(text
(word)))
(brack_group
(text
(word)
(word))))
(text
(word)
(word))
(end
(curly_group_text
(text
(word))))))
================================================================================
Environment with nested options
================================================================================
\begin{document}[foo [bar] (baz)]
Hello World!
\end{document}
--------------------------------------------------------------------------------
(source_file
(generic_environment
(begin
(curly_group_text
(text
(word)))
(brack_group
(text
(word))
(brack_group
(text
(word)))
(text
(word))))
(text
(word)
(word))
(end
(curly_group_text
(text
(word))))))
================================================================================
Environment with escaped options
================================================================================
\begin{document}[{[}{]}]
Hello World!
\end{document}
--------------------------------------------------------------------------------
(source_file
(generic_environment
(begin
(curly_group_text
(text
(word)))
(brack_group
(curly_group)
(curly_group)))
(text
(word)
(word))
(end
(curly_group_text
(text
(word))))))
================================================================================
Comment environment
================================================================================
Foo
\begin{comment}
\begin{document}
Hello World
\end{document}
\end{comment}
Bar
--------------------------------------------------------------------------------
(source_file
(text
(word))
(comment_environment
(begin
(curly_group_text
(text
(word))))
(comment)
(end
(curly_group_text
(text
(word)))))
(text
(word)))
================================================================================
Verbatim environment
================================================================================
Foo
\begin{verbatim}
\begin{document}
Hello World
\end{document}
\end{verbatim}
Bar
--------------------------------------------------------------------------------
(source_file
(text
(word))
(verbatim_environment
(begin
(curly_group_text
(text
(word))))
(comment)
(end
(curly_group_text
(text
(word)))))
(text
(word)))
================================================================================
Minted environment
================================================================================
\begin{minted}{c}
int a = 1;
\end{minted}
--------------------------------------------------------------------------------
(source_file
(minted_environment
(begin
(curly_group_text
(text
(word)))
(curly_group_text
(text
(word))))
(source_code)
(end
(curly_group_text
(text
(word))))))
================================================================================
Pycode environment
================================================================================
\begin{pycode}
print()
\end{pycode}
--------------------------------------------------------------------------------
(source_file
(pycode_environment
(begin
(curly_group_text
(text
(word))))
(source_code)
(end
(curly_group_text
(text
(word))))))
================================================================================
Math environment
================================================================================
\begin{equation*}
e^{i \pi} + 1 = 0
\end{equation*}
--------------------------------------------------------------------------------
(source_file
(math_environment
(begin
(curly_group_text
(text
(word))))
(text
(word)
(superscript
(curly_group
(text
(word)
(generic_command
(command_name)))))
(operator)
(word))
(text
(word))
(end
(curly_group_text
(text
(word))))))

@ -0,0 +1,34 @@
================================================================================
Nested curly groups
================================================================================
Foo {Bar Baz {Qux}}
--------------------------------------------------------------------------------
(source_file
(text
(word))
(curly_group
(text
(word)
(word))
(curly_group
(text
(word)))))
================================================================================
Unbalanced curly braces
================================================================================
} Foo { Bar
--------------------------------------------------------------------------------
(source_file
(ERROR)
(text
(word))
(ERROR
(text
(word))))

@ -0,0 +1,188 @@
================================================================================
Simple package include
================================================================================
\usepackage{amsmath}
--------------------------------------------------------------------------------
(source_file
(package_include
(curly_group_path_list
(path))))
================================================================================
Package include with two paths
================================================================================
\usepackage{amsmath,lipsum}
--------------------------------------------------------------------------------
(source_file
(package_include
(curly_group_path_list
(path)
(path))))
================================================================================
Package include with options
================================================================================
\usepackage[foo=.5\textwidth, bar baz]{qux}
--------------------------------------------------------------------------------
(source_file
(package_include
(brack_group_key_value
(key_value_pair
(text
(word))
(value
(text
(word)
(generic_command
(command_name)))))
(key_value_pair
(text
(word)
(word))))
(curly_group_path_list
(path))))
================================================================================
Simple class include
================================================================================
\documentclass{amsmath}
--------------------------------------------------------------------------------
(source_file
(class_include
(curly_group_path
(path))))
================================================================================
Class include with two paths
================================================================================
\documentclass{amsmath,lipsum}
--------------------------------------------------------------------------------
(source_file
(class_include
(curly_group_path
(path)
(MISSING "}")))
(text
(word))
(ERROR))
================================================================================
Class include with options
================================================================================
\documentclass[foo=.5\textwidth, bar baz]{qux}
--------------------------------------------------------------------------------
(source_file
(class_include
(brack_group_key_value
(key_value_pair
(text
(word))
(value
(text
(word)
(generic_command
(command_name)))))
(key_value_pair
(text
(word)
(word))))
(curly_group_path
(path))))
================================================================================
Simple LaTeX include
================================================================================
\input{foo.tex}
--------------------------------------------------------------------------------
(source_file
(latex_include
(curly_group_path
(path))))
================================================================================
Empty LaTeX include
================================================================================
\input{}
--------------------------------------------------------------------------------
(source_file
(ERROR))
================================================================================
BibLaTeX glob include
================================================================================
\addbibresource[glob]{foo.{1,2,3}.bib}
--------------------------------------------------------------------------------
(source_file
(biblatex_include
(brack_group_key_value
(key_value_pair
(text
(word))))
(curly_group_glob_pattern
(glob_pattern))))
================================================================================
BibTeX include with absolute path
================================================================================
\bibliography{/home/user/foo.bib}
--------------------------------------------------------------------------------
(source_file
(bibtex_include
(curly_group_path
(path))))
================================================================================
Graphics include with options
================================================================================
\includegraphics[scale=0.5,angle=45]{test}
--------------------------------------------------------------------------------
(source_file
(graphics_include
(brack_group_key_value
(key_value_pair
(text
(word))
(value
(text
(word))))
(key_value_pair
(text
(word))
(value
(text
(word)))))
(curly_group_path
(path))))

@ -0,0 +1,765 @@
================================================================================
tree-sitter-latex (Issue #11)
================================================================================
\documentclass{article}
\begin{document}
\texttt{foo :("@@@} foo foo
foo foo \texttt{0xffe00fff} foo foo foo foo foo foo foo foo foo foo foo
foo \texttt{0xfff00000}.
foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo
foo. foo foo foo foo foo foo foo foo foo foo
foo foo foo foo foo foo
\end{document}
--------------------------------------------------------------------------------
(source_file
(class_include
(curly_group_path
(path)))
(generic_environment
(begin
(curly_group_text
(text
(word))))
(generic_command
(command_name)
(curly_group
(text
(word)
(operator))
(text
(word))))
(text
(word)
(word)
(word)
(word)
(generic_command
(command_name)
(curly_group
(text
(word))))
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(generic_command
(command_name)
(curly_group
(text
(word))))
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word)
(word))
(end
(curly_group_text
(text
(word))))))
================================================================================
tree-sitter-latex (Issue #15)
================================================================================
\iffalse
something here
\fi
\usepackage{comment} % in the preamble
\begin{comment}
something
\end{comment}
--------------------------------------------------------------------------------
(source_file
(block_comment
(comment))
(package_include
(curly_group_path_list
(path)))
(line_comment)
(comment_environment
(begin
(curly_group_text
(text
(word))))
(comment)
(end
(curly_group_text
(text
(word))))))
================================================================================
tree-sitter-latex (Issue #10)
================================================================================
\titleformat{\section}{\relax}{\thesection}{1em}{\spacedsmallcaps}
\titlespacing*{\paragraph}{0pt}{1\baselineskip}{0.5\baselineskip}
--------------------------------------------------------------------------------
(source_file
(generic_command
(command_name)
(curly_group
(section))
(curly_group
(generic_command
(command_name)))
(curly_group
(generic_command
(command_name)))
(curly_group
(text
(word)))
(curly_group
(generic_command
(command_name))))
(generic_command
(command_name)
(curly_group
(paragraph))
(curly_group
(text
(word)))
(curly_group
(text
(word)
(generic_command
(command_name))))
(curly_group
(text
(word)
(generic_command
(command_name))))))
================================================================================
tree-sitter-latex (Issue #7)
================================================================================
\addbibresource{$HOME/ref.bib}
To clear \lstinline{biber} cache, run
\begin{lstlisting}[language=bash]
rm -rf "$(biber --cache)"
\end{lstlisting}
--------------------------------------------------------------------------------
(source_file
(biblatex_include
(curly_group_glob_pattern
(glob_pattern)))
(text
(word)
(word)
(generic_command
(command_name)
(curly_group
(text
(word))))
(word))
(text
(word))
(listing_environment
(begin
(curly_group_text
(text
(word))))
(source_code)
(end
(curly_group_text
(text
(word))))))
================================================================================
tree-sitter-latex (Issue #11)
================================================================================
\newenvironment{mycenter}
{\begin{center}}
{\end{center}}
--------------------------------------------------------------------------------
(source_file
(environment_definition
(curly_group_text
(text
(word)))
(curly_group_impl
(generic_command
(command_name)
(curly_group
(text
(word)))))
(curly_group_impl
(generic_command
(command_name)
(curly_group
(text
(word)))))))
================================================================================
tree-sitter-latex (Issue #10)
================================================================================
\titleformat{\section}{\relax}{\thesection}{1em}{\spacedsmallcaps}
\titlespacing*{\paragraph}{0pt}{1\baselineskip}{0.5\baselineskip}
--------------------------------------------------------------------------------
(source_file
(generic_command
(command_name)
(curly_group
(section))
(curly_group
(generic_command
(command_name)))
(curly_group
(generic_command
(command_name)))
(curly_group
(text
(word)))
(curly_group
(generic_command
(command_name))))
(generic_command
(command_name)
(curly_group
(paragraph))
(curly_group
(text
(word)))
(curly_group
(text
(word)
(generic_command
(command_name))))
(curly_group
(text
(word)
(generic_command
(command_name))))))
================================================================================
tree-sitter-latex (Issue #13)
================================================================================
\includegraphics[width=0.5\textwidth]{some.jpg}
--------------------------------------------------------------------------------
(source_file
(graphics_include
(brack_group_key_value
(key_value_pair
(text
(word))
(value
(text
(word)
(generic_command
(command_name))))))
(curly_group_path
(path))))
================================================================================
tree-sitter-latex (Issue #24)
================================================================================
\newtheorem{definition}{Definition}[section]
--------------------------------------------------------------------------------
(source_file
(theorem_definition
(curly_group_text
(text
(word)))
(curly_group
(text
(word)))
(brack_group_text
(text
(word)))))
================================================================================
tree-sitter-latex (Issue #25 Nesting of document structure)
================================================================================
\section{SomeSection}
1
\begin{itemize}
\item 2 \texttt{3} 4
\end{itemize}
5
--------------------------------------------------------------------------------
(source_file
(section
text: (curly_group
(text
word: (word)))
(text
word: (word))
(generic_environment
begin: (begin
name: (curly_group_text
text: (text
word: (word))))
(enum_item
(text
word: (word)
word: (generic_command
command: (command_name)
arg: (curly_group
(text
word: (word))))
word: (word)))
end: (end
name: (curly_group_text
text: (text
word: (word)))))
(text
word: (word))))
================================================================================
tree-sitter-latex (Issue #28 \usetikzlibrary with multiple libs)
================================================================================
\usetikzlibrary{
calc,
external,
shapes,
math
}
--------------------------------------------------------------------------------
(source_file
(tikz_library_import
(curly_group_path_list
(path)
(path)
(path)
(path))))
================================================================================
tree-sitter-latex (Issue #29)
================================================================================
\color{\currentcolor}
--------------------------------------------------------------------------------
(source_file
(color_reference
(curly_group_text
(text
(generic_command
(command_name))))))
================================================================================
tree-sitter-latex (Issue #3) | \text
================================================================================
Let $C =\{ f \colon M \to \mathbb{R} \mid \text{$f$ is smooth} \}$.
--------------------------------------------------------------------------------
(source_file
(text
(word))
(inline_formula
(text
(word))
(text
(word)
(generic_command
(command_name))
(word)
(generic_command
(command_name))
(word)
(generic_command
(command_name))
(generic_command
(command_name)
(curly_group
(text
(word))))
(generic_command
(command_name)))
(text_mode
(curly_group
(inline_formula
(text
(word)))
(text
(word)
(word))))
(generic_command
(command_name)))
(text
(word)))
================================================================================
tree-sitter-latex (Issue #3) | \intertext
================================================================================
Let
\begin{align*}
F &= x^2 + y^2
\intertext{and similarly}
G &= x^2 - y^2.
\end{align*}
--------------------------------------------------------------------------------
(source_file
(text
(word))
(math_environment
(begin
(curly_group_text
(text
(word))))
(text
(word)
(word))
(text
(word)
(superscript
(word))
(operator)
(word)
(superscript
(word)))
(text_mode
(curly_group
(text
(word)
(word))))
(text
(word)
(word))
(text
(word)
(superscript
(word))
(operator)
(word)
(superscript
(word)))
(end
(curly_group_text
(text
(word))))))
================================================================================
tree-sitter-latex (Issue #36) | Paired delimiter #1
================================================================================
\DeclarePairedDelimiter{\abs}{\lvert}{\rvert}
\DeclarePairedDelimiterX{\abs}[1]\lvert\rvert{#1}
--------------------------------------------------------------------------------
(source_file
(paired_delimiter_definition
(curly_group_command_name
(command_name))
(curly_group_impl
(generic_command
(command_name)))
(curly_group_impl
(generic_command
(command_name))))
(paired_delimiter_definition
(curly_group_command_name
(command_name))
(brack_group_argc
(argc))
(command_name)
(command_name)
(curly_group
(text
(placeholder)))))
================================================================================
tree-sitter-latex (Issue #36) | Paired delimiter #2
================================================================================
\DeclarePairedDelimiter{\foo}{(}{)}
--------------------------------------------------------------------------------
(source_file
(paired_delimiter_definition
(curly_group_command_name
(command_name))
(curly_group_impl)
(curly_group_impl)))
================================================================================
tree-sitter-latex (Issue #39) | Section with ToC entry
================================================================================
\section[Foo 1]{Bar 1}
Qux 1
\subsection[Foo 2]{Bar 2}
Qux 2
--------------------------------------------------------------------------------
(source_file
(section
(brack_group
(text
(word)
(word)))
(curly_group
(text
(word)
(word)))
(text
(word)
(word))
(subsection
(brack_group
(text
(word)
(word)))
(curly_group
(text
(word)
(word)))
(text
(word)
(word)))))
================================================================================
tree-sitter-latex (Issue #42) | Command with parens
================================================================================
\emph{test} (note here)
--------------------------------------------------------------------------------
(source_file
(generic_command
(command_name)
(curly_group
(text
(word))))
(text
(word)
(word)))
================================================================================
tree-sitter-latex (Issue #43) | \left and \right
================================================================================
\left\{ Foo \right.
--------------------------------------------------------------------------------
(source_file
(math_delimiter
(command_name)
(text
(word))
(word)))
================================================================================
tree-sitter-latex (Issue #43) | \left and \right with parens
================================================================================
\left( Foo \right]
--------------------------------------------------------------------------------
(source_file
(math_delimiter
(text
(word))))
================================================================================
tree-sitter-latex (Issue #44) | \definecolor
================================================================================
\definecolor{delim}{RGB}{20,105,176}
--------------------------------------------------------------------------------
(source_file
(color_definition
(curly_group_text
(text
(word)))
(curly_group_text
(text
(word)))
(curly_group
(text
(word))
(text
(word))
(text
(word)))))
================================================================================
tree-sitter-latex (Issue #48) | Brackets in math mode
================================================================================
\(]0,+\infty[\)
--------------------------------------------------------------------------------
(source_file
(inline_formula
(text
(word))
(text
(operator)
(generic_command
(command_name)))))
================================================================================
tree-sitter-latex (Issue #55) | minted with options
================================================================================
\documentclass{article}
\begin{document}
\begin{minted}[autogobble]{python}
foo()
\end{minted}
\end{document}
--------------------------------------------------------------------------------
(source_file
(class_include
(curly_group_path
(path)))
(generic_environment
(begin
(curly_group_text
(text
(word))))
(minted_environment
(begin
(curly_group_text
(text
(word)))
(brack_group_key_value
(key_value_pair
(text
(word))))
(curly_group_text
(text
(word))))
(source_code)
(end
(curly_group_text
(text
(word)))))
(end
(curly_group_text
(text
(word))))))
================================================================================
tree-sitter-latex (Issue #58) | math delimiters
================================================================================
\big( 2 + 2 \big)
\bigl( 2 + 2 \bigr)
\left( 2 + 2 \right)
\big\langle 2 + 2 \big\rangle
\bigl| v \bigr|
--------------------------------------------------------------------------------
(source_file
(math_delimiter
(text
(word)
(operator)
(word)))
(math_delimiter
(text
(word)
(operator)
(word)))
(math_delimiter
(text
(word)
(operator)
(word)))
(math_delimiter
(command_name)
(text
(word)
(operator)
(word))
(command_name))
(math_delimiter
(text
(word))))

@ -0,0 +1,225 @@
================================================================================
Simple displayed equation (dollar)
================================================================================
Foo $$ Bar Baz $$
--------------------------------------------------------------------------------
(source_file
(text
(word))
(displayed_equation
(text
(word)
(word))))
================================================================================
Simple displayed equation (command)
================================================================================
Foo \[ Bar Baz \]
--------------------------------------------------------------------------------
(source_file
(text
(word))
(displayed_equation
(text
(word)
(word))))
================================================================================
Displayed equation (mixed)
================================================================================
Foo \[ Bar Baz $$
--------------------------------------------------------------------------------
(source_file
(text
(word))
(displayed_equation
(text
(word)
(word))))
================================================================================
Displayed equation (nested)
================================================================================
Foo $$ Bar Baz \[ Qux \] $$
--------------------------------------------------------------------------------
(source_file
(text
(word))
(displayed_equation
(text
(word)
(word))
(displayed_equation
(text
(word)))))
================================================================================
Displayed equation (flat)
================================================================================
Foo $$ Bar $$ Baz $$ Qux $$
--------------------------------------------------------------------------------
(source_file
(text
(word))
(displayed_equation
(text
(word)))
(text
(word))
(displayed_equation
(text
(word))))
================================================================================
Simple inline formula (dollar)
================================================================================
Foo $ Bar Baz $
--------------------------------------------------------------------------------
(source_file
(text
(word))
(inline_formula
(text
(word)
(word))))
================================================================================
Simple inline formula (command)
================================================================================
Foo \( Bar Baz \)
--------------------------------------------------------------------------------
(source_file
(text
(word))
(inline_formula
(text
(word)
(word))))
================================================================================
Inline formula (mixed)
================================================================================
Foo \( Bar Baz $
--------------------------------------------------------------------------------
(source_file
(text
(word))
(inline_formula
(text
(word)
(word))))
================================================================================
Inline formula (nested)
================================================================================
Foo $ Bar Baz \( Qux \) $
--------------------------------------------------------------------------------
(source_file
(text
(word))
(inline_formula
(text
(word)
(word))
(inline_formula
(text
(word)))))
================================================================================
Inline formula (flat)
================================================================================
Foo $ Bar $ Baz $ Qux $
--------------------------------------------------------------------------------
(source_file
(text
(word))
(inline_formula
(text
(word)))
(text
(word))
(inline_formula
(text
(word))))
================================================================================
Inline formula closed with double dollar
================================================================================
$ foo $$ bar
--------------------------------------------------------------------------------
(source_file
(ERROR
(text
(word))
(word)))
================================================================================
Simple math set
================================================================================
\{ 1, 2, 3 \}
--------------------------------------------------------------------------------
(source_file
(generic_command
(command_name))
(text
(word))
(text
(word))
(text
(word)
(generic_command
(command_name))))
================================================================================
Subscripts and superscripts
================================================================================
Foo_{bar}^2
--------------------------------------------------------------------------------
(source_file
(text
(word)
(subscript
(curly_group
(text
(word))))
(superscript
(word))))

@ -0,0 +1,87 @@
================================================================================
Top level sections
================================================================================
\begin{document}
1
\section{Foo}
2
\section{Bar}
3
\end{document}
--------------------------------------------------------------------------------
(source_file
(generic_environment
(begin
(curly_group_text
(text
(word))))
(text
(word))
(section
(curly_group
(text
(word)))
(text
(word)))
(section
(curly_group
(text
(word)))
(text
(word)))
(end
(curly_group_text
(text
(word))))))
================================================================================
Nested sections
================================================================================
1
\part{\Foo}
2
\chapter{Bar}
3
\chapter{{Baz}}
4
--------------------------------------------------------------------------------
(source_file
(text
(word))
(part
(curly_group
(generic_command
(command_name)))
(text
(word))
(chapter
(curly_group
(text
(word)))
(text
(word)))
(chapter
(curly_group
(curly_group
(text
(word))))
(text
(word)))))

@ -0,0 +1,88 @@
================================================================================
Hello world
================================================================================
Hello World!
--------------------------------------------------------------------------------
(source_file
(text
(word)
(word)))
================================================================================
Matched parens and brackets
================================================================================
Foo Bar (Baz [(Qux)])
--------------------------------------------------------------------------------
(source_file
(text
(word)
(word))
(text
(word))
(text
(word)))
================================================================================
Unmatched parens
================================================================================
Foo ) Bar ( Baz
--------------------------------------------------------------------------------
(source_file
(text
(word))
(text
(word))
(text
(word)))
================================================================================
Comma separated words
================================================================================
Foo, Bar
--------------------------------------------------------------------------------
(source_file
(text
(word))
(text
(word)))
================================================================================
Valid macro parameter
================================================================================
Macro #1 parameter
--------------------------------------------------------------------------------
(source_file
(text
(word)
(placeholder)
(word)))
================================================================================
Invalid macro parameter
================================================================================
Foo # Bar
--------------------------------------------------------------------------------
(source_file
(text
(word)
(ERROR
(UNEXPECTED ' '))
(word)))

@ -0,0 +1,51 @@
================================================================================
Line comment
================================================================================
% Foo
Bar
--------------------------------------------------------------------------------
(source_file
(line_comment)
(text
(word)))
================================================================================
Escaped percent
================================================================================
\% Foo
--------------------------------------------------------------------------------
(source_file
(generic_command
(command_name))
(text
(word)))
================================================================================
Block comment
================================================================================
Hello World
\iffalse
\foo Bar \begin{Baz
\fi
Test
--------------------------------------------------------------------------------
(source_file
(text
(word)
(word)
(block_comment
(comment))
(word)))