mirror of https://github.com/Wilfred/difftastic/
Simplify parsing of special LaTeX commands
parent
2c0d03a36e
commit
ccb6fe7a57
@ -0,0 +1,5 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
IndentWidth: 2
|
||||
---
|
||||
|
||||
@ -1 +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
|
||||
@ -1,18 +1,53 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
branches: [master, develop, feature/*]
|
||||
pull_request:
|
||||
branches: [master]
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
CI: 1
|
||||
RUST_BACKTRACE: short
|
||||
RUSTFLAGS: '-D warnings'
|
||||
RUSTUP_MAX_RETRIES: 10
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
node:
|
||||
name: Node
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '12'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Run tests
|
||||
node-version: '16'
|
||||
cache: 'npm'
|
||||
- name: Install Dependencies
|
||||
run: npm install
|
||||
- name: Test
|
||||
run: npm test
|
||||
rust:
|
||||
name: Rust
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
override: true
|
||||
- name: Cache Dependencies
|
||||
uses: Swatinem/rust-cache@v1
|
||||
- name: Compile
|
||||
run: cargo test --no-run
|
||||
- name: Test
|
||||
run: cargo test -- --nocapture --quiet
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "tree_sitter_latex_binding",
|
||||
"include_dirs": [
|
||||
"<!(node -e \"require('nan')\")",
|
||||
"src"
|
||||
],
|
||||
"sources": [
|
||||
"bindings/node/binding.cc",
|
||||
"src/parser.c",
|
||||
# If your language uses an external scanner, add it here.
|
||||
],
|
||||
"cflags_c": [
|
||||
"-std=c99",
|
||||
]
|
||||
}
|
||||
]
|
||||
"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",
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,182 +0,0 @@
|
||||
{
|
||||
"citation": [
|
||||
"\\cite",
|
||||
"\\cite*",
|
||||
"\\Cite",
|
||||
"\\nocite",
|
||||
"\\citet",
|
||||
"\\citep",
|
||||
"\\citet*",
|
||||
"\\citep*",
|
||||
"\\citeauthor",
|
||||
"\\citeauthor*",
|
||||
"\\Citeauthor",
|
||||
"\\Citeauthor*",
|
||||
"\\citetitle",
|
||||
"\\citetitle*",
|
||||
"\\citeyear",
|
||||
"\\citeyear*",
|
||||
"\\citedate",
|
||||
"\\citedate*",
|
||||
"\\citeurl",
|
||||
"\\fullcite",
|
||||
"\\citeyearpar",
|
||||
"\\citealt",
|
||||
"\\citealp",
|
||||
"\\citetext",
|
||||
"\\parencite",
|
||||
"\\parencite*",
|
||||
"\\Parencite",
|
||||
"\\footcite",
|
||||
"\\footfullcite",
|
||||
"\\footcitetext",
|
||||
"\\textcite",
|
||||
"\\Textcite",
|
||||
"\\smartcite",
|
||||
"\\Smartcite",
|
||||
"\\supercite",
|
||||
"\\autocite",
|
||||
"\\Autocite",
|
||||
"\\autocite*",
|
||||
"\\Autocite*",
|
||||
"\\volcite",
|
||||
"\\Volcite",
|
||||
"\\pvolcite",
|
||||
"\\Pvolcite",
|
||||
"\\fvolcite",
|
||||
"\\ftvolcite",
|
||||
"\\svolcite",
|
||||
"\\Svolcite",
|
||||
"\\tvolcite",
|
||||
"\\Tvolcite",
|
||||
"\\avolcite",
|
||||
"\\Avolcite",
|
||||
"\\notecite",
|
||||
"\\notecite",
|
||||
"\\pnotecite",
|
||||
"\\Pnotecite",
|
||||
"\\fnotecite"
|
||||
],
|
||||
"labelReference": [
|
||||
"\\ref",
|
||||
"\\vref",
|
||||
"\\Vref",
|
||||
"\\autoref",
|
||||
"\\pageref",
|
||||
"\\cref",
|
||||
"\\Cref",
|
||||
"\\cref*",
|
||||
"\\Cref*",
|
||||
"\\namecref",
|
||||
"\\nameCref",
|
||||
"\\lcnamecref",
|
||||
"\\namecrefs",
|
||||
"\\nameCrefs",
|
||||
"\\lcnamecrefs",
|
||||
"\\labelcref",
|
||||
"\\labelcpageref"
|
||||
],
|
||||
"labelRangeReference": [
|
||||
"\\crefrange",
|
||||
"\\crefrange",
|
||||
"\\Crefrange",
|
||||
"\\Crefrange",
|
||||
"\\crefrange*",
|
||||
"\\crefrange*",
|
||||
"\\Crefrange*",
|
||||
"\\Crefrange*"
|
||||
],
|
||||
"glossaryEntryReference": [
|
||||
"\\gls",
|
||||
"\\Gls",
|
||||
"\\GLS",
|
||||
"\\glspl",
|
||||
"\\Glspl",
|
||||
"\\GLSpl",
|
||||
"\\glsdisp",
|
||||
"\\glslink",
|
||||
"\\glstext",
|
||||
"\\Glstext",
|
||||
"\\GLStext",
|
||||
"\\glsfirst",
|
||||
"\\Glsfirst",
|
||||
"\\GLSfirst",
|
||||
"\\glsplural",
|
||||
"\\Glsplural",
|
||||
"\\GLSplural",
|
||||
"\\glsfirstplural",
|
||||
"\\Glsfirstplural",
|
||||
"\\GLSfirstplural",
|
||||
"\\glsname",
|
||||
"\\Glsname",
|
||||
"\\GLSname",
|
||||
"\\glssymbol",
|
||||
"\\Glssymbol",
|
||||
"\\glsdesc",
|
||||
"\\Glsdesc",
|
||||
"\\GLSdesc",
|
||||
"\\glsuseri",
|
||||
"\\Glsuseri",
|
||||
"\\GLSuseri",
|
||||
"\\glsuserii",
|
||||
"\\Glsuserii",
|
||||
"\\GLSuserii",
|
||||
"\\glsuseriii",
|
||||
"\\Glsuseriii",
|
||||
"\\GLSuseriii",
|
||||
"\\glsuseriv",
|
||||
"\\Glsuseriv",
|
||||
"\\GLSuseriv",
|
||||
"\\glsuserv",
|
||||
"\\Glsuserv",
|
||||
"\\GLSuserv",
|
||||
"\\glsuservi",
|
||||
"\\Glsuservi",
|
||||
"\\GLSuservi"
|
||||
],
|
||||
"acronymReference": [
|
||||
"\\acrshort",
|
||||
"\\Acrshort",
|
||||
"\\ACRshort",
|
||||
"\\acrshortpl",
|
||||
"\\Acrshortpl",
|
||||
"\\ACRshortpl",
|
||||
"\\acrlong",
|
||||
"\\Acrlong",
|
||||
"\\ACRlong",
|
||||
"\\acrlongpl",
|
||||
"\\Acrlongpl",
|
||||
"\\ACRlongpl",
|
||||
"\\acrfull",
|
||||
"\\Acrfull",
|
||||
"\\ACRfull",
|
||||
"\\acrfullpl",
|
||||
"\\Acrfullpl",
|
||||
"\\ACRfullpl",
|
||||
"\\acs",
|
||||
"\\Acs",
|
||||
"\\acsp",
|
||||
"\\Acsp",
|
||||
"\\acl",
|
||||
"\\Acl",
|
||||
"\\aclp",
|
||||
"\\Aclp",
|
||||
"\\acf",
|
||||
"\\Acf",
|
||||
"\\acfp",
|
||||
"\\Acfp",
|
||||
"\\ac",
|
||||
"\\Ac",
|
||||
"\\acp",
|
||||
"\\glsentrylong",
|
||||
"\\Glsentrylong",
|
||||
"\\glsentrylongpl",
|
||||
"\\Glsentrylongpl",
|
||||
"\\glsentryshort",
|
||||
"\\Glsentryshort",
|
||||
"\\glsentryshortpl",
|
||||
"\\Glsentryshortpl",
|
||||
"\\glsentryfullpl",
|
||||
"\\Glsentryfullpl"
|
||||
]
|
||||
}
|
||||
@ -1,655 +1,90 @@
|
||||
/// <reference types="tree-sitter-cli/dsl" />
|
||||
// @ts-check
|
||||
|
||||
const commands = require('./commands.json');
|
||||
|
||||
const sepBy1 = (rule, sep) => seq(rule, repeat(seq(sep, rule)));
|
||||
|
||||
const sepBy = (rule, sep) => optional(sepBy1(rule, sep));
|
||||
const rules = require('./rules');
|
||||
|
||||
module.exports = grammar({
|
||||
name: 'latex',
|
||||
extras: $ => [$._whitespace, $.comment],
|
||||
word: $ => $.generic_command_name,
|
||||
extras: $ => [$._whitespace, $.line_comment],
|
||||
externals: $ => [
|
||||
$._generic_command_name,
|
||||
$._begin_command_name,
|
||||
$._end_command_name,
|
||||
$._iffalse_command_name,
|
||||
$._fi_command_name,
|
||||
$._caption_command_name,
|
||||
$._citation_command_name,
|
||||
$._label_definition_command_name,
|
||||
$._label_reference_command_name,
|
||||
$._label_reference_range_command_name,
|
||||
$._label_number_command_name,
|
||||
$._new_command_definition_command_name,
|
||||
$._old_command_definition_command_name,
|
||||
$._let_command_definition_command_name,
|
||||
$._environment_definition_command_name,
|
||||
$._glossary_entry_definition_command_name,
|
||||
$._glossary_entry_reference_command_name,
|
||||
$._acronym_definition_command_name,
|
||||
$._acronym_reference_command_name,
|
||||
$._theorem_definition_command_name,
|
||||
$._color_definition_command_name,
|
||||
$._color_set_definition_command_name,
|
||||
$._color_reference_command_name,
|
||||
$._tikz_library_import_command_name,
|
||||
$._package_include_command_name,
|
||||
$._class_include_command_name,
|
||||
$._latex_include_command_name,
|
||||
$._biblatex_include_command_name,
|
||||
$._bibtex_include_command_name,
|
||||
$._graphics_include_command_name,
|
||||
$._svg_include_command_name,
|
||||
$._inkscape_include_command_name,
|
||||
$._verbatim_include_command_name,
|
||||
$._import_command_name,
|
||||
$._escaped_lparen_command_name,
|
||||
$._escaped_rparen_command_name,
|
||||
$._escaped_lbrack_command_name,
|
||||
$._escaped_rbrack_command_name,
|
||||
$._escaped_lcurly_command_name,
|
||||
$._escaped_rcurly_command_name,
|
||||
$._part_command_name,
|
||||
$._chapter_command_name,
|
||||
$._section_command_name,
|
||||
$._subsection_command_name,
|
||||
$._subsubsection_command_name,
|
||||
$._paragraph_command_name,
|
||||
$._subparagraph_command_name,
|
||||
$._enum_item_command_name,
|
||||
$._verbatim_cmd_fi,
|
||||
$._verbatim_env_comment,
|
||||
$._verbatim_env_verbatim,
|
||||
$._verbatim_env_listing,
|
||||
$._verbatim_env_minted,
|
||||
],
|
||||
supertypes: $ => [$._include],
|
||||
rules: {
|
||||
document: $ => repeat($._content),
|
||||
source_file: $ => repeat($._full_content),
|
||||
|
||||
//--- Trivia ---//
|
||||
...rules,
|
||||
|
||||
_whitespace: $ => /\s+/,
|
||||
_full_content: $ =>
|
||||
choice($._section, $._basic_content, $._contextual_delimiter, '[', ']'),
|
||||
|
||||
comment: $ => /%[^\r\n]*/,
|
||||
_basic_content: $ =>
|
||||
choice(alias($._environment, $.environment), $._minimal_content),
|
||||
|
||||
//--- Content ---//
|
||||
|
||||
_simple_content: $ =>
|
||||
_minimal_content: $ =>
|
||||
choice(
|
||||
$.brace_group,
|
||||
$.mixed_group,
|
||||
$.param,
|
||||
$.text,
|
||||
$.curly_group,
|
||||
$.block_comment,
|
||||
$.displayed_equation,
|
||||
$.inline_formula,
|
||||
$.environment,
|
||||
$.caption,
|
||||
$.citation,
|
||||
$.package_include,
|
||||
$.class_include,
|
||||
$.latex_include,
|
||||
$.latex_input,
|
||||
$.biblatex_include,
|
||||
$.bibtex_include,
|
||||
$.graphics_include,
|
||||
$.svg_include,
|
||||
$.inkscape_include,
|
||||
$.verbatim_include,
|
||||
$.import,
|
||||
$.label_definition,
|
||||
$.label_reference,
|
||||
$.equation_label_reference,
|
||||
$.label_reference_range,
|
||||
$.label_number,
|
||||
$.command_definition,
|
||||
$.math_operator,
|
||||
$.glossary_entry_definition,
|
||||
$.glossary_entry_reference,
|
||||
$.acronym_definition,
|
||||
$.acronym_reference,
|
||||
$.theorem_definition,
|
||||
$.color_reference,
|
||||
$.color_definition,
|
||||
$.color_set_definition,
|
||||
$.pgf_library_import,
|
||||
$.tikz_library_import,
|
||||
$.generic_command
|
||||
),
|
||||
|
||||
_content: $ =>
|
||||
choice(
|
||||
$.part,
|
||||
$.chapter,
|
||||
$.section,
|
||||
$.subsection,
|
||||
$.subsubsection,
|
||||
$.paragraph,
|
||||
$.subparagraph,
|
||||
$.enum_item,
|
||||
$._simple_content
|
||||
),
|
||||
|
||||
//--- Structure ---//
|
||||
|
||||
part: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', choice('\\part', '\\part*')),
|
||||
field('text', $.brace_group),
|
||||
field(
|
||||
'child',
|
||||
repeat(
|
||||
choice(
|
||||
$.chapter,
|
||||
$.section,
|
||||
$.subsection,
|
||||
$.subsubsection,
|
||||
$.paragraph,
|
||||
$.subparagraph,
|
||||
$.enum_item,
|
||||
$._simple_content
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
chapter: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', choice('\\chapter', '\\chapter*')),
|
||||
field('text', $.brace_group),
|
||||
field(
|
||||
'child',
|
||||
repeat(
|
||||
choice(
|
||||
$.section,
|
||||
$.subsection,
|
||||
$.subsubsection,
|
||||
$.paragraph,
|
||||
$.subparagraph,
|
||||
$.enum_item,
|
||||
$._simple_content
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
section: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', choice('\\section', '\\section*')),
|
||||
field('text', $.brace_group),
|
||||
field(
|
||||
'child',
|
||||
repeat(
|
||||
choice(
|
||||
$.subsection,
|
||||
$.subsubsection,
|
||||
$.paragraph,
|
||||
$.subparagraph,
|
||||
$.enum_item,
|
||||
$._simple_content
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
subsection: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', choice('\\subsection', '\\subsection*')),
|
||||
field('text', $.brace_group),
|
||||
field(
|
||||
'child',
|
||||
repeat(
|
||||
choice(
|
||||
$.subsubsection,
|
||||
$.paragraph,
|
||||
$.subparagraph,
|
||||
$.enum_item,
|
||||
$._simple_content
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
subsubsection: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', choice('\\subsubsection', '\\subsubsection*')),
|
||||
field('text', $.brace_group),
|
||||
field(
|
||||
'child',
|
||||
repeat(
|
||||
choice(
|
||||
$.paragraph,
|
||||
$.subparagraph,
|
||||
$.enum_item,
|
||||
$._simple_content
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
paragraph: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', choice('\\paragraph', '\\paragraph*')),
|
||||
field('text', $.brace_group),
|
||||
field(
|
||||
'child',
|
||||
repeat(choice($.subparagraph, $.enum_item, $._simple_content))
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
subparagraph: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', choice('\\subparagraph', '\\subparagraph*')),
|
||||
field('text', $.brace_group),
|
||||
field('child', repeat(choice($.enum_item, $._simple_content)))
|
||||
)
|
||||
),
|
||||
|
||||
enum_item: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', '\\item'),
|
||||
optional(seq('[', field('label', $.word), ']')),
|
||||
field('child', repeat(choice($._simple_content)))
|
||||
)
|
||||
),
|
||||
|
||||
//--- Groups ---//
|
||||
|
||||
brace_group: $ =>
|
||||
seq(
|
||||
field('left', '{'),
|
||||
field('child', repeat($._content)),
|
||||
field('right', '}')
|
||||
),
|
||||
|
||||
bracket_group: $ =>
|
||||
seq(
|
||||
field('left', '['),
|
||||
field('child', repeat($._content)),
|
||||
field('right', ']')
|
||||
),
|
||||
|
||||
paren_group: $ =>
|
||||
seq(
|
||||
field('left', '('),
|
||||
field('child', repeat($._content)),
|
||||
field('right', ')')
|
||||
),
|
||||
|
||||
mixed_group: $ =>
|
||||
seq(
|
||||
field('left', choice('(', '[', '\\{')),
|
||||
field('child', repeat($._content)),
|
||||
field('right', choice(')', ']', '\\}'))
|
||||
),
|
||||
|
||||
key_val_options: $ =>
|
||||
seq(
|
||||
field('left', '['),
|
||||
sepBy(field('property', $.key_val_pair), ','),
|
||||
field('right', ']')
|
||||
),
|
||||
|
||||
key_val_pair: $ =>
|
||||
seq(
|
||||
field('key', repeat1($.word)),
|
||||
optional(seq(field('equals', '='), field('value', $._content)))
|
||||
),
|
||||
|
||||
//--- Text ---//
|
||||
|
||||
// Performance optimization: store text as a binary tree instead of a list
|
||||
// text: $ =>
|
||||
// prec.right(
|
||||
// seq(field('left', $._text_fragment), field('right', optional($.text)))
|
||||
// ),
|
||||
text: $ => prec.right(repeat1($._text_fragment)),
|
||||
|
||||
_text_fragment: $ => prec.right(choice($.word, ',', '=')),
|
||||
|
||||
word: $ => /[^\s\\%\{\},\$\[\]\(\)=\#]+/,
|
||||
|
||||
path: $ => /[^\*\"\[\]:;\|\{\}<>]+/,
|
||||
|
||||
param: $ => /#\d/,
|
||||
|
||||
//--- Math ---//
|
||||
|
||||
displayed_equation: $ =>
|
||||
prec.left(
|
||||
seq(
|
||||
field('left', choice('$$', '\\[')),
|
||||
field('child', repeat($._content)),
|
||||
field('right', choice('$$', '\\]'))
|
||||
)
|
||||
),
|
||||
|
||||
inline_formula: $ =>
|
||||
prec.left(
|
||||
seq(
|
||||
field('left', choice('$', '\\(')),
|
||||
field('child', repeat($._content)),
|
||||
field('right', choice('$', '\\)'))
|
||||
)
|
||||
),
|
||||
|
||||
//--- Environment ---//
|
||||
|
||||
begin: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', '\\begin'),
|
||||
'{',
|
||||
field('name', $.word),
|
||||
'}',
|
||||
field('option', repeat($.bracket_group))
|
||||
)
|
||||
),
|
||||
|
||||
end: $ => seq(field('command', '\\end'), '{', field('name', $.word), '}'),
|
||||
|
||||
environment: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('begin', $.begin),
|
||||
field('child', repeat($._content)),
|
||||
field('end', $.end)
|
||||
)
|
||||
),
|
||||
|
||||
//--- Special Commands ---//
|
||||
|
||||
caption: $ =>
|
||||
seq(
|
||||
field('command', '\\caption'),
|
||||
field('short', optional($.bracket_group)),
|
||||
field('long', $.brace_group)
|
||||
),
|
||||
|
||||
citation: $ =>
|
||||
seq(
|
||||
field('command', choice(...commands.citation)),
|
||||
optional(
|
||||
seq(
|
||||
field('prenote', $.bracket_group),
|
||||
field('postnote', optional($.bracket_group))
|
||||
)
|
||||
),
|
||||
'{',
|
||||
sepBy(field('key', $.word), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
package_include: $ =>
|
||||
seq(
|
||||
field('command', choice('\\usepackage', '\\RequirePackage')),
|
||||
field('option', optional($.key_val_options)),
|
||||
'{',
|
||||
sepBy(field('path', $.path), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
class_include: $ =>
|
||||
seq(
|
||||
field('command', '\\documentclass'),
|
||||
field('option', optional($.key_val_options)),
|
||||
'{',
|
||||
sepBy(field('path', $.path), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
latex_include: $ =>
|
||||
seq(
|
||||
field('command', choice('\\include', '\\subfileinclude')),
|
||||
'{',
|
||||
sepBy(field('path', $.path), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
latex_input: $ =>
|
||||
seq(
|
||||
field('command', choice('\\input', '\\subfile')),
|
||||
'{',
|
||||
sepBy(field('path', $.path), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
biblatex_include: $ =>
|
||||
seq(
|
||||
field('command', '\\addbibresource'),
|
||||
field('option', optional($.key_val_options)),
|
||||
'{',
|
||||
field('path', $.path),
|
||||
'}'
|
||||
),
|
||||
|
||||
bibtex_include: $ =>
|
||||
seq(
|
||||
field('command', '\\bibliography'),
|
||||
'{',
|
||||
sepBy(field('path', $.path), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
graphics_include: $ =>
|
||||
seq(
|
||||
field('command', '\\includegraphics'),
|
||||
field('option', optional($.key_val_options)),
|
||||
'{',
|
||||
sepBy(field('path', $.path), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
svg_include: $ =>
|
||||
seq(
|
||||
field('command', '\\includesvg'),
|
||||
field('option', optional($.key_val_options)),
|
||||
'{',
|
||||
sepBy(field('path', $.path), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
inkscape_include: $ =>
|
||||
seq(
|
||||
field('command', '\\includeinkscape'),
|
||||
field('option', optional($.key_val_options)),
|
||||
'{',
|
||||
sepBy(field('path', $.path), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
verbatim_include: $ =>
|
||||
seq(
|
||||
field('command', choice('\\verbatiminput', '\\VerbatimInput')),
|
||||
'{',
|
||||
sepBy(field('path', $.path), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
import: $ =>
|
||||
seq(
|
||||
field(
|
||||
'command',
|
||||
choice(
|
||||
'\\import',
|
||||
'\\subimport',
|
||||
'\\inputfrom',
|
||||
'\\subimportfrom',
|
||||
'\\includefrom',
|
||||
'\\subincludefrom'
|
||||
)
|
||||
),
|
||||
'{',
|
||||
field('directory', $.path),
|
||||
'}',
|
||||
'{',
|
||||
field('file', $.path),
|
||||
'}'
|
||||
),
|
||||
|
||||
label_definition: $ =>
|
||||
seq(field('command', '\\label'), '{', field('name', $.word), '}'),
|
||||
|
||||
label_reference: $ =>
|
||||
seq(
|
||||
field('command', choice(...commands.labelReference)),
|
||||
'{',
|
||||
sepBy(field('label', $.word), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
equation_label_reference: $ =>
|
||||
seq(
|
||||
field('command', '\\eqref'),
|
||||
'{',
|
||||
sepBy1(field('label', $.word), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
label_reference_range: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', choice(...commands.labelRangeReference)),
|
||||
'{',
|
||||
field('label1', $.word),
|
||||
'}',
|
||||
// optional to improve error handling
|
||||
optional(seq('{', field('label2', $.word), '}'))
|
||||
)
|
||||
),
|
||||
|
||||
label_number: $ =>
|
||||
seq(
|
||||
field('command', '\\newlabel'),
|
||||
'{',
|
||||
field('label', $.word),
|
||||
'}',
|
||||
field('number', $.brace_group)
|
||||
),
|
||||
|
||||
command_definition: $ =>
|
||||
seq(
|
||||
field(
|
||||
'command',
|
||||
choice('\\newcommand', '\\renewcommand', '\\DeclareRobustCommand')
|
||||
),
|
||||
field('argc', optional(seq('[', /\d/, ']'))),
|
||||
'{',
|
||||
field('name', $.generic_command_name),
|
||||
'}',
|
||||
field('implementation', $.brace_group)
|
||||
),
|
||||
|
||||
math_operator: $ =>
|
||||
seq(
|
||||
field(
|
||||
'command',
|
||||
choice('\\DeclareMathOperator', '\\DeclareMathOperator*')
|
||||
),
|
||||
'{',
|
||||
field('name', $.generic_command_name),
|
||||
'}',
|
||||
field('implementation', $.brace_group)
|
||||
),
|
||||
|
||||
glossary_entry_definition: $ =>
|
||||
seq(
|
||||
field('command', '\\newglossaryentry'),
|
||||
'{',
|
||||
field('name', $.word),
|
||||
'}',
|
||||
'{',
|
||||
sepBy(field('property', $.key_val_pair), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
glossary_entry_reference: $ =>
|
||||
seq(
|
||||
field('command', choice(...commands.glossaryEntryReference)),
|
||||
field('option', optional($.key_val_options)),
|
||||
'{',
|
||||
field('name', $.word),
|
||||
'}'
|
||||
),
|
||||
|
||||
acronym_definition: $ =>
|
||||
seq(
|
||||
'\\newacronym',
|
||||
field('option', optional($.key_val_options)),
|
||||
'{',
|
||||
field('name', $.word),
|
||||
'}',
|
||||
field('short', $.brace_group),
|
||||
field('long', $.brace_group)
|
||||
),
|
||||
|
||||
acronym_reference: $ =>
|
||||
seq(
|
||||
field('command', choice(...commands.acronymReference)),
|
||||
field('option', optional($.key_val_options)),
|
||||
'{',
|
||||
field('name', $.word),
|
||||
'}'
|
||||
),
|
||||
theorem_definition: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', choice('\\newtheorem', '\\declaretheorem')),
|
||||
'{',
|
||||
field('name', $.word),
|
||||
'}',
|
||||
choice(
|
||||
seq(
|
||||
field('title', $.brace_group),
|
||||
optional(seq('[', field('counter', $.word), ']'))
|
||||
),
|
||||
seq(
|
||||
'[',
|
||||
field('counter', $.word),
|
||||
']',
|
||||
field('title', $.brace_group)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
color_reference: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field(
|
||||
'command',
|
||||
choice('\\color', '\\colorbox', '\\textcolor', '\\pagecolor')
|
||||
),
|
||||
'{',
|
||||
field('name', $.word),
|
||||
'}'
|
||||
)
|
||||
),
|
||||
|
||||
color_definition: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', '\\definecolor'),
|
||||
'{',
|
||||
field('name', $.word),
|
||||
'}',
|
||||
'{',
|
||||
field('model', $.word),
|
||||
'}',
|
||||
// optional to improve error handling
|
||||
optional(seq('{', field('spec', $.text), '}'))
|
||||
)
|
||||
),
|
||||
|
||||
color_set_definition: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command', '\\definecolorset'),
|
||||
optional(seq('[', field('ty', $.word), ']')),
|
||||
'{',
|
||||
sepBy(field('model', $.word), ','),
|
||||
'}',
|
||||
optional(
|
||||
// optional to improve error handling
|
||||
seq(
|
||||
field('head', $.brace_group),
|
||||
field('tail', $.brace_group),
|
||||
field('spec', $.brace_group)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
pgf_library_import: $ =>
|
||||
seq(
|
||||
field('command', '\\usepgflibrary'),
|
||||
'{',
|
||||
sepBy(field('name', $.word), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
tikz_library_import: $ =>
|
||||
seq(
|
||||
field('command', '\\usetikzlibrary'),
|
||||
'{',
|
||||
sepBy(field('name', $.word), ','),
|
||||
'}'
|
||||
),
|
||||
|
||||
//--- Generic commands ---//
|
||||
|
||||
generic_command: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('name', $.generic_command_name),
|
||||
field(
|
||||
'arg',
|
||||
repeat(choice($.brace_group, $.mixed_group))
|
||||
)
|
||||
)
|
||||
$.math_set,
|
||||
$.text,
|
||||
$.macro_parameter,
|
||||
$._command
|
||||
),
|
||||
|
||||
generic_command_name: $ => /\\([^\r\n]|[@a-zA-Z]+\*?)?/,
|
||||
_contextual_delimiter: $ => choice(',', '=', '(', ')'),
|
||||
},
|
||||
});
|
||||
|
||||
@ -0,0 +1,191 @@
|
||||
/// <reference types="tree-sitter-cli/dsl" />
|
||||
// @ts-check
|
||||
|
||||
const { commandName } = require('../util');
|
||||
|
||||
module.exports = {
|
||||
_command: $ =>
|
||||
choice(
|
||||
$._include,
|
||||
$.caption,
|
||||
$.citation,
|
||||
$.label_definition,
|
||||
$.label_reference,
|
||||
$.label_reference_range,
|
||||
$.label_number,
|
||||
$.new_command_definition,
|
||||
$.old_command_definition,
|
||||
$.let_command_definition,
|
||||
$.environment_definition,
|
||||
$.glossary_entry_definition,
|
||||
$.glossary_entry_reference,
|
||||
$.acronym_definition,
|
||||
$.acronym_reference,
|
||||
$.theorem_definition,
|
||||
$.color_definition,
|
||||
$.color_set_definition,
|
||||
$.color_reference,
|
||||
$.tikz_library_import,
|
||||
alias($._generic_command, $.command),
|
||||
),
|
||||
|
||||
_generic_command: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
field('command_name', alias($._generic_command_name, $.command_name)),
|
||||
repeat(choice($.curly_group, $.mixed_group)),
|
||||
),
|
||||
),
|
||||
|
||||
caption: $ =>
|
||||
seq(
|
||||
commandName($, 'caption'),
|
||||
field('list_entry', optional($.brack_group)),
|
||||
field('heading', $.curly_group),
|
||||
),
|
||||
|
||||
citation: $ =>
|
||||
seq(
|
||||
commandName($, 'citation'),
|
||||
optional(
|
||||
seq(
|
||||
field('prenote', $.brack_group),
|
||||
field('postnote', optional($.brack_group)),
|
||||
),
|
||||
),
|
||||
$.curly_group_key_list,
|
||||
),
|
||||
|
||||
label_definition: $ =>
|
||||
seq(commandName($, 'label_definition'), field('name', $.curly_group_key)),
|
||||
|
||||
label_reference: $ =>
|
||||
seq(
|
||||
commandName($, 'label_reference'),
|
||||
field('names', $.curly_group_key_list),
|
||||
),
|
||||
|
||||
label_reference_range: $ =>
|
||||
seq(
|
||||
commandName($, 'label_reference_range'),
|
||||
field('name_lo', $.curly_group_key),
|
||||
field('name_hi', $.curly_group_key),
|
||||
),
|
||||
|
||||
label_number: $ =>
|
||||
seq(
|
||||
commandName($, 'label_number'),
|
||||
field('name', $.curly_group_key),
|
||||
field('number', $.curly_group),
|
||||
),
|
||||
|
||||
new_command_definition: $ =>
|
||||
seq(
|
||||
commandName($, 'new_command_definition'),
|
||||
field('declaration', $.curly_group_command_name),
|
||||
field('argc', optional($.brack_group_argc)),
|
||||
field('implementation', $.curly_group),
|
||||
),
|
||||
|
||||
old_command_definition: $ =>
|
||||
seq(
|
||||
commandName($, 'old_command_definition'),
|
||||
field('declaration', alias($._generic_command_name, $.command_name)),
|
||||
),
|
||||
|
||||
let_command_definition: $ =>
|
||||
seq(
|
||||
commandName($, 'let_command_definition'),
|
||||
field('declaration', alias($._generic_command_name, $.command_name)),
|
||||
optional('='),
|
||||
field('implementation', alias($._generic_command_name, $.command_name)),
|
||||
),
|
||||
|
||||
environment_definition: $ =>
|
||||
seq(
|
||||
commandName($, 'environment_definition'),
|
||||
field('name', $.curly_group_key),
|
||||
field('argc', optional($.brack_group_argc)),
|
||||
field('begin', $.curly_group_impl),
|
||||
field('end', $.curly_group_impl),
|
||||
),
|
||||
|
||||
glossary_entry_definition: $ =>
|
||||
seq(
|
||||
commandName($, 'glossary_entry_definition'),
|
||||
field('name', $.curly_group_key),
|
||||
field('properties', $.curly_group_key_value),
|
||||
),
|
||||
|
||||
glossary_entry_reference: $ =>
|
||||
seq(
|
||||
commandName($, 'glossary_entry_reference'),
|
||||
field('options', optional($.brack_group_key_value)),
|
||||
field('name', $.curly_group_key),
|
||||
),
|
||||
|
||||
acronym_definition: $ =>
|
||||
seq(
|
||||
commandName($, 'acronym_definition'),
|
||||
field('options', optional($.brack_group_key_value)),
|
||||
field('name', $.curly_group_key),
|
||||
field('abbrv', $.curly_group),
|
||||
field('full', $.curly_group),
|
||||
),
|
||||
|
||||
acronym_reference: $ =>
|
||||
seq(
|
||||
commandName($, 'acronym_reference'),
|
||||
field('options', optional($.brack_group_key_value)),
|
||||
field('name', $.curly_group_key),
|
||||
),
|
||||
|
||||
theorem_definition: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
commandName($, 'theorem_definition'),
|
||||
field('options', optional($.brack_group_key_value)),
|
||||
field('name', $.curly_group_key),
|
||||
optional(
|
||||
choice(
|
||||
seq(
|
||||
field('heading', $.curly_group),
|
||||
field('counter', optional($.brack_group_key)),
|
||||
),
|
||||
seq(
|
||||
field('counter', $.brack_group_key),
|
||||
field('heading', $.curly_group),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
color_definition: $ =>
|
||||
seq(
|
||||
commandName($, 'color_definition'),
|
||||
field('kind', optional($.brack_group_key)),
|
||||
field('name', $.curly_group_key),
|
||||
field('model', $.curly_group_key),
|
||||
field('spec', $.curly_group_text),
|
||||
),
|
||||
|
||||
color_set_definition: $ =>
|
||||
seq(
|
||||
commandName($, 'color_set_definition'),
|
||||
field('kind', optional($.brack_group_key)),
|
||||
field('model', $.curly_group_key_list),
|
||||
field('head', $.curly_group),
|
||||
field('tail', $.curly_group),
|
||||
field('spec', $.curly_group),
|
||||
),
|
||||
|
||||
color_reference: $ =>
|
||||
seq(commandName($, 'color_reference'), field('name', $.curly_group_key)),
|
||||
|
||||
tikz_library_import: $ =>
|
||||
seq(
|
||||
commandName($, 'tikz_library_import'),
|
||||
field('name', $.curly_group_key),
|
||||
),
|
||||
};
|
||||
@ -0,0 +1,66 @@
|
||||
/// <reference types="tree-sitter-cli/dsl" />
|
||||
// @ts-check
|
||||
|
||||
const { commandName } = require('../util');
|
||||
|
||||
const verbatimEnvironment = (prefix, name, lexerRule) => ({
|
||||
[`_${prefix}_environment`]: $ =>
|
||||
seq(
|
||||
field('begin', alias($[`_${prefix}_begin`], $.begin)),
|
||||
alias($[lexerRule], $.comment),
|
||||
field('end', alias($[`_${prefix}_end`], $.end)),
|
||||
),
|
||||
|
||||
[`_${prefix}_begin`]: $ =>
|
||||
seq(
|
||||
commandName($, 'begin'),
|
||||
field('name', alias($[`_${prefix}_curly_group_key`], $.curly_group_key)),
|
||||
field('options', optional($.brack_group)),
|
||||
),
|
||||
|
||||
[`_${prefix}_end`]: $ =>
|
||||
seq(
|
||||
commandName($, 'end'),
|
||||
field('name', alias($[`_${prefix}_curly_group_key`], $.curly_group_key)),
|
||||
),
|
||||
|
||||
[`_${prefix}_curly_group_key`]: $ =>
|
||||
seq(
|
||||
field('left', '{'),
|
||||
field('key', alias($[`_${prefix}_key`], $.key)),
|
||||
field('right', '}'),
|
||||
),
|
||||
|
||||
[`_${prefix}_key`]: $ => seq(field('word', alias(name, $.word))),
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
_environment: $ =>
|
||||
choice(
|
||||
$._comment_environment,
|
||||
$._verbatim_environment,
|
||||
$._listing_environment,
|
||||
$._generic_environment,
|
||||
),
|
||||
|
||||
// Regular environment
|
||||
_generic_environment: $ =>
|
||||
seq(field('begin', $.begin), repeat($._full_content), field('end', $.end)),
|
||||
|
||||
begin: $ =>
|
||||
prec.right(
|
||||
seq(
|
||||
commandName($, 'begin'),
|
||||
field('name', $.curly_group_key),
|
||||
field('options', optional($.brack_group)),
|
||||
),
|
||||
),
|
||||
|
||||
end: $ =>
|
||||
prec.right(seq(commandName($, 'end'), field('name', $.curly_group_key))),
|
||||
|
||||
// Verbatim environments
|
||||
...verbatimEnvironment('comment', 'comment', '_verbatim_env_comment'),
|
||||
...verbatimEnvironment('verbatim', 'verbatim', '_verbatim_env_verbatim'),
|
||||
...verbatimEnvironment('listing', 'lstlisting', '_verbatim_env_listing'),
|
||||
};
|
||||
@ -0,0 +1,81 @@
|
||||
/// <reference types="tree-sitter-cli/dsl" />
|
||||
// @ts-check
|
||||
|
||||
const { sepBy } = require('../util');
|
||||
|
||||
const group = (left, content, right) =>
|
||||
seq(field('left', left), content, field('right', right));
|
||||
|
||||
module.exports = {
|
||||
curly_group: $ => group('{', repeat($._full_content), '}'),
|
||||
|
||||
curly_group_key: $ => group('{', field('key', $.key), '}'),
|
||||
|
||||
curly_group_key_list: $ => group('{', sepBy(field('key', $.key), ','), '}'),
|
||||
|
||||
curly_group_key_value: $ =>
|
||||
group('{', sepBy(field('property', $.key_value_pair), ','), '}'),
|
||||
|
||||
curly_group_path: $ => group('{', field('path', $.path), '}'),
|
||||
|
||||
curly_group_path_list: $ =>
|
||||
group('{', sepBy(field('path', $.path), ','), '}'),
|
||||
|
||||
curly_group_text: $ => group('{', field('text', $.text), '}'),
|
||||
|
||||
curly_group_command_name: $ =>
|
||||
group(
|
||||
'{',
|
||||
field('command_name', alias($._generic_command_name, $.command_name)),
|
||||
'}',
|
||||
),
|
||||
|
||||
curly_group_impl: $ => group('{', repeat($._minimal_content), '}'),
|
||||
|
||||
curly_group_glob_pattern: $ =>
|
||||
group('{', field('glob_pattern', $.glob_pattern), '}'),
|
||||
|
||||
brack_group: $ =>
|
||||
prec.right(
|
||||
group(
|
||||
'[',
|
||||
repeat(
|
||||
choice($._basic_content, $.brack_group, $._contextual_delimiter),
|
||||
),
|
||||
']',
|
||||
),
|
||||
),
|
||||
|
||||
brack_group_key: $ => prec.right(1, group('[', field('key', $.key), ']')),
|
||||
|
||||
brack_group_key_value: $ =>
|
||||
group('[', sepBy(field('property', $.key_value_pair), ','), ']'),
|
||||
|
||||
brack_group_argc: $ => group('[', field('argc', $.argc), ']'),
|
||||
|
||||
mixed_group: $ =>
|
||||
group(
|
||||
choice('[', '('),
|
||||
repeat(choice($._basic_content, $.mixed_group, choice(',', '='))),
|
||||
choice(']', ')'),
|
||||
),
|
||||
|
||||
key_value_pair: $ =>
|
||||
seq(field('key', $.key), optional(seq('=', field('value', $.value)))),
|
||||
|
||||
value: $ =>
|
||||
prec.right(
|
||||
repeat1(
|
||||
choice(
|
||||
$.curly_group,
|
||||
$.displayed_equation,
|
||||
$.inline_formula,
|
||||
$.text,
|
||||
$.macro_parameter,
|
||||
$._command,
|
||||
choice('(', ')'),
|
||||
$.brack_group,
|
||||
),
|
||||
),
|
||||
),
|
||||
};
|
||||
@ -0,0 +1,62 @@
|
||||
/// <reference types="tree-sitter-cli/dsl" />
|
||||
// @ts-check
|
||||
|
||||
const { commandName } = require('../util');
|
||||
|
||||
const basicInclude = ($, rule) =>
|
||||
seq(
|
||||
commandName($, rule),
|
||||
field('options', optional($.brack_group_key_value)),
|
||||
field('path', $.curly_group_path),
|
||||
);
|
||||
|
||||
module.exports = {
|
||||
_include: $ =>
|
||||
choice(
|
||||
$.package_include,
|
||||
$.class_include,
|
||||
$.latex_include,
|
||||
$.biblatex_include,
|
||||
$.bibtex_include,
|
||||
$.graphics_include,
|
||||
$.svg_include,
|
||||
$.inkscape_include,
|
||||
$.verbatim_include,
|
||||
$.import,
|
||||
),
|
||||
|
||||
package_include: $ =>
|
||||
seq(
|
||||
commandName($, 'package_include'),
|
||||
field('options', optional($.brack_group_key_value)),
|
||||
field('paths', $.curly_group_path_list),
|
||||
),
|
||||
|
||||
class_include: $ => basicInclude($, 'class_include'),
|
||||
|
||||
latex_include: $ => basicInclude($, 'latex_include'),
|
||||
|
||||
biblatex_include: $ =>
|
||||
seq(
|
||||
commandName($, 'biblatex_include'),
|
||||
field('options', optional($.brack_group_key_value)),
|
||||
field('glob_pattern', $.curly_group_glob_pattern),
|
||||
),
|
||||
|
||||
bibtex_include: $ => basicInclude($, 'bibtex_include'),
|
||||
|
||||
graphics_include: $ => basicInclude($, 'graphics_include'),
|
||||
|
||||
svg_include: $ => basicInclude($, 'svg_include'),
|
||||
|
||||
inkscape_include: $ => basicInclude($, 'inkscape_include'),
|
||||
|
||||
verbatim_include: $ => basicInclude($, 'verbatim_include'),
|
||||
|
||||
import: $ =>
|
||||
seq(
|
||||
commandName($, 'import'),
|
||||
field('directory', $.curly_group_path),
|
||||
field('file', $.curly_group_path),
|
||||
),
|
||||
};
|
||||
@ -0,0 +1,22 @@
|
||||
/// <reference types="tree-sitter-cli/dsl" />
|
||||
// @ts-check
|
||||
|
||||
const commands = require('./commands');
|
||||
const environments = require('./environments');
|
||||
const groups = require('./groups');
|
||||
const includes = require('./includes');
|
||||
const math = require('./math');
|
||||
const sections = require('./sections');
|
||||
const text = require('./text');
|
||||
const trivia = require('./trivia');
|
||||
|
||||
module.exports = {
|
||||
...commands,
|
||||
...environments,
|
||||
...groups,
|
||||
...includes,
|
||||
...math,
|
||||
...sections,
|
||||
...text,
|
||||
...trivia,
|
||||
};
|
||||
@ -0,0 +1,26 @@
|
||||
module.exports = {
|
||||
displayed_equation: $ =>
|
||||
prec.left(
|
||||
seq(
|
||||
choice('$$', alias($._escaped_lbrack_command_name, $.command_name)),
|
||||
repeat($._full_content),
|
||||
choice('$$', alias($._escaped_rbrack_command_name, $.command_name)),
|
||||
),
|
||||
),
|
||||
|
||||
inline_formula: $ =>
|
||||
prec.left(
|
||||
seq(
|
||||
choice('$', alias($._escaped_lparen_command_name, $.command_name)),
|
||||
repeat($._full_content),
|
||||
choice('$', alias($._escaped_rparen_command_name, $.command_name)),
|
||||
),
|
||||
),
|
||||
|
||||
math_set: $ =>
|
||||
seq(
|
||||
field('left', alias($._escaped_lcurly_command_name, $.command_name)),
|
||||
repeat($._full_content),
|
||||
field('right', alias($._escaped_rcurly_command_name, $.command_name)),
|
||||
),
|
||||
};
|
||||
@ -0,0 +1,76 @@
|
||||
/// <reference types="tree-sitter-cli/dsl" />
|
||||
|
||||
const { commandName } = require('../util');
|
||||
|
||||
// @ts-check
|
||||
|
||||
const SECTIONS = [
|
||||
{
|
||||
rule: 'part',
|
||||
group: 'curly_group',
|
||||
},
|
||||
{
|
||||
rule: 'chapter',
|
||||
group: 'curly_group',
|
||||
},
|
||||
{
|
||||
rule: 'section',
|
||||
group: 'curly_group',
|
||||
},
|
||||
{
|
||||
rule: 'subsection',
|
||||
group: 'curly_group',
|
||||
},
|
||||
{
|
||||
rule: 'subsubsection',
|
||||
group: 'curly_group',
|
||||
},
|
||||
{
|
||||
rule: 'paragraph',
|
||||
group: 'curly_group',
|
||||
},
|
||||
{
|
||||
rule: 'subparagraph',
|
||||
group: 'curly_group',
|
||||
},
|
||||
{
|
||||
rule: 'enum_item',
|
||||
group: 'brack_group_key',
|
||||
},
|
||||
];
|
||||
|
||||
const rules = {};
|
||||
|
||||
(() => {
|
||||
for (let i = 0; i < SECTIONS.length; i++) {
|
||||
const { rule, group } = SECTIONS[i];
|
||||
|
||||
let start = i + 1;
|
||||
const layer = `_${rule}_layer`;
|
||||
|
||||
rules[layer] = $ => {
|
||||
return prec.right(
|
||||
choice(
|
||||
...SECTIONS.slice(start).map(section => repeat1($[section.rule])),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
rules[rule] = $ => {
|
||||
return prec.right(
|
||||
1,
|
||||
seq(
|
||||
commandName($, rule),
|
||||
field('heading', optional($[group])),
|
||||
repeat(choice($._basic_content, $._contextual_delimiter, '[', ']')),
|
||||
optional($[layer]),
|
||||
),
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
rules._section = $ =>
|
||||
prec.right(choice(...SECTIONS.map(({ rule }) => repeat1($[rule]))));
|
||||
})();
|
||||
|
||||
module.exports = { ...rules };
|
||||
@ -0,0 +1,26 @@
|
||||
/// <reference types="tree-sitter-cli/dsl" />
|
||||
// @ts-check
|
||||
|
||||
module.exports = {
|
||||
key: $ => $._words,
|
||||
|
||||
text: $ => $._words,
|
||||
|
||||
_words: $ => prec.right(repeat1(field('word', $.word))),
|
||||
|
||||
word: $ => /[^\s\\%\{\},\$\[\]\(\)=\#]+/,
|
||||
|
||||
glob_pattern: $ => repeat1($._glob_pattern_fragment),
|
||||
|
||||
_glob_pattern_fragment: $ =>
|
||||
choice(
|
||||
seq('{', repeat($._glob_pattern_fragment), '}'),
|
||||
/[^\"\[\]:;\|\{\}<>]+/,
|
||||
),
|
||||
|
||||
path: $ => /[^\*\"\[\]:;,\|\{\}<>]+/,
|
||||
|
||||
argc: $ => /\d/,
|
||||
|
||||
macro_parameter: $ => /#\d/,
|
||||
};
|
||||
@ -0,0 +1,15 @@
|
||||
/// <reference types="tree-sitter-cli/dsl" />
|
||||
// @ts-check
|
||||
|
||||
module.exports = {
|
||||
_whitespace: $ => /\s+/,
|
||||
|
||||
line_comment: $ => /%[^\r\n]*/,
|
||||
|
||||
block_comment: $ =>
|
||||
seq(
|
||||
field('left', alias($._iffalse_command_name, $.command_name)),
|
||||
field('comment', optional(alias($._verbatim_cmd_fi, $.comment))),
|
||||
field('right', alias($._fi_command_name, $.command_name)),
|
||||
),
|
||||
};
|
||||
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,456 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tree_sitter/parser.h>
|
||||
|
||||
#define ALPHABET_SIZE 128
|
||||
|
||||
typedef struct trie {
|
||||
struct trie *children[ALPHABET_SIZE];
|
||||
int value;
|
||||
} trie;
|
||||
|
||||
static trie *trie_new() {
|
||||
trie *root = (trie *)malloc(sizeof(trie));
|
||||
root->value = 0;
|
||||
memset(root->children, 0, sizeof(trie *) * ALPHABET_SIZE);
|
||||
return root;
|
||||
}
|
||||
|
||||
static void trie_insert(trie *root, char *key, int value) {
|
||||
trie *node = root;
|
||||
for (int i = 0; key[i]; i++) {
|
||||
int c = (int)key[i];
|
||||
if (!node->children[c]) {
|
||||
node->children[c] = trie_new();
|
||||
}
|
||||
|
||||
node = node->children[c];
|
||||
}
|
||||
|
||||
node->value = value;
|
||||
}
|
||||
|
||||
static void trie_insert_group(trie *root, char **keys, int value) {
|
||||
for (int i = 0; keys[i]; i++) {
|
||||
trie_insert(root, keys[i], value);
|
||||
}
|
||||
}
|
||||
|
||||
static trie *trie_lookup(trie *root, int32_t c) {
|
||||
return root && (c < ALPHABET_SIZE) ? root->children[c] : NULL;
|
||||
}
|
||||
|
||||
static void trie_free(trie *root) {
|
||||
for (int i = 0; i < ALPHABET_SIZE; i++) {
|
||||
if (root->children[i]) {
|
||||
trie_free(root->children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free(root);
|
||||
}
|
||||
|
||||
static char *citation_commands[] = {
|
||||
"cite", "cite*", "Cite", "nocite", "citet",
|
||||
"citep", "citet*", "citep*", "citeauthor", "citeauthor*",
|
||||
"Citeauthor", "Citeauthor*", "citetitle", "citetitle*", "citeyear",
|
||||
"citeyear*", "citedate", "citedate*", "citeurl", "fullcite",
|
||||
"citeyearpar", "citealt", "citealp", "citetext", "parencite",
|
||||
"parencite*", "Parencite", "footcite", "footfullcite", "footcitetext",
|
||||
"textcite", "Textcite", "smartcite", "Smartcite", "supercite",
|
||||
"autocite", "Autocite", "autocite*", "Autocite*", "volcite",
|
||||
"Volcite", "pvolcite", "Pvolcite", "fvolcite", "ftvolcite",
|
||||
"svolcite", "Svolcite", "tvolcite", "Tvolcite", "avolcite",
|
||||
"Avolcite", "notecite", "notecite", "pnotecite", "Pnotecite",
|
||||
"fnotecite", NULL};
|
||||
|
||||
static char *label_reference_commands[] = {
|
||||
"ref", "eqref", "vref", "Vref", "autoref",
|
||||
"pageref", "cref", "Cref", "cref*", "Cref*",
|
||||
"namecref", "nameCref", "lcnamecref", "namecrefs", "nameCrefs",
|
||||
"lcnamecrefs", "labelcref", "labelcpageref", NULL};
|
||||
|
||||
static char *label_reference_range_commands[] = {
|
||||
"crefrange", "crefrange", "Crefrange", "Crefrange", "crefrange*",
|
||||
"crefrange*", "Crefrange*", "Crefrange*", NULL};
|
||||
|
||||
static char *new_command_definition_commands[] = {
|
||||
"newcommand", "newcommand*", "renewcommand",
|
||||
"renewcommand*", "DeclareRobustCommand", "DeclareRobustCommand*",
|
||||
"DeclareMathOperator", "DeclareMathOperator*", NULL};
|
||||
|
||||
static char *glossary_entry_reference_commands[] = {"gls",
|
||||
"Gls",
|
||||
"GLS",
|
||||
"glspl",
|
||||
"Glspl",
|
||||
"GLSpl",
|
||||
"glsdisp",
|
||||
"glslink",
|
||||
"glstext",
|
||||
"Glstext",
|
||||
"GLStext",
|
||||
"glsfirst",
|
||||
"Glsfirst",
|
||||
"GLSfirst",
|
||||
"glsplural",
|
||||
"Glsplural",
|
||||
"GLSplural",
|
||||
"glsfirstplural",
|
||||
"Glsfirstplural",
|
||||
"GLSfirstplural",
|
||||
"glsname",
|
||||
"Glsname",
|
||||
"GLSname",
|
||||
"glssymbol",
|
||||
"Glssymbol",
|
||||
"glsdesc",
|
||||
"Glsdesc",
|
||||
"GLSdesc",
|
||||
"glsuseri",
|
||||
"Glsuseri",
|
||||
"GLSuseri",
|
||||
"glsuserii",
|
||||
"Glsuserii",
|
||||
"GLSuserii",
|
||||
"glsuseriii",
|
||||
"Glsuseriii",
|
||||
"GLSuseriii",
|
||||
"glsuseriv",
|
||||
"Glsuseriv",
|
||||
"GLSuseriv",
|
||||
"glsuserv",
|
||||
"Glsuserv",
|
||||
"GLSuserv",
|
||||
"glsuservi",
|
||||
"Glsuservi",
|
||||
"GLSuservi",
|
||||
NULL};
|
||||
|
||||
static char *acronym_reference_commands[] = {"acrshort",
|
||||
"Acrshort",
|
||||
"ACRshort",
|
||||
"acrshortpl",
|
||||
"Acrshortpl",
|
||||
"ACRshortpl",
|
||||
"acrlong",
|
||||
"Acrlong",
|
||||
"ACRlong",
|
||||
"acrlongpl",
|
||||
"Acrlongpl",
|
||||
"ACRlongpl",
|
||||
"acrfull",
|
||||
"Acrfull",
|
||||
"ACRfull",
|
||||
"acrfullpl",
|
||||
"Acrfullpl",
|
||||
"ACRfullpl",
|
||||
"acs",
|
||||
"Acs",
|
||||
"acsp",
|
||||
"Acsp",
|
||||
"acl",
|
||||
"Acl",
|
||||
"aclp",
|
||||
"Aclp",
|
||||
"acf",
|
||||
"Acf",
|
||||
"acfp",
|
||||
"Acfp",
|
||||
"ac",
|
||||
"Ac",
|
||||
"acp",
|
||||
"glsentrylong",
|
||||
"Glsentrylong",
|
||||
"glsentrylongpl",
|
||||
"Glsentrylongpl",
|
||||
"glsentryshort",
|
||||
"Glsentryshort",
|
||||
"glsentryshortpl",
|
||||
"Glsentryshortpl",
|
||||
"glsentryfullpl",
|
||||
"Glsentryfullpl",
|
||||
NULL};
|
||||
|
||||
static char *theorem_definition_commands[] = {"newtheorem", "declaretheorem",
|
||||
NULL};
|
||||
|
||||
static char *color_reference_commands[] = {"color", "colorbox", "textcolor",
|
||||
"pagecolor", NULL};
|
||||
|
||||
static char *tikz_library_import_commands[] = {"usepgflibrary",
|
||||
"usetikzlibrary", NULL};
|
||||
|
||||
static char *package_include_commands[] = {"usepackage", "RequirePackage",
|
||||
NULL};
|
||||
|
||||
static char *latex_include_commands[] = {"include", "subfileinclude", "input",
|
||||
"subfile", NULL};
|
||||
|
||||
static char *verbatim_include_commmands[] = {"verbatiminput", "VerbatimInput",
|
||||
NULL};
|
||||
|
||||
static char *import_commands[] = {
|
||||
"import", "subimport", "inputfrom", "subimportfrom",
|
||||
"includefrom", "subincludefrom", NULL};
|
||||
|
||||
static char *part_commands[] = {"part", "part*", NULL};
|
||||
|
||||
static char *chapter_commands[] = {"chapter", "chapter*", NULL};
|
||||
|
||||
static char *section_commands[] = {"section", "section*", NULL};
|
||||
|
||||
static char *subsection_commands[] = {"subsection", "subsection*", NULL};
|
||||
|
||||
static char *subsubsection_commands[] = {"subsubsection", "subsubsection*",
|
||||
NULL};
|
||||
|
||||
static char *paragraph_commands[] = {"paragraph", "paragraph*", NULL};
|
||||
|
||||
static char *subparagraph_commands[] = {"subparagraph", "subparagraph*", NULL};
|
||||
|
||||
static char *enum_item_commands[] = {"item", NULL};
|
||||
|
||||
enum TokenType {
|
||||
CMD_GENERIC,
|
||||
CMD_BEGIN,
|
||||
CMD_END,
|
||||
CMD_IFFALSE,
|
||||
CMD_FI,
|
||||
CMD_CAPTION,
|
||||
CMD_CITATION,
|
||||
CMD_LABEL_DEFINITION,
|
||||
CMD_LABEL_REFERENCE,
|
||||
CMD_LABEL_REFERENCE_RANGE,
|
||||
CMD_LABEL_NUMBER,
|
||||
CMD_NEW_CMD_DEFINITION,
|
||||
CMD_OLD_CMD_DEFINITION,
|
||||
CMD_LET_CMD_DEFINITION,
|
||||
CMD_ENV_DEFINITION,
|
||||
CMD_GLOSSARY_ENTRY_DEFINITION,
|
||||
CMD_GLOSSARY_ENTRY_REFERENCE,
|
||||
CMD_ACRONYM_DEFINITION,
|
||||
CMD_ACRONYM_REFERENCE,
|
||||
CMD_THEOREM_DEFINITION,
|
||||
CMD_COLOR_DEFINITION,
|
||||
CMD_COLOR_SET_DEFINITION,
|
||||
CMD_COLOR_REFERENCE,
|
||||
CMD_TIKZ_LIBRARY_IMPORT,
|
||||
CMD_PACKAGE_INCLUDE,
|
||||
CMD_CLASS_INCLUDE,
|
||||
CMD_LATEX_INCLUDE,
|
||||
CMD_BIBLATEX_INCLUDE,
|
||||
CMD_BIBTEX_INCLUDE,
|
||||
CMD_GRAPHICS_INCLUDE,
|
||||
CMD_SVG_INCLUDE,
|
||||
CMD_INKSCAPE_INCLUDE,
|
||||
CMD_VERBATIM_INCLUDE,
|
||||
CMD_IMPORT,
|
||||
CMD_ESCAPED_LPAREN,
|
||||
CMD_ESCAPED_RPAREN,
|
||||
CMD_ESCAPED_LBRACK,
|
||||
CMD_ESCAPED_RBRACK,
|
||||
CMD_ESCAPED_LCURLY,
|
||||
CMD_ESCAPED_RCURLY,
|
||||
CMD_PART,
|
||||
CMD_CHAPTER,
|
||||
CMD_SECTION,
|
||||
CMD_SUBSECTION,
|
||||
CMD_SUBSUBSECTION,
|
||||
CMD_PARAGRAPH,
|
||||
CMD_SUBPARAGRAPH,
|
||||
CMD_ENUM_ITEM,
|
||||
VERBATIM_CMD_FI,
|
||||
VERBATIM_ENV_COMMENT,
|
||||
VERBATIM_ENV_VERBATIM,
|
||||
VERBATIM_ENV_LISTING,
|
||||
VERBATIM_ENV_MINTED,
|
||||
};
|
||||
|
||||
static bool is_part_of_command_name(int32_t c) {
|
||||
switch (c) {
|
||||
case '_':
|
||||
case ':':
|
||||
case '*':
|
||||
return true;
|
||||
default:
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
|
||||
}
|
||||
}
|
||||
|
||||
static int scan_command_name(TSLexer *lexer, trie *commands) {
|
||||
trie *node = commands;
|
||||
bool escape = true;
|
||||
|
||||
lexer->advance(lexer, false);
|
||||
while (!lexer->eof(lexer)) {
|
||||
int c = lexer->lookahead;
|
||||
if (!is_part_of_command_name(c)) {
|
||||
break;
|
||||
}
|
||||
|
||||
node = trie_lookup(node, c);
|
||||
lexer->advance(lexer, false);
|
||||
escape = false;
|
||||
}
|
||||
|
||||
if (!lexer->eof(lexer)) {
|
||||
int c = lexer->lookahead;
|
||||
if (c != '\r' && c != '\n' && (escape || c == '*')) {
|
||||
node = trie_lookup(node, c);
|
||||
lexer->advance(lexer, false);
|
||||
}
|
||||
}
|
||||
|
||||
return node ? node->value : CMD_GENERIC;
|
||||
}
|
||||
|
||||
static bool scan_keyword(TSLexer *lexer, const char *keyword) {
|
||||
if (keyword) {
|
||||
for (int i = 0; keyword[i]; i++) {
|
||||
if (lexer->eof(lexer) || lexer->lookahead != keyword[i]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lexer->advance(lexer, false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void scan_verbatim(TSLexer *lexer, trie *commands, int end_command_type,
|
||||
const char *end_keyword) {
|
||||
while (!lexer->eof(lexer)) {
|
||||
while (!lexer->eof(lexer) && lexer->lookahead != '\\') {
|
||||
lexer->advance(lexer, false);
|
||||
}
|
||||
|
||||
lexer->mark_end(lexer);
|
||||
if (lexer->eof(lexer)) {
|
||||
break;
|
||||
}
|
||||
|
||||
int command_type = scan_command_name(lexer, commands);
|
||||
if (command_type == end_command_type && scan_keyword(lexer, end_keyword)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *tree_sitter_latex_external_scanner_create() {
|
||||
trie *commands = trie_new();
|
||||
trie_insert(commands, "begin", CMD_BEGIN);
|
||||
trie_insert(commands, "end", CMD_END);
|
||||
trie_insert(commands, "iffalse", CMD_IFFALSE);
|
||||
trie_insert(commands, "fi", CMD_FI);
|
||||
trie_insert(commands, "caption", CMD_CAPTION);
|
||||
trie_insert_group(commands, citation_commands, CMD_CITATION);
|
||||
trie_insert(commands, "label", CMD_LABEL_DEFINITION);
|
||||
trie_insert_group(commands, label_reference_commands, CMD_LABEL_REFERENCE);
|
||||
trie_insert_group(commands, label_reference_range_commands,
|
||||
CMD_LABEL_REFERENCE_RANGE);
|
||||
trie_insert(commands, "newlabel", CMD_LABEL_NUMBER);
|
||||
trie_insert_group(commands, new_command_definition_commands,
|
||||
CMD_NEW_CMD_DEFINITION);
|
||||
trie_insert(commands, "def", CMD_OLD_CMD_DEFINITION);
|
||||
trie_insert(commands, "let", CMD_LET_CMD_DEFINITION);
|
||||
trie_insert(commands, "newenvironment", CMD_ENV_DEFINITION);
|
||||
trie_insert(commands, "newglossaryentry", CMD_GLOSSARY_ENTRY_DEFINITION);
|
||||
trie_insert_group(commands, glossary_entry_reference_commands,
|
||||
CMD_GLOSSARY_ENTRY_REFERENCE);
|
||||
trie_insert(commands, "newacronym", CMD_ACRONYM_DEFINITION);
|
||||
trie_insert_group(commands, acronym_reference_commands,
|
||||
CMD_ACRONYM_REFERENCE);
|
||||
trie_insert_group(commands, theorem_definition_commands,
|
||||
CMD_THEOREM_DEFINITION);
|
||||
trie_insert(commands, "definecolor", CMD_COLOR_DEFINITION);
|
||||
trie_insert(commands, "definecolorset", CMD_COLOR_SET_DEFINITION);
|
||||
trie_insert_group(commands, color_reference_commands, CMD_COLOR_REFERENCE);
|
||||
trie_insert_group(commands, tikz_library_import_commands,
|
||||
CMD_TIKZ_LIBRARY_IMPORT);
|
||||
trie_insert_group(commands, package_include_commands, CMD_PACKAGE_INCLUDE);
|
||||
trie_insert(commands, "documentclass", CMD_CLASS_INCLUDE);
|
||||
trie_insert_group(commands, latex_include_commands, CMD_LATEX_INCLUDE);
|
||||
trie_insert(commands, "addbibresource", CMD_BIBLATEX_INCLUDE);
|
||||
trie_insert(commands, "bibliography", CMD_BIBTEX_INCLUDE);
|
||||
trie_insert(commands, "includegraphics", CMD_GRAPHICS_INCLUDE);
|
||||
trie_insert(commands, "includesvg", CMD_SVG_INCLUDE);
|
||||
trie_insert(commands, "includeinkscape", CMD_INKSCAPE_INCLUDE);
|
||||
trie_insert_group(commands, verbatim_include_commmands, CMD_VERBATIM_INCLUDE);
|
||||
trie_insert_group(commands, import_commands, CMD_IMPORT);
|
||||
trie_insert(commands, "(", CMD_ESCAPED_LPAREN);
|
||||
trie_insert(commands, ")", CMD_ESCAPED_RPAREN);
|
||||
trie_insert(commands, "[", CMD_ESCAPED_LBRACK);
|
||||
trie_insert(commands, "]", CMD_ESCAPED_RBRACK);
|
||||
trie_insert(commands, "{", CMD_ESCAPED_LCURLY);
|
||||
trie_insert(commands, "}", CMD_ESCAPED_RCURLY);
|
||||
trie_insert_group(commands, part_commands, CMD_PART);
|
||||
trie_insert_group(commands, chapter_commands, CMD_CHAPTER);
|
||||
trie_insert_group(commands, section_commands, CMD_SECTION);
|
||||
trie_insert_group(commands, subsection_commands, CMD_SUBSECTION);
|
||||
trie_insert_group(commands, subsubsection_commands, CMD_SUBSUBSECTION);
|
||||
trie_insert_group(commands, paragraph_commands, CMD_PARAGRAPH);
|
||||
trie_insert_group(commands, subparagraph_commands, CMD_SUBPARAGRAPH);
|
||||
trie_insert_group(commands, enum_item_commands, CMD_ENUM_ITEM);
|
||||
return commands;
|
||||
}
|
||||
|
||||
void tree_sitter_latex_external_scanner_destroy(void *payload) {
|
||||
trie_free((trie *)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) {
|
||||
trie *commands = (trie *)payload;
|
||||
for (int i = VERBATIM_CMD_FI; i <= VERBATIM_ENV_MINTED; i++) {
|
||||
if (valid_symbols[i]) {
|
||||
for (int j = i + 1; j <= VERBATIM_ENV_MINTED; j++) {
|
||||
if (valid_symbols[j]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
lexer->result_symbol = i;
|
||||
switch (i) {
|
||||
case VERBATIM_CMD_FI:
|
||||
scan_verbatim(lexer, commands, CMD_FI, NULL);
|
||||
break;
|
||||
case VERBATIM_ENV_COMMENT:
|
||||
scan_verbatim(lexer, commands, CMD_END, "{comment}");
|
||||
break;
|
||||
case VERBATIM_ENV_VERBATIM:
|
||||
scan_verbatim(lexer, commands, CMD_END, "{verbatim}");
|
||||
break;
|
||||
case VERBATIM_ENV_LISTING:
|
||||
scan_verbatim(lexer, commands, CMD_END, "{lstlisting}");
|
||||
break;
|
||||
case VERBATIM_ENV_MINTED:
|
||||
scan_verbatim(lexer, commands, CMD_END, "{comment}");
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (lexer->lookahead != '\\') {
|
||||
return false;
|
||||
}
|
||||
|
||||
int command_type = scan_command_name(lexer, commands);
|
||||
lexer->mark_end(lexer);
|
||||
lexer->result_symbol =
|
||||
valid_symbols[command_type] ? command_type : CMD_GENERIC;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
================================================================================
|
||||
Command without arguments
|
||||
================================================================================
|
||||
|
||||
\foo bar
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(command
|
||||
(command_name))
|
||||
(text
|
||||
(word)))
|
||||
|
||||
================================================================================
|
||||
Command with one curly argument
|
||||
================================================================================
|
||||
|
||||
\foo{bar}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(command
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word)))))
|
||||
|
||||
================================================================================
|
||||
Command with one curly argument and one mixed argument
|
||||
================================================================================
|
||||
|
||||
\foo{bar}[baz]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(command
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word)))
|
||||
(mixed_group
|
||||
(text
|
||||
(word)))))
|
||||
|
||||
================================================================================
|
||||
Command with nested paren argument
|
||||
================================================================================
|
||||
|
||||
\foo([bar])
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(command
|
||||
(command_name)
|
||||
(mixed_group
|
||||
(mixed_group
|
||||
(text
|
||||
(word))))))
|
||||
|
||||
================================================================================
|
||||
Command with incomplete argument
|
||||
================================================================================
|
||||
|
||||
\foo{ \begin{document} \end{document}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(command
|
||||
(command_name))
|
||||
(ERROR
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word)))))))
|
||||
|
||||
================================================================================
|
||||
Acroynm definition
|
||||
================================================================================
|
||||
|
||||
\newacronym[foo={bar}]{gcd}{GCD}{Greatest Common Divisor}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(acronym_definition
|
||||
(command_name)
|
||||
(brack_group_key_value
|
||||
(key_value_pair
|
||||
(key
|
||||
(word))
|
||||
(value
|
||||
(curly_group
|
||||
(text
|
||||
(word))))))
|
||||
(curly_group_key
|
||||
(key
|
||||
(word)))
|
||||
(curly_group
|
||||
(text
|
||||
(word)))
|
||||
(curly_group
|
||||
(text
|
||||
(word)
|
||||
(word)
|
||||
(word)))))
|
||||
@ -1,11 +0,0 @@
|
||||
================================================================================
|
||||
Issue #7 (env vars in paths)
|
||||
================================================================================
|
||||
|
||||
\addbibresource{$HOME/ref.bib}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(document
|
||||
(biblatex_include
|
||||
(path)))
|
||||
@ -0,0 +1,202 @@
|
||||
================================================================================
|
||||
Simple environment
|
||||
================================================================================
|
||||
|
||||
\begin{document}
|
||||
|
||||
Hello World!
|
||||
|
||||
\end{document}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))))
|
||||
|
||||
================================================================================
|
||||
Environment with options
|
||||
================================================================================
|
||||
|
||||
\begin{document}[foo bar]
|
||||
|
||||
Hello World!
|
||||
|
||||
\end{document}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word)))
|
||||
(brack_group
|
||||
(text
|
||||
(word)
|
||||
(word))))
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))))
|
||||
|
||||
================================================================================
|
||||
Environment with nested options
|
||||
================================================================================
|
||||
|
||||
\begin{document}[foo [bar] (baz)]
|
||||
|
||||
Hello World!
|
||||
|
||||
\end{document}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word)))
|
||||
(brack_group
|
||||
(text
|
||||
(word))
|
||||
(brack_group
|
||||
(text
|
||||
(word)))
|
||||
(text
|
||||
(word))))
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))))
|
||||
|
||||
================================================================================
|
||||
Environment with escaped options
|
||||
================================================================================
|
||||
|
||||
\begin{document}[{[}{]}]
|
||||
|
||||
Hello World!
|
||||
|
||||
\end{document}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word)))
|
||||
(brack_group
|
||||
(curly_group)
|
||||
(curly_group)))
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))))
|
||||
|
||||
================================================================================
|
||||
Comment environment
|
||||
================================================================================
|
||||
|
||||
Foo
|
||||
|
||||
\begin{comment}
|
||||
|
||||
\begin{document}
|
||||
|
||||
Hello World
|
||||
|
||||
\end{document}
|
||||
|
||||
\end{comment}
|
||||
|
||||
Bar
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(text
|
||||
(word))
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))
|
||||
(comment)
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word)))))
|
||||
(text
|
||||
(word)))
|
||||
|
||||
================================================================================
|
||||
Verbatim environment
|
||||
================================================================================
|
||||
|
||||
Foo
|
||||
|
||||
\begin{verbatim}
|
||||
|
||||
\begin{document}
|
||||
|
||||
Hello World
|
||||
|
||||
\end{document}
|
||||
|
||||
\end{verbatim}
|
||||
|
||||
Bar
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(text
|
||||
(word))
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))
|
||||
(comment)
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word)))))
|
||||
(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,199 @@
|
||||
================================================================================
|
||||
Simple package include
|
||||
================================================================================
|
||||
|
||||
\usepackage{amsmath}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(package_include
|
||||
(command_name)
|
||||
(curly_group_path_list
|
||||
(path))))
|
||||
|
||||
================================================================================
|
||||
Package include with two paths
|
||||
================================================================================
|
||||
|
||||
\usepackage{amsmath,lipsum}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(package_include
|
||||
(command_name)
|
||||
(curly_group_path_list
|
||||
(path)
|
||||
(path))))
|
||||
|
||||
================================================================================
|
||||
Package include with options
|
||||
================================================================================
|
||||
|
||||
\usepackage[foo=.5\textwidth, bar baz]{qux}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(package_include
|
||||
(command_name)
|
||||
(brack_group_key_value
|
||||
(key_value_pair
|
||||
(key
|
||||
(word))
|
||||
(value
|
||||
(text
|
||||
(word))
|
||||
(command
|
||||
(command_name))))
|
||||
(key_value_pair
|
||||
(key
|
||||
(word)
|
||||
(word))))
|
||||
(curly_group_path_list
|
||||
(path))))
|
||||
|
||||
================================================================================
|
||||
Simple class include
|
||||
================================================================================
|
||||
|
||||
\documentclass{amsmath}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(class_include
|
||||
(command_name)
|
||||
(curly_group_path
|
||||
(path))))
|
||||
|
||||
================================================================================
|
||||
Class include with two paths
|
||||
================================================================================
|
||||
|
||||
\documentclass{amsmath,lipsum}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(class_include
|
||||
(command_name)
|
||||
(curly_group_path
|
||||
(path)
|
||||
(MISSING "}")))
|
||||
(text
|
||||
(word))
|
||||
(ERROR))
|
||||
|
||||
================================================================================
|
||||
Class include with options
|
||||
================================================================================
|
||||
|
||||
\documentclass[foo=.5\textwidth, bar baz]{qux}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(class_include
|
||||
(command_name)
|
||||
(brack_group_key_value
|
||||
(key_value_pair
|
||||
(key
|
||||
(word))
|
||||
(value
|
||||
(text
|
||||
(word))
|
||||
(command
|
||||
(command_name))))
|
||||
(key_value_pair
|
||||
(key
|
||||
(word)
|
||||
(word))))
|
||||
(curly_group_path
|
||||
(path))))
|
||||
|
||||
================================================================================
|
||||
Simple LaTeX include
|
||||
================================================================================
|
||||
|
||||
\input{foo.tex}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(latex_include
|
||||
(command_name)
|
||||
(curly_group_path
|
||||
(path))))
|
||||
|
||||
================================================================================
|
||||
Empty LaTeX include
|
||||
================================================================================
|
||||
|
||||
\input{}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(ERROR
|
||||
(command_name)))
|
||||
|
||||
================================================================================
|
||||
BibLaTeX glob include
|
||||
================================================================================
|
||||
|
||||
\addbibresource[glob]{foo.{1,2,3}.bib}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(biblatex_include
|
||||
(command_name)
|
||||
(brack_group_key_value
|
||||
(key_value_pair
|
||||
(key
|
||||
(word))))
|
||||
(curly_group_glob_pattern
|
||||
(glob_pattern))))
|
||||
|
||||
================================================================================
|
||||
BibTeX include with absolute path
|
||||
================================================================================
|
||||
|
||||
\bibliography{/home/user/foo.bib}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(bibtex_include
|
||||
(command_name)
|
||||
(curly_group_path
|
||||
(path))))
|
||||
|
||||
================================================================================
|
||||
Graphics include with options
|
||||
================================================================================
|
||||
|
||||
\includegraphics[scale=0.5,angle=45]{test}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(graphics_include
|
||||
(command_name)
|
||||
(brack_group_key_value
|
||||
(key_value_pair
|
||||
(key
|
||||
(word))
|
||||
(value
|
||||
(text
|
||||
(word))))
|
||||
(key_value_pair
|
||||
(key
|
||||
(word))
|
||||
(value
|
||||
(text
|
||||
(word)))))
|
||||
(curly_group_path
|
||||
(path))))
|
||||
@ -0,0 +1,260 @@
|
||||
================================================================================
|
||||
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
|
||||
(command_name)
|
||||
(curly_group_path
|
||||
(path)))
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))
|
||||
(command
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(text
|
||||
(word))))
|
||||
(text
|
||||
(word)
|
||||
(word)
|
||||
(word)
|
||||
(word))
|
||||
(command
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word))))
|
||||
(text
|
||||
(word)
|
||||
(word)
|
||||
(word)
|
||||
(word)
|
||||
(word)
|
||||
(word)
|
||||
(word)
|
||||
(word)
|
||||
(word)
|
||||
(word)
|
||||
(word)
|
||||
(word))
|
||||
(command
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word))))
|
||||
(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))
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))))
|
||||
|
||||
================================================================================
|
||||
tree-sitter-latex (Issue #15)
|
||||
================================================================================
|
||||
|
||||
\iffalse
|
||||
something here
|
||||
\fi
|
||||
|
||||
\usepackage{comment} % in the preamble
|
||||
\begin{comment}
|
||||
something
|
||||
\end{comment}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(block_comment
|
||||
(command_name)
|
||||
(comment)
|
||||
(command_name))
|
||||
(package_include
|
||||
(command_name)
|
||||
(curly_group_path_list
|
||||
(path)))
|
||||
(line_comment)
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))
|
||||
(comment)
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))))
|
||||
|
||||
================================================================================
|
||||
tree-sitter-latex (Issue #10)
|
||||
================================================================================
|
||||
|
||||
\titleformat{\section}{\relax}{\thesection}{1em}{\spacedsmallcaps}
|
||||
\titlespacing*{\paragraph}{0pt}{1\baselineskip}{0.5\baselineskip}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(command
|
||||
(command_name)
|
||||
(curly_group
|
||||
(section
|
||||
(command_name)))
|
||||
(curly_group
|
||||
(command
|
||||
(command_name)))
|
||||
(curly_group
|
||||
(command
|
||||
(command_name)))
|
||||
(curly_group
|
||||
(text
|
||||
(word)))
|
||||
(curly_group
|
||||
(command
|
||||
(command_name))))
|
||||
(command
|
||||
(command_name)
|
||||
(curly_group
|
||||
(paragraph
|
||||
(command_name)))
|
||||
(curly_group
|
||||
(text
|
||||
(word)))
|
||||
(curly_group
|
||||
(text
|
||||
(word))
|
||||
(command
|
||||
(command_name)))
|
||||
(curly_group
|
||||
(text
|
||||
(word))
|
||||
(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
|
||||
(command_name)
|
||||
(curly_group_glob_pattern
|
||||
(glob_pattern)))
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(command
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word))))
|
||||
(text
|
||||
(word))
|
||||
(text
|
||||
(word))
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))
|
||||
(comment)
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))))
|
||||
|
||||
================================================================================
|
||||
tree-sitter-latex (Issue #11)
|
||||
================================================================================
|
||||
|
||||
\newenvironment{mycenter}
|
||||
{\begin{center}}
|
||||
{\end{center}}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(environment_definition
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word)))
|
||||
(curly_group_impl
|
||||
(command
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word)))))
|
||||
(curly_group_impl
|
||||
(command
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word)))))))
|
||||
@ -0,0 +1,216 @@
|
||||
================================================================================
|
||||
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
|
||||
(command_name)
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(command_name)))
|
||||
|
||||
================================================================================
|
||||
Displayed equation (mixed)
|
||||
================================================================================
|
||||
|
||||
Foo \[ Bar Baz $$
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(text
|
||||
(word))
|
||||
(displayed_equation
|
||||
(command_name)
|
||||
(text
|
||||
(word)
|
||||
(word))))
|
||||
|
||||
================================================================================
|
||||
Displayed equation (nested)
|
||||
================================================================================
|
||||
|
||||
Foo $$ Bar Baz \[ Qux \] $$
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(text
|
||||
(word))
|
||||
(displayed_equation
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(displayed_equation
|
||||
(command_name)
|
||||
(text
|
||||
(word))
|
||||
(command_name))))
|
||||
|
||||
================================================================================
|
||||
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
|
||||
(command_name)
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(command_name)))
|
||||
|
||||
================================================================================
|
||||
Inline formula (mixed)
|
||||
================================================================================
|
||||
|
||||
Foo \( Bar Baz $
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(text
|
||||
(word))
|
||||
(inline_formula
|
||||
(command_name)
|
||||
(text
|
||||
(word)
|
||||
(word))))
|
||||
|
||||
================================================================================
|
||||
Inline formula (nested)
|
||||
================================================================================
|
||||
|
||||
Foo $ Bar Baz \( Qux \) $
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(text
|
||||
(word))
|
||||
(inline_formula
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(inline_formula
|
||||
(command_name)
|
||||
(text
|
||||
(word))
|
||||
(command_name))))
|
||||
|
||||
================================================================================
|
||||
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
|
||||
(math_set
|
||||
(command_name)
|
||||
(text
|
||||
(word))
|
||||
(text
|
||||
(word))
|
||||
(text
|
||||
(word))
|
||||
(command_name)))
|
||||
@ -0,0 +1,94 @@
|
||||
================================================================================
|
||||
Top level sections
|
||||
================================================================================
|
||||
|
||||
\begin{document}
|
||||
|
||||
1
|
||||
|
||||
\section{Foo}
|
||||
|
||||
2
|
||||
|
||||
\section{Bar}
|
||||
|
||||
3
|
||||
|
||||
\end{document}
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(environment
|
||||
(begin
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))
|
||||
(text
|
||||
(word))
|
||||
(section
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word)))
|
||||
(text
|
||||
(word)))
|
||||
(section
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word)))
|
||||
(text
|
||||
(word)))
|
||||
(end
|
||||
(command_name)
|
||||
(curly_group_key
|
||||
(key
|
||||
(word))))))
|
||||
|
||||
================================================================================
|
||||
Nested sections
|
||||
================================================================================
|
||||
|
||||
1
|
||||
|
||||
\part{\Foo}
|
||||
|
||||
2
|
||||
|
||||
\chapter{Bar}
|
||||
|
||||
3
|
||||
|
||||
\chapter{{Baz}}
|
||||
|
||||
4
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(text
|
||||
(word))
|
||||
(part
|
||||
(command_name)
|
||||
(curly_group
|
||||
(command
|
||||
(command_name)))
|
||||
(text
|
||||
(word))
|
||||
(chapter
|
||||
(command_name)
|
||||
(curly_group
|
||||
(text
|
||||
(word)))
|
||||
(text
|
||||
(word)))
|
||||
(chapter
|
||||
(command_name)
|
||||
(curly_group
|
||||
(curly_group
|
||||
(text
|
||||
(word))))
|
||||
(text
|
||||
(word)))))
|
||||
@ -0,0 +1,89 @@
|
||||
================================================================================
|
||||
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))
|
||||
(macro_parameter)
|
||||
(text
|
||||
(word)))
|
||||
|
||||
================================================================================
|
||||
Invalid macro parameter
|
||||
================================================================================
|
||||
|
||||
Foo # Bar
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(text
|
||||
(word)
|
||||
(ERROR
|
||||
(UNEXPECTED ' '))
|
||||
(word)))
|
||||
@ -0,0 +1,54 @@
|
||||
================================================================================
|
||||
Line comment
|
||||
================================================================================
|
||||
|
||||
% Foo
|
||||
Bar
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(line_comment)
|
||||
(text
|
||||
(word)))
|
||||
|
||||
================================================================================
|
||||
Escaped percent
|
||||
================================================================================
|
||||
|
||||
\% Foo
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(command
|
||||
(command_name))
|
||||
(text
|
||||
(word)))
|
||||
|
||||
================================================================================
|
||||
Block comment
|
||||
================================================================================
|
||||
|
||||
Hello World
|
||||
|
||||
\iffalse
|
||||
|
||||
\foo Bar \begin{Baz
|
||||
|
||||
\fi
|
||||
|
||||
Test
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(text
|
||||
(word)
|
||||
(word))
|
||||
(block_comment
|
||||
(command_name)
|
||||
(comment)
|
||||
(command_name))
|
||||
(text
|
||||
(word)))
|
||||
@ -0,0 +1,15 @@
|
||||
/// <reference types="tree-sitter-cli/dsl" />
|
||||
// @ts-check
|
||||
|
||||
const sepBy1 = (rule, sep) => seq(rule, repeat(seq(sep, rule)));
|
||||
|
||||
const sepBy = (rule, sep) => optional(sepBy1(rule, sep));
|
||||
|
||||
const commandName = ($, rule) =>
|
||||
field('command_name', alias($[`_${rule}_command_name`], $.command_name));
|
||||
|
||||
module.exports = {
|
||||
sepBy1,
|
||||
sepBy,
|
||||
commandName,
|
||||
};
|
||||
Loading…
Reference in New Issue